Add documentation for the client-body-tagger action
[privoxy.git] / doc / source / user-manual.sgml
index d1b597f..90702c4 100644 (file)
 <!entity p-authors SYSTEM "p-authors.sgml">
 <!entity config SYSTEM "p-config.sgml">
 <!entity changelog SYSTEM "changelog.sgml">
-<!entity p-version "3.0.29">
-<!entity p-status "stable">
+<!entity p-version "3.0.34">
+<!entity p-status "UNRELEASED">
 <!entity % p-authors-formal "INCLUDE"> <!-- include additional text, etc  -->
-<!entity % p-not-stable "IGNORE">
-<!entity % p-stable "INCLUDE">
+<!entity % p-not-stable "INCLUDE">
+<!entity % p-stable "IGNORE">
 <!entity % p-text "IGNORE">        <!-- define we are not a text only doc -->
 <!entity % p-doc "INCLUDE">        <!-- and we are a formal doc           -->
 <!entity % p-readme "IGNORE">
@@ -35,7 +35,7 @@
 
  Purpose     :  user manual
 
- Copyright (C) 2001-2020 Privoxy Developers https://www.privoxy.org/
+ Copyright (C) 2001-2021 Privoxy Developers https://www.privoxy.org/
  See LICENSE.
 
  ========================================================================
@@ -54,7 +54,7 @@
  <subscript>
 <!-- Completely the wrong markup, but very little is allowed  -->
 <!-- in this part of an article. FIXME -->
- <link linkend="copyright">Copyright</link> &my-copy; 2001-2020 by
+ <link linkend="copyright">Copyright</link> &my-copy; 2001-2021 by
  <ulink url="https://www.privoxy.org/">Privoxy Developers</ulink>
  </subscript>
 </pubdate>
@@ -342,42 +342,42 @@ How to install the binary packages depends on your operating system:
         Run the setup program and from View / Category select:
       </para>
       <screen>
-  Devel
-    autoconf 2.5
-    automake 1.15
-    binutils
-    cmake
-    gcc-core
-    gcc-g++
-    git
-    make
-    mingw64-i686-gcc-core
-    mingw64-i686-zlib
-  Editors
-    vim
-  Libs
-    libxslt: GNOME XSLT library (runtime)
-  Net
-    curl
-    openssh
-  Text
-    docbook-dssl
-    docbook-sgml31
-    docbook-utils
-    openjade
-  Utils
-    gnupg
-  Web
-    w3m
+Devel
+  autoconf 2.5
+  automake 1.15
+  binutils
+  cmake
+  gcc-core
+  gcc-g++
+  git
+  make
+  mingw64-i686-gcc-core
+  mingw64-i686-zlib
+Editors
+  vim
+Libs
+  libxslt: GNOME XSLT library (runtime)
+Net
+  curl
+  openssh
+Text
+  docbook-dssl
+  docbook-sgml31
+  docbook-utils
+  openjade
+Utils
+  gnupg
+Web
+  w3m
 </screen>
 
       <para>
         If you haven't already downloaded the Privoxy source code, get it now:
       </para>
       <screen>
-  mkdir &lt;root-dir>
-  cd &lt;root-dir>
-  git clone https://www.privoxy.org/git/privoxy.git
+mkdir &lt;root-dir>
+cd &lt;root-dir>
+git clone https://www.privoxy.org/git/privoxy.git
 </screen>
 
       <para>
@@ -387,10 +387,10 @@ How to install the binary packages depends on your operating system:
         unzip into &lt;root-dir> and build the software:
       </para>
       <screen>
-  cd &lt;root-dir>
-  cd tidy-html5-x.y.z/build/cmake
-  cmake ../.. -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIB:BOOL=OFF -DCMAKE_INSTALL_PREFIX=/usr/local
-  make && make install
+cd &lt;root-dir>
+cd tidy-html5-x.y.z/build/cmake
+cmake ../.. -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIB:BOOL=OFF -DCMAKE_INSTALL_PREFIX=/usr/local
+make && make install
 </screen>
 
       <para>
@@ -398,14 +398,93 @@ How to install the binary packages depends on your operating system:
             <!-- FIXME:  which version(s) are known to work? -->
         <ulink url="https://sourceforge.net/projects/nsis/files/NSIS%203/">
                     https://sourceforge.net/projects/nsis/files/NSIS%203/</ulink>
-        and extract the NSIS directory to <literal>privoxy/windows</literal>.
-        Then edit the windows/GNUmakefile to set the location of the NSIS executable - eg:
+        and extract the NSIS directory to <literal>/&lt;root-dir>/nsis/</literal>.
+        Then edit the <filename>windows/GNUmakefile</filename> to set the location
+        of the NSIS executable - eg:
       </para>
       <screen>
 # Path to NSIS
-MAKENSIS = ./nsis/makensis.exe
+MAKENSIS = /&lt;root-dir>/nsis/makensis.exe
 </screen>
 
+      <para>
+        Get the latest 8.x PCRE code from
+        <ulink url="https://ftp.pcre.org/pub/pcre/">PCRE
+                    https://ftp.pcre.org/pub/pcre/</ulink>
+        and build the static PCRE libraries with
+
+        <screen>
+export CFLAGS="-O2 -fstack-protector-strong -D_FORTIFY_SOURCE=2"
+export LDFLAGS="-fstack-protector-strong"
+export CPPFLAGS="-DPCRE_STATIC"
+
+./configure  --host=i686-w64-mingw32 \
+             --prefix=/usr/local/i686-w64-mingw32 \
+             --enable-utf  --enable-unicode-properties \
+             --enable-jit \
+             --enable-newline-is-anycrlf \
+             --enable-pcre16 \
+             --enable-pcre32 \
+             --disable-pcregrep-libbz2 \
+             --disable-pcregrep-libz \
+             --disable-pcretest-libreadline \
+             --disable-stack-for-recursion  \
+             --enable-static --disable-shared \
+  &&  make
+</screen>
+      </para>
+
+
+      <para>
+        If you want to be able to have Privoxy do TLS Inspection, get the latest
+        2.16.x MBED-TLS library source code from
+        <ulink url="https://github.com/ARMmbed/mbedtls/tags">
+                    https://github.com/ARMmbed/mbedtls/tags</ulink>,
+        extract the tar file into <literal>&lt;root-dir&gt;</literal>
+        and build the static libraries with
+        <programlisting>
+export WINDOWS_BUILD=1
+#  build for a Windows platform
+
+unset DEBUG
+
+export CC=i686-w64-mingw32-gcc
+export LD=i686-w64-mingw32-gcc
+export CFLAGS="-O2 -fstack-protector-strong -D_FORTIFY_SOURCE=2"
+export LDFLAGS="${LDFLAGS} -fstack-protector-strong"
+
+make lib
+#  build the libraries
+</programlisting>
+      </para>
+
+
+      <para>
+        Get the brotli library from
+        <ulink url="https://github.com/google/brotli/releases">
+                    https://github.com/google/brotli/releases</ulink>
+        and build the static libraries with
+        <programlisting>
+./bootstrap
+#  to create the GNU autotools files
+
+autoconf
+
+export CFLAGS="-O2 -fstack-protector-strong -D_FORTIFY_SOURCE=2"
+export LDFLAGS="${LDFLAGS} -fstack-protector-strong"
+
+./configure  --host=i686-w64-mingw32 \
+             --prefix=/usr/local/i686-w64-mingw32 \
+             --enable-static   \
+             --disable-shared  \
+             --with-gnu-ld     \
+             --disable-silent-rules \
+  && make
+</programlisting>
+      </para>
+
+
+
       </sect4>
 
       <sect4 id="WINBUILD-BUILD"><title>Build</title>
@@ -414,8 +493,8 @@ MAKENSIS = ./nsis/makensis.exe
         To build just the Privoxy executable and not the whole installation package, do:
       </para>
       <programlisting>
-  cd &lt;root-dir>/privoxy
-  ./windows/MYconfigure && make
+cd &lt;root-dir>/privoxy
+./windows/MYconfigure && make
 </programlisting>
 
       <para>
@@ -423,10 +502,10 @@ MAKENSIS = ./nsis/makensis.exe
         for building software, so the process is:
       </para>
       <programlisting>
-  $ autoheader              # creates config.h.in
-  $ autoconf                # uses config.h.in to create the configure shell script
-  $ ./configure [options]   # creates GNUmakefile
-  $ make        [options]   # builds the program
+autoheader              # creates config.h.in
+autoconf                # uses config.h.in to create the configure shell script
+./configure [options]   # creates GNUmakefile
+make        [options]   # builds the program
 </programlisting>
 
       <para>
@@ -439,7 +518,8 @@ MAKENSIS = ./nsis/makensis.exe
   --enable-zlib
   --enable-static-linking
   --disable-pthread
-  --disable-dynamic-pcre
+  --with-brotli
+  --with-mbedtls
 </literallayout>
 
       <para>
@@ -448,11 +528,11 @@ MAKENSIS = ./nsis/makensis.exe
       </para>
 
       <programlisting>
-  $ export CFLAGS="-O2"              # set gcc optimization level
-  $ export LDFLAGS="-Wl,--nxcompat"  # Enable DEP
-  $ ./configure --host=i686-w64-mingw32 --enable-mingw32  --enable-zlib \
-  >             --enable-static-linking --disable-pthread --disable-dynamic-pcre
-  $ make                             # build Privoxy
+$ export CFLAGS="-O2"              # set gcc optimization level
+$ export LDFLAGS="-Wl,--nxcompat"  # Enable DEP
+$ ./configure --host=i686-w64-mingw32 --enable-mingw32  --enable-zlib \
+>             --enable-static-linking --disable-pthread
+$ make                             # build Privoxy
 </programlisting>
 
       <para>
@@ -592,8 +672,9 @@ MAKENSIS = ./nsis/makensis.exe
     use, filtering, you will need to force compression off. Example:
    </para>
  <screen>
-  { +<link linkend="filter">filter</link>{google}  +<link linkend="prevent-compression">prevent-compression</link> }
-   .google.</screen>
+{ +<link linkend="filter">filter</link>{google}  +<link linkend="prevent-compression">prevent-compression</link> }
+.google.
+</screen>
    <para>
     Or if you use a number of filters, or filter many sites, you may just want
     to turn off compression for all sites in
@@ -1134,7 +1215,7 @@ MAKENSIS = ./nsis/makensis.exe
  file.
 </para>
  <screen>
- # /etc/init.d/privoxy start
+# /etc/init.d/privoxy start
 </screen>
 </sect2>
 
@@ -1155,7 +1236,7 @@ MAKENSIS = ./nsis/makensis.exe
  To start <application>Privoxy</application> manually, run:
 </para>
  <screen>
- # service privoxy onestart
+# service privoxy onestart
 </screen>
 </sect2>
 
@@ -1183,7 +1264,7 @@ Click on the &my-app; Icon to start <application>Privoxy</application>. If no co
 Example Unix startup command:
 </para>
  <screen>
- # /usr/sbin/privoxy --user privoxy /etc/privoxy/config
+# /usr/sbin/privoxy --user privoxy /etc/privoxy/config
 </screen>
 <para>
  Note that if you installed <application>Privoxy</application> through
@@ -2002,12 +2083,13 @@ for details.
  might look like:
 </para>
 
- <screen>
-  { +<literal>handle-as-image</literal>  +<literal>block{Banner ads.}</literal> }
-  # Block these as if they were images. Send no block page.
-   banners.example.com
-   media.example.com/.*banners
-   .example.com/images/ads/</screen>
+<screen>
+{ +<literal>handle-as-image</literal>  +<literal>block{Banner ads.}</literal> }
+# Block these as if they were images. Send no block page.
+banners.example.com
+media.example.com/.*banners
+.example.com/images/ads/
+</screen>
 
 <para>
  You can trace this process for URL patterns and any given URL by visiting <ulink
@@ -2545,8 +2627,9 @@ example.org/blocked-example-page</screen>
    <quote>disabled</quote>. Syntax:
   </para>
    <screen>
-  +<replaceable class="function">name</replaceable>        # enable action <replaceable class="parameter">name</replaceable>
-  -<replaceable class="function">name</replaceable>        # disable action <replaceable class="parameter">name</replaceable></screen>
++<replaceable class="function">name</replaceable>        # enable action <replaceable class="parameter">name</replaceable>
+-<replaceable class="function">name</replaceable>        # disable action <replaceable class="parameter">name</replaceable>
+</screen>
   <para>
    Example: <literal>+handle-as-image</literal>
   </para>
@@ -2558,10 +2641,11 @@ example.org/blocked-example-page</screen>
    Parameterized, where some value is required in order to enable this type of action.
    Syntax:
   </para>
-   <screen>
-  +<replaceable class="function">name</replaceable>{<replaceable class="parameter">param</replaceable>}  # enable action and set parameter to <replaceable class="parameter">param</replaceable>,
-               # overwriting parameter from previous match if necessary
-  -<replaceable class="function">name</replaceable>         # disable action. The parameter can be omitted</screen>
+  <screen>
++<replaceable class="function">name</replaceable>{<replaceable class="parameter">param</replaceable>}  # enable action and set parameter to <replaceable class="parameter">param</replaceable>,
+             # overwriting parameter from previous match if necessary
+-<replaceable class="function">name</replaceable>         # disable action. The parameter can be omitted
+</screen>
   <para>
    Note that if the URL matches multiple positive forms of a parameterized action,
    the last match wins, i.e. the params from earlier matches are simply ignored.
@@ -2580,11 +2664,12 @@ example.org/blocked-example-page</screen>
    that can be executed for the same request repeatedly, like adding multiple
    headers, or filtering through multiple filters. Syntax:
   </para>
-   <screen>
-  +<replaceable class="function">name</replaceable>{<replaceable class="parameter">param</replaceable>}   # enable action and add <replaceable class="parameter">param</replaceable> to the list of parameters
-  -<replaceable class="function">name</replaceable>{<replaceable class="parameter">param</replaceable>}   # remove the parameter <replaceable class="parameter">param</replaceable> from the list of parameters
-                # If it was the last one left, disable the action.
-  <replaceable class="parameter">-name</replaceable>          # disable this action completely and remove all parameters from the list</screen>
+  <screen>
++<replaceable class="function">name</replaceable>{<replaceable class="parameter">param</replaceable>}   # enable action and add <replaceable class="parameter">param</replaceable> to the list of parameters
+-<replaceable class="function">name</replaceable>{<replaceable class="parameter">param</replaceable>}   # remove the parameter <replaceable class="parameter">param</replaceable> from the list of parameters
+               # If it was the last one left, disable the action.
+<replaceable class="parameter">-name</replaceable>          # disable this action completely and remove all parameters from the list
+</screen>
   <para>
    Examples: <literal>+add-header{X-Fun-Header: Some text}</literal> and
    <literal>+filter{html-annoyances}</literal>
@@ -2784,18 +2869,20 @@ example.org/blocked-example-page</screen>
  <varlistentry>
   <term>Example usage (section):</term>
   <listitem>
-     <screen>{+block{No nasty stuff for you.}}
+     <screen>
+{+block{No nasty stuff for you.}}
 # Block and replace with "blocked" page
- .nasty-stuff.example.com
+.nasty-stuff.example.com
 
 {+block{Doubleclick banners.} +handle-as-image}
 # Block and replace with image
- .ad.doubleclick.net
- .ads.r.us/banners/
+.ad.doubleclick.net
+.ads.r.us/banners/
 
 {+block{Layered ads.} +handle-as-empty-document}
 # Block and then ignore
- adserver.example.net/.*\.js$</screen>
+adserver.example.net/.*\.js$
+</screen>
   </listitem>
  </varlistentry>
 
@@ -2932,6 +3019,21 @@ example.org/blocked-example-page</screen>
     one. This can be used to rewrite the request destination behind the client's
     back, for example to specify a Tor exit relay for certain requests.
    </para>
+   <para>
+    Note that to change the destination host for
+    <link linkend="HTTPS-INSPECTION">https-inspected</link>
+    requests a protocol and host has to be added to the URI.
+   </para>
+   <para>
+    If <link linkend="HTTPS-INSPECTION">https inspection</link>
+    is enabled, the protocol can be downgraded from https to http
+    but upgrading a request from http to https is currently not
+    supported.
+   </para>
+   <para>
+    After detecting a rewrite, &my-app; does not update the actions
+    used for the request based on the new host.
+   </para>
    <para>
     Please refer to the <link linkend="filter-file">filter file chapter</link>
     to learn which client-header filters are available by default, and how to
@@ -2955,6 +3057,162 @@ example.org/blocked-example-page</screen>
 </variablelist>
 </sect3>
 
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3 renderas="sect4" id="client-body-filter">
+<title>client-body-filter</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Typical use:</term>
+  <listitem>
+   <para>
+   Rewrite or remove client request body.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Effect:</term>
+  <listitem>
+   <para>
+    All request bodies to which this action applies are filtered on-the-fly through
+    the specified regular expression based substitutions.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Type:</term>
+  <!-- boolean, parameterized, Multi-value -->
+  <listitem>
+   <para>Multi-value.</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Parameter:</term>
+  <listitem>
+   <para>
+    The name of a client-body filter, as defined in one of the
+    <link linkend="filter-file">filter files</link>.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    Please refer to the <link linkend="filter-file">filter file chapter</link>
+    to learn how to create your own client-body filters.
+   </para>
+   <para>
+    The distribution <filename>default.filter</filename> file contains a selection of
+    client-body filters for example purposes.
+   </para>
+   <para>
+    The amount of data that can be filtered is limited by the
+    <literal><link linkend="buffer-limit">buffer-limit</link></literal>
+    option in the main <link linkend="config">config file</link>. The
+    default is 4096 KB (4 Megs). Once this limit is exceeded, the whole
+    request body is passed through unfiltered.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Example usage (section):</term>
+  <listitem>
+     <screen>
+# Remove "test" everywhere in the request body
+{+client-body-filter{remove-test}}
+/
+</screen>
+  </listitem>
+ </varlistentry>
+
+</variablelist>
+</sect3>
+
+
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3 renderas="sect4" id="client-body-tagger">
+<title>client-body-tagger</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Typical use:</term>
+  <listitem>
+   <para>
+    Block requests based on the content of the body data.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Effect:</term>
+  <listitem>
+   <para>
+    Client request bodies to which this action applies are filtered on-the-fly through
+    the specified regular expression based substitutions, the result is used as tag.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Type:</term>
+  <!-- boolean, parameterized, Multi-value -->
+  <listitem>
+   <para>Multi-value.</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Parameter:</term>
+  <listitem>
+   <para>
+    The name of a client-body tagger, as defined in one of the
+    <link linkend="filter-file">filter files</link>.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    Please refer to the <link linkend="filter-file">filter file chapter</link>
+    to learn how to create your own client-body tagger.
+   </para>
+   <para>
+    Client-body taggers are applied to each request body on its own,
+    and as the body isn't modified, each tagger "sees" the original.
+   </para>
+   <para>
+    Chunk-encoded request bodies currently can't be tagged.
+    Request bodies larger than the buffer-limit can't be tagged either.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Example usage (section):</term>
+  <listitem>
+     <screen>
+# Apply blafasel tagger.
+{+client-body-tagger{blafasel}}
+/
+
+# Block request based on the tag created by the blafasel tagger.
+{+block{Request body contains blafasel}}
+TAG:^content contains blafasel$
+</screen>
+  </listitem>
+ </varlistentry>
+
+</variablelist>
+</sect3>
+
 
 <!--   ~~~~~       New section      ~~~~~     -->
 <sect3 renderas="sect4" id="client-header-tagger">
@@ -3970,11 +4228,12 @@ problem-host.example.com</screen>
   <term>Example usage:</term>
   <listitem>
      <screen>
- { +fast-redirects{simple-check} }
-   one.example.com
+{ +fast-redirects{simple-check} }
+one.example.com
 
- { +fast-redirects{check-decoded-url} }
-   another.example.com/testing</screen>
+{ +fast-redirects{check-decoded-url} }
+another.example.com/testing
+</screen>
   </listitem>
  </varlistentry>
 
@@ -4062,7 +4321,7 @@ problem-host.example.com</screen>
     <quote>action</quote> is not available.
    </para>
    <para>
-    The amount of data that can be filtered is limited to the
+    The amount of data that can be filtered is limited by the
     <literal><link linkend="buffer-limit">buffer-limit</link></literal>
     option in the main <link linkend="config">config file</link>. The
     default is 4096 KB (4 Megs). Once this limit is exceeded, the buffered
@@ -4206,10 +4465,18 @@ problem-host.example.com</screen>
     <anchor id="filter-no-ping">
    </para>
     <screen>+filter{no-ping}             # Removes non-standard ping attributes in &lt;a&gt; and &lt;area&gt; tags.</screen>
+   <para>
+    <anchor id="filter-github">
+   </para>
+    <screen>+filter{github}              # Removes the annoying "Sign-Up" banner and the Cookie disclaimer.</screen>
    <para>
     <anchor id="filter-google">
    </para>
     <screen>+filter{google}              # CSS-based block for Google text ads. Also removes a width limitation and the toolbar advertisement.</screen>
+   <para>
+    <anchor id="filter-imdb">
+   </para>
+    <screen>+filter{imdb}                # Removes some ads on IMDb.</screen>
    <para>
     <anchor id="filter-yahoo">
    </para>
@@ -4222,6 +4489,10 @@ problem-host.example.com</screen>
     <anchor id="filter-blogspot">
    </para>
     <screen>+filter{blogspot}            # Cleans up some Blogspot blogs. Read the fine print before using this.</screen>
+   <para>
+    <anchor id="filter-sourceforge">
+   </para>
+    <screen>+filter{sourceforge}         # Reduces the amount of ads for proprietary software on SourceForge.</screen>
   </listitem>
  </varlistentry>
 </variablelist>
@@ -4768,11 +5039,14 @@ new action
  <varlistentry>
   <term>Example usage:</term>
   <listitem>
-     <screen># Disarm the download link in Sourceforge's patch tracker
+     <screen>
+# Disarm the download link in Sourceforge's patch tracker
 { -filter \
- +content-type-overwrite{text/plain}\
- +hide-content-disposition{block} }
- .sourceforge.net/tracker/download\.php</screen>
+  +content-type-overwrite{text/plain} \
+  +hide-content-disposition{block} \
+}
+.sourceforge.net/tracker/download\.php
+</screen>
   </listitem>
  </varlistentry>
 </variablelist>
@@ -5112,7 +5386,7 @@ new action
  <varlistentry>
   <term>Example usage:</term>
   <listitem>
-     <screen>+hide-user-agent{Netscape 6.1 (X11; I; Linux 2.4.18 i686)}</screen>
+     <screen>+hide-user-agent{Mozilla/5.0 (X11; ElectroBSD i386; rv:78.0) Gecko/20100101 Firefox/78.0}</screen>
   </listitem>
  </varlistentry>
 </variablelist>
@@ -5162,8 +5436,8 @@ new action
   <listitem>
    <para>
     This action allows &my-app; to filter encrypted requests and responses.
-    For this to work &my-app; has to generate a certificate and send it
-    to the client which has to accept it.
+    For this to work &my-app; has to generate a certificate for the web site
+    and send it to the client which has to accept it.
    </para>
    <para>
     Before this works the directives in the
@@ -5260,7 +5534,7 @@ www.example.com</screen>
    <screen>
     {+ignore-certificate-errors}
     www.example.org
-   </screen>
+</screen>
   </listitem>
  </varlistentry>
 </variablelist>
@@ -5517,19 +5791,20 @@ www.example.com</screen>
 #
 { +filter{tiny-textforms} +prevent-compression }
 # Match only these sites
- .google.
- sourceforge.net
- sf.net
+.google.
+sourceforge.net
+sf.net
 
 # Or instead, we could set a universal default:
 #
 { +prevent-compression }
- / # Match all sites
+/ # Match all sites
 
 # Then maybe make exceptions for broken sites:
 #
 { -prevent-compression }
-.compusa.com/</screen>
+.compusa.com/
+</screen>
   </listitem>
  </varlistentry>
 
@@ -5621,11 +5896,14 @@ new action
  <varlistentry>
   <term>Example usage:</term>
   <listitem>
-     <screen># Let the browser revalidate without being tracked across sessions
+     <screen>
+# Let the browser revalidate without being tracked across sessions
 { +hide-if-modified-since{-60} \
- +overwrite-last-modified{randomize} \
- +crunch-if-none-match}
-/</screen>
+  +overwrite-last-modified{randomize} \
+  +crunch-if-none-match \
+}
+/
+</screen>
   </listitem>
  </varlistentry>
 </variablelist>
@@ -5716,14 +5994,15 @@ new action
  <varlistentry>
   <term>Example usages:</term>
   <listitem>
-    <screen># Replace example.com's style sheet with another one
+    <screen>
+# Replace example.com's style sheet with another one
 { +redirect{http://localhost/css-replacements/example.com.css} }
- example.com/stylesheet\.css
+example.com/stylesheet\.css
 
 # Create a short, easy to remember nickname for a favorite site
 # (relies on the browser to accept and forward invalid URLs to &my-app;)
 { +redirect{https://www.privoxy.org/user-manual/actions-file.html} }
- a
+a
 
 # Always use the expanded view for Undeadly.org articles
 # (Note the $ at the end of the URL pattern to make sure
@@ -5936,6 +6215,63 @@ TAG:^image/
 </sect3>
 
 
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3 renderas="sect4" id="suppress-tag">
+<title>suppress-tag</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Typical use:</term>
+  <listitem>
+   <para>
+   Suppress client or server tag.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Effect:</term>
+  <listitem>
+   <para>
+    Server or client tags to which this action applies are not added to the request,
+    thus making all actions that are specific to these request tags inactive.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Type:</term>
+  <!-- boolean, parameterized, Multi-value -->
+  <listitem>
+   <para>Multi-value.</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Parameter:</term>
+  <listitem>
+   <para>
+    The result tag of a server-header or client-header tagger, as defined in one of the
+    <link linkend="filter-file">filter files</link>.
+   </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Example usage (section):</term>
+  <listitem>
+     <screen>
+# Suppress tag produced by range-requests client-header tagger for requests coming from address 10.0.0.1
+{+suppress-tag{RANGE-REQUEST}}
+TAG:^IP-ADDRESS: 10\.0\.0\.1$
+</screen>
+  </listitem>
+ </varlistentry>
+
+</variablelist>
+</sect3>
+
+
 <!--   ~~~~~       New section      ~~~~~     -->
 <sect3 renderas="sect4" id="session-cookies-only">
 <title>session-cookies-only</title>
@@ -6197,32 +6533,33 @@ TAG:^image/
 </para>
 
  <screen>
- # Useful custom aliases we can use later.
- #
- # Note the (required!) section header line and that this section
- # must be at the top of the actions file!
- #
- {{alias}}
+# Useful custom aliases we can use later.
+#
+# Note the (required!) section header line and that this section
+# must be at the top of the actions file!
+#
+{{alias}}
 
- # These aliases just save typing later:
- # (Note that some already use other aliases!)
- #
- +crunch-all-cookies = +<link linkend="CRUNCH-INCOMING-COOKIES">crunch-incoming-cookies</link> +<link linkend="CRUNCH-OUTGOING-COOKIES">crunch-outgoing-cookies</link>
- -crunch-all-cookies = -<link linkend="CRUNCH-INCOMING-COOKIES">crunch-incoming-cookies</link> -<link linkend="CRUNCH-OUTGOING-COOKIES">crunch-outgoing-cookies</link>
- +block-as-image      = +block{Blocked image.} +handle-as-image
- allow-all-cookies   = -crunch-all-cookies -<link linkend="SESSION-COOKIES-ONLY">session-cookies-only</link> -<link linkend="FILTER-CONTENT-COOKIES">filter{content-cookies}</link>
+# These aliases just save typing later:
+# (Note that some already use other aliases!)
+#
++crunch-all-cookies = +<link linkend="CRUNCH-INCOMING-COOKIES">crunch-incoming-cookies</link> +<link linkend="CRUNCH-OUTGOING-COOKIES">crunch-outgoing-cookies</link>
+-crunch-all-cookies = -<link linkend="CRUNCH-INCOMING-COOKIES">crunch-incoming-cookies</link> -<link linkend="CRUNCH-OUTGOING-COOKIES">crunch-outgoing-cookies</link>
++block-as-image     = +block{Blocked image.} +handle-as-image
+allow-all-cookies   = -crunch-all-cookies -<link linkend="SESSION-COOKIES-ONLY">session-cookies-only</link> -<link linkend="FILTER-CONTENT-COOKIES">filter{content-cookies}</link>
 
- # These aliases define combinations of actions
- # that are useful for certain types of sites:
- #
- fragile     = -<link linkend="BLOCK">block</link> -<link linkend="FILTER">filter</link> -crunch-all-cookies -<link linkend="FAST-REDIRECTS">fast-redirects</link> -<link linkend="HIDE-REFERER">hide-referrer</link> -<link linkend="PREVENT-COMPRESSION">prevent-compression</link>
+# These aliases define combinations of actions
+# that are useful for certain types of sites:
+#
+fragile     = -<link linkend="BLOCK">block</link> -<link linkend="FILTER">filter</link> -crunch-all-cookies -<link linkend="FAST-REDIRECTS">fast-redirects</link> -<link linkend="HIDE-REFERER">hide-referrer</link> -<link linkend="PREVENT-COMPRESSION">prevent-compression</link>
 
- shop        = -crunch-all-cookies -<link linkend="FILTER-ALL-POPUPS">filter{all-popups}</link>
+shop        = -crunch-all-cookies -<link linkend="FILTER-ALL-POPUPS">filter{all-popups}</link>
 
- # Short names for other aliases, for really lazy people ;-)
- #
- c0 = +crunch-all-cookies
- c1 = -crunch-all-cookies</screen>
+# Short names for other aliases, for really lazy people ;-)
+#
+c0 = +crunch-all-cookies
+c1 = -crunch-all-cookies
+</screen>
 
 <para>
  ...and put them to use. These sections would appear in the lower part of an
@@ -6231,28 +6568,29 @@ TAG:^image/
 </para>
 
  <screen>
- # These sites are either very complex or very keen on
- # user data and require minimal interference to work:
- #
- {fragile}
- .office.microsoft.com
- .windowsupdate.microsoft.com
- # Gmail is really mail.google.com, not gmail.com
- mail.google.com
-
- # Shopping sites:
- # Allow cookies (for setting and retrieving your customer data)
- #
- {shop}
- .quietpc.com
- .worldpay.com   # for quietpc.com
- mybank.example.com
+# These sites are either very complex or very keen on
+# user data and require minimal interference to work:
+#
+{fragile}
+.office.microsoft.com
+.windowsupdate.microsoft.com
+# Gmail is really mail.google.com, not gmail.com
+mail.google.com
 
- # These shops require pop-ups:
- #
- {-filter{all-popups} -filter{unsolicited-popups}}
-  .dabs.com
-  .overclockers.co.uk</screen>
+# Shopping sites:
+# Allow cookies (for setting and retrieving your customer data)
+#
+{shop}
+.quietpc.com
+.worldpay.com   # for quietpc.com
+mybank.example.com
+
+# These shops require pop-ups:
+#
+{-filter{all-popups} -filter{unsolicited-popups}}
+.dabs.com
+.overclockers.co.uk
+</screen>
 
 <para>
  Aliases like <quote>shop</quote> and <quote>fragile</quote> are typically used for
@@ -6361,7 +6699,7 @@ for-privoxy-version=3.0.11</screen>
  #
  +crunch-all-cookies = +<link linkend="CRUNCH-INCOMING-COOKIES">crunch-incoming-cookies</link> +<link linkend="CRUNCH-OUTGOING-COOKIES">crunch-outgoing-cookies</link>
  -crunch-all-cookies = -<link linkend="CRUNCH-INCOMING-COOKIES">crunch-incoming-cookies</link> -<link linkend="CRUNCH-OUTGOING-COOKIES">crunch-outgoing-cookies</link>
- +block-as-image      = +block{Blocked image.} +handle-as-image
+ +block-as-image     = +block{Blocked image.} +handle-as-image
  mercy-for-cookies   = -crunch-all-cookies -<link linkend="SESSION-COOKIES-ONLY">session-cookies-only</link> -<link linkend="FILTER-CONTENT-COOKIES">filter{content-cookies}</link>
 
  # These aliases define combinations of actions
@@ -6661,10 +6999,11 @@ handle-as-text = -<link linkend="FILTER">filter</link> +-<link linkend="content-
 
  <screen>
 { allow-all-cookies }
- sourceforge.net
- .yahoo.com
- .msdn.microsoft.com
- .redhat.com</screen>
+sourceforge.net
+.yahoo.com
+.msdn.microsoft.com
+.redhat.com
+</screen>
 
 <para>
  Your bank is allergic to some filter, but you don't know which, so you disable them all:
@@ -6672,7 +7011,8 @@ handle-as-text = -<link linkend="FILTER">filter</link> +-<link linkend="content-
 
  <screen>
 { -<link linkend="FILTER">filter</link> }
- .your-home-banking-site.com</screen>
+.your-home-banking-site.com
+</screen>
 
 <para>
  Some file types you may not want to filter for various reasons:
@@ -6703,8 +7043,9 @@ stupid-server.example.com/</screen>
 
  <screen>
 { +<link linkend="BLOCK">block</link>{Nasty ads.} }
- www.example.com/nasty-ads/sponsor\.gif
- another.example.net/more/junk/here/</screen>
+www.example.com/nasty-ads/sponsor\.gif
+another.example.net/more/junk/here/
+</screen>
 
 <para>
  The URLs of dynamically generated banners, especially from large banner
@@ -6720,10 +7061,11 @@ stupid-server.example.com/</screen>
 
  <screen>
 { +block-as-image }
- .doubleclick.net
- .fastclick.net
- /Realmedia/ads/
- ar.atwola.com/</screen>
+.doubleclick.net
+.fastclick.net
+/Realmedia/ads/
+ar.atwola.com/
+</screen>
 
 <para>
  Now you noticed that the default configuration breaks Forbes Magazine,
@@ -6739,9 +7081,10 @@ stupid-server.example.com/</screen>
 
 <screen>
 { fragile }
- .forbes.com
- webmail.example.com
- .mybank.com</screen>
+.forbes.com
+webmail.example.com
+.mybank.com
+</screen>
 
 <para>
  You like the <quote>fun</quote> text replacements in <filename>default.filter</filename>,
@@ -6752,7 +7095,8 @@ stupid-server.example.com/</screen>
 
 <screen>
 { +<link linkend="filter-fun">filter{fun}</link> }
- / # For ALL sites!</screen>
+/ # For ALL sites!
+</screen>
 
 <para>
  Note that the above is not really a good idea: There are exceptions
@@ -6771,9 +7115,10 @@ stupid-server.example.com/</screen>
 
 <screen>
 { allow-ads }
- .sourceforge.net
- .slashdot.org
- .osdn.net</screen>
+.sourceforge.net
+.slashdot.org
+.osdn.net
+</screen>
 
 <para>
  Note that <literal>allow-ads</literal> has been aliased to
@@ -6791,7 +7136,8 @@ stupid-server.example.com/</screen>
 
 <screen>
 { handle-as-text }
- /.*\.sh$</screen>
+/.*\.sh$
+</screen>
 
 <para>
  <filename>user.action</filename> is generally the best place to define
@@ -6828,18 +7174,21 @@ stupid-server.example.com/</screen>
 </para>
 
 <para>
- &my-app; supports three different pcrs-based filter actions:
+ &my-app; supports four different pcrs-based filter actions:
  <literal><link linkend="filter">filter</link></literal> to
  rewrite the content that is send to the client,
  <literal><link linkend="client-header-filter">client-header-filter</link></literal>
- to rewrite headers that are send by the client, and
+ to rewrite headers that are send by the client,
  <literal><link linkend="server-header-filter">server-header-filter</link></literal>
- to rewrite headers that are send by the server.
+ to rewrite headers that are send by the server, and
+ <literal><link linkend="client-body-filter">client-body-filter</link></literal>
+ to rewrite client request body.
 </para>
 
 <para>
- &my-app; also supports two tagger actions:
- <literal><link linkend="client-header-tagger">client-header-tagger</link></literal>
+ &my-app; also supports three tagger actions:
+ <literal><link linkend="client-header-tagger">client-header-tagger</link></literal>,
+ <literal><link linkend="client-body-tagger">client-body-tagger</link></literal>
  and
  <literal><link linkend="server-header-tagger">server-header-tagger</link></literal>.
  Taggers and filters use the same syntax in the filter files, the difference
@@ -6893,7 +7242,8 @@ stupid-server.example.com/</screen>
  filter file is organized in sections, which are called <emphasis>filters</emphasis>
  here. Each filter consists of a heading line, that starts with one of the
  <emphasis>keywords</emphasis> <literal>FILTER:</literal>,
- <literal>CLIENT-HEADER-FILTER:</literal> or <literal>SERVER-HEADER-FILTER:</literal>
+ <literal>CLIENT-HEADER-FILTER:</literal>, <literal>SERVER-HEADER-FILTER:</literal> or
+ <literal>CLIENT-BODY-FILTER:</literal>
  followed by the filter's <emphasis>name</emphasis>, and a short (one line)
  <emphasis>description</emphasis> of what it does. Below that line
  come the <emphasis>jobs</emphasis>, i.e. lines that define the actual
@@ -7872,11 +8222,37 @@ Requests</title>
 <sect2 id="license"><title>License</title>
 
 <sect3 id="gplv2"><title>GNU General Public License version 2</title>
- <screen><![ RCDATA [ &GPLv2; ]]></screen>
+ <literallayout class="Monospaced"><![ RCDATA [ &GPLv2; ]]></literallayout>
 </sect3>
 
 <sect3 id="gplv3"><title>GNU General Public License version 3</title>
- <screen><![ RCDATA [ &GPLv3; ]]></screen>
+ <literallayout class="Monospaced"><![ RCDATA [ &GPLv3; ]]></literallayout>
+</sect3>
+
+<sect3 id="third-party-licenses"><title>Third-party licenses and copyrights</title>
+<para>
+ Privoxy depends on a couple of third-party libraries which have seperate licenses.
+ Please refer to the third-party websites for up-to-date license and copyright
+ information.
+</para>
+<para>
+ Privoxy depends on <ulink url="https://pcre.org/">pcre</ulink>.
+</para>
+<para>
+ When compiled with FEATURE_BROTLI (optional), Privoxy depends on
+ <ulink url="https://www.brotli.org/">brotli</ulink>.
+</para>
+<para>
+ When compiled with FEATURE_HTTPS_INSPECTION (optional),
+ Privoxy depends on a TLS library. The supported libraries are
+ <ulink url="https://www.openssl.org/">LibreSSL</ulink>,
+ <ulink url="https://tls.mbed.org/">mbed TLS</ulink> and
+ <ulink url="https://www.openssl.org/">OpenSSL</ulink>.
+</para>
+<para>
+ When compiled with FEATURE_ZLIB (optional),
+ Privoxy depends on <ulink url="https://zlib.net/">zlib</ulink>.
+</para>
 </sect3>
 
 </sect2>
@@ -8454,11 +8830,11 @@ Requests</title>
 </para>
 
  <screen>
- Matches for http://www.google.com:
+Matches for http://www.google.com:
 
- In file: default.action <guibutton>[ View ]</guibutton> <guibutton>[ Edit ]</guibutton>
+In file: default.action <guibutton>[ View ]</guibutton> <guibutton>[ Edit ]</guibutton>
 
- {+change-x-forwarded-for{block}
+{+change-x-forwarded-for{block}
  +deanimate-gifs {last}
  +fast-redirects {check-decoded-url}
  +filter {refresh-tags}
@@ -8470,14 +8846,14 @@ Requests</title>
  +hide-from-header {block}
  +hide-referrer {forge}
  +session-cookies-only
- +set-image-blocker {pattern}
+ +set-image-blocker {pattern} }
 /
 
- { -session-cookies-only }
- .google.com
+{ -session-cookies-only }
+.google.com
 
- { -fast-redirects }
- .google.com
+{ -fast-redirects }
+.google.com
 
 In file: user.action <guibutton>[ View ]</guibutton> <guibutton>[ Edit ]</guibutton>
 (no matches in this file)
@@ -8540,64 +8916,64 @@ In file: user.action <guibutton>[ View ]</guibutton> <guibutton>[ Edit ]</guibut
 </para>
 
  <screen>
- Final results:
-
- -add-header
- -block
- +change-x-forwarded-for{block}
- -client-header-filter{hide-tor-exit-notation}
- -content-type-overwrite
- -crunch-client-header
- -crunch-if-none-match
- -crunch-incoming-cookies
- -crunch-outgoing-cookies
- -crunch-server-header
- +deanimate-gifs {last}
- -downgrade-http-version
- -fast-redirects
- -filter {js-events}
- -filter {content-cookies}
- -filter {all-popups}
- -filter {banners-by-link}
- -filter {tiny-textforms}
- -filter {frameset-borders}
- -filter {demoronizer}
- -filter {shockwave-flash}
- -filter {quicktime-kioskmode}
- -filter {fun}
- -filter {crude-parental}
- -filter {site-specifics}
- -filter {js-annoyances}
- -filter {html-annoyances}
- +filter {refresh-tags}
- -filter {unsolicited-popups}
- +filter {img-reorder}
- +filter {banners-by-size}
- +filter {webbugs}
- +filter {jumping-windows}
- +filter {ie-exploits}
- -filter {google}
- -filter {yahoo}
- -filter {msn}
- -filter {blogspot}
- -filter {no-ping}
- -force-text-mode
- -handle-as-empty-document
- -handle-as-image
- -hide-accept-language
- -hide-content-disposition
- +hide-from-header {block}
- -hide-if-modified-since
- +hide-referrer {forge}
- -hide-user-agent
- -limit-connect
- -overwrite-last-modified
- -prevent-compression
- -redirect
- -server-header-filter{xml-to-html}
- -server-header-filter{html-to-xml}
- -session-cookies-only
- +set-image-blocker {pattern}
+Final results:
+
+-add-header
+-block
++change-x-forwarded-for{block}
+-client-header-filter{hide-tor-exit-notation}
+-content-type-overwrite
+-crunch-client-header
+-crunch-if-none-match
+-crunch-incoming-cookies
+-crunch-outgoing-cookies
+-crunch-server-header
++deanimate-gifs {last}
+-downgrade-http-version
+-fast-redirects
+-filter {js-events}
+-filter {content-cookies}
+-filter {all-popups}
+-filter {banners-by-link}
+-filter {tiny-textforms}
+-filter {frameset-borders}
+-filter {demoronizer}
+-filter {shockwave-flash}
+-filter {quicktime-kioskmode}
+-filter {fun}
+-filter {crude-parental}
+-filter {site-specifics}
+-filter {js-annoyances}
+-filter {html-annoyances}
++filter {refresh-tags}
+-filter {unsolicited-popups}
++filter {img-reorder}
++filter {banners-by-size}
++filter {webbugs}
++filter {jumping-windows}
++filter {ie-exploits}
+-filter {google}
+-filter {yahoo}
+-filter {msn}
+-filter {blogspot}
+-filter {no-ping}
+-force-text-mode
+-handle-as-empty-document
+-handle-as-image
+-hide-accept-language
+-hide-content-disposition
++hide-from-header {block}
+-hide-if-modified-since
++hide-referrer {forge}
+-hide-user-agent
+-limit-connect
+-overwrite-last-modified
+-prevent-compression
+-redirect
+-server-header-filter{xml-to-html}
+-server-header-filter{html-to-xml}
+-session-cookies-only
++set-image-blocker {pattern}
 </screen>
 
 <para>
@@ -8612,14 +8988,14 @@ In file: user.action <guibutton>[ View ]</guibutton> <guibutton>[ Edit ]</guibut
 </para>
 
  <screen>
- { +block{Domains starts with "ad"} }
-  ad*.
+{ +block{Domains starts with "ad"} }
+ad*.
 
- { +block{Domain contains "ad"} }
-  .ad.
+{ +block{Domain contains "ad"} }
+.ad.
 
- { +block{Doubleclick banner server} +handle-as-image }
-  .[a-vx-z]*.doubleclick.net
+{ +block{Doubleclick banner server} +handle-as-image }
+.[a-vx-z]*.doubleclick.net
 </screen>
 
 <para>
@@ -8653,68 +9029,68 @@ In file: user.action <guibutton>[ View ]</guibutton> <guibutton>[ Edit ]</guibut
 </para>
 
  <screen>
- Matches for http://www.example.net/adsl/HOWTO/:
-
- In file: default.action <guibutton>[ View ]</guibutton> <guibutton>[ Edit ]</guibutton>
-
- {-add-header
 -block
 +change-x-forwarded-for{block}
 -client-header-filter{hide-tor-exit-notation}
 -content-type-overwrite
 -crunch-client-header
 -crunch-if-none-match
 -crunch-incoming-cookies
 -crunch-outgoing-cookies
 -crunch-server-header
 +deanimate-gifs
 -downgrade-http-version
 +fast-redirects {check-decoded-url}
 -filter {js-events}
 -filter {content-cookies}
 -filter {all-popups}
 -filter {banners-by-link}
 -filter {tiny-textforms}
 -filter {frameset-borders}
 -filter {demoronizer}
 -filter {shockwave-flash}
 -filter {quicktime-kioskmode}
 -filter {fun}
 -filter {crude-parental}
 -filter {site-specifics}
 -filter {js-annoyances}
 -filter {html-annoyances}
 +filter {refresh-tags}
 -filter {unsolicited-popups}
 +filter {img-reorder}
 +filter {banners-by-size}
 +filter {webbugs}
 +filter {jumping-windows}
 +filter {ie-exploits}
 -filter {google}
 -filter {yahoo}
 -filter {msn}
 -filter {blogspot}
 -filter {no-ping}
 -force-text-mode
 -handle-as-empty-document
 -handle-as-image
 -hide-accept-language
 -hide-content-disposition
 +hide-from-header{block}
 +hide-referer{forge}
 -hide-user-agent
 -overwrite-last-modified
 +prevent-compression
 -redirect
 -server-header-filter{xml-to-html}
 -server-header-filter{html-to-xml}
 +session-cookies-only
 +set-image-blocker{blank} }
-   /
-
- { +block{Path contains "ads".} +handle-as-image }
-  /ads
+Matches for http://www.example.net/adsl/HOWTO/:
+
+In file: default.action <guibutton>[ View ]</guibutton> <guibutton>[ Edit ]</guibutton>
+
+{-add-header
+ -block
+ +change-x-forwarded-for{block}
+ -client-header-filter{hide-tor-exit-notation}
+ -content-type-overwrite
+ -crunch-client-header
+ -crunch-if-none-match
+ -crunch-incoming-cookies
+ -crunch-outgoing-cookies
+ -crunch-server-header
+ +deanimate-gifs
+ -downgrade-http-version
+ +fast-redirects {check-decoded-url}
+ -filter {js-events}
+ -filter {content-cookies}
+ -filter {all-popups}
+ -filter {banners-by-link}
+ -filter {tiny-textforms}
+ -filter {frameset-borders}
+ -filter {demoronizer}
+ -filter {shockwave-flash}
+ -filter {quicktime-kioskmode}
+ -filter {fun}
+ -filter {crude-parental}
+ -filter {site-specifics}
+ -filter {js-annoyances}
+ -filter {html-annoyances}
+ +filter {refresh-tags}
+ -filter {unsolicited-popups}
+ +filter {img-reorder}
+ +filter {banners-by-size}
+ +filter {webbugs}
+ +filter {jumping-windows}
+ +filter {ie-exploits}
+ -filter {google}
+ -filter {yahoo}
+ -filter {msn}
+ -filter {blogspot}
+ -filter {no-ping}
+ -force-text-mode
+ -handle-as-empty-document
+ -handle-as-image
+ -hide-accept-language
+ -hide-content-disposition
+ +hide-from-header{block}
+ +hide-referer{forge}
+ -hide-user-agent
+ -overwrite-last-modified
+ +prevent-compression
+ -redirect
+ -server-header-filter{xml-to-html}
+ -server-header-filter{html-to-xml}
+ +session-cookies-only
+ +set-image-blocker{blank} }
+/
+
+{ +block{Path contains "ads".} +handle-as-image }
+/ads
 </screen>
 
 <para>
@@ -8732,8 +9108,8 @@ In file: user.action <guibutton>[ View ]</guibutton> <guibutton>[ Edit ]</guibut
 </para>
 
  <screen>
- { -block }
-  /adsl
+{ -block }
+/adsl
 </screen>
 
 <para>
@@ -8749,8 +9125,8 @@ In file: user.action <guibutton>[ View ]</guibutton> <guibutton>[ Edit ]</guibut
 </para>
 
  <screen>
- { +block{Path starts with "ads".} +handle-as-image }
- /ads
+{ +block{Path starts with "ads".} +handle-as-image }
+/ads
 </screen>
 
 <para>
@@ -8766,12 +9142,12 @@ In file: user.action <guibutton>[ View ]</guibutton> <guibutton>[ Edit ]</guibut
 </para>
 
  <screen>
- { shop }
- .quietpc.com
- .worldpay.com   # for quietpc.com
- .jungle.com
- .scan.co.uk
- .forbes.com
+{ shop }
+.quietpc.com
+.worldpay.com   # for quietpc.com
+.jungle.com
+.scan.co.uk
+.forbes.com
 </screen>
 
 <para>
@@ -8781,11 +9157,11 @@ In file: user.action <guibutton>[ View ]</guibutton> <guibutton>[ Edit ]</guibut
 </para>
 
  <screen>
- { -filter }
- # Disable ALL filter actions for sites in this section
- .forbes.com
- developer.ibm.com
- localhost
+{ -filter }
+# Disable ALL filter actions for sites in this section
+.forbes.com
+developer.ibm.com
+localhost
 </screen>
 
 <para>
@@ -8811,10 +9187,11 @@ In file: user.action <guibutton>[ View ]</guibutton> <guibutton>[ Edit ]</guibut
 </para>
 
  <screen>
- { fragile }
- # Handle with care: easy to break
- mail.google.
- mybank.example.com</screen>
+{ fragile }
+# Handle with care: easy to break
+mail.google.
+mybank.example.com
+</screen>
 
 
 <para>