X-Git-Url: http://www.privoxy.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=jcc.c;h=6cee5d4ba0fcf96dba09e628f16835df3a292a3f;hb=735b418b180f02974e7bab27d45078d44abf7866;hp=0d82c1dc3e0047d86a005362e5e8161740687870;hpb=daeac1da1e3d19b29970af1872a7d9f10dcc7cc4;p=privoxy.git diff --git a/jcc.c b/jcc.c index 0d82c1dc..6cee5d4b 100644 --- a/jcc.c +++ b/jcc.c @@ -1,4 +1,4 @@ -const char jcc_rcs[] = "$Id: jcc.c,v 1.194 2008/10/12 18:35:18 fabiankeil Exp $"; +const char jcc_rcs[] = "$Id: jcc.c,v 1.201 2008/11/02 16:48:20 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/jcc.c,v $ @@ -33,6 +33,32 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.194 2008/10/12 18:35:18 fabiankeil Exp $" * * Revisions : * $Log: jcc.c,v $ + * Revision 1.201 2008/11/02 16:48:20 fabiankeil + * Revert revision 1.195 and try again. + * + * Revision 1.200 2008/10/26 16:53:18 fabiankeil + * Fix gcc44 warning. + * + * Revision 1.199 2008/10/26 15:36:10 fabiankeil + * Remove two debug messages with LOG_LEVEL_INFO. + * + * Revision 1.198 2008/10/22 15:19:55 fabiankeil + * Once More, With Feeling: if there is no logfile + * because the user didn't specify one, we shouldn't + * call init_error_log() after receiving SIGHUP either. + * + * 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. @@ -2027,7 +2053,6 @@ static int server_response_is_complete(struct client_state *csp, size_t content_ * "HEAD" implies no body, we are thus expecting * no content. XXX: incomplete "list" of methods? */ - log_error(LOG_LEVEL_INFO, "Method %s implies no body.", csp->http->gpc); csp->expected_content_length = 0; content_length_known = TRUE; } @@ -2037,7 +2062,6 @@ static int server_response_is_complete(struct client_state *csp, size_t content_ /* * Expect no body. XXX: incomplete "list" of status codes? */ - log_error(LOG_LEVEL_INFO, "Status code %d implies no body.", csp->http->status); csp->expected_content_length = 0; content_length_known = TRUE; } @@ -2047,6 +2071,28 @@ static int server_response_is_complete(struct client_state *csp, size_t content_ } #endif /* FEATURE_CONNECTION_KEEP_ALIVE */ +/********************************************************************* + * + * Function : mark_server_socket_tainted + * + * Description : Makes sure we don't reuse a server socket + * (if we didn't read everything the server sent + * us reusing the socket would lead to garbage). + * + * Parameters : + * 1 : csp = Current client state (buffers, headers, etc...) + * + * Returns : void. + * + *********************************************************************/ +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; + } +} /********************************************************************* * @@ -2557,7 +2603,8 @@ static void chat(struct client_state *csp) if (n < 0) { log_error(LOG_LEVEL_ERROR, "select() failed!: %E"); - break; + mark_server_socket_tainted(csp); + return; } /* @@ -2570,13 +2617,16 @@ static void chat(struct client_state *csp) if (len <= 0) { + /* XXX: not sure if this is necessary. */ + mark_server_socket_tainted(csp); break; /* "game over, man" */ } if (write_socket(csp->sfd, buf, (size_t)len)) { log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", http->host); - break; + mark_server_socket_tainted(csp); + return; } continue; } @@ -2617,7 +2667,8 @@ 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."); - break; + mark_server_socket_tainted(csp); + return; } rsp = error_response(csp, "connect-failed", errno); @@ -2636,10 +2687,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; } } @@ -2713,7 +2763,8 @@ static void chat(struct client_state *csp) log_error(LOG_LEVEL_ERROR, "write modified content to client failed: %E"); freez(hdr); freez(p); - break; + mark_server_socket_tainted(csp); + return; } freez(hdr); @@ -2770,7 +2821,8 @@ 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); - break; + mark_server_socket_tainted(csp); + return; } hdrlen = strlen(hdr); @@ -2781,7 +2833,8 @@ static void chat(struct client_state *csp) log_error(LOG_LEVEL_CONNECT, "Flush header and buffers to client failed: %E"); freez(hdr); - break; + mark_server_socket_tainted(csp); + return; } /* @@ -2800,7 +2853,8 @@ 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"); - break; + mark_server_socket_tainted(csp); + return; } } byte_count += (size_t)len; @@ -2819,7 +2873,8 @@ 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); - break; + mark_server_socket_tainted(csp); + return; } header_start = csp->iob->cur; @@ -2855,7 +2910,8 @@ 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); - break; + mark_server_socket_tainted(csp); + return; } assert(csp->headers->first->str); @@ -2879,7 +2935,8 @@ static void chat(struct client_state *csp) write_socket(csp->cfd, INVALID_SERVER_HEADERS_RESPONSE, strlen(INVALID_SERVER_HEADERS_RESPONSE)); free_http_request(http); - break; + mark_server_socket_tainted(csp); + return; } /* @@ -2906,7 +2963,8 @@ static void chat(struct client_state *csp) * and are done here after cleaning up. */ freez(hdr); - break; + mark_server_socket_tainted(csp); + return; } /* Buffer and pcrs filter this if appropriate. */ @@ -2935,7 +2993,8 @@ static void chat(struct client_state *csp) * to the client... it probably can't hear us anyway. */ freez(hdr); - break; + mark_server_socket_tainted(csp); + return; } byte_count += (size_t)len; @@ -2948,7 +3007,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 */ @@ -2970,17 +3029,8 @@ static void chat(struct client_state *csp) } continue; } - /* - * 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; + mark_server_socket_tainted(csp); + return; /* huh? we should never get here */ } if (csp->content_length == 0) @@ -2992,6 +3042,15 @@ static void chat(struct client_state *csp) csp->content_length = byte_count; } + if ((csp->flags & CSP_FLAG_CONTENT_LENGTH_SET) + && (csp->expected_content_length != byte_count)) + { + log_error(LOG_LEVEL_ERROR, + "Received %d bytes while expecting %d.", + byte_count, csp->expected_content_length); + mark_server_socket_tainted(csp); + } + log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 200 %d", csp->ip_addr_str, http->ocmd, csp->content_length); } @@ -3796,7 +3855,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