diff options
author | Jim Jagielski <jim@apache.org> | 2002-10-14 16:11:24 +0200 |
---|---|---|
committer | Jim Jagielski <jim@apache.org> | 2002-10-14 16:11:24 +0200 |
commit | 62f1105335f6458635c2e40813647c5f055b6da3 (patch) | |
tree | 2de4527c1c6e6fafd1d48dc68ec75b0a2433b86b /modules/proxy | |
parent | This stuff shouldn't have been committed. This is the SSL upgrade stuff, (diff) | |
download | apache2-62f1105335f6458635c2e40813647c5f055b6da3.tar.xz apache2-62f1105335f6458635c2e40813647c5f055b6da3.zip |
Haven't heard any vetoes regarding this, so might as well fold it
in. Not too happy about cluttering up the list of directives either.
But, at least, it allows 2.0 to proxy stupid IIS as much as 1.3.
Docs to come soon.
PR:
Obtained from:
Submitted by:
Reviewed by:
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@97202 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'modules/proxy')
-rw-r--r-- | modules/proxy/mod_proxy.c | 36 | ||||
-rw-r--r-- | modules/proxy/mod_proxy.h | 9 | ||||
-rw-r--r-- | modules/proxy/proxy_util.c | 52 |
3 files changed, 82 insertions, 15 deletions
diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c index 58eadbf989..1092cce778 100644 --- a/modules/proxy/mod_proxy.c +++ b/modules/proxy/mod_proxy.c @@ -63,8 +63,6 @@ #include "apr_optional.h" -extern module AP_MODULE_DECLARE_DATA proxy_module; - #ifndef MAX #define MAX(x,y) ((x) >= (y) ? (x) : (y)) #endif @@ -499,10 +497,12 @@ static void * create_proxy_config(apr_pool_t *p, server_rec *s) ps->maxfwd_set = 0; ps->error_override = 0; ps->error_override_set = 0; - ps->preserve_host_set =0; - ps->preserve_host =0; - ps->timeout=0; - ps->timeout_set=0; + ps->preserve_host_set = 0; + ps->preserve_host = 0; + ps->timeout = 0; + ps->timeout_set = 0; + ps->badopt = bad_error; + ps->badopt_set = 0; return ps; } @@ -529,6 +529,7 @@ static void * merge_proxy_config(apr_pool_t *p, void *basev, void *overridesv) ps->error_override = (overrides->error_override_set == 0) ? base->error_override : overrides->error_override; ps->preserve_host = (overrides->preserve_host_set == 0) ? base->preserve_host : overrides->preserve_host; ps->timeout= (overrides->timeout_set == 0) ? base->timeout : overrides->timeout; + ps->badopt = (overrides->badopt_set == 0) ? base->badopt : overrides->badopt; return ps; } @@ -914,6 +915,27 @@ static const char* return NULL; } +static const char* + set_bad_opt(cmd_parms *parms, void *dummy, const char *arg) +{ + proxy_server_conf *psf = + ap_get_module_config(parms->server->module_config, &proxy_module); + + if (strcasecmp(arg, "IsError") == 0) + psf->badopt = bad_error; + else if (strcasecmp(arg, "Ignore") == 0) + psf->badopt = bad_ignore; + else if (strcasecmp(arg, "StartBody") == 0) + psf->badopt = bad_body; + else { + return "ProxyBadHeader must be one of: " + "IsError | Ignore | StartBody"; + } + + psf->badopt_set = 1; + return NULL; +} + static void ap_add_per_proxy_conf(server_rec *s, ap_conf_vector_t *dir_config) { proxy_server_conf *sconf = ap_get_module_config(s->module_config, @@ -1042,6 +1064,8 @@ static const command_rec proxy_cmds[] = AP_INIT_TAKE1("ProxyTimeout", set_proxy_timeout, NULL, RSRC_CONF, "Set the timeout (in seconds) for a proxied connection. " "This overrides the server timeout"), + AP_INIT_TAKE1("ProxyBadHeader", set_bad_opt, NULL, RSRC_CONF, + "How to handle bad header line in response: IsError | Ignore | StartBody"), {NULL} }; diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h index b971ceff87..930aa97b3c 100644 --- a/modules/proxy/mod_proxy.h +++ b/modules/proxy/mod_proxy.h @@ -195,6 +195,12 @@ typedef struct { int preserve_host_set; apr_interval_time_t timeout; apr_interval_time_t timeout_set; + enum { + bad_error, + bad_ignore, + bad_body + } badopt; /* how to deal with bad headers */ + char badopt_set; } proxy_server_conf; @@ -284,4 +290,7 @@ PROXY_DECLARE(int) ap_proxy_connect_to_backend(apr_socket_t **, const char *, ap PROXY_DECLARE(int) ap_proxy_ssl_enable(conn_rec *c); PROXY_DECLARE(int) ap_proxy_ssl_disable(conn_rec *c); +/* For proxy_util */ +extern module AP_MODULE_DECLARE_DATA proxy_module; + #endif /*MOD_PROXY_H*/ diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c index d989372c77..e447f98fe7 100644 --- a/modules/proxy/proxy_util.c +++ b/modules/proxy/proxy_util.c @@ -433,6 +433,11 @@ PROXY_DECLARE(apr_table_t *)ap_proxy_read_headers(request_rec *r, request_rec *r int len; char *value, *end; char field[MAX_STRING_LEN]; + int saw_headers = 0; + void *sconf = r->server->module_config; + proxy_server_conf *psc; + + psc = (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module); headers_out = apr_table_make(r->pool, 20); @@ -444,19 +449,47 @@ PROXY_DECLARE(apr_table_t *)ap_proxy_read_headers(request_rec *r, request_rec *r if (!(value = strchr(buffer, ':'))) { /* Find the colon separator */ - /* Buggy MS IIS servers sometimes return invalid headers - * (an extra "HTTP/1.0 200, OK" line sprinkled in between - * the usual MIME headers). Try to deal with it in a sensible - * way, but log the fact. - * XXX: The mask check is buggy if we ever see an HTTP/1.10 */ + /* We may encounter invalid headers, usually from buggy + * MS IIS servers, so we need to determine just how to handle + * them. We can either ignore them, assume that they mark the + * start-of-body (eg: a missing CRLF) or (the default) mark + * the headers as totally bogus and return a 500. The sole + * exception is an extra "HTTP/1.0 200, OK" line sprinkled + * in between the usual MIME headers, which is a favorite + * IIS bug. + */ + /* XXX: The mask check is buggy if we ever see an HTTP/1.10 */ if (!apr_date_checkmask(buffer, "HTTP/#.# ###*")) { - /* Nope, it wasn't even an extra HTTP header. Give up. */ - return NULL; + if (psc->badopt == bad_error) { + /* Nope, it wasn't even an extra HTTP header. Give up. */ + return NULL; + } + else if (psc->badopt == bad_body) { + /* if we've already started loading headers_out, then + * return what we've accumulated so far, in the hopes + * that they are useful. Otherwise, we completely bail. + */ + /* FIXME: We've already scarfed the supposed 1st line of + * the body, so the actual content may end up being bogus + * as well. If the content is HTML, we may be lucky. + */ + if (saw_headers) { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, r->server, + "proxy: Starting body due to bogus non-header in headers " + "returned by %s (%s)", r->uri, r->method); + return headers_out; + } else { + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, r->server, + "proxy: No HTTP headers " + "returned by %s (%s)", r->uri, r->method); + return NULL; + } + } } - + /* this is the psc->badopt == bad_ignore case */ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, r->server, - "proxy: Ignoring duplicate HTTP header " + "proxy: Ignoring bogus HTTP header " "returned by %s (%s)", r->uri, r->method); continue; } @@ -475,6 +508,7 @@ PROXY_DECLARE(apr_table_t *)ap_proxy_read_headers(request_rec *r, request_rec *r /* make sure we add so as not to destroy duplicated headers */ apr_table_add(headers_out, buffer, value); + saw_headers = 1; /* the header was too long; at the least we should skip extra data */ if (len >= size - 1) { |