- Factor enlist_new_test() out of load_action_files().
[privoxy.git] / urlmatch.c
index 96d8877..3e4e621 100644 (file)
@@ -1,4 +1,4 @@
-const char urlmatch_rcs[] = "$Id: urlmatch.c,v 1.18 2007/07/30 16:42:21 fabiankeil Exp $";
+const char urlmatch_rcs[] = "$Id: urlmatch.c,v 1.20 2007/09/02 15:31:20 fabiankeil Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/urlmatch.c,v $
@@ -33,6 +33,14 @@ const char urlmatch_rcs[] = "$Id: urlmatch.c,v 1.18 2007/07/30 16:42:21 fabianke
  *
  * Revisions   :
  *    $Log: urlmatch.c,v $
+ *    Revision 1.20  2007/09/02 15:31:20  fabiankeil
+ *    Move match_portlist() from filter.c to urlmatch.c.
+ *    It's used for url matching, not for filtering.
+ *
+ *    Revision 1.19  2007/09/02 13:42:11  fabiankeil
+ *    - Allow port lists in url patterns.
+ *    - Ditch unused url_spec member pathlen.
+ *
  *    Revision 1.18  2007/07/30 16:42:21  fabiankeil
  *    Move the method check into unknown_method()
  *    and loop through the known methods instead
@@ -166,10 +174,6 @@ const char urlmatch_rcs[] = "$Id: urlmatch.c,v 1.18 2007/07/30 16:42:21 fabianke
 #include "ssplit.h"
 #include "miscutil.h"
 #include "errlog.h"
-/*
- * XXX: only for match_portlist() which I will relocate soonish.
- */
-#include "filters.h"
 
 const char urlmatch_h_rcs[] = URLMATCH_H_VERSION;
 
@@ -1019,9 +1023,10 @@ void free_url_spec(struct url_spec *url)
 int url_match(const struct url_spec *pattern,
               const struct http_request *url)
 {
-   int port_matches;
-   int domain_matches;
-   int path_matches;
+   /* XXX: these should probably be functions. */
+#define PORT_MATCHES ((NULL == pattern->port_list) || match_portlist(pattern->port_list, url->port))
+#define DOMAIN_MATCHES ((NULL == pattern->dbuffer) || (0 == domain_match(pattern, url)))
+#define PATH_MATCHES ((NULL == pattern->path) || (0 == regexec(pattern->preg, url->path, 0, NULL, 0)))
 
    if (pattern->tag_regex != NULL)
    {
@@ -1029,11 +1034,87 @@ int url_match(const struct url_spec *pattern,
       return 0;
    } 
 
-   port_matches = (NULL == pattern->port_list) || match_portlist(pattern->port_list, url->port);
-   domain_matches = (NULL == pattern->dbuffer) || (0 == domain_match(pattern, url));
-   path_matches = (NULL == pattern->path) || (0 == regexec(pattern->preg, url->path, 0, NULL, 0));
+   return (PORT_MATCHES && DOMAIN_MATCHES && PATH_MATCHES);
+
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  match_portlist
+ *
+ * Description :  Check if a given number is covered by a comma
+ *                separated list of numbers and ranges (a,b-c,d,..)
+ *
+ * Parameters  :
+ *          1  :  portlist = String with list
+ *          2  :  port = port to check
+ *
+ * Returns     :  0 => no match
+ *                1 => match
+ *
+ *********************************************************************/
+int match_portlist(const char *portlist, int port)
+{
+   char *min, *max, *next, *portlist_copy;
+
+   min = next = portlist_copy = strdup(portlist);
+
+   /*
+    * Zero-terminate first item and remember offset for next
+    */
+   if (NULL != (next = strchr(portlist_copy, (int) ',')))
+   {
+      *next++ = '\0';
+   }
+
+   /*
+    * Loop through all items, checking for match
+    */
+   while(min)
+   {
+      if (NULL == (max = strchr(min, (int) '-')))
+      {
+         /*
+          * No dash, check for equality
+          */
+         if (port == atoi(min))
+         {
+            free(portlist_copy);
+            return(1);
+         }
+      }
+      else
+      {
+         /*
+          * This is a range, so check if between min and max,
+          * or, if max was omitted, between min and 65K
+          */
+         *max++ = '\0';
+         if(port >= atoi(min) && port <= (atoi(max) ? atoi(max) : 65535))
+         {
+            free(portlist_copy);
+            return(1);
+         }
+
+      }
+
+      /*
+       * Jump to next item
+       */
+      min = next;
+
+      /*
+       * Zero-terminate next item and remember offset for n+1
+       */
+      if ((NULL != next) && (NULL != (next = strchr(next, (int) ','))))
+      {
+         *next++ = '\0';
+      }
+   }
 
-   return (port_matches && domain_matches && path_matches);
+   free(portlist_copy);
+   return 0;
 
 }