From 16d411b0af4234e8bca3bca70ad86bbb35e466c1 Mon Sep 17 00:00:00 2001 From: marcus Date: Sat, 6 Dec 2003 01:14:27 +0000 Subject: [PATCH] - http://allafrica.com/tools/apache/mod_proxy/mod_proxy-khk_1.3.26-patch.diff Changed files: mod_proxy-khk_1.3.26-patch.diff -> 1.1 --- mod_proxy-khk_1.3.26-patch.diff | 569 ++++++++++++++++++++++++++++++++ 1 file changed, 569 insertions(+) create mode 100644 mod_proxy-khk_1.3.26-patch.diff diff --git a/mod_proxy-khk_1.3.26-patch.diff b/mod_proxy-khk_1.3.26-patch.diff new file mode 100644 index 0000000..d78b996 --- /dev/null +++ b/mod_proxy-khk_1.3.26-patch.diff @@ -0,0 +1,569 @@ +diff -u apache_1.3.26/src/modules/proxy/mod_proxy.c apache_1.3.26-patched/src/modules/proxy/mod_proxy.c +--- apache_1.3.26/src/modules/proxy/mod_proxy.c Mon Jun 17 20:59:59 2002 ++++ apache_1.3.26-patched/src/modules/proxy/mod_proxy.c Sun Jun 23 19:25:57 2002 +@@ -218,6 +218,9 @@ + static int proxy_fixup(request_rec *r) + { + char *url, *p; ++#ifdef EAPI ++ int rc; ++#endif /* EAPI */ + + if (r->proxyreq == NOT_PROXY || strncmp(r->filename, "proxy:", 6) != 0) + return DECLINED; +@@ -225,6 +228,14 @@ + url = &r->filename[6]; + + /* canonicalise each specific scheme */ ++#ifdef EAPI ++ if (ap_hook_use("ap::mod_proxy::canon", ++ AP_HOOK_SIG3(int,ptr,ptr), ++ AP_HOOK_DECLINE(DECLINED), ++ &rc, r, url) && rc != DECLINED) ++ return rc; ++ else ++#endif /* EAPI */ + if (strncasecmp(url, "http:", 5) == 0) + return ap_proxy_http_canon(r, url + 5, "http", DEFAULT_HTTP_PORT); + else if (strncasecmp(url, "ftp:", 4) == 0) +@@ -240,9 +251,44 @@ + static void proxy_init(server_rec *r, pool *p) + { + ap_proxy_garbage_init(r, p); ++#ifdef EAPI ++ ap_hook_use("ap::mod_proxy::init", ++ AP_HOOK_SIG3(void,ptr,ptr), AP_HOOK_ALL, r, p); ++#endif + } + +- ++#ifdef EAPI ++static void proxy_addmod(module *m) ++{ ++ /* export: ap_proxy_http_canon() as `ap::mod_proxy::http::canon' */ ++ ap_hook_configure("ap::mod_proxy::http::canon", ++ AP_HOOK_SIG5(int,ptr,ptr,ptr,int), AP_HOOK_TOPMOST); ++ ap_hook_register("ap::mod_proxy::http::canon", ++ ap_proxy_http_canon, AP_HOOK_NOCTX); ++ ++ /* export: ap_proxy_http_handler() as `ap::mod_proxy::http::handler' */ ++ ap_hook_configure("ap::mod_proxy::http::handler", ++ AP_HOOK_SIG6(int,ptr,ptr,ptr,ptr,int), AP_HOOK_TOPMOST); ++ ap_hook_register("ap::mod_proxy::http::handler", ++ ap_proxy_http_handler, AP_HOOK_NOCTX); ++ ++ /* export: ap_proxyerror() as `ap::mod_proxy::error' */ ++ ap_hook_configure("ap::mod_proxy::error", ++ AP_HOOK_SIG3(int,ptr,ptr), AP_HOOK_TOPMOST); ++ ap_hook_register("ap::mod_proxy::error", ++ ap_proxyerror, AP_HOOK_NOCTX); ++ return; ++} ++ ++static void proxy_remmod(module *m) ++{ ++ /* remove the hook references */ ++ ap_hook_unregister("ap::mod_proxy::http::canon", ap_proxy_http_canon); ++ ap_hook_unregister("ap::mod_proxy::http::handler", ap_proxy_http_handler); ++ ap_hook_unregister("ap::mod_proxy::error", ap_proxyerror); ++ return; ++} ++#endif /* EAPI */ + + /* Send a redirection if the request contains a hostname which is not */ + /* fully qualified, i.e. doesn't have a domain name appended. Some proxy */ +@@ -374,6 +420,14 @@ + * CONNECT is a special method that bypasses the normal proxy + * code. + */ ++#ifdef EAPI ++ if (!ap_hook_use("ap::mod_proxy::handler", ++ AP_HOOK_SIG7(int,ptr,ptr,ptr,ptr,int,ptr), ++ AP_HOOK_DECLINE(DECLINED), ++ &rc, r, cr, url, ++ ents[i].hostname, ents[i].port, ++ ents[i].protocol) || rc == DECLINED) { ++#endif /* EAPI */ + if (r->method_number == M_CONNECT) + rc = ap_proxy_connect_handler(r, cr, url, ents[i].hostname, + ents[i].port); +@@ -383,6 +437,9 @@ + ents[i].port); + else + rc = DECLINED; ++#ifdef EAPI ++ } ++#endif /* EAPI */ + + /* an error or success */ + if (rc != DECLINED && rc != HTTP_BAD_GATEWAY) +@@ -397,6 +454,14 @@ + */ + + /* handle the scheme */ ++#ifdef EAPI ++ if (ap_hook_use("ap::mod_proxy::handler", ++ AP_HOOK_SIG7(int,ptr,ptr,ptr,ptr,int,ptr), ++ AP_HOOK_DECLINE(DECLINED), ++ &rc, r, cr, url, ++ NULL, 0, scheme) && rc != DECLINED) ++ return rc; ++#endif /* EAPI */ + if (r->method_number == M_CONNECT) { + return ap_proxy_connect_handler(r, cr, url, NULL, 0); + } +@@ -460,6 +525,11 @@ + ps->cache.dirlength_set = 0; + ps->cache.cache_completion = (float)DEFAULT_CACHE_COMPLETION; + ps->cache.cache_completion_set = 0; ++ /* header manipulation */ ++ ps->freshen_date = ap_make_array(p, 10, sizeof(hdr_actions_entry)); ++ ps->resp_exp_vector = ap_make_array(p, 10, sizeof(resp_exp_vector_entry)); ++ ps->req_headers = ap_make_array(p, 10, sizeof(hdr_actions_entry)); ++ ps->resp_headers = ap_make_array(p, 10, sizeof(hdr_actions_entry)); + + return ps; + } +@@ -496,6 +566,18 @@ + ps->cache.dirlevels = (overrides->cache.dirlevels_set == 0) ? base->cache.dirlevels : overrides->cache.dirlevels; + ps->cache.dirlength = (overrides->cache.dirlength_set == 0) ? base->cache.dirlength : overrides->cache.dirlength; + ps->cache.cache_completion = (overrides->cache.cache_completion_set == 0) ? base->cache.cache_completion : overrides->cache.cache_completion; ++ /* put freshen_date and resp_exp_vector from the overriding config ++ in front of the base config arrays, the semantics being that ++ virtual server configs should be checked first */ ++ ps->freshen_date = ap_append_arrays(p,overrides->freshen_date,base->freshen_date); ++ ps->resp_exp_vector = ap_append_arrays(p,overrides->resp_exp_vector,base->resp_exp_vector); ++ /* add req_ and resp_headers from the overriding config after ++ those from the base config arrays, the semantics being that the ++ directives are applied in declaration order, with those ++ specific to a virtual server coming after and therefore ++ overriding those from the root config */ ++ ps->req_headers = ap_append_arrays(p,base->req_headers,overrides->req_headers); ++ ps->resp_headers = ap_append_arrays(p,base->resp_headers,overrides->resp_headers); + + return ps; + } +@@ -920,6 +1002,120 @@ + return NULL; + } + ++static const char* ++ set_freshen_date(cmd_parms *parms, void *mconfig, char *one, char *two) ++{ ++ proxy_server_conf *psf = ++ ap_get_module_config(parms->server->module_config, &proxy_module); ++ hdr_actions_entry *f = ++ (hdr_actions_entry *)ap_push_array(psf->freshen_date); ++ /* set action */ ++ if (strcasecmp(one, "Off") == 0) ++ f->action = hdr_off; ++ else if (strcasecmp(one, "On") == 0) ++ f->action = hdr_on; ++ else ++ return "CacheFreshenDate must be either On or Off"; ++ /* set pattern (null is okay, will be dealt with at match time) */ ++ if (two) { ++ f->pattern = ap_pregcomp(parms->pool,two,REG_EXTENDED|REG_NOSUB); ++ if (f->pattern == NULL) ++ return ap_psprintf ++ (parms->pool,"Regular expression could not be compiled: %s", two); ++ } else { ++ f->pattern = NULL; ++ } ++ return NULL; ++} ++ ++static const char* ++ set_resp_exp_vector(cmd_parms *parms, void *mconfig, char *one, char *two) ++{ ++ proxy_server_conf *psf = ++ ap_get_module_config(parms->server->module_config, &proxy_module); ++ resp_exp_vector_entry *rev = ++ (resp_exp_vector_entry *)ap_push_array(psf->resp_exp_vector); ++ int i = atoi(one); ++ /* set seconds number */ ++ if (i < -1) ++ return "ProxyResponseExpiresVector must be a number of seconds (0 for \"immediately), or -1 to explicitly disable\""; ++ rev->vector = i; ++ /* set pattern (again, null is okay) */ ++ if (two) { ++ rev->pattern = ap_pregcomp(parms->pool,two,REG_EXTENDED|REG_NOSUB); ++ if (rev->pattern == NULL) ++ return ap_psprintf ++ (parms->pool,"Regular expression could not be compiled: %s", two); ++ } else { ++ rev->pattern = NULL; ++ } ++ return NULL; ++} ++ ++static const char* ++ set_header_directive(cmd_parms *parms, void *mconfig, const char *args) ++{ ++ char *one = ap_getword_conf(parms->pool,&args); ++ char *two = ap_getword_conf(parms->pool,&args); ++ char *three = ap_getword_conf(parms->pool,&args); ++ char *four = ap_getword_conf(parms->pool,&args); ++ proxy_server_conf *psf = ++ ap_get_module_config(parms->server->module_config, &proxy_module); ++ hdr_actions_entry *h; ++ /* push onto the correct array */ ++ if (strcmp("ProxyRequestHeader",(char*)parms->info) == 0) ++ h = (hdr_actions_entry *)ap_push_array(psf->req_headers); ++ else ++ h = (hdr_actions_entry *)ap_push_array(psf->resp_headers); ++ /* set action */ ++ if (strcasecmp(one,"set") == 0) ++ h->action = hdr_set; ++ else if (strcasecmp(one,"unset") == 0) ++ h->action = hdr_unset; ++ else if (strcasecmp(one,"add") == 0) ++ h->action = hdr_add; ++ else if (strcasecmp(one,"append") == 0) ++ h->action = hdr_append; ++ else ++ return ap_psprintf ++ (parms->pool, "Argument to %s must be one of set | unset | add | append", ++ (char*)parms->info); ++ /* set which header */ ++ h->header = ap_pstrdup(parms->pool,two); ++ /* unset only takes 2/3 arguments -- so set its pattern and return */ ++ if (h->action == hdr_unset) { ++ if (strcmp(three,"")!=0) { ++ h->pattern = ap_pregcomp(parms->pool,three,REG_EXTENDED|REG_NOSUB); ++ if (h->pattern == NULL) ++ return ap_psprintf ++ (parms->pool,"Regular expression could not be compiled: %s", three); ++ } else { ++ h->pattern = NULL; ++ } ++ if (!strcmp(four,"")==0) ++ return ap_psprintf ++ (parms->pool,"%s 'unset' only takes two or three arguments", ++ (char*)parms->info); ++ return NULL; ++ } ++ /* set value string */ ++ if (strcmp(three,"")==0) ++ return ap_psprintf ++ (parms->pool,"%s requires at least three arguments", (char*)parms->info); ++ h->value = ap_pstrdup(parms->pool,three); ++ /* set pattern */ ++ if (strcmp(four,"")!=0) { ++ h->pattern = ap_pregcomp(parms->pool,four,REG_EXTENDED|REG_NOSUB); ++ if (h->pattern == NULL) ++ return ap_psprintf ++ (parms->pool,"Regular expression could not be compiled: %s", four); ++ } else { ++ h->pattern = NULL; ++ } ++ ++ return NULL; ++} ++ + static const handler_rec proxy_handlers[] = + { + {"proxy-server", proxy_handler}, +@@ -970,6 +1166,16 @@ + "Force a http cache completion after this percentage is loaded"}, + {"ProxyVia", set_via_opt, NULL, RSRC_CONF, TAKE1, + "Configure Via: proxy header header to one of: on | off | block | full"}, ++ {"CacheFreshenDate", set_freshen_date, NULL, RSRC_CONF, TAKE12, ++ "Whether to update the Date header when returning cached proxy responses"}, ++ {"ProxyResponseExpiresVector", set_resp_exp_vector, NULL, RSRC_CONF, TAKE12, ++ "A constant to add to current time for expires headers on proxy response"}, ++ {"ProxyRequestHeader", set_header_directive, (void*)"ProxyRequestHeader", ++ RSRC_CONF,RAW_ARGS, ++ "A directive for headers to be sent with proxy requests"}, ++ {"ProxyResponseHeader", set_header_directive, (void*)"ProxyResponseHeader", ++ RSRC_CONF,RAW_ARGS, ++ "A directive for headers that are returned with responses"}, + {NULL} + }; + +@@ -994,4 +1200,10 @@ + NULL, /* child_init */ + NULL, /* child_exit */ + proxy_detect /* post read-request */ ++#ifdef EAPI ++ ,proxy_addmod, /* EAPI: add_module */ ++ proxy_remmod, /* EAPI: remove_module */ ++ NULL, /* EAPI: rewrite_command */ ++ NULL /* EAPI: new_connection */ ++#endif + }; +diff -u apache_1.3.26/src/modules/proxy/mod_proxy.h apache_1.3.26-patched/src/modules/proxy/mod_proxy.h +--- apache_1.3.26/src/modules/proxy/mod_proxy.h Sun Apr 21 07:35:07 2002 ++++ apache_1.3.26-patched/src/modules/proxy/mod_proxy.h Sun Jun 23 18:36:11 2002 +@@ -145,6 +145,23 @@ + struct in_addr addr; + }; + ++/* for configurable headers */ ++typedef enum { ++ hdr_on, hdr_off, hdr_set, hdr_unset, hdr_add, hdr_append ++} hdr_actions; ++ ++typedef struct { ++ hdr_actions action; ++ char *header; ++ char *value; ++ regex_t *pattern; ++} hdr_actions_entry; ++ ++typedef struct { ++ int vector; ++ regex_t *pattern; ++} resp_exp_vector_entry; ++ + #define DEFAULT_CACHE_SPACE 5 + #define DEFAULT_CACHE_MAXEXPIRE SEC_ONE_DAY + #define DEFAULT_CACHE_EXPIRE SEC_ONE_HR +@@ -203,6 +220,10 @@ + char recv_buffer_size_set; + size_t io_buffer_size; + char io_buffer_size_set; ++ array_header *freshen_date; ++ array_header *resp_exp_vector; ++ array_header *req_headers; ++ array_header *resp_headers; + } proxy_server_conf; + + struct hdr_entry { +@@ -299,6 +320,10 @@ + table *ap_proxy_read_headers(request_rec *r, char *buffer, int size, BUFF *f); + 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); + void ap_proxy_write_headers(cache_req *c, const char *respline, table *t); ++void ap_proxy_freshen_date(request_rec *r, proxy_server_conf *psf, table* t); ++void ap_proxy_vectored_exp(request_rec *r, proxy_server_conf *psf, table* t); ++void ap_proxy_header_fixup(request_rec *r, proxy_server_conf *psf, table* t, ++ array_header *directives); + int ap_proxy_liststr(const char *list, const char *key, char **val); + void ap_proxy_hash(const char *it, char *val, int ndepth, int nlength); + int ap_proxy_hex2sec(const char *x); +diff -u apache_1.3.26/src/modules/proxy/proxy_cache.c apache_1.3.26-patched/src/modules/proxy/proxy_cache.c +--- apache_1.3.26/src/modules/proxy/proxy_cache.c Mon Jun 3 08:28:27 2002 ++++ apache_1.3.26-patched/src/modules/proxy/proxy_cache.c Sun Jun 23 19:59:20 2002 +@@ -747,6 +747,8 @@ + int ap_proxy_cache_conditional(request_rec *r, cache_req *c, BUFF *cachefp) + { + const char *etag, *wetag = NULL; ++ proxy_server_conf *psf = (proxy_server_conf *) ++ ap_get_module_config(r->server->module_config,&proxy_module); + + /* get etag */ + if ((etag = ap_table_get(c->hdrs, "Etag"))) { +@@ -905,6 +907,11 @@ + /* content type is already set in the headers */ + r->content_type = ap_table_get(r->headers_out, "Content-Type"); + ++ /* handle the cases where we need to modify the date and expires ++ outgoing headers */ ++ ap_proxy_freshen_date(r,psf,r->headers_out); ++ ap_proxy_vectored_exp(r,psf,r->headers_out); ++ + ap_send_http_header(r); + + /* are we rewriting the cache file? */ +diff -u apache_1.3.26/src/modules/proxy/proxy_http.c apache_1.3.26-patched/src/modules/proxy/proxy_http.c +--- apache_1.3.26/src/modules/proxy/proxy_http.c Mon Jun 17 20:59:59 2002 ++++ apache_1.3.26-patched/src/modules/proxy/proxy_http.c Sun Jun 23 20:14:14 2002 +@@ -170,6 +170,9 @@ + const char *datestr, *urlstr; + int result, major, minor; + const char *content_length; ++#ifdef EAPI ++ char *peer; ++#endif + + void *sconf = r->server->module_config; + proxy_server_conf *conf = +@@ -191,6 +194,12 @@ + return HTTP_BAD_REQUEST; + urlptr += 3; + destport = DEFAULT_HTTP_PORT; ++#ifdef EAPI ++ ap_hook_use("ap::mod_proxy::http::handler::set_destport", ++ AP_HOOK_SIG2(int,ptr), ++ AP_HOOK_TOPMOST, ++ &destport, r); ++#endif /* EAPI */ + strp = strchr(urlptr, '/'); + if (strp == NULL) { + desthost = ap_pstrdup(p, urlptr); +@@ -228,12 +237,18 @@ + err = ap_proxy_host2addr(proxyhost, &server_hp); + if (err != NULL) + return DECLINED; /* try another */ ++#ifdef EAPI ++ peer = ap_psprintf(p, "%s:%u", proxyhost, proxyport); ++#endif + } + else { + server.sin_port = htons((unsigned short)destport); + err = ap_proxy_host2addr(desthost, &server_hp); + if (err != NULL) + return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, err); ++#ifdef EAPI ++ peer = ap_psprintf(p, "%s:%u", desthost, destport); ++#endif + } + + +@@ -308,14 +323,45 @@ + f = ap_bcreate(p, B_RDWR | B_SOCKET); + ap_bpushfd(f, sock, sock); + ++#ifdef EAPI ++ { ++ char *errmsg = NULL; ++ ap_hook_use("ap::mod_proxy::http::handler::new_connection", ++ AP_HOOK_SIG4(ptr,ptr,ptr,ptr), ++ AP_HOOK_DECLINE(NULL), ++ &errmsg, r, f, peer); ++ if (errmsg != NULL) ++ return ap_proxyerror(r, HTTP_BAD_GATEWAY, errmsg); ++ } ++#endif /* EAPI */ ++ + ap_hard_timeout("proxy send", r); + ap_bvputs(f, r->method, " ", proxyhost ? url : urlptr, " HTTP/1.1" CRLF, + NULL); ++#ifdef EAPI ++ { ++ int rc = DECLINED; ++ ap_hook_use("ap::mod_proxy::http::handler::write_host_header", ++ AP_HOOK_SIG6(int,ptr,ptr,ptr,int,ptr), ++ AP_HOOK_DECLINE(DECLINED), ++ &rc, r, f, desthost, destport, destportstr); ++ if (rc == DECLINED) { ++ if (destportstr != NULL && destport != DEFAULT_HTTP_PORT) ++ ap_bvputs(f, "Host: ", desthost, ":", destportstr, CRLF, NULL); ++ else ++ ap_bvputs(f, "Host: ", desthost, CRLF, NULL); ++ } ++ } ++#else /* EAPI */ + /* Send Host: now, adding it to req_hdrs wouldn't be much better */ + if (destportstr != NULL && destport != DEFAULT_HTTP_PORT) + ap_bvputs(f, "Host: ", desthost, ":", destportstr, CRLF, NULL); + else + ap_bvputs(f, "Host: ", desthost, CRLF, NULL); ++#endif /* EAPI */ ++ ++ /* run fixup for the request header directives */ ++ ap_proxy_header_fixup(r,conf,req_hdrs,conf->req_headers); + + if (conf->viaopt == via_block) { + /* Block all outgoing Via: headers */ +diff -u apache_1.3.26/src/modules/proxy/proxy_util.c apache_1.3.26-patched/src/modules/proxy/proxy_util.c +--- apache_1.3.26/src/modules/proxy/proxy_util.c Mon Jun 17 20:59:59 2002 ++++ apache_1.3.26-patched/src/modules/proxy/proxy_util.c Sun Jun 23 20:03:54 2002 +@@ -712,7 +712,10 @@ + */ + void ap_proxy_write_headers(cache_req *c, const char *respline, table *t) + { +- /* write status line */ ++ proxy_server_conf *psf = (proxy_server_conf *) ++ ap_get_module_config(c->req->server->module_config,&proxy_module); ++ ++ /* write status line */ + if (respline && c->fp != NULL && + ap_bvputs(c->fp, respline, CRLF, NULL) == -1) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req, +@@ -721,6 +724,17 @@ + return; + } + ++ /* Set extra response headers. We can set whatever we want here ++ * (including Expires and family) because we've already written ++ * the hex header line for the cache file. But the rest of the ++ * cache file, including the HTTP headers, will include whatever ++ * we adjust here. This is good, in general, but it does mean we ++ * have to adjust any running-vector Expires headers in the ++ * ap_proxy_send_headers, so even cached files get nice clean ++ * headers with times set correctly in the future. */ ++ ap_proxy_vectored_exp(c->req,psf,t); ++ ap_proxy_header_fixup(c->req,psf,t,psf->resp_headers); ++ + /* write response headers to the cache file */ + ap_table_do(ap_proxy_send_hdr_line, c, t, NULL); + +@@ -732,6 +746,77 @@ + } + } + ++void ap_proxy_freshen_date(request_rec *r, proxy_server_conf *psf, table* t) ++{ ++ int i; ++ hdr_actions_entry *list = (hdr_actions_entry*)psf->freshen_date->elts; ++ for(i=0; i < psf->freshen_date->nelts; i++) { ++ if(((list+i)->pattern == NULL) || ++ (regexec((list+i)->pattern,r->uri,0,NULL,0) != REG_NOMATCH)) { ++ if ((list+i)->action == hdr_on) { ++ ap_table_set(t, "Date", ++ ap_ht_time(r->pool, time(NULL), "%a %d %b %Y %T %Z", 1)); ++ } ++ return; ++ } ++ } ++} ++ ++/* see whether there are ProxyVectoredExpire directives to apply to ++ this request. (Don't do anything unless there is already an Expires ++ header here.) */ ++void ap_proxy_vectored_exp(request_rec *r, proxy_server_conf *psf, table* t) ++{ ++ int i; ++ resp_exp_vector_entry *list; ++ /* don't do anything to a doc that doesn't *already* have an Expires */ ++ if (! ap_table_get(t,"Expires")) return; ++ /* okay, loop through directives */ ++ list = (resp_exp_vector_entry*)psf->resp_exp_vector->elts; ++ for(i=0; i < psf->resp_exp_vector->nelts; i++) { ++ if(((list+i)->pattern == NULL) || ++ (regexec((list+i)->pattern,r->uri,0,NULL,0) != REG_NOMATCH)) { ++ if ((list+i)->vector == -1) { ++ } else if ((list+i)->vector == 0) { ++ ap_table_setn(t, "Expires", "0"); ++ ap_table_setn(t, "Cache-Control", "max-age=0"); ++ } else { ++ ap_table_set(t, "Expires", ++ ap_ht_time(r->pool, time(NULL)+(list+i)->vector, ++ "%a %d %b %Y %T %Z", 1)); ++ ap_table_set(t, "Cache-Control", ++ ap_psprintf(r->pool,"max-age=%d",(list+i)->vector)); ++ } ++ return; ++ } ++ } ++} ++ ++void ap_proxy_header_fixup(request_rec *r, proxy_server_conf *psf, ++ table *t, array_header *directives) ++{ ++ int i; ++ hdr_actions_entry *list = (hdr_actions_entry *)directives->elts; ++ for (i=0; i < directives->nelts; i++) { ++ if(((list+i)->pattern == NULL) || ++ (regexec((list+i)->pattern,r->uri,0,NULL,0) != REG_NOMATCH)) { ++ switch ((list+i)->action) { ++ case hdr_set: ++ ap_table_setn(t,(list+i)->header,(list+i)->value); ++ break; ++ case hdr_unset: ++ ap_table_unset(t,(list+i)->header); ++ break; ++ case hdr_add: ++ ap_table_addn(t,(list+i)->header,(list+i)->value); ++ break; ++ case hdr_append: ++ ap_table_mergen(t,(list+i)->header,(list+i)->value); ++ break; ++ } ++ } ++ } ++} + + /* + * list is a comma-separated list of case-insensitive tokens, with -- 2.44.0