X-Git-Url: http://www.privoxy.org/gitweb/?a=blobdiff_plain;f=jcc.c;h=32c1df7757b75d8fedf3439853727cbe95d5ee3e;hb=b6c268cca2189e8b28f43fe9417df75d0ca80076;hp=d65b6e1727540f89947c78f9499c9f34543268e1;hpb=f454c054d7070d782b3d3206c8701e2282a0ca4c;p=privoxy.git diff --git a/jcc.c b/jcc.c index d65b6e17..32c1df77 100644 --- a/jcc.c +++ b/jcc.c @@ -1,4 +1,4 @@ -const char jcc_rcs[] = "$Id: jcc.c,v 1.114 2006/12/27 18:52:02 fabiankeil Exp $"; +const char jcc_rcs[] = "$Id: jcc.c,v 1.118 2007/01/07 07:43:43 joergs Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/jcc.c,v $ @@ -6,7 +6,7 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.114 2006/12/27 18:52:02 fabiankeil Exp $" * Purpose : Main file. Contains main() method, main loop, and * the main connection-handling function. * - * Copyright : Written by and Copyright (C) 2001 the SourceForge + * Copyright : Written by and Copyright (C) 2001-2007 the SourceForge * Privoxy team. http://www.privoxy.org/ * * Based on the Internet Junkbuster originally written @@ -33,6 +33,20 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.114 2006/12/27 18:52:02 fabiankeil Exp $" * * Revisions : * $Log: jcc.c,v $ + * Revision 1.118 2007/01/07 07:43:43 joergs + * AmigaOS4 support added. + * + * Revision 1.117 2006/12/31 17:56:37 fabiankeil + * Added config option accept-intercepted-requests + * and disabled it by default. + * + * Revision 1.116 2006/12/29 19:08:22 fabiankeil + * Reverted parts of my last commit + * to keep error handling working. + * + * Revision 1.115 2006/12/29 17:38:57 fabiankeil + * Fixed gcc43 conversion warnings. + * * Revision 1.114 2006/12/27 18:52:02 fabiankeil * Fix -pedantic ISO C warning about converting * from function pointer to object pointer. @@ -896,6 +910,7 @@ const char CHEADER[] = const char CFORBIDDEN[] = "HTTP/1.0 403 Connection not allowable\r\n" + "Proxy-Agent: Privoxy " VERSION "\r\n" "X-Hint: If you read this message interactively, then you know why this happens ,-)\r\n" "Connection: close\r\n\r\n"; @@ -909,11 +924,20 @@ const char GOPHER_RESPONSE[] = "Connection: close\r\n\r\n" "Invalid request. Privoxy doesn't support gopher.\r\n"; +/* XXX: should be a template */ const char MISSING_DESTINATION_RESPONSE[] = "HTTP/1.0 400 Bad request received from browser\r\n" + "Proxy-Agent: Privoxy " VERSION "\r\n" "Connection: close\r\n\r\n" "Bad request. Privoxy was unable to extract the destination.\r\n"; +/* XXX: should be a template */ +const char NO_SERVER_DATA_RESPONSE[] = + "HTTP/1.0 502 Server or forwarder response empty\r\n" + "Proxy-Agent: Privoxy " VERSION "\r\n" + "Connection: close\r\n\r\n" + "Empty server or forwarder response.\r\n" + "The connection was closed without sending any data.\r\n"; #if !defined(_WIN32) && !defined(__OS2__) && !defined(AMIGA) /********************************************************************* @@ -1020,7 +1044,7 @@ static void chat(struct client_state *csp) int max_forwarded_connect_retries = csp->config->forwarded_connect_retries; const struct forward_spec * fwd; struct http_request *http; - size_t len; /* for buffer sizes */ + int len; /* for buffer sizes (and negative error codes) */ #ifdef FEATURE_KILL_POPUPS int block_popups; /* bool, 1==will block popups */ int block_popups_now = 0; /* bool, 1==currently blocking popups */ @@ -1180,9 +1204,23 @@ static void chat(struct client_state *csp) { /* * Intercepted or invalid request without domain - * inside the request line. Try to get it another way. + * inside the request line. Try to get it another way, + * unless accept-intercepted-requests is disabled. */ - if (JB_ERR_OK == get_destination_from_headers(headers, http)) + if (!(csp->config->feature_flags & RUNTIME_FEATURE_ACCEPT_INTERCEPTED_REQUESTS)) + { + log_error(LOG_LEVEL_ERROR, "%s's request: \'%s\' is invalid." + " Privoxy isn't configured to accept intercepted requests.", + csp->ip_addr_str, http->cmd); + log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 400 0", csp->ip_addr_str, http->cmd); + + strcpy(buf, CHEADER); + write_socket(csp->cfd, buf, strlen(buf)); + free_http_request(http); + destroy_list(headers); + return; + } + else if (JB_ERR_OK == get_destination_from_headers(headers, http)) { /* Split the domain we just got for pattern matching */ init_domain_components(http); @@ -1473,10 +1511,15 @@ static void chat(struct client_state *csp) if (csp->sfd == JB_INVALID_SOCKET) { - log_error(LOG_LEVEL_CONNECT, "connect to: %s failed: %E", - http->hostport); + if (fwd->type != SOCKS_NONE) + { + /* Socks error. */ + rsp = error_response(csp, "forwarding-failed", errno); - if (errno == EINVAL) + log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 503 0", + csp->ip_addr_str, http->ocmd); + } + else if (errno == EINVAL) { rsp = error_response(csp, "no-such-domain", errno); @@ -1487,6 +1530,9 @@ static void chat(struct client_state *csp) { rsp = error_response(csp, "connect-failed", errno); + log_error(LOG_LEVEL_CONNECT, "connect to: %s failed: %E", + http->hostport); + log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 503 0", csp->ip_addr_str, http->ocmd); } @@ -1507,8 +1553,6 @@ static void chat(struct client_state *csp) return; } - log_error(LOG_LEVEL_CONNECT, "OK"); - if (fwd->forward_host || (http->ssl == 0)) { /* write the client's (modified) header to the server @@ -1558,6 +1602,8 @@ static void chat(struct client_state *csp) IOB_RESET(csp); } + log_error(LOG_LEVEL_CONNECT, "to %s successful", http->hostport); + /* we're finished with the client's header */ freez(hdr); @@ -1728,7 +1774,7 @@ static void chat(struct client_state *csp) * Let's pretend the server just sent us a blank line. */ snprintf(buf, sizeof(buf), "\r\n"); - len = strlen(buf); + len = (int)strlen(buf); /* * Now, let the normal header parsing algorithm below do its @@ -1782,7 +1828,7 @@ static void chat(struct client_state *csp) if (write_socket(csp->cfd, hdr, hdrlen) || ((flushed = flush_socket(csp->cfd, csp)) < 0) - || (write_socket(csp->cfd, buf, len))) + || (write_socket(csp->cfd, buf, (size_t)len))) { log_error(LOG_LEVEL_CONNECT, "Flush header and buffers to client failed: %E"); @@ -1790,7 +1836,7 @@ static void chat(struct client_state *csp) return; } - byte_count += hdrlen + (size_t)flushed + len; + byte_count += hdrlen + (size_t)(flushed + len); freez(hdr); content_filter = NULL; server_body = 1; @@ -1799,13 +1845,13 @@ static void chat(struct client_state *csp) } else { - if (write_socket(csp->cfd, buf, len)) + if (write_socket(csp->cfd, buf, (size_t)len)) { log_error(LOG_LEVEL_ERROR, "write to client failed: %E"); return; } } - byte_count += len; + byte_count += (size_t)len; continue; } else @@ -1875,6 +1921,17 @@ static void chat(struct client_state *csp) } } + /* Did we actually get anything? */ + if (NULL == csp->headers->first) + { + log_error(LOG_LEVEL_ERROR, "Empty server or forwarder response."); + log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 502 0", csp->ip_addr_str, http->cmd); + strcpy(buf, NO_SERVER_DATA_RESPONSE); + write_socket(csp->cfd, buf, strlen(buf)); + free_http_request(http); + return; + } + /* we have now received the entire header. * filter it and send the result to the client */ @@ -1941,7 +1998,7 @@ static void chat(struct client_state *csp) */ if (write_socket(csp->cfd, hdr, strlen(hdr)) - || ((len = (size_t)flush_socket(csp->cfd, csp)) < 0)) + || ((len = flush_socket(csp->cfd, csp)) < 0)) { log_error(LOG_LEVEL_CONNECT, "write header to client failed: %E"); @@ -1953,7 +2010,7 @@ static void chat(struct client_state *csp) return; } - byte_count += len; + byte_count += (size_t)len; } /* we're finished with the server's header */ @@ -2663,7 +2720,7 @@ static void listen_loop(void) bfd = bind_port_helper(config); } - log_error(LOG_LEVEL_CONNECT, "accept connection ... "); + log_error(LOG_LEVEL_CONNECT, "Listening for new connections ... "); if (!accept_connection(csp, bfd)) { @@ -2680,7 +2737,7 @@ static void listen_loop(void) } else { - log_error(LOG_LEVEL_CONNECT, "OK"); + log_error(LOG_LEVEL_CONNECT, "accepted connection from %s", csp->ip_addr_str); } #ifdef FEATURE_TOGGLE @@ -2771,13 +2828,22 @@ static void listen_loop(void) #define SELECTED_ONE_OPTION csp->cfd = ReleaseSocket(csp->cfd, -1); - if((child_id = (int)CreateNewProcTags( - NP_Entry, (ULONG)server_thread, - NP_Output, Output(), - NP_CloseOutput, FALSE, - NP_Name, (ULONG)"privoxy child", - NP_StackSize, 200*1024, - TAG_DONE))) +#ifdef __amigaos4__ + child_id = (int)CreateNewProcTags(NP_Entry, (ULONG)server_thread, + NP_Output, Output(), + NP_CloseOutput, FALSE, + NP_Name, (ULONG)"privoxy child", + NP_Child, TRUE, + TAG_DONE); +#else + child_id = (int)CreateNewProcTags(NP_Entry, (ULONG)server_thread, + NP_Output, Output(), + NP_CloseOutput, FALSE, + NP_Name, (ULONG)"privoxy child", + NP_StackSize, 200*1024, + TAG_DONE); +#endif + if(0 != child_id) { childs++; ((struct Task *)child_id)->tc_UserData = csp;