X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=jcc.c;h=85be466c1e091cdc9df134ba5af4b0325d8a75c0;hp=03b2431be60571c0d0b3d57cb5faf0876d6886cd;hb=def547e44b817a959280a96ca921b554945da5b6;hpb=fac8bb933e5355946a02ede417460779a1aca33a diff --git a/jcc.c b/jcc.c index 03b2431b..85be466c 100644 --- a/jcc.c +++ b/jcc.c @@ -1,4 +1,4 @@ -const char jcc_rcs[] = "$Id: jcc.c,v 1.256 2009/06/11 11:49:11 fabiankeil Exp $"; +const char jcc_rcs[] = "$Id: jcc.c,v 1.262 2009/07/05 12:02:25 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/jcc.c,v $ @@ -1141,8 +1141,9 @@ static void mark_server_socket_tainted(struct client_state *csp) { if ((csp->flags & CSP_FLAG_SERVER_CONNECTION_KEEP_ALIVE)) { - log_error(LOG_LEVEL_CONNECT, "Unsetting keep-alive flag."); - csp->flags &= ~CSP_FLAG_SERVER_CONNECTION_KEEP_ALIVE; + log_error(LOG_LEVEL_CONNECT, + "Marking the server socket %d tainted.", csp->sfd); + csp->flags |= CSP_FLAG_SERVER_SOCKET_TAINTED; } } @@ -1442,6 +1443,39 @@ static jb_err parse_client_request(struct client_state *csp) return JB_ERR_PARSE; } +#ifdef FEATURE_CONNECTION_KEEP_ALIVE + if ((csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE)) + { + if (csp->iob->cur[0] != '\0') + { + csp->flags |= CSP_FLAG_SERVER_SOCKET_TAINTED; + if (!strcmpic(csp->http->gpc, "POST")) + { + /* 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."); + } + else + { + /* XXX: and so is this */ + csp->flags |= CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ; + log_error(LOG_LEVEL_CONNECT, + "Possible pipeline attempt detected. The connection will not " + "be kept alive and we will only serve the first request."); + /* Nuke the pipelined requests from orbit, just to be sure. */ + csp->iob->buf[0] = '\0'; + csp->iob->eod = csp->iob->cur = csp->iob->buf; + } + } + else + { + csp->flags |= CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ; + log_error(LOG_LEVEL_CONNECT, "Complete client request received."); + } + } +#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */ + return JB_ERR_OK; } @@ -1598,6 +1632,7 @@ static void chat(struct client_state *csp) #ifdef FEATURE_CONNECTION_KEEP_ALIVE if ((csp->sfd != JB_INVALID_SOCKET) + && !(csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED) && socket_is_still_usable(csp->sfd) && connection_destination_matches(&csp->server_connection, http, fwd)) { @@ -1727,7 +1762,17 @@ static void chat(struct client_state *csp) #else FD_ZERO(&rfds); #endif - FD_SET(csp->cfd, &rfds); +#ifdef FEATURE_CONNECTION_KEEP_ALIVE + if ((csp->flags & CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ)) + { + maxfd = csp->sfd; + } + else +#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */ + { + FD_SET(csp->cfd, &rfds); + } + FD_SET(csp->sfd, &rfds); #ifdef FEATURE_CONNECTION_KEEP_ALIVE @@ -2091,7 +2136,8 @@ static void chat(struct client_state *csp) /* Did we actually get anything? */ if (NULL == csp->headers->first) { - log_error(LOG_LEVEL_ERROR, "Empty server or forwarder response."); + log_error(LOG_LEVEL_ERROR, + "Empty server or forwarder response received on socket %d.", csp->sfd); log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 502 0", csp->ip_addr_str, http->cmd); send_crunch_response(csp, error_response(csp, "no-server-data")); free_http_request(http); @@ -2279,6 +2325,7 @@ 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->cfd != JB_INVALID_SOCKET) && (csp->sfd != JB_INVALID_SOCKET) && socket_is_still_usable(csp->sfd); @@ -3068,7 +3115,7 @@ static jb_socket bind_port_helper(struct configuration_spec * config) (NULL != config->haddr) ? config->haddr : "INADDR_ANY", config->hport); default : - log_error(LOG_LEVEL_FATAL, "can't bind to %s:%d: because %E", + log_error(LOG_LEVEL_FATAL, "can't bind to %s:%d: %E", (NULL != config->haddr) ? config->haddr : "INADDR_ANY", config->hport); }