Remove useless parentheses in get_destination_from_headers()
[privoxy.git] / filters.c
index 761ac81..dd554ba 100644 (file)
--- a/filters.c
+++ b/filters.c
@@ -1,4 +1,4 @@
-const char filters_rcs[] = "$Id: filters.c,v 1.126 2010/01/10 13:53:43 ler762 Exp $";
+const char filters_rcs[] = "$Id: filters.c,v 1.140 2011/03/03 14:47:28 fabiankeil Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/filters.c,v $
@@ -13,7 +13,7 @@ const char filters_rcs[] = "$Id: filters.c,v 1.126 2010/01/10 13:53:43 ler762 Ex
  *                   `execute_single_pcrs_command', `rewrite_url',
  *                   `get_last_url'
  *
- * Copyright   :  Written by and Copyright (C) 2001, 2004-2009 the
+ * Copyright   :  Written by and Copyright (C) 2001-2010 the
  *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
@@ -50,11 +50,6 @@ const char filters_rcs[] = "$Id: filters.c,v 1.126 2010/01/10 13:53:43 ler762 Ex
 #include <string.h>
 #include <assert.h>
 
-#ifdef HAVE_RFC2553
-#include <netdb.h>
-#include <sys/socket.h>
-#endif /* def HAVE_RFC2553 */
-
 #ifndef _WIN32
 #ifndef __OS2__
 #include <unistd.h>
@@ -98,6 +93,8 @@ const char filters_h_rcs[] = FILTERS_H_VERSION;
  */
 #define ijb_isdigit(__X) isdigit((int)(unsigned char)(__X))
 
+typedef char *(*filter_function_ptr)();
+static filter_function_ptr get_filter_function(const struct client_state *csp);
 static jb_err remove_chunked_transfer_coding(char *buffer, size_t *size);
 static jb_err prepare_for_filtering(struct client_state *csp);
 
@@ -292,6 +289,10 @@ int block_acl(const struct access_control_addr *dst, const struct client_state *
             {
                return(0);
             }
+            else
+            {
+               return(1);
+            }
          }
          else if (
 #ifdef HAVE_RFC2553
@@ -623,7 +624,6 @@ struct http_response *block_url(struct client_state *csp)
             return cgi_error_memory();
          }
       }
-
       else if (0 == strcmpic(p, "blank"))
       {
          rsp->status = strdup("403 Request blocked by Privoxy");
@@ -646,7 +646,6 @@ struct http_response *block_url(struct client_state *csp)
             return cgi_error_memory();
          }
       }
-
       else
       {
          rsp->status = strdup("302 Local Redirect from Privoxy");
@@ -729,11 +728,11 @@ struct http_response *block_url(struct client_state *csp)
            && !strstr(p, "compatible")    /* MSIE */
            && !strstr(p, "Opera"))        /* and Opera. */
       {
-         rsp->status = strdup("200 Request for blocked URL");
+         rsp->status = strdup("200 Request blocked by Privoxy");
       }
       else
       {
-         rsp->status = strdup("403 Request for blocked URL");
+         rsp->status = strdup("403 Request blocked by Privoxy");
       }
 
       if (rsp->status == NULL)
@@ -797,7 +796,7 @@ struct http_response *block_url(struct client_state *csp)
          return cgi_error_memory();
       }
    }
-   rsp->reason = RSP_REASON_BLOCKED;
+   rsp->crunch_reason = BLOCKED;
 
    return finish_http_response(csp, rsp);
 
@@ -957,7 +956,7 @@ struct http_response *trust_url(struct client_state *csp)
       free_http_response(rsp);
       return cgi_error_memory();
    }
-   rsp->reason = RSP_REASON_UNTRUSTED;
+   rsp->crunch_reason = UNTRUSTED;
 
    return finish_http_response(csp, rsp);
 }
@@ -1003,10 +1002,9 @@ pcrs_job *compile_dynamic_pcrs_job_list(const struct client_state *csp, const st
       dummy = pcrs_compile_dynamic_command(pattern->str, variables, &error);
       if (NULL == dummy)
       {
-         assert(error < 0);
          log_error(LOG_LEVEL_ERROR,
-            "Adding filter job \'%s\' to dynamic filter %s failed: %s",
-            pattern->str, b->name, pcrs_strerror(error));
+            "Compiling dynamic pcrs job '%s' for '%s' failed with error code %d: %s",
+            pattern->str, b->name, error, pcrs_strerror(error));
          continue;
       }
       else
@@ -1297,7 +1295,7 @@ struct http_response *redirect_url(struct client_state *csp)
             free_http_response(rsp);
             return cgi_error_memory();
          }
-         rsp->reason = RSP_REASON_REDIRECTED;
+         rsp->crunch_reason = REDIRECTED;
          freez(new_url);
 
          return finish_http_response(csp, rsp);
@@ -1512,7 +1510,8 @@ int is_untrusted_url(const struct client_state *csp)
  *********************************************************************/
 static char *pcrs_filter_response(struct client_state *csp)
 {
-   int hits=0;
+   int hits = 0;
+   int i;
    size_t size, prev_size;
 
    char *old = NULL;
@@ -1523,8 +1522,6 @@ static char *pcrs_filter_response(struct client_state *csp)
    struct re_filterfile_spec *b;
    struct list_entry *filtername;
 
-   int i, found_filters = 0;
-
    /* 
     * Sanity first
     */
@@ -1533,23 +1530,7 @@ static char *pcrs_filter_response(struct client_state *csp)
       return(NULL);
    }
 
-   /*
-    * Need to check the set of re_filterfiles...
-    */
-   for (i = 0; i < MAX_AF_FILES; i++)
-   {
-      fl = csp->rlist[i];
-      if (NULL != fl)
-      {
-         if (NULL != fl->f)
-         {
-           found_filters = 1;
-           break;
-         }
-      }
-   }
-
-   if (0 == found_filters)
+   if (filters_available(csp) == FALSE)
    {
       log_error(LOG_LEVEL_ERROR, "Inconsistent configuration: "
          "content filtering enabled, but no content filters available.");
@@ -1757,48 +1738,10 @@ static char *gif_deanimate_response(struct client_state *csp)
  *                NULL if no content filter is active
  *
  *********************************************************************/
-filter_function_ptr get_filter_function(struct client_state *csp)
+static filter_function_ptr get_filter_function(const struct client_state *csp)
 {
    filter_function_ptr filter_function = NULL;
 
-   if ((csp->content_type & CT_TABOO)
-      && !(csp->action->flags & ACTION_FORCE_TEXT_MODE))
-   {
-      return NULL;
-   }
-
-   /*
-    * Are we enabling text mode by force?
-    */
-   if (csp->action->flags & ACTION_FORCE_TEXT_MODE)
-   {
-      /*
-       * Do we really have to?
-       */
-      if (csp->content_type & CT_TEXT)
-      {
-         log_error(LOG_LEVEL_HEADER, "Text mode is already enabled.");   
-      }
-      else
-      {
-         csp->content_type |= CT_TEXT;
-         log_error(LOG_LEVEL_HEADER, "Text mode enabled by force. Take cover!");   
-      }
-   }
-
-   if (!(csp->content_type & CT_DECLARED))
-   {
-      /*
-       * The server didn't bother to declare a MIME-Type.
-       * Assume it's text that can be filtered.
-       *
-       * This also regulary happens with 304 responses,
-       * therefore logging anything here would cause
-       * too much noise.
-       */
-      csp->content_type |= CT_TEXT;
-   }
-
    /*
     * Choose the applying filter function based on
     * the content type and action settings.
@@ -1861,8 +1804,14 @@ static jb_err remove_chunked_transfer_coding(char *buffer, size_t *size)
 
       if ((newsize += chunksize) >= *size)
       {
+         /*
+          * XXX: The message is a bit confusing. Isn't the real problem that
+          *      the specified chunk size is greater than the number of bytes
+          *      left in the buffer? This probably means the connection got
+          *      closed prematurely. To be investigated after 3.0.17 is out.
+          */
          log_error(LOG_LEVEL_ERROR,
-            "Chunk size %d exceeds buffer size %d in  \"chunked\" transfer coding",
+            "Chunk size %d exceeds buffer size %d in \"chunked\" transfer coding",
             chunksize, *size);
          return JB_ERR_PARSE;
       }
@@ -1966,20 +1915,23 @@ static jb_err prepare_for_filtering(struct client_state *csp)
 
 /*********************************************************************
  *
- * Function    :  execute_content_filter
+ * Function    :  execute_content_filters
  *
  * Description :  Executes a given content filter.
  *
  * Parameters  :
  *          1  :  csp = Current client state (buffers, headers, etc...)
- *          2  :  content_filter = The filter function to execute
  *
  * Returns     :  Pointer to the modified buffer, or
  *                NULL if filtering failed or wasn't necessary.
  *
  *********************************************************************/
-char *execute_content_filter(struct client_state *csp, filter_function_ptr content_filter)
+char *execute_content_filters(struct client_state *csp)
 {
+   filter_function_ptr content_filter;
+
+   assert(content_filters_enabled(csp->action));
+
    if (0 == csp->iob->eod - csp->iob->cur)
    {
       /*
@@ -2005,6 +1957,8 @@ char *execute_content_filter(struct client_state *csp, filter_function_ptr conte
       return NULL;
    }
 
+   content_filter = get_filter_function(csp);
+
    return ((*content_filter)(csp));
 }
 
@@ -2309,7 +2263,7 @@ struct http_response *direct_response(struct client_state *csp)
                }
 
                rsp->is_static = 1;
-               rsp->reason = RSP_REASON_UNSUPPORTED;
+               rsp->crunch_reason = UNSUPPORTED;
 
                return(finish_http_response(csp, rsp));
             }
@@ -2320,6 +2274,81 @@ struct http_response *direct_response(struct client_state *csp)
 }
 
 
+/*********************************************************************
+ *
+ * Function    :  content_requires_filtering
+ *
+ * Description :  Checks whether there are any content filters
+ *                enabled for the current request and if they
+ *                can actually be applied..
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *
+ * Returns     :  TRUE for yes, FALSE otherwise
+ *
+ *********************************************************************/
+int content_requires_filtering(struct client_state *csp)
+{
+   if ((csp->content_type & CT_TABOO)
+      && !(csp->action->flags & ACTION_FORCE_TEXT_MODE))
+   {
+      return FALSE;
+   }
+
+   /*
+    * Are we enabling text mode by force?
+    */
+   if (csp->action->flags & ACTION_FORCE_TEXT_MODE)
+   {
+      /*
+       * Do we really have to?
+       */
+      if (csp->content_type & CT_TEXT)
+      {
+         log_error(LOG_LEVEL_HEADER, "Text mode is already enabled.");
+      }
+      else
+      {
+         csp->content_type |= CT_TEXT;
+         log_error(LOG_LEVEL_HEADER, "Text mode enabled by force. Take cover!");
+      }
+   }
+
+   if (!(csp->content_type & CT_DECLARED))
+   {
+      /*
+       * The server didn't bother to declare a MIME-Type.
+       * Assume it's text that can be filtered.
+       *
+       * This also regulary happens with 304 responses,
+       * therefore logging anything here would cause
+       * too much noise.
+       */
+      csp->content_type |= CT_TEXT;
+   }
+
+   /*
+    * Choose the applying filter function based on
+    * the content type and action settings.
+    */
+   if ((csp->content_type & CT_TEXT) &&
+       (csp->rlist != NULL) &&
+       (!list_is_empty(csp->action->multi[ACTION_MULTI_FILTER])))
+   {
+      return TRUE;
+   }
+   else if ((csp->content_type & CT_GIF)  &&
+            (csp->action->flags & ACTION_DEANIMATE))
+   {
+      return TRUE;
+   }
+
+   return FALSE;
+
+}
+
+
 /*********************************************************************
  *
  * Function    :  content_filters_enabled
@@ -2339,6 +2368,34 @@ int content_filters_enabled(const struct current_action_spec *action)
       !list_is_empty(action->multi[ACTION_MULTI_FILTER]));
 }
 
+
+/*********************************************************************
+ *
+ * Function    :  filters_available
+ *
+ * Description :  Checks whether there are any filters available.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *
+ * Returns     :  TRUE for yes, FALSE otherwise.
+ *
+ *********************************************************************/
+int filters_available(const struct client_state *csp)
+{
+   int i;
+   for (i = 0; i < MAX_AF_FILES; i++)
+   {
+      const struct file_list *fl = csp->rlist[i];
+      if ((NULL != fl) && (NULL != fl->f))
+      {
+         return TRUE;
+      }
+   }
+   return FALSE;
+}
+
+
 /*
   Local Variables:
   tab-width: 3