]>
Commit | Line | Data |
---|---|---|
11efc153 | 1 | --- apache_1.3.26/src/modules/proxy/mod_proxy.c Mon Jun 17 20:59:59 2002 |
2 | +++ apache_1.3.26-patched/src/modules/proxy/mod_proxy.c Sun Jun 23 19:25:57 2002 | |
3 | @@ -460,6 +525,11 @@ | |
4 | ps->cache.dirlength_set = 0; | |
5 | ps->cache.cache_completion = (float)DEFAULT_CACHE_COMPLETION; | |
6 | ps->cache.cache_completion_set = 0; | |
7 | + /* header manipulation */ | |
8 | + ps->freshen_date = ap_make_array(p, 10, sizeof(hdr_actions_entry)); | |
9 | + ps->resp_exp_vector = ap_make_array(p, 10, sizeof(resp_exp_vector_entry)); | |
10 | + ps->req_headers = ap_make_array(p, 10, sizeof(hdr_actions_entry)); | |
11 | + ps->resp_headers = ap_make_array(p, 10, sizeof(hdr_actions_entry)); | |
12 | ||
13 | return ps; | |
14 | } | |
15 | @@ -496,6 +566,18 @@ | |
16 | ps->cache.dirlevels = (overrides->cache.dirlevels_set == 0) ? base->cache.dirlevels : overrides->cache.dirlevels; | |
17 | ps->cache.dirlength = (overrides->cache.dirlength_set == 0) ? base->cache.dirlength : overrides->cache.dirlength; | |
18 | ps->cache.cache_completion = (overrides->cache.cache_completion_set == 0) ? base->cache.cache_completion : overrides->cache.cache_completion; | |
19 | + /* put freshen_date and resp_exp_vector from the overriding config | |
20 | + in front of the base config arrays, the semantics being that | |
21 | + virtual server configs should be checked first */ | |
22 | + ps->freshen_date = ap_append_arrays(p,overrides->freshen_date,base->freshen_date); | |
23 | + ps->resp_exp_vector = ap_append_arrays(p,overrides->resp_exp_vector,base->resp_exp_vector); | |
24 | + /* add req_ and resp_headers from the overriding config after | |
25 | + those from the base config arrays, the semantics being that the | |
26 | + directives are applied in declaration order, with those | |
27 | + specific to a virtual server coming after and therefore | |
28 | + overriding those from the root config */ | |
29 | + ps->req_headers = ap_append_arrays(p,base->req_headers,overrides->req_headers); | |
30 | + ps->resp_headers = ap_append_arrays(p,base->resp_headers,overrides->resp_headers); | |
31 | ||
32 | return ps; | |
33 | } | |
34 | @@ -920,6 +1002,120 @@ | |
35 | return NULL; | |
36 | } | |
37 | ||
38 | +static const char* | |
39 | + set_freshen_date(cmd_parms *parms, void *mconfig, char *one, char *two) | |
40 | +{ | |
41 | + proxy_server_conf *psf = | |
42 | + ap_get_module_config(parms->server->module_config, &proxy_module); | |
43 | + hdr_actions_entry *f = | |
44 | + (hdr_actions_entry *)ap_push_array(psf->freshen_date); | |
45 | + /* set action */ | |
46 | + if (strcasecmp(one, "Off") == 0) | |
47 | + f->action = hdr_off; | |
48 | + else if (strcasecmp(one, "On") == 0) | |
49 | + f->action = hdr_on; | |
50 | + else | |
51 | + return "CacheFreshenDate must be either On or Off"; | |
52 | + /* set pattern (null is okay, will be dealt with at match time) */ | |
53 | + if (two) { | |
54 | + f->pattern = ap_pregcomp(parms->pool,two,REG_EXTENDED|REG_NOSUB); | |
55 | + if (f->pattern == NULL) | |
56 | + return ap_psprintf | |
57 | + (parms->pool,"Regular expression could not be compiled: %s", two); | |
58 | + } else { | |
59 | + f->pattern = NULL; | |
60 | + } | |
61 | + return NULL; | |
62 | +} | |
63 | + | |
64 | +static const char* | |
65 | + set_resp_exp_vector(cmd_parms *parms, void *mconfig, char *one, char *two) | |
66 | +{ | |
67 | + proxy_server_conf *psf = | |
68 | + ap_get_module_config(parms->server->module_config, &proxy_module); | |
69 | + resp_exp_vector_entry *rev = | |
70 | + (resp_exp_vector_entry *)ap_push_array(psf->resp_exp_vector); | |
71 | + int i = atoi(one); | |
72 | + /* set seconds number */ | |
73 | + if (i < -1) | |
74 | + return "ProxyResponseExpiresVector must be a number of seconds (0 for \"immediately), or -1 to explicitly disable\""; | |
75 | + rev->vector = i; | |
76 | + /* set pattern (again, null is okay) */ | |
77 | + if (two) { | |
78 | + rev->pattern = ap_pregcomp(parms->pool,two,REG_EXTENDED|REG_NOSUB); | |
79 | + if (rev->pattern == NULL) | |
80 | + return ap_psprintf | |
81 | + (parms->pool,"Regular expression could not be compiled: %s", two); | |
82 | + } else { | |
83 | + rev->pattern = NULL; | |
84 | + } | |
85 | + return NULL; | |
86 | +} | |
87 | + | |
88 | +static const char* | |
89 | + set_header_directive(cmd_parms *parms, void *mconfig, const char *args) | |
90 | +{ | |
91 | + char *one = ap_getword_conf(parms->pool,&args); | |
92 | + char *two = ap_getword_conf(parms->pool,&args); | |
93 | + char *three = ap_getword_conf(parms->pool,&args); | |
94 | + char *four = ap_getword_conf(parms->pool,&args); | |
95 | + proxy_server_conf *psf = | |
96 | + ap_get_module_config(parms->server->module_config, &proxy_module); | |
97 | + hdr_actions_entry *h; | |
98 | + /* push onto the correct array */ | |
99 | + if (strcmp("ProxyRequestHeader",(char*)parms->info) == 0) | |
100 | + h = (hdr_actions_entry *)ap_push_array(psf->req_headers); | |
101 | + else | |
102 | + h = (hdr_actions_entry *)ap_push_array(psf->resp_headers); | |
103 | + /* set action */ | |
104 | + if (strcasecmp(one,"set") == 0) | |
105 | + h->action = hdr_set; | |
106 | + else if (strcasecmp(one,"unset") == 0) | |
107 | + h->action = hdr_unset; | |
108 | + else if (strcasecmp(one,"add") == 0) | |
109 | + h->action = hdr_add; | |
110 | + else if (strcasecmp(one,"append") == 0) | |
111 | + h->action = hdr_append; | |
112 | + else | |
113 | + return ap_psprintf | |
114 | + (parms->pool, "Argument to %s must be one of set | unset | add | append", | |
115 | + (char*)parms->info); | |
116 | + /* set which header */ | |
117 | + h->header = ap_pstrdup(parms->pool,two); | |
118 | + /* unset only takes 2/3 arguments -- so set its pattern and return */ | |
119 | + if (h->action == hdr_unset) { | |
120 | + if (strcmp(three,"")!=0) { | |
121 | + h->pattern = ap_pregcomp(parms->pool,three,REG_EXTENDED|REG_NOSUB); | |
122 | + if (h->pattern == NULL) | |
123 | + return ap_psprintf | |
124 | + (parms->pool,"Regular expression could not be compiled: %s", three); | |
125 | + } else { | |
126 | + h->pattern = NULL; | |
127 | + } | |
128 | + if (!strcmp(four,"")==0) | |
129 | + return ap_psprintf | |
130 | + (parms->pool,"%s 'unset' only takes two or three arguments", | |
131 | + (char*)parms->info); | |
132 | + return NULL; | |
133 | + } | |
134 | + /* set value string */ | |
135 | + if (strcmp(three,"")==0) | |
136 | + return ap_psprintf | |
137 | + (parms->pool,"%s requires at least three arguments", (char*)parms->info); | |
138 | + h->value = ap_pstrdup(parms->pool,three); | |
139 | + /* set pattern */ | |
140 | + if (strcmp(four,"")!=0) { | |
141 | + h->pattern = ap_pregcomp(parms->pool,four,REG_EXTENDED|REG_NOSUB); | |
142 | + if (h->pattern == NULL) | |
143 | + return ap_psprintf | |
144 | + (parms->pool,"Regular expression could not be compiled: %s", four); | |
145 | + } else { | |
146 | + h->pattern = NULL; | |
147 | + } | |
148 | + | |
149 | + return NULL; | |
150 | +} | |
151 | + | |
152 | static const handler_rec proxy_handlers[] = | |
153 | { | |
154 | {"proxy-server", proxy_handler}, | |
155 | @@ -970,6 +1166,16 @@ | |
156 | "Force a http cache completion after this percentage is loaded"}, | |
157 | {"ProxyVia", set_via_opt, NULL, RSRC_CONF, TAKE1, | |
158 | "Configure Via: proxy header header to one of: on | off | block | full"}, | |
159 | + {"CacheFreshenDate", set_freshen_date, NULL, RSRC_CONF, TAKE12, | |
160 | + "Whether to update the Date header when returning cached proxy responses"}, | |
161 | + {"ProxyResponseExpiresVector", set_resp_exp_vector, NULL, RSRC_CONF, TAKE12, | |
162 | + "A constant to add to current time for expires headers on proxy response"}, | |
163 | + {"ProxyRequestHeader", set_header_directive, (void*)"ProxyRequestHeader", | |
164 | + RSRC_CONF,RAW_ARGS, | |
165 | + "A directive for headers to be sent with proxy requests"}, | |
166 | + {"ProxyResponseHeader", set_header_directive, (void*)"ProxyResponseHeader", | |
167 | + RSRC_CONF,RAW_ARGS, | |
168 | + "A directive for headers that are returned with responses"}, | |
169 | {NULL} | |
170 | }; | |
171 | ||
172 | --- apache_1.3.26/src/modules/proxy/mod_proxy.h Sun Apr 21 07:35:07 2002 | |
173 | +++ apache_1.3.26-patched/src/modules/proxy/mod_proxy.h Sun Jun 23 18:36:11 2002 | |
174 | @@ -145,6 +145,23 @@ | |
175 | struct in_addr addr; | |
176 | }; | |
177 | ||
178 | +/* for configurable headers */ | |
179 | +typedef enum { | |
180 | + hdr_on, hdr_off, hdr_set, hdr_unset, hdr_add, hdr_append | |
181 | +} hdr_actions; | |
182 | + | |
183 | +typedef struct { | |
184 | + hdr_actions action; | |
185 | + char *header; | |
186 | + char *value; | |
187 | + regex_t *pattern; | |
188 | +} hdr_actions_entry; | |
189 | + | |
190 | +typedef struct { | |
191 | + int vector; | |
192 | + regex_t *pattern; | |
193 | +} resp_exp_vector_entry; | |
194 | + | |
195 | #define DEFAULT_CACHE_SPACE 5 | |
196 | #define DEFAULT_CACHE_MAXEXPIRE SEC_ONE_DAY | |
197 | #define DEFAULT_CACHE_EXPIRE SEC_ONE_HR | |
198 | @@ -203,6 +220,10 @@ | |
199 | char recv_buffer_size_set; | |
200 | size_t io_buffer_size; | |
201 | char io_buffer_size_set; | |
202 | + array_header *freshen_date; | |
203 | + array_header *resp_exp_vector; | |
204 | + array_header *req_headers; | |
205 | + array_header *resp_headers; | |
206 | } proxy_server_conf; | |
207 | ||
208 | struct hdr_entry { | |
209 | @@ -299,6 +320,10 @@ | |
210 | table *ap_proxy_read_headers(request_rec *r, char *buffer, int size, BUFF *f); | |
211 | 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); | |
212 | void ap_proxy_write_headers(cache_req *c, const char *respline, table *t); | |
213 | +void ap_proxy_freshen_date(request_rec *r, proxy_server_conf *psf, table* t); | |
214 | +void ap_proxy_vectored_exp(request_rec *r, proxy_server_conf *psf, table* t); | |
215 | +void ap_proxy_header_fixup(request_rec *r, proxy_server_conf *psf, table* t, | |
216 | + array_header *directives); | |
217 | int ap_proxy_liststr(const char *list, const char *key, char **val); | |
218 | void ap_proxy_hash(const char *it, char *val, int ndepth, int nlength); | |
219 | int ap_proxy_hex2sec(const char *x); | |
220 | diff -u apache_1.3.26/src/modules/proxy/proxy_cache.c apache_1.3.26-patched/src/modules/proxy/proxy_cache.c | |
221 | --- apache_1.3.26/src/modules/proxy/proxy_cache.c Mon Jun 3 08:28:27 2002 | |
222 | +++ apache_1.3.26-patched/src/modules/proxy/proxy_cache.c Sun Jun 23 19:59:20 2002 | |
223 | @@ -747,6 +747,8 @@ | |
224 | int ap_proxy_cache_conditional(request_rec *r, cache_req *c, BUFF *cachefp) | |
225 | { | |
226 | const char *etag, *wetag = NULL; | |
227 | + proxy_server_conf *psf = (proxy_server_conf *) | |
228 | + ap_get_module_config(r->server->module_config,&proxy_module); | |
229 | ||
230 | /* get etag */ | |
231 | if ((etag = ap_table_get(c->hdrs, "Etag"))) { | |
232 | @@ -905,6 +907,11 @@ | |
233 | /* content type is already set in the headers */ | |
234 | r->content_type = ap_table_get(r->headers_out, "Content-Type"); | |
235 | ||
236 | + /* handle the cases where we need to modify the date and expires | |
237 | + outgoing headers */ | |
238 | + ap_proxy_freshen_date(r,psf,r->headers_out); | |
239 | + ap_proxy_vectored_exp(r,psf,r->headers_out); | |
240 | + | |
241 | ap_send_http_header(r); | |
242 | ||
243 | /* are we rewriting the cache file? */ | |
244 | --- apache_1.3.26/src/modules/proxy/proxy_http.c Mon Jun 17 20:59:59 2002 | |
245 | +++ apache_1.3.26-patched/src/modules/proxy/proxy_http.c Sun Jun 23 20:14:14 2002 | |
246 | @@ -317,6 +317,9 @@ | |
247 | else | |
248 | ap_bvputs(f, "Host: ", desthost, CRLF, NULL); | |
249 | #endif /* EAPI */ | |
250 | + | |
251 | + /* run fixup for the request header directives */ | |
252 | + ap_proxy_header_fixup(r,conf,req_hdrs,conf->req_headers); | |
253 | ||
254 | if (conf->viaopt == via_block) { | |
255 | /* Block all outgoing Via: headers */ | |
256 | --- apache_1.3.26/src/modules/proxy/proxy_util.c Mon Jun 17 20:59:59 2002 | |
257 | +++ apache_1.3.26-patched/src/modules/proxy/proxy_util.c Sun Jun 23 20:03:54 2002 | |
258 | @@ -712,7 +712,10 @@ | |
259 | */ | |
260 | void ap_proxy_write_headers(cache_req *c, const char *respline, table *t) | |
261 | { | |
262 | - /* write status line */ | |
263 | + proxy_server_conf *psf = (proxy_server_conf *) | |
264 | + ap_get_module_config(c->req->server->module_config,&proxy_module); | |
265 | + | |
266 | + /* write status line */ | |
267 | if (respline && c->fp != NULL && | |
268 | ap_bvputs(c->fp, respline, CRLF, NULL) == -1) { | |
269 | ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req, | |
270 | @@ -721,6 +724,17 @@ | |
271 | return; | |
272 | } | |
273 | ||
274 | + /* Set extra response headers. We can set whatever we want here | |
275 | + * (including Expires and family) because we've already written | |
276 | + * the hex header line for the cache file. But the rest of the | |
277 | + * cache file, including the HTTP headers, will include whatever | |
278 | + * we adjust here. This is good, in general, but it does mean we | |
279 | + * have to adjust any running-vector Expires headers in the | |
280 | + * ap_proxy_send_headers, so even cached files get nice clean | |
281 | + * headers with times set correctly in the future. */ | |
282 | + ap_proxy_vectored_exp(c->req,psf,t); | |
283 | + ap_proxy_header_fixup(c->req,psf,t,psf->resp_headers); | |
284 | + | |
285 | /* write response headers to the cache file */ | |
286 | ap_table_do(ap_proxy_send_hdr_line, c, t, NULL); | |
287 | ||
288 | @@ -732,6 +746,77 @@ | |
289 | } | |
290 | } | |
291 | ||
292 | +void ap_proxy_freshen_date(request_rec *r, proxy_server_conf *psf, table* t) | |
293 | +{ | |
294 | + int i; | |
295 | + hdr_actions_entry *list = (hdr_actions_entry*)psf->freshen_date->elts; | |
296 | + for(i=0; i < psf->freshen_date->nelts; i++) { | |
297 | + if(((list+i)->pattern == NULL) || | |
298 | + (regexec((list+i)->pattern,r->uri,0,NULL,0) != REG_NOMATCH)) { | |
299 | + if ((list+i)->action == hdr_on) { | |
300 | + ap_table_set(t, "Date", | |
301 | + ap_ht_time(r->pool, time(NULL), "%a %d %b %Y %T %Z", 1)); | |
302 | + } | |
303 | + return; | |
304 | + } | |
305 | + } | |
306 | +} | |
307 | + | |
308 | +/* see whether there are ProxyVectoredExpire directives to apply to | |
309 | + this request. (Don't do anything unless there is already an Expires | |
310 | + header here.) */ | |
311 | +void ap_proxy_vectored_exp(request_rec *r, proxy_server_conf *psf, table* t) | |
312 | +{ | |
313 | + int i; | |
314 | + resp_exp_vector_entry *list; | |
315 | + /* don't do anything to a doc that doesn't *already* have an Expires */ | |
316 | + if (! ap_table_get(t,"Expires")) return; | |
317 | + /* okay, loop through directives */ | |
318 | + list = (resp_exp_vector_entry*)psf->resp_exp_vector->elts; | |
319 | + for(i=0; i < psf->resp_exp_vector->nelts; i++) { | |
320 | + if(((list+i)->pattern == NULL) || | |
321 | + (regexec((list+i)->pattern,r->uri,0,NULL,0) != REG_NOMATCH)) { | |
322 | + if ((list+i)->vector == -1) { | |
323 | + } else if ((list+i)->vector == 0) { | |
324 | + ap_table_setn(t, "Expires", "0"); | |
325 | + ap_table_setn(t, "Cache-Control", "max-age=0"); | |
326 | + } else { | |
327 | + ap_table_set(t, "Expires", | |
328 | + ap_ht_time(r->pool, time(NULL)+(list+i)->vector, | |
329 | + "%a %d %b %Y %T %Z", 1)); | |
330 | + ap_table_set(t, "Cache-Control", | |
331 | + ap_psprintf(r->pool,"max-age=%d",(list+i)->vector)); | |
332 | + } | |
333 | + return; | |
334 | + } | |
335 | + } | |
336 | +} | |
337 | + | |
338 | +void ap_proxy_header_fixup(request_rec *r, proxy_server_conf *psf, | |
339 | + table *t, array_header *directives) | |
340 | +{ | |
341 | + int i; | |
342 | + hdr_actions_entry *list = (hdr_actions_entry *)directives->elts; | |
343 | + for (i=0; i < directives->nelts; i++) { | |
344 | + if(((list+i)->pattern == NULL) || | |
345 | + (regexec((list+i)->pattern,r->uri,0,NULL,0) != REG_NOMATCH)) { | |
346 | + switch ((list+i)->action) { | |
347 | + case hdr_set: | |
348 | + ap_table_setn(t,(list+i)->header,(list+i)->value); | |
349 | + break; | |
350 | + case hdr_unset: | |
351 | + ap_table_unset(t,(list+i)->header); | |
352 | + break; | |
353 | + case hdr_add: | |
354 | + ap_table_addn(t,(list+i)->header,(list+i)->value); | |
355 | + break; | |
356 | + case hdr_append: | |
357 | + ap_table_mergen(t,(list+i)->header,(list+i)->value); | |
358 | + break; | |
359 | + } | |
360 | + } | |
361 | + } | |
362 | +} | |
363 | ||
364 | /* | |
365 | * list is a comma-separated list of case-insensitive tokens, with |