X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=filters.c;h=dd554ba0f936fcef635b3d4352bab401fedbe8e3;hp=993444ca1a83966b85a6a2e7b2e93974459d77cf;hb=2b846688545bf947722a0437608a793202f80cf6;hpb=fc240895e6d9de7652430d0a7d90c12095ea6071 diff --git a/filters.c b/filters.c index 993444ca..dd554ba0 100644 --- a/filters.c +++ b/filters.c @@ -1,4 +1,4 @@ -const char filters_rcs[] = "$Id: filters.c,v 1.122 2009/06/08 16:48:09 fabiankeil Exp $"; +const char filters_rcs[] = "$Id: filters.c,v 1.140 2011/03/03 14:47:28 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/filters.c,v $ @@ -13,7 +13,7 @@ const char filters_rcs[] = "$Id: filters.c,v 1.122 2009/06/08 16:48:09 fabiankei * `execute_single_pcrs_command', `rewrite_url', * `get_last_url' * - * Copyright : Written by and Copyright (C) 2001, 2004-2009 the + * Copyright : Written by and Copyright (C) 2001-2010 the * Privoxy team. http://www.privoxy.org/ * * Based on the Internet Junkbuster originally written @@ -50,11 +50,6 @@ const char filters_rcs[] = "$Id: filters.c,v 1.122 2009/06/08 16:48:09 fabiankei #include #include -#ifdef HAVE_RFC2553 -#include -#include -#endif /* def HAVE_RFC2553 */ - #ifndef _WIN32 #ifndef __OS2__ #include @@ -98,6 +93,8 @@ const char filters_h_rcs[] = FILTERS_H_VERSION; */ #define ijb_isdigit(__X) isdigit((int)(unsigned char)(__X)) +typedef char *(*filter_function_ptr)(); +static filter_function_ptr get_filter_function(const struct client_state *csp); static jb_err remove_chunked_transfer_coding(char *buffer, size_t *size); static jb_err prepare_for_filtering(struct client_state *csp); @@ -292,6 +289,10 @@ int block_acl(const struct access_control_addr *dst, const struct client_state * { return(0); } + else + { + return(1); + } } else if ( #ifdef HAVE_RFC2553 @@ -419,14 +420,15 @@ int acl_addr(const char *aspec, struct access_control_addr *aca) hints.ai_socktype = SOCK_STREAM; i = getaddrinfo(acl_spec, ((p) ? ++p : NULL), &hints, &result); - freez(acl_spec); if (i != 0) { log_error(LOG_LEVEL_ERROR, "Can not resolve [%s]:%s: %s", acl_spec, p, gai_strerror(i)); + freez(acl_spec); return(-1); } + freez(acl_spec); /* TODO: Allow multihomed hostnames */ memcpy(&(aca->addr), result->ai_addr, result->ai_addrlen); @@ -598,7 +600,6 @@ struct http_response *block_url(struct client_state *csp) { log_error(LOG_LEVEL_ERROR, "handle-as-empty-document overruled by handle-as-image."); } -#if 1 /* Two alternative strategies, use this one for now: */ /* and handle accordingly: */ if ((p == NULL) || (0 == strcmpic(p, "pattern"))) @@ -623,7 +624,6 @@ struct http_response *block_url(struct client_state *csp) return cgi_error_memory(); } } - else if (0 == strcmpic(p, "blank")) { rsp->status = strdup("403 Request blocked by Privoxy"); @@ -646,7 +646,6 @@ struct http_response *block_url(struct client_state *csp) return cgi_error_memory(); } } - else { rsp->status = strdup("302 Local Redirect from Privoxy"); @@ -663,32 +662,10 @@ struct http_response *block_url(struct client_state *csp) } } -#else /* Following code is disabled for now */ - - /* and handle accordingly: */ - if ((p == NULL) || (0 == strcmpic(p, "pattern"))) - { - p = CGI_PREFIX "send-banner?type=pattern"; - } - else if (0 == strcmpic(p, "blank")) - { - p = CGI_PREFIX "send-banner?type=blank"; - } - rsp->status = strdup("302 Local Redirect from Privoxy"); - if (rsp->status == NULL) - { - free_http_response(rsp); - return cgi_error_memory(); - } - - if (enlist_unique_header(rsp->headers, "Location", p)) - { - free_http_response(rsp); - return cgi_error_memory(); - } -#endif /* Preceeding code is disabled for now */ } - else if(csp->action->flags & ACTION_HANDLE_AS_EMPTY_DOCUMENT) + else +#endif /* def FEATURE_IMAGE_BLOCKING */ + if(csp->action->flags & ACTION_HANDLE_AS_EMPTY_DOCUMENT) { /* * Send empty document. @@ -699,7 +676,21 @@ struct http_response *block_url(struct client_state *csp) rsp->body = strdup(" "); rsp->content_length = 1; - rsp->status = strdup("403 Request blocked by Privoxy"); + if (csp->config->feature_flags & RUNTIME_FEATURE_EMPTY_DOC_RETURNS_OK) + { + /* + * Workaround for firefox bug 492459 + * https://bugzilla.mozilla.org/show_bug.cgi?id=492459 + * Return a 200 OK status for pages blocked with +handle-as-empty-document + * if the "handle-as-empty-doc-returns-ok" runtime config option is set. + */ + rsp->status = strdup("200 Request blocked by Privoxy"); + } + else + { + rsp->status = strdup("403 Request blocked by Privoxy"); + } + if (rsp->status == NULL) { free_http_response(rsp); @@ -716,7 +707,6 @@ struct http_response *block_url(struct client_state *csp) } } else -#endif /* def FEATURE_IMAGE_BLOCKING */ /* * Else, generate an HTML "blocked" message: @@ -738,11 +728,11 @@ struct http_response *block_url(struct client_state *csp) && !strstr(p, "compatible") /* MSIE */ && !strstr(p, "Opera")) /* and Opera. */ { - rsp->status = strdup("200 Request for blocked URL"); + rsp->status = strdup("200 Request blocked by Privoxy"); } else { - rsp->status = strdup("403 Request for blocked URL"); + rsp->status = strdup("403 Request blocked by Privoxy"); } if (rsp->status == NULL) @@ -806,7 +796,7 @@ struct http_response *block_url(struct client_state *csp) return cgi_error_memory(); } } - rsp->reason = RSP_REASON_BLOCKED; + rsp->crunch_reason = BLOCKED; return finish_http_response(csp, rsp); @@ -966,7 +956,7 @@ struct http_response *trust_url(struct client_state *csp) free_http_response(rsp); return cgi_error_memory(); } - rsp->reason = RSP_REASON_UNTRUSTED; + rsp->crunch_reason = UNTRUSTED; return finish_http_response(csp, rsp); } @@ -1012,10 +1002,9 @@ pcrs_job *compile_dynamic_pcrs_job_list(const struct client_state *csp, const st dummy = pcrs_compile_dynamic_command(pattern->str, variables, &error); if (NULL == dummy) { - assert(error < 0); log_error(LOG_LEVEL_ERROR, - "Adding filter job \'%s\' to dynamic filter %s failed: %s", - pattern->str, b->name, pcrs_strerror(error)); + "Compiling dynamic pcrs job '%s' for '%s' failed with error code %d: %s", + pattern->str, b->name, error, pcrs_strerror(error)); continue; } else @@ -1306,7 +1295,7 @@ struct http_response *redirect_url(struct client_state *csp) free_http_response(rsp); return cgi_error_memory(); } - rsp->reason = RSP_REASON_REDIRECTED; + rsp->crunch_reason = REDIRECTED; freez(new_url); return finish_http_response(csp, rsp); @@ -1521,7 +1510,8 @@ int is_untrusted_url(const struct client_state *csp) *********************************************************************/ static char *pcrs_filter_response(struct client_state *csp) { - int hits=0; + int hits = 0; + int i; size_t size, prev_size; char *old = NULL; @@ -1532,8 +1522,6 @@ static char *pcrs_filter_response(struct client_state *csp) struct re_filterfile_spec *b; struct list_entry *filtername; - int i, found_filters = 0; - /* * Sanity first */ @@ -1542,23 +1530,7 @@ static char *pcrs_filter_response(struct client_state *csp) return(NULL); } - /* - * Need to check the set of re_filterfiles... - */ - for (i = 0; i < MAX_AF_FILES; i++) - { - fl = csp->rlist[i]; - if (NULL != fl) - { - if (NULL != fl->f) - { - found_filters = 1; - break; - } - } - } - - if (0 == found_filters) + if (filters_available(csp) == FALSE) { log_error(LOG_LEVEL_ERROR, "Inconsistent configuration: " "content filtering enabled, but no content filters available."); @@ -1766,48 +1738,10 @@ static char *gif_deanimate_response(struct client_state *csp) * NULL if no content filter is active * *********************************************************************/ -filter_function_ptr get_filter_function(struct client_state *csp) +static filter_function_ptr get_filter_function(const struct client_state *csp) { filter_function_ptr filter_function = NULL; - if ((csp->content_type & CT_TABOO) - && !(csp->action->flags & ACTION_FORCE_TEXT_MODE)) - { - return NULL; - } - - /* - * 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!"); - } - } - - if (!(csp->content_type & CT_DECLARED)) - { - /* - * The server didn't bother to declare a MIME-Type. - * Assume it's text that can be filtered. - * - * This also regulary happens with 304 responses, - * therefore logging anything here would cause - * too much noise. - */ - csp->content_type |= CT_TEXT; - } - /* * Choose the applying filter function based on * the content type and action settings. @@ -1870,8 +1804,14 @@ static jb_err remove_chunked_transfer_coding(char *buffer, size_t *size) if ((newsize += chunksize) >= *size) { + /* + * XXX: The message is a bit confusing. Isn't the real problem that + * the specified chunk size is greater than the number of bytes + * left in the buffer? This probably means the connection got + * closed prematurely. To be investigated after 3.0.17 is out. + */ log_error(LOG_LEVEL_ERROR, - "Chunk size %d exceeds buffer size %d in \"chunked\" transfer coding", + "Chunk size %d exceeds buffer size %d in \"chunked\" transfer coding", chunksize, *size); return JB_ERR_PARSE; } @@ -1975,20 +1915,23 @@ static jb_err prepare_for_filtering(struct client_state *csp) /********************************************************************* * - * Function : execute_content_filter + * Function : execute_content_filters * * Description : Executes a given content filter. * * Parameters : * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : content_filter = The filter function to execute * * Returns : Pointer to the modified buffer, or * NULL if filtering failed or wasn't necessary. * *********************************************************************/ -char *execute_content_filter(struct client_state *csp, filter_function_ptr content_filter) +char *execute_content_filters(struct client_state *csp) { + filter_function_ptr content_filter; + + assert(content_filters_enabled(csp->action)); + if (0 == csp->iob->eod - csp->iob->cur) { /* @@ -2014,6 +1957,8 @@ char *execute_content_filter(struct client_state *csp, filter_function_ptr conte return NULL; } + content_filter = get_filter_function(csp); + return ((*content_filter)(csp)); } @@ -2318,7 +2263,7 @@ struct http_response *direct_response(struct client_state *csp) } rsp->is_static = 1; - rsp->reason = RSP_REASON_UNSUPPORTED; + rsp->crunch_reason = UNSUPPORTED; return(finish_http_response(csp, rsp)); } @@ -2329,6 +2274,81 @@ struct http_response *direct_response(struct client_state *csp) } +/********************************************************************* + * + * Function : content_requires_filtering + * + * Description : Checks whether there are any content filters + * enabled for the current request and if they + * can actually be applied.. + * + * Parameters : + * 1 : csp = Current client state (buffers, headers, etc...) + * + * Returns : TRUE for yes, FALSE otherwise + * + *********************************************************************/ +int content_requires_filtering(struct client_state *csp) +{ + if ((csp->content_type & CT_TABOO) + && !(csp->action->flags & ACTION_FORCE_TEXT_MODE)) + { + return FALSE; + } + + /* + * 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!"); + } + } + + if (!(csp->content_type & CT_DECLARED)) + { + /* + * The server didn't bother to declare a MIME-Type. + * Assume it's text that can be filtered. + * + * This also regulary happens with 304 responses, + * therefore logging anything here would cause + * too much noise. + */ + csp->content_type |= CT_TEXT; + } + + /* + * Choose the applying filter function based on + * the content type and action settings. + */ + if ((csp->content_type & CT_TEXT) && + (csp->rlist != NULL) && + (!list_is_empty(csp->action->multi[ACTION_MULTI_FILTER]))) + { + return TRUE; + } + else if ((csp->content_type & CT_GIF) && + (csp->action->flags & ACTION_DEANIMATE)) + { + return TRUE; + } + + return FALSE; + +} + + /********************************************************************* * * Function : content_filters_enabled @@ -2348,6 +2368,34 @@ int content_filters_enabled(const struct current_action_spec *action) !list_is_empty(action->multi[ACTION_MULTI_FILTER])); } + +/********************************************************************* + * + * Function : filters_available + * + * Description : Checks whether there are any filters available. + * + * Parameters : + * 1 : csp = Current client state (buffers, headers, etc...) + * + * Returns : TRUE for yes, FALSE otherwise. + * + *********************************************************************/ +int filters_available(const struct client_state *csp) +{ + int i; + for (i = 0; i < MAX_AF_FILES; i++) + { + const struct file_list *fl = csp->rlist[i]; + if ((NULL != fl) && (NULL != fl->f)) + { + return TRUE; + } + } + return FALSE; +} + + /* Local Variables: tab-width: 3