From 65a065fd16408655139c44885b31bf57a5cb5b8c Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Tue, 14 Sep 2010 07:16:07 +0000 Subject: [PATCH] Add content_requires_filtering() as chat() not only needs to now if filtering is enabled, but also if the filters can be executed. --- filters.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- filters.h | 3 ++- jcc.c | 14 +++++----- 3 files changed, 85 insertions(+), 9 deletions(-) diff --git a/filters.c b/filters.c index d8f77a0e..1caac7e1 100644 --- a/filters.c +++ b/filters.c @@ -1,4 +1,4 @@ -const char filters_rcs[] = "$Id: filters.c,v 1.131 2010/09/14 07:13:10 fabiankeil Exp $"; +const char filters_rcs[] = "$Id: filters.c,v 1.132 2010/09/14 07:14:56 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/filters.c,v $ @@ -2308,6 +2308,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 diff --git a/filters.h b/filters.h index 0ec16a97..6e08dda3 100644 --- a/filters.h +++ b/filters.h @@ -1,6 +1,6 @@ #ifndef FILTERS_H_INCLUDED #define FILTERS_H_INCLUDED -#define FILTERS_H_VERSION "$Id: filters.h,v 1.39 2010/09/14 07:13:10 fabiankeil Exp $" +#define FILTERS_H_VERSION "$Id: filters.h,v 1.40 2010/09/14 07:14:56 fabiankeil Exp $" /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/filters.h,v $ @@ -108,6 +108,7 @@ extern char *get_last_url(char *subject, const char *redirect_mode); extern pcrs_job *compile_dynamic_pcrs_job_list(const struct client_state *csp, const struct re_filterfile_spec *b); +extern int content_requires_filtering(struct client_state *csp); extern int content_filters_enabled(const struct current_action_spec *action); extern int filters_available(const struct client_state *csp); diff --git a/jcc.c b/jcc.c index ce7c661c..317d87cf 100644 --- a/jcc.c +++ b/jcc.c @@ -1,4 +1,4 @@ -const char jcc_rcs[] = "$Id: jcc.c,v 1.328 2010/09/14 07:13:10 fabiankeil Exp $"; +const char jcc_rcs[] = "$Id: jcc.c,v 1.329 2010/09/14 07:14:15 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/jcc.c,v $ @@ -1521,7 +1521,7 @@ static void chat(struct client_state *csp) const struct forward_spec *fwd; struct http_request *http; long len = 0; /* for buffer sizes (and negative error codes) */ - int content_filtering_is_enabled = 0; + int buffer_and_filter_content = 0; /* Skeleton for HTTP response, if we should intercept the request */ struct http_response *rsp; @@ -2047,7 +2047,7 @@ static void chat(struct client_state *csp) * now is the time to apply content modification * and send the result to the client. */ - if (content_filtering_is_enabled) + if (buffer_and_filter_content) { p = execute_content_filters(csp); /* @@ -2113,7 +2113,7 @@ static void chat(struct client_state *csp) */ if (server_body || http->ssl) { - if (content_filtering_is_enabled) + if (buffer_and_filter_content) { /* * If there is no memory left for buffering the content, or the buffer limit @@ -2161,7 +2161,7 @@ static void chat(struct client_state *csp) */ byte_count = (unsigned long long)flushed; freez(hdr); - content_filtering_is_enabled = 0; + buffer_and_filter_content = 0; server_body = 1; } } @@ -2328,12 +2328,12 @@ static void chat(struct client_state *csp) if (!http->ssl) /* We talk plaintext */ { - content_filtering_is_enabled = content_filters_enabled(csp->action); + buffer_and_filter_content = content_requires_filtering(csp); } /* * Only write if we're not buffering for content modification */ - if (!content_filtering_is_enabled) + if (!buffer_and_filter_content) { /* * Write the server's (modified) header to -- 2.39.2