diff -ru ./actionlist.h /tmp/unionfs/privoxy-devel-oben/actionlist.h --- ./actionlist.h Sun Oct 3 14:53:32 2004 +++ /tmp/unionfs/privoxy-devel-oben/actionlist.h Wed May 17 18:24:42 2006 @@ -133,7 +133,23 @@ DEFINE_ACTION_STRING ("hide-from-header", ACTION_HIDE_FROM, ACTION_STRING_FROM) DEFINE_CGI_PARAM_RADIO ("hide-from-header", ACTION_HIDE_FROM, ACTION_STRING_FROM, "block", 1) DEFINE_CGI_PARAM_CUSTOM ("hide-from-header", ACTION_HIDE_FROM, ACTION_STRING_FROM, "spam_me_senseless@sittingduck.xyz") +DEFINE_ACTION_STRING ("crunch-server-header", ACTION_CRUNCH_SERVER_HEADER, ACTION_STRING_SERVER_HEADER) +DEFINE_CGI_PARAM_NO_RADIO("crunch-server-header", ACTION_CRUNCH_SERVER_HEADER, ACTION_STRING_SERVER_HEADER, "X-Whatever:") +DEFINE_ACTION_STRING ("crunch-client-header", ACTION_CRUNCH_CLIENT_HEADER, ACTION_STRING_CLIENT_HEADER) +DEFINE_CGI_PARAM_NO_RADIO("crunch-client-header", ACTION_CRUNCH_CLIENT_HEADER, ACTION_STRING_CLIENT_HEADER, "X-Whatever:") +DEFINE_ACTION_STRING ("hide-accept-language", ACTION_HIDE_ACCEPT_LANGUAGE, ACTION_STRING_LANGUAGE) +DEFINE_CGI_PARAM_RADIO ("hide-accept-language", ACTION_HIDE_ACCEPT_LANGUAGE, ACTION_STRING_LANGUAGE, "block", 0) +DEFINE_CGI_PARAM_CUSTOM ("hide-accept-language", ACTION_HIDE_ACCEPT_LANGUAGE, ACTION_STRING_LANGUAGE, "de-de") +DEFINE_ACTION_STRING ("content-type-overwrite", ACTION_CONTENT_TYPE_OVERWRITE, ACTION_STRING_CONTENT_TYPE) +DEFINE_CGI_PARAM_NO_RADIO("content-type-overwrite", ACTION_CONTENT_TYPE_OVERWRITE, ACTION_STRING_CONTENT_TYPE, "text/html") +DEFINE_ACTION_STRING ("hide-content-disposition", ACTION_HIDE_CONTENT_DISPOSITION, ACTION_STRING_CONTENT_DISPOSITION) +DEFINE_CGI_PARAM_RADIO ("hide-content-disposition", ACTION_HIDE_CONTENT_DISPOSITION, ACTION_STRING_CONTENT_DISPOSITION, "block", 0) +DEFINE_CGI_PARAM_CUSTOM ("hide-content-disposition", ACTION_HIDE_CONTENT_DISPOSITION, ACTION_STRING_CONTENT_DISPOSITION, "attachment; filename=WHATEVER.txt") +DEFINE_ACTION_BOOL ("crunch-if-modified-since", ACTION_CRUNCH_IF_MODIFIED_SINCE) +DEFINE_ACTION_BOOL ("crunch-if-none-match", ACTION_CRUNCH_IF_NONE_MATCH) +DEFINE_ACTION_BOOL ("force-text-mode", ACTION_FORCE_TEXT_MODE) DEFINE_ACTION_STRING ("hide-referrer", ACTION_HIDE_REFERER, ACTION_STRING_REFERER) +DEFINE_CGI_PARAM_RADIO ("hide-referrer", ACTION_HIDE_REFERER, ACTION_STRING_REFERER, "conditional-block", 2) DEFINE_CGI_PARAM_RADIO ("hide-referrer", ACTION_HIDE_REFERER, ACTION_STRING_REFERER, "forge", 1) DEFINE_CGI_PARAM_RADIO ("hide-referrer", ACTION_HIDE_REFERER, ACTION_STRING_REFERER, "block", 0) DEFINE_CGI_PARAM_CUSTOM ("hide-referrer", ACTION_HIDE_REFERER, ACTION_STRING_REFERER, "http://www.google.com/") diff -ru ./cgi.c /tmp/unionfs/privoxy-devel-oben/cgi.c --- ./cgi.c Tue Feb 17 14:30:23 2004 +++ /tmp/unionfs/privoxy-devel-oben/cgi.c Fri May 5 15:34:25 2006 @@ -1763,15 +1763,29 @@ else { /* - * Compliant browsers should not cache this due to the "Cache-Control" - * setting. However, to be certain, we also set both "Last-Modified" - * and "Expires" to the current time. + * Setting "Cache-Control" to "no-cache" and "Expires" to + * the current time doesn't exactly forbid caching, it just + * requires the client to revalidate the cached copy. + * + * If a temporary problem occurres and the user tries again after + * getting Privoxy's error message, a compliant browser may set the + * If-Modified-Since header with the content of the error page's + * Last-Modified header. More often than not, the document on the server + * is older than Privoxy's error message, the server would send status code + * 304 and the browser would display the outdated error message again and again. + * + * As a last resort we set "Last-Modified" to Tim Berners-Lee's birthday, + * which predates the age of any page on the web and can be safely used to + * "revalidate" without getting a status code 304. + * + * There is no need to let the useless If-Modified-Since header reach the + * server, it is therefore stripped by client_if_modified_since in parsers.c. */ if (!err) err = enlist_unique_header(rsp->headers, "Cache-Control", "no-cache"); get_http_time(0, buf); if (!err) err = enlist_unique_header(rsp->headers, "Date", buf); - if (!err) err = enlist_unique_header(rsp->headers, "Last-Modified", buf); + if (!err) err = enlist_unique_header(rsp->headers, "Last-Modified", "Wed, 08 Jun 1955 12:00:00 GMT"); if (!err) err = enlist_unique_header(rsp->headers, "Expires", "Sat, 17 Jun 2000 12:00:00 GMT"); } diff -ru ./errlog.c /tmp/unionfs/privoxy-devel-oben/errlog.c --- ./errlog.c Sun Apr 3 22:10:50 2005 +++ /tmp/unionfs/privoxy-devel-oben/errlog.c Wed May 17 18:11:12 2006 @@ -415,6 +415,14 @@ } log_error(LOG_LEVEL_INFO, "Privoxy version " VERSION); + log_error(LOG_LEVEL_INFO, "The patch you are using is not supported by the Privoxy team!\n\n" + "Before you send any bug reports to the Privoxy developers, " + "make sure the problem exists in vanilla Privoxy as well.\n" + "Feel free to report problems introduced by this patch to: " + "Fabian Keil \n" + "Additional information about this patch can be found at: " + "http://www.fabiankeil.de/sourcecode/privoxy/\n" + "Patch version: 2006-05-17\n"); if (prog_name != NULL) { log_error(LOG_LEVEL_INFO, "Program name: %s", prog_name); diff -ru ./jbsockets.c /tmp/unionfs/privoxy-devel-oben/jbsockets.c --- ./jbsockets.c Sat Jan 21 17:16:08 2006 +++ /tmp/unionfs/privoxy-devel-oben/jbsockets.c Sat May 6 15:21:15 2006 @@ -787,6 +787,7 @@ { struct sockaddr_in inaddr; struct hostent *hostp; + unsigned int dns_retries = 0; #if defined(HAVE_GETHOSTBYNAME_R_6_ARGS) || defined(HAVE_GETHOSTBYNAME_R_5_ARGS) || defined(HAVE_GETHOSTBYNAME_R_3_ARGS) struct hostent result; #if defined(HAVE_GETHOSTBYNAME_R_6_ARGS) || defined(HAVE_GETHOSTBYNAME_R_5_ARGS) @@ -826,7 +827,12 @@ hostp = gethostbyname(host); pthread_mutex_unlock(&gethostbyname_mutex); #else - hostp = gethostbyname(host); + while ( NULL == (hostp = gethostbyname(host)) + && (h_errno == TRY_AGAIN) && (dns_retries++ < 10) ) + { + log_error(LOG_LEVEL_ERROR, "%u. timeout while trying to resolve %s. Trying again.", + dns_retries, host); + } #endif /* def HAVE_GETHOSTBYNAME_R_(6|5|3)_ARGS */ /* * On Mac OSX, if a domain exists but doesn't have a type A diff -ru ./jcc.c /tmp/unionfs/privoxy-devel-oben/jcc.c --- ./jcc.c Sun Apr 3 22:10:50 2005 +++ /tmp/unionfs/privoxy-devel-oben/jcc.c Sat May 6 15:21:39 2006 @@ -860,6 +860,7 @@ int server_body; int ms_iis5_hack = 0; int byte_count = 0; + unsigned int socks_retries = 0; const struct forward_spec * fwd; struct http_request *http; int len; /* for buffer sizes */ @@ -1209,7 +1210,12 @@ /* here we connect to the server, gateway, or the forwarder */ - csp->sfd = forwarded_connect(fwd, http, csp); + while ( (csp->sfd = forwarded_connect(fwd, http, csp)) + && (errno == EINVAL) && (socks_retries++ < 3)) + { + log_error(LOG_LEVEL_ERROR, "failed the %u. time to connect to %s. Trying again.", + socks_retries, http->hostport); + } if (csp->sfd == JB_INVALID_SOCKET) { diff -ru ./parsers.c /tmp/unionfs/privoxy-devel-oben/parsers.c --- ./parsers.c Sat Jan 21 17:16:08 2006 +++ /tmp/unionfs/privoxy-devel-oben/parsers.c Wed May 17 18:29:17 2006 @@ -491,25 +491,31 @@ { "Accept-Encoding:", 16, client_accept_encoding }, { "TE:", 3, client_te }, { "Host:", 5, client_host }, -/* { "if-modified-since:", 18, crumble }, */ + { "if-modified-since:", 18, client_if_modified_since }, { "Keep-Alive:", 11, crumble }, { "connection:", 11, crumble }, { "proxy-connection:", 17, crumble }, { "max-forwards:", 13, client_max_forwards }, + { "Accept-Language:", 16, client_accept_language }, + { "if-none-match:", 14, client_if_none_match }, + { "X-Filter:", 9, client_x_filter }, + { "*", 0, crunch_client_header }, { NULL, 0, NULL } }; const struct parsers server_patterns[] = { - { "HTTP", 4, server_http }, - { "set-cookie:", 11, server_set_cookie }, - { "connection:", 11, crumble }, - { "Content-Type:", 13, server_content_type }, - { "Content-Length:", 15, server_content_length }, - { "Content-MD5:", 12, server_content_md5 }, - { "Content-Encoding:", 17, server_content_encoding }, - { "Transfer-Encoding:", 18, server_transfer_coding }, - { "Keep-Alive:", 11, crumble }, + { "HTTP", 4, server_http }, + { "set-cookie:", 11, server_set_cookie }, + { "connection:", 11, crumble }, + { "Content-Type:", 13, server_content_type }, + { "Content-Length:", 15, server_content_length }, + { "Content-MD5:", 12, server_content_md5 }, + { "Content-Encoding:", 17, server_content_encoding }, + { "Transfer-Encoding:", 18, server_transfer_coding }, + { "Keep-Alive:", 11, crumble }, + { "content-disposition:", 20, server_content_disposition }, + { "*", 0, crunch_server_header }, { NULL, 0, NULL } }; @@ -789,7 +795,8 @@ if (v == pats) log_error(LOG_LEVEL_HEADER, "scan: %s", p->str); - if (strncmpic(p->str, v->str, v->len) == 0) + /*Does the current parser take this header?*/ + if ((strncmpic(p->str, v->str, v->len) == 0) || (v->len == CHECK_EVERY_HEADER_REMAINING)) { err = v->parser(csp, (char **)&(p->str)); } @@ -833,12 +840,46 @@ *********************************************************************/ jb_err crumble(struct client_state *csp, char **header) { - log_error(LOG_LEVEL_HEADER, "crunch!"); + log_error(LOG_LEVEL_HEADER, "crumble crunched: %s!", *header); freez(*header); return JB_ERR_OK; } +/********************************************************************* + * + * Function : crunch_server_header + * + * Description : Crunch server header if it matches a string supplied by the + * user. Called from `sed'. + * + * Parameters : + * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : header = On input, pointer to header to modify. + * On output, pointer to the modified header, or NULL + * to remove the header. This function frees the + * original string if necessary. + * + * Returns : JB_ERR_OK on success and always succeeds + * + *********************************************************************/ +jb_err crunch_server_header(struct client_state *csp, char **header) +{ + const char *crunch_pattern; + /*Is there a header to crunch*/ + + if ((csp->action->flags & ACTION_CRUNCH_SERVER_HEADER)) + { + crunch_pattern = csp->action->string[ACTION_STRING_SERVER_HEADER]; + /*Is the current header the lucky one?*/ + if (strstr(*header, crunch_pattern)) + { + log_error(LOG_LEVEL_HEADER, "Crunching server header: %s", *header); + freez(*header); + } + } + return JB_ERR_OK; +} /********************************************************************* * * Function : server_content_type @@ -863,9 +904,14 @@ *********************************************************************/ jb_err server_content_type(struct client_state *csp, char **header) { + const char *newval; + + newval = csp->action->string[ACTION_STRING_CONTENT_TYPE]; + if (csp->content_type != CT_TABOO) { if ((strstr(*header, " text/") && !strstr(*header, "plain")) + || strstr(*header, "xml") || strstr(*header, "application/x-javascript")) csp->content_type = CT_TEXT; else if (strstr(*header, " image/gif")) @@ -875,7 +921,52 @@ else csp->content_type = 0; } - + /* + * Are we enabling text mode by force? + */ + if (csp->action->flags & ACTION_FORCE_TEXT_MODE) + { + /* + * Do we really have to? + */ + if (csp->content_type == CT_TEXT) + { + log_error(LOG_LEVEL_HEADER, "Text mode is already enabled."); + } + else + { + csp->content_type = CT_TEXT; + log_error(LOG_LEVEL_HEADER, "Text mode enabled by force. Take cover!"); + } + } + /* + * Are we messing with the content type? + */ + if (csp->action->flags & ACTION_CONTENT_TYPE_OVERWRITE) + { + /* + * Make sure the user doesn't accidently + * change the content type of binary documents. + */ + if (csp->content_type == CT_TEXT) + { + freez(*header); + *header = strdup("Content-Type: "); + string_append(header, newval); + + if (header == NULL) + { + log_error(LOG_LEVEL_HEADER, "Insufficient memory. Conten-Type crunched without replacement!"); + return JB_ERR_MEMORY; + } + log_error(LOG_LEVEL_HEADER, "Modified: %s!", *header); + } + else + { + log_error(LOG_LEVEL_HEADER, "%s not replaced. It doesn't look like text. " + "Enable force-text-mode if you know what you're doing.", *header); + } + } return JB_ERR_OK; } @@ -1032,6 +1123,68 @@ return JB_ERR_OK; } +/********************************************************************* + * + * Function : server_content_disposition + * + * Description : If enabled, blocks or modifies the "content-disposition" header. + * Called from `sed'. + * + * Parameters : + * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : header = On input, pointer to header to modify. + * On output, pointer to the modified header, or NULL + * to remove the header. This function frees the + * original string if necessary. + * + * Returns : JB_ERR_OK on success, or + * JB_ERR_MEMORY on out-of-memory error. + * + *********************************************************************/ +jb_err server_content_disposition(struct client_state *csp, char **header) +{ + const char *newval; + + /* + * Are we messing with the content-disposition header? + */ + if ((csp->action->flags & ACTION_HIDE_CONTENT_DISPOSITION) == 0) + { + /*Me tinks not*/ + return JB_ERR_OK; + } + + newval = csp->action->string[ACTION_STRING_CONTENT_DISPOSITION]; + + if ((newval == NULL) || (0 == strcmpic(newval, "block")) ) + { + /* + * Blocking content-disposition header + */ + log_error(LOG_LEVEL_HEADER, "Crunching %s!", *header); + freez(*header); + return JB_ERR_OK; + } + else + { + /* + * Replacing content-disposition header + */ + freez(*header); + *header = strdup("content-disposition: "); + string_append(header, newval); + + if (*header == NULL) + { + log_error(LOG_LEVEL_HEADER, "Insufficent memory. content-disposition header not fully replaced."); + } + else + { + log_error(LOG_LEVEL_HEADER, "content-disposition header crunched and replaced with: %s", *header); + } + } + return (*header == NULL) ? JB_ERR_MEMORY : JB_ERR_OK; +} /********************************************************************* * @@ -1129,10 +1282,13 @@ jb_err client_referrer(struct client_state *csp, char **header) { const char *newval; - + const char *host; + char *referer; + int hostlenght; + #ifdef FEATURE_FORCE_LOAD /* Since the referrer can include the prefix even - * even if the request itself is non-forced, we must + * if the request itself is non-forced, we must * clean it unconditionally */ strclean(*header, FORCE_PREFIX); @@ -1146,27 +1302,73 @@ return JB_ERR_OK; } - freez(*header); - newval = csp->action->string[ACTION_STRING_REFERER]; + if ((0 != strcmpic(newval, "conditional-block"))) + { + freez(*header); + } if ((newval == NULL) || (0 == strcmpic(newval, "block")) ) { /* * Blocking referer */ - log_error(LOG_LEVEL_HEADER, "crunch!"); + log_error(LOG_LEVEL_HEADER, "Referer crunched!"); return JB_ERR_OK; } - else if (0 == strncmpic(newval, "http://", 7)) + else if (0 == strcmpic(newval, "conditional-block")) { /* - * We have a specific (fixed) referer we want to send. + * Block referer if host has changed. */ - log_error(LOG_LEVEL_HEADER, "modified"); + if (NULL == (host = strdup(csp->http->hostport))) + { + freez(*header); + log_error(LOG_LEVEL_HEADER, "Referer crunched! Couldn't allocate memory for temporary host copy."); + return JB_ERR_MEMORY; + } + if (NULL == (referer = strdup(*header))) + { + freez(*header); + freez(host); + log_error(LOG_LEVEL_HEADER, "Referer crunched! Couldn't allocate memory for temporary referer copy."); + return JB_ERR_MEMORY; + } + hostlenght = strlen(host); + if ( hostlenght < (strlen(referer)-17) ) /*referer begins with 'Referer: http[s]://'*/ + { + /*Shorten referer to make sure the referer is blocked + *if www.example.org/www.example.com-shall-see-the-referer/ + *links to www.example.com/ + */ + referer[hostlenght+17] = '\n'; + } + if ( 0 == strstr(referer, host)) /*Host has changed*/ + { + log_error(LOG_LEVEL_HEADER, "New host is: %s. Crunching %s!", host, *header); + freez(*header); + } + else + { + log_error(LOG_LEVEL_HEADER, "%s (not modified, still on %s)", *header, host); + } + freez(referer); + freez(host); + return JB_ERR_OK; + } + else if (0 != strcmpic(newval, "forge")) + { + /* + * We have a specific (fixed) referer we want to send. + */ + if ((0 != strncmpic(newval, "http://", 7)) && (0 != strncmpic(newval, "https://", 8))) + { + log_error(LOG_LEVEL_HEADER, "Parameter: +referrer{%s} is a bad idea, but I don't care.", newval); + } *header = strdup("Referer: "); string_append(header, newval); + log_error(LOG_LEVEL_HEADER, "Referer overwritten with: %s", *header); return (*header == NULL) ? JB_ERR_MEMORY : JB_ERR_OK; } @@ -1176,23 +1378,114 @@ * Forge a referer as http://[hostname:port of REQUEST]/ * to fool stupid checks for in-site links */ - if (0 != strcmpic(newval, "forge")) - { - /* - * Invalid choice - but forge is probably the best default. - */ - log_error(LOG_LEVEL_ERROR, "Bad parameter: +referer{%s}", newval); - } *header = strdup("Referer: http://"); string_append(header, csp->http->hostport); string_append(header, "/"); - log_error(LOG_LEVEL_HEADER, "crunch+forge to %s", *header); + log_error(LOG_LEVEL_HEADER, "Referer forged to: %s", *header); return (*header == NULL) ? JB_ERR_MEMORY : JB_ERR_OK; } } +/********************************************************************* + * + * Function : client_accept_language + * + * Description : Handle the "Accept-Language" config setting properly. + * Called from `sed'. + * + * Parameters : + * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : header = On input, pointer to header to modify. + * On output, pointer to the modified header, or NULL + * to remove the header. This function frees the + * original string if necessary. + * + * Returns : JB_ERR_OK on success, or + * JB_ERR_MEMORY on out-of-memory error. + * + *********************************************************************/ +jb_err client_accept_language(struct client_state *csp, char **header) +{ + const char *newval; + + /* + * Are we messing with the Accept-Language? + */ + if ((csp->action->flags & ACTION_HIDE_ACCEPT_LANGUAGE) == 0) + { + /*I don't think so*/ + return JB_ERR_OK; + } + + newval = csp->action->string[ACTION_STRING_LANGUAGE]; + + if ((newval == NULL) || (0 == strcmpic(newval, "block")) ) + { + /* + * Blocking Accept-Language header + */ + log_error(LOG_LEVEL_HEADER, "Crunching Accept-Language!"); + freez(*header); + return JB_ERR_OK; + } + else + { + /* + * Replacing Accept-Language header + */ + freez(*header); + *header = strdup("Accept-Language: "); + string_append(header, newval); + + if (*header == NULL) + { + log_error(LOG_LEVEL_HEADER, " Insufficent memory. Accept-Language header crunched without replacement."); + } + else + { + log_error(LOG_LEVEL_HEADER, "Accept-Language header crunched and replaced with: %s", *header); + } + } + return (*header == NULL) ? JB_ERR_MEMORY : JB_ERR_OK; +} + +/********************************************************************* + * + * Function : crunch_client_header + * + * Description : Crunch client header if it matches a string supplied by the + * user. Called from `sed'. + * + * Parameters : + * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : header = On input, pointer to header to modify. + * On output, pointer to the modified header, or NULL + * to remove the header. This function frees the + * original string if necessary. + * + * Returns : JB_ERR_OK on success and always succeeds + * + *********************************************************************/ +jb_err crunch_client_header(struct client_state *csp, char **header) +{ + const char *crunch_pattern; + /*Is there a header to crunch*/ + + if ((csp->action->flags & ACTION_CRUNCH_CLIENT_HEADER)) + { + crunch_pattern = csp->action->string[ACTION_STRING_CLIENT_HEADER]; + + /*Is the current header the lucky one?*/ + if (strstr(*header, crunch_pattern)) + { + log_error(LOG_LEVEL_HEADER, "Crunching client header: %s", *header); + freez(*header); + } + } + return JB_ERR_OK; +} /********************************************************************* * @@ -1228,16 +1521,15 @@ return JB_ERR_OK; } - log_error(LOG_LEVEL_HEADER, "modified"); - freez(*header); *header = strdup("User-Agent: "); string_append(header, newval); + log_error(LOG_LEVEL_HEADER, "Modified: %s", *header); + return (*header == NULL) ? JB_ERR_MEMORY : JB_ERR_OK; } - /********************************************************************* * * Function : client_ua @@ -1259,7 +1551,7 @@ { if ((csp->action->flags & ACTION_HIDE_USER_AGENT) != 0) { - log_error(LOG_LEVEL_HEADER, "crunch!"); + log_error(LOG_LEVEL_HEADER, "crunched User-Agent!"); freez(*header); } @@ -1303,7 +1595,7 @@ */ if ((newval == NULL) || (0 == strcmpic(newval, "block")) ) { - log_error(LOG_LEVEL_HEADER, "crunch!"); + log_error(LOG_LEVEL_HEADER, "crunched From!"); return JB_ERR_OK; } @@ -1394,7 +1686,7 @@ else { freez(*header); - log_error(LOG_LEVEL_HEADER, " crunch!"); + log_error(LOG_LEVEL_HEADER, "crunched x-forwarded-for!"); } return JB_ERR_OK; @@ -1520,6 +1812,109 @@ return JB_ERR_OK; } +/********************************************************************* + * + * Function : client_if_modified_since + * + * Description : Remove the If-Modified-Since header. + * + * Parameters : + * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : header = On input, pointer to header to modify. + * On output, pointer to the modified header, or NULL + * to remove the header. This function frees the + * original string if necessary. + * + * Returns : JB_ERR_OK on success, or + * JB_ERR_MEMORY on out-of-memory error. + * + *********************************************************************/ +jb_err client_if_modified_since(struct client_state *csp, char **header) +{ + if (csp->action->flags & ACTION_CRUNCH_IF_MODIFIED_SINCE) + { + log_error(LOG_LEVEL_HEADER, "Crunching %s", *header); + freez(*header); + } + else if ( 0 == strcmpic(*header, "If-Modified-Since: Wed, 08 Jun 1955 12:00:00 GMT")) + { + /* + * The client got an error message because of a temporary problem, + * the problem is gone and the client now tries to revalidate our + * error message on the real server. The revalidation would always + * end with the transmission of the whole document and there is + * no need to expose the bogus If-Modified-Since header. + */ + log_error(LOG_LEVEL_HEADER, "Crunching useless If-Modified-Since header."); + freez(*header); + } + + return JB_ERR_OK; +} + +/********************************************************************* + * + * Function : client_if_none_match + * + * Description : Remove the If-None-Match header. + * + * Parameters : + * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : header = On input, pointer to header to modify. + * On output, pointer to the modified header, or NULL + * to remove the header. This function frees the + * original string if necessary. + * + * Returns : JB_ERR_OK on success, or + * JB_ERR_MEMORY on out-of-memory error. + * + *********************************************************************/ +jb_err client_if_none_match(struct client_state *csp, char **header) +{ + if (csp->action->flags & ACTION_CRUNCH_IF_NONE_MATCH) + { + log_error(LOG_LEVEL_HEADER, "Crunching %s", *header); + freez(*header); + } + + return JB_ERR_OK; +} + +/********************************************************************* + * + * Function : client_x_filter + * + * Description : Disables filtering if the client set "X-Filter: No". + * Called from `sed'. + * + * Parameters : + * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : header = On input, pointer to header to modify. + * On output, pointer to the modified header, or NULL + * to remove the header. This function frees the + * original string if necessary. + * + * Returns : JB_ERR_OK on success + * + *********************************************************************/ +jb_err client_x_filter(struct client_state *csp, char **header) +{ + if ( 0 == strcmpic(*header, "X-Filter: No")) + { + if (csp->action->flags & ACTION_FORCE_TEXT_MODE) + { + log_error(LOG_LEVEL_HEADER, "force-text-mode overruled the client's request to disable filtering!"); + } + else + { + csp->content_type = CT_TABOO; + log_error(LOG_LEVEL_HEADER, "Disabled filter mode on behalf of the client."); + } + log_error(LOG_LEVEL_HEADER, "Crunching %s", *header); + freez(*header); + } + return JB_ERR_OK; +} /* the following functions add headers directly to the header list */ @@ -1761,6 +2156,7 @@ *********************************************************************/ jb_err connection_close_adder(struct client_state *csp) { + log_error(LOG_LEVEL_HEADER, "Adding: Connection: close"); return enlist(csp->headers, "Connection: close"); } diff -ru ./parsers.h /tmp/unionfs/privoxy-devel-oben/parsers.h --- ./parsers.h Wed Sep 25 16:52:46 2002 +++ /tmp/unionfs/privoxy-devel-oben/parsers.h Wed May 17 19:12:10 2006 @@ -209,6 +209,11 @@ extern jb_err client_te (struct client_state *csp, char **header); extern jb_err client_max_forwards (struct client_state *csp, char **header); extern jb_err client_host(struct client_state *csp, char **header); +extern jb_err client_if_modified_since(struct client_state *csp, char **header); +extern jb_err client_accept_language (struct client_state *csp, char **header); +extern jb_err client_if_none_match (struct client_state *csp, char **header); +extern jb_err crunch_client_header (struct client_state *csp, char **header); +extern jb_err client_x_filter (struct client_state *csp, char **header); extern jb_err client_host_adder (struct client_state *csp); @@ -226,6 +231,8 @@ extern jb_err server_content_encoding(struct client_state *csp, char **header); extern jb_err server_transfer_coding (struct client_state *csp, char **header); extern jb_err server_http (struct client_state *csp, char **header); +extern jb_err crunch_server_header (struct client_state *csp, char **header); +extern jb_err server_content_disposition(struct client_state *csp, char **header); #ifdef FEATURE_FORCE_LOAD extern int strclean(const char *string, const char *substring); diff -ru ./project.h /tmp/unionfs/privoxy-devel-oben/project.h --- ./project.h Mon Jan 30 00:10:56 2006 +++ /tmp/unionfs/privoxy-devel-oben/project.h Wed May 17 18:22:15 2006 @@ -880,19 +880,57 @@ #define ACTION_JPEG_INSPECT 0x00020000UL /** Action string index: How to deanimate GIFs */ -#define ACTION_STRING_DEANIMATE 0 +#define ACTION_STRING_DEANIMATE 0 /** Action string index: Replacement for "From:" header */ -#define ACTION_STRING_FROM 1 +#define ACTION_STRING_FROM 1 /** Action string index: How to block images */ -#define ACTION_STRING_IMAGE_BLOCKER 2 +#define ACTION_STRING_IMAGE_BLOCKER 2 /** Action string index: Replacement for "Referer:" header */ -#define ACTION_STRING_REFERER 3 +#define ACTION_STRING_REFERER 3 /** Action string index: Replacement for "User-Agent:" header */ -#define ACTION_STRING_USER_AGENT 4 +#define ACTION_STRING_USER_AGENT 4 /** Action string index: Legal CONNECT ports. */ -#define ACTION_STRING_LIMIT_CONNECT 5 +#define ACTION_STRING_LIMIT_CONNECT 5 +/** Action string index: Server headers containing this pattern are crunched*/ +#define ACTION_STRING_SERVER_HEADER 6 +/** Action string index: Client headers containing this pattern are crunched*/ +#define ACTION_STRING_CLIENT_HEADER 7 +/** Action string index: Replacement for the "Accept-Language:" header*/ +#define ACTION_STRING_LANGUAGE 8 +/** Action string index: Replacement for the "Content-Type:" header*/ +#define ACTION_STRING_CONTENT_TYPE 9 +/** Action string index: Replacement for the "content-dispostion:" header*/ +#define ACTION_STRING_CONTENT_DISPOSITION 10 /** Number of string actions. */ -#define ACTION_STRING_COUNT 6 +#define ACTION_STRING_COUNT 11 + +/* + * These defines really belong a few lines higher, + * but moving them down here makes this patch apply + * against Privoxy 3.0.3 too. + */ +/** Action bitmap: Crunch "if-modified-since" header. */ +#define ACTION_CRUNCH_IF_MODIFIED_SINCE 0x00040000UL +/** Action bitmap: Overwrite Content-Type header. */ +#define ACTION_CONTENT_TYPE_OVERWRITE 0x00080000UL +/** Action bitmap: Crunch specified server header. */ +#define ACTION_CRUNCH_SERVER_HEADER 0x00100000UL +/** Action bitmap: Crunch specified client header */ +#define ACTION_CRUNCH_CLIENT_HEADER 0x00200000UL +/** Action bitmap: Enable text mode by force */ +#define ACTION_FORCE_TEXT_MODE 0x00400000UL +/** Action bitmap: Enable text mode by force */ +#define ACTION_CRUNCH_IF_NONE_MATCH 0x00800000UL +/** Action bitmap: Enable content-dispostion crunching */ +#define ACTION_HIDE_CONTENT_DISPOSITION 0x01000000UL +/** Action bitmap: Replace or block Accept-Language header */ +#define ACTION_HIDE_ACCEPT_LANGUAGE 0x02000000UL + + + +/*To make the ugly hack in sed easier to understand*/ +#define CHECK_EVERY_HEADER_REMAINING 0 + /** Index into current_action_spec::multi[] for headers to add. */ #define ACTION_MULTI_ADD_HEADER 0 diff -ru ./templates/edit-actions-for-url /tmp/unionfs/privoxy-devel-oben/templates/edit-actions-for-url --- ./templates/edit-actions-for-url Fri Apr 7 17:42:07 2006 +++ /tmp/unionfs/privoxy-devel-oben/templates/edit-actions-for-url Wed May 17 19:09:56 2006 @@ -393,6 +393,17 @@ + + +

Warning:

+

+ This Privoxy version is not supported by the Privoxy Team. + You are using an inofficial patch. +

+ + + # This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in @@ -594,6 +605,196 @@ hide-forwarded-for-headers Block any existing X-Forwarded-for header, and do not add a new one. + + + + + + crunch-if-modified-since + Remove If-Modified-Since header to circumvent browser cache. Useful for filter testing, + but hurts performance. + + + + + + crunch-if-none-match + Remove If-None-Match header to circumvent browser cache. Useful for filter testing, + but hurts performance. + + + + + + content-type-overwrite + Replace Content-Type header. Useful to let the browser render broken + XHTML as broken + HTML. By default it only applies to + text documents, if you know what you're doing you + can enable force-text-mode to modify binary content types as well. + + +   +   +   +   + New Content-Type:
+ + + + + + + + force-text-mode + + Enable filtering on documents whose Content-Type wasn't recognized as text. + Do think twice, nothing is alright. + + + + + + + + crunch-client-header + Remove header(s) matching the supplied pattern. Together with add-header you can + build a custom header replacement action. + + +   +   +   +   + Header string to suppress:
+ + + + + + + + + crunch-server-header + Remove server header(s) matching the supplied pattern. + + +   +   +   +   + Header string to suppress:
+ + + + + + + + hide-accept-language + Pretend to have different language settings. (Makes a fake User-Agent more believable, + but can lead to foreign content.) + + +   +   +   +   + + This isn't the optinon you're looking for.
+
+
+ + + + + + + hide-content-disposition + Block or overwrite the content-disposition header. Useful to view a document inside the browser, + even if you were supposed to save it first, or to change the suggested file name. + + +   +   +   +   + +
+
+
+ + + Fake as this web address:
+ value="@hide-referrer-param@">
+ +
+