From: Fabian Keil Date: Sun, 24 Nov 2013 14:24:18 +0000 (+0000) Subject: Introduce negative tag patterns NO-REQUEST-TAG and NO-RESPONSE-TAG X-Git-Tag: v_3_0_22~215 X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=commitdiff_plain;h=74c6330838b7b06fb29fc7ead87f49e3f13f1bf2 Introduce negative tag patterns NO-REQUEST-TAG and NO-RESPONSE-TAG They apply if no matching tag is found after parsing client or server headers. --- diff --git a/actions.c b/actions.c index acd3d7cb..b07d8bc9 100644 --- a/actions.c +++ b/actions.c @@ -1,4 +1,4 @@ -const char actions_rcs[] = "$Id: actions.c,v 1.87 2012/11/24 13:59:00 fabiankeil Exp $"; +const char actions_rcs[] = "$Id: actions.c,v 1.88 2013/11/24 14:22:51 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/actions.c,v $ @@ -810,8 +810,8 @@ int update_action_bits_for_tag(struct client_state *csp, const char *tag) /* and through all the action patterns, */ for (b = b->next; NULL != b; b = b->next) { - /* skip the URL patterns, */ - if (NULL == b->url->pattern.tag_regex) + /* skip everything but TAG patterns, */ + if (!(b->url->flags & PATTERN_SPEC_TAG_PATTERN)) { continue; } @@ -835,6 +835,76 @@ int update_action_bits_for_tag(struct client_state *csp, const char *tag) } +/********************************************************************* + * + * Function : check_negative_tag_patterns + * + * Description : Updates the action bits based on NO-*-TAG patterns. + * + * Parameters : + * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : flag = The tag pattern type + * + * Returns : JB_ERR_OK in case off success, or + * JB_ERR_MEMORY on out-of-memory error. + * + *********************************************************************/ +jb_err check_negative_tag_patterns(struct client_state *csp, unsigned int flag) +{ + struct list_entry *tag; + struct file_list *fl; + struct url_actions *b = NULL; + int i; + + for (i = 0; i < MAX_AF_FILES; i++) + { + fl = csp->actions_list[i]; + if ((fl == NULL) || ((b = fl->f) == NULL)) + { + continue; + } + for (b = b->next; NULL != b; b = b->next) + { + int tag_found = 0; + if (0 == (b->url->flags & flag)) + { + continue; + } + for (tag = csp->tags->first; NULL != tag; tag = tag->next) + { + if (0 == regexec(b->url->pattern.tag_regex, tag->str, 0, NULL, 0)) + { + /* + * The pattern matches at least one tag, thus the action + * section doesn't apply and we don't need to look at the + * other tags. + */ + tag_found = 1; + break; + } + } + if (!tag_found) + { + /* + * The pattern doesn't match any tags, + * thus the action section applies. + */ + if (merge_current_action(csp->action, b->action)) + { + log_error(LOG_LEVEL_ERROR, + "Out of memory while changing action bits"); + return JB_ERR_MEMORY; + } + log_error(LOG_LEVEL_HEADER, "Updated action bits based on: %s", + b->url->spec); + } + } + } + + return JB_ERR_OK; +} + + /********************************************************************* * * Function : free_current_action diff --git a/actions.h b/actions.h index be9f02ce..5b9e7dcd 100644 --- a/actions.h +++ b/actions.h @@ -1,6 +1,6 @@ #ifndef ACTIONS_H_INCLUDED #define ACTIONS_H_INCLUDED -#define ACTIONS_H_VERSION "$Id: actions.h,v 1.21 2012/07/27 17:39:57 fabiankeil Exp $" +#define ACTIONS_H_VERSION "$Id: actions.h,v 1.22 2013/11/24 14:23:28 fabiankeil Exp $" /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/actions.h,v $ @@ -64,6 +64,7 @@ extern jb_err merge_actions (struct action_spec *dest, extern int update_action_bits_for_all_tags(struct client_state *csp); #endif extern int update_action_bits_for_tag(struct client_state *csp, const char *tag); +extern jb_err check_negative_tag_patterns(struct client_state *csp, unsigned int flag); extern jb_err copy_action (struct action_spec *dest, const struct action_spec *src); extern char * actions_to_text (const struct action_spec *action); diff --git a/parsers.c b/parsers.c index bd5d33d2..0e58c115 100644 --- a/parsers.c +++ b/parsers.c @@ -1,4 +1,4 @@ -const char parsers_rcs[] = "$Id: parsers.c,v 1.278 2013/08/06 12:58:28 fabiankeil Exp $"; +const char parsers_rcs[] = "$Id: parsers.c,v 1.279 2013/08/06 12:59:34 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/parsers.c,v $ @@ -1097,6 +1097,7 @@ static void enforce_header_order(struct list *headers, const struct list *ordere return; } + /********************************************************************* * * Function : sed @@ -1126,19 +1127,21 @@ jb_err sed(struct client_state *csp, int filter_server_headers) const add_header_func_ptr *f; jb_err err = JB_ERR_OK; + scan_headers(csp); + if (filter_server_headers) { v = server_patterns; f = add_server_headers; + check_negative_tag_patterns(csp, PATTERN_SPEC_NO_RESPONSE_TAG_PATTERN); } else { v = client_patterns; f = add_client_headers; + check_negative_tag_patterns(csp, PATTERN_SPEC_NO_REQUEST_TAG_PATTERN); } - scan_headers(csp); - while ((err == JB_ERR_OK) && (v->str != NULL)) { for (p = csp->headers->first; (err == JB_ERR_OK) && (p != NULL); p = p->next) diff --git a/project.h b/project.h index efcb4568..8e0e9372 100644 --- a/project.h +++ b/project.h @@ -1,7 +1,7 @@ #ifndef PROJECT_H_INCLUDED #define PROJECT_H_INCLUDED /** Version string. */ -#define PROJECT_H_VERSION "$Id: project.h,v 1.198 2013/11/24 14:22:51 fabiankeil Exp $" +#define PROJECT_H_VERSION "$Id: project.h,v 1.199 2013/11/24 14:23:28 fabiankeil Exp $" /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/project.h,v $ @@ -393,6 +393,17 @@ struct pattern_spec */ #define ANCHOR_RIGHT 2 +/** Pattern spec bitmap: It's an URL pattern. */ +#define PATTERN_SPEC_URL_PATTERN 0x00000001UL + +/** Pattern spec bitmap: It's a TAG pattern. */ +#define PATTERN_SPEC_TAG_PATTERN 0x00000002UL + +/** Pattern spec bitmap: It's a NO-REQUEST-TAG pattern. */ +#define PATTERN_SPEC_NO_REQUEST_TAG_PATTERN 0x00000004UL + +/** Pattern spec bitmap: It's a NO-RESPONSE-TAG pattern. */ +#define PATTERN_SPEC_NO_RESPONSE_TAG_PATTERN 0x00000008UL /** * An I/O buffer. Holds a string which can be appended to, and can have data diff --git a/urlmatch.c b/urlmatch.c index 3e807bbd..092ae0f5 100644 --- a/urlmatch.c +++ b/urlmatch.c @@ -1,4 +1,4 @@ -const char urlmatch_rcs[] = "$Id: urlmatch.c,v 1.75 2012/12/07 12:49:47 fabiankeil Exp $"; +const char urlmatch_rcs[] = "$Id: urlmatch.c,v 1.76 2013/11/24 14:22:51 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/urlmatch.c,v $ @@ -1114,13 +1114,31 @@ jb_err create_url_spec(struct pattern_spec *url, char *buf) /* Remember the original specification for the CGI pages. */ url->spec = strdup_or_die(buf); - /* Is it a tag pattern? */ + /* Is it a positive tag pattern? */ if (0 == strncmpic(url->spec, "TAG:", 4)) { /* The pattern starts with the first character after "TAG:" */ const char *tag_pattern = buf + 4; + url->flags |= PATTERN_SPEC_TAG_PATTERN; return compile_pattern(tag_pattern, NO_ANCHORING, url, &url->pattern.tag_regex); } + /* Is it a negative tag pattern? */ + if (0 == strncmpic(url->spec, "NO-REQUEST-TAG:", 15)) + { + /* The pattern starts with the first character after "NO-REQUEST-TAG:" */ + const char *tag_pattern = buf + 15; + url->flags |= PATTERN_SPEC_NO_REQUEST_TAG_PATTERN; + return compile_pattern(tag_pattern, NO_ANCHORING, url, &url->pattern.tag_regex); + } + if (0 == strncmpic(url->spec, "NO-RESPONSE-TAG:", 16)) + { + /* The pattern starts with the first character after "NO-RESPONSE-TAG:" */ + const char *tag_pattern = buf + 16; + url->flags |= PATTERN_SPEC_NO_RESPONSE_TAG_PATTERN; + return compile_pattern(tag_pattern, NO_ANCHORING, url, &url->pattern.tag_regex); + } + + url->flags |= PATTERN_SPEC_URL_PATTERN; /* If it isn't a tag pattern it must be an URL pattern. */ return compile_url_pattern(url, buf); @@ -1250,9 +1268,9 @@ static int path_matches(const char *path, const struct pattern_spec *pattern) int url_match(const struct pattern_spec *pattern, const struct http_request *http) { - if (pattern->pattern.tag_regex != NULL) + if (!(pattern->flags & PATTERN_SPEC_URL_PATTERN)) { - /* It's a tag pattern and shouldn't be matched against URLs */ + /* It's not an URL pattern and thus shouldn't be matched against URLs */ return 0; }