X-Git-Url: http://www.privoxy.org/gitweb/?a=blobdiff_plain;f=jcc.c;h=9364300c132c53f31eaecb01391af45e1171c220;hb=ccca702c7aee2651fd7944e0d7ccbcb06f8558ec;hp=4b3e4ebaa3985096254740dc8aa6fb7beb8ff95c;hpb=c1106aa0f9d5e26d68c852bc1ef02beb088562d9;p=privoxy.git diff --git a/jcc.c b/jcc.c index 4b3e4eba..9364300c 100644 --- a/jcc.c +++ b/jcc.c @@ -1,4 +1,4 @@ -const char jcc_rcs[] = "$Id: jcc.c,v 1.187 2008/09/07 12:35:05 fabiankeil Exp $"; +const char jcc_rcs[] = "$Id: jcc.c,v 1.191 2008/10/11 18:00:14 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/jcc.c,v $ @@ -33,6 +33,21 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.187 2008/09/07 12:35:05 fabiankeil Exp $" * * Revisions : * $Log: jcc.c,v $ + * 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. + * + * Revision 1.189 2008/10/11 09:53:00 fabiankeil + * Let server_response_is_complete() deal properly with + * content that is neither buffered nor read all at once. + * + * Revision 1.188 2008/10/09 18:21:41 fabiankeil + * Flush work-in-progress changes to keep outgoing connections + * alive where possible. Incomplete and mostly #ifdef'd out. + * * Revision 1.187 2008/09/07 12:35:05 fabiankeil * Add mutex lock support for _WIN32. * @@ -1984,12 +1999,13 @@ static jb_err change_request_destination(struct client_state *csp) * * Parameters : * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : content_length = Length of content received so far. * * Returns : TRUE if the response is complete, * FALSE otherwise. * *********************************************************************/ -static int server_response_is_complete(struct client_state *csp) +static int server_response_is_complete(struct client_state *csp, size_t content_length) { int content_length_known = (csp->flags & CSP_FLAG_CONTENT_LENGTH_SET); @@ -2015,7 +2031,7 @@ static int server_response_is_complete(struct client_state *csp) } return (content_length_known && ((0 == csp->expected_content_length) - || (csp->expected_content_length <= (csp->iob->eod - csp->iob->cur)))); + || (csp->expected_content_length <= content_length))); } #endif /* FEATURE_CONNECTION_KEEP_ALIVE */ @@ -2434,7 +2450,6 @@ static void chat(struct client_state *csp) http->hostport); } - /* Write the answer to the client */ if (rsp != NULL) { @@ -2447,19 +2462,18 @@ static void chat(struct client_state *csp) if (fwd->forward_host || (http->ssl == 0)) { - /* write the client's (modified) header to the server + /* + * Write the client's (modified) header to the server * (along with anything else that may be in the buffer) */ - 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); } @@ -2488,7 +2502,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. @@ -2511,12 +2525,12 @@ static void chat(struct client_state *csp) FD_SET(csp->sfd, &rfds); #ifdef FEATURE_CONNECTION_KEEP_ALIVE - if (server_body && server_response_is_complete(csp)) + if (server_body && server_response_is_complete(csp, byte_count)) { log_error(LOG_LEVEL_CONNECT, - "Stopped reading from server. Expected content length: %d. " + "Done reading from server. Expected content length: %d. " "Actual content length: %d. Most recently received: %d.", - csp->expected_content_length, (csp->iob->eod - csp->iob->cur), len); + csp->expected_content_length, byte_count, len); len = 0; /* * XXX: should not jump around, @@ -2534,10 +2548,10 @@ static void chat(struct client_state *csp) return; } - /* this is the body of the browser's request - * just read it and write it. + /* + * This is the body of the browser's request, + * just read and write it. */ - if (FD_ISSET(csp->cfd, &rfds)) { len = read_socket(csp->cfd, buf, sizeof(buf) - 1); @@ -2556,15 +2570,13 @@ static void chat(struct client_state *csp) } /* - * The server wants to talk. It could be the header or the body. + * The server wants to talk. It could be the header or the body. * If `hdr' is null, then it's the header otherwise it's the body. * FIXME: Does `hdr' really mean `host'? No. */ - - if (FD_ISSET(csp->sfd, &rfds)) { - fflush( 0 ); + fflush(0); len = read_socket(csp->sfd, buf, sizeof(buf) - 1); if (len < 0) @@ -2597,7 +2609,6 @@ static void chat(struct client_state *csp) } rsp = error_response(csp, "connect-failed", errno); - if (rsp) { send_crunch_response(csp, rsp); @@ -2607,15 +2618,30 @@ static void chat(struct client_state *csp) } #ifdef FEATURE_CONNECTION_KEEP_ALIVE + if (csp->flags & CSP_FLAG_CHUNKED) + { + if ((len > 5) && !memcmp(buf+len-5, "0\r\n\r\n", 5)) + { + /* 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; + csp->flags |= CSP_FLAG_CONTENT_LENGTH_SET; + } + } reading_done: #endif /* FEATURE_CONNECTION_KEEP_ALIVE */ - /* Add a trailing zero. This lets filter_popups - * use string operations. + /* + * Add a trailing zero to let be able to use string operations. + * XXX: do we still need this with filter_popups gone? */ buf[len] = '\0'; - /* Normally, this would indicate that we've read + /* + * Normally, this would indicate that we've read * as much as the server has sent us and we can * close the client connection. However, Microsoft * in its wisdom has released IIS/5 with a bug that @@ -2705,7 +2731,6 @@ static void chat(struct client_state *csp) * of the server document, just write it to the client, * unless we need to buffer the body for later content-filtering */ - if (server_body || http->ssl) { if (content_filter) @@ -2720,7 +2745,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) @@ -2741,8 +2767,8 @@ 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; } @@ -2771,15 +2797,10 @@ static void chat(struct client_state *csp) } else { - /* we're still looking for the end of the - * server's header ... (does that make header - * parsing an "out of body experience" ? - */ - - /* - * buffer up the data we just read. If that fails, - * there's little we can do but send our static - * out-of-memory page. + /* + * We're still looking for the end of the server's header. + * Buffer up the data we just read. If that fails, there's + * little we can do but send our static out-of-memory page. */ if (add_to_iob(csp, buf, len)) { @@ -2795,10 +2816,9 @@ static void chat(struct client_state *csp) { if (ms_iis5_hack) { - /* Well, we tried our MS IIS/5 - * hack and it didn't work. - * The header is incomplete - * and there isn't anything + /* + * Well, we tried our MS IIS/5 hack and it didn't work. + * The header is incomplete and there isn't anything * we can do about it. */ log_error(LOG_LEVEL_INFO, @@ -2807,10 +2827,9 @@ static void chat(struct client_state *csp) } else { - /* Since we have to wait for - * more from the server before - * we can parse the headers - * we just continue here. + /* + * Since we have to wait for more from the server before + * we can parse the headers we just continue here. */ continue; } @@ -2887,7 +2906,8 @@ static void chat(struct client_state *csp) */ if (!content_filter) { - /* write the server's (modified) header to + /* + * Write the server's (modified) header to * the client (along with anything else that * may be in the buffer) */ @@ -2897,9 +2917,9 @@ static void chat(struct client_state *csp) { log_error(LOG_LEVEL_CONNECT, "write header to client failed: %E"); - /* the write failed, so don't bother - * mentioning it to the client... - * it probably can't hear us anyway. + /* + * The write failed, so don't bother mentioning it + * to the client... it probably can't hear us anyway. */ freez(hdr); return; @@ -2913,10 +2933,10 @@ static void chat(struct client_state *csp) freez(hdr); server_body = 1; - /* If this was a MS IIS/5 hack then it means - * the server has already closed the - * connection. Nothing more to read. Time - * to bail. + /* + * If this was a MS IIS/5 hack then it means the server + * has already closed the connection. Nothing more to read. + * Time to bail. */ if (ms_iis5_hack) { @@ -2934,9 +2954,8 @@ static void chat(struct client_state *csp) if (csp->content_length == 0) { /* - * If Privoxy didn't recalculate the - * Content-Lenght, byte_count is still - * correct. + * If Privoxy didn't recalculate the Content-Lenght, + * byte_count is still correct. */ csp->content_length = byte_count; }