Merge branch 'master' of ssh://git.privoxy.org:23/git/privoxy
authorLee <ler762@users.sourceforge.net>
Tue, 2 Jun 2020 04:35:17 +0000 (00:35 -0400)
committerLee <ler762@users.sourceforge.net>
Tue, 2 Jun 2020 04:35:17 +0000 (00:35 -0400)
61 files changed:
AUTHORS
TODO
cgi.c
cgi.h
cgiedit.c
cgisimple.c
cgisimple.h
config
deanimate.c
debian/changelog
debian/compat [deleted file]
debian/control
debian/copyright
debian/patches/05_defaut_action.patch
debian/privoxy.service
debian/salsa-ci.yml [moved from debian/gitlab-ci.yml with 100% similarity]
debian/tests/control
debian/upstream/metadata [new file with mode: 0644]
debian/watch
default.action.master
default.filter
doc/source/copyright.sgml
doc/source/developer-manual.sgml
doc/source/faq.sgml
doc/source/p-authors.sgml
doc/source/p-config.sgml
doc/source/privoxy-man-page.sgml
doc/source/user-manual.sgml
doc/webserver/developer-manual/newrelease.html
doc/webserver/faq/copyright.html
doc/webserver/faq/trouble.html
doc/webserver/sponsors/index.html
doc/webserver/user-manual/actions-file.html
doc/webserver/user-manual/appendix.html
doc/webserver/user-manual/config.html
doc/webserver/user-manual/copyright.html
errlog.c
errlog.h
filters.c
fuzz.c
gateway.c
jbsockets.c
jcc.c
list.c
loadcfg.c
loaders.c
match-all.action
parsers.c
project.h
regression-tests.action
ssl.c
ssl.h
strptime.h
templates/edit-actions-for-url
templates/show-url-info
tools/privoxy-log-parser.pl
tools/privoxy-regression-test.pl
urlmatch.c
w32log.c
w32log.h
win32.c

diff --git a/AUTHORS b/AUTHORS
index e9ff3ef..e7048df 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -120,6 +120,7 @@ include (in alphabetical order):
  Amuro Namie
  Mark Nelson
  Tobias Netzel
+ John Palkovic
  Adam Piggott
  Petr PĂ­sar
  Dan Price
diff --git a/TODO b/TODO
index d658185..ed96b7e 100644 (file)
--- a/TODO
+++ b/TODO
@@ -51,17 +51,6 @@ https://www.privoxy.org/faq/general.html#DONATE
 
 14) Allow to filter POST parameters.
 
-16) Filter SSL encrypted content as well.
-
-    At the beginning we could use a unencrypted connection between
-    client and Privoxy, and use an encrypted connection between
-    Privoxy and the server.
-
-    This should be good enough for most of the content the
-    user would want to filter.
-
-    Interested donors: 2.
-
 19) enable-forward-fallback. Syntax? Suggested by K.R.
 
 21) User Manual delivery doesn't accept multiple slashes. Should it?
@@ -136,10 +125,6 @@ https://www.privoxy.org/faq/general.html#DONATE
 
     Interested donors: 1.
 
-54) Move away from CVS to a more modern revision control system.
-    The move to git is work in progress:
-    https://sourceforge.net/p/ijbswa/mailman/message/34994343/
-
 58) Move more template strings from the code into the actual templates.
 
 59) Import the German template translation.
@@ -259,7 +244,7 @@ https://www.privoxy.org/faq/general.html#DONATE
     go through all filters and skip the filter types the caller isn't
     interested in.
 
-98) When showing action section on the CGI pages, properly escape
+98) When showing action sections on the CGI pages, properly escape
     line breaks so they can be copy&pasted into action files without
     adjustments.
 
@@ -341,9 +326,6 @@ https://www.privoxy.org/faq/general.html#DONATE
 
 122) Allow customized log messages.
 
-123) Evaluate if the voluntarily-disclose-session-keys option in Firefox
-     (and other browsers) can be leveraged. Probably depends on #16.
-
 124) Add support for the "lightweight OS capability and sandbox framework"
      Capsicum. http://www.cl.cam.ac.uk/research/security/capsicum/
      Interested donors: 1.
@@ -460,6 +442,9 @@ https://www.privoxy.org/faq/general.html#DONATE
      performance point of view, using a single thread should reduce Privoxy's
      memory footprint a bit which may be noticeable in case of multi-user setups
      with hundreds of idle connections.
+
+159) Support Brotli compression.
+
 ##########################################################################
 
 Hosting wish list (relevant for #53)
diff --git a/cgi.c b/cgi.c
index ec86b64..b9f8194 100644 (file)
--- a/cgi.c
+++ b/cgi.c
@@ -3,11 +3,11 @@
  * File        :  $Source: /cvsroot/ijbswa/current/cgi.c,v $
  *
  * Purpose     :  Declares functions to intercept request, generate
- *                html or gif answers, and to compose HTTP resonses.
+ *                html or gif answers, and to compose HTTP responses.
  *                This only contains the framework functions, the
  *                actual handler functions are declared elsewhere.
  *
- * Copyright   :  Written by and Copyright (C) 2001-2017
+ * Copyright   :  Written by and Copyright (C) 2001-2020
  *                members of the Privoxy team. https://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
 #if defined(FEATURE_CGI_EDIT_ACTIONS) || defined(FEATURE_TOGGLE)
 #include "cgiedit.h"
 #endif /* defined(FEATURE_CGI_EDIT_ACTIONS) || defined (FEATURE_TOGGLE) */
+#ifdef FEATURE_HTTPS_INSPECTION
+#include "ssl.h"
+#endif
 
 /* loadcfg.h is for global_toggle_state only */
 #include "loadcfg.h"
 /* jcc.h is for mutex semaphore globals only */
 #include "jcc.h"
 
+static char *make_menu(const struct client_state *csp, const char *self);
+
 /*
  * List of CGI functions: name, handler, description
  * Note: Do NOT use single quotes in the description;
@@ -244,7 +249,7 @@ const char image_pattern_data[] =
    "\000\000\000\000\111\105\116\104\256\102\140\202";
 
 /*
- * 1x1 transparant PNG.
+ * 1x1 transparent PNG.
  */
 const char image_blank_data[] =
  "\211\120\116\107\015\012\032\012\000\000\000\015\111\110\104\122"
@@ -267,7 +272,7 @@ const char image_pattern_data[] =
    "\270\005\000\073";
 
 /*
- * 1x1 transparant GIF.
+ * 1x1 transparent GIF.
  */
 const char image_blank_data[] =
    "GIF89a\001\000\001\000\200\000\000\377\377\377\000\000"
@@ -401,8 +406,13 @@ struct http_response *dispatch_cgi(struct client_state *csp)
 static char *grep_cgi_referrer(const struct client_state *csp)
 {
    struct list_entry *p;
+   struct list_entry *first_header =
+#ifdef FEATURE_HTTPS_INSPECTION
+      client_use_ssl(csp) ? csp->https_headers->first :
+#endif
+      csp->headers->first;
 
-   for (p = csp->headers->first; p != NULL; p = p->next)
+   for (p = first_header; p != NULL; p = p->next)
    {
       if (p->str == NULL) continue;
       if (strncmpic(p->str, "Referer: ", 9) == 0)
@@ -434,6 +444,7 @@ static int referrer_is_safe(const struct client_state *csp)
 {
    char *referrer;
    static const char alternative_prefix[] = "http://" CGI_SITE_1_HOST "/";
+   static const char alt_prefix_https[] = "https://" CGI_SITE_1_HOST "/";
    const char *trusted_cgi_referrer = csp->config->trusted_cgi_referrer;
 
    referrer = grep_cgi_referrer(csp);
@@ -444,8 +455,12 @@ static int referrer_is_safe(const struct client_state *csp)
       log_error(LOG_LEVEL_ERROR, "Denying access to %s. No referrer found.",
          csp->http->url);
    }
-   else if ((0 == strncmp(referrer, CGI_PREFIX, sizeof(CGI_PREFIX)-1)
-         || (0 == strncmp(referrer, alternative_prefix, strlen(alternative_prefix)))))
+   else if ((0 == strncmp(referrer, CGI_PREFIX, sizeof(CGI_PREFIX)-1))
+#ifdef FEATURE_HTTPS_INSPECTION
+         || (0 == strncmp(referrer, CGI_PREFIX_HTTPS, sizeof(CGI_PREFIX_HTTPS)-1))
+         || (0 == strncmp(referrer, alt_prefix_https, strlen(alt_prefix_https)))
+#endif
+         || (0 == strncmp(referrer, alternative_prefix, strlen(alternative_prefix))))
    {
       /* Trustworthy referrer */
       log_error(LOG_LEVEL_CGI, "Granting access to %s, referrer %s is trustworthy.",
@@ -735,22 +750,22 @@ char get_char_param(const struct map *parameters,
  *
  * Function    :  get_string_param
  *
- * Description :  Get a string paramater, to be used as an
- *                ACTION_STRING or ACTION_MULTI paramater.
+ * Description :  Get a string parameter, to be used as an
+ *                ACTION_STRING or ACTION_MULTI parameter.
  *                Validates the input to prevent stupid/malicious
  *                users from corrupting their action file.
  *
  * Parameters  :
  *          1  :  parameters = map of cgi parameters
  *          2  :  param_name = The name of the parameter to read
- *          3  :  pparam = destination for paramater.  Allocated as
+ *          3  :  pparam = destination for parameter.  Allocated as
  *                part of the map "parameters", so don't free it.
  *                Set to NULL if not specified.
  *
- * Returns     :  JB_ERR_OK         on success, or if the paramater
+ * Returns     :  JB_ERR_OK         on success, or if the parameter
  *                                  was not specified.
  *                JB_ERR_MEMORY     on out-of-memory.
- *                JB_ERR_CGI_PARAMS if the paramater is not valid.
+ *                JB_ERR_CGI_PARAMS if the parameter is not valid.
  *
  *********************************************************************/
 jb_err get_string_param(const struct map *parameters,
@@ -1225,7 +1240,7 @@ jb_err cgi_error_no_template(const struct client_state *csp,
  *                In this context, "unexpected" means "anything other
  *                than JB_ERR_MEMORY or JB_ERR_CGI_PARAMS" - CGIs are
  *                expected to handle all other errors internally,
- *                since they can give more relavent error messages
+ *                since they can give more relevant error messages
  *                that way.
  *
  *                Note this is not a true CGI, it takes an error
@@ -1605,7 +1620,7 @@ struct http_response *finish_http_response(struct client_state *csp, struct http
     * unless the client asked for HTTP/1.0.
     */
    snprintf(buf, sizeof(buf), "%s %s",
-      strcmpic(csp->http->ver, "HTTP/1.0") ? "HTTP/1.1" : "HTTP/1.0",
+      strcmpic(csp->http->version, "HTTP/1.0") ? "HTTP/1.1" : "HTTP/1.0",
       rsp->status ? rsp->status : "200 OK");
    err = enlist_first(rsp->headers, buf);
 
@@ -2194,8 +2209,15 @@ struct map *default_exports(const struct client_state *csp, const char *caller)
    if (!err) err = map(exports, "my-hostname",   1, html_encode(hostname ? hostname : "unknown"), 0);
    freez(hostname);
    if (!err) err = map(exports, "homepage",      1, html_encode(HOME_PAGE_URL), 0);
-   if (!err) err = map(exports, "default-cgi",   1, html_encode(CGI_PREFIX), 0);
-   if (!err) err = map(exports, "menu",          1, make_menu(caller, csp->config->feature_flags), 0);
+   if (!err)
+   {
+      err = map(exports, "default-cgi",   1, html_encode(
+#ifdef FEATURE_HTTPS_INSPECTION
+        client_use_ssl(csp) ? CGI_PREFIX_HTTPS :
+#endif
+        CGI_PREFIX), 0);
+   }
+   if (!err) err = map(exports, "menu",          1, make_menu(csp, caller), 0);
    if (!err) err = map(exports, "code-status",   1, CODE_STATUS, 1);
    if (!strncmpic(csp->config->usermanual, "file://", 7) ||
        !strncmpic(csp->config->usermanual, "http", 4))
@@ -2206,7 +2228,14 @@ struct map *default_exports(const struct client_state *csp, const char *caller)
    else
    {
       /* Manual is delivered by Privoxy. */
-      if (!err) err = map(exports, "user-manual", 1, html_encode(CGI_PREFIX"user-manual/"), 0);
+      if (!err)
+      {
+         err = map(exports, "user-manual", 1, html_encode(
+#ifdef FEATURE_HTTPS_INSPECTION
+           client_use_ssl(csp) ? CGI_PREFIX_HTTPS"user-manual/" :
+#endif
+           CGI_PREFIX"user-manual/"), 0);
+      }
    }
    if (!err) err = map(exports, "actions-help-prefix", 1, ACTIONS_HELP_PREFIX ,1);
 #ifdef FEATURE_TOGGLE
@@ -2383,15 +2412,14 @@ jb_err map_conditional(struct map *exports, const char *name, int choose_first)
  *                and the toggle CGI if toggling is disabled.
  *
  * Parameters  :
- *          1  :  self = name of CGI to leave out, can be NULL for
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  self = name of CGI to leave out, can be NULL for
  *                complete listing.
- *          2  :  feature_flags = feature bitmap from csp->config
- *
  *
  * Returns     :  menu string, or NULL on out-of-memory error.
  *
  *********************************************************************/
-char *make_menu(const char *self, const unsigned feature_flags)
+char *make_menu(const struct client_state *csp, const char *self)
 {
    const struct cgi_dispatcher *d;
    char *result = strdup("");
@@ -2406,7 +2434,7 @@ char *make_menu(const char *self, const unsigned feature_flags)
    {
 
 #ifdef FEATURE_TOGGLE
-      if (!(feature_flags & RUNTIME_FEATURE_CGI_TOGGLE) && !strcmp(d->name, "toggle"))
+      if (!(csp->config->feature_flags & RUNTIME_FEATURE_CGI_TOGGLE) && !strcmp(d->name, "toggle"))
       {
          /*
           * Suppress the toggle link if remote toggling is disabled.
@@ -2424,7 +2452,11 @@ char *make_menu(const char *self, const unsigned feature_flags)
           * the "blocked" template's JavaScript.
           */
          string_append(&result, "<li><a href=\"");
-         html_encoded_prefix = html_encode(CGI_PREFIX);
+         html_encoded_prefix = html_encode(
+#ifdef FEATURE_HTTPS_INSPECTION
+            client_use_ssl(csp) ? CGI_PREFIX_HTTPS :
+#endif
+            CGI_PREFIX);
          if (html_encoded_prefix == NULL)
          {
             return NULL;
diff --git a/cgi.h b/cgi.h
index 45b8979..e4a132e 100644 (file)
--- a/cgi.h
+++ b/cgi.h
@@ -5,7 +5,7 @@
  * File        :  $Source: /cvsroot/ijbswa/current/cgi.h,v $
  *
  * Purpose     :  Declares functions to intercept request, generate
- *                html or gif answers, and to compose HTTP resonses.
+ *                html or gif answers, and to compose HTTP responses.
  *
  *                Functions declared include:
  *
@@ -110,7 +110,6 @@ extern char *compress_buffer(char *buffer, size_t *buffer_length, int compressio
  */
 extern void get_http_time(int time_offset, char *buf, size_t buffer_size);
 extern char *add_help_link(const char *item, struct configuration_spec *config);
-extern char *make_menu(const char *self, const unsigned feature_flags);
 extern char *dump_map(const struct map *the_map);
 
 /*
index 830a826..14886d4 100644 (file)
--- a/cgiedit.c
+++ b/cgiedit.c
@@ -1100,7 +1100,7 @@ jb_err edit_parse_actions_file(struct editable_file * file)
 
    /* alias_list contains the aliases defined in this file.
     * It might be better to use the "file_line.data" fields
-    * in the relavent places instead.
+    * in the relevant places instead.
     */
 
    cur_line = file->lines;
@@ -2750,7 +2750,7 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp,
     * browsers (BR #1570678).
     *
     * The config option split-large-forms works around this browser
-    * bug (HTTP has no URL length limitation) by deviding the action
+    * bug (HTTP has no URL length limitation) by dividing the action
     * list form into multiple smaller ones. It means the URLs are shorter
     * and work in broken browsers as well, but the user can no longer change
     * all actions with one submit.
@@ -2782,6 +2782,9 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp,
 #ifndef FEATURE_EXTERNAL_FILTERS
    if (!err) err = map_block_killer(exports, "external-content-filters");
 #endif
+#ifndef FEATURE_HTTP_INSPECTION
+   if (!err) err = map_block_killer(exports, "https-inspection");
+#endif
 
    if (err)
    {
index 0148120..f962fdf 100644 (file)
@@ -1365,7 +1365,7 @@ jb_err cgi_show_url_info(struct client_state *csp,
 
    if (url_param[0] == '\0')
    {
-      /* URL paramater not specified, display query form only. */
+      /* URL parameter not specified, display query form only. */
       free(url_param);
       if (map_block_killer(exports, "url-given")
         || map(exports, "url", 1, "", 1))
@@ -1438,11 +1438,14 @@ jb_err cgi_show_url_info(struct client_state *csp,
       }
 
       /*
-       * We have a warning about SSL paths.  Hide it for unencrypted sites.
+       * We have a warning about SSL paths. Hide it for unencrypted sites
+       * and unconditionally if https inspection is enabled.
        */
+#ifndef FEATURE_HTTPS_INSPECTION
       if (!url_to_query->ssl)
+#endif
       {
-         if (map_block_killer(exports, "https"))
+         if (map_block_killer(exports, "https-and-no-https-inspection"))
          {
             free_current_action(action);
             free_map(exports);
@@ -1714,7 +1717,7 @@ jb_err cgi_robots_txt(struct client_state *csp,
  *
  * Function    :  show_defines
  *
- * Description :  Add to a map the state od all conditional #defines
+ * Description :  Add to a map the state of all conditional #defines
  *                used when building
  *
  * Parameters  :
index e51f6d3..01e6a9e 100644 (file)
@@ -5,7 +5,7 @@
  * File        :  $Source: /cvsroot/ijbswa/current/cgisimple.h,v $
  *
  * Purpose     :  Declares functions to intercept request, generate
- *                html or gif answers, and to compose HTTP resonses.
+ *                html or gif answers, and to compose HTTP responses.
  *
  *                Functions declared include:
  *
diff --git a/config b/config
index df22862..0256c45 100644 (file)
--- a/config
+++ b/config
@@ -567,7 +567,7 @@ logfile logfile
 #
 #      The available debug levels are:
 #
-#        debug     1 # Log the destination for each request Privoxy let through. See also debug 1024.
+#        debug     1 # Log the destination for each request. See also debug 1024.
 #        debug     2 # show each connection status
 #        debug     4 # show I/O status
 #        debug     8 # show header parsing
@@ -609,7 +609,7 @@ logfile logfile
 #      you read the log messages, you may even be able to solve the
 #      problem on your own.
 #
-#debug     1 # Log the destination for each request Privoxy let through. See also debug 1024.
+#debug     1 # Log the destination for each request.
 #debug  1024 # Log the destination for requests Privoxy didn't let through, and the reason why.
 #debug  4096 # Startup banner and warnings
 #debug  8192 # Non-fatal errors
@@ -1000,7 +1000,7 @@ enforce-blocks 0
 #      whole destination part are optional.
 #
 #      If your system implements RFC 3493, then src_addr and dst_addr
-#      can be IPv6 addresses delimeted by brackets, port can be a
+#      can be IPv6 addresses delimited by brackets, port can be a
 #      number or a service name, and src_masklen and dst_masklen can
 #      be a number from 0 to 128.
 #
@@ -1986,13 +1986,13 @@ socket-timeout 300
 #  Notes:
 #
 #      Under high load incoming connection may queue up before
-#      Privoxy gets around to serve them. The queue length is
-#      limitted by the operating system. Once the queue is full,
-#      additional connections are dropped before Privoxy can accept
-#      and serve them.
+#      Privoxy gets around to serve them. The queue length is limited
+#      by the operating system. Once the queue is full, additional
+#      connections are dropped before Privoxy can accept and serve
+#      them.
 #
 #      Increasing the queue length allows Privoxy to accept more
-#      incomming connections that arrive roughly at the same time.
+#      incoming connections that arrive roughly at the same time.
 #
 #      Note that Privoxy can only request a certain queue length,
 #      whether or not the requested length is actually used depends
index 6a80259..bba74d4 100644 (file)
@@ -304,8 +304,8 @@ static int gif_extract_image(struct binbuffer *src, struct binbuffer *dst)
  *                an (optional) image block and an arbitrary number
  *                of image extension blocks, produce an output GIF with
  *                only one image block that contains the last image
- *                (extenstion) block of the original.
- *                Also strip Comments, Application extenstions, etc.
+ *                (extension) block of the original.
+ *                Also strip Comments, Application extensions, etc.
  *
  * Parameters  :
  *          1  :  src = Pointer to the source binbuffer
index a547a9a..0bade0b 100644 (file)
@@ -1,11 +1,25 @@
-privoxy (3.0.29~git6a358e-1) UNRELEASED; urgency=medium
+privoxy (3.0.29~gitec5b42-1) UNRELEASED; urgency=medium
 
   * New upstream developement version.
   * Update all patches to new version.
   * 36_trusted-cgi-referer-example and 37_ppedit-tests403 are now
     incorporated upstream.
+  * d/copyright: use ./ prefix to upstream filenames, because orig.tar.gz
+    is build with a ./ prefix.
 
- -- Roland Rosenfeld <roland@debian.org>  Sat, 30 Nov 2019 12:44:20 +0100
+ -- Roland Rosenfeld <roland@debian.org>  Sat, 04 Apr 2020 14:46:51 +0200
+
+privoxy (3.0.28-3) unstable; urgency=medium
+
+  * Add buildlog to salsa-ci test pipeline.
+  * d/salsa-ci.yml stripped down using pipline-jobs.yml
+  * Build-depend on debhelper-compat (= 12) instead of using d/compat.
+  * Upgrade to Standards-Version 4.5.0 (no changes).
+  * Add upstream metadata.
+  * privoxy.service: run After=network-online.target, this fixes
+    LP#1870101.
+
+ -- Roland Rosenfeld <roland@debian.org>  Thu, 02 Apr 2020 18:04:44 +0200
 
 privoxy (3.0.28-2) unstable; urgency=medium
 
diff --git a/debian/compat b/debian/compat
deleted file mode 100644 (file)
index 48082f7..0000000
+++ /dev/null
@@ -1 +0,0 @@
-12
index c483d5c..b7464f8 100644 (file)
@@ -3,7 +3,7 @@ Section: web
 Priority: optional
 Maintainer: Roland Rosenfeld <roland@debian.org>
 Build-Depends: autoconf,
-               debhelper (>= 12~),
+               debhelper-compat (= 12),
                docbook,
                docbook-dsssl,
                docbook-utils,
@@ -15,7 +15,7 @@ Build-Depends: autoconf,
                sgmlspl,
                w3m,
                zlib1g-dev
-Standards-Version: 4.3.0
+Standards-Version: 4.5.0
 Homepage: https://www.privoxy.org/
 Vcs-Git: https://salsa.debian.org/debian/privoxy.git
 Vcs-Browser: https://salsa.debian.org/debian/privoxy
index 059f519..9c41e3f 100644 (file)
@@ -16,14 +16,14 @@ Comment:
  Junkbusters Corporation.  http://www.junkbusters.com
 License: GPL-2+
 
-Files: regression-tests.action tools/uagen.pl tools/privoxy-regression-test.pl
tools/privoxy-log-parser.pl tools/url-pattern-translator.pl utils/changelog2doc.pl
- utils/create-package-feed.pl
+Files: ./regression-tests.action ./tools/uagen.pl ./tools/privoxy-regression-test.pl
./tools/privoxy-log-parser.pl ./tools/url-pattern-translator.pl ./utils/changelog2doc.pl
./utils/create-package-feed.pl
 Copyright:
  Copyright (c) 2006-2017 Fabian Keil <fk@fabiankeil.de>
 License: ISC
 
-Files: strptime.h
+Files: ./strptime.h
 Copyright:
  Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
 Comment:
@@ -36,7 +36,7 @@ Copyright:
  2002-2018  Roland Rosenfeld <roland@debian.org>
 License: GPL-2+
 
-Files: pcre/*
+Files: ./pcre/*
 Copyright: Copyright (c) 1997-2000 University of Cambridge
 Comment:
  Written by: Philip Hazel <ph10@cam.ac.uk>
index 4e1ab72..4e8911e 100644 (file)
@@ -4,7 +4,7 @@ Subject: Several changes/additons to default.action.
 
 --- a/default.action.master
 +++ b/default.action.master
-@@ -2433,6 +2433,9 @@ schneegans.de/sv/\?url=referer
+@@ -2435,6 +2435,9 @@ schneegans.de/sv/\?url=referer
  #MASTER# REMARKS: Exclude per Debian bug report #377843
  # URL = http://blogs.msdn.com/wga/archive/2006/07/16/667063.aspx
  blogs.msdn.com
@@ -14,7 +14,7 @@ Subject: Several changes/additons to default.action.
  
  {-filter{unsolicited-popups}}
  # Sticky Actions = -filter{unsolicited-popups}
-@@ -2491,6 +2494,11 @@ tr.anp.se/
+@@ -2493,6 +2496,11 @@ tr.anp.se/
  {+filter{tiny-textforms}}
  .sourceforge.net/tracker
  
index 8ad06d3..d8c08ed 100644 (file)
@@ -1,7 +1,7 @@
 [Unit]
 Description=Privacy enhancing HTTP Proxy
 Documentation=man:privoxy(8) https://www.privoxy.org/user-manual/
-After=network.target
+After=network-online.target
 
 [Service]
 Environment=PIDFILE=/run/privoxy.pid
similarity index 100%
rename from debian/gitlab-ci.yml
rename to debian/salsa-ci.yml
index 6968f2a..1566c8f 100644 (file)
@@ -1,2 +1,2 @@
 Tests: privoxy-regression-test
-Depends: @, curl
+Depends: curl, @
diff --git a/debian/upstream/metadata b/debian/upstream/metadata
new file mode 100644 (file)
index 0000000..cd970b6
--- /dev/null
@@ -0,0 +1,10 @@
+Archive: SourceForge
+Bug-Database: https://sourceforge.net/p/ijbswa/bugs/
+Bug-Submit: https://sourceforge.net/p/ijbswa/bugs/new/
+Changelog: https://www.privoxy.org/gitweb/?p=privoxy.git;a=blob_plain;f=ChangeLog
+Documentation: https://www.privoxy.org/user-manual/
+Donation: https://www.privoxy.org/faq/general.html#DONATE
+FAQ: https://www.privoxy.org/faq/
+Repository: https://www.privoxy.org/git/privoxy.git
+Repository-Browse: https://www.privoxy.org/gitweb/?p=privoxy.git
+Security-Contact: Fabian Keil <fk@fabiankeil.de>
index 2687b2e..c204478 100644 (file)
@@ -3,6 +3,6 @@
 # Compulsory line, this is a version 3 file
 version=3
 
-#http://sourceforge.net/project/showfiles.php?group_id=11118 http://prdownloads.sourceforge.net/ijbswa/privoxy-(.*)-stable-src.tar.gz\?download
+#https://sourceforge.net/project/showfiles.php?group_id=11118 https://prdownloads.sourceforge.net/ijbswa/privoxy-(.*)-stable-src.tar.gz\?download
 
 opts=pgpsigurlmangle=s/$/.asc/ https://sf.net/ijbswa/privoxy-(\d+.*)-(?:stable|beta)-src.tar.gz
index 24d62e7..d6f2a9f 100644 (file)
 #                 and enhancements are better placed in user.action,
 #                 the match-all section has been moved to match-all.action.
 #
-#  Copyright   :  Written by and Copyright (C) 2001-2019 the
+#  Copyright   :  Written by and Copyright (C) 2001-2020 the
 #                 Privoxy team. https://www.privoxy.org/
 #
 # Feedback welcome, for details please have a look at:
 # https://www.privoxy.org/user-manual/contact.html
 #
-# The current development version of this file is located:
-# http://ijbswa.cvs.sourceforge.net/viewvc/ijbswa/current/default.action.master
+# The current development version of this file is located at:
+# https://www.privoxy.org/gitweb/?p=privoxy.git;a=blob_plain;f=default.action.master;hb=HEAD
 #
 #############################################################################
 # Syntax
 #    Client-header filters predefined in the supplied default.filter include:
 #
 #     hide-tor-exit-notation: Removes the Tor exit node notation in Host and Referer headers.
+#     no-brotli-accepted:     Strips "br" from the Accept-Encoding header
 #     privoxy-control:        Removes X-Privoxy-Control headers.
 #
 # +client-header-tagger{string}
@@ -546,6 +547,7 @@ allow-ads   = -block -filter{banners-by-size} -filter{banners-by-link}
 #
 { \
 +change-x-forwarded-for{block} \
++client-header-filter{no-brotli-accepted} \
 +client-header-tagger{css-requests} \
 +client-header-tagger{image-requests} \
 +client-header-tagger{range-requests} \
@@ -560,6 +562,7 @@ standard.Cautious
 #
 { \
 +change-x-forwarded-for{block} \
++client-header-filter{no-brotli-accepted} \
 +client-header-tagger{css-requests} \
 +client-header-tagger{image-requests} \
 +client-header-tagger{range-requests} \
@@ -590,6 +593,7 @@ standard.Medium
 #
 { \
 +change-x-forwarded-for{block} \
++client-header-filter{no-brotli-accepted} \
 +client-header-tagger{css-requests} \
 +client-header-tagger{image-requests} \
 +client-header-tagger{range-requests} \
@@ -2144,6 +2148,9 @@ yandex.ru/.*&retpath=http
 disqus.com/
 # URL = http://www.youtube.com/embed/blafasel?feature=oembed&enablejsapi=1&origin=http://www.example.com&wmode=opaque
 .youtube.com/.*origin=http
+# URL = https://oss-fuzz.com/login?dest=https%3A%2F%2Foss-fuzz.com%2Ftestcase-detail%2F5727799779524608
+#MASTER# REMARKS: Only match based on the host so the test works even without https-inspection enabled.
+oss-fuzz.com/
 
 {+redirect{s@.*url=@http://@} -block}
 # Sticky Actions = +redirect -block
index 548befe..e8bc150 100644 (file)
@@ -4,7 +4,7 @@
 #
 #  Purpose     :  Rules to process the content of web pages
 #
-#  Copyright   :  Written by and Copyright (C) 2001-2018 the
+#  Copyright   :  Written by and Copyright (C) 2001-2020 the
 #                 Privoxy team. https://www.privoxy.org/
 #
 #                 This program is free software; you can redistribute it
@@ -743,6 +743,16 @@ CLIENT-HEADER-FILTER: hide-tor-exit-notation Removes the Tor exit node notation
 
 s@^((?:Referer|Host):\s*(?:https?://)?[^/]*)\.[^\./]*?\.exit@$1@i
 
+#################################################################################
+#
+# no-brotli-accepted: Strips "br" from the Accept-Encoding header as Privoxy
+#                     currently doesn't support Brotli.
+#
+#################################################################################
+CLIENT-HEADER-FILTER: no-brotli-accepted Strip "br" from Accept-Encoding header
+
+s@(^Accept-Encoding:.*?)(?:br, |, br|br)@$1@i
+
 #################################################################################
 #
 # less-download-windows: Prevents annoying download windows for content types
index 88b3a5b..c2b075d 100644 (file)
@@ -3,7 +3,7 @@
 
  Purpose     :  Entity included in other project documents.
 
- Copyright (C) 2001-2019 Privoxy Developers https://www.privoxy.org/
+ Copyright (C) 2001-2020 Privoxy Developers https://www.privoxy.org/
  See LICENSE.
 
  ======================================================================
@@ -29,7 +29,7 @@
 -->
 
 <para>
- Copyright &my-copy; 2001-2019 by Privoxy Developers <email>privoxy-devel@lists.privoxy.org</email>
+ Copyright &my-copy; 2001-2020 by Privoxy Developers <email>privoxy-devel@lists.privoxy.org</email>
 </para>
 
 <para>
index da62dad..6a0e72e 100644 (file)
@@ -2550,7 +2550,7 @@ for-privoxy-version=3.0.11
         The main compilation takes place with IBM Visual Age C++.
         Some ancillary work takes place with GNU tools, available from
         various sources like hobbes.nmsu.edu.
-        Specificially, you will need <filename>autoheader</filename>,
+        Specifically, you will need <filename>autoheader</filename>,
         <filename>autoconf</filename> and <filename>sh</filename> tools.
         The packaging takes place with WarpIN, available from various sources, including
         its home page: <ulink url="http://www.xworkplace.org/">xworkplace</ulink>.
index 453dbd9..9de4fde 100644 (file)
@@ -116,7 +116,7 @@ Hal.
  It is not a substitute for the
  <ulink url="../user-manual/index.html"><citetitle>Privoxy User Manual</citetitle></ulink>.
 <!--
- This works, at least in some situtations:
+ This works, at least in some situations:
  Test: <ulink url="privoxy-user-manual.pdf"><citetitle>User Manual</citetitle></ulink>.
 -->
  </para>
@@ -2999,7 +2999,7 @@ browsing has slowed to a crawl. What gives? </title>
  this is not considered a Privoxy bug.
 </para>
 <para>
- To prevent the crashes you can rewrite your filter to use less ressources,
+ To prevent the crashes you can rewrite your filter to use less resources,
  increase the relevant memory limit or recompile pcre to use less stack space.
  For details please see the
  <ulink url="http://pcre.org/original/doc/html/pcrestack.html">pcrestack man page</ulink>
index 42b4c0b..69284d9 100644 (file)
@@ -154,6 +154,7 @@ Current Privoxy Team:
  Amuro Namie
  Mark Nelson
  Tobias Netzel
+ John Palkovic
  Adam Piggott
  Petr P&iacute;sar
  Dan Price
index e2b205b..2e7c50e 100644 (file)
@@ -1016,7 +1016,7 @@ actionsfile
     The available debug levels are:
    </para>
     <programlisting>
-  debug     1 # Log the destination for each request &my-app; let through. See also debug 1024.
+  debug     1 # Log the destination for each request. See also debug 1024.
   debug     2 # show each connection status
   debug     4 # show I/O status
   debug     8 # show header parsing
@@ -1677,7 +1677,7 @@ ACLs: permit-access and deny-access</title>
     If your system implements
     <ulink url="http://tools.ietf.org/html/rfc3493">RFC 3493</ulink>, then
     <replaceable class="parameter">src_addr</replaceable> and <replaceable
-    class="parameter">dst_addr</replaceable> can be IPv6 addresses delimeted by
+    class="parameter">dst_addr</replaceable> can be IPv6 addresses delimited by
     brackets, <replaceable class="parameter">port</replaceable> can be a number
     or a service name, and
     <replaceable class="parameter">src_masklen</replaceable> and
@@ -3235,13 +3235,13 @@ forward-socks4, forward-socks4a, forward-socks5 and forward-socks5t</title>
   <listitem>
    <para>
     Under high load incoming connection may queue up before Privoxy
-    gets around to serve them. The queue length is limitted by the
+    gets around to serve them. The queue length is limited by the
     operating system. Once the queue is full, additional connections
     are dropped before Privoxy can accept and serve them.
    </para>
    <para>
     Increasing the queue length allows Privoxy to accept more
-    incomming connections that arrive roughly at the same time.
+    incoming connections that arrive roughly at the same time.
    </para>
    <para>
     Note that Privoxy can only request a certain queue length,
index 4736f12..0097c55 100644 (file)
@@ -43,7 +43,7 @@
 <!entity % p-not-stable "INCLUDE">
 <!entity % p-stable "IGNORE">
 <!entity % p-text "IGNORE">           <!-- define we are not a text only doc -->
-<!entity % p-authors-formal "IGNORE"> <!-- exclude additional formating      -->
+<!entity % p-authors-formal "IGNORE"> <!-- exclude additional formatting      -->
 <!entity my-copy "(C)">               <!-- db2man barfs on copyright symbol  -->
 <!entity % seealso-extra "IGNORE">    <!-- for excluding sections of seealso -->
 ]>
index dc9c3d8..d9ee3ea 100644 (file)
@@ -3987,7 +3987,7 @@ problem-host.example.com</screen>
     looks for the string <quote>http://</quote>, either in plain text
     (invalid but often used) or encoded as <quote>http%3a//</quote>.
     Some sites use their own URL encoding scheme, encrypt the address
-    of the target server or replace it with a database id. In theses cases
+    of the target server or replace it with a database id. In these cases
     <literal>fast-redirects</literal> is fooled and the request reaches the
     redirection server where it probably gets logged.
    </para>
@@ -5523,9 +5523,10 @@ www.example.com</screen>
    <para>
     Note that some (rare) ill-configured sites don't handle requests for uncompressed
     documents correctly. Broken PHP applications tend to send an empty document body,
-    some IIS versions only send the beginning of the content. If you enable
-    <literal>prevent-compression</literal> per default, you might want to add
-    exceptions for those sites. See the example for how to do that.
+    some IIS versions only send the beginning of the content and some content delivery
+    networks let the connection time out.
+    If you enable <literal>prevent-compression</literal> per default, you might
+    want to add exceptions for those sites. See the example for how to do that.
    </para>
   </listitem>
  </varlistentry>
@@ -7473,7 +7474,7 @@ pre-defined filters for your convenience:
     sometimes appear on some pages, or user agents that don't correct for this on
     the fly.
 <!--
-    My version of Mozilla (ancient) shows litte square boxes for quote
+    My version of Mozilla (ancient) shows little square boxes for quote
     characters, and apostrophes on moronized pages. So many pages have this, I
     can read them fine now. HB 08/27/06
 -->
index af54836..0a076ca 100644 (file)
@@ -434,7 +434,7 @@ for-privoxy-version=3.0.11</pre>
           </tr>
         </table>
         <p>You will need a mix of development tools. The main compilation takes place with IBM Visual Age C++. Some
-        ancillary work takes place with GNU tools, available from various sources like hobbes.nmsu.edu. Specificially,
+        ancillary work takes place with GNU tools, available from various sources like hobbes.nmsu.edu. Specifically,
         you will need <tt class="FILENAME">autoheader</tt>, <tt class="FILENAME">autoconf</tt> and <tt class=
         "FILENAME">sh</tt> tools. The packaging takes place with WarpIN, available from various sources, including its
         home page: <a href="http://www.xworkplace.org/" target="_top">xworkplace</a>.</p>
index bb3d0a1..1a0a7d6 100644 (file)
@@ -25,7 +25,7 @@
   </div>
   <div class="SECT1">
     <h1 class="SECT1"><a name="COPYRIGHT" id="COPYRIGHT">7. Privoxy Copyright, License and History</a></h1>
-    <p>Copyright &copy; 2001-2019 by Privoxy Developers <code class="EMAIL">&#60;<a href=
+    <p>Copyright &copy; 2001-2020 by Privoxy Developers <code class="EMAIL">&#60;<a href=
     "mailto:privoxy-devel@lists.privoxy.org">privoxy-devel@lists.privoxy.org</a>&#62;</code></p>
     <p>Some source code is based on code Copyright &copy; 1997 by Anonymous Coders and Junkbusters, Inc. and licensed
     under the <i class="CITETITLE">GNU General Public License</i>.</p>
index faf550b..2697c44 100644 (file)
@@ -446,7 +446,7 @@ Request: 66.70.21.80/scripts/click.php?hid=a71b9f6504b0c5681fa5&#38;si=Ua</pre>
       sufficient.</p>
       <p>Unless the problem occurs with the filters available in the default configuration, this is not considered a
       Privoxy bug.</p>
-      <p>To prevent the crashes you can rewrite your filter to use less ressources, increase the relevant memory limit
+      <p>To prevent the crashes you can rewrite your filter to use less resources, increase the relevant memory limit
       or recompile pcre to use less stack space. For details please see the <a href=
       "http://pcre.org/original/doc/html/pcrestack.html" target="_top">pcrestack man page</a> and the documentation of
       your operating system.</p>
index 5fe10db..aee1f6a 100644 (file)
@@ -15,6 +15,7 @@
   <p><a href="https://www.top10vpn.com">https://www.top10vpn.com</a></p>
   <h3>Bronze sponsor</h3>
   <p><a href="https://www.betrugstest.com/">https://www.betrugstest.com/</a></p>
+  <p><a href="https://www.vpncompare.co.uk/">https://www.vpncompare.co.uk/</a></p>
   <h3>Becoming a Privoxy sponsor</h3>
   <p>If you want to become a sponsor, please have a look at the <a title=
   "FAQ: How can I become a sponsor and get my logo or link on privoxy.org?" href="../faq/general.html#SPONSOR">sponsor
index f5a98de..912f33c 100644 (file)
@@ -73,7 +73,7 @@
         <p>The default profiles, and their associated actions, as pre-defined in <tt class=
         "FILENAME">default.action</tt> are:</p>
         <div class="TABLE">
-          <a name="AEN3105" id="AEN3105"></a>
+          <a name="AEN3104" id="AEN3104"></a>
           <p><b>Table 1. Default Configurations</b></p>
           <table border="1" frame="border" rules="all" class="CALSTABLE">
             <col width="1*" title="C1">
@@ -1524,7 +1524,7 @@ problem-host.example.com</pre>
               <p>To detect a redirection URL, <tt class="LITERAL">fast-redirects</tt> only looks for the string
               <span class="QUOTE">"http://"</span>, either in plain text (invalid but often used) or encoded as
               <span class="QUOTE">"http%3a//"</span>. Some sites use their own URL encoding scheme, encrypt the address
-              of the target server or replace it with a database id. In theses cases <tt class=
+              of the target server or replace it with a database id. In these cases <tt class=
               "LITERAL">fast-redirects</tt> is fooled and the request reaches the redirection server where it probably
               gets logged.</p>
             </dd>
@@ -2730,8 +2730,9 @@ www.example.com</pre>
               action settings.</p>
               <p>Note that some (rare) ill-configured sites don't handle requests for uncompressed documents correctly.
               Broken PHP applications tend to send an empty document body, some IIS versions only send the beginning of
-              the content. If you enable <tt class="LITERAL">prevent-compression</tt> per default, you might want to
-              add exceptions for those sites. See the example for how to do that.</p>
+              the content and some content delivery networks let the connection time out. If you enable <tt class=
+              "LITERAL">prevent-compression</tt> per default, you might want to add exceptions for those sites. See the
+              example for how to do that.</p>
             </dd>
             <dt>Example usage (sections):</dt>
             <dd>
index 4c4511a..a3bac6a 100644 (file)
       these. If not, you will get a friendly error message. Internet access is not necessary either.</p>
       <ul>
         <li>
-          <p>Privoxy main page:</p><a name="AEN6290" id="AEN6290"></a>
+          <p>Privoxy main page:</p><a name="AEN6289" id="AEN6289"></a>
           <blockquote class="BLOCKQUOTE">
             <p><a href="http://config.privoxy.org/" target="_top">http://config.privoxy.org/</a></p>
           </blockquote>
           "APPLICATION">Privoxy</span>)</p>
         </li>
         <li>
-          <p>View and toggle client tags:</p><a name="AEN6298" id="AEN6298"></a>
+          <p>View and toggle client tags:</p><a name="AEN6297" id="AEN6297"></a>
           <blockquote class="BLOCKQUOTE">
             <p><a href="http://config.privoxy.org/client-tags" target=
             "_top">http://config.privoxy.org/client-tags</a></p>
         </li>
         <li>
           <p>Show information about the current configuration, including viewing and editing of actions
-          files:</p><a name="AEN6303" id="AEN6303"></a>
+          files:</p><a name="AEN6302" id="AEN6302"></a>
           <blockquote class="BLOCKQUOTE">
             <p><a href="http://config.privoxy.org/show-status" target=
             "_top">http://config.privoxy.org/show-status</a></p>
           </blockquote>
         </li>
         <li>
-          <p>Show the browser's request headers:</p><a name="AEN6308" id="AEN6308"></a>
+          <p>Show the browser's request headers:</p><a name="AEN6307" id="AEN6307"></a>
           <blockquote class="BLOCKQUOTE">
             <p><a href="http://config.privoxy.org/show-request" target=
             "_top">http://config.privoxy.org/show-request</a></p>
           </blockquote>
         </li>
         <li>
-          <p>Show which actions apply to a URL and why:</p><a name="AEN6313" id="AEN6313"></a>
+          <p>Show which actions apply to a URL and why:</p><a name="AEN6312" id="AEN6312"></a>
           <blockquote class="BLOCKQUOTE">
             <p><a href="http://config.privoxy.org/show-url-info" target=
             "_top">http://config.privoxy.org/show-url-info</a></p>
         <li>
           <p>Toggle Privoxy on or off. This feature can be turned off/on in the main <tt class="FILENAME">config</tt>
           file. When toggled <span class="QUOTE">"off"</span>, <span class="QUOTE">"Privoxy"</span> continues to run,
-          but only as a pass-through proxy, with no actions taking place:</p><a name="AEN6321" id="AEN6321"></a>
+          but only as a pass-through proxy, with no actions taking place:</p><a name="AEN6320" id="AEN6320"></a>
           <blockquote class="BLOCKQUOTE">
             <p><a href="http://config.privoxy.org/toggle" target="_top">http://config.privoxy.org/toggle</a></p>
           </blockquote>
-          <p>Short cuts. Turn off, then on:</p><a name="AEN6325" id="AEN6325"></a>
+          <p>Short cuts. Turn off, then on:</p><a name="AEN6324" id="AEN6324"></a>
           <blockquote class="BLOCKQUOTE">
             <p><a href="http://config.privoxy.org/toggle?set=disable" target=
             "_top">http://config.privoxy.org/toggle?set=disable</a></p>
-          </blockquote><a name="AEN6328" id="AEN6328"></a>
+          </blockquote><a name="AEN6327" id="AEN6327"></a>
           <blockquote class="BLOCKQUOTE">
             <p><a href="http://config.privoxy.org/toggle?set=enable" target=
             "_top">http://config.privoxy.org/toggle?set=enable</a></p>
index e0566ac..206d1e4 100644 (file)
               <table border="0" bgcolor="#E0E0E0" width="90%">
                 <tr>
                   <td>
-                    <pre class="PROGRAMLISTING">  debug     1 # Log the destination for each request <span class=
-                    "APPLICATION">Privoxy</span> let through. See also debug 1024.
+                    <pre class=
+                    "PROGRAMLISTING">  debug     1 # Log the destination for each request. See also debug 1024.
   debug     2 # show each connection status
   debug     4 # show I/O status
   debug     8 # show header parsing
               destination part are optional.</p>
               <p>If your system implements <a href="http://tools.ietf.org/html/rfc3493" target="_top">RFC 3493</a>,
               then <tt class="REPLACEABLE"><i>src_addr</i></tt> and <tt class="REPLACEABLE"><i>dst_addr</i></tt> can be
-              IPv6 addresses delimeted by brackets, <tt class="REPLACEABLE"><i>port</i></tt> can be a number or a
+              IPv6 addresses delimited by brackets, <tt class="REPLACEABLE"><i>port</i></tt> can be a number or a
               service name, and <tt class="REPLACEABLE"><i>src_masklen</i></tt> and <tt class=
               "REPLACEABLE"><i>dst_masklen</i></tt> can be a number from 0 to 128.</p>
             </dd>
             <dt>Notes:</dt>
             <dd>
               <p>Under high load incoming connection may queue up before Privoxy gets around to serve them. The queue
-              length is limitted by the operating system. Once the queue is full, additional connections are dropped
+              length is limited by the operating system. Once the queue is full, additional connections are dropped
               before Privoxy can accept and serve them.</p>
-              <p>Increasing the queue length allows Privoxy to accept more incomming connections that arrive roughly at
+              <p>Increasing the queue length allows Privoxy to accept more incoming connections that arrive roughly at
               the same time.</p>
               <p>Note that Privoxy can only request a certain queue length, whether or not the requested length is
               actually used depends on the operating system which may use a different length instead.</p>
index 7be80d4..79d11fe 100644 (file)
@@ -27,7 +27,7 @@
   </div>
   <div class="SECT1">
     <h1 class="SECT1"><a name="COPYRIGHT">12. Privoxy Copyright, License and History</a></h1>
-    <p>Copyright &copy; 2001-2019 by Privoxy Developers <code class="EMAIL">&#60;<a href=
+    <p>Copyright &copy; 2001-2020 by Privoxy Developers <code class="EMAIL">&#60;<a href=
     "mailto:privoxy-devel@lists.privoxy.org">privoxy-devel@lists.privoxy.org</a>&#62;</code></p>
     <p>Some source code is based on code Copyright &copy; 1997 by Anonymous Coders and Junkbusters, Inc. and licensed
     under the <i class="CITETITLE">GNU General Public License</i>.</p>
@@ -523,6 +523,7 @@ Public License instead of this License.
       &nbsp;Amuro&nbsp;Namie<br>
       &nbsp;Mark&nbsp;Nelson<br>
       &nbsp;Tobias&nbsp;Netzel<br>
+      &nbsp;John&nbsp;Palkovic<br>
       &nbsp;Adam&nbsp;Piggott<br>
       &nbsp;Petr&nbsp;P&iacute;sar<br>
       &nbsp;Dan&nbsp;Price<br>
index fd723b4..05a2c82 100644 (file)
--- a/errlog.c
+++ b/errlog.c
@@ -601,7 +601,7 @@ static inline const char *get_log_level_string(int loglevel)
       case LOG_LEVEL_FATAL:
          log_level_string = "Fatal error";
          break;
-      case LOG_LEVEL_GPC:
+      case LOG_LEVEL_REQUEST:
          log_level_string = "Request";
          break;
       case LOG_LEVEL_CONNECT:
@@ -684,7 +684,7 @@ void log_error(int loglevel, const char *fmt, ...)
     * the taskbar icon animate.  (There is an option to disable
     * this but checking that is handled inside LogShowActivity()).
     */
-   if ((loglevel == LOG_LEVEL_GPC) || (loglevel == LOG_LEVEL_CRUNCH))
+   if ((loglevel == LOG_LEVEL_REQUEST) || (loglevel == LOG_LEVEL_CRUNCH))
    {
       LogShowActivity();
    }
@@ -799,7 +799,7 @@ void log_error(int loglevel, const char *fmt, ...)
             break;
          case 'c':
             /*
-             * Note that char paramaters are converted to int, so we need to
+             * Note that char parameters are converted to int, so we need to
              * pass "int" to va_arg.  (See K&R, 2nd ed, section A7.3.2, page 202)
              */
             tempbuf[0] = (char) va_arg(ap, int);
index 0a805f4..5bfc16a 100644 (file)
--- a/errlog.h
+++ b/errlog.h
@@ -37,8 +37,7 @@
 
 /* Debug level for errors */
 
-/* XXX: Should be renamed. */
-#define LOG_LEVEL_GPC        0x0001
+#define LOG_LEVEL_REQUEST    0x0001
 #define LOG_LEVEL_CONNECT    0x0002
 #define LOG_LEVEL_IO         0x0004
 #define LOG_LEVEL_HEADER     0x0008
index 278c113..c891f4f 100644 (file)
--- a/filters.c
+++ b/filters.c
@@ -206,7 +206,7 @@ static int match_sockaddr(const struct sockaddr_storage *network,
       return 0;
    }
 
-   /* TODO: Optimize by checking by words insted of octets */
+   /* TODO: Optimize by checking by words instead of octets */
    for (i = 0; (i < addr_len) && netmask_addr[i]; i++)
    {
       if ((network_addr[i] & netmask_addr[i]) !=
@@ -505,7 +505,7 @@ int acl_addr(const char *aspec, struct access_control_addr *aca)
  *
  * Description :  Check to see if CONNECT requests to the destination
  *                port of this request are forbidden. The check is
- *                independend of the actual request method.
+ *                independent of the actual request method.
  *
  * Parameters  :
  *          1  :  csp = Current client state (buffers, headers, etc...)
diff --git a/fuzz.c b/fuzz.c
index 6b94d16..a637e7b 100644 (file)
--- a/fuzz.c
+++ b/fuzz.c
@@ -429,7 +429,7 @@ static int fuzz_gzip(struct client_state *csp, char *fuzz_input_file)
  * Function    :  fuzz_socks
  *
  * Description :  Treat the fuzzed input as a socks response.
- *                XXX: This is pretty useless as parsing socks repsonse
+ *                XXX: This is pretty useless as parsing socks response
  *                     is trivial.
  *
  * Parameters  :
index f5d15a5..64ba523 100644 (file)
--- a/gateway.c
+++ b/gateway.c
@@ -218,6 +218,7 @@ void remember_connection(const struct reusable_connection *connection)
       return;
    }
 
+   assert(slot < SZ(reusable_connection));
    assert(NULL != connection->host);
    reusable_connection[slot].host = strdup_or_die(connection->host);
    reusable_connection[slot].sfd = connection->sfd;
index 16b2a90..556c927 100644 (file)
@@ -218,7 +218,7 @@ static jb_socket rfc2553_connect_to(const char *host, int portnum, struct client
 #endif
    int connect_failed;
    /*
-    * XXX: Initializeing it here is only necessary
+    * XXX: Initializing it here is only necessary
     *      because not all situations are properly
     *      covered yet.
     */
@@ -1323,7 +1323,7 @@ int accept_connection(struct client_state * csp, jb_socket fds[])
 #endif
    jb_socket afd;
 #if defined(_WIN32) || defined(__OS2__)
-   /* Wierdness - fix a warning. */
+   /* Weirdness - fix a warning. */
    int c_length;
 #else
    socklen_t c_length;
diff --git a/jcc.c b/jcc.c
index 614c7f1..2eaf0b7 100644 (file)
--- a/jcc.c
+++ b/jcc.c
@@ -485,8 +485,9 @@ static int client_protocol_is_unsupported(struct client_state *csp, char *req)
 #ifdef FEATURE_HTTPS_INSPECTION
       if (client_use_ssl(csp))
       {
-         ssl_send_data(&(csp->mbedtls_client_attr.ssl),
-            (const unsigned char *)response, strlen(response));
+         ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl),
+            (const unsigned char *)response, strlen(response),
+            get_write_delay(csp));
       }
       else
 #endif
@@ -848,18 +849,32 @@ static void send_crunch_response(struct client_state *csp, struct http_response
 
       /* Log that the request was crunched and why. */
       log_applied_actions(csp->action);
-      log_error(LOG_LEVEL_CRUNCH, "%s: %s", crunch_reason(rsp), http->url);
-      log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" %s %u",
-         csp->ip_addr_str, http->ocmd, status_code, rsp->content_length);
-
+#ifdef FEATURE_HTTPS_INSPECTION
+      if (client_use_ssl(csp))
+      {
+         log_error(LOG_LEVEL_CRUNCH, "%s: https://%s%s", crunch_reason(rsp),
+            http->hostport, http->path);
+         log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s https://%s%s %s\" %s %llu",
+            csp->ip_addr_str, http->gpc, http->hostport, http->path,
+            http->version, status_code, rsp->content_length);
+      }
+      else
+#endif
+      {
+         log_error(LOG_LEVEL_CRUNCH, "%s: %s", crunch_reason(rsp), http->url);
+         log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" %s %u",
+            csp->ip_addr_str, http->ocmd, status_code, rsp->content_length);
+      }
       /* Write the answer to the client */
 #ifdef FEATURE_HTTPS_INSPECTION
       if (client_use_ssl(csp))
       {
-         if ((ssl_send_data(&(csp->mbedtls_client_attr.ssl),
-                 (const unsigned char *)rsp->head, rsp->head_length) < 0)
-          || (ssl_send_data(&(csp->mbedtls_client_attr.ssl),
-                 (const unsigned char *)rsp->body, rsp->content_length) < 0))
+         if ((ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl),
+                (const unsigned char *)rsp->head, rsp->head_length,
+                get_write_delay(csp)) < 0)
+          || (ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl),
+                (const unsigned char *)rsp->body, rsp->content_length,
+                get_write_delay(csp)) < 0))
          {
             /* There is nothing we can do about it. */
             log_error(LOG_LEVEL_CONNECT, "Couldn't deliver the error message "
@@ -985,10 +1000,10 @@ static void build_request_line(struct client_state *csp, const struct forward_sp
     * if +downgrade action applies.
     */
    if ((csp->action->flags & ACTION_DOWNGRADE)
-     && (!strcmpic(http->ver, "HTTP/1.1")))
+     && (!strcmpic(http->version, "HTTP/1.1")))
    {
-      freez(http->ver);
-      http->ver = strdup_or_die("HTTP/1.0");
+      freez(http->version);
+      http->version = strdup_or_die("HTTP/1.0");
    }
 
    /*
@@ -1007,7 +1022,7 @@ static void build_request_line(struct client_state *csp, const struct forward_sp
       string_append(request_line, http->path);
    }
    string_append(request_line, " ");
-   string_append(request_line, http->ver);
+   string_append(request_line, http->version);
 
    if (*request_line == NULL)
    {
@@ -1607,7 +1622,7 @@ extern int fuzz_client_request(struct client_state *csp, char *fuzz_input_file)
    if (strcmp(fuzz_input_file, "-") != 0)
    {
       log_error(LOG_LEVEL_FATAL,
-         "Fuzzed client requests can currenty only be read from stdin (-).");
+         "Fuzzed client requests can currently only be read from stdin (-).");
    }
    err = receive_client_request(csp);
    if (err != JB_ERR_OK)
@@ -1898,7 +1913,7 @@ static jb_err parse_client_request(struct client_state *csp)
 
 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
    if ((csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_KEEP_ALIVE)
-    && (!strcmpic(csp->http->ver, "HTTP/1.1"))
+    && (!strcmpic(csp->http->version, "HTTP/1.1"))
     && (csp->http->ssl == 0))
    {
       /* Assume persistence until further notice */
@@ -2037,11 +2052,12 @@ static int send_http_request(struct client_state *csp)
  * Returns     :  0 on success, anything else is an error.
  *
  *********************************************************************/
-static jb_err receive_and_send_encrypted_post_data(struct client_state *csp)
+static int receive_and_send_encrypted_post_data(struct client_state *csp)
 {
    int content_length_known = csp->expected_client_content_length != 0;
 
-   while (is_ssl_pending(&(csp->mbedtls_client_attr.ssl)))
+   while (is_ssl_pending(&(csp->mbedtls_client_attr.ssl))
+      || (content_length_known && csp->expected_client_content_length != 0))
    {
       unsigned char buf[BUFFER_SIZE];
       int len;
@@ -2065,7 +2081,7 @@ static jb_err receive_and_send_encrypted_post_data(struct client_state *csp)
          /* XXX: Does this actually happen? */
          break;
       }
-      log_error(LOG_LEVEL_HEADER, "Forwarding %d bytes of encrypted POST data",
+      log_error(LOG_LEVEL_CONNECT, "Forwarding %d bytes of encrypted POST data",
          len);
       len = ssl_send_data(&(csp->mbedtls_server_attr.ssl), buf, (size_t)len);
       if (len == -1)
@@ -2080,13 +2096,13 @@ static jb_err receive_and_send_encrypted_post_data(struct client_state *csp)
          }
          if (csp->expected_client_content_length == 0)
          {
-            log_error(LOG_LEVEL_HEADER, "Forwarded the last %d bytes", len);
+            log_error(LOG_LEVEL_CONNECT, "Forwarded the last %d bytes", len);
             break;
          }
       }
    }
 
-   log_error(LOG_LEVEL_HEADER, "Done forwarding encrypted POST data");
+   log_error(LOG_LEVEL_CONNECT, "Done forwarding encrypted POST data");
 
    return 0;
 
@@ -2257,8 +2273,8 @@ static jb_err process_encrypted_request(struct client_state *csp)
       /* XXX: Also used for JB_ERR_MEMORY */
       log_error(LOG_LEVEL_ERROR, "Failed to receive encrypted request: %s",
          jb_err_to_string(err));
-      ssl_send_data(&(csp->mbedtls_client_attr.ssl),
-         (const unsigned char *)CHEADER, strlen(CHEADER));
+      ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl),
+         (const unsigned char *)CHEADER, strlen(CHEADER), get_write_delay(csp));
       return err;
    }
 
@@ -2267,8 +2283,8 @@ static jb_err process_encrypted_request(struct client_state *csp)
    if (request_line == NULL)
    {
       log_error(LOG_LEVEL_ERROR, "Failed to get the encrypted request line");
-      ssl_send_data(&(csp->mbedtls_client_attr.ssl),
-         (const unsigned char *)CHEADER, strlen(CHEADER));
+      ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl),
+         (const unsigned char *)CHEADER, strlen(CHEADER), get_write_delay(csp));
       return JB_ERR_PARSE;
    }
    assert(*request_line != '\0');
@@ -2300,8 +2316,8 @@ static jb_err process_encrypted_request(struct client_state *csp)
    freez(request_line);
    if (JB_ERR_OK != err)
    {
-      ssl_send_data(&(csp->mbedtls_client_attr.ssl),
-         (const unsigned char *)CHEADER, strlen(CHEADER));
+      ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl),
+         (const unsigned char *)CHEADER, strlen(CHEADER), get_write_delay(csp));
       /* XXX: Use correct size */
       log_error(LOG_LEVEL_CLF, "%s - - [%T] \"Invalid request\" 400 0", csp->ip_addr_str);
       log_error(LOG_LEVEL_ERROR,
@@ -2335,8 +2351,8 @@ static jb_err process_encrypted_request(struct client_state *csp)
        */
       log_error(LOG_LEVEL_ERROR,
          "Failed to get the encrypted request destination");
-      ssl_send_data(&(csp->mbedtls_client_attr.ssl),
-         (const unsigned char *)CHEADER, strlen(CHEADER));
+      ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl),
+         (const unsigned char *)CHEADER, strlen(CHEADER), get_write_delay(csp));
       return JB_ERR_PARSE;
    }
 
@@ -2373,8 +2389,8 @@ static jb_err process_encrypted_request(struct client_state *csp)
    err = sed_https(csp);
    if (JB_ERR_OK != err)
    {
-      ssl_send_data(&(csp->mbedtls_client_attr.ssl),
-         (const unsigned char *)CHEADER, strlen(CHEADER));
+      ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl),
+         (const unsigned char *)CHEADER, strlen(CHEADER), get_write_delay(csp));
       log_error(LOG_LEVEL_ERROR, "Failed to parse client request from %s.",
          csp->ip_addr_str);
       log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 400 0",
@@ -2384,10 +2400,39 @@ static jb_err process_encrypted_request(struct client_state *csp)
 
    log_error(LOG_LEVEL_HEADER, "Encrypted request processed");
    log_applied_actions(csp->action);
+   log_error(LOG_LEVEL_REQUEST, "https://%s%s", csp->http->hostport,
+      csp->http->path);
 
    return err;
 
 }
+
+/*********************************************************************
+ *
+ * Function    :  cgi_page_requested
+ *
+ * Description :  Checks if a request is for an internal CGI page.
+ *
+ * Parameters  :
+ *          1  :  host = The host requested by the client.
+ *
+ * Returns     :  1 if a CGI page has been requested, 0 otherwise
+ *
+ *********************************************************************/
+static int cgi_page_requested(const char *host)
+{
+   if ((0 == strcmpic(host, CGI_SITE_1_HOST))
+    || (0 == strcmpic(host, CGI_SITE_1_HOST "."))
+    || (0 == strcmpic(host, CGI_SITE_2_HOST))
+    || (0 == strcmpic(host, CGI_SITE_2_HOST ".")))
+   {
+      return 1;
+   }
+
+   return 0;
+
+}
+
 #endif
 
 
@@ -2666,35 +2711,10 @@ static void handle_established_connection(struct client_state *csp)
 #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
 
 #ifdef FEATURE_HTTPS_INSPECTION
-         /*
-          * Reading data from standard or secured connection (HTTP/HTTPS)
-          */
          if (client_use_ssl(csp))
          {
-            /*
-             * Receiving HTTP request from client over TLS/SSL and sending
-             * it to server over TLS/SSL.
-             */
-            len = ssl_recv_data(&(csp->mbedtls_client_attr.ssl),
-               (unsigned char *)csp->receive_buffer, (size_t)max_bytes_to_read);
-
-            if (len <= 0)
-            {
-               mark_server_socket_tainted(csp);
-               break;
-            }
-
-            ret = ssl_send_data(&(csp->mbedtls_server_attr.ssl),
-               (const unsigned char *)csp->receive_buffer, (size_t)len);
-
-            if (ret < 0)
-            {
-               log_error(LOG_LEVEL_ERROR,
-                  "Send request over TLS/SSL to: %s failed", http->host);
-               mark_server_socket_tainted(csp);
-               close_client_and_server_ssl_connections(csp);
-               return;
-            }
+            log_error(LOG_LEVEL_CONNECT, "Breaking with TLS/SSL.");
+            break;
          }
          else
 #endif /* def FEATURE_HTTPS_INSPECTION */
@@ -2944,11 +2964,12 @@ static void handle_established_connection(struct client_state *csp)
                    */
                   if (client_use_ssl(csp))
                   {
-                     if ((ssl_send_data(&(csp->mbedtls_client_attr.ssl),
-                            (const unsigned char *)hdr, strlen(hdr)) < 0)
-                        || (ssl_send_data(&(csp->mbedtls_client_attr.ssl),
+                     if ((ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl),
+                              (const unsigned char *)hdr, strlen(hdr),
+                              get_write_delay(csp)) < 0)
+                        || (ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl),
                               (const unsigned char *) ((p != NULL) ? p : csp->iob->cur),
-                              csp->content_length) < 0))
+                              csp->content_length, get_write_delay(csp)) < 0))
                      {
                         log_error(LOG_LEVEL_ERROR, "write modified content to "
                            "client over TLS/SSL failed");
@@ -3046,12 +3067,13 @@ static void handle_established_connection(struct client_state *csp)
                    */
                   if (client_use_ssl(csp))
                   {
-                     if ((ssl_send_data(&(csp->mbedtls_client_attr.ssl),
-                            (const unsigned char *)hdr, hdrlen) < 0)
+                     if ((ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl),
+                             (const unsigned char *)hdr, hdrlen, get_write_delay(csp)) < 0)
                         || ((flushed = ssl_flush_socket(&(csp->mbedtls_client_attr.ssl),
                                 csp->iob)) < 0)
-                        || (ssl_send_data(&(csp->mbedtls_client_attr.ssl),
-                              (const unsigned char *)csp->receive_buffer, (size_t)len) < 0))
+                        || (ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl),
+                              (const unsigned char *)csp->receive_buffer, (size_t)len,
+                              get_write_delay(csp)) < 0))
                      {
                         log_error(LOG_LEVEL_CONNECT,
                            "Flush header and buffers to client failed");
@@ -3096,8 +3118,9 @@ static void handle_established_connection(struct client_state *csp)
                 */
                if (client_use_ssl(csp))
                {
-                  ret = ssl_send_data(&(csp->mbedtls_client_attr.ssl),
-                     (const unsigned char *)csp->receive_buffer, (size_t)len);
+                  ret = ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl),
+                     (const unsigned char *)csp->receive_buffer, (size_t)len,
+                     get_write_delay(csp));
                   if (ret < 0)
                   {
                      log_error(LOG_LEVEL_ERROR,
@@ -3161,9 +3184,9 @@ static void handle_established_connection(struct client_state *csp)
                    */
                   if (client_use_ssl(csp))
                   {
-                     ssl_send_data(&(csp->mbedtls_client_attr.ssl),
+                     ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl),
                         (const unsigned char *)INVALID_SERVER_HEADERS_RESPONSE,
-                        strlen(INVALID_SERVER_HEADERS_RESPONSE));
+                        strlen(INVALID_SERVER_HEADERS_RESPONSE), get_write_delay(csp));
                   }
                   else
 #endif /* def FEATURE_HTTPS_INSPECTION */
@@ -3255,9 +3278,10 @@ static void handle_established_connection(struct client_state *csp)
                 */
                if (client_use_ssl(csp))
                {
-                  ssl_send_data(&(csp->mbedtls_client_attr.ssl),
+                  ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl),
                      (const unsigned char *)INVALID_SERVER_HEADERS_RESPONSE,
-                     strlen(INVALID_SERVER_HEADERS_RESPONSE));
+                     strlen(INVALID_SERVER_HEADERS_RESPONSE),
+                     get_write_delay(csp));
                }
                else
 #endif /* def FEATURE_HTTPS_INSPECTION */
@@ -3287,9 +3311,10 @@ static void handle_established_connection(struct client_state *csp)
                 */
                if (client_use_ssl(csp))
                {
-                  ssl_send_data(&(csp->mbedtls_client_attr.ssl),
+                  ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl),
                      (const unsigned char *)INVALID_SERVER_HEADERS_RESPONSE,
-                     strlen(INVALID_SERVER_HEADERS_RESPONSE));
+                     strlen(INVALID_SERVER_HEADERS_RESPONSE),
+                     get_write_delay(csp));
                }
                else
 #endif
@@ -3356,8 +3381,9 @@ static void handle_established_connection(struct client_state *csp)
 #ifdef FEATURE_HTTPS_INSPECTION
                if (client_use_ssl(csp))
                {
-                  if ((ssl_send_data(&(csp->mbedtls_client_attr.ssl),
-                          (const unsigned char *)hdr, strlen(hdr)) < 0)
+                  if ((ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl),
+                          (const unsigned char *)hdr, strlen(hdr),
+                          get_write_delay(csp)) < 0)
                      || (len = ssl_flush_socket(&(csp->mbedtls_client_attr.ssl),
                             csp->iob) < 0))
                   {
@@ -3417,9 +3443,10 @@ static void handle_established_connection(struct client_state *csp)
                 */
                if (client_use_ssl(csp))
                {
-                  ssl_send_data(&(csp->mbedtls_client_attr.ssl),
+                  ssl_send_data_delayed(&(csp->mbedtls_client_attr.ssl),
                      (const unsigned char *)INVALID_SERVER_HEADERS_RESPONSE,
-                     strlen(INVALID_SERVER_HEADERS_RESPONSE));
+                     strlen(INVALID_SERVER_HEADERS_RESPONSE),
+                     get_write_delay(csp));
                }
                else
 #endif /* def FEATURE_HTTPS_INSPECTION */
@@ -3465,9 +3492,19 @@ static void handle_established_connection(struct client_state *csp)
    }
 #endif
 
-   log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 200 %llu",
-      csp->ip_addr_str, http->ocmd, csp->content_length);
-
+#ifdef FEATURE_HTTPS_INSPECTION
+   if (client_use_ssl(csp))
+   {
+      log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s https://%s%s %s\" 200 %llu",
+         csp->ip_addr_str, http->gpc, http->hostport, http->path,
+         http->version, csp->content_length);
+   }
+   else
+#endif
+   {
+      log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 200 %llu",
+         csp->ip_addr_str, http->ocmd, csp->content_length);
+   }
    csp->server_connection.timestamp = time(NULL);
 }
 
@@ -3516,6 +3553,17 @@ static void chat(struct client_state *csp)
    {
       return;
    }
+#ifdef FEATURE_HTTPS_INSPECTION
+   /*
+    * Log the request unless we're https inspecting
+    * in which case we don't have the path yet and
+    * will log the request later.
+    */
+   if (!client_use_ssl(csp))
+#endif
+   {
+      log_error(LOG_LEVEL_REQUEST, "%s%s", http->hostport, http->path);
+   }
 
    /* decide how to route the HTTP request */
    fwd = forward_url(csp, http);
@@ -3531,7 +3579,8 @@ static void chat(struct client_state *csp)
     * Setting flags to use old solution with SSL tunnel and to disable
     * certificates verification.
     */
-   if (csp->http->ssl && !(csp->action->flags & ACTION_HTTPS_INSPECTION))
+   if (csp->http->ssl && !(csp->action->flags & ACTION_HTTPS_INSPECTION)
+      && !cgi_page_requested(csp->http->host))
    {
       use_ssl_tunnel = 1;
    }
@@ -3638,8 +3687,6 @@ static void chat(struct client_state *csp)
    }
 
    log_applied_actions(csp->action);
-   log_error(LOG_LEVEL_GPC, "%s%s", http->hostport, http->path);
-
    if (fwd->forward_host)
    {
       log_error(LOG_LEVEL_CONNECT, "via [%s]:%d to: %s",
@@ -3689,7 +3736,7 @@ static void chat(struct client_state *csp)
          int ret;
          /*
           * Creating an SSL proxy. If forwarding is disabled, we must send
-          * CSUCCEED mesage to client. Then TLS/SSL connection with client
+          * CSUCCEED message to client. Then TLS/SSL connection with client
           * is created.
           */
 
diff --git a/list.c b/list.c
index 4faf693..89bb010 100644 (file)
--- a/list.c
+++ b/list.c
@@ -130,7 +130,7 @@ void destroy_list (struct list *the_list)
  * Description :  Check that a string list is valid.  The intended
  *                usage is "assert(list_is_valid(the_list))".
  *                Currently this checks that "the_list->last"
- *                is correct, and that the list dosn't contain
+ *                is correct, and that the list doesn't contain
  *                circular references.  It is likely to crash if
  *                it's passed complete garbage.
  *
@@ -1120,7 +1120,7 @@ jb_err unmap(struct map *the_map, const char *name)
  *          2  :  name = name parameter to look for
  *
  * Returns     :  the value if found, else the empty string.
- *                Return value is alloced as part of the map, so
+ *                Return value is allocated as part of the map, so
  *                it is freed when the map is destroyed.  Caller
  *                must not free or modify it.
  *
index 7d8c392..55874d5 100644 (file)
--- a/loadcfg.c
+++ b/loadcfg.c
@@ -121,7 +121,7 @@ static struct file_list *current_configfile = NULL;
 /*
  * This takes the "cryptic" hash of each keyword and aliases them to
  * something a little more readable.  This also makes changing the
- * hash values easier if they should change or the hash algorthm changes.
+ * hash values easier if they should change or the hash algorithm changes.
  * Use the included "hash" program to find out what the hash will be
  * for any string supplied on the command line.  (Or just put it in the
  * config file and read the number from the error message in the log).
index 68b4c61..20f0888 100644 (file)
--- a/loaders.c
+++ b/loaders.c
@@ -1211,7 +1211,7 @@ int load_one_re_filterfile(struct client_state *csp, int fileid)
 
          /*
           * If this is the first filter block, chain it
-          * to the file_list rather than its (nonexistant)
+          * to the file_list rather than its (nonexistent)
           * predecessor
           */
          if (fs->f == NULL)
index 37520d3..d7bbc6b 100644 (file)
@@ -7,6 +7,7 @@
 #############################################################################
 { \
 +change-x-forwarded-for{block} \
++client-header-filter{no-brotli-accepted} \
 +client-header-tagger{css-requests} \
 +client-header-tagger{image-requests} \
 +client-header-tagger{range-requests} \
index b65474c..37a647c 100644 (file)
--- a/parsers.c
+++ b/parsers.c
@@ -1208,7 +1208,7 @@ jb_err sed_https(struct client_state *csp)
    struct list headers;
 
    /*
-    * Temporarly replace csp->headers with csp->https_headers
+    * Temporarily replace csp->headers with csp->https_headers
     * to trick sed() into filtering the https headers.
     */
    headers.first = csp->headers->first;
@@ -1217,7 +1217,7 @@ jb_err sed_https(struct client_state *csp)
    csp->headers->last  = csp->https_headers->last;
 
    /*
-    * Start with fresh tags. Already exising tags may
+    * Start with fresh tags. Already existing tags may
     * be set again. This is necessary to overrule
     * URL-based patterns.
     */
@@ -1225,12 +1225,18 @@ jb_err sed_https(struct client_state *csp)
 
    /*
     * We want client header filters and taggers
-    * so temporarly remove the flag.
+    * so temporarily remove the flag.
     */
    csp->flags &= ~CSP_FLAG_CLIENT_HEADER_PARSING_DONE;
    err = sed(csp, FILTER_CLIENT_HEADERS);
    csp->flags |= CSP_FLAG_CLIENT_HEADER_PARSING_DONE;
 
+   /*
+    * Update the last header which may have changed
+    * due to header additions,
+    */
+   csp->https_headers->last = csp->headers->last;
+
    csp->headers->first = headers.first;
    csp->headers->last  = headers.last;
 
@@ -1952,7 +1958,7 @@ static jb_err client_connection(struct client_state *csp, char **header)
       if ((csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_SHARING)
         && !(csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED))
       {
-          if (!strcmpic(csp->http->ver, "HTTP/1.1"))
+          if (!strcmpic(csp->http->version, "HTTP/1.1"))
           {
              log_error(LOG_LEVEL_HEADER,
                 "Removing \'%s\' to imply keep-alive.", *header);
@@ -2453,7 +2459,7 @@ static jb_err server_content_encoding(struct client_state *csp, char **header)
  *
  * Description :  Remove the Content-Encoding header if the
  *                decompression was successful and the content
- *                has been modifed.
+ *                has been modified.
  *
  * Parameters  :
  *          1  :  csp = Current client state (buffers, headers, etc...)
@@ -3893,7 +3899,7 @@ static jb_err client_connection_header_adder(struct client_state *csp)
 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
    if ((csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_KEEP_ALIVE)
       && !(csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED)
-      && !strcmpic(csp->http->ver, "HTTP/1.1"))
+      && !strcmpic(csp->http->version, "HTTP/1.1"))
    {
       csp->flags |= CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE;
       return JB_ERR_OK;
@@ -4535,7 +4541,7 @@ jb_err get_destination_from_headers(const struct list *headers, struct http_requ
    string_append(&http->cmd, " ");
    string_append(&http->cmd, http->url);
    string_append(&http->cmd, " ");
-   string_append(&http->cmd, http->ver);
+   string_append(&http->cmd, http->version);
    if (http->cmd == NULL)
    {
       return JB_ERR_MEMORY;
@@ -4616,7 +4622,7 @@ jb_err get_destination_from_https_headers(const struct list *headers, struct htt
    string_append(&http->cmd, " ");
    string_append(&http->cmd, http->url);
    string_append(&http->cmd, " ");
-   string_append(&http->cmd, http->ver);
+   string_append(&http->cmd, http->version);
    if (http->cmd == NULL)
    {
       return JB_ERR_MEMORY;
index e5b034b..943e66d 100644 (file)
--- a/project.h
+++ b/project.h
@@ -175,7 +175,7 @@ typedef enum privoxy_err jb_err;
 /**
  * This macro is used to free a pointer that may be NULL.
  * It also sets the variable to NULL after it's been freed.
- * The paramater should be a simple variable without side effects.
+ * The parameter should be a simple variable without side effects.
  */
 #define freez(X)  { if(X) { free((void*)X); X = NULL ; } }
 
@@ -276,7 +276,7 @@ struct map_entry
 
 /**
  * A map from a string to another string.
- * This is used for the paramaters passed in a HTTP GET request, and
+ * This is used for the parameters passed in a HTTP GET request, and
  * to store the exports when the CGI interface is filling in a template.
  */
 struct map
@@ -319,7 +319,7 @@ struct http_request
    char *ocmd;     /**< Backup of original cmd for CLF logging */
    char *gpc;      /**< HTTP method: GET, POST, ... */
    char *url;      /**< The URL */
-   char *ver;      /**< Protocol version */
+   char *version;  /**< Protocol version */
    int status;     /**< HTTP Status */
 
    char *host;     /**< Host part of URL */
@@ -338,8 +338,8 @@ struct http_request
 #endif /* ndef FEATURE_EXTENDED_HOST_PATTERNS */
 
 #ifdef FEATURE_HTTPS_INSPECTION
-   int client_ssl;                                                  /**< Flag if we should comunicate with slient over ssl   */
-   int server_ssl;                                                  /**< Flag if we should comunicate with server over ssl   */
+   int client_ssl;                                                  /**< Flag if we should communicate with client over ssl   */
+   int server_ssl;                                                  /**< Flag if we should communicate with server over ssl   */
    unsigned char hash_of_host_hex[(HASH_OF_HOST_BUF_SIZE * 2) + 1]; /**< chars for hash in hex string and one for '\0'       */
    unsigned char hash_of_host[HASH_OF_HOST_BUF_SIZE+1];             /**< chars for bytes of hash and one for '\0'            */
 #endif
@@ -351,7 +351,7 @@ struct http_request
  * Struct for linked list containing certificates
  */
 typedef struct certs_chain {
-   char text_buf[CERT_INFO_BUF_SIZE];    /* text info about properties of certificate               */
+   char info_buf[CERT_INFO_BUF_SIZE];    /* text info about properties of certificate               */
    char file_buf[CERT_FILE_BUF_SIZE];    /* buffer for whole certificate - format to save in file   */
    struct certs_chain *next;             /* next certificate in chain of trust                      */
 } certs_chain_t;
@@ -650,7 +650,7 @@ struct current_action_spec
    unsigned long flags;
 
    /**
-    * Paramaters for those actions that require them.
+    * Parameters for those actions that require them.
     * Each entry is valid if & only if the corresponding entry in "flags" is
     * set.
     */
@@ -922,7 +922,7 @@ struct reusable_connection
 #define CSP_FLAG_UNSUPPORTED_CLIENT_EXPECTATION     0x02000000U
 
 /**
- * Flag for csp->flags: Set if we answered the request ourselve.
+ * Flag for csp->flags: Set if we answered the request ourselves.
  */
 #define CSP_FLAG_CRUNCHED                           0x04000000U
 
@@ -1105,7 +1105,7 @@ struct client_state
 
    /*
     * Server certificate chain of trust including strings with certificates
-    * informations and string with whole certificate file
+    * information and string with whole certificate file
     */
    struct certs_chain server_certs_chain;
 #endif
@@ -1603,6 +1603,7 @@ struct configuration_spec
  * INCLUDES the trailing slash.
  */
 #define CGI_PREFIX  "http://" CGI_SITE_2_HOST CGI_SITE_2_PATH "/"
+#define CGI_PREFIX_HTTPS "https://" CGI_SITE_2_HOST CGI_SITE_2_PATH "/"
 
 #endif /* ndef PROJECT_H_INCLUDED */
 
index b151a71..a1bc8e3 100644 (file)
@@ -8,7 +8,7 @@
 #
 #############################################################################
 #
-# Copyright (c) 2007-2018 Fabian Keil <fk@fabiankeil.de>
+# Copyright (c) 2007-2020 Fabian Keil <fk@fabiankeil.de>
 #
 # Permission to use, copy, modify, and distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
@@ -1086,3 +1086,7 @@ redirect.example.net/
 # Redirected URL = http://redirect2.example.net/blafasel?x=http://redirected.example.net/&parameter1=part-of-the-redirected-url1&parameter2=part-of-the-redirected-url1
 # Redirect Destination = http://redirected.example.net/&parameter1=part-of-the-redirected-url1&parameter2=part-of-the-redirected-url1
 redirect2.example.net/
+
+{+delay-response{1}}
+# Fetch Test = http://config.privoxy.org/show-url-info?url=http%3A%2F%2Fwww.example.com%2Fprivoxy-test-delay-response
+config.privoxy.org/show-url-info\?url=http%3A%2F%2Fwww\.example\.com%2Fprivoxy-test-delay-response
diff --git a/ssl.c b/ssl.c
index 4d94b2e..852a9ce 100644 (file)
--- a/ssl.c
+++ b/ssl.c
@@ -50,6 +50,7 @@
 #include "errlog.h"
 #include "jcc.h"
 #include "ssl.h"
+#include "encode.h"
 
 
 /*
@@ -162,7 +163,10 @@ extern int server_use_ssl(const struct client_state *csp)
  *
  * Function    :  is_ssl_pending
  *
- * Description :  Tests if there are some waiting data on ssl connection
+ * Description :  Tests if there are some waiting data on ssl connection.
+ *                Only considers data that has actually been received
+ *                locally and ignores data that is still on the fly
+ *                or has not yet been sent by the remote end.
  *
  * Parameters  :
  *          1  :  ssl = SSL context to test
@@ -256,6 +260,69 @@ extern int ssl_send_data(mbedtls_ssl_context *ssl, const unsigned char *buf, siz
 }
 
 
+/*********************************************************************
+ *
+ * Function    :  ssl_send_data_delayed
+ *
+ * Description :  Sends the contents of buf (for n bytes) to given SSL
+ *                connection, optionally delaying the operation.
+ *
+ * Parameters  :
+ *          1  :  ssl = SSL context to send data to
+ *          2  :  buf = Pointer to data to be sent
+ *          3  :  len = Length of data to be sent to the SSL context
+ *          4  :  delay = Delay in milliseconds.
+ *
+ * Returns     :  0 on success (entire buffer sent).
+ *                nonzero on error.
+ *
+ *********************************************************************/
+extern int ssl_send_data_delayed(mbedtls_ssl_context *ssl,
+                                 const unsigned char *buf, size_t len,
+                                 unsigned int delay)
+{
+   size_t i = 0;
+
+   if (delay == 0)
+   {
+      if (ssl_send_data(ssl, buf, len) < 0)
+      {
+         return -1;
+      }
+      else
+      {
+         return 0;
+      }
+   }
+
+   while (i < len)
+   {
+      size_t write_length;
+      enum { MAX_WRITE_LENGTH = 10 };
+
+      if ((i + MAX_WRITE_LENGTH) > len)
+      {
+         write_length = len - i;
+      }
+      else
+      {
+         write_length = MAX_WRITE_LENGTH;
+      }
+
+      privoxy_millisleep(delay);
+
+      if (ssl_send_data(ssl, buf + i, write_length) < 0)
+      {
+         return -1;
+      }
+      i += write_length;
+   }
+
+   return 0;
+
+}
+
+
 /*********************************************************************
  *
  * Function    :  ssl_recv_data
@@ -648,7 +715,7 @@ static void free_client_ssl_structures(struct client_state *csp)
 {
    /*
    * We can't use function mbedtls_net_free, because this function
-   * inter alia close TCP connection on setted fd. Instead of this
+   * inter alia close TCP connection on set fd. Instead of this
    * function, we change fd to -1, which is the same what does
    * rest of mbedtls_net_free function.
    */
@@ -828,6 +895,7 @@ extern int create_server_ssl_connection(struct client_state *csp)
          {
             log_error(LOG_LEVEL_ERROR,
                "mbedtls_ssl_handshake with server failed: %s", err_buf);
+            free_certificate_chain(csp);
             ret = -1;
          }
          goto exit;
@@ -907,7 +975,7 @@ static void free_server_ssl_structures(struct client_state *csp)
 {
    /*
    * We can't use function mbedtls_net_free, because this function
-   * inter alia close TCP connection on setted fd. Instead of this
+   * inter alia close TCP connection on set fd. Instead of this
    * function, we change fd to -1, which is the same what does
    * rest of mbedtls_net_free function.
    */
@@ -1992,7 +2060,7 @@ extern void ssl_send_certificate_error(struct client_state *csp)
    int ret = 0;
    struct certs_chain *cert = NULL;
 
-   /* Header of message with certificate informations */
+   /* Header of message with certificate information */
    const char message_begin[] =
       "HTTP/1.1 200 OK\r\n"
       "Content-Type: text/html\r\n"
@@ -2017,7 +2085,7 @@ extern void ssl_send_certificate_error(struct client_state *csp)
    {
       size_t base64_len = 4 * ((strlen(cert->file_buf) + 2) / 3) + 1;
 
-      message_len += strlen(cert->text_buf) + strlen("<pre></pre>\n")
+      message_len += strlen(cert->info_buf) + strlen("<pre></pre>\n")
                      +  base64_len + strlen("<a href=\"data:application"
                         "/x-x509-ca-cert;base64,\">Download certificate</a>");
       cert = cert->next;
@@ -2052,7 +2120,7 @@ extern void ssl_send_certificate_error(struct client_state *csp)
       }
 
       strlcat(message, "<pre>",        message_len);
-      strlcat(message, cert->text_buf, message_len);
+      strlcat(message, cert->info_buf, message_len);
       strlcat(message, "</pre>\n",     message_len);
 
       if (ret == 0)
@@ -2082,10 +2150,10 @@ extern void ssl_send_certificate_error(struct client_state *csp)
  * Function    :  ssl_verify_callback
  *
  * Description :  This is a callback function for certificate verification.
- *                It's called for all certificates in server certificate
- *                trusted chain and it's preparing information about this
- *                certificates. Prepared informations can be used to inform
- *                user about invalid certificates.
+ *                It's called once for each certificate in the server's
+ *                certificate trusted chain and prepares information about
+ *                the certificate. The information can be used to inform
+ *                the user about invalid certificates.
  *
  * Parameters  :
  *          1  :  csp_void = Current client state (buffers, headers, etc...)
@@ -2117,7 +2185,7 @@ static int ssl_verify_callback(void *csp_void, mbedtls_x509_crt *crt,
     */
    last->next = malloc_or_die(sizeof(struct certs_chain));
    last->next->next = NULL;
-   memset(last->next->text_buf, 0, sizeof(last->next->text_buf));
+   memset(last->next->info_buf, 0, sizeof(last->next->info_buf));
    memset(last->next->file_buf, 0, sizeof(last->next->file_buf));
 
    /*
@@ -2127,14 +2195,27 @@ static int ssl_verify_callback(void *csp_void, mbedtls_x509_crt *crt,
       crt->raw.p, crt->raw.len, (unsigned char *)last->file_buf,
       sizeof(last->file_buf)-1, &olen)) != 0)
    {
+      char err_buf[ERROR_BUF_SIZE];
+
+      mbedtls_strerror(ret, err_buf, sizeof(err_buf));
+      log_error(LOG_LEVEL_ERROR, "mbedtls_pem_write_buffer() failed: %s",
+         err_buf);
+
       return(ret);
    }
 
    /*
     * Saving certificate information into buffer
     */
-   mbedtls_x509_crt_info(last->text_buf, sizeof(last->text_buf) - 1,
-      CERT_INFO_PREFIX, crt);
+   {
+      char buf[CERT_INFO_BUF_SIZE];
+      char *encoded_text;
+
+      mbedtls_x509_crt_info(buf, sizeof(buf), CERT_INFO_PREFIX, crt);
+      encoded_text = html_encode(buf);
+      strlcpy(last->info_buf, encoded_text, sizeof(last->info_buf));
+      freez(encoded_text);
+   }
 
    return 0;
 }
@@ -2145,7 +2226,7 @@ static int ssl_verify_callback(void *csp_void, mbedtls_x509_crt *crt,
  * Function    :  free_certificate_chain
  *
  * Description :  Frees certificates linked list. This linked list is
- *                used to save informations about certificates in
+ *                used to save information about certificates in
  *                trusted chain.
  *
  * Parameters  :
@@ -2159,21 +2240,18 @@ static void free_certificate_chain(struct client_state *csp)
    struct certs_chain *cert = csp->server_certs_chain.next;
 
    /* Cleaning buffers */
-   memset(csp->server_certs_chain.text_buf, 0,
-      sizeof(csp->server_certs_chain.text_buf));
+   memset(csp->server_certs_chain.info_buf, 0,
+      sizeof(csp->server_certs_chain.info_buf));
    memset(csp->server_certs_chain.file_buf, 0,
       sizeof(csp->server_certs_chain.file_buf));
    csp->server_certs_chain.next = NULL;
 
    /* Freeing memory in whole linked list */
-   if (cert != NULL)
+   while (cert != NULL)
    {
-      do
-      {
-         struct certs_chain *cert_for_free = cert;
-         cert = cert->next;
-         freez(cert_for_free);
-      } while (cert != NULL);
+      struct certs_chain *cert_for_free = cert;
+      cert = cert->next;
+      freez(cert_for_free);
    }
 }
 
@@ -2251,7 +2329,7 @@ static int host_to_hash(struct client_state *csp)
  * Function    :  tunnel_established_successfully
  *
  * Description :  Check if parent proxy server response contains
- *                informations about successfully created connection with
+ *                information about successfully created connection with
  *                destination server. (HTTP/... 2xx ...)
  *
  * Parameters  :
diff --git a/ssl.h b/ssl.h
index 1c65182..f62f973 100644 (file)
--- a/ssl.h
+++ b/ssl.h
@@ -54,6 +54,8 @@ extern int tunnel_established_successfully(const char *response, unsigned int re
 
 /* Functions for sending and receiving data over TLS/SSL connections */
 extern int  ssl_send_data(mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len);
+extern int ssl_send_data_delayed(mbedtls_ssl_context *ssl, const unsigned char *buf,
+                                 size_t len, unsigned int delay);
 extern int  ssl_recv_data(mbedtls_ssl_context *ssl, unsigned char *buf, size_t maxLen);
 extern long ssl_flush_socket(mbedtls_ssl_context *ssl, struct iob *iob);
 extern void ssl_send_certificate_error(struct client_state *csp);
index d505b9e..b1d34d4 100644 (file)
@@ -297,7 +297,7 @@ strptime_internal (rp, fmt, tm, decided, era_cnt)
        }
 
       /* Any character but `%' must be matched by the same character
-        in the iput string.  */
+        in the input string.  */
       if (*fmt != '%')
        {
          match_char (*fmt++, *rp++);
index 5a10639..e3a240c 100644 (file)
@@ -6,7 +6,7 @@
 #                particular section in an actions file.
 #
 #
-# Copyright   :  Written by and Copyright (C) 2001-2014 the
+# Copyright   :  Written by and Copyright (C) 2001-2020 the
 #                Privoxy team. https://www.privoxy.org/
 #
 #                Original Author: Copyright (C) 2001 Jonathan Foster
@@ -957,6 +957,42 @@ function show_limit_connect_opts(tf)
         <input type="text" name="hide_user_agent_mode" size="40"
         value="@hide-user-agent-param@"></td>
     </tr>
+
+<!-- @if-https-inspection-start -->
+   <tr class="bg1" align="left" valign="top">
+      <td class="en1" align="center" valign="middle"><input type="radio"
+        name="https_inspection" value="Y" @https-inspection-y@
+        ></td>
+      <td class="dis1" align="center" valign="middle"><input type="radio"
+        name="https_inspection" value="N" @https-inspection-n@
+        ></td>
+      <td class="noc1" align="center" valign="middle"><input type="radio"
+        name="https_inspection" value="X" @https-inspection-x@
+        ></td>
+      <td class="action"><a href="@user-manual@@actions-help-prefix@HTTPS-INSPECTION">https-inspection</a></td>
+      <td>
+       Enable content and header filtering for https requests.
+     </td>
+    </tr>
+
+   <tr class="bg1" align="left" valign="top">
+      <td class="en1" align="center" valign="middle"><input type="radio"
+        name="ignore_certificate_errors" value="Y" @ignore-certificate-errors-y@
+        ></td>
+      <td class="dis1" align="center" valign="middle"><input type="radio"
+        name="ignore_certificate_errors" value="N" @ignore-certificate-errors-n@
+        ></td>
+      <td class="noc1" align="center" valign="middle"><input type="radio"
+        name="ignore_certificate_errors" value="X" @ignore-certificate-errors-x@
+        ></td>
+      <td class="action"><a href="@user-manual@@actions-help-prefix@IGNORE-CERTIFICATE-ERRORS">ignore-certificate-errors</a></td>
+      <td>
+       Don't verify certificates when forwarding encrypted requests.
+     </td>
+    </tr>
+
+<!-- if-https-inspection-end@ -->
+
     <tr class="bg1" align="left" valign="top">
       <td class="en1" align="center" valign="middle"><input type="radio"
         name="limit_connect" id="limit_connect_y" value="Y" @limit-connect-y@
index bb2dc91..0514a4a 100644 (file)
     </tr>
     <tr>
       <td class="box">
-<!-- @if-https-start -->
+<!-- @if-https-and-no-https-inspection-start -->
         <h2>NOTE:</h2>
         <p>This is a HTTPS URL, so the part after the "/" is ignored
           as Privoxy doesn't see the path for real HTTPS requests either.</p>
-<!-- if-https-end@ -->
+<!-- if-https-and-no-https-inspection-end@ -->
 <!-- if-valid-url-end@ -->
         <h2>Matches for <a href="@url@">@url@</a>:</h2>
         @matches@
index 9558544..90966a0 100755 (executable)
@@ -23,7 +23,7 @@
 #         hash key as input.
 #       - Add --compress and --decompress options.
 #
-# Copyright (c) 2007-2017 Fabian Keil <fk@fabiankeil.de>
+# Copyright (c) 2007-2020 Fabian Keil <fk@fabiankeil.de>
 #
 # Permission to use, copy, modify, and distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
@@ -43,7 +43,7 @@ use warnings;
 use Getopt::Long;
 
 use constant {
-    PRIVOXY_LOG_PARSER_VERSION => '0.9',
+    PRIVOXY_LOG_PARSER_VERSION => '0.9.1',
     # Feel free to mess with these ...
     DEFAULT_BACKGROUND => 'black',  # Choose registered colour (like 'black')
     DEFAULT_TEXT_COLOUR => 'white', # Choose registered colour (like 'black')
@@ -111,7 +111,7 @@ my $no_msecs_mode; # XXX: should probably be removed
 my $shorten_thread_ids;
 my $line_end;
 
-sub prepare_our_stuff () {
+sub prepare_our_stuff() {
 
     # Syntax Higlight hash
     @all_colours = (
@@ -219,7 +219,7 @@ sub prepare_our_stuff () {
     init_stats();
 }
 
-sub paint_it ($) {
+sub paint_it($) {
 ###############################################################
 # Takes a colour string and returns an ANSI escape sequence
 # (unless --no-syntax-highlighting is used).
@@ -296,7 +296,7 @@ sub paint_it ($) {
     return $colour_code;
 }
 
-sub get_semantic_html_markup ($) {
+sub get_semantic_html_markup($) {
 ###############################################################
 # Takes a string and returns a span element
 ###############################################################
@@ -314,7 +314,7 @@ sub get_semantic_html_markup ($) {
     return $code;
 }
 
-sub cli_option_is_set ($) {
+sub cli_option_is_set($) {
 
     our %cli_options;
     my $cli_option = shift;
@@ -324,7 +324,7 @@ sub cli_option_is_set ($) {
     return $cli_options{$cli_option};
 }
 
-sub get_html_title () {
+sub get_html_title() {
 
     our %cli_options;
     return $cli_options{'title'};
@@ -354,7 +354,7 @@ sub init_css_colours() {
     );
 }
 
-sub get_css_colour ($) {
+sub get_css_colour($) {
 
    our %css_colours;
    my $colour = shift;
@@ -364,7 +364,7 @@ sub get_css_colour ($) {
    return '#' . $css_colours{$colour};
 }
 
-sub get_css_line ($) {
+sub get_css_line($) {
 
     my $class = shift;
     my $css_line;
@@ -378,7 +378,7 @@ sub get_css_line ($) {
     return $css_line;
 }
 
-sub get_css_line_for_colour ($) {
+sub get_css_line_for_colour($) {
 
     my $colour = shift;
     my $css_line;
@@ -392,7 +392,7 @@ sub get_css_line_for_colour ($) {
 }
 
 # XXX: Wrong solution
-sub get_missing_css_lines () {
+sub get_missing_css_lines() {
 
     my $css_line;
 
@@ -404,7 +404,7 @@ sub get_missing_css_lines () {
     return $css_line;
 }
 
-sub get_css () {
+sub get_css() {
 
     our %css_colours; #XXX: Wrong solution
 
@@ -433,7 +433,7 @@ sub get_css () {
     return $css;
 }
 
-sub print_intro () {
+sub print_intro() {
 
     my $intro = '';
 
@@ -451,7 +451,7 @@ sub print_intro () {
     }
 }
 
-sub print_outro () {
+sub print_outro() {
 
     my $outro = '';
 
@@ -463,11 +463,11 @@ sub print_outro () {
     }
 }
 
-sub get_line_end () {
+sub get_line_end() {
     return cli_option_is_set('html-output') ? "<br>\n" : "\n";
 }
 
-sub get_colour_html_markup ($) {
+sub get_colour_html_markup($) {
 ###############################################################
 # Takes a colour string a span element. XXX: WHAT?
 # XXX: This function shouldn't be necessary, the
@@ -486,21 +486,21 @@ sub get_colour_html_markup ($) {
     return $code;
 }
 
-sub default_colours () {
+sub default_colours() {
     # XXX: Properly
     our $bg_code;
     return reset_colours();
 }
 
-sub show_colours () {
+sub show_colours() {
     # XXX: Implement
 }
 
-sub reset_colours () {
+sub reset_colours() {
     return ESCAPE . "0m";
 }
 
-sub set_background ($){
+sub set_background($) {
 
     my $colour = shift;
     our $bg_code;
@@ -523,11 +523,11 @@ sub set_background ($){
     }
 }
 
-sub get_background (){
+sub get_background() {
     return our $bg_code;
 }
 
-sub prepare_highlight_hash ($) {
+sub prepare_highlight_hash($) {
     my $ref = shift;
 
     foreach my $key (keys %$ref) {
@@ -537,7 +537,7 @@ sub prepare_highlight_hash ($) {
     }
 }
 
-sub prepare_colour_array ($) {
+sub prepare_colour_array($) {
     my $ref = shift;
 
     foreach my $i (0 ... @$ref - 1) {
@@ -547,7 +547,7 @@ sub prepare_colour_array ($) {
     }
 }
 
-sub found_unknown_content ($) {
+sub found_unknown_content($) {
 
     my $unknown = shift;
     my $message;
@@ -566,7 +566,7 @@ sub found_unknown_content ($) {
     die "Unworthy content parser" if PUNISH_MISSING_LOG_KNOWLEDGE_WITH_DEATH;
 }
 
-sub log_parse_error ($) {
+sub log_parse_error($) {
 
     my $message = shift;
 
@@ -577,7 +577,7 @@ sub log_parse_error ($) {
     }
 }
 
-sub debug_message (@) {
+sub debug_message(@) {
     my @message = @_;
 
     print $h{'debug'} . "@message" . $h{'Standard'} . "\n";
@@ -587,7 +587,7 @@ sub debug_message (@) {
 # highlighter functions that aren't loglevel-specific
 ################################################################################
 
-sub h ($) {
+sub h($) {
 
     # Get highlight marker
     my $highlight = shift; # XXX: Stupid name;
@@ -609,7 +609,7 @@ sub h ($) {
     return $result;
 }
 
-sub highlight_known_headers ($) {
+sub highlight_known_headers($) {
 
     my $content = shift;
 
@@ -624,7 +624,7 @@ sub highlight_known_headers ($) {
     return $content;
 }
 
-sub highlight_matched_request_line ($$) {
+sub highlight_matched_request_line($$) {
 
     my $result = shift; # XXX: Stupid name;
     my $regex = shift;
@@ -634,7 +634,7 @@ sub highlight_matched_request_line ($$) {
     return $result;
 }
 
-sub highlight_request_line ($) {
+sub highlight_request_line($) {
 
     my $rl = shift;
     my ($method, $url, $http_version);
@@ -675,7 +675,7 @@ sub highlight_request_line ($) {
     return $rl;
 }
 
-sub highlight_response_line ($) {
+sub highlight_response_line($) {
 
     my $rl = shift;
     my ($http_version, $status_code, $status_message);
@@ -702,7 +702,7 @@ sub highlight_response_line ($) {
     return $rl;
 }
 
-sub highlight_matched_url ($$) {
+sub highlight_matched_url($$) {
 
     my $result = shift; # XXX: Stupid name;
     my $regex = shift;
@@ -717,7 +717,7 @@ sub highlight_matched_url ($$) {
     return $result;
 }
 
-sub highlight_matched_host ($$) {
+sub highlight_matched_host($$) {
 
     my ($result, $regex) = @_; # XXX: result ist stupid name;
 
@@ -728,7 +728,7 @@ sub highlight_matched_host ($$) {
     return $result;
 }
 
-sub highlight_matched_pattern ($$$) {
+sub highlight_matched_pattern($$$) {
 
     my $result = shift; # XXX: Stupid name;
     my $key = shift;
@@ -743,7 +743,7 @@ sub highlight_matched_pattern ($$$) {
     return $result;
 }
 
-sub highlight_matched_path ($$) {
+sub highlight_matched_path($$) {
 
     my $result = shift; # XXX: Stupid name;
     my $regex = shift;
@@ -755,7 +755,7 @@ sub highlight_matched_path ($$) {
     return $result;
 }
 
-sub highlight_url ($) {
+sub highlight_url($) {
 
     my $url = shift;
 
@@ -772,7 +772,7 @@ sub highlight_url ($) {
     return $url;
 }
 
-sub update_header_highlight_regex ($) {
+sub update_header_highlight_regex($) {
 
     my $header = shift;
     my $headers = join ('|', keys %header_colours);
@@ -785,7 +785,7 @@ sub update_header_highlight_regex ($) {
 # loglevel-specific highlighter functions
 ################################################################################
 
-sub handle_loglevel_header ($) {
+sub handle_loglevel_header($) {
 
     my $c = shift;
 
@@ -1037,7 +1037,7 @@ sub handle_loglevel_header ($) {
     return $c;
 }
 
-sub handle_loglevel_re_filter ($) {
+sub handle_loglevel_re_filter($) {
 
     my $content = shift;
     my $c = $content;
@@ -1219,7 +1219,7 @@ sub handle_loglevel_re_filter ($) {
     return $content;
 }
 
-sub handle_loglevel_redirect ($) {
+sub handle_loglevel_redirect($) {
 
     my $c = shift;
 
@@ -1285,7 +1285,7 @@ sub handle_loglevel_redirect ($) {
     return $c;
 }
 
-sub handle_loglevel_gif_deanimate ($) {
+sub handle_loglevel_gif_deanimate($) {
 
     my $content = shift;
 
@@ -1331,7 +1331,7 @@ sub handle_loglevel_gif_deanimate ($) {
     return $content;
 }
 
-sub handle_loglevel_request ($) {
+sub handle_loglevel_request($) {
 
     my $content = shift;
 
@@ -1366,7 +1366,7 @@ sub handle_loglevel_request ($) {
     return $content;
 }
 
-sub handle_loglevel_crunch ($) {
+sub handle_loglevel_crunch($) {
 
     my $content = shift;
 
@@ -1390,7 +1390,7 @@ sub handle_loglevel_crunch ($) {
     return $content;
 }
 
-sub handle_loglevel_connect ($) {
+sub handle_loglevel_connect($) {
 
     my $c = shift;
 
@@ -1735,6 +1735,17 @@ sub handle_loglevel_connect ($) {
         $c =~ s@(?<=Shifting )(\d+)@$h{'Number'}$1$h{'Standard'}@;
         $c =~ s@(?<=by )(\d+)@$h{'Number'}$1$h{'Standard'}@;
 
+    } elsif ($c =~ m/^Flushed (\d+) bytes of request body while expecting (\d+)/) {
+
+        # Flushed 30 bytes of request body while expecting 30
+        $c =~ s@(?<=Flushed )(\d+)@$h{'Number'}$1$h{'Standard'}@;
+        $c =~ s@(?<=expecting )(\d+)@$h{'Number'}$1$h{'Standard'}@;
+
+    } elsif ($c =~ m/^Performing the TLS\/SSL handshake with client. Hash of host:/) {
+
+        # Performing the TLS/SSL handshake with client. Hash of host: bab5296b25e256c7b06b92b17b56bcae
+        $c = highlight_matched_host($c, '(?<=Hash of host: ).+');
+
     } elsif ($c =~ m/^Looks like we / or
              $c =~ m/^Unsetting keep-alive flag/ or
              $c =~ m/^No connections to wait/ or
@@ -1776,7 +1787,7 @@ sub handle_loglevel_connect ($) {
 }
 
 
-sub handle_loglevel_info ($) {
+sub handle_loglevel_info($) {
 
     my $c = shift;
 
@@ -1902,7 +1913,7 @@ sub handle_loglevel_info ($) {
     return $c;
 }
 
-sub handle_loglevel_cgi ($) {
+sub handle_loglevel_cgi($) {
 
     my $c = shift;
 
@@ -1924,7 +1935,7 @@ sub handle_loglevel_cgi ($) {
     return $c;
 }
 
-sub handle_loglevel_force ($) {
+sub handle_loglevel_force($) {
 
     my $c = shift;
 
@@ -1948,7 +1959,7 @@ sub handle_loglevel_force ($) {
     return $c;
 }
 
-sub handle_loglevel_error ($) {
+sub handle_loglevel_error($) {
 
     my $c = shift;
 
@@ -1976,11 +1987,45 @@ sub handle_loglevel_error ($) {
 }
 
 
-sub handle_loglevel_ignore ($) {
+sub handle_loglevel_ignore($) {
     return shift;
 }
 
-sub gather_loglevel_request_stats ($$) {
+sub gather_loglevel_clf_stats($) {
+
+    my $content = shift;
+    my ($method, $resource, $http_version, $status_code, $size);
+    our %stats;
+    our %cli_options;
+
+    # +0200] "GET https://www.youtube.com/watch?v=JmcA9LIIXWw HTTP/1.1" 200 68004
+    $content =~ m/^[+-]\d{4}\] "(\w+) (.+) (HTTP\/\d\.\d)" (\d+) (\d+)/;
+    $method       = $1;
+    $resource     = $2;
+    $http_version = $3;
+    $status_code  = $4;
+    $size         = $5;
+
+    unless (defined $method) {
+        print("Failed to parse: $content\n");
+        return;
+    }
+    $stats{'method'}{$method}++;
+    if ($cli_options{'url-statistics-threshold'} != 0) {
+        $stats{'resource'}{$resource}++;
+    }
+    $stats{'http-version'}{$http_version}++;
+
+    if ($cli_options{'host-statistics-threshold'} != 0) {
+        $resource =~ m@(?:http[s]://)([^/]+)/?@;
+        $stats{'hosts'}{$1}++;
+    }
+    $stats{'content-size-total'} += $size;
+    $stats{'status-code'}{$status_code}++;
+    $stats{requests_clf}++;
+}
+
+sub gather_loglevel_request_stats($$) {
     my $c = shift;
     my $thread = shift;
     our %stats;
@@ -1988,12 +2033,11 @@ sub gather_loglevel_request_stats ($$) {
     $stats{requests}++;
 }
 
-sub gather_loglevel_crunch_stats ($$) {
+sub gather_loglevel_crunch_stats($$) {
     my $c = shift;
     my $thread = shift;
     our %stats;
 
-    $stats{requests}++;
     $stats{crunches}++;
 
     if ($c =~ m/^Redirected:/) {
@@ -2015,7 +2059,7 @@ sub gather_loglevel_crunch_stats ($$) {
 }
 
 
-sub gather_loglevel_error_stats ($$) {
+sub gather_loglevel_error_stats($$) {
 
     my $c = shift;
     my $thread = shift;
@@ -2034,7 +2078,7 @@ sub gather_loglevel_error_stats ($$) {
     }
 }
 
-sub gather_loglevel_connect_stats ($$) {
+sub gather_loglevel_connect_stats($$) {
 
     my ($c, $thread) = @_;
     our %thread_data;
@@ -2076,7 +2120,7 @@ sub gather_loglevel_connect_stats ($$) {
     }
 }
 
-sub gather_loglevel_header_stats ($$) {
+sub gather_loglevel_header_stats($$) {
 
     my ($c, $thread) = @_;
     our %stats;
@@ -2088,27 +2132,13 @@ sub gather_loglevel_header_stats ($$) {
         # A HTTP/1.1 response without Connection header implies keep-alive.
         # Keeping the server header 'Connection: keep-alive' around.
         $stats{'server-keep-alive'}++;
-
-    } elsif ($c =~ m/^scan: ((\w+) (.+) (HTTP\/\d\.\d))/) {
-
-        # scan: HTTP/1.1 200 OK
-        $stats{'method'}{$2}++;
-        if ($cli_options{'url-statistics-threshold'} != 0) {
-            $stats{'resource'}{$3}++;
-        }
-        $stats{'http-version'}{$4}++;
-
-    } elsif ($cli_options{'host-statistics-threshold'} != 0 and
-             $c =~ m/^scan: Host: ([^\s]+)/) {
-
-        # scan: Host: p.p
-        $stats{'hosts'}{$1}++;
     }
 }
 
-sub init_stats () {
+sub init_stats() {
     our %stats = (
         requests => 0,
+        requests_clf => 0,
         crunches => 0,
         'server-keep-alive' => 0,
         'reused-connections' => 0,
@@ -2122,11 +2152,12 @@ sub init_stats () {
         'reused-connections' => 0,
         'server-keep-alive' => 0,
         'closed-client-connections' => 0,
+        'content-size-total' => 0,
         );
         $stats{'client-requests-on-connection'}{1} = 0;
 }
 
-sub get_percentage ($$) {
+sub get_percentage($$) {
     my $big = shift;
     my $small = shift;
 
@@ -2141,32 +2172,45 @@ sub get_percentage ($$) {
     return sprintf("%.2f%%", $small / $big * 100);
 }
 
-sub print_stats () {
+sub print_stats() {
 
     our %stats;
     our %cli_options;
     my $new_connections = $stats{requests} - $stats{crunches} - $stats{'reused-connections'};
-    my $outgoing_requests = $stats{requests} - $stats{crunches};
     my $client_requests_checksum = 0;
 
+    if ($stats{requests_clf} && $stats{requests}
+        && $stats{requests_clf} != $stats{requests}) {
+        print "Inconsistent request counts: " . $stats{requests} . "/" . $stats{requests_clf} . "\n";
+    }
+    if ($stats{requests_clf} && $stats{requests} eq 0) {
+        $stats{requests} = $stats{requests_clf};
+    }
+
     if ($stats{requests} eq 0) {
         print "No requests yet.\n";
         return;
     }
 
     print "Client requests total: " . $stats{requests} . "\n";
-    print "Crunches: " . $stats{crunches} . " (" .
-        get_percentage($stats{requests}, $stats{crunches}) . ")\n";
-    print "Blocks: " . $stats{'blocked'} . " (" .
-        get_percentage($stats{requests}, $stats{'blocked'}) . ")\n";
-    print "Fast redirections: " . $stats{'fast-redirections'} . " (" .
-        get_percentage($stats{requests}, $stats{'fast-redirections'}) . ")\n";
-    print "Connection timeouts: " . $stats{'connection-timeout'} . " (" .
-        get_percentage($stats{requests}, $stats{'connection-timeout'}) . ")\n";
-    print "Connection failures: " . $stats{'connection-failure'} . " (" .
-        get_percentage($stats{requests}, $stats{'connection-failure'}) . ")\n";
-    print "Outgoing requests: " . $outgoing_requests . " (" .
-        get_percentage($stats{requests}, $outgoing_requests) . ")\n";
+    if ($stats{crunches}) {
+        my $outgoing_requests = $stats{requests} - $stats{crunches};
+        print "Crunches: " . $stats{crunches} . " (" .
+            get_percentage($stats{requests}, $stats{crunches}) . ")\n";
+        print "Blocks: " . $stats{'blocked'} . " (" .
+            get_percentage($stats{requests}, $stats{'blocked'}) . ")\n";
+        print "Fast redirections: " . $stats{'fast-redirections'} . " (" .
+            get_percentage($stats{requests}, $stats{'fast-redirections'}) . ")\n";
+        print "Connection timeouts: " . $stats{'connection-timeout'} . " (" .
+            get_percentage($stats{requests}, $stats{'connection-timeout'}) . ")\n";
+        print "Connection failures: " . $stats{'connection-failure'} . " (" .
+            get_percentage($stats{requests}, $stats{'connection-failure'}) . ")\n";
+        print "Outgoing requests: " . $outgoing_requests . " (" .
+            get_percentage($stats{requests}, $outgoing_requests) . ")\n";
+    } else {
+        print "No crunches detected. Is 'debug 1024' enabled?\n";
+    }
+
     print "Server keep-alive offers: " . $stats{'server-keep-alive'} . " (" .
         get_percentage($stats{requests}, $stats{'server-keep-alive'}) . ")\n";
     print "New outgoing connections: " . $new_connections . " (" .
@@ -2186,7 +2230,9 @@ sub print_stats () {
         get_percentage($stats{requests}, $stats{'empty-responses-on-reused-connections'}) .
         ")\n";
     print "Client connections: " .  $stats{'closed-client-connections'} . "\n";
-
+    if ($stats{'content-size-total'}) {
+        print "Bytes transfered excluding headers: " .  $stats{'content-size-total'} . "\n";
+    }
     my $lines_printed = 0;
     print "Client requests per connection distribution:\n";
     foreach my $client_requests (sort {
@@ -2213,11 +2259,23 @@ sub print_stats () {
             printf "%8d : %-8s\n", $stats{'method'}{$method}, $method;
         }
     } else {
-        print "Method distribution unknown. No response headers parsed yet. Is 'debug 8' enabled?\n";
+        print "Method distribution unknown. No CLF message parsed yet. Is 'debug 512' enabled?\n";
+    }
+    if (exists $stats{'http-version'}) {
+        print "Client HTTP versions:\n";
+        foreach my $http_version (sort {$stats{'http-version'}{$b} <=> $stats{'http-version'}{$a}} keys %{$stats{'http-version'}}) {
+            printf "%8d : %-8s\n",  $stats{'http-version'}{$http_version}, $http_version;
+        }
+    } else {
+        print "HTTP version distribution unknown. No CLF message parsed yet. Is 'debug 512' enabled?\n";
     }
-    print "Client HTTP versions:\n";
-    foreach my $http_version (sort {$stats{'http-version'}{$b} <=> $stats{'http-version'}{$a}} keys %{$stats{'http-version'}}) {
-        printf "%d : %s\n",  $stats{'http-version'}{$http_version}, $http_version;
+    if (exists $stats{'status-code'}) {
+        print "HTTP status codes:\n";
+        foreach my $status_code (sort {$stats{'status-code'}{$b} <=> $stats{'status-code'}{$a}} keys %{$stats{'status-code'}}) {
+            printf "%8d : %-8d\n",  $stats{'status-code'}{$status_code}, $status_code;
+        }
+    } else {
+        print "Status code distribution unknown. No CLF message parsed yet. Is 'debug 512' enabled?\n";
     }
 
     if ($cli_options{'url-statistics-threshold'} == 0) {
@@ -2252,7 +2310,7 @@ sub print_stats () {
 # Functions that actually print stuff
 ################################################################################
 
-sub print_clf_message () {
+sub print_clf_message() {
 
     our ($ip, $timestamp, $request_line, $status_code, $size);
     my $output = '';
@@ -2274,7 +2332,7 @@ sub print_clf_message () {
     print $output;
 }
 
-sub print_non_clf_message ($) {
+sub print_non_clf_message($) {
 
     my $content = shift;
     my $msec_string = $no_msecs_mode ? '' : '.' . $req{$t}{'msecs'};
@@ -2299,7 +2357,7 @@ sub print_non_clf_message ($) {
         . $line_end;
 }
 
-sub shorten_thread_id ($) {
+sub shorten_thread_id($) {
 
     my $thread_id = shift;
 
@@ -2313,7 +2371,7 @@ sub shorten_thread_id ($) {
     return $short_thread_ids{$thread_id}
 }
 
-sub parse_loop () {
+sub parse_loop() {
 
     my ($day, $time_stamp, $thread, $log_level, $content, $c, $msecs);
     my $last_msecs  = 0;
@@ -2413,7 +2471,7 @@ sub parse_loop () {
     }
 }
 
-sub stats_loop () {
+sub stats_loop() {
 
     my ($day, $time_stamp, $msecs, $thread, $log_level, $content);
     my $strict_checks = cli_option_is_set('strict-checks');
@@ -2441,10 +2499,14 @@ sub stats_loop () {
     while (<>) {
         (undef, $time_stamp, $thread, $log_level, $content) = split(/ /, $_, 5);
 
-        # Skip LOG_LEVEL_CLF
-        next if (not defined($log_level) or $time_stamp eq "-");
 
-        if (defined($log_level_handlers{$log_level})) {
+        next if (not defined($log_level));
+
+        if ($time_stamp eq "-") {
+
+            gather_loglevel_clf_stats($content);
+
+        } elsif (defined($log_level_handlers{$log_level})) {
 
             $content = $log_level_handlers{$log_level}($content, $thread);
 
@@ -2491,7 +2553,7 @@ sub VersionMessage {
     print $version_message;
 }
 
-sub get_cli_options () {
+sub get_cli_options() {
 
     our %cli_options = (
         'html-output'              => CLI_OPTION_DEFAULT_TO_HTML_OUTPUT,
@@ -2533,7 +2595,7 @@ sub get_cli_options () {
    $line_end = get_line_end();
 }
 
-sub help () {
+sub help() {
 
     our %cli_options;
 
@@ -2564,7 +2626,7 @@ see "perldoc $0" for more information
 ################################################################################
 # main
 ################################################################################
-sub main () {
+sub main() {
 
     get_cli_options();
     set_background(DEFAULT_BACKGROUND);
index 17ad75e..f93ffb5 100755 (executable)
@@ -1924,7 +1924,7 @@ is likely to get lost with the next update.
 
 Overwrite conditions are an alternative and can be added in any action
 file as long as the come after the test that is expected to fail.
-They causes all previous tests a matching the condition to be skipped.
+They cause all previous tests that match the condition to be skipped.
 
 It is recommended to put the overwrite condition below the custom Privoxy
 section that causes the expected test failure and before the custom test
index d953263..6949eed 100644 (file)
@@ -87,7 +87,7 @@ void free_http_request(struct http_request *http)
    freez(http->url);
    freez(http->hostport);
    freez(http->path);
-   freez(http->ver);
+   freez(http->version);
    freez(http->host_ip_addr_str);
 #ifndef FEATURE_EXTENDED_HOST_PATTERNS
    freez(http->dbuffer);
@@ -291,12 +291,17 @@ jb_err parse_http_url(const char *url, struct http_request *http, int require_pr
          /*
           * Got a path.
           *
-          * NOTE: The following line ignores the path for HTTPS URLS.
-          * This means that you get consistent behaviour if you type a
-          * https URL in and it's parsed by the function.  (When the
-          * URL is actually retrieved, SSL hides the path part).
+          * If FEATURE_HTTPS_INSPECTION isn't available, ignore the
+          * path for https URLs so that we get consistent behaviour
+          * if a https URL is parsed. When the URL is actually
+          * retrieved, https hides the path part.
           */
-         http->path = strdup_or_die(http->ssl ? "/" : url_path);
+         http->path = strdup_or_die(
+#ifndef FEATURE_HTTPS_INSPECTION
+            http->ssl ? "/" :
+#endif
+            url_path
+         );
          *url_path = '\0';
          http->hostport = strdup_or_die(url_noproto);
       }
@@ -587,7 +592,7 @@ jb_err parse_http_request(const char *req, struct http_request *http)
     */
    http->cmd = strdup_or_die(req);
    http->gpc = strdup_or_die(v[0]);
-   http->ver = strdup_or_die(v[2]);
+   http->version = strdup_or_die(v[2]);
    http->ocmd = strdup_or_die(http->cmd);
 
    freez(buf);
index a26569f..b60eae7 100644 (file)
--- a/w32log.c
+++ b/w32log.c
@@ -3,7 +3,7 @@
  * File        :  $Source: /cvsroot/ijbswa/current/w32log.c,v $
  *
  * Purpose     :  Functions for creating and destroying the log window,
- *                ouputting strings, processing messages and so on.
+ *                outputting strings, processing messages and so on.
  *
  * Copyright   :  Written by and Copyright (C) 2001-2009 members of
  *                the Privoxy team.  https://www.privoxy.org/
index 1507352..1c80c09 100644 (file)
--- a/w32log.h
+++ b/w32log.h
@@ -5,7 +5,7 @@
  * File        :  $Source: /cvsroot/ijbswa/current/w32log.h,v $
  *
  * Purpose     :  Functions for creating and destroying the log window,
- *                ouputting strings, processing messages and so on.
+ *                outputting strings, processing messages and so on.
  *
  * Copyright   :  Written by and Copyright (C) 2001-2009 members of
  *                the Privoxy team.  https://www.privoxy.org/
diff --git a/win32.c b/win32.c
index ecfb63a..201d8da 100644 (file)
--- a/win32.c
+++ b/win32.c
@@ -163,7 +163,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
 #if 0
    /*
     * Cheat in parsing the command line.  We only ever have at most one
-    * paramater, which may optionally be specified inside double quotes.
+    * parameter, which may optionally be specified inside double quotes.
     */
 
    if (lpCmdLine != NULL)