Sync with default.filter. Why isn't this file
[privoxy.git] / jcc.c
diff --git a/jcc.c b/jcc.c
index 0d6ef70..96302a1 100644 (file)
--- a/jcc.c
+++ b/jcc.c
@@ -1,4 +1,4 @@
-const char jcc_rcs[] = "$Id: jcc.c,v 1.172 2008/04/16 16:38:21 fabiankeil Exp $";
+const char jcc_rcs[] = "$Id: jcc.c,v 1.180 2008/05/21 15:26:32 fabiankeil Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/jcc.c,v $
@@ -33,6 +33,36 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.172 2008/04/16 16:38:21 fabiankeil Exp $"
  *
  * Revisions   :
  *    $Log: jcc.c,v $
+ *    Revision 1.180  2008/05/21 15:26:32  fabiankeil
+ *    - Mark csp as immutable for send_crunch_response().
+ *    - Fix comment spelling.
+ *
+ *    Revision 1.179  2008/05/20 20:13:32  fabiankeil
+ *    Factor update_server_headers() out of sed(), ditch the
+ *    first_run hack and make server_patterns_light static.
+ *
+ *    Revision 1.178  2008/05/10 13:23:38  fabiankeil
+ *    Don't provide get_header() with the whole client state
+ *    structure when it only needs access to csp->iob.
+ *
+ *    Revision 1.177  2008/05/10 11:51:12  fabiankeil
+ *    Make the "read the rest of the headers" loop a bit more readable.
+ *
+ *    Revision 1.176  2008/05/10 11:37:57  fabiankeil
+ *    - Instead of logging when the IIS5 hack is enabled, log when it fails.
+ *    - Remove useless comment.
+ *
+ *    Revision 1.175  2008/05/09 18:53:59  fabiankeil
+ *    Fix comment grammar.
+ *
+ *    Revision 1.174  2008/05/07 18:05:53  fabiankeil
+ *    Remove the pointless buffer in client_protocol_is_unsupported().
+ *
+ *    Revision 1.173  2008/05/06 15:09:00  fabiankeil
+ *    Least-effort fix for bug #1821930 (reported by Lee):
+ *    If the response doesn't look like HTTP,
+ *    tell the client and log the problem.
+ *
  *    Revision 1.172  2008/04/16 16:38:21  fabiankeil
  *    Don't pass the whole csp structure to flush_socket()
  *    when it only needs a file descriptor and a buffer.
@@ -1086,7 +1116,7 @@ static int client_protocol_is_unsupported(const struct client_state *csp, char *
 static jb_err get_request_destination_elsewhere(struct client_state *csp, struct list *headers);
 static jb_err get_server_headers(struct client_state *csp);
 static const char *crunch_reason(const struct http_response *rsp);
-static void send_crunch_response(struct client_state *csp, struct http_response *rsp);
+static void send_crunch_response(const struct client_state *csp, struct http_response *rsp);
 /*
  * static int request_contains_null_bytes(const struct client_state *csp, char *buf, int len);
  */
@@ -1320,8 +1350,6 @@ static void sig_handler(int the_signal)
  *********************************************************************/
 static int client_protocol_is_unsupported(const struct client_state *csp, char *req)
 {
-   char buf[BUFFER_SIZE];
-
    /*
     * If it's a FTP or gopher request, we don't support it.
     *
@@ -1337,21 +1365,26 @@ static int client_protocol_is_unsupported(const struct client_state *csp, char *
     */
    if (!strncmpic(req, "GET ftp://", 10) || !strncmpic(req, "GET gopher://", 13))
    {
+      const char *response = NULL;
+      const char *protocol = NULL;
+
       if (!strncmpic(req, "GET ftp://", 10))
       {
-         strlcpy(buf, FTP_RESPONSE, sizeof(buf));
-         log_error(LOG_LEVEL_ERROR, "%s tried to use Privoxy as FTP proxy: %s",
-            csp->ip_addr_str, req);
+         response = FTP_RESPONSE;
+         protocol = "FTP";
       }
       else
       {
-         strlcpy(buf, GOPHER_RESPONSE, sizeof(buf));
-         log_error(LOG_LEVEL_ERROR, "%s tried to use Privoxy as gopher proxy: %s",
-            csp->ip_addr_str, req);
+         response = GOPHER_RESPONSE;
+         protocol = "GOPHER";
       }
-      log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 400 0", csp->ip_addr_str, req);
+      log_error(LOG_LEVEL_ERROR,
+         "%s tried to use Privoxy as %s proxy: %s",
+         csp->ip_addr_str, protocol, req);
+      log_error(LOG_LEVEL_CLF,
+         "%s - - [%T] \"%s\" 400 0", csp->ip_addr_str, req);
       freez(req);
-      write_socket(csp->cfd, buf, strlen(buf));
+      write_socket(csp->cfd, response, strlen(response));
 
       return TRUE;
    }
@@ -1459,7 +1492,7 @@ static jb_err get_server_headers(struct client_state *csp)
    int continue_hack_in_da_house = 0;
    char * header;
 
-   while (((header = get_header(csp)) != NULL) || continue_hack_in_da_house)
+   while (((header = get_header(csp->iob)) != NULL) || continue_hack_in_da_house)
    {
       if (header == NULL)
       {
@@ -1476,7 +1509,7 @@ static jb_err get_server_headers(struct client_state *csp)
       {
          /*
           * It's a bodyless continue response, don't
-          * stop header parsing after reaching it's end.
+          * stop header parsing after reaching its end.
           *
           * As a result Privoxy will concatenate the
           * next response's head and parse and deliver
@@ -1510,7 +1543,6 @@ static jb_err get_server_headers(struct client_state *csp)
          return JB_ERR_PARSE;
       }
 
-      /* Enlist header */
       if (JB_ERR_MEMORY == enlist(csp->headers, header))
       {
          /*
@@ -1603,7 +1635,7 @@ static const char *crunch_reason(const struct http_response *rsp)
  * Returns     :  Nothing.
  *
  *********************************************************************/
-static void send_crunch_response(struct client_state *csp, struct http_response *rsp)
+static void send_crunch_response(const struct client_state *csp, struct http_response *rsp)
 {
       const struct http_request *http = csp->http;
       char status_code[4];
@@ -1968,7 +2000,7 @@ static void chat(struct client_state *csp)
          return;
       }
 
-      req = get_header(csp);
+      req = get_header(csp->iob);
 
    } while ((NULL != req) && ('\0' == *req));
 
@@ -2056,8 +2088,20 @@ static void chat(struct client_state *csp)
    init_list(headers);
    for (;;)
    {
-      if ( ( ( p = get_header(csp) ) != NULL) && ( *p == '\0' ) )
+      p = get_header(csp->iob);
+
+      if (p == NULL)
       {
+         /* There are no additional headers to read. */
+         break;
+      }
+
+      if (*p == '\0')
+      {
+         /*
+          * We didn't receive a complete header
+          * line yet, get the rest of it.
+          */
          len = read_socket(csp->cfd, buf, sizeof(buf) - 1);
          if (len <= 0)
          {
@@ -2066,23 +2110,25 @@ static void chat(struct client_state *csp)
             return;
          }
          
-         /*
-          * If there is no memory left for buffering the
-          * request, there is nothing we can do but hang up
-          */
          if (add_to_iob(csp, buf, len))
          {
+            /*
+             * If there is no memory left for buffering the
+             * request, there is nothing we can do but hang up
+             */
             destroy_list(headers);
             return;
          }
-         continue;
       }
-
-      if (p == NULL) break;
-
-      enlist(headers, p);
-      freez(p);
-
+      else
+      {
+         /*
+          * We were able to read a complete
+          * header and can finaly enlist it.
+          */
+         enlist(headers, p);
+         freez(p);
+      }
    }
 
    if (http->host == NULL)
@@ -2137,7 +2183,7 @@ static void chat(struct client_state *csp)
    list_append_list_unique(csp->headers, headers);
    destroy_list(headers);
 
-   err = sed(client_patterns, add_client_headers, csp);
+   err = sed(csp, FILTER_CLIENT_HEADERS);
    if (JB_ERR_OK != err)
    {
       assert(err == JB_ERR_PARSE);
@@ -2498,9 +2544,10 @@ static void chat(struct client_state *csp)
                      csp->content_length = (size_t)(csp->iob->eod - csp->iob->cur);
                   }
 
-                  if (JB_ERR_OK != sed(server_patterns_light, NULL, csp))
+                  if (JB_ERR_OK != update_server_headers(csp))
                   {
-                     log_error(LOG_LEVEL_FATAL, "Failed to parse server headers.");
+                     log_error(LOG_LEVEL_FATAL,
+                        "Failed to update server headers. after filtering.");
                   }
 
                   hdr = list_to_text(csp->headers);
@@ -2510,12 +2557,6 @@ static void chat(struct client_state *csp)
                      log_error(LOG_LEVEL_FATAL, "Out of memory parsing server header");
                   }
 
-                  /*
-                   * Shouldn't happen because this was the second sed run
-                   * and tags are only created for the first one.
-                   */
-                  assert(!crunch_response_triggered(csp, crunchers_all));
-
                   if (write_socket(csp->cfd, hdr, strlen(hdr))
                    || write_socket(csp->cfd, p != NULL ? p : csp->iob->cur, csp->content_length))
                   {
@@ -2536,9 +2577,6 @@ 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);
 
@@ -2651,6 +2689,8 @@ static void chat(struct client_state *csp)
                    * and there isn't anything
                    * we can do about it.
                    */
+                  log_error(LOG_LEVEL_INFO,
+                     "MS IIS5 hack didn't produce valid headers.");
                   break;
                }
                else
@@ -2697,10 +2737,11 @@ static void chat(struct client_state *csp)
                return;
             }
 
-            /* we have now received the entire header.
+            /*
+             * We have now received the entire server header,
              * filter it and send the result to the client
              */
-            if (JB_ERR_OK != sed(server_patterns, add_server_headers, csp))
+            if (JB_ERR_OK != sed(csp, FILTER_SERVER_HEADERS))
             {
                log_error(LOG_LEVEL_FATAL, "Failed to parse server headers.");
             }
@@ -2766,6 +2807,8 @@ static void chat(struct client_state *csp)
              */
             if (ms_iis5_hack)
             {
+               log_error(LOG_LEVEL_INFO,
+                  "Closed server connection detected with MS IIS5 hack enabled.");
                break;
             }
          }
@@ -2996,7 +3039,7 @@ int main(int argc, const char *argv[])
     * Parse the command line arguments
     *
     * XXX: simply printing usage information in case of
-    * invalid arguments isn't particular user friendly.
+    * invalid arguments isn't particularly user friendly.
     */
    while (++argc_pos < argc)
    {