Regenerated config file for 3.0.7 (beta) release.
[privoxy.git] / jcc.c
diff --git a/jcc.c b/jcc.c
index d17c0fb..482e810 100644 (file)
--- a/jcc.c
+++ b/jcc.c
@@ -1,4 +1,4 @@
-const char jcc_rcs[] = "$Id: jcc.c,v 1.148 2007/08/26 16:47:13 fabiankeil Exp $";
+const char jcc_rcs[] = "$Id: jcc.c,v 1.157 2007/11/03 17:34:49 fabiankeil Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/jcc.c,v $
@@ -33,6 +33,45 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.148 2007/08/26 16:47:13 fabiankeil Exp $"
  *
  * Revisions   :
  *    $Log: jcc.c,v $
+ *    Revision 1.157  2007/11/03 17:34:49  fabiankeil
+ *    Log the "weak randomization factor" warning only
+ *    once for mingw32 and provide some more details.
+ *
+ *    Revision 1.156  2007/11/01 18:20:58  fabiankeil
+ *    Initialize log module after initializing mutexes, future
+ *    deadlocks in that code should now work cross-platform.
+ *
+ *    Revision 1.155  2007/10/23 20:12:45  fabiankeil
+ *    Fix first CSUCCEED line to end in \r\n as required by RFC1945.
+ *    Reported by Bert van Leeuwen in BR#1818808.
+ *
+ *    Revision 1.154  2007/10/19 17:00:08  fabiankeil
+ *    Downgrade "Flushing header and buffers" message to LOG_LEVEL_INFO.
+ *
+ *    Revision 1.153  2007/10/14 14:12:41  fabiankeil
+ *    When in daemon mode, close stderr after the configuration file has been
+ *    parsed the first time. If logfile isn't set, stop logging. Fixes BR#897436.
+ *
+ *    Revision 1.152  2007/10/04 18:03:34  fabiankeil
+ *    - Fix a crash when parsing invalid requests whose first header
+ *      is rejected by get_header(). Regression (re?)introduced
+ *      in r1.143 by yours truly.
+ *    - Move ACTION_VANILLA_WAFER handling into parsers.c's
+ *      client_cookie_adder() to make sure send-vanilla-wafer can be
+ *      controlled through tags (and thus regression-tested).
+ *
+ *    Revision 1.151  2007/09/29 10:21:16  fabiankeil
+ *    - Move get_filter_function() from jcc.c to filters.c
+ *      so the filter functions can be static.
+ *    - Don't bother filtering body-less responses.
+ *
+ *    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.
+ *
  *    Revision 1.148  2007/08/26 16:47:13  fabiankeil
  *    Add Stephen Gildea's --pre-chroot-nslookup patch [#1276666],
  *    extensive comments moved to user manual.
@@ -1053,19 +1092,9 @@ const char *pidfile = NULL;
 int received_hup_signal = 0;
 #endif /* defined unix */
 
-/* The vanilla wafer. */
-static const char VANILLA_WAFER[] =
-   "NOTICE=TO_WHOM_IT_MAY_CONCERN_"
-   "Do_not_send_me_any_copyrighted_information_other_than_the_"
-   "document_that_I_am_requesting_or_any_of_its_necessary_components._"
-   "In_particular_do_not_send_me_any_cookies_that_"
-   "are_subject_to_a_claim_of_copyright_by_anybody._"
-   "Take_notice_that_I_refuse_to_be_bound_by_any_license_condition_"
-   "(copyright_or_otherwise)_applying_to_any_cookie._";
-
 /* HTTP snipplets. */
 static const char CSUCCEED[] =
-   "HTTP/1.0 200 Connection established\n"
+   "HTTP/1.0 200 Connection established\r\n"
    "Proxy-Agent: Privoxy/" VERSION "\r\n\r\n";
 
 static const char CHEADER[] =
@@ -1110,6 +1139,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"
@@ -1117,6 +1147,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[] =
@@ -1129,8 +1160,6 @@ static const char MESSED_UP_REQUEST_RESPONSE[] =
 /* A function to crunch a response */
 typedef struct http_response *(*crunch_func_ptr)(struct client_state *);
 
-typedef char *(*filter_function_ptr)();
-
 /* Crunch function flags */
 #define CF_NO_FLAGS        0
 /* Cruncher applies to forced requests as well */
@@ -1146,7 +1175,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[] = {
@@ -1811,87 +1839,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
@@ -1971,7 +1918,7 @@ static void chat(struct client_state *csp)
 
    } while ((NULL != req) && ('\0' == *req));
 
-   if (NULL != req)
+   if ((NULL != req) && ('\0' != *req))
    {
       /* Request received. Validate and parse it. */
 
@@ -2134,16 +2081,6 @@ static void chat(struct client_state *csp)
    list_append_list_unique(csp->headers, headers);
    destroy_list(headers);
 
-   /*
-    * If the user has not supplied any wafers, and the user has not
-    * told us to suppress the vanilla wafer, then send the vanilla wafer.
-    */
-   if (list_is_empty(csp->action->multi[ACTION_MULTI_WAFER])
-       && ((csp->action->flags & ACTION_VANILLA_WAFER) != 0))
-   {
-      enlist(csp->action->multi[ACTION_MULTI_WAFER], VANILLA_WAFER);
-   }
-
    err = sed(client_patterns, add_client_headers, csp);
    if (JB_ERR_OK != err)
    {
@@ -2176,7 +2113,8 @@ static void chat(struct client_state *csp)
       /* Never get here - LOG_LEVEL_FATAL causes program exit */
    }
 
-   /* build the http request to send to the server
+   /*
+    * build the http request to send to the server
     * we have to do one of the following:
     *
     * create = use the original HTTP request to create a new
@@ -2534,12 +2472,13 @@ static void chat(struct client_state *csp)
                 */
                if (content_filter)
                {
+                  p = execute_content_filter(csp, content_filter);
                   /*
                    * If the content filter fails, use the original
                    * buffer and length.
                    * (see p != NULL ? p : csp->iob->cur below)
                    */
-                  if (NULL == (p = (*content_filter)(csp)))
+                  if (NULL == p)
                   {
                      csp->content_length = (size_t)(csp->iob->eod - csp->iob->cur);
                   }
@@ -2582,6 +2521,9 @@ static void chat(struct client_state *csp)
              * This is NOT the body, so
              * Let's pretend the server just sent us a blank line.
              */
+            log_error(LOG_LEVEL_INFO,
+               "Malformerd HTTP headers detected and MS IIS5 hack enabled. "
+               "Expect an invalid response or even no response at all.");
             snprintf(buf, sizeof(buf), "\r\n");
             len = (int)strlen(buf);
 
@@ -2613,7 +2555,7 @@ static void chat(struct client_state *csp)
                   size_t hdrlen;
                   int flushed;
 
-                  log_error(LOG_LEVEL_ERROR, "Flushing header and buffers. Stepping back from filtering.");
+                  log_error(LOG_LEVEL_INFO, "Flushing header and buffers. Stepping back from filtering.");
 
                   hdr = list_to_text(csp->headers);
                   if (hdr == NULL)
@@ -3172,6 +3114,7 @@ int main(int argc, const char *argv[])
    files->next = NULL;
    clients->next = NULL;
 
+   /* XXX: factor out initialising after the next stable release. */
 #ifdef AMIGA
    InitAmiga();
 #elif defined(_WIN32)
@@ -3181,9 +3124,21 @@ int main(int argc, const char *argv[])
    /* Prepare mutexes if supported and necessary. */
    initialize_mutexes();
 
+   /* Enable logging until further notice. */
+   init_log_module(Argv[0]);
+
    random_seed = (unsigned int)time(NULL);
 #ifdef HAVE_RANDOM
    srandom(random_seed);
+#elif defined (_WIN32)
+   /*
+    * See pick_from_range() in miscutil.c for details.
+    */
+   log_error(LOG_LEVEL_INFO,
+      "No thread-safe PRNG implemented for your platform. "
+      "Using weak \'randomization\' factor which will "
+      "limit the already questionable usefulness of "
+      "header-time-randomizing actions (disabled by default).");
 #else
    srand(random_seed);
 #endif /* ifdef HAVE_RANDOM */
@@ -3291,10 +3246,9 @@ int main(int argc, const char *argv[])
          close ( fd );
       }
 #endif /* 1 */
-      /* FIXME: should close stderr (fd 2) here too, but the test
-       * for existence
-       * and load config file is done in listen_loop() and puts
-       * some messages on stderr there.
+      /*
+       * stderr (fd 2) will be closed later on, when the
+       * log file has been parsed.
        */
 
       close( 0 );
@@ -3533,7 +3487,7 @@ static void listen_loop(void)
        */
       if (received_hup_signal)
       {
-         init_error_log(Argv[0], config->logfile, config->debug);
+         init_error_log(Argv[0], config->logfile);
          received_hup_signal = 0;
       }
 #endif