X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=jcc.c;h=e5a76aab01d41eb7bf4330d93cc22009bc71c593;hp=eb407a9570da160dfbd8236705e1c2ea4370ea16;hb=072ef5304611eadb2ce1a8ad43c04e9edc38fdca;hpb=c06de2cb9fd25aa9d8f5ad2a86cf8df938aa3f1c diff --git a/jcc.c b/jcc.c index eb407a95..e5a76aab 100644 --- a/jcc.c +++ b/jcc.c @@ -1,4 +1,4 @@ -const char jcc_rcs[] = "$Id: jcc.c,v 1.190 2008/10/11 14:58:00 fabiankeil Exp $"; +const char jcc_rcs[] = "$Id: jcc.c,v 1.197 2008/10/20 17:02:40 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/jcc.c,v $ @@ -33,6 +33,33 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.190 2008/10/11 14:58:00 fabiankeil Exp $" * * Revisions : * $Log: jcc.c,v $ + * Revision 1.197 2008/10/20 17:02:40 fabiankeil + * If SIGHUP is received while we aren't running in daemon + * mode, calling init_error_log() would be a mistake. + * + * Revision 1.196 2008/10/16 09:16:41 fabiankeil + * - Fix two gcc44 conversion warnings. + * - Don't bother logging the last five bytes + * of the 0-chunk. + * + * 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 + * FEATURE_CONNECTION_KEEP_ALIVE, it actually matters. + * + * Revision 1.192 2008/10/11 18:19:14 fabiankeil + * Even more chat() cosmetics. + * + * Revision 1.191 2008/10/11 18:00:14 fabiankeil + * Reformat some comments in chat(). + * * Revision 1.190 2008/10/11 14:58:00 fabiankeil * In case of chunk-encoded content, stop reading if * the buffer looks like it ends with the last chunk. @@ -2466,12 +2493,11 @@ static void chat(struct client_state *csp) if (write_socket(csp->sfd, hdr, strlen(hdr)) || (flush_socket(csp->sfd, csp->iob) < 0)) { - log_error(LOG_LEVEL_CONNECT, "write header to: %s failed: %E", - http->hostport); + log_error(LOG_LEVEL_CONNECT, + "write header to: %s failed: %E", http->hostport); rsp = error_response(csp, "connect-failed", errno); - - if(rsp) + if (rsp) { send_crunch_response(csp, rsp); } @@ -2500,7 +2526,7 @@ static void chat(struct client_state *csp) /* we're finished with the client's header */ freez(hdr); - maxfd = ( csp->cfd > csp->sfd ) ? csp->cfd : csp->sfd; + maxfd = (csp->cfd > csp->sfd) ? csp->cfd : csp->sfd; /* pass data between the client and server * until one or the other shuts down the connection. @@ -2543,7 +2569,7 @@ static void chat(struct client_state *csp) if (n < 0) { log_error(LOG_LEVEL_ERROR, "select() failed!: %E"); - return; + break; } /* @@ -2562,7 +2588,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; } @@ -2574,7 +2600,7 @@ static void chat(struct client_state *csp) */ if (FD_ISSET(csp->sfd, &rfds)) { - fflush( 0 ); + fflush(0); len = read_socket(csp->sfd, buf, sizeof(buf) - 1); if (len < 0) @@ -2603,11 +2629,10 @@ 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); - if (rsp) { send_crunch_response(csp, rsp); @@ -2623,10 +2648,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; } } @@ -2700,7 +2724,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); @@ -2744,7 +2768,8 @@ static void chat(struct client_state *csp) size_t hdrlen; int flushed; - log_error(LOG_LEVEL_INFO, "Flushing header and buffers. Stepping back from filtering."); + log_error(LOG_LEVEL_INFO, + "Flushing header and buffers. Stepping back from filtering."); hdr = list_to_text(csp->headers); if (hdr == NULL) @@ -2756,8 +2781,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); @@ -2765,10 +2789,10 @@ static void chat(struct client_state *csp) || ((flushed = flush_socket(csp->cfd, csp->iob)) < 0) || (write_socket(csp->cfd, buf, (size_t)len))) { - log_error(LOG_LEVEL_CONNECT, "Flush header and buffers to client failed: %E"); - + log_error(LOG_LEVEL_CONNECT, + "Flush header and buffers to client failed: %E"); freez(hdr); - return; + break; } /* @@ -2787,7 +2811,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; @@ -2795,6 +2819,7 @@ static void chat(struct client_state *csp) } else { + const char *header_start; /* * We're still looking for the end of the server's header. * Buffer up the data we just read. If that fails, there's @@ -2805,10 +2830,11 @@ 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; + /* Convert iob into something sed() can digest */ if (JB_ERR_PARSE == get_server_headers(csp)) { @@ -2840,7 +2866,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); @@ -2864,7 +2890,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; } /* @@ -2891,7 +2917,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. */ @@ -2920,11 +2946,21 @@ 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; } + else + { + /* + * XXX: the header lenght should probably + * be calculated by get_server_headers(). + */ + int header_length = csp->iob->cur - header_start; + assert(csp->iob->cur > header_start); + byte_count += (size_t)len - header_length; + } /* we're finished with the server's header */ @@ -2945,8 +2981,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) @@ -3762,7 +3807,10 @@ static void listen_loop(void) */ if (received_hup_signal) { - init_error_log(Argv[0], config->logfile); + if (NULL != config->logfile) + { + init_error_log(Argv[0], config->logfile); + } received_hup_signal = 0; } #endif