If the redirect URL contains characters RFC 3986 doesn't permit, encode them
[privoxy.git] / jcc.c
diff --git a/jcc.c b/jcc.c
index a3f1428..3efa390 100644 (file)
--- a/jcc.c
+++ b/jcc.c
@@ -1,4 +1,4 @@
-const char jcc_rcs[] = "$Id: jcc.c,v 1.365 2011/09/04 11:10:56 fabiankeil Exp $";
+const char jcc_rcs[] = "$Id: jcc.c,v 1.371 2011/10/23 11:24:33 fabiankeil Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/jcc.c,v $
@@ -198,6 +198,10 @@ privoxy_mutex_t localtime_mutex;
 privoxy_mutex_t rand_mutex;
 #endif /* ndef HAVE_RANDOM */
 
+#ifdef HAVE_STRTOK
+privoxy_mutex_t strtok_mutex;
+#endif /* def HAVE_STRTOK */
+
 #endif /* def MUTEX_LOCKS_AVAILABLE */
 
 #if defined(unix)
@@ -1693,16 +1697,16 @@ static void chat(struct client_state *csp)
    }
 #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
 
-   hdr = list_to_text(csp->headers);
-   if (hdr == NULL)
-   {
-      /* FIXME Should handle error properly */
-      log_error(LOG_LEVEL_FATAL, "Out of memory parsing client header");
-   }
-   list_remove_all(csp->headers);
-
    if (fwd->forward_host || (http->ssl == 0))
    {
+      hdr = list_to_text(csp->headers);
+      if (hdr == NULL)
+      {
+         /* FIXME Should handle error properly */
+         log_error(LOG_LEVEL_FATAL, "Out of memory parsing client header");
+      }
+      list_remove_all(csp->headers);
+
       /*
        * Write the client's (modified) header to the server
        * (along with anything else that may be in the buffer)
@@ -1722,17 +1726,18 @@ static void chat(struct client_state *csp)
          freez(hdr);
          return;
       }
+      freez(hdr);
    }
    else
    {
       /*
        * We're running an SSL tunnel and we're not forwarding,
-       * so just send the "connect succeeded" message to the
-       * client, flush the rest, and get out of the way.
+       * so just ditch the client headers, send the "connect succeeded"
+       * message to the client, flush the rest, and get out of the way.
        */
+      list_remove_all(csp->headers);
       if (write_socket(csp->cfd, CSUCCEED, strlen(CSUCCEED)))
       {
-         freez(hdr);
          return;
       }
       IOB_RESET(csp);
@@ -1742,9 +1747,6 @@ static void chat(struct client_state *csp)
 
    csp->server_connection.request_sent = time(NULL);
 
-   /* we're finished with the client's header */
-   freez(hdr);
-
    maxfd = (csp->cfd > csp->server_connection.sfd) ?
       csp->cfd : csp->server_connection.sfd;
 
@@ -2513,11 +2515,13 @@ static void serve(struct client_state *csp)
 
       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->flags & CSP_FLAG_CRUNCHED))
+         && !(csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED)
+         && ((csp->flags & CSP_FLAG_SERVER_CONNECTION_KEEP_ALIVE)
+             || (csp->flags & CSP_FLAG_CRUNCHED))
          && (csp->cfd != JB_INVALID_SOCKET)
-         && (csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE);
+         && ((csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE)
+             || (csp->config->feature_flags &
+                RUNTIME_FEATURE_CONNECTION_SHARING));
 
       if (continue_chatting && !(csp->flags & CSP_FLAG_CRUNCHED))
       {
@@ -2544,22 +2548,24 @@ static void serve(struct client_state *csp)
 
       if (continue_chatting)
       {
-         unsigned int client_timeout;
+         unsigned int client_timeout = 1; /* XXX: Use something else here? */
 
-         if (csp->server_connection.sfd != JB_INVALID_SOCKET)
+         if (0 != (csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE))
          {
-            client_timeout = (unsigned)csp->server_connection.keep_alive_timeout - latency;
-            log_error(LOG_LEVEL_CONNECT,
-               "Waiting for the next client request on socket %d. "
-               "Keeping the server socket %d to %s open.",
-               csp->cfd, csp->server_connection.sfd, csp->server_connection.host);
-         }
-         else
-         {
-            client_timeout = 1; /* XXX: Use something else here? */
-            log_error(LOG_LEVEL_CONNECT,
-               "Waiting for the next client request on socket %d. "
-               "No server socket to keep open.", csp->cfd);
+            if (csp->server_connection.sfd != JB_INVALID_SOCKET)
+            {
+               client_timeout = (unsigned)csp->server_connection.keep_alive_timeout - latency;
+               log_error(LOG_LEVEL_CONNECT,
+                  "Waiting for the next client request on socket %d. "
+                  "Keeping the server socket %d to %s open.",
+                  csp->cfd, csp->server_connection.sfd, csp->server_connection.host);
+            }
+            else
+            {
+               log_error(LOG_LEVEL_CONNECT,
+                  "Waiting for the next client request on socket %d. "
+                  "No server socket to keep open.", csp->cfd);
+            }
          }
          if ((csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE)
             && data_is_available(csp->cfd, (int)client_timeout)
@@ -2571,9 +2577,12 @@ static void serve(struct client_state *csp)
          }
          else
          {
-            log_error(LOG_LEVEL_CONNECT,
-               "No additional client request received in time on socket %d.",
-                csp->cfd);
+            if (0 != (csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE))
+            {
+               log_error(LOG_LEVEL_CONNECT,
+                  "No additional client request received in time on socket %d.",
+                  csp->cfd);
+            }
 #ifdef FEATURE_CONNECTION_SHARING
             if ((csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_SHARING)
                && (socket_is_still_alive(csp->server_connection.sfd)))
@@ -2842,6 +2851,10 @@ static void initialize_mutexes(void)
 #ifndef HAVE_RANDOM
    privoxy_mutex_init(&rand_mutex);
 #endif /* ndef HAVE_RANDOM */
+
+#ifdef HAVE_STRTOK
+   privoxy_mutex_init(&strtok_mutex);
+#endif /* def HAVE_STRTOK */
 #endif /* def MUTEX_LOCKS_AVAILABLE */
 }
 
@@ -3090,10 +3103,9 @@ int main(int argc, char **argv)
 #if !defined(_WIN32) && !defined(__OS2__) && !defined(AMIGA)
 {
    int idx;
-   const int catched_signals[] = { SIGTERM, SIGINT, SIGHUP, 0 };
-   const int ignored_signals[] = { SIGPIPE, 0 };
+   const int catched_signals[] = { SIGTERM, SIGINT, SIGHUP };
 
-   for (idx = 0; catched_signals[idx] != 0; idx++)
+   for (idx = 0; idx < SZ(catched_signals); idx++)
    {
 #ifdef sun /* FIXME: Is it safe to check for HAVE_SIGSET instead? */
       if (sigset(catched_signals[idx], sig_handler) == SIG_ERR)
@@ -3105,12 +3117,9 @@ int main(int argc, char **argv)
       }
    }
 
-   for (idx = 0; ignored_signals[idx] != 0; idx++)
+   if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
    {
-      if (signal(ignored_signals[idx], SIG_IGN) == SIG_ERR)
-      {
-         log_error(LOG_LEVEL_FATAL, "Can't set ignore-handler for signal %d: %E", ignored_signals[idx]);
-      }
+      log_error(LOG_LEVEL_FATAL, "Can't set ignore-handler for SIGPIPE: %E");
    }
 
 }