Trailing dots in old-school domain patterns mean "(\..*)?", not "\..*".
[privoxy.git] / jcc.c
diff --git a/jcc.c b/jcc.c
index f58152c..22f3cc0 100644 (file)
--- a/jcc.c
+++ b/jcc.c
@@ -1,4 +1,4 @@
-const char jcc_rcs[] = "$Id: jcc.c,v 1.174 2008/05/07 18:05:53 fabiankeil Exp $";
+const char jcc_rcs[] = "$Id: jcc.c,v 1.181 2008/05/21 15:47:15 fabiankeil Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/jcc.c,v $
@@ -33,6 +33,32 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.174 2008/05/07 18:05:53 fabiankeil Exp $"
  *
  * Revisions   :
  *    $Log: jcc.c,v $
+ *    Revision 1.181  2008/05/21 15:47:15  fabiankeil
+ *    Streamline sed()'s prototype and declare
+ *    the header parse and add structures static.
+ *
+ *    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().
  *
@@ -1094,7 +1120,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);
  */
@@ -1470,7 +1496,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)
       {
@@ -1487,7 +1513,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
@@ -1521,7 +1547,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))
       {
          /*
@@ -1614,7 +1639,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];
@@ -1897,10 +1922,15 @@ static jb_err change_request_destination(struct client_state *csp)
       log_error(LOG_LEVEL_ERROR, "Couldn't parse rewritten request: %s.",
          jb_err_to_string(err));
    }
-   http->ocmd = strdup(http->cmd); /* XXX: ocmd is a misleading name */
-   if (http->ocmd == NULL)
+   else
    {
-      log_error(LOG_LEVEL_FATAL, "Out of memory copying rewritten HTTP request line");
+      /* XXX: ocmd is a misleading name */
+      http->ocmd = strdup(http->cmd);
+      if (http->ocmd == NULL)
+      {
+         log_error(LOG_LEVEL_FATAL,
+            "Out of memory copying rewritten HTTP request line");
+      }
    }
 
    return err;
@@ -1979,7 +2009,7 @@ static void chat(struct client_state *csp)
          return;
       }
 
-      req = get_header(csp);
+      req = get_header(csp->iob);
 
    } while ((NULL != req) && ('\0' == *req));
 
@@ -2067,8 +2097,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)
          {
@@ -2077,23 +2119,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)
@@ -2148,7 +2192,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);
@@ -2509,9 +2553,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);
@@ -2521,12 +2566,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))
                   {
@@ -2547,9 +2586,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);
 
@@ -2662,6 +2698,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
@@ -2708,10 +2746,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.");
             }
@@ -2777,6 +2816,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;
             }
          }