From 9fd58c0d3a56323ce94837f217e6609e9c7b2402 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Wed, 21 Aug 2019 17:14:43 +0000 Subject: [PATCH] Add "Cross-origin resource sharing" (CORS) support MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This allows to access Privoxy's CGI interface via JavaScript from another domain (white-listed with the new cors-allowed-origin directive). Based on a patch by Nedžad Hrnjica. Sponsored by: Robert Klemme. --- cgi.c | 12 ++++++++++++ loadcfg.c | 14 ++++++++++++++ project.h | 3 +++ 3 files changed, 29 insertions(+) diff --git a/cgi.c b/cgi.c index 22601760..c67aed4b 100644 --- a/cgi.c +++ b/cgi.c @@ -1585,6 +1585,18 @@ struct http_response *finish_http_response(struct client_state *csp, struct http return rsp; } + /* + * Add "Cross-origin resource sharing" (CORS) headers if enabled + */ + if (NULL != csp->config->cors_allowed_origin) + { + enlist_unique_header(rsp->headers, "Access-Control-Allow-Origin", + strdup_or_die(csp->config->cors_allowed_origin)); + enlist_unique_header(rsp->headers, "Access-Control-Allow-Methods", "GET,POST"); + enlist_unique_header(rsp->headers, "Access-Control-Allow-Headers", "X-Requested-With"); + enlist_unique_header(rsp->headers, "Access-Control-Max-Age", "86400"); + } + /* * Fill in the HTTP Status, using HTTP/1.1 * unless the client asked for HTTP/1.0. diff --git a/loadcfg.c b/loadcfg.c index eac9206a..88379eb5 100644 --- a/loadcfg.c +++ b/loadcfg.c @@ -141,6 +141,7 @@ static struct file_list *current_configfile = NULL; #define hash_compression_level 2464423563U /* "compression-level" */ #define hash_confdir 1978389U /* "confdir" */ #define hash_connection_sharing 1348841265U /* "connection-sharing" */ +#define hash_cors_allowed_origin 2769345637U /* "cors-allowed-origin" */ #define hash_debug 78263U /* "debug" */ #define hash_default_server_timeout 2530089913U /* "default-server-timeout" */ #define hash_deny_access 1227333715U /* "deny-access" */ @@ -647,6 +648,7 @@ struct configuration_spec * load_config(void) config->compression_level = 1; #endif config->feature_flags &= ~RUNTIME_FEATURE_TOLERATE_PIPELINING; + config->cors_allowed_origin = NULL; configfp = fopen(configfile, "r"); if (NULL == configfp) @@ -881,6 +883,18 @@ struct configuration_spec * load_config(void) break; #endif +/* ************************************************************************* + * cors-allowed-origin http://www.example.org + * *************************************************************************/ + case hash_cors_allowed_origin : + /* + * We don't validate the specified referrer as + * it's only used for string comparison. + */ + freez(config->cors_allowed_origin); + config->cors_allowed_origin = strdup_or_die(arg); + break; + /* ************************************************************************* * debug n * Specifies debug level, multiple values are ORed together. diff --git a/project.h b/project.h index 779c5c71..78d53ce3 100644 --- a/project.h +++ b/project.h @@ -1303,6 +1303,9 @@ struct configuration_spec /** The directory for customized CGI templates. */ const char *templdir; + /** "Cross-origin resource sharing" (CORS) allowed origin */ + const char *cors_allowed_origin; + #ifdef FEATURE_EXTERNAL_FILTERS /** The template used to create temporary files. */ const char *temporary_directory; -- 2.39.2