From: wessels <> Date: Thu, 15 Oct 1998 03:11:55 +0000 (+0000) Subject: allow whitespace in request URI's. X-Git-Tag: SQUID_3_0_PRE1~2574 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d548ee642e233f85b3f9cb68a46dd135a4ccc22a;p=thirdparty%2Fsquid.git allow whitespace in request URI's. --- diff --git a/src/cache_cf.cc b/src/cache_cf.cc index 0d858697a9..1c8a6cfbb9 100644 --- a/src/cache_cf.cc +++ b/src/cache_cf.cc @@ -1,6 +1,6 @@ /* - * $Id: cache_cf.cc,v 1.307 1998/10/13 23:33:31 wessels Exp $ + * $Id: cache_cf.cc,v 1.308 1998/10/14 21:11:55 wessels Exp $ * * DEBUG: section 3 Configuration File Parsing * AUTHOR: Harvest Derived @@ -1407,6 +1407,42 @@ parse_stringlist(wordlist ** list) #define free_wordlist wordlistDestroy +#define free_uri_whitespace free_int + +static void +parse_uri_whitespace(int *var) +{ + char *token = strtok(NULL, w_space); + if (token == NULL) + self_destruct(); + if (!strcasecmp(token, "deny")) + *var = URI_WHITESPACE_DENY; + else if (!strcasecmp(token, "allow")) + *var = URI_WHITESPACE_ALLOW; + else if (!strcasecmp(token, "encode")) + *var = URI_WHITESPACE_ENCODE; + else if (!strcasecmp(token, "chop")) + *var = URI_WHITESPACE_CHOP; + else + self_destruct(); +} + + +static void +dump_uri_whitespace(StoreEntry * entry, const char *name, int var) +{ + char *s; + if (var == URI_WHITESPACE_ALLOW) + s = "allow"; + else if (var == URI_WHITESPACE_ENCODE) + s = "encode"; + else if (var == URI_WHITESPACE_CHOP) + s = "chop"; + else + s = "deny"; + storeAppendPrintf(entry, "%s %s\n", name, s); +} + #include "cf_parser.c" peer_t diff --git a/src/cf.data.pre b/src/cf.data.pre index 5787214759..07b6b8af0f 100644 --- a/src/cf.data.pre +++ b/src/cf.data.pre @@ -1,6 +1,6 @@ # -# $Id: cf.data.pre,v 1.121 1998/10/13 23:42:03 wessels Exp $ +# $Id: cf.data.pre,v 1.122 1998/10/14 21:11:57 wessels Exp $ # # # SQUID Internet Object Cache http://squid.nlanr.net/Squid/ @@ -2657,4 +2657,28 @@ DOC_START objects. DOC_END +NAME: uri_whitespace +TYPE: uri_whitespace +LOC: Config.uri_whitespace +DEFAULT: deny +DOC_START + What to do with requests that have whitespace characters in the + URI. Options: + + deny: The request is denied. The user receives an "Invalid + Request" message. + allow: The request is allowed and the URI is not changed. The + whitespace characters remain in the URI. Note the + whitespace is passed to redirector processes if they + are in use. + encode: The request is allowed and the whitespace characters are + encoded according to RFC1738. This could be considered + a violation of the HTTP/1.1 + RFC because proxies are not allowed to rewrite URI's. + chop: The request is allowed and the URI is chopped at the + first whitespace. This might also be considered a + violation. +uri_whitespace deny +DOC_END + EOF diff --git a/src/client_side.cc b/src/client_side.cc index 373bc89b8f..c6d149e9f9 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -1,6 +1,6 @@ /* - * $Id: client_side.cc,v 1.411 1998/10/13 23:39:08 wessels Exp $ + * $Id: client_side.cc,v 1.412 1998/10/14 21:11:58 wessels Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -1882,16 +1882,25 @@ parseHttpRequest(ConnStateData * conn, method_t * method_p, int *status, debug(33, 5) ("parseHttpRequest: Method is '%s'\n", mstr); *method_p = method; - /* look for URL */ - if ((url = strtok(NULL, "\r\n\t ")) == NULL) { + /* look for URL+HTTP/x.x */ + if ((url = strtok(NULL, "\r\n")) == NULL) { debug(33, 1) ("parseHttpRequest: Missing URL\n"); return parseHttpRequestAbort(conn, "error:missing-url"); } - debug(33, 5) ("parseHttpRequest: Request is '%s'\n", url); - - token = strtok(NULL, null_string); - for (t = token; t && *t && *t != '\n' && *t != '\r'; t++); - if (t == NULL || *t == '\0' || t == token || strncasecmp(token, "HTTP/", 5)) { + t = url + strlen(url); + assert(*t == '\0'); + token = NULL; + while (t > url) { + t--; + if (isspace(*t) && !strncmp(t + 1, "HTTP/", 5)) { + token = t + 1; + break; + } + } + while (t > url && isspace(*t)) + *(t--) = '\0'; + debug(33, 5) ("parseHttpRequest: URI is '%s'\n", url); + if (token == NULL) { debug(33, 3) ("parseHttpRequest: Missing HTTP identifier\n"); #if RELAXED_HTTP_PARSER http_ver = (float) 0.9; /* wild guess */ @@ -2030,7 +2039,10 @@ parseHttpRequest(ConnStateData * conn, method_t * method_p, int *status, strcpy(http->uri, url); http->flags.accel = 0; } - http->log_uri = xstrdup(http->uri); + if (!stringHasWhitespace(http->uri)) + http->log_uri = xstrdup(http->uri); + else + http->log_uri = xstrdup(rfc1738_escape(http->uri)); debug(33, 5) ("parseHttpRequest: Complete request received\n"); if (free_request) safe_free(url); diff --git a/src/defines.h b/src/defines.h index 6ac6b86bbb..b2e3813455 100644 --- a/src/defines.h +++ b/src/defines.h @@ -1,6 +1,6 @@ /* - * $Id: defines.h,v 1.66 1998/09/14 22:18:45 wessels Exp $ + * $Id: defines.h,v 1.67 1998/10/14 21:12:00 wessels Exp $ * * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ @@ -258,3 +258,8 @@ #define PEER_TCP_MAGIC_COUNT 10 #define CLIENT_SOCK_SZ 4096 + +#define URI_WHITESPACE_DENY 0 +#define URI_WHITESPACE_ALLOW 1 +#define URI_WHITESPACE_ENCODE 2 +#define URI_WHITESPACE_CHOP 3 diff --git a/src/protos.h b/src/protos.h index d4aadad899..66a5d4e7d4 100644 --- a/src/protos.h +++ b/src/protos.h @@ -1,6 +1,6 @@ /* - * $Id: protos.h,v 1.277 1998/10/12 21:41:01 wessels Exp $ + * $Id: protos.h,v 1.278 1998/10/14 21:12:01 wessels Exp $ * * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ @@ -992,6 +992,8 @@ extern void pconnInit(void); extern int asnMatchIp(void *, struct in_addr); extern void asnInit(void); extern void asnFreeMemory(void); + +/* tools.c */ extern void dlinkAdd(void *data, dlink_node *, dlink_list *); extern void dlinkAddTail(void *data, dlink_node *, dlink_list *); extern void dlinkDelete(dlink_node * m, dlink_list * list); @@ -999,6 +1001,7 @@ extern void kb_incr(kb_t *, size_t); extern double gb_to_double(const gb_t *); extern const char *gb_to_str(const gb_t *); extern void gb_flush(gb_t *); /* internal, do not use this */ +extern int stringHasWhitespace(const char *); #if USE_HTCP extern void htcpInit(void); diff --git a/src/structs.h b/src/structs.h index 4692832b5b..503528200f 100644 --- a/src/structs.h +++ b/src/structs.h @@ -1,6 +1,6 @@ /* - * $Id: structs.h,v 1.239 1998/10/10 14:57:43 wessels Exp $ + * $Id: structs.h,v 1.240 1998/10/14 21:12:02 wessels Exp $ * * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ @@ -438,6 +438,7 @@ struct _SquidConfig { int http_min_poll; } comm_incoming; int max_open_disk_fds; + int uri_whitespace; }; struct _SquidConfig2 { diff --git a/src/tools.cc b/src/tools.cc index 133787632f..3d2e3f8744 100644 --- a/src/tools.cc +++ b/src/tools.cc @@ -1,6 +1,6 @@ /* - * $Id: tools.cc,v 1.169 1998/10/12 20:26:41 wessels Exp $ + * $Id: tools.cc,v 1.170 1998/10/14 21:12:03 wessels Exp $ * * DEBUG: section 21 Misc Functions * AUTHOR: Harvest Derived @@ -830,3 +830,9 @@ debugObj(int section, int level, const char *label, void *obj, ObjPackMethod pm) packerClean(&p); memBufClean(&mb); } + +int +stringHasWhitespace(const char *s) +{ + return (strcspn(s, w_space) != strlen(s)); +} diff --git a/src/url.cc b/src/url.cc index a5fa027456..7d91a0ec93 100644 --- a/src/url.cc +++ b/src/url.cc @@ -1,6 +1,6 @@ /* - * $Id: url.cc,v 1.108 1998/08/26 19:53:41 wessels Exp $ + * $Id: url.cc,v 1.109 1998/10/14 21:12:04 wessels Exp $ * * DEBUG: section 23 URL Parsing * AUTHOR: Duane Wessels @@ -216,7 +216,7 @@ urlParse(method_t method, char *url) } else if (!strncmp(url, "urn:", 4)) { return urnParse(method, url); } else { - if (sscanf(url, "%[^:]://%[^/]%s", proto, host, urlpath) < 2) + if (sscanf(url, "%[^:]://%[^/]%[^\r\n]", proto, host, urlpath) < 2) return NULL; protocol = urlParseProtocol(proto); port = urlDefaultPort(protocol); @@ -256,6 +256,22 @@ urlParse(method_t method, char *url) return NULL; } #endif + if (stringHasWhitespace(urlpath)) { + debug(23, 1) ("urlParse: URI has whitespace: {%s}\n", url); + switch (Config.uri_whitespace) { + case URI_WHITESPACE_DENY: + return NULL; + case URI_WHITESPACE_ALLOW: + break; + case URI_WHITESPACE_ENCODE: + t = rfc1738_escape(urlpath); + xstrncpy(urlpath, t, MAX_URL); + break; + case URI_WHITESPACE_CHOP: + *(urlpath + strcspn(urlpath, w_space)) = '\0'; + break; + } + } request = requestCreate(method, protocol, urlpath); xstrncpy(request->host, host, SQUIDHOSTNAMELEN); xstrncpy(request->login, login, MAX_LOGIN_SZ); @@ -310,7 +326,7 @@ urlCanonicalClean(const request_t * request) char *t; if (request->protocol == PROTO_URN) { snprintf(buf, MAX_URL, "urn:%s", strBuf(request->urlpath)); - } else + } else { switch (request->method) { case METHOD_CONNECT: snprintf(buf, MAX_URL, "%s:%d", request->host, request->port); @@ -339,6 +355,9 @@ urlCanonicalClean(const request_t * request) *(++t) = '\0'; break; } + } + if (stringHasWhitespace(buf)) + xstrncpy(buf, rfc1738_escape(buf), MAX_URL); return buf; }