From: wessels <> Date: Thu, 15 Sep 2005 03:09:38 +0000 (+0000) Subject: Some changes related to URL-parsing for upcoming ICAP additions: X-Git-Tag: SQUID_3_0_PRE4~623 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d4a04ed5cd6b82e20582caf649bc7d59b6e07efc;p=thirdparty%2Fsquid.git Some changes related to URL-parsing for upcoming ICAP additions: - findTrailingHTTPVersion() now has optional 'char *end' arg for parsing non-terminated buffers. If end defaults to NULL, then the string must be NULL terminated. - urlParseMethod() now has optional 'char *end' arg. - urlParseProtocol() now has optional 'char *end' arg. - urlParse() now has optional 'HttpRequest *' arg. If non-NULL, urlParse() does not allocate a new HttpRequest and returns this passed arg. --- diff --git a/src/client_side.cc b/src/client_side.cc index 1ef357d98e..a9c160d8c7 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -1,6 +1,6 @@ /* - * $Id: client_side.cc,v 1.694 2005/09/14 17:10:38 serassio Exp $ + * $Id: client_side.cc,v 1.695 2005/09/14 21:09:38 wessels Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -153,7 +153,6 @@ static void clientUpdateSocketStats(log_type logType, size_t size); static ClientSocketContext *clientParseRequestMethod(char *inbuf, method_t * method_p, ConnStateData::Pointer & conn); static char *skipLeadingSpace(char *aString); -static char *findTrailingHTTPVersion(char *uriAndHTTPVersion); #if UNUSED_CODE static void trimTrailingSpaces(char *aString, size_t len); #endif @@ -1615,18 +1614,26 @@ skipLeadingSpace(char *aString) return result; } -static char * -findTrailingHTTPVersion(char *uriAndHTTPVersion) +/* + * 'end' defaults to NULL for backwards compatibility + * remove default value if we ever get rid of NULL-terminated + * request buffers. + */ +const char * +findTrailingHTTPVersion(const char *uriAndHTTPVersion, const char *end) { - char *token; + if (NULL == end) { + end = uriAndHTTPVersion + strcspn(uriAndHTTPVersion, "\r\n"); + assert(end); + } - for (token = strchr(uriAndHTTPVersion, '\n'); token > uriAndHTTPVersion; token--) { - if (*token == '\n' || *token == '\r') + for (; end > uriAndHTTPVersion; end--) { + if (*end == '\n' || *end == '\r') continue; - if (xisspace(*token)) { - if (strncasecmp(token + 1, "HTTP/", 5) == 0) - return token + 1; + if (xisspace(*end)) { + if (strncasecmp(end + 1, "HTTP/", 5) == 0) + return end + 1; else break; } @@ -1849,7 +1856,7 @@ parseHttpRequest(ConnStateData::Pointer & conn, method_t * method_p, ClientHttpRequest *http; ClientSocketContext *result; StoreIOBuffer tempBuffer; - char *http_version; + const char *http_version; /* pre-set these values to make aborting simpler */ *prefix_p = NULL; @@ -1905,7 +1912,7 @@ parseHttpRequest(ConnStateData::Pointer & conn, method_t * method_p, /* Is there a legitimate first line to the headers ? */ if ((result = clientParseHttpRequestLine(inbuf, conn, method_p, &url, - http_ver, http_version))) { + http_ver, (char *) http_version))) { /* something wrong, abort */ xfree(inbuf); return result; diff --git a/src/protos.h b/src/protos.h index 562910c4a7..093ea1c5f6 100644 --- a/src/protos.h +++ b/src/protos.h @@ -1,6 +1,6 @@ /* - * $Id: protos.h,v 1.509 2005/09/12 23:28:57 wessels Exp $ + * $Id: protos.h,v 1.510 2005/09/14 21:09:38 wessels Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -819,10 +819,10 @@ SQUIDCEXTERN void unlinkdUnlink(const char *); SQUIDCEXTERN char *url_convert_hex(char *org_url, int allocate); SQUIDCEXTERN char *url_escape(const char *url); -SQUIDCEXTERN protocol_t urlParseProtocol(const char *); -SQUIDCEXTERN method_t urlParseMethod(const char *); +SQUIDCEXTERN protocol_t urlParseProtocol(const char *, const char *e = NULL); +SQUIDCEXTERN method_t urlParseMethod(const char *, const char *e = NULL); SQUIDCEXTERN void urlInitialize(void); -SQUIDCEXTERN HttpRequest *urlParse(method_t, char *); +SQUIDCEXTERN HttpRequest *urlParse(method_t, char *, HttpRequest *request = NULL); SQUIDCEXTERN const char *urlCanonical(HttpRequest *); SQUIDCEXTERN char *urlRInternal(const char *host, u_short port, const char *dir, const char *name); SQUIDCEXTERN char *urlInternal(const char *dir, const char *name); diff --git a/src/url.cc b/src/url.cc index fc8086e7c2..36e5e96eaf 100644 --- a/src/url.cc +++ b/src/url.cc @@ -1,6 +1,6 @@ /* - * $Id: url.cc,v 1.146 2003/08/10 11:00:45 robertc Exp $ + * $Id: url.cc,v 1.147 2005/09/14 21:09:38 wessels Exp $ * * DEBUG: section 23 URL Parsing * AUTHOR: Duane Wessels @@ -189,9 +189,13 @@ method_t &operator++ (method_t &aMethod) return aMethod; } - +/* + * urlParseMethod() takes begin and end pointers, but for backwards + * compatibility, end defaults to NULL, in which case we assume begin + * is NULL-terminated. + */ method_t -urlParseMethod(const char *s) +urlParseMethod(const char *b, const char *e) { method_t method = METHOD_NONE; /* @@ -200,57 +204,79 @@ urlParseMethod(const char *s) * which have the form %EXT[0-9][0-9] */ - if (*s == '%') + if (*b == '%') return METHOD_NONE; + /* + * if e is NULL, b must be NULL terminated and we + * make e point to the first whitespace character + * after b. + */ + if (NULL == e) + e = b + strcspn(b, w_space); + for (++method; method < METHOD_ENUM_END; ++method) { - if (0 == strcasecmp(s, RequestMethodStr[method])) + if (0 == strncasecmp(b, RequestMethodStr[method], e-b)) return method; } return METHOD_NONE; } - +/* + * urlParseProtocol() takes begin (b) and end (e) pointers, but for + * backwards compatibility, e defaults to NULL, in which case we + * assume b is NULL-terminated. + */ protocol_t -urlParseProtocol(const char *s) +urlParseProtocol(const char *b, const char *e) { + /* + * if e is NULL, b must be NULL terminated and we + * make e point to the first whitespace character + * after b. + */ + + if (NULL == e) + e = b + strcspn(b, ":"); + + int len = e - b; + /* test common stuff first */ - if (strcasecmp(s, "http") == 0) + if (strncasecmp(b, "http", len) == 0) return PROTO_HTTP; - if (strcasecmp(s, "ftp") == 0) + if (strncasecmp(b, "ftp", len) == 0) return PROTO_FTP; - if (strcasecmp(s, "https") == 0) + if (strncasecmp(b, "https", len) == 0) return PROTO_HTTPS; - if (strcasecmp(s, "file") == 0) + if (strncasecmp(b, "file", len) == 0) return PROTO_FTP; - if (strcasecmp(s, "gopher") == 0) + if (strncasecmp(b, "gopher", len) == 0) return PROTO_GOPHER; - if (strcasecmp(s, "wais") == 0) + if (strncasecmp(b, "wais", len) == 0) return PROTO_WAIS; - if (strcasecmp(s, "cache_object") == 0) + if (strncasecmp(b, "cache_object", len) == 0) return PROTO_CACHEOBJ; - if (strcasecmp(s, "urn") == 0) + if (strncasecmp(b, "urn", len) == 0) return PROTO_URN; - if (strcasecmp(s, "whois") == 0) + if (strncasecmp(b, "whois", len) == 0) return PROTO_WHOIS; - if (strcasecmp(s, "internal") == 0) + if (strncasecmp(b, "internal", len) == 0) return PROTO_INTERNAL; return PROTO_NONE; } - int urlDefaultPort(protocol_t p) { @@ -284,14 +310,19 @@ urlDefaultPort(protocol_t p) } } +/* + * Parse a URI/URL. + * + * If the 'request' arg is non-NULL, put parsed values there instead + * of allocating a new HttpRequest. + */ HttpRequest * -urlParse(method_t method, char *url) +urlParse(method_t method, char *url, HttpRequest *request) { LOCAL_ARRAY(char, proto, MAX_URL); LOCAL_ARRAY(char, login, MAX_URL); LOCAL_ARRAY(char, host, MAX_URL); LOCAL_ARRAY(char, urlpath, MAX_URL); - HttpRequest *request = NULL; char *t = NULL; char *q = NULL; int port; @@ -426,7 +457,14 @@ urlParse(method_t method, char *url) } } - request = requestCreate(method, protocol, urlpath); + if (NULL == request) + request = requestCreate(method, protocol, urlpath); + else { + request->method = method; + request->protocol = protocol; + request->urlpath = urlpath; + } + xstrncpy(request->host, host, SQUIDHOSTNAMELEN); xstrncpy(request->login, login, MAX_LOGIN_SZ); request->port = (u_short) port;