From: Fabian Keil Date: Mon, 14 Aug 2006 08:25:19 +0000 (+0000) Subject: Split filter-headers{} into filter-client-headers{} X-Git-Tag: v_3_0_5~170 X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=commitdiff_plain;h=06f4c2c07f6f1043d6a6c25a1405aa042c92157b Split filter-headers{} into filter-client-headers{} and filter-server-headers{}. Added parse_header_time() to share some code. Replaced timegm() with mktime(). --- diff --git a/actionlist.h b/actionlist.h index d8dddd6c..d37566b3 100644 --- a/actionlist.h +++ b/actionlist.h @@ -39,6 +39,9 @@ * * Revisions : * $Log: actionlist.h,v $ + * Revision 1.20 2006/08/03 02:46:41 david__schmidt + * Incorporate Fabian Keil's patch work: http://www.fabiankeil.de/sourcecode/privoxy/ + * * Revision 1.19 2006/07/18 14:48:45 david__schmidt * Reorganizing the repository: swapping out what was HEAD (the old 3.1 branch) * with what was really the latest development (the v_3_0_branch branch) @@ -139,7 +142,8 @@ DEFINE_ACTION_BOOL ("hide-forwarded-for-headers", ACTION_HIDE_FORWARDED) 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_BOOL ("filter-headers", ACTION_FILTER_HEADERS) +DEFINE_ACTION_BOOL ("filter-client-headers", ACTION_FILTER_CLIENT_HEADERS) +DEFINE_ACTION_BOOL ("filter-server-headers", ACTION_FILTER_SERVER_HEADERS) 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) diff --git a/parsers.c b/parsers.c index da4f3173..63c9e3de 100644 --- a/parsers.c +++ b/parsers.c @@ -1,4 +1,4 @@ -const char parsers_rcs[] = "$Id: parsers.c,v 1.59 2006/08/03 02:46:41 david__schmidt Exp $"; +const char parsers_rcs[] = "$Id: parsers.c,v 1.60 2006/08/12 03:54:37 david__schmidt Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/parsers.c,v $ @@ -40,6 +40,9 @@ const char parsers_rcs[] = "$Id: parsers.c,v 1.59 2006/08/03 02:46:41 david__sch * * Revisions : * $Log: parsers.c,v $ + * Revision 1.60 2006/08/12 03:54:37 david__schmidt + * Windows service integration + * * Revision 1.59 2006/08/03 02:46:41 david__schmidt * Incorporate Fabian Keil's patch work: http://www.fabiankeil.de/sourcecode/privoxy/ * @@ -473,6 +476,10 @@ const char parsers_rcs[] = "$Id: parsers.c,v 1.59 2006/08/03 02:46:41 david__sch #include "miscutil.h" #include "list.h" +#ifndef HAVE_STRPTIME +#include "strptime.c" +#endif + const char parsers_h_rcs[] = PARSERS_H_VERSION; /* Fix a problem with Solaris. There should be no effect on other @@ -508,7 +515,7 @@ const struct parsers client_patterns[] = { { "if-none-match:", 14, client_if_none_match }, { "X-Filter:", 9, client_x_filter }, { "*", 0, crunch_client_header }, - { "*", 0, filter_header }, + { "*", 0, filter_client_header }, { NULL, 0, NULL } }; @@ -525,7 +532,7 @@ const struct parsers server_patterns[] = { { "content-disposition:", 20, server_content_disposition }, { "Last-Modified:", 14, server_last_modified }, { "*", 0, crunch_server_header }, - { "*", 0, filter_header }, + { "*", 0, filter_server_header }, { NULL, 0, NULL } }; @@ -868,6 +875,57 @@ char *sed(const struct parsers pats[], /* here begins the family of parser functions that reformat header lines */ +/********************************************************************* + * + * Function : filter_server_header + * + * Description : Checks if server header filtering is enabled. + * If it is, filter_header is called to do the work. + * + * 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 filter_server_header(struct client_state *csp, char **header) +{ + if (csp->action->flags & ACTION_FILTER_SERVER_HEADERS) + { + filter_header(csp, header); + } + return(JB_ERR_OK); +} + +/********************************************************************* + * + * Function : filter_client_header + * + * Description : Checks if client header filtering is enabled. + * If it is, filter_header is called to do the work. + * + * 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 filter_client_header(struct client_state *csp, char **header) +{ + if (csp->action->flags & ACTION_FILTER_CLIENT_HEADERS) + { + filter_header(csp, header); + } + return(JB_ERR_OK); +} /********************************************************************* * @@ -910,10 +968,6 @@ jb_err filter_header(struct client_state *csp, char **header) # define INDEX_OR_NOT [i] #endif - if (!(csp->action->flags & ACTION_FILTER_HEADERS)) - { - return(JB_ERR_OK); - } log_error(LOG_LEVEL_RE_FILTER, "Entered filter_headers"); /* * Need to check the set of re_filterfiles... @@ -1407,7 +1461,7 @@ jb_err server_last_modified(struct client_state *csp, char **header) char buf[BUFFER_SIZE]; char newheader[50]; - struct tm *timeptr; + struct tm *timeptr = NULL; time_t now, last_modified; long int rtime; long int days, hours, minutes, seconds; @@ -1456,14 +1510,13 @@ jb_err server_last_modified(struct client_state *csp, char **header) log_error(LOG_LEVEL_HEADER, "Randomizing: %s", *header); now = time(NULL); timeptr = gmtime(&now); - if (strptime(*header, "Last-Modified: %a, %d %b %Y %T", timeptr) == NULL) + if ( (last_modified = parse_header_time(*header, timeptr)) < 0 ) { log_error(LOG_LEVEL_HEADER, "Couldn't parse: %s (crunching!)", *header); freez(*header); } else { - last_modified = timegm(timeptr); rtime = difftime(now, last_modified); if (rtime) { @@ -1473,8 +1526,8 @@ jb_err server_last_modified(struct client_state *csp, char **header) rtime = rand() % rtime + 1; #endif /* (ifndef _WIN32 || __OS2__) */ last_modified += rtime; - timeptr = gmtime(&last_modified); - strftime(newheader, sizeof(newheader), "%a, %d %b %Y %T GMT", timeptr); + timeptr = localtime(&last_modified); + strftime(newheader, sizeof(newheader), "%a, %d %b %Y %H:%M:%S GMT", timeptr); freez(*header); *header = strdup("Last-Modified: "); string_append(header, newheader); @@ -2154,7 +2207,7 @@ jb_err client_host(struct client_state *csp, char **header) jb_err client_if_modified_since(struct client_state *csp, char **header) { char newheader[50]; - struct tm *timeptr; + struct tm *timeptr = NULL; time_t tm = 0; const char *newval; time_t rtime; @@ -2185,35 +2238,37 @@ jb_err client_if_modified_since(struct client_state *csp, char **header) } else /* add random value */ { - /* - * tm must be initinalized to prevent segmentation faults. - */ - timeptr = gmtime(&tm); - if (strptime(*header, "If-Modified-Since: %a, %d %b %Y %T", timeptr) == NULL) + if ( (tm = parse_header_time(*header, timeptr)) < 0 ) { log_error(LOG_LEVEL_HEADER, "Couldn't parse: %s (crunching!)", *header); freez(*header); } else { - rtime = strtol(newval, &endptr, 0); - - log_error(LOG_LEVEL_HEADER, "Randomizing: %s (random range: %d hou%s)", - *header, rtime, (rtime == 1 || rtime == -1) ? "r": "rs"); - - rtime *= 3600; + rtime = (time_t) strtol(newval, &endptr, 0); + if(rtime) + { + log_error(LOG_LEVEL_HEADER, "Randomizing: %s (random range: %d hou%s)", + *header, rtime, (rtime == 1 || rtime == -1) ? "r": "rs"); + rtime *= 3600; #if !defined(_WIN32) && !defined(__OS2__) - rtime = random() % rtime; + rtime = random() % rtime + 1; #else - rtime = rand() % rtime; + rtime = rand() % rtime + 1; #endif /* (_WIN32 || __OS2__) */ - if(newval[0] == '-') + if(newval[0] == '-') + { + rtime *= -1; + } + } + else { - rtime *= -1; + log_error(LOG_LEVEL_ERROR, "Random range is 0. Assuming time transformation test.", + *header); } - tm = timegm(timeptr) + rtime; - timeptr = gmtime(&tm); - strftime(newheader, sizeof(newheader), "%a, %d %b %Y %T GMT", timeptr); + tm += rtime; + timeptr = localtime(&tm); + strftime(newheader, sizeof(newheader), "%a, %d %b %Y %H:%M:%S GMT", timeptr); freez(*header); *header = strdup("If-Modified-Since: "); @@ -2759,6 +2814,37 @@ int strclean(const char *string, const char *substring) } #endif /* def FEATURE_FORCE_LOAD */ +/********************************************************************* + * + * Function : parse_header_time + * + * Description : Transforms time inside a HTTP header into + * the usual time format. + * + * Parameters : + * 1 : header = header to parse + * 2 : timeptr = storage for the resulting time structure + * + * Returns : Time in seconds since Unix epoch or -1 for failure. + * + *********************************************************************/ +time_t parse_header_time(char *header, struct tm *timeptr) { + + char * timestring; + time_t tm; + + tm = time(NULL); + timeptr = localtime(&tm); + /* Skipping header name */ + timestring = strstr(header, ": "); + if (strptime(timestring, ": %a, %d %b %Y %H:%M:%S", timeptr) == NULL) + { + return(-1); + } + tm = mktime(timeptr); + return(tm); +} + /* Local Variables: diff --git a/parsers.h b/parsers.h index 74f60e6b..c562c941 100644 --- a/parsers.h +++ b/parsers.h @@ -1,6 +1,6 @@ #ifndef PARSERS_H_INCLUDED #define PARSERS_H_INCLUDED -#define PARSERS_H_VERSION "$Id: parsers.h,v 1.28 2006/07/18 14:48:47 david__schmidt Exp $" +#define PARSERS_H_VERSION "$Id: parsers.h,v 1.29 2006/08/03 02:46:41 david__schmidt Exp $" /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/parsers.h,v $ @@ -43,6 +43,9 @@ * * Revisions : * $Log: parsers.h,v $ + * Revision 1.29 2006/08/03 02:46:41 david__schmidt + * Incorporate Fabian Keil's patch work: http://www.fabiankeil.de/sourcecode/privoxy/ + * * Revision 1.28 2006/07/18 14:48:47 david__schmidt * Reorganizing the repository: swapping out what was HEAD (the old 3.1 branch) * with what was really the latest development (the v_3_0_branch branch) @@ -203,6 +206,7 @@ extern char *get_header(struct client_state *csp); extern char *get_header_value(const struct list *header_list, const char *header_name); extern char *sed(const struct parsers pats[], const add_header_func_ptr more_headers[], struct client_state *csp); extern void get_http_time(int time_offset, char *buf); +time_t parse_header_time(char *header, struct tm *timeptr); extern jb_err crumble (struct client_state *csp, char **header); extern jb_err client_referrer (struct client_state *csp, char **header); @@ -220,6 +224,8 @@ 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 filter_header (struct client_state *csp, char **header); +extern jb_err filter_client_header (struct client_state *csp, char **header); +extern jb_err filter_server_header (struct client_state *csp, char **header); extern jb_err client_x_filter (struct client_state *csp, char **header); diff --git a/project.h b/project.h index aaaeed2b..73e0a75a 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.74 2006/07/18 14:48:47 david__schmidt Exp $" +#define PROJECT_H_VERSION "$Id: project.h,v 1.75 2006/08/03 02:46:41 david__schmidt Exp $" /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/project.h,v $ @@ -37,6 +37,9 @@ * * Revisions : * $Log: project.h,v $ + * Revision 1.75 2006/08/03 02:46:41 david__schmidt + * Incorporate Fabian Keil's patch work: http://www.fabiankeil.de/sourcecode/privoxy/ + * * Revision 1.74 2006/07/18 14:48:47 david__schmidt * Reorganizing the repository: swapping out what was HEAD (the old 3.1 branch) * with what was really the latest development (the v_3_0_branch branch) @@ -945,8 +948,10 @@ struct iob #define ACTION_REDIRECT 0x10000000UL /** Action bitmap: Answer blocked Connects verbosely */ #define ACTION_TREAT_FORBIDDEN_CONNECTS_LIKE_BLOCKS 0x20000000UL -/** Action bitmap: Filter headers with pcre */ -#define ACTION_FILTER_HEADERS 0x40000000UL +/** Action bitmap: Filter server headers with pcre */ +#define ACTION_FILTER_SERVER_HEADERS 0x40000000UL +/** Action bitmap: Filter client headers with pcre */ +#define ACTION_FILTER_CLIENT_HEADERS 0x80000000UL /*To make the ugly hack in sed easier to understand*/