Return-Path: Delivered-To: apache-cvs-archive@hyperreal.org Received: (qmail 3852 invoked by uid 6000); 1 Apr 1998 14:41:47 -0000 Received: (qmail 3846 invoked by alias); 1 Apr 1998 14:41:46 -0000 Delivered-To: apache-1.3-cvs@hyperreal.org Received: (qmail 3828 invoked by uid 177); 1 Apr 1998 14:41:46 -0000 Date: 1 Apr 1998 14:41:46 -0000 Message-ID: <19980401144146.3824.qmail@hyperreal.org> From: martin@hyperreal.org To: apache-1.3-cvs@hyperreal.org Subject: cvs commit: apache-1.3/src/modules/proxy mod_proxy.c Sender: apache-cvs-owner@apache.org Precedence: bulk Reply-To: new-httpd@apache.org martin 98/04/01 06:41:45 Modified: src/include util_uri.h src/main http_protocol.c util_uri.c src/modules/proxy mod_proxy.c Log: After recent changes, the proxying of "CONNECT host:port HTTP/1.0" requests (as are issued by current browsers for https://host/ URLs) ceased to work. Now the request method is parsed early and used to decide which of two URI parsing routines should be used (either the full scheme://user:port@host... format, or the fixed host:port format for CONNECTs). Yet to fix: the request method is currently determined twice. "Probably" the later check is redundant (but I'm not sure because of the difficult logic with internal subrequests etc.) Revision Changes Path 1.6 +1 -0 apache-1.3/src/include/util_uri.h Index: util_uri.h =================================================================== RCS file: /home/cvs/apache-1.3/src/include/util_uri.h,v retrieving revision 1.5 retrieving revision 1.6 diff -u -u -r1.5 -r1.6 --- util_uri.h 1998/03/31 12:52:33 1.5 +++ util_uri.h 1998/04/01 14:41:32 1.6 @@ -112,6 +112,7 @@ API_EXPORT(char *) unparse_uri_components(pool *p, const uri_components *uptr, unsigned flags); API_EXPORT(int) parse_uri_components(pool *p, const char *uri, uri_components *uptr); +API_EXPORT(int) parse_hostinfo_components(pool *p, const char *hostinfo, uri_components *uptr); /* called by the core in main() */ extern void util_uri_init(void); 1.206 +31 -2 apache-1.3/src/main/http_protocol.c Index: http_protocol.c =================================================================== RCS file: /home/cvs/apache-1.3/src/main/http_protocol.c,v retrieving revision 1.205 retrieving revision 1.206 diff -u -u -r1.205 -r1.206 --- http_protocol.c 1998/03/31 12:52:45 1.205 +++ http_protocol.c 1998/04/01 14:41:34 1.206 @@ -581,14 +581,20 @@ r->unparsed_uri = pstrdup(r->pool, uri); - /* Simple syntax Errors in URLs are trapped by parse_uri_components(). */ - status = parse_uri_components(r->pool, uri, &r->parsed_uri); + if (r->method_number == M_CONNECT) { + status = parse_hostinfo_components(r->pool, uri, &r->parsed_uri); + } else { + /* Simple syntax Errors in URLs are trapped by parse_uri_components(). */ + status = parse_uri_components(r->pool, uri, &r->parsed_uri); + } if (is_HTTP_SUCCESS(status)) { /* if it has a scheme we may need to do absoluteURI vhost stuff */ if (r->parsed_uri.scheme && !strcasecmp(r->parsed_uri.scheme, http_method(r))) { r->hostname = r->parsed_uri.hostname; + } else if (r->method_number == M_CONNECT) { + r->hostname = r->parsed_uri.hostname; } r->args = r->parsed_uri.query; r->uri = r->parsed_uri.path ? r->parsed_uri.path @@ -664,6 +670,29 @@ r->the_request = pstrdup(r->pool, l); r->method = getword_white(r->pool, &ll); uri = getword_white(r->pool, &ll); + + /* Provide quick information about the request method as soon as known */ + if (!strcmp(r->method, "HEAD")) { + r->header_only = 1; + r->method_number = M_GET; + } + else if (!strcmp(r->method, "GET")) + r->method_number = M_GET; + else if (!strcmp(r->method, "POST")) + r->method_number = M_POST; + else if (!strcmp(r->method, "PUT")) + r->method_number = M_PUT; + else if (!strcmp(r->method, "DELETE")) + r->method_number = M_DELETE; + else if (!strcmp(r->method, "CONNECT")) + r->method_number = M_CONNECT; + else if (!strcmp(r->method, "OPTIONS")) + r->method_number = M_OPTIONS; + else if (!strcmp(r->method, "TRACE")) + r->method_number = M_TRACE; + else + r->method_number = M_INVALID; /* Will eventually croak. */ + parse_uri(r, uri); r->assbackwards = (ll[0] == '\0'); 1.18 +37 -0 apache-1.3/src/main/util_uri.c Index: util_uri.c =================================================================== RCS file: /home/cvs/apache-1.3/src/main/util_uri.c,v retrieving revision 1.17 retrieving revision 1.18 diff -u -u -r1.17 -r1.18 --- util_uri.c 1998/03/31 12:52:51 1.17 +++ util_uri.c 1998/04/01 14:41:36 1.18 @@ -543,4 +543,41 @@ hostinfo = s + 1; goto deal_with_host; } + +/* Special case for CONNECT parsing: it comes with the hostinfo part only */ +/* See the INTERNET-DRAFT document "Tunneling SSL Through a WWW Proxy" + * currently at http://www.mcom.com/newsref/std/tunneling_ssl.html + * for the format of the "CONNECT host:port HTTP/1.0" request + */ +API_EXPORT(int) parse_hostinfo_components(pool *p, const char *hostinfo, uri_components *uptr) +{ + const char *s; + char *endstr; + + /* Initialize the structure. parse_uri() and parse_uri_components() + * can be called more than once per request. + */ + memset (uptr, '\0', sizeof(*uptr)); + uptr->is_initialized = 1; + uptr->hostinfo = pstrdup(p, hostinfo); + + /* We expect hostinfo to point to the first character of + * the hostname. There must be a port, separated by a colon + */ + s = strchr(hostinfo, ':'); + if (s == NULL) { + return HTTP_BAD_REQUEST; + } + uptr->hostname = pstrndup(p, hostinfo, s - hostinfo); + ++s; + uptr->port_str = pstrdup(p, s); + if (*s != '\0') { + uptr->port = strtol(uptr->port_str, &endstr, 10); + if (*endstr == '\0') { + return HTTP_OK; + } + /* Invalid characters after ':' found */ + } + return HTTP_BAD_REQUEST; +} #endif 1.50 +9 -0 apache-1.3/src/modules/proxy/mod_proxy.c Index: mod_proxy.c =================================================================== RCS file: /home/cvs/apache-1.3/src/modules/proxy/mod_proxy.c,v retrieving revision 1.49 retrieving revision 1.50 diff -u -u -r1.49 -r1.50 --- mod_proxy.c 1998/03/31 12:52:59 1.49 +++ mod_proxy.c 1998/04/01 14:41:43 1.50 @@ -155,6 +155,15 @@ r->handler = "proxy-server"; } } + /* We need special treatment for CONNECT proxying: it has no scheme part */ + else if (conf->req && r->method_number == M_CONNECT + && r->parsed_uri.hostname + && r->parsed_uri.port_str) { + r->proxyreq = 1; + r->uri = r->unparsed_uri; + r->filename = pstrcat(r->pool, "proxy:", r->uri, NULL); + r->handler = "proxy-server"; + } return DECLINED; }