X-Git-Url: http://www.privoxy.org/gitweb/?a=blobdiff_plain;f=jcc.c;h=fa3731bb639deb00d6606001a894fbe30ca5a225;hb=e154953bec0b4942897c73d309d336e8ef3834ef;hp=de6d35b2075c58672543671c50f0c668f850193c;hpb=effa99e4df3dbc95aafd3dd940c0454ca0a2ce44;p=privoxy.git diff --git a/jcc.c b/jcc.c index de6d35b2..fa3731bb 100644 --- a/jcc.c +++ b/jcc.c @@ -1,4 +1,4 @@ -const char jcc_rcs[] = "$Id: jcc.c,v 1.255 2009/06/11 11:46:22 fabiankeil Exp $"; +const char jcc_rcs[] = "$Id: jcc.c,v 1.261 2009/07/05 12:00:53 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/jcc.c,v $ @@ -657,6 +657,9 @@ static const char *crunch_reason(const struct http_response *rsp) case RSP_REASON_CONNECTION_TIMEOUT: reason = "Connection timeout"; break; + case RSP_REASON_NO_SERVER_DATA: + reason = "No server data received"; + break; default: reason = "No reason recorded"; break; @@ -1138,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 connection to the server tainted."); + csp->flags |= CSP_FLAG_SERVER_SOCKET_TAINTED; } } @@ -1439,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; } @@ -1595,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)) { @@ -1724,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 @@ -2088,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); @@ -2276,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); @@ -3065,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); }