+ <screen>
+# My user.action file. <fred@example.com></screen>
+</para>
+
+<para>
+ As <link linkend="aliases">aliases</link> are local to the actions
+ file that they are defined in, you can't use the ones from
+ <filename>default.action</filename>, unless you repeat them here:
+</para>
+
+<para>
+ <screen>
+# Aliases are local to the file they are defined in.
+# (Re-)define aliases for this file:
+#
+{{alias}}
+#
+# These aliases just save typing later, and the alias names should
+# be self explanatory.
+#
++crunch-all-cookies = +crunch-incoming-cookies +crunch-outgoing-cookies
+-crunch-all-cookies = -crunch-incoming-cookies -crunch-outgoing-cookies
+ allow-all-cookies = -crunch-all-cookies -session-cookies-only
+ allow-popups = -filter{all-popups} -kill-popups
++block-as-image = +block +handle-as-image
+-block-as-image = -block
+
+# These aliases define combinations of actions that are useful for
+# certain types of sites:
+#
+fragile = -block -crunch-all-cookies -filter -fast-redirects -hide-referrer -kill-popups
+shop = -crunch-all-cookies allow-popups
+
+# Allow ads for selected useful free sites:
+#
+allow-ads = -block -filter{banners-by-size} -filter{banners-by-link}
+
+# Alias for specific file types that are text, but might have conflicting
+# MIME types. We want the browser to force these to be text documents.
+handle-as-text = -<link linkend="FILTER">filter</link> +-<link linkend="content-type-overwrite">content-type-overwrite{text/plain}</link> +-<link linkend="FORCE-TEXT-MODE">force-text-mode</link> -<link linkend="HIDE-CONTENT-DISPOSITION">hide-content-disposition</link></screen>
+
+</para>
+
+<para>
+ Say you have accounts on some sites that you visit regularly, and
+ you don't want to have to log in manually each time. So you'd like
+ to allow persistent cookies for these sites. The
+ <literal>allow-all-cookies</literal> alias defined above does exactly
+ that, i.e. it disables crunching of cookies in any direction, and the
+ processing of cookies to make them only temporary.
+</para>
+
+<para>
+ <screen>
+{ allow-all-cookies }
+ sourceforge.net
+ .yahoo.com
+ .msdn.microsoft.com
+ .redhat.com</screen>
+</para>
+
+<para>
+ Your bank is allergic to some filter, but you don't know which, so you disable them all:
+</para>
+
+<para>
+ <screen>
+{ -<link linkend="FILTER">filter</link> }
+ .your-home-banking-site.com</screen>
+</para>
+
+<para>
+ Some file types you may not want to filter for various reasons:
+</para>
+
+<para>
+ <screen>
+# Technical documentation is likely to contain strings that might
+# erroneously get altered by the JavaScript-oriented filters:
+#
+.tldp.org
+/(.*/)?selfhtml/
+
+# And this stupid host sends streaming video with a wrong MIME type,
+# so that Privoxy thinks it is getting HTML and starts filtering:
+#
+stupid-server.example.com/</screen>
+</para>
+
+<para>
+ Example of a simple <link linkend="BLOCK">block</link> action. Say you've
+ seen an ad on your favourite page on example.com that you want to get rid of.
+ You have right-clicked the image, selected <quote>copy image location</quote>
+ and pasted the URL below while removing the leading http://, into a
+ <literal>{ +block }</literal> section. Note that <literal>{ +handle-as-image
+ }</literal> need not be specified, since all URLs ending in
+ <literal>.gif</literal> will be tagged as images by the general rules as set
+ in default.action anyway:
+</para>
+
+<para>
+ <screen>
+{ +<link linkend="BLOCK">block</link> }
+ www.example.com/nasty-ads/sponsor\.gif
+ another.example.net/more/junk/here/</screen>
+</para>
+
+<para>
+ The URLs of dynamically generated banners, especially from large banner
+ farms, often don't use the well-known image file name extensions, which
+ makes it impossible for <application>Privoxy</application> to guess
+ the file type just by looking at the URL.
+ You can use the <literal>+block-as-image</literal> alias defined above for
+ these cases.
+ Note that objects which match this rule but then turn out NOT to be an
+ image are typically rendered as a <quote>broken image</quote> icon by the
+ browser. Use cautiously.
+</para>
+
+<para>
+ <screen>
+{ +block-as-image }
+ .doubleclick.net
+ .fastclick.net
+ /Realmedia/ads/
+ ar.atwola.com/</screen>
+</para>
+
+<para>
+ Now you noticed that the default configuration breaks Forbes Magazine,
+ but you were too lazy to find out which action is the culprit, and you
+ were again too lazy to give <link linkend="contact">feedback</link>, so
+ you just used the <literal>fragile</literal> alias on the site, and
+ -- <emphasis>whoa!</emphasis> -- it worked. The <literal>fragile</literal>
+ aliases disables those actions that are most likely to break a site. Also,
+ good for testing purposes to see if it is <application>Privoxy</application>
+ that is causing the problem or not. We later find other regular sites
+ that misbehave, and add those to our personalized list of troublemakers:
+</para>
+
+<para>
+<screen>
+{ fragile }
+ .forbes.com
+ webmail.example.com
+ .mybank.com</screen>
+</para>
+
+<para>
+ You like the <quote>fun</quote> text replacements in <filename>default.filter</filename>,
+ but it is disabled in the distributed actions file.
+ So you'd like to turn it on in your private,
+ update-safe config, once and for all:
+</para>
+
+<para>
+<screen>
+{ +<link linkend="filter-fun">filter{fun}</link> }
+ / # For ALL sites!</screen>
+</para>
+
+<para>
+ Note that the above is not really a good idea: There are exceptions
+ to the filters in <filename>default.action</filename> for things that
+ really shouldn't be filtered, like code on CVS->Web interfaces. Since
+ <filename>user.action</filename> has the last word, these exceptions
+ won't be valid for the <quote>fun</quote> filtering specified here.
+</para>
+
+<para>
+ You might also worry about how your favourite free websites are
+ funded, and find that they rely on displaying banner advertisements
+ to survive. So you might want to specifically allow banners for those
+ sites that you feel provide value to you:
+</para>
+
+<para>
+<screen>
+{ allow-ads }
+ .sourceforge.net
+ .slashdot.org
+ .osdn.net</screen>
+</para>
+
+<para>
+ Note that <literal>allow-ads</literal> has been aliased to
+ <literal>-<link linkend="block">block</link></literal>,
+ <literal>-<link linkend="filter-banners-by-size">filter{banners-by-size}</link></literal>, and
+ <literal>-<link linkend="filter-banners-by-link">filter{banners-by-link}</link></literal> above.
+</para>
+
+<para>
+ Invoke another alias here to force an over-ride of the MIME type <literal>
+ application/x-sh</literal> which typically would open a download type
+ dialog. In my case, I want to look at the shell script, and then I can save
+ it should I choose to.
+</para>
+
+<para>
+<screen>
+{ handle-as-text }
+ /.*\.sh$</screen>
+</para>
+
+<para>
+ <filename>user.action</filename> is generally the best place to define
+ exceptions and additions to the default policies of
+ <filename>default.action</filename>. Some actions are safe to have their
+ default policies set here though. So let's set a default policy to have a
+ <quote>blank</quote> image as opposed to the checkerboard pattern for
+ <emphasis>ALL</emphasis> sites. <quote>/</quote> of course matches all URL
+ paths and patterns:
+</para>
+
+<para>
+<screen>
+{ +<link linkend="set-image-blocker">set-image-blocker{blank}</link> }
+/ # ALL sites</screen>
+</para>
+
+</sect3>
+</sect2>
+
+<!-- ~ End section ~ -->
+
+</sect1>
+
+<!-- ~ End section ~ -->
+
+<!-- ~~~~~~~~ New section Header ~~~~~~~~~ -->
+
+<sect1 id="filter-file">
+<title>Filter Files</title>
+
+<para>
+ On-the-fly text substitutions need
+ to be defined in a <quote>filter file</quote>. Once defined, they
+ can then be invoked as an <quote>action</quote>.
+</para>
+
+<para>
+ &my-app; supports three different 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
+ <literal><link linkend="server-header-filter">server-header-filter</link></literal>
+ to rewrite headers that are send by the server.
+</para>
+
+<para>
+ &my-app; also supports two tagger actions:
+ <literal><link linkend="client-header-tagger">client-header-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
+ is that taggers don't modify the text they are filtering, but use a rewritten
+ version of the filtered text as tag. The tags can then be used to change the
+ applying actions through sections with <link linkend="tag-pattern">tag-patterns</link>.
+</para>
+
+
+<para>
+ Multiple filter files can be defined through the <literal> <link
+ linkend="filterfile">filterfile</link></literal> config directive. The filters
+ as supplied by the developers are located in
+ <filename>default.filter</filename>. It is recommended that any locally
+ defined or modified filters go in a separately defined file such as
+ <filename>user.filter</filename>.
+ </para>
+
+<para>
+ Common tasks for content filters are to eliminate common annoyances in
+ HTML and JavaScript, such as pop-up windows,
+ exit consoles, crippled windows without navigation tools, the
+ infamous <BLINK> tag etc, to suppress images with certain
+ width and height attributes (standard banner sizes or web-bugs),
+ or just to have fun.
+</para>
+
+<para>
+ Enabled content filters are applied to any content whose
+ <quote>Content Type</quote> header is recognised as a sign
+ of text-based content, with the exception of <literal>text/plain</literal>.
+ Use the <link linkend="FORCE-TEXT-MODE">force-text-mode</link> action
+ to also filter other content.
+</para>
+
+<para>
+ Substitutions are made at the source level, so if you want to <quote>roll
+ your own</quote> filters, you should first be familiar with HTML syntax,
+ and, of course, regular expressions.
+</para>
+
+<para>
+ Just like the <link linkend="actions-file">actions files</link>, the
+ 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>
+ 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
+ text substitutions. By convention, the name of a filter
+ should describe what the filter <emphasis>eliminates</emphasis>. The
+ comment is used in the <ulink url="http://config.privoxy.org/">web-based
+ user interface</ulink>.
+</para>
+
+<para>
+ Once a filter called <replaceable>name</replaceable> has been defined
+ in the filter file, it can be invoked by using an action of the form
+ +<literal><link linkend="filter">filter</link>{<replaceable>name</replaceable>}</literal>
+ in any <link linkend="actions-file">actions file</link>.
+</para>
+
+<para>
+ Filter definitions start with a header line that contains the filter
+ type, the filter name and the filter description.
+ A content filter header line for a filter called <quote>foo</quote> could look
+ like this:
+</para>
+
+<para>
+ <screen>FILTER: foo Replace all "foo" with "bar"</screen>
+</para>
+
+<para>
+ Below that line, and up to the next header line, come the jobs that
+ define what text replacements the filter executes. They are specified
+ 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.
+</para>
+
+<para>
+ If you are new to
+ <ulink url="http://en.wikipedia.org/wiki/Regular_expressions"><quote>Regular
+ Expressions</quote></ulink>, you might want to take a look at
+ the <link linkend="regex">Appendix on regular expressions</link>, and
+ see the <ulink url="http://perldoc.perl.org/perlre.html">Perl
+ manual</ulink> for
+ <ulink url="http://perldoc.perl.org/perlop.html">the
+ <literal>s///</literal> operator's syntax</ulink> and <ulink
+ url="http://perldoc.perl.org/perlre.html">Perl-style regular
+ expressions</ulink> in general.
+ The below examples might also help to get you started.
+</para>
+
+
+<!-- ~~~~~~~~ New section Header ~~~~~~~~~ -->
+
+<sect2><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
+ <quote>foo</quote> with <quote>bar</quote>, there is only one (trivial) job
+ needed:
+</para>
+
+<para>
+ <screen>s/foo/bar/</screen>
+</para>
+
+<para>
+ But wait! Didn't the comment say that <emphasis>all</emphasis> occurrences
+ of <quote>foo</quote> should be replaced? Our current job will only take
+ care of the first <quote>foo</quote> on each page. For global substitution,
+ we'll need to add the <literal>g</literal> option:
+</para>
+
+<para>
+ <screen>s/foo/bar/g</screen>
+</para>
+
+<para>
+ Our complete filter now looks like this:
+</para>
+<para>
+ <screen>FILTER: foo Replace all "foo" with "bar"
+s/foo/bar/g</screen>
+</para>
+
+<para>
+ Let's look at some real filters for more interesting examples. Here you see
+ a filter that protects against some common annoyances that arise from JavaScript
+ abuse. Let's look at its jobs one after the other:
+</para>
+
+
+<para>
+ <screen>
+FILTER: js-annoyances Get rid of particularly annoying JavaScript abuse
+
+# Get rid of JavaScript referrer tracking. Test page: http://www.randomoddness.com/untitled.htm
+#
+s|(<script.*)document\.referrer(.*</script>)|$1"Not Your Business!"$2|Usg</screen>
+</para>
+
+<para>
+ Following the header line and a comment, you see the job. Note that it uses
+ <literal>|</literal> as the delimiter instead of <literal>/</literal>, because
+ the pattern contains a forward slash, which would otherwise have to be escaped
+ by a backslash (<literal>\</literal>).
+</para>
+
+<para>
+ Now, let's examine the pattern: it starts with the text <literal><script.*</literal>
+ enclosed in parentheses. Since the dot matches any character, and <literal>*</literal>
+ means: <quote>Match an arbitrary number of the element left of myself</quote>, this
+ matches <quote><script</quote>, followed by <emphasis>any</emphasis> text, i.e.
+ it matches the whole page, from the start of the first <script> tag.
+</para>
+
+<para>
+ That's more than we want, but the pattern continues: <literal>document\.referrer</literal>
+ matches only the exact string <quote>document.referrer</quote>. The dot needed to
+ be <emphasis>escaped</emphasis>, i.e. preceded by a backslash, to take away its
+ special meaning as a joker, and make it just a regular dot. So far, the meaning is:
+ Match from the start of the first <script> tag in a the page, up to, and including,
+ the text <quote>document.referrer</quote>, if <emphasis>both</emphasis> are present
+ in the page (and appear in that order).
+</para>
+
+<para>
+ But there's still more pattern to go. The next element, again enclosed in parentheses,
+ is <literal>.*</script></literal>. You already know what <literal>.*</literal>
+ means, so the whole pattern translates to: Match from the start of the first <script>
+ tag in a page to the end of the last <script> tag, provided that the text
+ <quote>document.referrer</quote> appears somewhere in between.
+</para>
+
+<para>
+ This is still not the whole story, since we have ignored the options and the parentheses:
+ The portions of the page matched by sub-patterns that are enclosed in parentheses, will be
+ remembered and be available through the variables <literal>$1, $2, ...</literal> in
+ the substitute. The <literal>U</literal> option switches to ungreedy matching, which means
+ that the first <literal>.*</literal> in the pattern will only <quote>eat up</quote> all
+ text in between <quote><script</quote> and the <emphasis>first</emphasis> occurrence
+ of <quote>document.referrer</quote>, and that the second <literal>.*</literal> will
+ only span the text up to the <emphasis>first</emphasis> <quote></script></quote>
+ tag. Furthermore, the <literal>s</literal> option says that the match may span
+ multiple lines in the page, and the <literal>g</literal> option again means that the
+ substitution is global.
+</para>
+
+<para>
+ So, to summarize, the pattern means: Match all scripts that contain the text
+ <quote>document.referrer</quote>. Remember the parts of the script from
+ (and including) the start tag up to (and excluding) the string
+ <quote>document.referrer</quote> as <literal>$1</literal>, and the part following
+ that string, up to and including the closing tag, as <literal>$2</literal>.
+</para>
+
+<para>
+ Now the pattern is deciphered, but wasn't this about substituting things? So
+ lets look at the substitute: <literal>$1"Not Your Business!"$2</literal> is
+ easy to read: The text remembered as <literal>$1</literal>, followed by
+ <literal>"Not Your Business!"</literal> (<emphasis>including</emphasis>
+ the quotation marks!), followed by the text remembered as <literal>$2</literal>.
+ This produces an exact copy of the original string, with the middle part
+ (the <quote>document.referrer</quote>) replaced by <literal>"Not Your
+ Business!"</literal>.
+</para>
+
+<para>
+ The whole job now reads: Replace <quote>document.referrer</quote> by
+ <literal>"Not Your Business!"</literal> wherever it appears inside a
+ <script> tag. Note that this job won't break JavaScript syntax,
+ since both the original and the replacement are syntactically valid
+ string objects. The script just won't have access to the referrer
+ information anymore.