You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Jim Jagielski <ji...@jaguNET.com> on 2002/10/07 20:59:57 UTC
[PATCH] bogus header handling in ap_proxy_read_headers
This patch adds a directive that controls how the proxy module should
handle bogus headers when reading headers... Right now, any bogus
header results in in BAD_GATEWAY... 1.3 was somewhat more resiliant.
Index: modules/proxy/mod_proxy.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/proxy/mod_proxy.c,v
retrieving revision 1.89
diff -u -r1.89 mod_proxy.c
--- modules/proxy/mod_proxy.c 8 Sep 2002 17:56:18 -0000 1.89
+++ modules/proxy/mod_proxy.c 7 Oct 2002 18:54:03 -0000
@@ -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 @@
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 @@
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 @@
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 @@
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}
};
Index: modules/proxy/mod_proxy.h
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/proxy/mod_proxy.h,v
retrieving revision 1.84
diff -u -r1.84 mod_proxy.h
--- modules/proxy/mod_proxy.h 11 Jul 2002 18:45:22 -0000 1.84
+++ modules/proxy/mod_proxy.h 7 Oct 2002 18:54:04 -0000
@@ -195,6 +195,12 @@
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;
@@ -283,5 +289,8 @@
PROXY_DECLARE(int) ap_proxy_connect_to_backend(apr_socket_t **, const char *, apr_sockaddr_t *, const char *, proxy_server_conf *, server_rec *, apr_pool_t *);
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*/
Index: modules/proxy/proxy_util.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/proxy/proxy_util.c,v
retrieving revision 1.98
diff -u -r1.98 proxy_util.c
--- modules/proxy/proxy_util.c 25 Aug 2002 20:40:11 -0000 1.98
+++ modules/proxy/proxy_util.c 7 Oct 2002 18:54:05 -0000
@@ -433,6 +433,11 @@
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,46 @@
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. 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 +507,7 @@
/* 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) {
--
===========================================================================
Jim Jagielski [|] jim@jaguNET.com [|] http://www.jaguNET.com/
"A society that will trade a little liberty for a little order
will lose both and deserve neither" - T.Jefferson
RE: [PATCH] bogus header handling in ap_proxy_read_headers
Posted by Bill Stoddard <bi...@wstoddard.com>.
> This patch adds a directive
Do we really need a new directive? I just have this general unease at the
number of new config directives we have been creating lately...
Bill