If we got a complete client request, keep watching the client socket until the next...
[privoxy.git] / jcc.c
diff --git a/jcc.c b/jcc.c
index 950c4a2..f0e7fe9 100644 (file)
--- a/jcc.c
+++ b/jcc.c
@@ -1,4 +1,4 @@
-const char jcc_rcs[] = "$Id: jcc.c,v 1.285 2009/09/06 14:15:46 fabiankeil Exp $";
+const char jcc_rcs[] = "$Id: jcc.c,v 1.289 2009/09/10 14:58:54 fabiankeil Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/jcc.c,v $
@@ -1599,6 +1599,7 @@ static void chat(struct client_state *csp)
    /* Skeleton for HTTP response, if we should intercept the request */
    struct http_response *rsp;
    struct timeval timeout;
+   int watch_client_socket = 1;
 
    memset(buf, 0, sizeof(buf));
 
@@ -1840,7 +1841,7 @@ static void chat(struct client_state *csp)
       FD_ZERO(&rfds);
 #endif
 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
-      if ((csp->flags & CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ))
+      if (!watch_client_socket)
       {
          maxfd = csp->sfd;
       }
@@ -1869,7 +1870,7 @@ static void chat(struct client_state *csp)
       {
          log_error(LOG_LEVEL_CONNECT,
             "Done reading from server. Expected content length: %llu. "
-            "Actual content length: %llu. Most recently received: %d.",
+            "Actual content length: %llu. Bytes most recently read: %d.",
             csp->expected_content_length, byte_count, len);
          len = 0;
          /*
@@ -1911,14 +1912,40 @@ static void chat(struct client_state *csp)
        */
       if (FD_ISSET(csp->cfd, &rfds))
       {
-         unsigned max_bytes_to_read = sizeof(buf) - 1;
+         int max_bytes_to_read = sizeof(buf) - 1;
 
 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
+         if ((csp->flags & CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ))
+         {
+            if (data_is_available(csp->cfd, 0))
+            {
+               /*
+                * If the next request is already waiting, we have
+                * to stop select()ing the client socket. Otherwise
+                * we would always return right away and get nothing
+                * else done.
+                */
+               watch_client_socket = 0;
+               log_error(LOG_LEVEL_CONNECT,
+                  "Stopping to watch the client socket. "
+                  "There's already another request waiting.");
+               continue;
+            }
+            /*
+             * If the client socket is set, but there's no data
+             * available on the socket, the client went fishing
+             * and continuing talking to the server makes no sense.
+             */
+            log_error(LOG_LEVEL_CONNECT, "The client closed socket %d while "
+               "the server socket %d is still open.", csp->cfd, csp->sfd);
+            mark_server_socket_tainted(csp);
+            break;
+         }
          if (csp->expected_client_content_length != 0)
          {
             if (csp->expected_client_content_length < (sizeof(buf) - 1))
             {
-               max_bytes_to_read = csp->expected_client_content_length;
+               max_bytes_to_read = (int)csp->expected_client_content_length;
             }
             log_error(LOG_LEVEL_CONNECT,
                "Waiting for up to %d bytes from the client.",
@@ -1940,7 +1967,7 @@ static void chat(struct client_state *csp)
          if (csp->expected_client_content_length != 0)
          {
             assert(len <= max_bytes_to_read);
-            csp->expected_client_content_length -= len;
+            csp->expected_client_content_length -= (unsigned)len;
             log_error(LOG_LEVEL_CONNECT,
                "Expected client content length set to %llu "
                "after reading %d bytes.",
@@ -2247,7 +2274,7 @@ static void chat(struct client_state *csp)
                    * we can parse the headers we just continue here.
                    */
                   log_error(LOG_LEVEL_CONNECT,
-                     "Continuing buffering headers. Most recently received: %d",
+                     "Continuing buffering headers. Bytes most recently read: %d.",
                      len);
                   continue;
                }
@@ -2783,9 +2810,9 @@ static void initialize_mutexes(void)
  *
  *********************************************************************/
 #ifdef __MINGW32__
-int real_main(int argc, const char *argv[])
+int real_main(int argc, char **argv)
 #else
-int main(int argc, const char *argv[])
+int main(int argc, char **argv)
 #endif
 {
    int argc_pos = 0;