X-Git-Url: http://www.privoxy.org/gitweb/?a=blobdiff_plain;f=jcc.c;h=a09621eccad92d5ff197ba799b076be2c219d28a;hb=307ea1408d6788f44f6892d91b293870054f6732;hp=fcc238d36c14483fdd56bf19c9c421fa797b07c9;hpb=3c371f1faa10155a901a25ed635a663e7dbd19ef;p=privoxy.git diff --git a/jcc.c b/jcc.c index fcc238d3..a09621ec 100644 --- a/jcc.c +++ b/jcc.c @@ -1,4 +1,4 @@ -const char jcc_rcs[] = "$Id: jcc.c,v 1.287 2009/09/09 17:12:08 fabiankeil Exp $"; +const char jcc_rcs[] = "$Id: jcc.c,v 1.294 2009/09/18 18:57:20 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/jcc.c,v $ @@ -1231,7 +1231,8 @@ static void verify_request_length(struct client_state *csp) *********************************************************************/ static void mark_server_socket_tainted(struct client_state *csp) { - if ((csp->flags & CSP_FLAG_SERVER_CONNECTION_KEEP_ALIVE)) + if ((csp->flags & CSP_FLAG_SERVER_CONNECTION_KEEP_ALIVE) + && !(csp->flags |= CSP_FLAG_SERVER_SOCKET_TAINTED)) { log_error(LOG_LEVEL_CONNECT, "Marking the server socket %d tainted.", csp->sfd); @@ -1329,6 +1330,7 @@ static jb_err receive_client_request(struct client_state *csp) req = get_request_line(csp); if (req == NULL) { + mark_server_socket_tainted(csp); return JB_ERR_PARSE; } assert(*req != '\0'); @@ -1599,6 +1601,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 +1843,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; } @@ -1867,10 +1870,20 @@ static void chat(struct client_state *csp) } if (server_body && server_response_is_complete(csp, byte_count)) { - log_error(LOG_LEVEL_CONNECT, - "Done reading from server. Expected content length: %llu. " - "Actual content length: %llu. Most recently received: %d.", - csp->expected_content_length, byte_count, len); + if (csp->expected_content_length == byte_count) + { + log_error(LOG_LEVEL_CONNECT, + "Done reading from server. Content length: %llu as expected. " + "Bytes most recently read: %d.", + byte_count, len); + } + else + { + log_error(LOG_LEVEL_CONNECT, + "Done reading from server. Expected content length: %llu. " + "Actual content length: %llu. Bytes most recently read: %d.", + csp->expected_content_length, byte_count, len); + } len = 0; /* * XXX: should not jump around, @@ -1914,6 +1927,32 @@ static void chat(struct client_state *csp) 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)) @@ -2247,7 +2286,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; } @@ -2441,12 +2480,16 @@ static void serve(struct client_state *csp) static int monitor_thread_running = 0; #endif /* def FEATURE_CONNECTION_SHARING */ int continue_chatting = 0; - unsigned int latency = 0; do { + unsigned int latency; + chat(csp); + latency = (unsigned)(csp->server_connection.response_received - + csp->server_connection.request_sent); + continue_chatting = (csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_KEEP_ALIVE) && (csp->flags & CSP_FLAG_SERVER_CONNECTION_KEEP_ALIVE) @@ -2513,6 +2556,13 @@ static void serve(struct client_state *csp) if ((csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_SHARING) && (socket_is_still_usable(csp->sfd))) { + time_t time_open = time(NULL) - csp->server_connection.timestamp; + + if (csp->server_connection.keep_alive_timeout < time_open + latency) + { + break; + } + remember_connection(csp, forward_url(csp, csp->http)); csp->sfd = JB_INVALID_SOCKET; close_socket(csp->cfd);