- Don't rerun crunchers that only depend on the request URL.
[privoxy.git] / urlmatch.c
index 1d65c3f..f3eaa41 100644 (file)
@@ -1,4 +1,4 @@
-const char urlmatch_rcs[] = "$Id: urlmatch.c,v 1.12 2006/07/18 14:48:47 david__schmidt Exp $";
+const char urlmatch_rcs[] = "$Id: urlmatch.c,v 1.16 2007/02/13 13:59:24 fabiankeil Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/urlmatch.c,v $
@@ -6,7 +6,7 @@ const char urlmatch_rcs[] = "$Id: urlmatch.c,v 1.12 2006/07/18 14:48:47 david__s
  * Purpose     :  Declares functions to match URLs against URL
  *                patterns.
  *
- * Copyright   :  Written by and Copyright (C) 2001-2003, 2006 the SourceForge
+ * Copyright   :  Written by and Copyright (C) 2001-2003, 2006-2007 the SourceForge
  *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
@@ -33,6 +33,25 @@ const char urlmatch_rcs[] = "$Id: urlmatch.c,v 1.12 2006/07/18 14:48:47 david__s
  *
  * Revisions   :
  *    $Log: urlmatch.c,v $
+ *    Revision 1.16  2007/02/13 13:59:24  fabiankeil
+ *    Remove redundant log message.
+ *
+ *    Revision 1.15  2007/01/28 16:11:23  fabiankeil
+ *    Accept WebDAV methods for subversion
+ *    in parse_http_request(). Closes FR 1581425.
+ *
+ *    Revision 1.14  2007/01/06 14:23:56  fabiankeil
+ *    Fix gcc43 warnings. Mark *csp as immutable
+ *    for parse_http_url() and url_match().
+ *    Replace a sprintf call with snprintf.
+ *
+ *    Revision 1.13  2006/12/06 19:50:54  fabiankeil
+ *    parse_http_url() now handles intercepted
+ *    HTTP request lines as well. Moved parts
+ *    of parse_http_url()'s code into
+ *    init_domain_components() so that it can
+ *    be reused in chat().
+ *
  *    Revision 1.12  2006/07/18 14:48:47  david__schmidt
  *    Reorganizing the repository: swapping out what was HEAD (the old 3.1 branch)
  *    with what was really the latest development (the v_3_0_branch branch)
@@ -205,7 +224,7 @@ jb_err init_domain_components(struct http_request *http)
    /* map to lower case */
    for (p = http->dbuffer; *p ; p++)
    {
-      *p = tolower((int)(unsigned char)*p);
+      *p = (char)tolower((int)(unsigned char)*p);
    }
 
    /* split the domain name into components */
@@ -222,7 +241,7 @@ jb_err init_domain_components(struct http_request *http)
    }
 
    /* save a copy of the pointers in dvec */
-   size = http->dcount * sizeof(*http->dvec);
+   size = (size_t)http->dcount * sizeof(*http->dvec);
 
    http->dvec = (char **)malloc(size);
    if (NULL == http->dvec)
@@ -258,7 +277,7 @@ jb_err init_domain_components(struct http_request *http)
  *********************************************************************/
 jb_err parse_http_url(const char * url,
                       struct http_request *http,
-                      struct client_state *csp)
+                      const struct client_state *csp)
 {
    int host_available = 1; /* A proxy can dream. */
 
@@ -458,7 +477,7 @@ jb_err parse_http_url(const char * url,
  *********************************************************************/
 jb_err parse_http_request(const char *req,
                           struct http_request *http,
-                          struct client_state *csp)
+                          const struct client_state *csp)
 {
    char *buf;
    char *v[10];
@@ -477,7 +496,6 @@ jb_err parse_http_request(const char *req,
    n = ssplit(buf, " \r\n", v, SZ(v), 1, 1);
    if (n != 3)
    {
-      log_error(LOG_LEVEL_ERROR, "Trouble ssplitting: %s", buf);
       free(buf);
       return JB_ERR_PARSE;
    }
@@ -523,6 +541,22 @@ jb_err parse_http_request(const char *req,
          || (0 == strcmpic(v[0], "unsubscribe"))
          || (0 == strcmpic(v[0], "notify"))
          || (0 == strcmpic(v[0], "poll"))
+
+         /*
+          * Or yet another WebDAV extension, this time for
+          * Web Distributed Authoring and Versioning (RFC3253)
+          */
+         || (0 == strcmpic(v[0], "version-control"))
+         || (0 == strcmpic(v[0], "report"))
+         || (0 == strcmpic(v[0], "checkout"))
+         || (0 == strcmpic(v[0], "checkin"))
+         || (0 == strcmpic(v[0], "uncheckout"))
+         || (0 == strcmpic(v[0], "mkworkspace"))
+         || (0 == strcmpic(v[0], "update"))
+         || (0 == strcmpic(v[0], "label"))
+         || (0 == strcmpic(v[0], "merge"))
+         || (0 == strcmpic(v[0], "baseline-control"))
+         || (0 == strcmpic(v[0], "mkactivity"))
          )
    {
       /* Normal */
@@ -710,6 +744,9 @@ static int domain_match(const struct url_spec *pattern, const struct http_reques
 jb_err create_url_spec(struct url_spec * url, const char * buf)
 {
    char *p;
+   int errcode;
+   size_t errlen;
+   char rebuf[BUFFER_SIZE];
 
    assert(url);
    assert(buf);
@@ -727,6 +764,38 @@ jb_err create_url_spec(struct url_spec * url, const char * buf)
       return JB_ERR_MEMORY;
    }
 
+   /* Is it tag pattern? */
+   if (0 == strncmpic("TAG:", url->spec, 4))
+   {
+      if (NULL == (url->tag_regex = zalloc(sizeof(*url->tag_regex))))
+      {
+         freez(url->spec);
+         return JB_ERR_MEMORY;
+      }
+
+      /* buf + 4 to skip "TAG:" */
+      errcode = regcomp(url->tag_regex, buf + 4, (REG_EXTENDED|REG_NOSUB|REG_ICASE));
+      if (errcode)
+      {
+         errlen = regerror(errcode, url->preg, rebuf, sizeof(rebuf));
+         if (errlen > (sizeof(rebuf) - 1))
+         {
+            errlen = sizeof(rebuf) - 1;
+         }
+         rebuf[errlen] = '\0';
+
+         log_error(LOG_LEVEL_ERROR, "error compiling %s: %s", url->spec, rebuf);
+
+         freez(url->spec);
+         regfree(url->tag_regex);
+         freez(url->tag_regex);
+
+         return JB_ERR_PARSE;
+      }
+      return JB_ERR_OK;
+   }
+
+   /* Only reached for URL patterns */
    if ((p = strchr(buf, '/')) != NULL)
    {
       if (NULL == (url->path = strdup(p)))
@@ -744,9 +813,6 @@ jb_err create_url_spec(struct url_spec * url, const char * buf)
    }
    if (url->path)
    {
-      int errcode;
-      char rebuf[BUFFER_SIZE];
-
       if (NULL == (url->preg = zalloc(sizeof(*url->preg))))
       {
          freez(url->spec);
@@ -754,14 +820,13 @@ jb_err create_url_spec(struct url_spec * url, const char * buf)
          return JB_ERR_MEMORY;
       }
 
-      sprintf(rebuf, "^(%s)", url->path);
+      snprintf(rebuf, sizeof(rebuf), "^(%s)", url->path);
 
       errcode = regcomp(url->preg, rebuf,
             (REG_EXTENDED|REG_NOSUB|REG_ICASE));
       if (errcode)
       {
-         size_t errlen = regerror(errcode,
-            url->preg, rebuf, sizeof(rebuf));
+         errlen = regerror(errcode, url->preg, rebuf, sizeof(rebuf));
 
          if (errlen > (sizeof(rebuf) - (size_t)1))
          {
@@ -825,7 +890,7 @@ jb_err create_url_spec(struct url_spec * url, const char * buf)
        */
       for (p = url->dbuffer; *p ; p++)
       {
-         *p = tolower((int)(unsigned char)*p);
+         *p = (char)tolower((int)(unsigned char)*p);
       }
 
       /* 
@@ -849,7 +914,7 @@ jb_err create_url_spec(struct url_spec * url, const char * buf)
          /* 
           * Save a copy of the pointers in dvec
           */
-         size = url->dcount * sizeof(*url->dvec);
+         size = (size_t)url->dcount * sizeof(*url->dvec);
 
          url->dvec = (char **)malloc(size);
          if (NULL == url->dvec)
@@ -903,6 +968,11 @@ void free_url_spec(struct url_spec *url)
       regfree(url->preg);
       freez(url->preg);
    }
+   if (url->tag_regex)
+   {
+      regfree(url->tag_regex);
+      freez(url->tag_regex);
+   }
 }
 
 
@@ -916,12 +986,18 @@ void free_url_spec(struct url_spec *url)
  *          1  :  pattern = a URL pattern
  *          2  :  url = URL to match
  *
- * Returns     :  0 iff the URL matches the pattern, else nonzero.
+ * Returns     :  Nonzero if the URL matches the pattern, else 0.
  *
  *********************************************************************/
 int url_match(const struct url_spec *pattern,
               const struct http_request *url)
 {
+   if (pattern->tag_regex != NULL)
+   {
+      /* It's a tag pattern and shouldn't be matched against URLs */
+      return 0;
+   } 
+
    return ((pattern->port == 0) || (pattern->port == url->port))
        && ((pattern->dbuffer == NULL) || (domain_match(pattern, url) == 0))
        && ((pattern->path == NULL) ||