- Don't let --verbose imply --show-skipped-tests. It's just
[privoxy.git] / jcc.c
diff --git a/jcc.c b/jcc.c
index 5991a72..db38ba2 100644 (file)
--- a/jcc.c
+++ b/jcc.c
@@ -1,4 +1,4 @@
-const char jcc_rcs[] = "$Id: jcc.c,v 1.245 2009/04/24 15:29:43 fabiankeil Exp $";
+const char jcc_rcs[] = "$Id: jcc.c,v 1.248 2009/05/10 10:25:19 fabiankeil Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/jcc.c,v $
@@ -33,6 +33,17 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.245 2009/04/24 15:29:43 fabiankeil Exp $"
  *
  * Revisions   :
  *    $Log: jcc.c,v $
+ *    Revision 1.248  2009/05/10 10:25:19  fabiankeil
+ *    Change wait_for_alive_connection() prototype to use (void).
+ *
+ *    Revision 1.247  2009/05/10 10:19:23  fabiankeil
+ *    Reenable server-side-only keep-alive support, but only share
+ *    outgoing connections if the connection-sharing option is set.
+ *
+ *    Revision 1.246  2009/05/10 10:12:30  fabiankeil
+ *    Initial keep-alive support for the client socket.
+ *    Temporarily disable the server-side-only keep-alive code.
+ *
  *    Revision 1.245  2009/04/24 15:29:43  fabiankeil
  *    Allow to limit the number of of client connections.
  *
@@ -2275,7 +2286,7 @@ static int server_response_is_complete(struct client_state *csp,
  * Returns     :  N/A
  *
  *********************************************************************/
-static void wait_for_alive_connections()
+static void wait_for_alive_connections(void)
 {
    int connections_alive = close_unusable_connections();
 
@@ -2891,6 +2902,7 @@ static void chat(struct client_state *csp)
       }
 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
       save_connection_destination(csp->sfd, http, fwd, &csp->server_connection);
+      csp->server_connection.keep_alive_timeout = (unsigned)csp->config->keep_alive_timeout;
    }
 #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
 
@@ -3507,6 +3519,7 @@ static void serve(struct client_state *csp)
 #endif /* def AMIGA */
 {
 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
+   static int monitor_thread_running = 0;
    int continue_chatting = 0;
    do
    {
@@ -3519,30 +3532,6 @@ static void serve(struct client_state *csp)
          && (csp->sfd != JB_INVALID_SOCKET)
          && socket_is_still_usable(csp->sfd);
 
-      /*
-       * Get the csp in a mostly vergin state again.
-       * XXX: Should be done elsewhere.
-       */
-      csp->content_type = 0;
-      csp->content_length = 0;
-      csp->expected_content_length = 0;
-      list_remove_all(csp->headers);
-      freez(csp->iob->buf);
-      memset(csp->iob, 0, sizeof(csp->iob));
-      freez(csp->error_message);
-      free_http_request(csp->http);
-      destroy_list(csp->headers);
-      destroy_list(csp->tags);
-      free_current_action(csp->action);
-      if (NULL != csp->fwd)
-      {
-         unload_forward_spec(csp->fwd);
-         csp->fwd = NULL;
-      }
-
-      /* XXX: Store per-connection flags someplace else. */
-      csp->flags = CSP_FLAG_ACTIVE | (csp->flags & CSP_FLAG_TOGGLED_ON);
-
       if (continue_chatting)
       {
          log_error(LOG_LEVEL_CONNECT,
@@ -3551,18 +3540,58 @@ static void serve(struct client_state *csp)
             csp->sfd, csp->server_connection.host);
 
          if ((csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE)
-            && data_is_available(csp->cfd, csp->config->keep_alive_timeout)
+            && data_is_available(csp->cfd, (int)csp->server_connection.keep_alive_timeout)
             && socket_is_still_usable(csp->cfd))
          {
             log_error(LOG_LEVEL_CONNECT, "Client request arrived in "
                "time or the client closed the connection.");
+            /*
+             * Get the csp in a mostly vergin state again.
+             * XXX: Should be done elsewhere.
+             */
+            csp->content_type = 0;
+            csp->content_length = 0;
+            csp->expected_content_length = 0;
+            list_remove_all(csp->headers);
+            freez(csp->iob->buf);
+            memset(csp->iob, 0, sizeof(csp->iob));
+            freez(csp->error_message);
+            free_http_request(csp->http);
+            destroy_list(csp->headers);
+            destroy_list(csp->tags);
+            free_current_action(csp->action);
+            if (NULL != csp->fwd)
+            {
+               unload_forward_spec(csp->fwd);
+               csp->fwd = NULL;
+            }
+
+            /* XXX: Store per-connection flags someplace else. */
+            csp->flags = CSP_FLAG_ACTIVE | (csp->flags & CSP_FLAG_TOGGLED_ON);
          }
          else
          {
             log_error(LOG_LEVEL_CONNECT,
-               "No additional client request received in time. "
-               "Closing server socket %d, initially opened for %s.",
-               csp->sfd, csp->server_connection.host);
+               "No additional client request received in time.");
+            if ((csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_SHARING))
+            {
+               remember_connection(csp->sfd, csp->http,
+                  forward_url(csp, csp->http),
+                  csp->server_connection.keep_alive_timeout);
+               csp->sfd = JB_INVALID_SOCKET;
+               close_socket(csp->cfd);
+               csp->cfd = JB_INVALID_SOCKET;
+               privoxy_mutex_lock(&connection_reuse_mutex);
+               if (!monitor_thread_running)
+               {
+                  monitor_thread_running = 1;
+                  privoxy_mutex_unlock(&connection_reuse_mutex);
+                  wait_for_alive_connections();
+                  privoxy_mutex_lock(&connection_reuse_mutex);
+                  monitor_thread_running = 0;
+               }
+               privoxy_mutex_unlock(&connection_reuse_mutex);
+            }
             break;
          }
       }
@@ -3573,12 +3602,17 @@ static void serve(struct client_state *csp)
             "Closing.", csp->sfd, csp->server_connection.host);
       }
    } while (continue_chatting);
+
+   mark_connection_closed(&csp->server_connection);
 #else
    chat(csp);
 #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
 
    if (csp->sfd != JB_INVALID_SOCKET)
    {
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+      forget_connection(csp->sfd);
+#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
       close_socket(csp->sfd);
    }