|
Packit |
90a5c9 |
/* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
Packit |
90a5c9 |
* contributor license agreements. See the NOTICE file distributed with
|
|
Packit |
90a5c9 |
* this work for additional information regarding copyright ownership.
|
|
Packit |
90a5c9 |
* The ASF licenses this file to You under the Apache License, Version 2.0
|
|
Packit |
90a5c9 |
* (the "License"); you may not use this file except in compliance with
|
|
Packit |
90a5c9 |
* the License. You may obtain a copy of the License at
|
|
Packit |
90a5c9 |
*
|
|
Packit |
90a5c9 |
* http://www.apache.org/licenses/LICENSE-2.0
|
|
Packit |
90a5c9 |
*
|
|
Packit |
90a5c9 |
* Unless required by applicable law or agreed to in writing, software
|
|
Packit |
90a5c9 |
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
Packit |
90a5c9 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
Packit |
90a5c9 |
* See the License for the specific language governing permissions and
|
|
Packit |
90a5c9 |
* limitations under the License.
|
|
Packit |
90a5c9 |
*/
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
#include "mod_proxy.h"
|
|
Packit |
90a5c9 |
#include "apr_dbm.h"
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
module AP_MODULE_DECLARE_DATA proxy_express_module;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
static int proxy_available = 0;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
typedef struct {
|
|
Packit |
90a5c9 |
const char *dbmfile;
|
|
Packit |
90a5c9 |
const char *dbmtype;
|
|
Packit |
90a5c9 |
int enabled;
|
|
Packit |
90a5c9 |
} express_server_conf;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
static const char *set_dbmfile(cmd_parms *cmd,
|
|
Packit |
90a5c9 |
void *dconf,
|
|
Packit |
90a5c9 |
const char *arg)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
express_server_conf *sconf;
|
|
Packit |
90a5c9 |
sconf = ap_get_module_config(cmd->server->module_config, &proxy_express_module);
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
if ((sconf->dbmfile = ap_server_root_relative(cmd->pool, arg)) == NULL) {
|
|
Packit |
90a5c9 |
return apr_pstrcat(cmd->pool, "ProxyExpressDBMFile: bad path to file: ",
|
|
Packit |
90a5c9 |
arg, NULL);
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
return NULL;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
static const char *set_dbmtype(cmd_parms *cmd,
|
|
Packit |
90a5c9 |
void *dconf,
|
|
Packit |
90a5c9 |
const char *arg)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
express_server_conf *sconf;
|
|
Packit |
90a5c9 |
sconf = ap_get_module_config(cmd->server->module_config, &proxy_express_module);
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
sconf->dbmtype = arg;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
return NULL;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
static const char *set_enabled(cmd_parms *cmd,
|
|
Packit |
90a5c9 |
void *dconf,
|
|
Packit |
90a5c9 |
int flag)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
express_server_conf *sconf;
|
|
Packit |
90a5c9 |
sconf = ap_get_module_config(cmd->server->module_config, &proxy_express_module);
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
sconf->enabled = flag;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
return NULL;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
static void *server_create(apr_pool_t *p, server_rec *s)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
express_server_conf *a;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
a = (express_server_conf *)apr_pcalloc(p, sizeof(express_server_conf));
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
a->dbmfile = NULL;
|
|
Packit |
90a5c9 |
a->dbmtype = "default";
|
|
Packit |
90a5c9 |
a->enabled = 0;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
return (void *)a;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
static void *server_merge(apr_pool_t *p, void *basev, void *overridesv)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
express_server_conf *a, *base, *overrides;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
a = (express_server_conf *)apr_pcalloc(p,
|
|
Packit |
90a5c9 |
sizeof(express_server_conf));
|
|
Packit |
90a5c9 |
base = (express_server_conf *)basev;
|
|
Packit |
90a5c9 |
overrides = (express_server_conf *)overridesv;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
a->dbmfile = (overrides->dbmfile) ? overrides->dbmfile : base->dbmfile;
|
|
Packit |
90a5c9 |
a->dbmtype = (overrides->dbmtype) ? overrides->dbmtype : base->dbmtype;
|
|
Packit |
90a5c9 |
a->enabled = (overrides->enabled) ? overrides->enabled : base->enabled;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
return (void *)a;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
static int post_config(apr_pool_t *p,
|
|
Packit |
90a5c9 |
apr_pool_t *plog,
|
|
Packit |
90a5c9 |
apr_pool_t *ptemp,
|
|
Packit |
90a5c9 |
server_rec *s)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
proxy_available = (ap_find_linked_module("mod_proxy.c") != NULL);
|
|
Packit |
90a5c9 |
return OK;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
static int xlate_name(request_rec *r)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
int i;
|
|
Packit |
90a5c9 |
const char *name;
|
|
Packit |
90a5c9 |
char *backend = NULL;
|
|
Packit |
90a5c9 |
apr_dbm_t *db;
|
|
Packit |
90a5c9 |
apr_status_t rv;
|
|
Packit |
90a5c9 |
apr_datum_t key, val;
|
|
Packit |
90a5c9 |
struct proxy_alias *ralias;
|
|
Packit |
90a5c9 |
proxy_dir_conf *dconf;
|
|
Packit |
90a5c9 |
express_server_conf *sconf;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
sconf = ap_get_module_config(r->server->module_config, &proxy_express_module);
|
|
Packit |
90a5c9 |
dconf = ap_get_module_config(r->per_dir_config, &proxy_module);
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
if (!sconf->enabled) {
|
|
Packit |
90a5c9 |
return DECLINED;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01001) "proxy_express: Enabled");
|
|
Packit |
90a5c9 |
if (!sconf->dbmfile || (r->filename && strncmp(r->filename, "proxy:", 6) == 0)) {
|
|
Packit |
90a5c9 |
/* it should be go on as an internal proxy request */
|
|
Packit |
90a5c9 |
return DECLINED;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01002)
|
|
Packit |
90a5c9 |
"proxy_express: Opening DBM file: %s (%s)",
|
|
Packit |
90a5c9 |
sconf->dbmfile, sconf->dbmtype);
|
|
Packit |
90a5c9 |
rv = apr_dbm_open_ex(&db, sconf->dbmtype, sconf->dbmfile, APR_DBM_READONLY,
|
|
Packit |
90a5c9 |
APR_OS_DEFAULT, r->pool);
|
|
Packit |
90a5c9 |
if (rv != APR_SUCCESS) {
|
|
Packit |
90a5c9 |
return DECLINED;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
name = ap_get_server_name(r);
|
|
Packit |
90a5c9 |
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01003)
|
|
Packit |
90a5c9 |
"proxy_express: looking for %s", name);
|
|
Packit |
90a5c9 |
key.dptr = (char *)name;
|
|
Packit |
90a5c9 |
key.dsize = strlen(key.dptr);
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
rv = apr_dbm_fetch(db, key, &val;;
|
|
Packit |
90a5c9 |
if (rv == APR_SUCCESS) {
|
|
Packit |
90a5c9 |
backend = apr_pstrmemdup(r->pool, val.dptr, val.dsize);
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
apr_dbm_close(db);
|
|
Packit |
90a5c9 |
if (rv != APR_SUCCESS || !backend) {
|
|
Packit |
90a5c9 |
return DECLINED;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01004)
|
|
Packit |
90a5c9 |
"proxy_express: found %s -> %s", name, backend);
|
|
Packit |
90a5c9 |
r->filename = apr_pstrcat(r->pool, "proxy:", backend, r->uri, NULL);
|
|
Packit |
90a5c9 |
r->handler = "proxy-server";
|
|
Packit |
90a5c9 |
r->proxyreq = PROXYREQ_REVERSE;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01005)
|
|
Packit |
90a5c9 |
"proxy_express: rewritten as: %s", r->filename);
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
ralias = (struct proxy_alias *)dconf->raliases->elts;
|
|
Packit |
90a5c9 |
/*
|
|
Packit |
90a5c9 |
* See if we have already added a ProxyPassReverse entry
|
|
Packit |
90a5c9 |
* for this host... If so, don't do it again.
|
|
Packit |
90a5c9 |
*/
|
|
Packit |
90a5c9 |
/*
|
|
Packit |
90a5c9 |
* NOTE: dconf is process specific so this will only
|
|
Packit |
90a5c9 |
* work as long as we maintain that this process
|
|
Packit |
90a5c9 |
* or thread is handling the backend
|
|
Packit |
90a5c9 |
*/
|
|
Packit |
90a5c9 |
for (i = 0; i < dconf->raliases->nelts; i++, ralias++) {
|
|
Packit |
90a5c9 |
if (strcasecmp(backend, ralias->real) == 0) {
|
|
Packit |
90a5c9 |
ralias = NULL;
|
|
Packit |
90a5c9 |
break;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
/* Didn't find one... add it */
|
|
Packit |
90a5c9 |
if (!ralias) {
|
|
Packit |
90a5c9 |
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01006)
|
|
Packit |
90a5c9 |
"proxy_express: adding PPR entry");
|
|
Packit |
90a5c9 |
ralias = apr_array_push(dconf->raliases);
|
|
Packit |
90a5c9 |
ralias->fake = "/";
|
|
Packit |
90a5c9 |
ralias->real = apr_pstrdup(dconf->raliases->pool, backend);
|
|
Packit |
90a5c9 |
ralias->flags = 0;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
return OK;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
static const command_rec command_table[] = {
|
|
Packit |
90a5c9 |
AP_INIT_FLAG("ProxyExpressEnable", set_enabled, NULL, OR_FILEINFO,
|
|
Packit |
90a5c9 |
"Enable the ProxyExpress functionality"),
|
|
Packit |
90a5c9 |
AP_INIT_TAKE1("ProxyExpressDBMFile", set_dbmfile, NULL, OR_FILEINFO,
|
|
Packit |
90a5c9 |
"Location of ProxyExpressDBMFile file"),
|
|
Packit |
90a5c9 |
AP_INIT_TAKE1("ProxyExpressDBMType", set_dbmtype, NULL, OR_FILEINFO,
|
|
Packit |
90a5c9 |
"Type of ProxyExpressDBMFile file"),
|
|
Packit |
90a5c9 |
{ NULL }
|
|
Packit |
90a5c9 |
};
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
static void register_hooks(apr_pool_t *p)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
ap_hook_post_config(post_config, NULL, NULL, APR_HOOK_LAST);
|
|
Packit |
90a5c9 |
ap_hook_translate_name(xlate_name, NULL, NULL, APR_HOOK_FIRST);
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
/* the main config structure */
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
AP_DECLARE_MODULE(proxy_express) =
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
STANDARD20_MODULE_STUFF,
|
|
Packit |
90a5c9 |
NULL, /* create per-dir config structures */
|
|
Packit |
90a5c9 |
NULL, /* merge per-dir config structures */
|
|
Packit |
90a5c9 |
server_create, /* create per-server config structures */
|
|
Packit |
90a5c9 |
server_merge, /* merge per-server config structures */
|
|
Packit |
90a5c9 |
command_table, /* table of config file commands */
|
|
Packit |
90a5c9 |
register_hooks /* register hooks */
|
|
Packit |
90a5c9 |
};
|