]>
Commit | Line | Data |
---|---|---|
180ac886 | 1 | diff -u apache_1.3.26/src/modules/proxy/mod_proxy.c apache_1.3.26-patched/src/modules/proxy/mod_proxy.c |
2 | --- apache_1.3.26/src/modules/proxy/mod_proxy.c Mon Jun 17 20:59:59 2002 | |
3 | +++ apache_1.3.26-patched/src/modules/proxy/mod_proxy.c Sun Jun 23 19:25:57 2002 | |
4 | @@ -218,6 +218,9 @@ | |
5 | static int proxy_fixup(request_rec *r) | |
6 | { | |
7 | char *url, *p; | |
8 | +#ifdef EAPI | |
9 | + int rc; | |
10 | +#endif /* EAPI */ | |
11 | ||
12 | if (r->proxyreq == NOT_PROXY || strncmp(r->filename, "proxy:", 6) != 0) | |
13 | return DECLINED; | |
14 | @@ -225,6 +228,14 @@ | |
15 | url = &r->filename[6]; | |
16 | ||
17 | /* canonicalise each specific scheme */ | |
18 | +#ifdef EAPI | |
19 | + if (ap_hook_use("ap::mod_proxy::canon", | |
20 | + AP_HOOK_SIG3(int,ptr,ptr), | |
21 | + AP_HOOK_DECLINE(DECLINED), | |
22 | + &rc, r, url) && rc != DECLINED) | |
23 | + return rc; | |
24 | + else | |
25 | +#endif /* EAPI */ | |
26 | if (strncasecmp(url, "http:", 5) == 0) | |
27 | return ap_proxy_http_canon(r, url + 5, "http", DEFAULT_HTTP_PORT); | |
28 | else if (strncasecmp(url, "ftp:", 4) == 0) | |
29 | @@ -240,9 +251,44 @@ | |
30 | static void proxy_init(server_rec *r, pool *p) | |
31 | { | |
32 | ap_proxy_garbage_init(r, p); | |
33 | +#ifdef EAPI | |
34 | + ap_hook_use("ap::mod_proxy::init", | |
35 | + AP_HOOK_SIG3(void,ptr,ptr), AP_HOOK_ALL, r, p); | |
36 | +#endif | |
37 | } | |
38 | ||
39 | - | |
40 | +#ifdef EAPI | |
41 | +static void proxy_addmod(module *m) | |
42 | +{ | |
43 | + /* export: ap_proxy_http_canon() as `ap::mod_proxy::http::canon' */ | |
44 | + ap_hook_configure("ap::mod_proxy::http::canon", | |
45 | + AP_HOOK_SIG5(int,ptr,ptr,ptr,int), AP_HOOK_TOPMOST); | |
46 | + ap_hook_register("ap::mod_proxy::http::canon", | |
47 | + ap_proxy_http_canon, AP_HOOK_NOCTX); | |
48 | + | |
49 | + /* export: ap_proxy_http_handler() as `ap::mod_proxy::http::handler' */ | |
50 | + ap_hook_configure("ap::mod_proxy::http::handler", | |
51 | + AP_HOOK_SIG6(int,ptr,ptr,ptr,ptr,int), AP_HOOK_TOPMOST); | |
52 | + ap_hook_register("ap::mod_proxy::http::handler", | |
53 | + ap_proxy_http_handler, AP_HOOK_NOCTX); | |
54 | + | |
55 | + /* export: ap_proxyerror() as `ap::mod_proxy::error' */ | |
56 | + ap_hook_configure("ap::mod_proxy::error", | |
57 | + AP_HOOK_SIG3(int,ptr,ptr), AP_HOOK_TOPMOST); | |
58 | + ap_hook_register("ap::mod_proxy::error", | |
59 | + ap_proxyerror, AP_HOOK_NOCTX); | |
60 | + return; | |
61 | +} | |
62 | + | |
63 | +static void proxy_remmod(module *m) | |
64 | +{ | |
65 | + /* remove the hook references */ | |
66 | + ap_hook_unregister("ap::mod_proxy::http::canon", ap_proxy_http_canon); | |
67 | + ap_hook_unregister("ap::mod_proxy::http::handler", ap_proxy_http_handler); | |
68 | + ap_hook_unregister("ap::mod_proxy::error", ap_proxyerror); | |
69 | + return; | |
70 | +} | |
71 | +#endif /* EAPI */ | |
72 | ||
73 | /* Send a redirection if the request contains a hostname which is not */ | |
74 | /* fully qualified, i.e. doesn't have a domain name appended. Some proxy */ | |
75 | @@ -374,6 +420,14 @@ | |
76 | * CONNECT is a special method that bypasses the normal proxy | |
77 | * code. | |
78 | */ | |
79 | +#ifdef EAPI | |
80 | + if (!ap_hook_use("ap::mod_proxy::handler", | |
81 | + AP_HOOK_SIG7(int,ptr,ptr,ptr,ptr,int,ptr), | |
82 | + AP_HOOK_DECLINE(DECLINED), | |
83 | + &rc, r, cr, url, | |
84 | + ents[i].hostname, ents[i].port, | |
85 | + ents[i].protocol) || rc == DECLINED) { | |
86 | +#endif /* EAPI */ | |
87 | if (r->method_number == M_CONNECT) | |
88 | rc = ap_proxy_connect_handler(r, cr, url, ents[i].hostname, | |
89 | ents[i].port); | |
90 | @@ -383,6 +437,9 @@ | |
91 | ents[i].port); | |
92 | else | |
93 | rc = DECLINED; | |
94 | +#ifdef EAPI | |
95 | + } | |
96 | +#endif /* EAPI */ | |
97 | ||
98 | /* an error or success */ | |
99 | if (rc != DECLINED && rc != HTTP_BAD_GATEWAY) | |
100 | @@ -397,6 +454,14 @@ | |
101 | */ | |
102 | ||
103 | /* handle the scheme */ | |
104 | +#ifdef EAPI | |
105 | + if (ap_hook_use("ap::mod_proxy::handler", | |
106 | + AP_HOOK_SIG7(int,ptr,ptr,ptr,ptr,int,ptr), | |
107 | + AP_HOOK_DECLINE(DECLINED), | |
108 | + &rc, r, cr, url, | |
109 | + NULL, 0, scheme) && rc != DECLINED) | |
110 | + return rc; | |
111 | +#endif /* EAPI */ | |
112 | if (r->method_number == M_CONNECT) { | |
113 | return ap_proxy_connect_handler(r, cr, url, NULL, 0); | |
114 | } | |
115 | @@ -460,6 +525,11 @@ | |
116 | ps->cache.dirlength_set = 0; | |
117 | ps->cache.cache_completion = (float)DEFAULT_CACHE_COMPLETION; | |
118 | ps->cache.cache_completion_set = 0; | |
119 | + /* header manipulation */ | |
120 | + ps->freshen_date = ap_make_array(p, 10, sizeof(hdr_actions_entry)); | |
121 | + ps->resp_exp_vector = ap_make_array(p, 10, sizeof(resp_exp_vector_entry)); | |
122 | + ps->req_headers = ap_make_array(p, 10, sizeof(hdr_actions_entry)); | |
123 | + ps->resp_headers = ap_make_array(p, 10, sizeof(hdr_actions_entry)); | |
124 | ||
125 | return ps; | |
126 | } | |
127 | @@ -496,6 +566,18 @@ | |
128 | ps->cache.dirlevels = (overrides->cache.dirlevels_set == 0) ? base->cache.dirlevels : overrides->cache.dirlevels; | |
129 | ps->cache.dirlength = (overrides->cache.dirlength_set == 0) ? base->cache.dirlength : overrides->cache.dirlength; | |
130 | ps->cache.cache_completion = (overrides->cache.cache_completion_set == 0) ? base->cache.cache_completion : overrides->cache.cache_completion; | |
131 | + /* put freshen_date and resp_exp_vector from the overriding config | |
132 | + in front of the base config arrays, the semantics being that | |
133 | + virtual server configs should be checked first */ | |
134 | + ps->freshen_date = ap_append_arrays(p,overrides->freshen_date,base->freshen_date); | |
135 | + ps->resp_exp_vector = ap_append_arrays(p,overrides->resp_exp_vector,base->resp_exp_vector); | |
136 | + /* add req_ and resp_headers from the overriding config after | |
137 | + those from the base config arrays, the semantics being that the | |
138 | + directives are applied in declaration order, with those | |
139 | + specific to a virtual server coming after and therefore | |
140 | + overriding those from the root config */ | |
141 | + ps->req_headers = ap_append_arrays(p,base->req_headers,overrides->req_headers); | |
142 | + ps->resp_headers = ap_append_arrays(p,base->resp_headers,overrides->resp_headers); | |
143 | ||
144 | return ps; | |
145 | } | |
146 | @@ -920,6 +1002,120 @@ | |
147 | return NULL; | |
148 | } | |
149 | ||
150 | +static const char* | |
151 | + set_freshen_date(cmd_parms *parms, void *mconfig, char *one, char *two) | |
152 | +{ | |
153 | + proxy_server_conf *psf = | |
154 | + ap_get_module_config(parms->server->module_config, &proxy_module); | |
155 | + hdr_actions_entry *f = | |
156 | + (hdr_actions_entry *)ap_push_array(psf->freshen_date); | |
157 | + /* set action */ | |
158 | + if (strcasecmp(one, "Off") == 0) | |
159 | + f->action = hdr_off; | |
160 | + else if (strcasecmp(one, "On") == 0) | |
161 | + f->action = hdr_on; | |
162 | + else | |
163 | + return "CacheFreshenDate must be either On or Off"; | |
164 | + /* set pattern (null is okay, will be dealt with at match time) */ | |
165 | + if (two) { | |
166 | + f->pattern = ap_pregcomp(parms->pool,two,REG_EXTENDED|REG_NOSUB); | |
167 | + if (f->pattern == NULL) | |
168 | + return ap_psprintf | |
169 | + (parms->pool,"Regular expression could not be compiled: %s", two); | |
170 | + } else { | |
171 | + f->pattern = NULL; | |
172 | + } | |
173 | + return NULL; | |
174 | +} | |
175 | + | |
176 | +static const char* | |
177 | + set_resp_exp_vector(cmd_parms *parms, void *mconfig, char *one, char *two) | |
178 | +{ | |
179 | + proxy_server_conf *psf = | |
180 | + ap_get_module_config(parms->server->module_config, &proxy_module); | |
181 | + resp_exp_vector_entry *rev = | |
182 | + (resp_exp_vector_entry *)ap_push_array(psf->resp_exp_vector); | |
183 | + int i = atoi(one); | |
184 | + /* set seconds number */ | |
185 | + if (i < -1) | |
186 | + return "ProxyResponseExpiresVector must be a number of seconds (0 for \"immediately), or -1 to explicitly disable\""; | |
187 | + rev->vector = i; | |
188 | + /* set pattern (again, null is okay) */ | |
189 | + if (two) { | |
190 | + rev->pattern = ap_pregcomp(parms->pool,two,REG_EXTENDED|REG_NOSUB); | |
191 | + if (rev->pattern == NULL) | |
192 | + return ap_psprintf | |
193 | + (parms->pool,"Regular expression could not be compiled: %s", two); | |
194 | + } else { | |
195 | + rev->pattern = NULL; | |
196 | + } | |
197 | + return NULL; | |
198 | +} | |
199 | + | |
200 | +static const char* | |
201 | + set_header_directive(cmd_parms *parms, void *mconfig, const char *args) | |
202 | +{ | |
203 | + char *one = ap_getword_conf(parms->pool,&args); | |
204 | + char *two = ap_getword_conf(parms->pool,&args); | |
205 | + char *three = ap_getword_conf(parms->pool,&args); | |
206 | + char *four = ap_getword_conf(parms->pool,&args); | |
207 | + proxy_server_conf *psf = | |
208 | + ap_get_module_config(parms->server->module_config, &proxy_module); | |
209 | + hdr_actions_entry *h; | |
210 | + /* push onto the correct array */ | |
211 | + if (strcmp("ProxyRequestHeader",(char*)parms->info) == 0) | |
212 | + h = (hdr_actions_entry *)ap_push_array(psf->req_headers); | |
213 | + else | |
214 | + h = (hdr_actions_entry *)ap_push_array(psf->resp_headers); | |
215 | + /* set action */ | |
216 | + if (strcasecmp(one,"set") == 0) | |
217 | + h->action = hdr_set; | |
218 | + else if (strcasecmp(one,"unset") == 0) | |
219 | + h->action = hdr_unset; | |
220 | + else if (strcasecmp(one,"add") == 0) | |
221 | + h->action = hdr_add; | |
222 | + else if (strcasecmp(one,"append") == 0) | |
223 | + h->action = hdr_append; | |
224 | + else | |
225 | + return ap_psprintf | |
226 | + (parms->pool, "Argument to %s must be one of set | unset | add | append", | |
227 | + (char*)parms->info); | |
228 | + /* set which header */ | |
229 | + h->header = ap_pstrdup(parms->pool,two); | |
230 | + /* unset only takes 2/3 arguments -- so set its pattern and return */ | |
231 | + if (h->action == hdr_unset) { | |
232 | + if (strcmp(three,"")!=0) { | |
233 | + h->pattern = ap_pregcomp(parms->pool,three,REG_EXTENDED|REG_NOSUB); | |
234 | + if (h->pattern == NULL) | |
235 | + return ap_psprintf | |
236 | + (parms->pool,"Regular expression could not be compiled: %s", three); | |
237 | + } else { | |
238 | + h->pattern = NULL; | |
239 | + } | |
240 | + if (!strcmp(four,"")==0) | |
241 | + return ap_psprintf | |
242 | + (parms->pool,"%s 'unset' only takes two or three arguments", | |
243 | + (char*)parms->info); | |
244 | + return NULL; | |
245 | + } | |
246 | + /* set value string */ | |
247 | + if (strcmp(three,"")==0) | |
248 | + return ap_psprintf | |
249 | + (parms->pool,"%s requires at least three arguments", (char*)parms->info); | |
250 | + h->value = ap_pstrdup(parms->pool,three); | |
251 | + /* set pattern */ | |
252 | + if (strcmp(four,"")!=0) { | |
253 | + h->pattern = ap_pregcomp(parms->pool,four,REG_EXTENDED|REG_NOSUB); | |
254 | + if (h->pattern == NULL) | |
255 | + return ap_psprintf | |
256 | + (parms->pool,"Regular expression could not be compiled: %s", four); | |
257 | + } else { | |
258 | + h->pattern = NULL; | |
259 | + } | |
260 | + | |
261 | + return NULL; | |
262 | +} | |
263 | + | |
264 | static const handler_rec proxy_handlers[] = | |
265 | { | |
266 | {"proxy-server", proxy_handler}, | |
267 | @@ -970,6 +1166,16 @@ | |
268 | "Force a http cache completion after this percentage is loaded"}, | |
269 | {"ProxyVia", set_via_opt, NULL, RSRC_CONF, TAKE1, | |
270 | "Configure Via: proxy header header to one of: on | off | block | full"}, | |
271 | + {"CacheFreshenDate", set_freshen_date, NULL, RSRC_CONF, TAKE12, | |
272 | + "Whether to update the Date header when returning cached proxy responses"}, | |
273 | + {"ProxyResponseExpiresVector", set_resp_exp_vector, NULL, RSRC_CONF, TAKE12, | |
274 | + "A constant to add to current time for expires headers on proxy response"}, | |
275 | + {"ProxyRequestHeader", set_header_directive, (void*)"ProxyRequestHeader", | |
276 | + RSRC_CONF,RAW_ARGS, | |
277 | + "A directive for headers to be sent with proxy requests"}, | |
278 | + {"ProxyResponseHeader", set_header_directive, (void*)"ProxyResponseHeader", | |
279 | + RSRC_CONF,RAW_ARGS, | |
280 | + "A directive for headers that are returned with responses"}, | |
281 | {NULL} | |
282 | }; | |
283 | ||
284 | @@ -994,4 +1200,10 @@ | |
285 | NULL, /* child_init */ | |
286 | NULL, /* child_exit */ | |
287 | proxy_detect /* post read-request */ | |
288 | +#ifdef EAPI | |
289 | + ,proxy_addmod, /* EAPI: add_module */ | |
290 | + proxy_remmod, /* EAPI: remove_module */ | |
291 | + NULL, /* EAPI: rewrite_command */ | |
292 | + NULL /* EAPI: new_connection */ | |
293 | +#endif | |
294 | }; | |
295 | diff -u apache_1.3.26/src/modules/proxy/mod_proxy.h apache_1.3.26-patched/src/modules/proxy/mod_proxy.h | |
296 | --- apache_1.3.26/src/modules/proxy/mod_proxy.h Sun Apr 21 07:35:07 2002 | |
297 | +++ apache_1.3.26-patched/src/modules/proxy/mod_proxy.h Sun Jun 23 18:36:11 2002 | |
298 | @@ -145,6 +145,23 @@ | |
299 | struct in_addr addr; | |
300 | }; | |
301 | ||
302 | +/* for configurable headers */ | |
303 | +typedef enum { | |
304 | + hdr_on, hdr_off, hdr_set, hdr_unset, hdr_add, hdr_append | |
305 | +} hdr_actions; | |
306 | + | |
307 | +typedef struct { | |
308 | + hdr_actions action; | |
309 | + char *header; | |
310 | + char *value; | |
311 | + regex_t *pattern; | |
312 | +} hdr_actions_entry; | |
313 | + | |
314 | +typedef struct { | |
315 | + int vector; | |
316 | + regex_t *pattern; | |
317 | +} resp_exp_vector_entry; | |
318 | + | |
319 | #define DEFAULT_CACHE_SPACE 5 | |
320 | #define DEFAULT_CACHE_MAXEXPIRE SEC_ONE_DAY | |
321 | #define DEFAULT_CACHE_EXPIRE SEC_ONE_HR | |
322 | @@ -203,6 +220,10 @@ | |
323 | char recv_buffer_size_set; | |
324 | size_t io_buffer_size; | |
325 | char io_buffer_size_set; | |
326 | + array_header *freshen_date; | |
327 | + array_header *resp_exp_vector; | |
328 | + array_header *req_headers; | |
329 | + array_header *resp_headers; | |
330 | } proxy_server_conf; | |
331 | ||
332 | struct hdr_entry { | |
333 | @@ -299,6 +320,10 @@ | |
334 | table *ap_proxy_read_headers(request_rec *r, char *buffer, int size, BUFF *f); | |
335 | long int ap_proxy_send_fb(BUFF *f, request_rec *r, cache_req *c, off_t len, int nowrite, int chunked, size_t recv_buffer_size); | |
336 | void ap_proxy_write_headers(cache_req *c, const char *respline, table *t); | |
337 | +void ap_proxy_freshen_date(request_rec *r, proxy_server_conf *psf, table* t); | |
338 | +void ap_proxy_vectored_exp(request_rec *r, proxy_server_conf *psf, table* t); | |
339 | +void ap_proxy_header_fixup(request_rec *r, proxy_server_conf *psf, table* t, | |
340 | + array_header *directives); | |
341 | int ap_proxy_liststr(const char *list, const char *key, char **val); | |
342 | void ap_proxy_hash(const char *it, char *val, int ndepth, int nlength); | |
343 | int ap_proxy_hex2sec(const char *x); | |
344 | diff -u apache_1.3.26/src/modules/proxy/proxy_cache.c apache_1.3.26-patched/src/modules/proxy/proxy_cache.c | |
345 | --- apache_1.3.26/src/modules/proxy/proxy_cache.c Mon Jun 3 08:28:27 2002 | |
346 | +++ apache_1.3.26-patched/src/modules/proxy/proxy_cache.c Sun Jun 23 19:59:20 2002 | |
347 | @@ -747,6 +747,8 @@ | |
348 | int ap_proxy_cache_conditional(request_rec *r, cache_req *c, BUFF *cachefp) | |
349 | { | |
350 | const char *etag, *wetag = NULL; | |
351 | + proxy_server_conf *psf = (proxy_server_conf *) | |
352 | + ap_get_module_config(r->server->module_config,&proxy_module); | |
353 | ||
354 | /* get etag */ | |
355 | if ((etag = ap_table_get(c->hdrs, "Etag"))) { | |
356 | @@ -905,6 +907,11 @@ | |
357 | /* content type is already set in the headers */ | |
358 | r->content_type = ap_table_get(r->headers_out, "Content-Type"); | |
359 | ||
360 | + /* handle the cases where we need to modify the date and expires | |
361 | + outgoing headers */ | |
362 | + ap_proxy_freshen_date(r,psf,r->headers_out); | |
363 | + ap_proxy_vectored_exp(r,psf,r->headers_out); | |
364 | + | |
365 | ap_send_http_header(r); | |
366 | ||
367 | /* are we rewriting the cache file? */ | |
368 | diff -u apache_1.3.26/src/modules/proxy/proxy_http.c apache_1.3.26-patched/src/modules/proxy/proxy_http.c | |
369 | --- apache_1.3.26/src/modules/proxy/proxy_http.c Mon Jun 17 20:59:59 2002 | |
370 | +++ apache_1.3.26-patched/src/modules/proxy/proxy_http.c Sun Jun 23 20:14:14 2002 | |
371 | @@ -170,6 +170,9 @@ | |
372 | const char *datestr, *urlstr; | |
373 | int result, major, minor; | |
374 | const char *content_length; | |
375 | +#ifdef EAPI | |
376 | + char *peer; | |
377 | +#endif | |
378 | ||
379 | void *sconf = r->server->module_config; | |
380 | proxy_server_conf *conf = | |
381 | @@ -191,6 +194,12 @@ | |
382 | return HTTP_BAD_REQUEST; | |
383 | urlptr += 3; | |
384 | destport = DEFAULT_HTTP_PORT; | |
385 | +#ifdef EAPI | |
386 | + ap_hook_use("ap::mod_proxy::http::handler::set_destport", | |
387 | + AP_HOOK_SIG2(int,ptr), | |
388 | + AP_HOOK_TOPMOST, | |
389 | + &destport, r); | |
390 | +#endif /* EAPI */ | |
391 | strp = strchr(urlptr, '/'); | |
392 | if (strp == NULL) { | |
393 | desthost = ap_pstrdup(p, urlptr); | |
394 | @@ -228,12 +237,18 @@ | |
395 | err = ap_proxy_host2addr(proxyhost, &server_hp); | |
396 | if (err != NULL) | |
397 | return DECLINED; /* try another */ | |
398 | +#ifdef EAPI | |
399 | + peer = ap_psprintf(p, "%s:%u", proxyhost, proxyport); | |
400 | +#endif | |
401 | } | |
402 | else { | |
403 | server.sin_port = htons((unsigned short)destport); | |
404 | err = ap_proxy_host2addr(desthost, &server_hp); | |
405 | if (err != NULL) | |
406 | return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, err); | |
407 | +#ifdef EAPI | |
408 | + peer = ap_psprintf(p, "%s:%u", desthost, destport); | |
409 | +#endif | |
410 | } | |
411 | ||
412 | ||
413 | @@ -308,14 +323,45 @@ | |
414 | f = ap_bcreate(p, B_RDWR | B_SOCKET); | |
415 | ap_bpushfd(f, sock, sock); | |
416 | ||
417 | +#ifdef EAPI | |
418 | + { | |
419 | + char *errmsg = NULL; | |
420 | + ap_hook_use("ap::mod_proxy::http::handler::new_connection", | |
421 | + AP_HOOK_SIG4(ptr,ptr,ptr,ptr), | |
422 | + AP_HOOK_DECLINE(NULL), | |
423 | + &errmsg, r, f, peer); | |
424 | + if (errmsg != NULL) | |
425 | + return ap_proxyerror(r, HTTP_BAD_GATEWAY, errmsg); | |
426 | + } | |
427 | +#endif /* EAPI */ | |
428 | + | |
429 | ap_hard_timeout("proxy send", r); | |
430 | ap_bvputs(f, r->method, " ", proxyhost ? url : urlptr, " HTTP/1.1" CRLF, | |
431 | NULL); | |
432 | +#ifdef EAPI | |
433 | + { | |
434 | + int rc = DECLINED; | |
435 | + ap_hook_use("ap::mod_proxy::http::handler::write_host_header", | |
436 | + AP_HOOK_SIG6(int,ptr,ptr,ptr,int,ptr), | |
437 | + AP_HOOK_DECLINE(DECLINED), | |
438 | + &rc, r, f, desthost, destport, destportstr); | |
439 | + if (rc == DECLINED) { | |
440 | + if (destportstr != NULL && destport != DEFAULT_HTTP_PORT) | |
441 | + ap_bvputs(f, "Host: ", desthost, ":", destportstr, CRLF, NULL); | |
442 | + else | |
443 | + ap_bvputs(f, "Host: ", desthost, CRLF, NULL); | |
444 | + } | |
445 | + } | |
446 | +#else /* EAPI */ | |
447 | /* Send Host: now, adding it to req_hdrs wouldn't be much better */ | |
448 | if (destportstr != NULL && destport != DEFAULT_HTTP_PORT) | |
449 | ap_bvputs(f, "Host: ", desthost, ":", destportstr, CRLF, NULL); | |
450 | else | |
451 | ap_bvputs(f, "Host: ", desthost, CRLF, NULL); | |
452 | +#endif /* EAPI */ | |
453 | + | |
454 | + /* run fixup for the request header directives */ | |
455 | + ap_proxy_header_fixup(r,conf,req_hdrs,conf->req_headers); | |
456 | ||
457 | if (conf->viaopt == via_block) { | |
458 | /* Block all outgoing Via: headers */ | |
459 | diff -u apache_1.3.26/src/modules/proxy/proxy_util.c apache_1.3.26-patched/src/modules/proxy/proxy_util.c | |
460 | --- apache_1.3.26/src/modules/proxy/proxy_util.c Mon Jun 17 20:59:59 2002 | |
461 | +++ apache_1.3.26-patched/src/modules/proxy/proxy_util.c Sun Jun 23 20:03:54 2002 | |
462 | @@ -712,7 +712,10 @@ | |
463 | */ | |
464 | void ap_proxy_write_headers(cache_req *c, const char *respline, table *t) | |
465 | { | |
466 | - /* write status line */ | |
467 | + proxy_server_conf *psf = (proxy_server_conf *) | |
468 | + ap_get_module_config(c->req->server->module_config,&proxy_module); | |
469 | + | |
470 | + /* write status line */ | |
471 | if (respline && c->fp != NULL && | |
472 | ap_bvputs(c->fp, respline, CRLF, NULL) == -1) { | |
473 | ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req, | |
474 | @@ -721,6 +724,17 @@ | |
475 | return; | |
476 | } | |
477 | ||
478 | + /* Set extra response headers. We can set whatever we want here | |
479 | + * (including Expires and family) because we've already written | |
480 | + * the hex header line for the cache file. But the rest of the | |
481 | + * cache file, including the HTTP headers, will include whatever | |
482 | + * we adjust here. This is good, in general, but it does mean we | |
483 | + * have to adjust any running-vector Expires headers in the | |
484 | + * ap_proxy_send_headers, so even cached files get nice clean | |
485 | + * headers with times set correctly in the future. */ | |
486 | + ap_proxy_vectored_exp(c->req,psf,t); | |
487 | + ap_proxy_header_fixup(c->req,psf,t,psf->resp_headers); | |
488 | + | |
489 | /* write response headers to the cache file */ | |
490 | ap_table_do(ap_proxy_send_hdr_line, c, t, NULL); | |
491 | ||
492 | @@ -732,6 +746,77 @@ | |
493 | } | |
494 | } | |
495 | ||
496 | +void ap_proxy_freshen_date(request_rec *r, proxy_server_conf *psf, table* t) | |
497 | +{ | |
498 | + int i; | |
499 | + hdr_actions_entry *list = (hdr_actions_entry*)psf->freshen_date->elts; | |
500 | + for(i=0; i < psf->freshen_date->nelts; i++) { | |
501 | + if(((list+i)->pattern == NULL) || | |
502 | + (regexec((list+i)->pattern,r->uri,0,NULL,0) != REG_NOMATCH)) { | |
503 | + if ((list+i)->action == hdr_on) { | |
504 | + ap_table_set(t, "Date", | |
505 | + ap_ht_time(r->pool, time(NULL), "%a %d %b %Y %T %Z", 1)); | |
506 | + } | |
507 | + return; | |
508 | + } | |
509 | + } | |
510 | +} | |
511 | + | |
512 | +/* see whether there are ProxyVectoredExpire directives to apply to | |
513 | + this request. (Don't do anything unless there is already an Expires | |
514 | + header here.) */ | |
515 | +void ap_proxy_vectored_exp(request_rec *r, proxy_server_conf *psf, table* t) | |
516 | +{ | |
517 | + int i; | |
518 | + resp_exp_vector_entry *list; | |
519 | + /* don't do anything to a doc that doesn't *already* have an Expires */ | |
520 | + if (! ap_table_get(t,"Expires")) return; | |
521 | + /* okay, loop through directives */ | |
522 | + list = (resp_exp_vector_entry*)psf->resp_exp_vector->elts; | |
523 | + for(i=0; i < psf->resp_exp_vector->nelts; i++) { | |
524 | + if(((list+i)->pattern == NULL) || | |
525 | + (regexec((list+i)->pattern,r->uri,0,NULL,0) != REG_NOMATCH)) { | |
526 | + if ((list+i)->vector == -1) { | |
527 | + } else if ((list+i)->vector == 0) { | |
528 | + ap_table_setn(t, "Expires", "0"); | |
529 | + ap_table_setn(t, "Cache-Control", "max-age=0"); | |
530 | + } else { | |
531 | + ap_table_set(t, "Expires", | |
532 | + ap_ht_time(r->pool, time(NULL)+(list+i)->vector, | |
533 | + "%a %d %b %Y %T %Z", 1)); | |
534 | + ap_table_set(t, "Cache-Control", | |
535 | + ap_psprintf(r->pool,"max-age=%d",(list+i)->vector)); | |
536 | + } | |
537 | + return; | |
538 | + } | |
539 | + } | |
540 | +} | |
541 | + | |
542 | +void ap_proxy_header_fixup(request_rec *r, proxy_server_conf *psf, | |
543 | + table *t, array_header *directives) | |
544 | +{ | |
545 | + int i; | |
546 | + hdr_actions_entry *list = (hdr_actions_entry *)directives->elts; | |
547 | + for (i=0; i < directives->nelts; i++) { | |
548 | + if(((list+i)->pattern == NULL) || | |
549 | + (regexec((list+i)->pattern,r->uri,0,NULL,0) != REG_NOMATCH)) { | |
550 | + switch ((list+i)->action) { | |
551 | + case hdr_set: | |
552 | + ap_table_setn(t,(list+i)->header,(list+i)->value); | |
553 | + break; | |
554 | + case hdr_unset: | |
555 | + ap_table_unset(t,(list+i)->header); | |
556 | + break; | |
557 | + case hdr_add: | |
558 | + ap_table_addn(t,(list+i)->header,(list+i)->value); | |
559 | + break; | |
560 | + case hdr_append: | |
561 | + ap_table_mergen(t,(list+i)->header,(list+i)->value); | |
562 | + break; | |
563 | + } | |
564 | + } | |
565 | + } | |
566 | +} | |
567 | ||
568 | /* | |
569 | * list is a comma-separated list of case-insensitive tokens, with |