X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=urlmatch.c;h=ed7399be021db4d4c86dfc2c1393f4eb216ceeff;hp=d0ed49bbb4767c3189be4755655e808bceead62c;hb=4169cab396ff364c0c43f49cdb8d855dadb59c39;hpb=7f93e2b7daee594b59093ed5ff754fee846fe558 diff --git a/urlmatch.c b/urlmatch.c index d0ed49bb..ed7399be 100644 --- a/urlmatch.c +++ b/urlmatch.c @@ -1,4 +1,4 @@ -const char urlmatch_rcs[] = "$Id: urlmatch.c,v 1.78 2013/11/24 14:25:19 fabiankeil Exp $"; +const char urlmatch_rcs[] = "$Id: urlmatch.c,v 1.84 2014/06/20 09:47:10 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/urlmatch.c,v $ @@ -6,7 +6,7 @@ const char urlmatch_rcs[] = "$Id: urlmatch.c,v 1.78 2013/11/24 14:25:19 fabianke * Purpose : Declares functions to match URLs against URL * patterns. * - * Copyright : Written by and Copyright (C) 2001-2011 + * Copyright : Written by and Copyright (C) 2001-2014 * the Privoxy team. http://www.privoxy.org/ * * Based on the Internet Junkbuster originally written @@ -454,6 +454,12 @@ static int unknown_method(const char *method) */ "VERSION-CONTROL", "REPORT", "CHECKOUT", "CHECKIN", "UNCHECKOUT", "MKWORKSPACE", "UPDATE", "LABEL", "MERGE", "BASELINE-CONTROL", "MKACTIVITY", + /* + * The PATCH method is defined by RFC5789, the format of the + * actual patch in the body depends on the application, but from + * Privoxy's point of view it doesn't matter. + */ + "PATCH", }; int i; @@ -470,6 +476,50 @@ static int unknown_method(const char *method) } +/********************************************************************* + * + * Function : normalize_http_version + * + * Description : Take a supported HTTP version string and remove + * leading zeroes etc., reject unsupported versions. + * + * This is an explicit RFC 2616 (3.1) MUST and + * RFC 7230 mandates that intermediaries send their + * own HTTP-version in forwarded messages. + * + * Parameters : + * 1 : http_version = HTTP version string + * + * Returns : JB_ERR_OK on success + * JB_ERR_PARSE if the HTTP version is unsupported + * + *********************************************************************/ +jb_err static normalize_http_version(char *http_version) +{ + unsigned int major_version; + unsigned int minor_version; + + if (2 != sscanf(http_version, "HTTP/%u.%u", &major_version, &minor_version)) + { + log_error(LOG_LEVEL_ERROR, "Unsupported HTTP version: %s", http_version); + return JB_ERR_PARSE; + } + + if (major_version != 1 || (minor_version != 0 && minor_version != 1)) + { + log_error(LOG_LEVEL_ERROR, "The only supported HTTP " + "versions are 1.0 and 1.1. This rules out: %s", http_version); + return JB_ERR_PARSE; + } + + assert(strlen(http_version) >= 8); + snprintf(http_version, 9, "HTTP/%u.%u", major_version, minor_version); + + return JB_ERR_OK; + +} + + /********************************************************************* * * Function : parse_http_request @@ -489,7 +539,7 @@ static int unknown_method(const char *method) jb_err parse_http_request(const char *req, struct http_request *http) { char *buf; - char *v[10]; /* XXX: Why 10? We should only need three. */ + char *v[3]; int n; jb_err err; @@ -520,10 +570,8 @@ jb_err parse_http_request(const char *req, struct http_request *http) return JB_ERR_PARSE; } - if (strcmpic(v[2], "HTTP/1.1") && strcmpic(v[2], "HTTP/1.0")) + if (JB_ERR_OK != normalize_http_version(v[2])) { - log_error(LOG_LEVEL_ERROR, "The only supported HTTP " - "versions are 1.0 and 1.1. This rules out: %s", v[2]); freez(buf); return JB_ERR_PARSE; } @@ -543,6 +591,7 @@ jb_err parse_http_request(const char *req, struct http_request *http) http->cmd = strdup_or_die(req); http->gpc = strdup_or_die(v[0]); http->ver = strdup_or_die(v[2]); + http->ocmd = strdup_or_die(http->cmd); freez(buf); @@ -774,22 +823,22 @@ static jb_err compile_host_pattern(struct pattern_spec *url, const char *host_pa */ if (host_pattern[strlen(host_pattern) - 1] == '.') { - url->unanchored |= ANCHOR_RIGHT; + url->pattern.url_spec.unanchored |= ANCHOR_RIGHT; } if (host_pattern[0] == '.') { - url->unanchored |= ANCHOR_LEFT; + url->pattern.url_spec.unanchored |= ANCHOR_LEFT; } /* * Split domain into components */ - url->dbuffer = strdup_or_die(host_pattern); + url->pattern.url_spec.dbuffer = strdup_or_die(host_pattern); /* * Map to lower case */ - for (p = url->dbuffer; *p ; p++) + for (p = url->pattern.url_spec.dbuffer; *p ; p++) { *p = (char)privoxy_tolower(*p); } @@ -797,23 +846,23 @@ static jb_err compile_host_pattern(struct pattern_spec *url, const char *host_pa /* * Split the domain name into components */ - url->dcount = ssplit(url->dbuffer, ".", v, SZ(v)); + url->pattern.url_spec.dcount = ssplit(url->pattern.url_spec.dbuffer, ".", v, SZ(v)); - if (url->dcount < 0) + if (url->pattern.url_spec.dcount < 0) { free_pattern_spec(url); return JB_ERR_PARSE; } - else if (url->dcount != 0) + else if (url->pattern.url_spec.dcount != 0) { /* * Save a copy of the pointers in dvec */ - size = (size_t)url->dcount * sizeof(*url->dvec); + size = (size_t)url->pattern.url_spec.dcount * sizeof(*url->pattern.url_spec.dvec); - url->dvec = malloc_or_die(size); + url->pattern.url_spec.dvec = malloc_or_die(size); - memcpy(url->dvec, v, size); + memcpy(url->pattern.url_spec.dvec, v, size); } /* * else dcount == 0 in which case we needn't do anything, @@ -1003,25 +1052,25 @@ static int simple_domaincmp(char **pv, char **fv, int len) * Function : domain_match * * Description : Domain-wise Compare fqdn's. Governed by the bimap in - * pattern->unachored, the comparison is un-, left-, + * p.pattern->unachored, the comparison is un-, left-, * right-anchored, or both. * The individual domain names are compared with * simplematch(). * * Parameters : - * 1 : pattern = a domain that may contain a '*' as a wildcard. + * 1 : p = a domain that may contain a '*' as a wildcard. * 2 : fqdn = domain name against which the patterns are compared. * * Returns : 0 => domains are equivalent, else no match. * *********************************************************************/ -static int domain_match(const struct pattern_spec *pattern, const struct http_request *fqdn) +static int domain_match(const struct pattern_spec *p, const struct http_request *fqdn) { char **pv, **fv; /* vectors */ int plen, flen; - int unanchored = pattern->unanchored & (ANCHOR_RIGHT | ANCHOR_LEFT); + int unanchored = p->pattern.url_spec.unanchored & (ANCHOR_RIGHT | ANCHOR_LEFT); - plen = pattern->dcount; + plen = p->pattern.url_spec.dcount; flen = fqdn->dcount; if (flen < plen) @@ -1030,7 +1079,7 @@ static int domain_match(const struct pattern_spec *pattern, const struct http_re return 1; } - pv = pattern->dvec; + pv = p->pattern.url_spec.dvec; fv = fqdn->dvec; if (unanchored == ANCHOR_LEFT)