Apache HTTPD
mod_proxy_express.c
Go to the documentation of this file.
1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "mod_proxy.h"
18#include "apr_dbm.h"
19
20module AP_MODULE_DECLARE_DATA proxy_express_module;
21
22#include "apr_version.h"
23#if !APR_VERSION_AT_LEAST(2,0,0)
24#include "apu_version.h"
25#endif
26
27static int proxy_available = 0;
28
29typedef struct {
30 const char *dbmfile;
31 const char *dbmtype;
34
35static const char *set_dbmfile(cmd_parms *cmd,
36 void *dconf,
37 const char *arg)
38{
40 sconf = ap_get_module_config(cmd->server->module_config, &proxy_express_module);
41
42 if ((sconf->dbmfile = ap_server_root_relative(cmd->pool, arg)) == NULL) {
43 return apr_pstrcat(cmd->pool, "ProxyExpressDBMFile: bad path to file: ",
44 arg, NULL);
45 }
46 return NULL;
47}
48
49static const char *set_dbmtype(cmd_parms *cmd,
50 void *dconf,
51 const char *arg)
52{
54 sconf = ap_get_module_config(cmd->server->module_config, &proxy_express_module);
55
56 sconf->dbmtype = arg;
57
58 return NULL;
59}
60
61static const char *set_enabled(cmd_parms *cmd,
62 void *dconf,
63 int flag)
64{
66 sconf = ap_get_module_config(cmd->server->module_config, &proxy_express_module);
67
68 sconf->enabled = flag;
69
70 return NULL;
71}
72
74{
76
78
79 a->dbmfile = NULL;
80 a->dbmtype = "default";
81 a->enabled = 0;
82
83 return (void *)a;
84}
85
86static void *server_merge(apr_pool_t *p, void *basev, void *overridesv)
87{
89
91 sizeof(express_server_conf));
94
95 a->dbmfile = (overrides->dbmfile) ? overrides->dbmfile : base->dbmfile;
96 a->dbmtype = (overrides->dbmtype) ? overrides->dbmtype : base->dbmtype;
97 a->enabled = (overrides->enabled) ? overrides->enabled : base->enabled;
98
99 return (void *)a;
100}
101
104 apr_pool_t *ptemp,
105 server_rec *s)
106{
107 proxy_available = (ap_find_linked_module("mod_proxy.c") != NULL);
108 return OK;
109}
110
111
113{
114 int i;
115 const char *name;
116 char *backend = NULL;
117 apr_dbm_t *db;
118 apr_status_t rv;
120 struct proxy_alias *ralias;
121 proxy_dir_conf *dconf;
123#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
125 const apu_err_t *err;
126#endif
127
128 sconf = ap_get_module_config(r->server->module_config, &proxy_express_module);
129 dconf = ap_get_module_config(r->per_dir_config, &proxy_module);
130
131 if (!sconf->enabled) {
132 return DECLINED;
133 }
134
135 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01001) "proxy_express: Enabled");
136 if (!sconf->dbmfile || (r->filename && strncmp(r->filename, "proxy:", 6) == 0)) {
137 /* it should be go on as an internal proxy request */
138 return DECLINED;
139 }
140
142 "proxy_express: Opening DBM file: %s (%s)",
143 sconf->dbmfile, sconf->dbmtype);
144
145#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
146 rv = apr_dbm_get_driver(&driver, sconf->dbmtype, &err, r->pool);
147 if (rv != APR_SUCCESS) {
149 APLOGNO(10275) "The dbm library '%s' could not be loaded: %s (%s: %d)",
150 sconf->dbmtype, err->msg, err->reason, err->rc);
151 return DECLINED;
152 }
153
154 rv = apr_dbm_open2(&db, driver, sconf->dbmfile, APR_DBM_READONLY,
156 if (rv != APR_SUCCESS) {
158 APLOGNO(10276) "The '%s' file '%s' could not be loaded",
159 sconf->dbmtype, sconf->dbmfile);
160 return DECLINED;
161 }
162#else
163 rv = apr_dbm_open_ex(&db, sconf->dbmtype, sconf->dbmfile, APR_DBM_READONLY,
165 if (rv != APR_SUCCESS) {
166 return DECLINED;
167 }
168#endif
169
172 "proxy_express: looking for %s", name);
173 key.dptr = (char *)name;
174 key.dsize = strlen(key.dptr);
175
176 rv = apr_dbm_fetch(db, key, &val);
177 if (rv == APR_SUCCESS) {
178 backend = apr_pstrmemdup(r->pool, val.dptr, val.dsize);
179 }
180 apr_dbm_close(db);
181 if (rv != APR_SUCCESS || !backend) {
182 return DECLINED;
183 }
184
186 "proxy_express: found %s -> %s", name, backend);
187 r->filename = apr_pstrcat(r->pool, "proxy:", backend, r->uri, NULL);
188 r->handler = "proxy-server";
190
192 "proxy_express: rewritten as: %s", r->filename);
193
194 ralias = (struct proxy_alias *)dconf->raliases->elts;
195 /*
196 * See if we have already added a ProxyPassReverse entry
197 * for this host... If so, don't do it again.
198 */
199 /*
200 * NOTE: dconf is process specific so this will only
201 * work as long as we maintain that this process
202 * or thread is handling the backend
203 */
204 for (i = 0; i < dconf->raliases->nelts; i++, ralias++) {
205 if (strcasecmp(backend, ralias->real) == 0) {
206 ralias = NULL;
207 break;
208 }
209 }
210
211 /* Didn't find one... add it */
212 if (!ralias) {
214 "proxy_express: adding PPR entry");
216 ralias->fake = "/";
217 ralias->real = apr_pstrdup(dconf->raliases->pool, backend);
218 ralias->flags = 0;
219 }
220 return OK;
221}
222
223static const command_rec command_table[] = {
224 AP_INIT_FLAG("ProxyExpressEnable", set_enabled, NULL, OR_FILEINFO,
225 "Enable the ProxyExpress functionality"),
226 AP_INIT_TAKE1("ProxyExpressDBMFile", set_dbmfile, NULL, OR_FILEINFO,
227 "Location of ProxyExpressDBMFile file"),
228 AP_INIT_TAKE1("ProxyExpressDBMType", set_dbmtype, NULL, OR_FILEINFO,
229 "Type of ProxyExpressDBMFile file"),
230 { NULL }
231};
232
238
239/* the main config structure */
240
242{
244 NULL, /* create per-dir config structures */
245 NULL, /* merge per-dir config structures */
246 server_create, /* create per-server config structures */
247 server_merge, /* merge per-server config structures */
248 command_table, /* table of config file commands */
249 register_hooks /* register hooks */
250};
APR-UTIL DBM library.
APR Versioning Interface.
APR-util Versioning Interface.
#define AP_INIT_TAKE1(directive, func, mconfig, where, help)
#define ap_get_module_config(v, m)
void ap_hook_post_config(ap_HOOK_post_config_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
Definition config.c:105
#define AP_DECLARE_MODULE(foo)
#define AP_INIT_FLAG(directive, func, mconfig, where, help)
ap_conf_vector_t * base
char * ap_server_root_relative(apr_pool_t *p, const char *fname)
Definition config.c:1594
request_rec * r
#define DECLINED
Definition httpd.h:457
#define OK
Definition httpd.h:456
const char * ap_get_server_name(request_rec *r)
Definition core.c:1145
#define APLOGNO(n)
Definition http_log.h:117
#define ap_log_rerror
Definition http_log.h:454
#define APLOG_ERR
Definition http_log.h:67
#define APLOG_MARK
Definition http_log.h:283
#define APLOG_DEBUG
Definition http_log.h:71
void ap_hook_translate_name(ap_HOOK_translate_name_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
Definition request.c:81
void const char * arg
Definition http_vhost.h:63
apr_bucket apr_bucket_brigade * a
const char const apr_dbd_driver_t ** driver
Definition apr_dbd.h:106
#define APR_DBM_READONLY
Definition apr_dbm.h:56
#define APR_HOOK_FIRST
Definition apr_hooks.h:301
#define APR_HOOK_LAST
Definition apr_hooks.h:305
#define OR_FILEINFO
#define STANDARD20_MODULE_STUFF
#define PROXYREQ_REVERSE
Definition httpd.h:1135
apr_size_t size
apr_uint32_t val
Definition apr_atomic.h:66
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
const char * key
const char apr_int32_t flag
#define APR_OS_DEFAULT
int strcasecmp(const char *a, const char *b)
#define apr_pcalloc(p, size)
Definition apr_pools.h:465
const char * s
Definition apr_strings.h:95
apr_int32_t apr_int32_t apr_int32_t err
apr_cmdtype_e cmd
apr_pool_t * p
Definition md_event.c:32
Proxy Extension Module for Apache.
static int post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
static const command_rec command_table[]
static int proxy_available
static const char * set_dbmfile(cmd_parms *cmd, void *dconf, const char *arg)
static const char * set_dbmtype(cmd_parms *cmd, void *dconf, const char *arg)
static void * server_create(apr_pool_t *p, server_rec *s)
static void * server_merge(apr_pool_t *p, void *basev, void *overridesv)
static int xlate_name(request_rec *r)
static void register_hooks(apr_pool_t *p)
static const char * set_enabled(cmd_parms *cmd, void *dconf, int flag)
return NULL
Definition mod_so.c:359
int i
Definition mod_so.c:347
sconf
Definition mod_so.c:349
char * name
apr_pool_t * pool
Definition apr_tables.h:64
apr_array_header_t * raliases
Definition mod_proxy.h:226
A structure that represents the current request.
Definition httpd.h:845
char * uri
Definition httpd.h:1016
const char * handler
Definition httpd.h:994
apr_pool_t * pool
Definition httpd.h:847
char * filename
Definition httpd.h:1018
int proxyreq
Definition httpd.h:873
server_rec * server
Definition httpd.h:851
struct ap_conf_vector_t * per_dir_config
Definition httpd.h:1047
A structure to store information for each virtual server.
Definition httpd.h:1322
struct ap_conf_vector_t * module_config
Definition httpd.h:1341