X-Git-Url: http://www.privoxy.org/gitweb/?a=blobdiff_plain;f=jcc.c;h=c1e09ea8e981adac57712e171317f8d2fccfb533;hb=4a6b6a65eeb0d803d8e5f1ce3fbace7fe8ff7c3c;hp=8491c84a7980451f5778157dbc5fe0246d4696b8;hpb=2afa3221231342abdf0298bf1c463042843e05ab;p=privoxy.git diff --git a/jcc.c b/jcc.c index 8491c84a..c1e09ea8 100644 --- a/jcc.c +++ b/jcc.c @@ -1,4 +1,4 @@ -const char jcc_rcs[] = "$Id: jcc.c,v 1.38 2001/09/16 13:01:46 jongfoster Exp $"; +const char jcc_rcs[] = "$Id: jcc.c,v 1.45 2001/10/07 15:42:11 oes Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/jcc.c,v $ @@ -33,6 +33,43 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.38 2001/09/16 13:01:46 jongfoster Exp $"; * * Revisions : * $Log: jcc.c,v $ + * Revision 1.45 2001/10/07 15:42:11 oes + * Replaced 6 boolean members of csp with one bitmap (csp->flags) + * + * Moved downgrading of the HTTP version from parse_http_request to + * chat(), since we can't decide if it is necessary before we have + * determined the actions for the URL. The HTTP command is now + * *always* re-built so the repairs need no longer be special-cased. + * + * filter_popups now gets a csp pointer so it can raise the new + * CSP_FLAG_MODIFIED flag. + * + * Bugfix + * + * Added configurable size limit for the IOB. If the IOB grows so + * large that the next read would exceed the limit, the header + * is generated, and the header & unfiltered buffer are flushed + * to the client. Chat then continues in non-buffering, + * non-filtering body mode. + * + * Revision 1.44 2001/10/02 18:13:57 oes + * Ooops + * + * Revision 1.43 2001/10/02 15:32:13 oes + * Moved generation of hdr + * + * Revision 1.42 2001/09/21 23:02:02 david__schmidt + * Cleaning up 2 compiler warnings on OS/2. + * + * Revision 1.41 2001/09/16 17:05:14 jongfoster + * Removing unused #include showarg.h + * + * Revision 1.40 2001/09/16 15:41:45 jongfoster + * Fixing signed/unsigned comparison warning. + * + * Revision 1.39 2001/09/16 13:21:27 jongfoster + * Changes to use new list functions. + * * Revision 1.38 2001/09/16 13:01:46 jongfoster * Removing redundant function call that zeroed zalloc()'d memory. * @@ -324,6 +361,10 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.38 2001/09/16 13:01:46 jongfoster Exp $"; # include /* declarations for threads and stuff. */ # endif +# ifdef __EMX__ +# include /* OS/2/EMX needs a little help with select */ +# endif + # ifndef FD_ZERO # include # endif @@ -335,7 +376,6 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.38 2001/09/16 13:01:46 jongfoster Exp $"; #include "jcc.h" #include "filters.h" #include "loaders.h" -#include "showargs.h" #include "parsers.h" #include "killpopup.h" #include "miscutil.h" @@ -411,17 +451,17 @@ static void chat(struct client_state *csp) { /* * This next lines are a little ugly, but they simplifies the if statements - * below. Basically if TOGGLE, then we want the if to test "csp->toggled_on", - * else we don't. And if FEATURE_FORCE_LOAD, then we want the if to test - * "csp->toggled_on", else we don't + * below. Basically if TOGGLE, then we want the if to test if the + * CSP_FLAG_TOGGLED_ON flag ist set, else we don't. And if FEATURE_FORCE_LOAD, + * then we want the if to test for CSP_FLAG_FORCED , else we don't */ #ifdef FEATURE_TOGGLE -# define IS_TOGGLED_ON_AND (csp->toggled_on) && +# define IS_TOGGLED_ON_AND (csp->flags & CSP_FLAG_TOGGLED_ON) && #else /* ifndef FEATURE_TOGGLE */ # define IS_TOGGLED_ON_AND #endif /* ndef FEATURE_TOGGLE */ #ifdef FEATURE_FORCE_LOAD -# define IS_NOT_FORCED_AND (!csp->force) && +# define IS_NOT_FORCED_AND !(csp->flags & CSP_FLAG_FORCED) && #else /* ifndef FEATURE_FORCE_LOAD */ # define IS_NOT_FORCED_AND #endif /* def FEATURE_FORCE_LOAD */ @@ -486,14 +526,11 @@ static void chat(struct client_state *csp) { strclean(req, FORCE_PREFIX); log_error(LOG_LEVEL_FORCE, "Enforcing request \"%s\".\n", req); - csp->force = 1; + csp->flags |= CSP_FLAG_FORCED; } - else - { - csp->force = 0; - } + #endif /* def FEATURE_FORCE_LOAD */ - + parse_http_request(req, http, csp); freez(req); break; @@ -521,52 +558,43 @@ static void chat(struct client_state *csp) * we have to do one of the following: * * create = use the original HTTP request to create a new - * HTTP request that has only the path component - * without the http://domainspec - * pass = pass the original HTTP request unchanged + * HTTP request that has either the path component + * without the http://domainspec (w/path) or the + * full orininal URL (w/url) + * Note that the path and/or the HTTP version may + * have been altered by now. + * + * connect = Open a socket to the host:port of the server + * and short-circuit server and client socket. * - * drop = drop the HTTP request + * pass = Pass the request unchanged if forwarding a CONNECT + * request to a parent proxy. Note that we'll be sending + * the CFAIL message ourselves if connecting to the parent + * fails, but we won't send a CSUCCEED message if it works, + * since that would result in a double message (ours and the + * parent's). After sending the request to the parent, we simply + * tunnel. * - * here's the matrix: + * here's the matrix: * SSL * 0 1 * +--------+--------+ * | | | - * 0 | create | drop | - * | | | + * 0 | create | connect| + * | w/path | | * Forwarding +--------+--------+ * | | | - * 1 | pass | pass | - * | | | + * 1 | create | pass | + * | w/url | | * +--------+--------+ * */ - if (fwd->forward_host) - { - /* if forwarding, just pass the request as is */ - enlist(csp->headers, http->cmd); - } - else - { - if (http->ssl == 0) - { - /* otherwise elide the host information from the url */ - p = NULL; - p = strsav(p, http->gpc); - p = strsav(p, " "); - p = strsav(p, http->path); - p = strsav(p, " "); - p = strsav(p, http->ver); - enlist(csp->headers, p); - freez(p); - } - } - - /* decide what we're to do with cookies */ - + /* + * Determine the actions for this URL + */ #ifdef FEATURE_TOGGLE - if (!csp->toggled_on) + if (!(csp->flags & CSP_FLAG_TOGGLED_ON)) { /* Most compatible set of actions (i.e. none) */ init_current_action(csp->action); @@ -578,6 +606,44 @@ static void chat(struct client_state *csp) } #ifdef FEATURE_COOKIE_JAR + + /* + * Downgrade http version from 1.1 to 1.0 if +downgrade + * action applies + */ + if (!strcmpic(http->ver, "HTTP/1.1") && csp->action->flags & ACTION_DOWNGRADE) + { + freez(http->ver); + http->ver = strdup("HTTP/1.0"); + } + + /* + * (Re)build the HTTP request for non-SSL requests. + * If forwarding, use the whole URL, else, use only the path. + */ + if (http->ssl == 0) + { + freez(http->cmd); + + http->cmd = strsav(http->cmd, http->gpc); + http->cmd = strsav(http->cmd, " "); + + if (fwd->forward_host) + { + http->cmd = strsav(http->cmd, http->url); + } + else + { + http->cmd = strsav(http->cmd, http->path); + } + + http->cmd = strsav(http->cmd, " "); + http->cmd = strsav(http->cmd, http->ver); + + } + enlist(csp->headers, http->cmd); + + /* * If we're logging cookies in a cookie jar, and the user has not * supplied any wafers, and the user has not told us to suppress the @@ -624,9 +690,6 @@ static void chat(struct client_state *csp) /* We have a request. */ - hdr = sed(client_patterns, add_client_headers, csp); - list_remove_all(csp->headers); - /* * Now, check to see if we need to intercept it, i.e. * If @@ -664,7 +727,7 @@ static void chat(struct client_state *csp) #ifdef FEATURE_STATISTICS /* Count as a rejected request */ - csp->rejected = 1; + csp->flags |= CSP_FLAG_REJECTED; #endif /* def FEATURE_STATISTICS */ /* Log (FIXME: All intercept reasons apprear as "crunch" with Status 200) */ @@ -673,7 +736,6 @@ static void chat(struct client_state *csp) /* Clean up and return */ free_http_response(rsp); - freez(hdr); return; } @@ -724,12 +786,14 @@ static void chat(struct client_state *csp) } free_http_response(rsp); - freez(hdr); return; } log_error(LOG_LEVEL_CONNECT, "OK"); + hdr = sed(client_patterns, add_client_headers, csp); + list_remove_all(csp->headers); + if (fwd->forward_host || (http->ssl == 0)) { /* write the client's (modified) header to the server @@ -871,7 +935,7 @@ static void chat(struct client_state *csp) /* Filter the popups on this read. */ if (block_popups_now) { - filter_popups(buf); + filter_popups(buf, csp); } #endif /* def FEATURE_KILL_POPUPS */ @@ -919,14 +983,16 @@ static void chat(struct client_state *csp) n = strlen(hdr); if ((write_socket(csp->cfd, hdr, n) != n) - || (write_socket(csp->cfd, p != NULL ? p : csp->iob->cur, csp->content_length) != csp->content_length)) + || (write_socket(csp->cfd, p != NULL ? p : csp->iob->cur, csp->content_length) != (int)csp->content_length)) { - log_error(LOG_LEVEL_CONNECT, "write modified content to client failed: %E"); + log_error(LOG_LEVEL_ERROR, "write modified content to client failed: %E"); return; } freez(hdr); - freez(p); + if (NULL != p) { + freez(p); + } } break; /* "game over, man" */ @@ -957,6 +1023,36 @@ static void chat(struct client_state *csp) if (content_filter) { add_to_iob(csp, buf, n); + + /* + * If the buffer limit will be reached on the next read, + * switch to non-filtering mode, i.e. make & write the + * header, flush the socket and get out of the way. + */ + if (csp->iob->eod - csp->iob->buf + BUFFER_SIZE > csp->config->buffer_limit) + { + log_error(LOG_LEVEL_ERROR, "Buffer size limit reached! Flushing and stepping back."); + + hdr = sed(server_patterns, add_server_headers, csp); + n = strlen(hdr); + byte_count += n; + + if (((write_socket(csp->cfd, hdr, n) != n) + || (n = flush_socket(csp->cfd, csp) < 0))) + { + log_error(LOG_LEVEL_CONNECT, "write header to client failed: %E"); + + freez(hdr); + return; + } + + freez(hdr); + byte_count += n; + + content_filter = NULL; + server_body = 1; + + } } else { @@ -1045,7 +1141,7 @@ static void chat(struct client_state *csp) * Filter the part of the body that came in the same read * as the last headers: */ - filter_popups(csp->iob->cur); + filter_popups(csp->iob->cur, csp); } #endif /* def FEATURE_KILL_POPUPS */ @@ -1140,7 +1236,7 @@ static void serve(struct client_state *csp) close_socket(csp->sfd); } - csp->active = 0; + csp->flags &= ~CSP_FLAG_ACTIVE; } @@ -1318,7 +1414,7 @@ static void listen_loop(void) continue; } - csp->active = 1; + csp->flags |= CSP_FLAG_ACTIVE; csp->sfd = -1; csp->config = config = load_config(); @@ -1380,8 +1476,10 @@ static void listen_loop(void) } #ifdef FEATURE_TOGGLE - /* by haroon - most of credit to srt19170 */ - csp->toggled_on = g_bToggleIJB; + if (g_bToggleIJB) + { + csp->flags |= CSP_FLAG_TOGGLED_ON; + } #endif /* def FEATURE_TOGGLE */ if (run_loader(csp)) @@ -1493,7 +1591,7 @@ static void listen_loop(void) wait( NULL ); #endif /* !defined(_WIN32) && defined(__CYGWIN__) */ close_socket(csp->cfd); - csp->active = 0; + csp->flags &= ~CSP_FLAG_ACTIVE; } #endif @@ -1510,7 +1608,7 @@ static void listen_loop(void) write_socket(csp->cfd, buf, strlen(buf)); close_socket(csp->cfd); - csp->active = 0; + csp->flags &= ~CSP_FLAG_ACTIVE; sleep(5); continue; }