Add a FAQ entry for tainted sockets
[privoxy.git] / doc / source / user-manual.sgml
index bc4a467..b4ad6a3 100644 (file)
@@ -9,10 +9,11 @@
 <!entity history SYSTEM "history.sgml">
 <!entity copyright SYSTEM "copyright.sgml">
 <!entity license SYSTEM "license.sgml">
+<!entity GPLv2 SYSTEM "../../LICENSE">
 <!entity p-authors SYSTEM "p-authors.sgml">
 <!entity config SYSTEM "p-config.sgml">
 <!entity changelog SYSTEM "changelog.sgml">
-<!entity p-version "3.0.21">
+<!entity p-version "3.0.25">
 <!entity p-status "UNRELEASED">
 <!entity % p-authors-formal "INCLUDE"> <!-- include additional text, etc  -->
 <!entity % p-not-stable "INCLUDE">
@@ -35,9 +36,9 @@
                 This file belongs into
                 ijbswa.sourceforge.net:/home/groups/i/ij/ijbswa/htdocs/
 
- $Id: user-manual.sgml,v 2.167 2013/01/25 14:19:27 fabiankeil Exp $
+ $Id: user-manual.sgml,v 2.203 2016/02/26 12:27:32 fabiankeil Exp $
 
- Copyright (C) 2001-2013 Privoxy Developers http://www.privoxy.org/
+ Copyright (C) 2001-2014 Privoxy Developers http://www.privoxy.org/
  See LICENSE.
 
  ========================================================================
  <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-2013 by
+ <link linkend="copyright">Copyright</link> &my-copy; 2001-2014 by
  <ulink url="http://www.privoxy.org/">Privoxy Developers</ulink>
  </subscript>
 </pubdate>
 
-<pubdate>$Id: user-manual.sgml,v 2.167 2013/01/25 14:19:27 fabiankeil Exp $</pubdate>
+<pubdate>$Id: user-manual.sgml,v 2.203 2016/02/26 12:27:32 fabiankeil Exp $</pubdate>
 
 <!--
 
@@ -116,7 +117,7 @@ Hal.
 <sect1 label="1" id="introduction"><title>Introduction</title>
 <para>
  This documentation is included with the current &p-status; version of
- <application>Privoxy</application>, v.&p-version;<![%p-not-stable;[,
+ <application>Privoxy</application>, &p-version;<![%p-not-stable;[,
  and is mostly complete at this point. The most up to date reference for the
  time being is still the comments in the source files and in the individual
  configuration files. Development of a new version is currently nearing
@@ -334,22 +335,12 @@ How to install the binary packages depends on your operating system:
 </sect3>
 
 <!--   ~~~~~       New section      ~~~~~     -->
-<sect3 id="installation-tbz"><title>FreeBSD</title>
+<sect3 id="installation-freebsd"><title>FreeBSD</title>
 
 <para>
  Privoxy is part of FreeBSD's Ports Collection, you can build and install
  it with <literal>cd /usr/ports/www/privoxy; make install clean</literal>.
 </para>
-<para>
- If you don't use the ports, you can fetch and install
- the package with <literal>pkg_add -r privoxy</literal>.
-</para>
-<para>
- The port skeleton and the package can also be downloaded from the
- <ulink url="https://sourceforge.net/project/showfiles.php?group_id=11118">File Release
- Page</ulink>, but there's no reason to use them unless you're interested in the
- beta releases which are only available there.
-</para>
 </sect3>
 
 </sect2>
@@ -633,18 +624,6 @@ How to install the binary packages depends on your operating system:
   </para>
  </listitem>
 
-<!--
- Did anyone test these lately?
- fk 2007-11-10
- <listitem>
-  <para>
-   For easy access to &my-app;'s most important controls, drag the provided
-   <link linkend="bookmarklets">Bookmarklets</link> into your browser's
-   personal toolbar.
-  </para>
- </listitem>
--->
-
  <listitem>
   <para>
    Please see the section <link linkend="contact">Contacting the
@@ -1087,6 +1066,29 @@ How to install the binary packages depends on your operating system:
 </para>
 </sect2>
 
+<sect2 id="start-freebsd">
+<title>FreeBSD and ElectroBSD</title>
+<para>
+ To start <application>Privoxy</application> upon booting, add
+ "privoxy_enable='YES'" to <filename>/etc/rc.conf</filename>.
+ <application>Privoxy</application> will use
+ <filename>/usr/local/etc/privoxy/config</filename> as its main
+ configuration file.
+</para>
+<para>
+ If you installed <application>Privoxy</application> into a jail, the
+ paths above are relative to the jail root.
+</para>
+<para>
+ To start <application>Privoxy</application> manually, run:
+</para>
+<para>
+ <screen>
+ # service privoxy onestart
+</screen>
+</para>
+</sect2>
+
 <sect2 id="start-windows">
 <title>Windows</title>
 <para>
@@ -1106,15 +1108,21 @@ Click on the &my-app; Icon to start <application>Privoxy</application>. If no co
 </sect2>
 
 <sect2 id="start-unices">
-<title>Solaris, NetBSD, FreeBSD, HP-UX and others</title>
+<title>Generic instructions for Unix derivates (Solaris, NetBSD, HP-UX etc.)</title>
 <para>
 Example Unix startup command:
 </para>
 <para>
  <screen>
- # /usr/sbin/privoxy /etc/privoxy/config
+ # /usr/sbin/privoxy --user privoxy /etc/privoxy/config
 </screen>
 </para>
+<para>
+ Note that if you installed <application>Privoxy</application> through
+ a package manager, the package will probably contain a platform-specific
+ script or configuration file to start <application>Privoxy</application>
+ upon boot.
+</para>
 </sect2>
 
 <sect2 id="start-os2">
@@ -1130,32 +1138,21 @@ Example Unix startup command:
 <sect2 id="start-macosx">
 <title>Mac OS X</title>
 <para>
-  After downloading the privoxy software, unzip the downloaded file by
-  double-clicking on the zip file icon.  Then, double-click on the
-  installer package icon and follow the installation process.
-</para>
-<para>
-  The privoxy service will automatically start after a successful
-  installation.  In addition, the privoxy service will automatically
-  start every time your computer starts up.
-</para>
-<para>
-  To prevent the privoxy service from automatically starting when your
-  computer starts up, remove or rename the folder named
-  /Library/StartupItems/Privoxy.
-</para>
-<para>
-  A simple application named Privoxy Utility has been created which
-  enables administrators to easily start and stop the privoxy service.
+ The privoxy service will automatically start after a successful installation
+ (and thereafter every time your computer starts up) however you will need to
+ configure your web browser(s) to use it. To do so, configure them to use a
+ proxy for HTTP and HTTPS at the address 127.0.0.1:8118.
 </para>
 <para>
-  In addition, the Privoxy Utility presents a simple way for
-  administrators to edit the various privoxy config files.  A method
-  to uninstall the software is also available.
+ To prevent the privoxy service from automatically starting when your computer
+ starts up, remove or rename the file <literal>/Library/LaunchDaemons/org.ijbswa.privoxy.plist</literal>
+ (on OS X 10.5 and higher) or the folder named
+ <literal>/Library/StartupItems/Privoxy</literal> (on OS X 10.4 'Tiger').
 </para>
 <para>
-  An administrator username and password must be supplied in order for
-  the Privoxy Utility to perform any of the tasks.
+ To manually start or stop the privoxy service, use the scripts startPrivoxy.sh
+ and stopPrivoxy.sh supplied in /Applications/Privoxy. They must be run from an
+ administrator account, using sudo.
 </para>
 </sect2>
 
@@ -1353,9 +1350,10 @@ must find a better place for this paragraph
    <emphasis>--pre-chroot-nslookup hostname</emphasis>
   </para>
   <para>
-   Specifies a hostname to look up before doing a chroot. On some systems, initializing the
-   resolver library involves reading config files from /etc and/or loading additional shared
-   libraries from /lib. On these systems, doing a hostname lookup before the chroot reduces
+   Specifies a hostname (for example www.privoxy.org) to look up before doing a chroot.
+   On some systems, initializing the resolver library involves reading config files from
+   /etc and/or loading additional shared libraries from /lib.
+   On these systems, doing a hostname lookup before the chroot reduces
    the number of files that must be copied into the chroot tree.
   </para>
   <para>
@@ -1410,7 +1408,7 @@ for details.
 
 <!--   ~~~~~       New section      ~~~~~     -->
 
-<sect2>
+<sect2 id="control-with-webbrowser">
 <title>Controlling Privoxy with Your Web Browser</title>
 <para>
  <application>Privoxy</application>'s user interface can be reached through the special
@@ -1466,10 +1464,7 @@ for details.
  it as a test to see whether it is <application>Privoxy</application>
  causing the problem or not. <application>Privoxy</application> continues
  to run as a proxy in this case, but all manipulation is disabled, i.e.
- <application>Privoxy</application> acts like a normal forwarding proxy. There
- is even a toggle <link linkend="bookmarklets">Bookmarklet</link> offered, so
- that you can toggle <application>Privoxy</application> with one click from
- your browser.
+ <application>Privoxy</application> acts like a normal forwarding proxy.
 </para>
 
 <para>
@@ -1878,7 +1873,7 @@ for details.
 </para>
 
 <!--   ~~~~~       New section      ~~~~~     -->
-<sect2>
+<sect2 id="right-mix">
 <title>Finding the Right Mix</title>
 <para>
  Note that some <link linkend="actions">actions</link>, like cookie suppression
@@ -1903,7 +1898,7 @@ for details.
 </sect2>
 
 <!--   ~~~~~       New section      ~~~~~     -->
-<sect2>
+<sect2 id="how-to-edit">
 <title>How to Edit</title>
 <para>
  The easiest way to edit the actions files is with a browser by
@@ -1993,23 +1988,23 @@ for details.
 
 <para>
  Generally, an URL pattern has the form
- <literal>&lt;domain&gt;&lt;port&gt;/&lt;path&gt;</literal>, where the
- <literal>&lt;domain&gt;</literal>, the <literal>&lt;port&gt;</literal>
+ <literal>&lt;host&gt;&lt;port&gt;/&lt;path&gt;</literal>, where the
+ <literal>&lt;host&gt;</literal>, the <literal>&lt;port&gt;</literal>
  and the <literal>&lt;path&gt;</literal> are optional. (This is why the special
  <literal>/</literal> pattern matches all URLs). Note that the protocol
  portion of the URL pattern (e.g. <literal>http://</literal>) should
  <emphasis>not</emphasis> be included in the pattern. This is assumed already!
 </para>
 <para>
- The pattern matching syntax is different for the domain and path parts of
- the URL. The domain part uses a simple globbing type matching technique,
+ The pattern matching syntax is different for the host and path parts of
+ the URL. The host part uses a simple globbing type matching technique,
  while the path part uses more flexible
  <ulink url="http://en.wikipedia.org/wiki/Regular_expressions"><quote>Regular
   Expressions</quote></ulink> (POSIX 1003.2).
 </para>
 <para>
  The port part of a pattern is a decimal port number preceded by a colon
- (<literal>:</literal>). If the domain part contains a numerical IPv6 address,
+ (<literal>:</literal>). If the host part contains a numerical IPv6 address,
  it has to be put into angle brackets
  (<literal>&lt;</literal>, <literal>&gt;</literal>).
 </para>
@@ -2019,7 +2014,7 @@ for details.
   <term><literal>www.example.com/</literal></term>
   <listitem>
    <para>
-    is a domain-only pattern and will match any request to <literal>www.example.com</literal>,
+    is a host-only pattern and will match any request to <literal>www.example.com</literal>,
     regardless of which document on that server is requested. So ALL pages in
     this domain would be covered by the scope of this action. Note that a
     simple <literal>example.com</literal> is different and would NOT match.
@@ -2030,7 +2025,7 @@ for details.
   <term><literal>www.example.com</literal></term>
   <listitem>
    <para>
-    means exactly the same. For domain-only patterns, the trailing <literal>/</literal> may
+    means exactly the same. For host-only patterns, the trailing <literal>/</literal> may
     be omitted.
    </para>
   </listitem>
@@ -2079,6 +2074,15 @@ for details.
    </para>
   </listitem>
  </varlistentry>
+ <varlistentry>
+  <term><literal>10.0.0.1/</literal></term>
+  <listitem>
+   <para>
+    Matches any URL with the host address <literal>10.0.0.1</literal>.
+    (Note that the real URL uses plain brackets, not angle brackets.)
+   </para>
+  </listitem>
+ </varlistentry>
  <varlistentry>
   <term><literal>&lt;2001:db8::1&gt;/</literal></term>
   <listitem>
@@ -2102,11 +2106,13 @@ for details.
 
 
 <!--   ~~~~~       New section      ~~~~~     -->
-<sect3><title>The Domain Pattern</title>
+<sect3 id="host-pattern"><title>The Host Pattern</title>
 
 <para>
- The matching of the domain part offers some flexible options: if the
- domain starts or ends with a dot, it becomes unanchored at that end.
+ The matching of the host part offers some flexible options: if the
+ host pattern starts or ends with a dot, it becomes unanchored at that end.
+ The host pattern is often referred to as domain pattern as it is usually
+ used to match domain names and not IP addresses.
  For example:
 </para>
 
@@ -2213,7 +2219,7 @@ for details.
 
 
 <!--   ~~~~~       New section      ~~~~~     -->
-<sect3><title>The Path Pattern</title>
+<sect3 id="path-pattern"><title>The Path Pattern</title>
 
 <para>
  <application>Privoxy</application> uses <quote>modern</quote> POSIX 1003.2
@@ -2372,6 +2378,23 @@ for details.
 
 </sect3>
 
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3 id="negative-tag-patterns"><title>The Negative Tag Patterns</title>
+
+<para>
+ To match requests that do not have a certain tag, specify a negative tag pattern
+ by prefixing the tag pattern line with either <quote>NO-REQUEST-TAG:</quote>
+ or <quote>NO-RESPONSE-TAG:</quote> instead of <quote>TAG:</quote>.
+</para>
+
+<para>
+ Negative tag patterns created with <quote>NO-REQUEST-TAG:</quote> are checked
+ after all client headers are scanned, the ones created with <quote>NO-RESPONSE-TAG:</quote>
+ are checked after all server headers are scanned. In both cases all the created
+ tags are considered.
+</para>
+
+
 </sect2>
 
 <!--  ~  End section  ~  -->
@@ -2773,7 +2796,7 @@ for details.
   <term>Type:</term>
   <!-- boolean, parameterized, Multi-value -->
   <listitem>
-   <para>Parameterized.</para>
+   <para>Multi-value.</para>
   </listitem>
  </varlistentry>
 
@@ -2860,7 +2883,7 @@ for details.
   <term>Type:</term>
   <!-- boolean, parameterized, Multi-value -->
   <listitem>
-   <para>Parameterized.</para>
+   <para>Multi-value.</para>
   </listitem>
  </varlistentry>
 
@@ -3581,6 +3604,94 @@ problem-host.example.com</screen>
 </variablelist>
 </sect3>
 
+<!--   ~~~~~       New section      ~~~~~     -->
+<sect3 renderas="sect4" id="external-filter">
+<title>external-filter</title>
+
+<variablelist>
+ <varlistentry>
+  <term>Typical use:</term>
+  <listitem>
+   <para>Modify content using a programming language of your choice.</para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Effect:</term>
+  <listitem>
+   <para>
+    All instances of text-based type, most notably HTML and JavaScript, to which
+    this action applies, can be filtered on-the-fly through the specified external
+    filter.
+    By default plain text documents are exempted from filtering, because web
+    servers often use the <literal>text/plain</literal> MIME type for all files
+    whose type they don't know.)
+   </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 an external content filter, as defined in the
+    <link linkend="filter-file">filter file</link>.
+    External filters can be defined in one or more files as defined by the
+    <literal><link linkend="filterfile">filterfile</link></literal>
+    option in the <link linkend="config">config file</link>.
+   </para>
+   <para>
+    When used in its negative form,
+    and without parameters, <emphasis>all</emphasis> filtering with external
+    filters is completely disabled.
+  </para>
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Notes:</term>
+  <listitem>
+   <para>
+    External filters are scripts or programs that can modify the content in
+    case common <literal><link linkend="filter">filters</link></literal>
+    aren't powerful enough. With the exception that this action doesn't
+    use pcrs-based filters, the notes in the
+    <literal><link linkend="filter">filter</link></literal> section apply.
+   </para>
+   <warning>
+    <para>
+     Currently external filters are executed with &my-app;'s privileges.
+     Only use external filters you understand and trust.
+    </para>
+   </warning>
+   <para>
+    This feature is experimental, the <literal><link
+    linkend="external-filter-syntax">syntax</link></literal>
+    may change in the future.
+   </para>
+
+  </listitem>
+ </varlistentry>
+
+ <varlistentry>
+  <term>Example usage:</term>
+  <listitem>
+   <para>
+    <screen>+external-filter{fancy-filter}</screen>
+   </para>
+  </listitem>
+ </varlistentry>
+</variablelist>
+</sect3>
+
 <!--   ~~~~~       New section      ~~~~~     -->
 <sect3 renderas="sect4" id="fast-redirects">
 <title>fast-redirects</title>
@@ -3735,7 +3846,7 @@ problem-host.example.com</screen>
   <term>Type:</term>
   <!-- boolean, parameterized, Multi-value -->
   <listitem>
-   <para>Parameterized.</para>
+   <para>Multi-value.</para>
   </listitem>
  </varlistentry>
 
@@ -3843,7 +3954,7 @@ problem-host.example.com</screen>
    </para>
    <para>
     <anchor id="filter-js-events">
-    <screen>+filter{js-events}           # Kill all JS event bindings and timers (Radically destructive! Only for extra nasty sites).</screen>
+    <screen>+filter{js-events}           # Kill JavaScript event bindings and timers (Radically destructive! Only for extra nasty sites).</screen>
    </para>
    <para>
     <anchor id="filter-html-annoyances">
@@ -3855,15 +3966,15 @@ problem-host.example.com</screen>
    </para>
    <para>
     <anchor id="filter-refresh-tags">
-    <screen>+filter{refresh-tags}        # Kill automatic refresh tags (for dial-on-demand setups).</screen>
+    <screen>+filter{refresh-tags}        # Kill automatic refresh tags if refresh time is larger than 9 seconds.</screen>
    </para>
    <para>
     <anchor id="filter-unsolicited-popups">
-    <screen>+filter{unsolicited-popups}  # Disable only unsolicited pop-up windows. Useful if your browser lacks this ability.</screen>
+    <screen>+filter{unsolicited-popups}  # Disable only unsolicited pop-up windows.</screen>
    </para>
    <para>
     <anchor id="filter-all-popups">
-    <screen>+filter{all-popups}          # Kill all popups in JavaScript and HTML. Useful if your browser lacks this ability.</screen>
+    <screen>+filter{all-popups}          # Kill all popups in JavaScript and HTML.</screen>
    </para>
    <para>
     <anchor id="filter-img-reorder">
@@ -3893,6 +4004,10 @@ problem-host.example.com</screen>
     <anchor id="filter-frameset-borders">
     <screen>+filter{frameset-borders}    # Give frames a border and make them resizable.</screen>
    </para>
+   <para>
+    <anchor id="filter-iframes">
+    <screen>+filter{iframes}             # Removes all detected iframes. Should only be enabled for individual sites.</screen>
+   </para>
    <para>
     <anchor id="filter-demoronizer">
     <screen>+filter{demoronizer}         # Fix MS's non-standard use of standard charsets.</screen>
@@ -4048,7 +4163,7 @@ new action
   <term>Type:</term>
   <!-- Boolean, Parameterized, Multi-value -->
   <listitem>
-   <para>Multi-value.</para>
+   <para>Parameterized.</para>
   </listitem>
  </varlistentry>
 
@@ -4081,6 +4196,32 @@ new action
       for socks5 connections (with remote DNS resolution).
      </para>
     </listitem>
+    <listitem>
+     <para>
+      <quote>forward-webserver 127.0.0.1:80</quote> to use the HTTP
+      server listening at 127.0.0.1 port 80 without adjusting the
+      request headers.
+     </para>
+     <para>
+      This makes it more convenient to use Privoxy to make
+      existing websites available as onion services as well.
+     </para>
+     <para>
+      Many websites serve content with hardcoded URLs and
+      can't be easily adjusted to change the domain based
+      on the one used by the client.
+     </para>
+     <para>
+      Putting Privoxy between Tor and the webserver (or an stunnel
+      that forwards to the webserver) allows to rewrite headers and
+      content to make client and server happy at the same time.
+     </para>
+     <para>
+      Using Privoxy for webservers that are only reachable through
+      onion addresses and whose location is supposed to be secret
+      is not recommended and should not be necessary anyway.
+     </para>
+    </listitem>
    </itemizedlist>
   </listitem>
  </varlistentry>
@@ -4103,7 +4244,8 @@ new action
     <para>
      If the ports are missing or invalid, default values will be used. This might change
      in the future and you shouldn't rely on it. Otherwise incorrect syntax causes Privoxy
-     to exit.
+     to exit. Due to design limitations, invalid parameter syntax isn't detected until the
+     action is used the first time.
     </para>
     <para>
      Use the <ulink url="http://config.privoxy.org/show-url-info">show-url-info CGI page</ulink>
@@ -4118,15 +4260,17 @@ new action
   <listitem>
    <para>
      <screen>
-# Always use direct connections for requests previously tagged as
+# Use an ssh tunnel for requests previously tagged as
 # <quote>User-Agent: fetch libfetch/2.0</quote> and make sure
 # resuming downloads continues to work.
+#
 # This way you can continue to use Tor for your normal browsing,
 # without overloading the Tor network with your FreeBSD ports updates
 # or downloads of bigger files like ISOs.
+#
 # Note that HTTP headers are easy to fake and therefore their
 # values are as (un)trustworthy as your clients and users.
-{+forward-override{forward .} \
+{+forward-override{forward-socks5 10.0.0.2:2222 .} \
  -hide-if-modified-since      \
  -overwrite-last-modified     \
 }
@@ -5256,9 +5400,15 @@ new action
     <link linkend="filter-file">filter file</link> section.
    </para>
    <para>
-    This action will be ignored if you use it together with
-    <literal><link linkend="block">block</link></literal>.
-    It can be combined with
+    Requests can't be blocked and redirected at the same time,
+    applying this action together with
+    <literal><link linkend="block">block</link></literal>
+    is a configuration error. Currently the request is blocked
+    and an error message logged, the behavior may change in the
+    future and result in Privoxy rejecting the action file.
+   </para>
+   <para>
+    This action can be combined with
     <literal><link linkend="fast-redirects">fast-redirects{check-decoded-url}</link></literal>
     to redirect to a decoded version of a rewritten URL.
    </para>
@@ -5283,7 +5433,7 @@ new action
  example.com/stylesheet\.css
 
 # Create a short, easy to remember nickname for a favorite site
-# (relies on the browser accept and forward invalid URLs to &my-app;)
+# (relies on the browser to accept and forward invalid URLs to &my-app;)
 { +redirect{http://www.privoxy.org/user-manual/actions-file.html} }
  a
 
@@ -5301,6 +5451,19 @@ undeadly.org/cgi\?action=article&amp;sid=\d*$
 {+redirect{s@^http://[^/]*/results\.aspx\?q=([^&amp;]*).*@http://search.yahoo.com/search?p=$1@}}
 search.msn.com//results\.aspx\?q=
 
+# Redirect http://example.com/&amp;bla=fasel&amp;toChange=foo (and any other value but "bar")
+# to       http://example.com/&amp;bla=fasel&amp;toChange=bar
+#
+# The URL pattern makes sure that the following request isn't redirected again.
+{+redirect{s@toChange=[^&amp;]+@toChange=bar@}}
+example.com/.*toChange=(?!bar)
+
+# Add a shortcut to look up illumos bugs
+{+redirect{s@^http://i([0-9]+)/.*@https://www.illumos.org/issues/$1@}}
+# Redirected URL = http://i4974/
+# Redirect Destination = https://www.illumos.org/issues/4974
+i[0-9][0-9][0-9][0-9]*/
+
 # Redirect remote requests for this manual
 # to the local version delivered by Privoxy
 {+redirect{s@^http://www@http://config@}}
@@ -5341,7 +5504,7 @@ www.privoxy.org/user-manual/</screen>
   <term>Type:</term>
   <!-- boolean, parameterized, Multi-value -->
   <listitem>
-   <para>Parameterized.</para>
+   <para>Multi-value.</para>
   </listitem>
  </varlistentry>
 
@@ -5424,7 +5587,7 @@ example.org/instance-that-is-delivered-as-xml-but-is-not
   <term>Type:</term>
   <!-- boolean, parameterized, Multi-value -->
   <listitem>
-   <para>Parameterized.</para>
+   <para>Multi-value.</para>
   </listitem>
  </varlistentry>
 
@@ -5469,6 +5632,14 @@ example.org/instance-that-is-delivered-as-xml-but-is-not
 # Tag every request with the content type declared by the server
 {+server-header-tagger{content-type}}
 /
+
+# If the response has a tag starting with 'image/' enable an external
+# filter that only applies to images.
+#
+# Note that the filter is not available by default, it's just a
+# <literal><link linkend="external-filter-syntax">silly example</link></literal>.
+{+external-filter{rotate-image} +force-text-mode}
+TAG:^image/
     </screen>
     </para>
   </listitem>
@@ -5687,7 +5858,7 @@ example.org/instance-that-is-delivered-as-xml-but-is-not
 
 
 <!--   ~~~~~       New section      ~~~~~     -->
-<sect3>
+<sect3 id="summary">
 <title>Summary</title>
 <para>
  Note that many of these actions have the potential to cause a page to
@@ -5830,7 +6001,7 @@ hal stop here
  and <filename>user.action</filename> file and see how all these pieces come together:
 </para>
 
-<sect3>
+<sect3 id="match-all">
 <title>match-all.action</title>
 <para>
  Remember <emphasis>all actions are disabled when matching starts</emphasis>,
@@ -5873,7 +6044,7 @@ hal stop here
 </para>
 </sect3>
 
-<sect3>
+<sect3 id="default-action">
 <title>default.action</title>
 
 <para>
@@ -6162,7 +6333,7 @@ wiki.
 
 </sect3>
 
-<sect3><title>user.action</title>
+<sect3 id="user-action"><title>user.action</title>
 
 <para>
  So far we are painting with a broad brush by setting general policies,
@@ -6429,7 +6600,7 @@ stupid-server.example.com/</screen>
 </para>
 
 <para>
- &my-app; supports three different filter actions:
+ &my-app; supports three 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>
@@ -6449,6 +6620,13 @@ stupid-server.example.com/</screen>
  applying actions through sections with <link linkend="tag-pattern">tag-patterns</link>.
 </para>
 
+<para>
+ Finally &my-app; supports the
+ <literal><link linkend="external-filter">external-filter</link></literal> action
+ to enable <literal><link linkend="external-filter-syntax">external filters</link></literal>
+ written in proper programming languages.
+</para>
+
 
 <para>
  Multiple filter files can be defined through the <literal> <link
@@ -6521,9 +6699,35 @@ stupid-server.example.com/</screen>
  in a syntax that imitates <ulink url="http://www.perl.org/">Perl</ulink>'s
  <literal>s///</literal> operator. If you are familiar with Perl, you
  will find this to be quite intuitive, and may want to look at the
- PCRS documentation for the subtle differences to Perl behaviour. Most
- notably, the non-standard option letter <literal>U</literal> is supported,
- which turns the default to ungreedy matching.
+ PCRS documentation for the subtle differences to Perl behaviour.
+</para>
+
+<para>
+ Most notably, the non-standard option letter <literal>U</literal> is supported,
+ which turns the default to ungreedy matching (add <literal>?</literal> to
+ quantifiers to turn them greedy again).
+</para>
+
+<para>
+ The non-standard option letter <literal>D</literal> (dynamic) allows
+ to use the variables $host, $origin (the IP address the request came from),
+ $path and $url. They will be replaced with the value they refer to before
+ the filter is executed.
+</para>
+
+<para>
+ Note that '$' is a bad choice for a delimiter in a dynamic filter as you
+ might end up with unintended variables if you use a variable name
+ directly after the delimiter. Variables will be resolved without
+ escaping anything, therefore you also have to be careful not to chose
+ delimiters that appear in the replacement text. For example '<' should
+ be save, while '?' will sooner or later cause conflicts with $url.
+</para>
+
+<para>
+ The non-standard option letter <literal>T</literal> (trivial) prevents
+ parsing for backreferences in the substitute. Use it if you want to include
+ text like '$&' in your substitute without quoting.
 </para>
 
 <para>
@@ -6543,7 +6747,7 @@ stupid-server.example.com/</screen>
 
 <!--   ~~~~~~~~       New section Header    ~~~~~~~~~     -->
 
-<sect2><title>Filter File Tutorial</title>
+<sect2 id="filter-file-tut"><title>Filter File Tutorial</title>
 <para>
  Now, let's complete our <quote>foo</quote> content filter. We have already defined
  the heading, but the jobs are still missing. Since all it does is to replace
@@ -7240,6 +7444,78 @@ pre-defined filters for your convenience:
 </variablelist>
 
 </sect2>
+
+<!--   ~~~~~~~~       New section Header    ~~~~~~~~~     -->
+<sect2 id="external-filter-syntax"><title>External filter syntax</title>
+<para>
+ External filters are scripts or programs that can modify the content in
+ case common <literal><link linkend="filter">filters</link></literal>
+ aren't powerful enough.
+</para>
+<para>
+ External filters can be written in any language the platform &my-app; runs
+ on supports.
+</para>
+<para>
+ They are controlled with the
+ <literal><link linkend="external-filter">external-filter</link></literal> action
+ and have to be defined in the <literal><link linkend="filterfile">filterfile</link></literal>
+ first.
+</para>
+<para>
+ The header looks like any other filter, but instead of pcrs jobs, external
+ filters contain a single job which can be a program or a shell script (which
+ may call other scripts or programs).
+</para>
+<para>
+ External filters read the content from STDIN and write the rewritten
+ content to STDOUT. The environment variables PRIVOXY_URL, PRIVOXY_PATH,
+ PRIVOXY_HOST, PRIVOXY_ORIGIN can be used to get some details about the
+ client request.
+</para>
+<para>
+ &my-app; will temporary store the content to filter in the
+ <literal><link linkend="temporary-directory">temporary-directory</link></literal>.
+</para>
+<para>
+ <screen>
+EXTERNAL-FILTER: cat Pointless example filter that doesn't actually modify the content
+/bin/cat
+
+# Incorrect reimplementation of the filter above in POSIX shell.
+#
+# Note that it's a single job that spans multiple lines, the line
+# breaks are not passed to the shell, thus the semicolons are required.
+#
+# If the script isn't trivial, it is recommended to put it into an external file.
+#
+# In general, writing external filters entirely in POSIX shell is not
+# considered a good idea.
+EXTERNAL-FILTER: cat2 Pointless example filter that despite its name may actually modify the content
+while read line; \
+do \
+  echo "$line"; \
+done
+
+EXTERNAL-FILTER: rotate-image Rotate an image by 180 degree. Test filter with limited value.
+/usr/local/bin/convert - -rotate 180 -
+
+EXTERNAL-FILTER: citation-needed Adds a "[citation needed]" tag to an image. The coordinates may need adjustment.
+/usr/local/bin/convert - -pointsize 16 -fill white  -annotate +17+418 "[citation needed]" -
+</screen>
+</para>
+
+<warning>
+ <para>
+  Currently external filters are executed with &my-app;'s privileges!
+  Only use external filters you understand and trust.
+ </para>
+</warning>
+<para>
+ External filters are experimental and the syntax may change in the future.
+</para>
+</sect2>
+
 </sect1>
 
 <!--  ~  End section  ~  -->
@@ -7360,11 +7636,20 @@ Requests</title>
  &copyright;
 <!-- end copyright -->
 
+<para>
+ <application>Privoxy</application> is free software; you can
+ redistribute it and/or modify it under the terms of the
+ <citetitle>GNU General Public License</citetitle>, version 2,
+ as published by the Free Software Foundation and included in
+ the next section.
+</para>
+
 <!--   ~~~~~       New section      ~~~~~     -->
-<sect2><title>License</title>
-<!-- Include copyright.sgml: -->
- &license;
-<!-- end copyright -->
+<sect2 id="license"><title>License</title>
+<para>
+ <screen><![ RCDATA [ &GPLv2; ]]></screen>
+</para>
+
 </sect2>
 <!--  ~  End section  ~  -->
 
@@ -7632,7 +7917,7 @@ Requests</title>
 
 
 <!--   ~~~~~       New section      ~~~~~     -->
-<sect2>
+<sect2 id="internal-pages">
 <title>Privoxy's Internal Pages</title>
 
 <para>
@@ -7749,84 +8034,6 @@ Requests</title>
  </itemizedlist>
 </para>
 
-<para>
- These may be bookmarked for quick reference. See next.
-
-</para>
-
-<sect3 id="bookmarklets">
-<title>Bookmarklets</title>
-<para>
- Below are some <quote>bookmarklets</quote> to allow you to easily access a
- <quote>mini</quote> version of some of <application>Privoxy's</application>
- special pages. They are designed for MS Internet Explorer, but should work
- equally well in Netscape, Mozilla, and other browsers which support
- JavaScript. They are designed to run directly from your bookmarks - not by
- clicking the links below (although that should work for testing).
-</para>
-<para>
- To save them, right-click the link and choose <quote>Add to Favorites</quote>
- (IE) or <quote>Add Bookmark</quote> (Netscape). You will get a warning that
- the bookmark <quote>may not be safe</quote> - just click OK. Then you can run the
- Bookmarklet directly from your favorites/bookmarks. For even faster access,
- you can put them on the <quote>Links</quote> bar (IE) or the <quote>Personal
- Toolbar</quote> (Netscape), and run them with a single click.
-</para>
-
-<para>
- <itemizedlist>
-
-  <listitem>
-   <para>
-    <ulink
-    url="javascript:void(window.open('http://config.privoxy.org/toggle?mini=y&#38;set=enabled','ijbstatus','width=250,height=100,resizable=yes,scrollbars=no,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());">Privoxy - Enable</ulink>
-   </para>
-  </listitem>
-
-  <listitem>
-   <para>
-    <ulink
-    url="javascript:void(window.open('http://config.privoxy.org/toggle?mini=y&#38;set=disabled','ijbstatus','width=250,height=100,resizable=yes,scrollbars=no,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());">Privoxy - Disable</ulink>
-   </para>
-  </listitem>
-
-  <listitem>
-   <para>
-    <ulink
-    url="javascript:void(window.open('http://config.privoxy.org/toggle?mini=y&#38;set=toggle','ijbstatus','width=250,height=100,resizable=yes,scrollbars=no,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());">Privoxy - Toggle Privoxy</ulink> (Toggles between enabled and disabled)
-   </para>
-  </listitem>
-
-  <listitem>
-   <para>
-    <ulink
-    url="javascript:void(window.open('http://config.privoxy.org/toggle?mini=y','ijbstatus','width=250,height=2,resizable=yes,scrollbars=no,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());">Privoxy- View Status</ulink>
-   </para>
-  </listitem>
-<!--
-  <listitem>
-   <para>
-    <ulink url="javascript:w=Math.floor(screen.width/2);h=Math.floor(screen.height*0.9);void(window.open('http://www.privoxy.org/actions/index.php?url='+escape(location.href),'Feedback','screenx='+w+',width='+w+',height='+h+',scrollbars=yes,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());">Privoxy - Submit Actions File Feedback</ulink>
-   </para>
-  </listitem>
- -->
-  <listitem>
-   <para>
-    <ulink url="javascript:void(window.open('http://config.privoxy.org/show-url-info?url='+escape(location.href),'Why').focus());">Privoxy - Why?</ulink>
-   </para>
-  </listitem>
- </itemizedlist>
-</para>
-
-<para>
- Credit: The site which gave us the general idea for these bookmarklets is
- <ulink url="http://www.bookmarklets.com/">www.bookmarklets.com</ulink>. They
- have more information about bookmarklets.
-</para>
-
-
-</sect3>
-
 </sect2>
 
 
@@ -7978,8 +8185,7 @@ Requests</title>
 <para>
  One quick test to see if <application>Privoxy</application> is causing a problem
  or not, is to disable it temporarily. This should be the first troubleshooting
- step. See <link linkend="bookmarklets">the Bookmarklets</link> section on a quick
- and easy way to do this (be sure to flush caches afterward!). Looking at the
+ step (be sure to flush caches afterward!). Looking at the
  logs is a good idea too. (Note that both the toggle feature and logging are
  enabled via <filename>config</filename> file settings, and may need to be
  turned <quote>on</quote>.)