- Move get_filter_function() from jcc.c to filters.c
authorFabian Keil <fk@fabiankeil.de>
Sat, 29 Sep 2007 10:21:16 +0000 (10:21 +0000)
committerFabian Keil <fk@fabiankeil.de>
Sat, 29 Sep 2007 10:21:16 +0000 (10:21 +0000)
  so the filter functions can be static.
- Don't bother filtering body-less responses.

filters.c
filters.h
jcc.c

index a4757be..c3a7fdf 100644 (file)
--- a/filters.c
+++ b/filters.c
@@ -1,4 +1,4 @@
-const char filters_rcs[] = "$Id: filters.c,v 1.91 2007/09/02 15:31:20 fabiankeil Exp $";
+const char filters_rcs[] = "$Id: filters.c,v 1.92 2007/09/28 16:38:55 fabiankeil Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/filters.c,v $
@@ -40,6 +40,15 @@ const char filters_rcs[] = "$Id: filters.c,v 1.91 2007/09/02 15:31:20 fabiankeil
  *
  * Revisions   :
  *    $Log: filters.c,v $
+ *    Revision 1.92  2007/09/28 16:38:55  fabiankeil
+ *    - Execute content filters through execute_content_filter().
+ *    - Add prepare_for_filtering() so filter functions don't have to
+ *      care about de-chunking and decompression. As a side effect this enables
+ *      decompression for gif_deanimate_response() and jpeg_inspect_response().
+ *    - Change remove_chunked_transfer_coding()'s return type to jb_err.
+ *      Some clowns feel like chunking empty responses in which case
+ *      (size == 0) is valid but previously would be interpreted as error.
+ *
  *    Revision 1.91  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.
@@ -1740,7 +1749,7 @@ int is_untrusted_url(const struct client_state *csp)
  *                or NULL if there were no hits or something went wrong
  *
  *********************************************************************/
-char *pcrs_filter_response(struct client_state *csp)
+static char *pcrs_filter_response(struct client_state *csp)
 {
    int hits=0;
    size_t size, prev_size;
@@ -1926,7 +1935,7 @@ char *pcrs_filter_response(struct client_state *csp)
  *                or NULL in case something went wrong.
  *
  *********************************************************************/
-char *gif_deanimate_response(struct client_state *csp)
+static char *gif_deanimate_response(struct client_state *csp)
 {
    struct binbuffer *in, *out;
    char *p;
@@ -1985,7 +1994,7 @@ char *gif_deanimate_response(struct client_state *csp)
  *                or NULL in case something went wrong.
  *
  *********************************************************************/
-char *jpeg_inspect_response(struct client_state *csp)
+static char *jpeg_inspect_response(struct client_state *csp)
 {
    struct binbuffer  *in = NULL;
    struct binbuffer *out = NULL;
@@ -2034,6 +2043,87 @@ char *jpeg_inspect_response(struct client_state *csp)
 }
 
 
+/*********************************************************************
+ *
+ * Function    :  get_filter_function
+ *
+ * Description :  Decides which content filter function has
+ *                to be applied (if any).
+ *
+ *                XXX: Doesn't handle filter_popups()
+ *                because of the different prototype. Probably
+ *                we should ditch filter_popups() anyway, it's
+ *                even less reliable than popup blocking based
+ *                on pcrs filters.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *
+ * Returns     :  The content filter function to run, or
+ *                NULL if no content filter is active
+ *
+ *********************************************************************/
+filter_function_ptr get_filter_function(struct client_state *csp)
+{
+   filter_function_ptr filter_function = 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.
+    */
+   if ((csp->content_type & CT_TEXT) &&
+       (csp->rlist != NULL) &&
+       (!list_is_empty(csp->action->multi[ACTION_MULTI_FILTER])))
+   {
+      filter_function = pcrs_filter_response;
+   }
+   else if ((csp->content_type & CT_GIF)  &&
+            (csp->action->flags & ACTION_DEANIMATE))
+   {
+      filter_function = gif_deanimate_response;
+   }
+   else if ((csp->content_type & CT_JPEG)  &&
+            (csp->action->flags & ACTION_JPEG_INSPECT))
+   {
+      filter_function = jpeg_inspect_response;
+   }
+
+   return filter_function;
+}
+
+
 /*********************************************************************
  *
  * Function    :  remove_chunked_transfer_coding
@@ -2154,6 +2244,12 @@ static jb_err prepare_for_filtering(struct client_state *csp)
     */
    if (csp->content_type & (CT_GZIP|CT_DEFLATE))
    {
+      if (0 == csp->iob->eod - csp->iob->cur)
+      {
+         /* Nothing left after de-chunking. */
+         return JB_ERR_OK;
+      }
+
       err = decompress_iob(csp);
 
       if (JB_ERR_OK == err)
@@ -2188,12 +2284,21 @@ static jb_err prepare_for_filtering(struct client_state *csp)
  *          1  :  csp = Current client state (buffers, headers, etc...)
  *          2  :  content_filter = The filter function to execute
  *
- * Returns     :  JB_ERR_OK for success,
- *                JB_ERR_PARSE otherwise
+ * 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)
 {
+   if (0 == csp->iob->eod - csp->iob->cur)
+   {
+      /*
+       * No content (probably status code 301, 302 ...),
+       * no filtering necessary.
+       */
+      return NULL;
+   }
+
    if (JB_ERR_OK != prepare_for_filtering(csp))
    {
       /*
@@ -2205,7 +2310,9 @@ char *execute_content_filter(struct client_state *csp, filter_function_ptr conte
 
    if (0 == csp->iob->eod - csp->iob->cur)
    {
-      /* Empty buffer, nothing to do. */
+      /*
+       * Clown alarm: chunked and/or compressed nothing delivered.
+       */
       return NULL;
    }
 
index 09d47f8..12bfdd7 100644 (file)
--- a/filters.h
+++ b/filters.h
@@ -1,6 +1,6 @@
 #ifndef FILTERS_H_INCLUDED
 #define FILTERS_H_INCLUDED
-#define FILTERS_H_VERSION "$Id: filters.h,v 1.28 2007/09/02 15:31:20 fabiankeil Exp $"
+#define FILTERS_H_VERSION "$Id: filters.h,v 1.29 2007/09/28 16:38:55 fabiankeil Exp $"
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/filters.h,v $
  *
  * Revisions   :
  *    $Log: filters.h,v $
+ *    Revision 1.29  2007/09/28 16:38:55  fabiankeil
+ *    - Execute content filters through execute_content_filter().
+ *    - Add prepare_for_filtering() so filter functions don't have to
+ *      care about de-chunking and decompression. As a side effect this enables
+ *      decompression for gif_deanimate_response() and jpeg_inspect_response().
+ *    - Change remove_chunked_transfer_coding()'s return type to jb_err.
+ *      Some clowns feel like chunking empty responses in which case
+ *      (size == 0) is valid but previously would be interpreted as error.
+ *
  *    Revision 1.28  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.
@@ -301,9 +310,7 @@ extern const struct forward_spec *forward_url(struct http_request *http, struct
 typedef char *(*filter_function_ptr)();
 extern char *execute_content_filter(struct client_state *csp, filter_function_ptr content_filter);
 
-extern char *pcrs_filter_response(struct client_state *csp);
-extern char *gif_deanimate_response(struct client_state *csp);
-extern char *jpeg_inspect_response(struct client_state *csp);
+extern filter_function_ptr get_filter_function(struct client_state *csp);
 extern char *execute_single_pcrs_command(char *subject, const char *pcrs_command, int *hits);
 extern char *rewrite_url(char *old_url, const char *pcrs_command);
 extern char *get_last_url(char *subject, const char *redirect_mode);
diff --git a/jcc.c b/jcc.c
index e454d0e..7266e1a 100644 (file)
--- a/jcc.c
+++ b/jcc.c
@@ -1,4 +1,4 @@
-const char jcc_rcs[] = "$Id: jcc.c,v 1.149 2007/09/04 15:08:48 fabiankeil Exp $";
+const char jcc_rcs[] = "$Id: jcc.c,v 1.150 2007/09/28 16:39:29 fabiankeil Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/jcc.c,v $
@@ -33,6 +33,9 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.149 2007/09/04 15:08:48 fabiankeil Exp $"
  *
  * Revisions   :
  *    $Log: jcc.c,v $
+ *    Revision 1.150  2007/09/28 16:39:29  fabiankeil
+ *    Execute content filters through execute_content_filter().
+ *
  *    Revision 1.149  2007/09/04 15:08:48  fabiankeil
  *    Initialize req to NULL to make sure it's defined if the
  *    first read_socket() call fails. Reported by icmp30.
@@ -1114,6 +1117,7 @@ static const char NO_SERVER_DATA_RESPONSE[] =
    "Empty server or forwarder response.\r\n"
    "The connection was closed without sending any data.\r\n";
 
+#if 0
 /* XXX: should be a template */
 static const char NULL_BYTE_RESPONSE[] =
    "HTTP/1.0 400 Bad request received from browser\r\n"
@@ -1121,6 +1125,7 @@ static const char NULL_BYTE_RESPONSE[] =
    "Content-Type: text/plain\r\n"
    "Connection: close\r\n\r\n"
    "Bad request. Null byte(s) before end of request.\r\n";
+#endif
 
 /* XXX: should be a template */
 static const char MESSED_UP_REQUEST_RESPONSE[] =
@@ -1148,7 +1153,6 @@ struct cruncher
 };
 
 static int crunch_response_triggered(struct client_state *csp, const struct cruncher crunchers[]);
-static filter_function_ptr get_filter_function(struct client_state *csp);
 
 /* Complete list of cruncher functions */
 static const struct cruncher crunchers_all[] = {
@@ -1813,87 +1817,6 @@ static jb_err change_request_destination(struct client_state *csp)
 }
 
 
-/*********************************************************************
- *
- * Function    :  get_filter_function
- *
- * Description :  Decides which content filter function has
- *                to be applied (if any).
- *
- *                XXX: Doesn't handle filter_popups()
- *                because of the different prototype. Probably
- *                we should ditch filter_popups() anyway, it's
- *                even less reliable than popup blocking based
- *                on pcrs filters.
- *
- * Parameters  :
- *          1  :  csp = Current client state (buffers, headers, etc...)
- *
- * Returns     :  The content filter function to run, or
- *                NULL if no content filter is active
- *
- *********************************************************************/
-static filter_function_ptr get_filter_function(struct client_state *csp)
-{
-   filter_function_ptr filter_function = 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.
-    */
-   if ((csp->content_type & CT_TEXT) &&
-       (csp->rlist != NULL) &&
-       (!list_is_empty(csp->action->multi[ACTION_MULTI_FILTER])))
-   {
-      filter_function = pcrs_filter_response;
-   }
-   else if ((csp->content_type & CT_GIF)  &&
-            (csp->action->flags & ACTION_DEANIMATE))
-   {
-      filter_function = gif_deanimate_response;
-   }
-   else if ((csp->content_type & CT_JPEG)  &&
-            (csp->action->flags & ACTION_JPEG_INSPECT))
-   {
-      filter_function = jpeg_inspect_response;
-   }
-
-   return filter_function;
-}
-
 /*********************************************************************
  *
  * Function    :  chat