X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=parsers.c;h=11845600fdb50b49700c85a8e9cc8d152df81c71;hp=41ad53ebbea6c8dc51908f82e2d2113d1ddec79a;hb=3c5d3feddfd392206430fcef1b4e0e93ce70d74d;hpb=b4a241df39fde279bddb890299d880e00287b258 diff --git a/parsers.c b/parsers.c index 41ad53eb..11845600 100644 --- a/parsers.c +++ b/parsers.c @@ -1,4 +1,4 @@ -const char parsers_rcs[] = "$Id: parsers.c,v 1.212 2010/06/13 12:25:33 fabiankeil Exp $"; +const char parsers_rcs[] = "$Id: parsers.c,v 1.222 2011/04/19 13:00:47 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/parsers.c,v $ @@ -152,6 +152,9 @@ static jb_err server_http (struct client_state *csp, char **header static jb_err crunch_server_header (struct client_state *csp, char **header); static jb_err server_last_modified (struct client_state *csp, char **header); static jb_err server_content_disposition(struct client_state *csp, char **header); +#ifdef FEATURE_ZLIB +static jb_err server_adjust_content_encoding(struct client_state *csp, char **header); +#endif #ifdef FEATURE_CONNECTION_KEEP_ALIVE static jb_err server_save_content_length(struct client_state *csp, char **header); @@ -616,10 +619,12 @@ jb_err decompress_iob(struct client_state *csp) } /* - * If we tried the limit and still didn't have enough - * memory, just give up. + * If we reached the buffer limit and still didn't have enough + * memory, just give up. Due to the ceiling enforced by the next + * if block we could actually check for equality here, but as it + * can be easily mistaken for a bug we don't. */ - if (bufsize == csp->config->buffer_limit) + if (bufsize >= csp->config->buffer_limit) { log_error(LOG_LEVEL_ERROR, "Buffer limit reached while decompressing iob"); return JB_ERR_MEMORY; @@ -1137,7 +1142,7 @@ jb_err update_server_headers(struct client_state *csp) { "Content-Length:", 15, server_adjust_content_length }, { "Transfer-Encoding:", 18, server_transfer_coding }, #ifdef FEATURE_ZLIB - { "Content-Encoding:", 17, server_content_encoding }, + { "Content-Encoding:", 17, server_adjust_content_encoding }, #endif /* def FEATURE_ZLIB */ { NULL, 0, NULL } }; @@ -1956,7 +1961,7 @@ static jb_err crunch_server_header(struct client_state *csp, char **header) * Function : server_content_type * * Description : Set the content-type for filterable types (text/.*, - * .*xml.*, javascript and image/gif) unless filtering has been + * .*xml.*, .*script.* and image/gif) unless filtering has been * forbidden (CT_TABOO) while parsing earlier headers. * NOTE: Since text/plain is commonly used by web servers * for files whose correct type is unknown, we don't @@ -2006,7 +2011,7 @@ static jb_err server_content_type(struct client_state *csp, char **header) */ if ((strstr(*header, "text/") && !strstr(*header, "plain")) || strstr(*header, "xml") - || strstr(*header, "application/x-javascript")) + || strstr(*header, "script")) { csp->content_type |= CT_TEXT; } @@ -2022,7 +2027,7 @@ static jb_err server_content_type(struct client_state *csp, char **header) if (csp->action->flags & ACTION_CONTENT_TYPE_OVERWRITE) { /* - * Make sure the user doesn't accidently + * Make sure the user doesn't accidentally * change the content type of binary documents. */ if ((csp->content_type & CT_TEXT) || (csp->action->flags & ACTION_FORCE_TEXT_MODE)) @@ -2116,16 +2121,16 @@ static jb_err server_transfer_coding(struct client_state *csp, char **header) * * Function : server_content_encoding * - * Description : This function is run twice for each request, - * unless FEATURE_ZLIB and filtering are disabled. + * Description : Used to check if the content is compressed, and if + * FEATURE_ZLIB is disabled, filtering is disabled as + * well. * - * The first run is used to check if the content - * is compressed, if FEATURE_ZLIB is disabled - * filtering is then disabled as well, if FEATURE_ZLIB - * is enabled the content is marked for decompression. + * If FEATURE_ZLIB is enabled and the compression type + * supported, the content is marked for decompression. * - * The second run is used to remove the Content-Encoding - * header if the decompression was successful. + * XXX: Doesn't properly deal with multiple or with + * unsupported but unknown encodings. + * Is case-sensitive but shouldn't be. * * Parameters : * 1 : csp = Current client state (buffers, headers, etc...) @@ -2141,19 +2146,25 @@ static jb_err server_transfer_coding(struct client_state *csp, char **header) static jb_err server_content_encoding(struct client_state *csp, char **header) { #ifdef FEATURE_ZLIB - if ((csp->flags & CSP_FLAG_MODIFIED) - && (csp->content_type & (CT_GZIP | CT_DEFLATE))) + if (strstr(*header, "sdch")) { /* - * We successfully decompressed the content, - * and have to clean the header now, so the - * client no longer expects compressed data.. - * - * XXX: There is a difference between cleaning - * and removing it completely. + * Shared Dictionary Compression over HTTP isn't supported, + * filtering it anyway is pretty much guaranteed to mess up + * the encoding. */ - log_error(LOG_LEVEL_HEADER, "Crunching: %s", *header); - freez(*header); + csp->content_type |= CT_TABOO; + + /* + * Log a warning if the user expects the content to be filtered. + */ + if ((csp->rlist != NULL) && + (!list_is_empty(csp->action->multi[ACTION_MULTI_FILTER]))) + { + log_error(LOG_LEVEL_INFO, + "SDCH-compressed content detected, content filtering disabled. " + "Consider suppressing SDCH offers made by the client."); + } } else if (strstr(*header, "gzip")) { @@ -2174,7 +2185,16 @@ static jb_err server_content_encoding(struct client_state *csp, char **header) csp->content_type |= CT_TABOO; } #else /* !defined(FEATURE_ZLIB) */ - if (strstr(*header, "gzip") || strstr(*header, "compress") || strstr(*header, "deflate")) + /* + * XXX: Using a black list here isn't the right approach. + * + * In case of SDCH, building with zlib support isn't + * going to help. + */ + if (strstr(*header, "gzip") || + strstr(*header, "compress") || + strstr(*header, "deflate") || + strstr(*header, "sdch")) { /* * Body is compressed, turn off pcrs and gif filtering. @@ -2200,6 +2220,49 @@ static jb_err server_content_encoding(struct client_state *csp, char **header) } +#ifdef FEATURE_ZLIB +/********************************************************************* + * + * Function : server_adjust_content_encoding + * + * Description : Remove the Content-Encoding header if the + * decompression was successful and the content + * has been modifed. + * + * 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. + * + *********************************************************************/ +static jb_err server_adjust_content_encoding(struct client_state *csp, char **header) +{ + if ((csp->flags & CSP_FLAG_MODIFIED) + && (csp->content_type & (CT_GZIP | CT_DEFLATE))) + { + /* + * We successfully decompressed the content, + * and have to clean the header now, so the + * client no longer expects compressed data.. + * + * XXX: There is a difference between cleaning + * and removing it completely. + */ + log_error(LOG_LEVEL_HEADER, "Crunching: %s", *header); + freez(*header); + } + + return JB_ERR_OK; + +} +#endif /* defined(FEATURE_ZLIB) */ + + /********************************************************************* * * Function : server_adjust_content_length @@ -2394,14 +2457,9 @@ static jb_err server_last_modified(struct client_state *csp, char **header) { const char *newval; char buf[BUFFER_SIZE]; - + time_t last_modified; char newheader[50]; -#ifdef HAVE_GMTIME_R - struct tm gmt; -#endif - struct tm *timeptr = NULL; - time_t now, last_modified; - + /* * Are we messing with the Last-Modified header? */ @@ -2446,16 +2504,7 @@ static jb_err server_last_modified(struct client_state *csp, char **header) const char *header_time = *header + sizeof("Last-Modified:"); log_error(LOG_LEVEL_HEADER, "Randomizing: %s", *header); - now = time(NULL); -#ifdef HAVE_GMTIME_R - gmtime_r(&now, &gmt); -#elif defined(MUTEX_LOCKS_AVAILABLE) - privoxy_mutex_lock(&gmtime_mutex); - gmtime(&now); - privoxy_mutex_unlock(&gmtime_mutex); -#else - gmtime(&now); -#endif + if (JB_ERR_OK != parse_header_time(header_time, &last_modified)) { log_error(LOG_LEVEL_HEADER, "Couldn't parse: %s in %s (crunching!)", header_time, *header); @@ -2463,7 +2512,14 @@ static jb_err server_last_modified(struct client_state *csp, char **header) } else { - long int rtime = (long int)difftime(now, last_modified); + time_t now; + struct tm *timeptr = NULL; + long int rtime; +#ifdef HAVE_GMTIME_R + struct tm gmt; +#endif + now = time(NULL); + rtime = (long int)difftime(now, last_modified); if (rtime) { long int days, hours, minutes, seconds; @@ -2554,22 +2610,7 @@ static jb_err client_accept_encoding(struct client_state *csp, char **header) if ((csp->action->flags & ACTION_NO_COMPRESSION) != 0) { log_error(LOG_LEVEL_HEADER, "Suppressed offer to compress content"); - freez(*header); - - /* Temporarily disable the correct behaviour to - * work around a PHP bug. - * - * if (!strcmpic(csp->http->ver, "HTTP/1.1")) - * { - * *header = strdup("Accept-Encoding: identity;q=1.0, *;q=0"); - * if (*header == NULL) - * { - * return JB_ERR_MEMORY; - * } - * } - * - */ } return JB_ERR_OK; @@ -3153,7 +3194,6 @@ static jb_err client_if_modified_since(struct client_state *csp, char **header) struct tm *timeptr = NULL; time_t tm = 0; const char *newval; - long int hours, minutes, seconds; char * endptr; if ( 0 == strcmpic(*header, "If-Modified-Since: Wed, 08 Jun 1955 12:00:00 GMT")) @@ -3188,6 +3228,7 @@ static jb_err client_if_modified_since(struct client_state *csp, char **header) } else { + long int hours, minutes, seconds; long int rtime = strtol(newval, &endptr, 0); const int negative_range = (rtime < 0); @@ -3530,7 +3571,7 @@ static jb_err client_x_forwarded_for_adder(struct client_state *csp) * * Function : server_connection_adder * - * Description : Adds an appropiate "Connection:" header to csp->headers + * Description : Adds an appropriate "Connection:" header to csp->headers * unless the header was already present. Called from `sed'. * * Parameters : @@ -3583,7 +3624,7 @@ static jb_err server_connection_adder(struct client_state *csp) * * Description : Adds a "Proxy-Connection: keep-alive" header to * csp->headers if the client asked for keep-alive. - * XXX: We should reuse existant ones. + * XXX: We should reuse existent ones. * * Parameters : * 1 : csp = Current client state (buffers, headers, etc...) @@ -3895,7 +3936,7 @@ static jb_err server_set_cookie(struct client_state *csp, char **header) * * Function : strclean * - * Description : In-Situ-Eliminate all occurances of substring in + * Description : In-Situ-Eliminate all occurrences of substring in * string * * Parameters : @@ -4015,7 +4056,8 @@ jb_err get_destination_from_headers(const struct list *headers, struct http_requ return JB_ERR_PARSE; } - if (NULL == (p = strdup((host)))) + p = strdup(host); + if (NULL == p) { log_error(LOG_LEVEL_ERROR, "Out of memory while parsing \"Host:\" header"); return JB_ERR_MEMORY; @@ -4159,7 +4201,7 @@ static jb_err handle_conditional_hide_referrer_parameter(char **header, const char *host, const int parameter_conditional_block) { char *referer = strdup(*header); - const size_t hostlenght = strlen(host); + const size_t hostlength = strlen(host); const char *referer_url = NULL; if (NULL == referer) @@ -4169,14 +4211,14 @@ static jb_err handle_conditional_hide_referrer_parameter(char **header, } /* referer begins with 'Referer: http[s]://' */ - if ((hostlenght+17) < strlen(referer)) + if ((hostlength+17) < strlen(referer)) { /* * 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] = '\0'; + referer[hostlength+17] = '\0'; } referer_url = strstr(referer, "http://"); if ((NULL == referer_url) || (NULL == strstr(referer_url, host)))