From 9c0c3d5ced559cb723247a54475fa59b403560b0 Mon Sep 17 00:00:00 2001 From: Mukund Sivaraman Date: Fri, 8 Jan 2010 22:05:17 +0530 Subject: [BB#17] Add custom HTTP request headers to outgoing HTTP requests --- docs/man5/tinyproxy.conf.txt.in | 11 ++++++++++ etc/tinyproxy.conf.in | 7 +++++++ src/conf.c | 46 ++++++++++++++++++++++++++++++++++++++++- src/conf.h | 13 ++++++++++++ src/reqs.c | 14 +++++++++++++ 5 files changed, 90 insertions(+), 1 deletion(-) diff --git a/docs/man5/tinyproxy.conf.txt.in b/docs/man5/tinyproxy.conf.txt.in index 4ce494b..2364944 100644 --- a/docs/man5/tinyproxy.conf.txt.in +++ b/docs/man5/tinyproxy.conf.txt.in @@ -219,6 +219,17 @@ The possible keywords and their descriptions are as follows: like `host.example.com` or a domain name like `.example.com` or even a top level domain name like `.com`. +*AddHeader*:: + + Configure one or more HTTP request headers to be added to outgoing + HTTP requests that Tinyproxy makes. Note that this option will not + work for HTTPS traffic, as Tinyproxy has no control over what + headers are exchanged. + + +---- +AddHeader "X-My-Header" "Powered by Tinyproxy" +---- + *ViaProxyName*:: RFC 2616 requires proxies to add a `Via` header to the HTTP diff --git a/etc/tinyproxy.conf.in b/etc/tinyproxy.conf.in index 04bcd4a..08f10bf 100644 --- a/etc/tinyproxy.conf.in +++ b/etc/tinyproxy.conf.in @@ -209,6 +209,13 @@ MaxRequestsPerChild 0 # Allow 127.0.0.1 +# +# AddHeader: Adds the specified headers to outgoing HTTP requests that +# Tinyproxy makes. Note that this option will not work for HTTPS +# traffic, as Tinyproxy has no control over what headers are exchanged. +# +#AddHeader "X-My-Header" "Powered by Tinyproxy" + # # ViaProxyName: The "Via" header is required by the HTTP RFC, but using # the real host name is a security concern. If the following directive diff --git a/src/conf.c b/src/conf.c index d2b4df4..786a5b8 100644 --- a/src/conf.c +++ b/src/conf.c @@ -123,6 +123,7 @@ static HANDLE_FUNC (handle_connectport); static HANDLE_FUNC (handle_defaulterrorfile); static HANDLE_FUNC (handle_deny); static HANDLE_FUNC (handle_errorfile); +static HANDLE_FUNC (handle_addheader); #ifdef FILTER_ENABLE static HANDLE_FUNC (handle_filter); static HANDLE_FUNC (handle_filtercasesensitive); @@ -226,8 +227,10 @@ struct { STDCONF ("deny", "(" "(" IPMASK "|" IPV6MASK ")" "|" ALNUM ")", handle_deny), STDCONF ("bind", "(" IP "|" IPV6 ")", handle_bind), - /* error files */ + /* other */ STDCONF ("errorfile", INT WS STR, handle_errorfile), + STDCONF ("addheader", STR WS STR, handle_addheader), + #ifdef FILTER_ENABLE /* filtering */ STDCONF ("filter", STR, handle_filter), @@ -260,6 +263,22 @@ struct { const unsigned int ndirectives = sizeof (directives) / sizeof (directives[0]); +static void +free_added_headers (vector_t add_headers) +{ + ssize_t i; + + for (i = 0; i < vector_length (add_headers); i++) { + http_header_t *header = (http_header_t *) + vector_getentry (add_headers, i, NULL); + + safefree (header->name); + safefree (header->value); + } + + vector_delete (add_headers); +} + static void free_config (struct config_s *conf) { safefree (conf->config_file); @@ -282,6 +301,7 @@ static void free_config (struct config_s *conf) safefree (conf->bind_address); safefree (conf->via_proxy_name); hashmap_delete (conf->errorpages); + free_added_headers (conf->add_headers); safefree (conf->errorpage_undef); safefree (conf->statpage); flush_access_list (conf->access_list); @@ -848,6 +868,30 @@ static HANDLE_FUNC (handle_errorfile) return 0; } +static HANDLE_FUNC (handle_addheader) +{ + char *name = get_string_arg (line, &match[2]); + char *value = get_string_arg (line, &match[3]); + http_header_t *header; + + if (!conf->add_headers) { + conf->add_headers = vector_create (); + } + + header = (http_header_t *) safemalloc (sizeof (http_header_t)); + header->name = name; + header->value = value; + + vector_prepend (conf->add_headers, header, sizeof *header); + + safefree (header); + + /* Don't free name or value here, as they are referenced in the + * struct inserted into the vector. */ + + return 0; +} + /* * Log level's strings. */ diff --git a/src/conf.h b/src/conf.h index d914b32..fbb4748 100644 --- a/src/conf.h +++ b/src/conf.h @@ -25,6 +25,14 @@ #include "hashmap.h" #include "vector.h" +/* + * Stores a HTTP header created using the AddHeader directive. + */ +typedef struct { + char *name; + char *value; +} http_header_t; + /* * Hold all the configuration time information. */ @@ -97,6 +105,11 @@ struct config_s { * anonymous feature is turned on. */ hashmap_t anonymous_map; + + /* + * Extra headers to be added to outgoing HTTP requests. + */ + vector_t add_headers; }; extern int reload_config_file (const char *config_fname, struct config_s *conf, diff --git a/src/reqs.c b/src/reqs.c index 2f6b67e..a2df786 100644 --- a/src/reqs.c +++ b/src/reqs.c @@ -1327,6 +1327,7 @@ connect_to_upstream (struct conn_s *connptr, struct request_s *request) */ void handle_connection (int fd) { + ssize_t i; struct conn_s *connptr; struct request_s *request = NULL; hashmap_t hashofheaders = NULL; @@ -1407,6 +1408,19 @@ void handle_connection (int fd) return; } + /* + * Add any user-specified headers (AddHeader directive) to the + * outgoing HTTP request. + */ + for (i = 0; i < vector_length (config.add_headers); i++) { + http_header_t *header = (http_header_t *) + vector_getentry (config.add_headers, i, NULL); + + hashmap_insert (hashofheaders, + header->name, + header->value, strlen (header->value) + 1); + } + request = process_request (connptr, hashofheaders); if (!request) { if (!connptr->error_variables && !connptr->show_stats) { -- cgit v1.2.3