Add changes in 3.0.14 BETA.
[privoxy.git] / jcc.c
diff --git a/jcc.c b/jcc.c
index b850569..d637017 100644 (file)
--- a/jcc.c
+++ b/jcc.c
@@ -1,4 +1,4 @@
-const char jcc_rcs[] = "$Id: jcc.c,v 1.267 2009/07/11 14:49:09 fabiankeil Exp $";
+const char jcc_rcs[] = "$Id: jcc.c,v 1.271 2009/07/14 17:50:34 fabiankeil Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/jcc.c,v $
@@ -1460,12 +1460,16 @@ static jb_err parse_client_request(struct client_state *csp)
       if (csp->iob->cur[0] != '\0')
       {
          csp->flags |= CSP_FLAG_SERVER_SOCKET_TAINTED;
-         if (!strcmpic(csp->http->gpc, "POST"))
+         if (strcmpic(csp->http->gpc, "GET")
+          && strcmpic(csp->http->gpc, "HEAD")
+          && strcmpic(csp->http->gpc, "TRACE")
+          && strcmpic(csp->http->gpc, "OPTIONS")
+          && strcmpic(csp->http->gpc, "DELETE"))
          {
             /* XXX: this is an incomplete hack */
             csp->flags &= ~CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ;
             log_error(LOG_LEVEL_CONNECT,
-               "POST request detected. The connection will not be kept alive.");
+               "There might be a request body. The connection will not be kept alive.");
          }
          else
          {
@@ -1750,6 +1754,8 @@ static void chat(struct client_state *csp)
 
    log_error(LOG_LEVEL_CONNECT, "to %s successful", http->hostport);
 
+   csp->server_connection.request_sent = time(NULL);
+
    /* we're finished with the client's header */
    freez(hdr);
 
@@ -2190,8 +2196,6 @@ static void chat(struct client_state *csp)
                return;
             }
 
-            csp->server_connection.timestamp = time(NULL);
-
             /*
              * We have now received the entire server header,
              * filter it and send the result to the client
@@ -2207,6 +2211,8 @@ static void chat(struct client_state *csp)
                log_error(LOG_LEVEL_FATAL, "Out of memory parsing server header");
             }
 
+            csp->server_connection.response_received = time(NULL);
+
             if (crunch_response_triggered(csp, crunchers_light))
             {
                /*
@@ -2314,6 +2320,8 @@ static void chat(struct client_state *csp)
 
    log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 200 %llu",
       csp->ip_addr_str, http->ocmd, csp->content_length);
+
+   csp->server_connection.timestamp = time(NULL);
 }
 
 
@@ -2340,27 +2348,39 @@ static void serve(struct client_state *csp)
 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
    static int monitor_thread_running = 0;
    int continue_chatting = 0;
+   unsigned int latency = 0;
+
    do
    {
       chat(csp);
 
+      if ((csp->flags & CSP_FLAG_SERVER_CONNECTION_KEEP_ALIVE)
+         && !(csp->flags & CSP_FLAG_SERVER_KEEP_ALIVE_TIMEOUT_SET))
+      {
+         log_error(LOG_LEVEL_CONNECT, "The server didn't specify how long "
+            "the connection will stay open. Assume it's only a second.");
+         csp->server_connection.keep_alive_timeout = 1;
+      }
+
       continue_chatting = (csp->config->feature_flags
          & RUNTIME_FEATURE_CONNECTION_KEEP_ALIVE)
          && (csp->flags & CSP_FLAG_SERVER_CONNECTION_KEEP_ALIVE)
          && !(csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED)
          && (csp->cfd != JB_INVALID_SOCKET)
          && (csp->sfd != JB_INVALID_SOCKET)
-         && socket_is_still_usable(csp->sfd);
+         && socket_is_still_usable(csp->sfd)
+         && (latency < csp->server_connection.keep_alive_timeout);
 
       if (continue_chatting)
       {
+         unsigned int client_timeout = (unsigned)csp->server_connection.keep_alive_timeout - latency;
          log_error(LOG_LEVEL_CONNECT,
             "Waiting for the next client request. "
             "Keeping the server socket %d to %s open.",
             csp->sfd, csp->server_connection.host);
 
          if ((csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE)
-            && data_is_available(csp->cfd, (int)csp->server_connection.keep_alive_timeout)
+            && data_is_available(csp->cfd, (int)client_timeout)
             && socket_is_still_usable(csp->cfd))
          {
             log_error(LOG_LEVEL_CONNECT, "Client request arrived in "