X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=jcc.c;h=06ce04ae5524522cb898560d105cbf063ad42be0;hp=8f408e8cf51a376a4fe059a5d14f83e042b0ca97;hb=0037521e356511ffd45f769e732e9bd4c120da0f;hpb=d52001f4635fd28608fd8a311d6b200e4663ecfa diff --git a/jcc.c b/jcc.c index 8f408e8c..06ce04ae 100644 --- a/jcc.c +++ b/jcc.c @@ -1,4 +1,4 @@ -const char jcc_rcs[] = "$Id: jcc.c,v 1.171 2008/03/27 18:27:25 fabiankeil Exp $"; +const char jcc_rcs[] = "$Id: jcc.c,v 1.177 2008/05/10 11:51:12 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/jcc.c,v $ @@ -33,6 +33,28 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.171 2008/03/27 18:27:25 fabiankeil Exp $" * * Revisions : * $Log: jcc.c,v $ + * Revision 1.177 2008/05/10 11:51:12 fabiankeil + * Make the "read the rest of the headers" loop a bit more readable. + * + * Revision 1.176 2008/05/10 11:37:57 fabiankeil + * - Instead of logging when the IIS5 hack is enabled, log when it fails. + * - Remove useless comment. + * + * Revision 1.175 2008/05/09 18:53:59 fabiankeil + * Fix comment grammar. + * + * Revision 1.174 2008/05/07 18:05:53 fabiankeil + * Remove the pointless buffer in client_protocol_is_unsupported(). + * + * Revision 1.173 2008/05/06 15:09:00 fabiankeil + * Least-effort fix for bug #1821930 (reported by Lee): + * If the response doesn't look like HTTP, + * tell the client and log the problem. + * + * Revision 1.172 2008/04/16 16:38:21 fabiankeil + * Don't pass the whole csp structure to flush_socket() + * when it only needs a file descriptor and a buffer. + * * Revision 1.171 2008/03/27 18:27:25 fabiankeil * Remove kill-popups action. * @@ -1184,6 +1206,14 @@ static const char NO_SERVER_DATA_RESPONSE[] = "Empty server or forwarder response.\r\n" "The connection has been closed but Privoxy didn't receive any data.\r\n"; +/* XXX: should be a template */ +static const char INVALID_SERVER_HEADERS_RESPONSE[] = + "HTTP/1.0 502 Server or forwarder response invalid\r\n" + "Proxy-Agent: Privoxy " VERSION "\r\n" + "Content-Type: text/plain\r\n" + "Connection: close\r\n\r\n" + "Bad response. The server or forwarder response doesn't look like HTTP.\r\n"; + #if 0 /* XXX: should be a template */ static const char NULL_BYTE_RESPONSE[] = @@ -1308,8 +1338,6 @@ static void sig_handler(int the_signal) *********************************************************************/ static int client_protocol_is_unsupported(const struct client_state *csp, char *req) { - char buf[BUFFER_SIZE]; - /* * If it's a FTP or gopher request, we don't support it. * @@ -1325,21 +1353,26 @@ static int client_protocol_is_unsupported(const struct client_state *csp, char * */ if (!strncmpic(req, "GET ftp://", 10) || !strncmpic(req, "GET gopher://", 13)) { + const char *response = NULL; + const char *protocol = NULL; + if (!strncmpic(req, "GET ftp://", 10)) { - strlcpy(buf, FTP_RESPONSE, sizeof(buf)); - log_error(LOG_LEVEL_ERROR, "%s tried to use Privoxy as FTP proxy: %s", - csp->ip_addr_str, req); + response = FTP_RESPONSE; + protocol = "FTP"; } else { - strlcpy(buf, GOPHER_RESPONSE, sizeof(buf)); - log_error(LOG_LEVEL_ERROR, "%s tried to use Privoxy as gopher proxy: %s", - csp->ip_addr_str, req); + response = GOPHER_RESPONSE; + protocol = "GOPHER"; } - log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 400 0", csp->ip_addr_str, req); + log_error(LOG_LEVEL_ERROR, + "%s tried to use Privoxy as %s proxy: %s", + csp->ip_addr_str, protocol, req); + log_error(LOG_LEVEL_CLF, + "%s - - [%T] \"%s\" 400 0", csp->ip_addr_str, req); freez(req); - write_socket(csp->cfd, buf, strlen(buf)); + write_socket(csp->cfd, response, strlen(response)); return TRUE; } @@ -1447,7 +1480,7 @@ static jb_err get_server_headers(struct client_state *csp) int continue_hack_in_da_house = 0; char * header; - while (((header = get_header(csp)) != NULL) || continue_hack_in_da_house) + while (((header = get_header(csp->iob)) != NULL) || continue_hack_in_da_house) { if (header == NULL) { @@ -1498,7 +1531,6 @@ static jb_err get_server_headers(struct client_state *csp) return JB_ERR_PARSE; } - /* Enlist header */ if (JB_ERR_MEMORY == enlist(csp->headers, header)) { /* @@ -1956,7 +1988,7 @@ static void chat(struct client_state *csp) return; } - req = get_header(csp); + req = get_header(csp->iob); } while ((NULL != req) && ('\0' == *req)); @@ -2044,8 +2076,20 @@ static void chat(struct client_state *csp) init_list(headers); for (;;) { - if ( ( ( p = get_header(csp) ) != NULL) && ( *p == '\0' ) ) + p = get_header(csp->iob); + + if (p == NULL) { + /* There are no additional headers to read. */ + break; + } + + if (*p == '\0') + { + /* + * We didn't receive a complete header + * line yet, get the rest of it. + */ len = read_socket(csp->cfd, buf, sizeof(buf) - 1); if (len <= 0) { @@ -2054,23 +2098,25 @@ static void chat(struct client_state *csp) return; } - /* - * If there is no memory left for buffering the - * request, there is nothing we can do but hang up - */ if (add_to_iob(csp, buf, len)) { + /* + * If there is no memory left for buffering the + * request, there is nothing we can do but hang up + */ destroy_list(headers); return; } - continue; } - - if (p == NULL) break; - - enlist(headers, p); - freez(p); - + else + { + /* + * We were able to read a complete + * header and can finaly enlist it. + */ + enlist(headers, p); + freez(p); + } } if (http->host == NULL) @@ -2524,9 +2570,6 @@ static void chat(struct client_state *csp) * This is NOT the body, so * Let's pretend the server just sent us a blank line. */ - log_error(LOG_LEVEL_INFO, - "Malformerd HTTP headers detected and MS IIS5 hack enabled. " - "Expect an invalid response or even no response at all."); snprintf(buf, sizeof(buf), "\r\n"); len = (int)strlen(buf); @@ -2639,6 +2682,8 @@ static void chat(struct client_state *csp) * and there isn't anything * we can do about it. */ + log_error(LOG_LEVEL_INFO, + "MS IIS5 hack didn't produce valid headers."); break; } else @@ -2662,6 +2707,29 @@ static void chat(struct client_state *csp) return; } + assert(csp->headers->first->str); + assert(!http->ssl); + if (strncmpic(csp->headers->first->str, "HTTP", 4)) + { + /* + * It doesn't look like a HTTP response: + * tell the client and log the problem. + */ + if (strlen(csp->headers->first->str) > 30) + { + csp->headers->first->str[30] = '\0'; + } + log_error(LOG_LEVEL_ERROR, + "Invalid server or forwarder response. Starts with: %s", + csp->headers->first->str); + log_error(LOG_LEVEL_CLF, + "%s - - [%T] \"%s\" 502 0", csp->ip_addr_str, http->cmd); + write_socket(csp->cfd, INVALID_SERVER_HEADERS_RESPONSE, + strlen(INVALID_SERVER_HEADERS_RESPONSE)); + free_http_request(http); + return; + } + /* we have now received the entire header. * filter it and send the result to the client */ @@ -2731,6 +2799,8 @@ static void chat(struct client_state *csp) */ if (ms_iis5_hack) { + log_error(LOG_LEVEL_INFO, + "Closed server connection detected with MS IIS5 hack enabled."); break; } } @@ -2961,7 +3031,7 @@ int main(int argc, const char *argv[]) * Parse the command line arguments * * XXX: simply printing usage information in case of - * invalid arguments isn't particular user friendly. + * invalid arguments isn't particularly user friendly. */ while (++argc_pos < argc) {