name change
[privoxy.git] / filters.c
index 0831df7..4fc07a2 100644 (file)
--- a/filters.c
+++ b/filters.c
@@ -1,4 +1,4 @@
-const char filters_rcs[] = "$Id: filters.c,v 1.42 2002/01/17 21:00:32 jongfoster Exp $";
+const char filters_rcs[] = "$Id: filters.c,v 1.48 2002/03/13 20:25:34 oes Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/filters.c,v $
@@ -38,6 +38,34 @@ const char filters_rcs[] = "$Id: filters.c,v 1.42 2002/01/17 21:00:32 jongfoster
  *
  * Revisions   :
  *    $Log: filters.c,v $
+ *    Revision 1.48  2002/03/13 20:25:34  oes
+ *    Better logging for content filters
+ *
+ *    Revision 1.47  2002/03/13 00:30:52  jongfoster
+ *    Killing warnings
+ *    Added option of always sending redirect for imageblock,
+ *    currently disabled with #if 0.
+ *
+ *    Revision 1.46  2002/03/12 01:42:49  oes
+ *    Introduced modular filters
+ *
+ *    Revision 1.45  2002/03/08 16:47:50  oes
+ *    Added choice beween GIF and PNG built-in images
+ *
+ *    Revision 1.44  2002/03/07 03:49:31  oes
+ *     - Fixed compiler warnings etc
+ *     - Changed built-in images from GIF to PNG
+ *       (with regard to Unisys patent issue)
+ *     - Added a 4x4 pattern PNG which is less intrusive
+ *       than the logo but also clearly marks the deleted banners
+ *
+ *    Revision 1.43  2002/01/22 23:51:59  jongfoster
+ *    Replacing strsav() with the safer string_append().
+ *
+ *    Adding missing html_encode() to error message generators.  Where encoded
+ *    and unencoded versions of a string were provided, removing the unencoded
+ *    one.
+ *
  *    Revision 1.42  2002/01/17 21:00:32  jongfoster
  *    Moving all our URL and URL pattern parsing code to urlmatch.c.
  *
@@ -456,7 +484,7 @@ int block_acl(struct access_control_addr *dst, struct client_state *csp)
  *
  * Function    :  acl_addr
  *
- * Description :  Called from `load_aclfile' to parse an ACL address.
+ * Description :  Called from `load_config' to parse an ACL address.
  *
  * Parameters  :
  *          1  :  aspec = String specifying ACL address.
@@ -473,7 +501,7 @@ int acl_addr(char *aspec, struct access_control_addr *aca)
    masklength = 32;
    port       =  0;
 
-   if ((p = strchr(aspec, '/')))
+   if ((p = strchr(aspec, '/')) != NULL)
    {
       *p++ = '\0';
 
@@ -489,7 +517,7 @@ int acl_addr(char *aspec, struct access_control_addr *aca)
       return(-1);
    }
 
-   if ((p = strchr(aspec, ':')))
+   if ((p = strchr(aspec, ':')) != NULL)
    {
       *p++ = '\0';
 
@@ -504,9 +532,8 @@ int acl_addr(char *aspec, struct access_control_addr *aca)
 
    aca->addr = ntohl(resolve_hostname_to_ip(aspec));
 
-   if (aca->addr == -1)
+   if (aca->addr == INADDR_NONE)
    {
-      log_error(LOG_LEVEL_ERROR, "can't resolve address for %s", aspec);
       return(-1);
    }
 
@@ -654,18 +681,20 @@ struct http_response *block_url(struct client_state *csp)
       /* determine HOW images should be blocked */
       p = csp->action->string[ACTION_STRING_IMAGE_BLOCKER];
 
+#if 1 /* Two alternative strategies, use this one for now: */
+
       /* and handle accordingly: */
       if ((p == NULL) || (0 == strcmpic(p, "logo")))
       {
-         rsp->body = bindup(image_junkbuster_gif_data, image_junkbuster_gif_length);
+         rsp->body = bindup(image_logo_data, image_logo_length);
          if (rsp->body == NULL)
          {
             free_http_response(rsp);
             return cgi_error_memory();
          }
-         rsp->content_length = image_junkbuster_gif_length;
+         rsp->content_length = image_logo_length;
 
-         if (enlist_unique_header(rsp->headers, "Content-Type", "image/gif"))
+         if (enlist_unique_header(rsp->headers, "Content-Type", BUILTIN_IMAGE_MIMETYPE))
          {
             free_http_response(rsp);
             return cgi_error_memory();
@@ -674,15 +703,32 @@ struct http_response *block_url(struct client_state *csp)
 
       else if (0 == strcmpic(p, "blank"))
       {
-         rsp->body = bindup(image_blank_gif_data, image_blank_gif_length);
+         rsp->body = bindup(image_blank_data, image_blank_length);
+         if (rsp->body == NULL)
+         {
+            free_http_response(rsp);
+            return cgi_error_memory();
+         }
+         rsp->content_length = image_blank_length;
+
+         if (enlist_unique_header(rsp->headers, "Content-Type", BUILTIN_IMAGE_MIMETYPE))
+         {
+            free_http_response(rsp);
+            return cgi_error_memory();
+         }
+      }
+
+      else if (0 == strcmpic(p, "pattern"))
+      {
+         rsp->body = bindup(image_pattern_data, image_pattern_length);
          if (rsp->body == NULL)
          {
             free_http_response(rsp);
             return cgi_error_memory();
          }
-         rsp->content_length = image_blank_gif_length;
+         rsp->content_length = image_pattern_length;
 
-         if (enlist_unique_header(rsp->headers, "Content-Type", "image/gif"))
+         if (enlist_unique_header(rsp->headers, "Content-Type", BUILTIN_IMAGE_MIMETYPE))
          {
             free_http_response(rsp);
             return cgi_error_memory();
@@ -704,6 +750,35 @@ struct http_response *block_url(struct client_state *csp)
             return cgi_error_memory();
          }
       }
+
+#else /* Following code is disabled for now */
+
+      /* and handle accordingly: */
+      if ((p == NULL) || (0 == strcmpic(p, "logo")))
+      {
+         p = CGI_PREFIX "send-banner?type=logo";
+      }
+      else if (0 == strcmpic(p, "blank"))
+      {
+         p = CGI_PREFIX "send-banner?type=blank";
+      }
+      else if (0 == strcmpic(p, "pattern"))
+      {
+         p = CGI_PREFIX "send-banner?type=pattern";
+      }
+      rsp->status = strdup("302 Local Redirect from Junkbuster");
+      if (rsp->status == NULL)
+      {
+         free_http_response(rsp);
+         return cgi_error_memory();
+      }
+
+      if (enlist_unique_header(rsp->headers, "Location", p))
+      {
+         free_http_response(rsp);
+         return cgi_error_memory();
+      }
+#endif /* Preceeding code is disabled for now */
    }
    else
 #endif /* def FEATURE_IMAGE_BLOCKING */
@@ -849,7 +924,7 @@ struct http_response *trust_url(struct client_state *csp)
     * Export the trust list
     */
    p = strdup("");
-   for (tl = csp->config->trust_list; (t = *tl) ; tl++)
+   for (tl = csp->config->trust_list; (t = *tl) != NULL ; tl++)
    {
       sprintf(buf, "<li>%s</li>\n", t->spec);
       string_append(&p, buf);
@@ -946,7 +1021,7 @@ struct http_response *redirect_url(struct client_state *csp)
    /*
     * find the last URL encoded in the request
     */
-   while ((p = strstr(p, "http://")))
+   while ((p = strstr(p, "http://")) != NULL)
    {
       q = p++;
    }
@@ -1107,7 +1182,7 @@ int is_untrusted_url(struct client_state *csp)
 
          FILE *fp;
 
-         if ((fp = fopen(csp->config->trustfile, "a")))
+         if (NULL != (fp = fopen(csp->config->trustfile, "a")))
          {
             char * path;
             char * path_end;
@@ -1158,16 +1233,17 @@ int is_untrusted_url(struct client_state *csp)
  *
  * Function    :  pcrs_filter_response
  *
- * Description :  Apply all the pcrs jobs from the joblist (re_filterfile)
- *                to the text buffer that's been accumulated in
- *                csp->iob->buf and set csp->content_length to the modified
- *                size and raise the CSP_FLAG_MODIFIED flag if appropriate.
+ * Description :  Ecexute all text substitutions from all applying
+ *                +filter actions on the text buffer that's been accumulated
+ *                in csp->iob->buf. If this changes the contents, set
+ *                csp->content_length to the modified size and raise the
+ *                CSP_FLAG_MODIFIED flag.
  *
  * Parameters  :
  *          1  :  csp = Current client state (buffers, headers, etc...)
  *
  * Returns     :  a pointer to the (newly allocated) modified buffer.
- *                or NULL in case something went wrong
+ *                or NULL if there were no hits or something went wrong
  *
  *********************************************************************/
 char *pcrs_filter_response(struct client_state *csp)
@@ -1180,14 +1256,23 @@ char *pcrs_filter_response(struct client_state *csp)
 
    struct file_list *fl;
    struct re_filterfile_spec *b;
+   struct list_entry *filtername;
 
-   /* Sanity first */
+   /* 
+    * Sanity first
+    */
    if (csp->iob->cur >= csp->iob->eod)
    {
       return(NULL);
    }
    size = csp->iob->eod - csp->iob->cur;
 
+   if ( ( NULL == (fl = csp->rlist) ) || ( NULL == fl->f) )
+   {
+      log_error(LOG_LEVEL_ERROR, "Unable to get current state of regexp filtering.");
+      return(NULL);
+   }
+
    /*
     * If the body has a "chunked" transfer-encoding,
     * get rid of it first, adjusting size and iob->eod
@@ -1203,30 +1288,42 @@ char *pcrs_filter_response(struct client_state *csp)
       csp->flags |= CSP_FLAG_MODIFIED;
    }
 
-   if ( ( NULL == (fl = csp->rlist) ) || ( NULL == (b = fl->f) ) )
+   /*
+    * For all applying +filter actions, look if a filter by that
+    * name exists and if yes, execute it's pcrs_joblist on the
+    * buffer.
+    */
+   for (b = fl->f; b; b = b->next)
    {
-      log_error(LOG_LEVEL_ERROR, "Unable to get current state of regexp filtering.");
-      return(NULL);
-   }
+      for (filtername = csp->action->multi[ACTION_MULTI_FILTER]->first;
+           filtername ; filtername = filtername->next)
+      {
+         if (strcmp(b->name, filtername->str) == 0)
+         {
+            int current_hits = 0;
 
-   if ( NULL == b->joblist )
-   {
-      log_error(LOG_LEVEL_RE_FILTER, "Empty joblist. Nothing to do.");
-      return(NULL);
-   }
+            if ( NULL == b->joblist )
+            {
+               log_error(LOG_LEVEL_RE_FILTER, "Filter %s has empty joblist. Nothing to do.", b->name);
+               return(NULL);
+            }
 
-   log_error(LOG_LEVEL_RE_FILTER, "re_filtering %s%s (size %d) ...",
-              csp->http->hostport, csp->http->path, size);
+            log_error(LOG_LEVEL_RE_FILTER, "re_filtering %s%s (size %d) with filter %s...",
+                      csp->http->hostport, csp->http->path, size, b->name);
 
-   /* Apply all jobs from the joblist */
-   for (job = b->joblist; NULL != job; job = job->next)
-   {
-      hits += pcrs_execute(job, old, size, &new, &size);
-      if (old != csp->iob->cur) free(old);
-      old=new;
-   }
+            /* Apply all jobs from the joblist */
+            for (job = b->joblist; NULL != job; job = job->next)
+            {
+               current_hits += pcrs_execute(job, old, size, &new, &size);
+               if (old != csp->iob->cur) free(old);
+               old=new;
+            }
 
-   log_error(LOG_LEVEL_RE_FILTER, " produced %d hits (new size %d).", hits, size);
+            log_error(LOG_LEVEL_RE_FILTER, " ...produced %d hits (new size %d).", current_hits, size);
+            hits += current_hits;
+         }
+      }
+   }
 
    /*
     * If there were no hits, destroy our copy and let
@@ -1266,7 +1363,7 @@ char *gif_deanimate_response(struct client_state *csp)
 {
    struct binbuffer *in, *out;
    char *p;
-   int size = csp->iob->eod - csp->iob->cur;
+   size_t size = csp->iob->eod - csp->iob->cur;
 
    /*
     * If the body has a "chunked" transfer-encoding,
@@ -1302,7 +1399,14 @@ char *gif_deanimate_response(struct client_state *csp)
    }
    else
    {
-      log_error(LOG_LEVEL_DEANIMATE, "Success! GIF shrunk from %d bytes to %d.", size, out->offset);
+      if ((int)size == out->offset)
+      {
+         log_error(LOG_LEVEL_DEANIMATE, "GIF not changed.");
+      }
+      else
+      {
+         log_error(LOG_LEVEL_DEANIMATE, "Success! GIF shrunk from %d bytes to %d.", size, out->offset);
+      }
       csp->content_length = out->offset;
       csp->flags |= CSP_FLAG_MODIFIED;
       p = out->buffer;