X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=jcc.c;h=028970f4ceadb0b9c30a7b1445b509db6100cee9;hp=d2ae203afc583b9322d8aa7fddb94552a67943fd;hb=92f1c5a1258893f24b4236a31983a5cf1a5b262a;hpb=af975ab9eaa4fe6df9c03b579f11b09d95755b2d diff --git a/jcc.c b/jcc.c index d2ae203a..028970f4 100644 --- a/jcc.c +++ b/jcc.c @@ -1,4 +1,4 @@ -const char jcc_rcs[] = "$Id: jcc.c,v 1.193 2008/10/12 15:57:35 fabiankeil Exp $"; +const char jcc_rcs[] = "$Id: jcc.c,v 1.195 2008/10/13 16:04:37 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/jcc.c,v $ @@ -33,6 +33,13 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.193 2008/10/12 15:57:35 fabiankeil Exp $" * * Revisions : * $Log: jcc.c,v $ + * Revision 1.195 2008/10/13 16:04:37 fabiankeil + * Make sure we don't try to reuse tainted server sockets. + * + * Revision 1.194 2008/10/12 18:35:18 fabiankeil + * The last commit was a bit too ambitious, apparently the content + * length adjustment is only necessary if we aren't buffering. + * * Revision 1.193 2008/10/12 15:57:35 fabiankeil * Fix content length calculation if we read headers * and the start of the body at once. Now that we have @@ -2553,7 +2560,7 @@ static void chat(struct client_state *csp) if (n < 0) { log_error(LOG_LEVEL_ERROR, "select() failed!: %E"); - return; + break; } /* @@ -2572,7 +2579,7 @@ static void chat(struct client_state *csp) if (write_socket(csp->sfd, buf, (size_t)len)) { log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", http->host); - return; + break; } continue; } @@ -2613,7 +2620,7 @@ static void chat(struct client_state *csp) */ log_error(LOG_LEVEL_ERROR, "Already forwarded the original headers. " "Unable to tell the client about the problem."); - return; + break; } rsp = error_response(csp, "connect-failed", errno); @@ -2632,10 +2639,9 @@ static void chat(struct client_state *csp) { /* XXX: this is a temporary hack */ log_error(LOG_LEVEL_CONNECT, - "Looks like we reached the end of the last chunk: " - "%d %d %d %d %d. We better stop reading.", - buf[len-5], buf[len-4], buf[len-3], buf[len-2], buf[len-1]); - csp->expected_content_length = byte_count + len; + "Looks like we reached the end of the last chunk. " + "We better stop reading."); + csp->expected_content_length = byte_count + (size_t)len; csp->flags |= CSP_FLAG_CONTENT_LENGTH_SET; } } @@ -2709,7 +2715,7 @@ static void chat(struct client_state *csp) log_error(LOG_LEVEL_ERROR, "write modified content to client failed: %E"); freez(hdr); freez(p); - return; + break; } freez(hdr); @@ -2766,8 +2772,7 @@ static void chat(struct client_state *csp) log_error(LOG_LEVEL_ERROR, "Out of memory while trying to flush."); rsp = cgi_error_memory(); send_crunch_response(csp, rsp); - - return; + break; } hdrlen = strlen(hdr); @@ -2778,7 +2783,7 @@ static void chat(struct client_state *csp) log_error(LOG_LEVEL_CONNECT, "Flush header and buffers to client failed: %E"); freez(hdr); - return; + break; } /* @@ -2797,7 +2802,7 @@ static void chat(struct client_state *csp) if (write_socket(csp->cfd, buf, (size_t)len)) { log_error(LOG_LEVEL_ERROR, "write to client failed: %E"); - return; + break; } } byte_count += (size_t)len; @@ -2816,8 +2821,7 @@ static void chat(struct client_state *csp) log_error(LOG_LEVEL_ERROR, "Out of memory while looking for end of server headers."); rsp = cgi_error_memory(); send_crunch_response(csp, rsp); - - return; + break; } header_start = csp->iob->cur; @@ -2853,7 +2857,7 @@ static void chat(struct client_state *csp) log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 502 0", csp->ip_addr_str, http->cmd); write_socket(csp->cfd, NO_SERVER_DATA_RESPONSE, strlen(NO_SERVER_DATA_RESPONSE)); free_http_request(http); - return; + break; } assert(csp->headers->first->str); @@ -2877,7 +2881,7 @@ static void chat(struct client_state *csp) write_socket(csp->cfd, INVALID_SERVER_HEADERS_RESPONSE, strlen(INVALID_SERVER_HEADERS_RESPONSE)); free_http_request(http); - return; + break; } /* @@ -2904,7 +2908,7 @@ static void chat(struct client_state *csp) * and are done here after cleaning up. */ freez(hdr); - return; + break; } /* Buffer and pcrs filter this if appropriate. */ @@ -2933,7 +2937,7 @@ static void chat(struct client_state *csp) * to the client... it probably can't hear us anyway. */ freez(hdr); - return; + break; } byte_count += (size_t)len; @@ -2946,7 +2950,7 @@ static void chat(struct client_state *csp) */ int header_length = csp->iob->cur - header_start; assert(csp->iob->cur > header_start); - byte_count += len - header_length; + byte_count += (size_t)len - header_length; } /* we're finished with the server's header */ @@ -2968,8 +2972,17 @@ static void chat(struct client_state *csp) } continue; } - - return; /* huh? we should never get here */ + /* + * If we reach this point, the server socket is tainted + * (most likely because we didn't read everything the + * server sent us) and reusing it would lead to garbage. + */ + 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; + } + return; } if (csp->content_length == 0)