Catch up on recent source changes.
[privoxy.git] / doc / webserver / user-manual / filter-file.html
1 <HTML
2 ><HEAD
3 ><TITLE
4 >The Filter File</TITLE
5 ><META
6 NAME="GENERATOR"
7 CONTENT="Modular DocBook HTML Stylesheet Version 1.64
8 "><LINK
9 REL="HOME"
10 TITLE="Privoxy User Manual"
11 HREF="index.html"><LINK
12 REL="PREVIOUS"
13 TITLE="Actions Files"
14 HREF="actions-file.html"><LINK
15 REL="NEXT"
16 TITLE="Templates"
17 HREF="templates.html"><LINK
18 REL="STYLESHEET"
19 TYPE="text/css"
20 HREF="../p_doc.css"></HEAD
21 ><BODY
22 CLASS="SECT1"
23 BGCOLOR="#EEEEEE"
24 TEXT="#000000"
25 LINK="#0000FF"
26 VLINK="#840084"
27 ALINK="#0000FF"
28 ><DIV
29 CLASS="NAVHEADER"
30 ><TABLE
31 WIDTH="100%"
32 BORDER="0"
33 CELLPADDING="0"
34 CELLSPACING="0"
35 ><TR
36 ><TH
37 COLSPAN="3"
38 ALIGN="center"
39 >Privoxy User Manual</TH
40 ></TR
41 ><TR
42 ><TD
43 WIDTH="10%"
44 ALIGN="left"
45 VALIGN="bottom"
46 ><A
47 HREF="actions-file.html"
48 >Prev</A
49 ></TD
50 ><TD
51 WIDTH="80%"
52 ALIGN="center"
53 VALIGN="bottom"
54 ></TD
55 ><TD
56 WIDTH="10%"
57 ALIGN="right"
58 VALIGN="bottom"
59 ><A
60 HREF="templates.html"
61 >Next</A
62 ></TD
63 ></TR
64 ></TABLE
65 ><HR
66 ALIGN="LEFT"
67 WIDTH="100%"></DIV
68 ><DIV
69 CLASS="SECT1"
70 ><H1
71 CLASS="SECT1"
72 ><A
73 NAME="FILTER-FILE"
74 >9. The Filter File</A
75 ></H1
76 ><P
77 > All text substitutions that can be invoked through the
78  <TT
79 CLASS="LITERAL"
80 ><A
81 HREF="actions-file.html#FILTER"
82 >filter</A
83 ></TT
84 > action
85  must first be defined in the filter file, which is typically
86  called <TT
87 CLASS="FILENAME"
88 >default.filter</TT
89 > and which can be
90  selected through the <TT
91 CLASS="LITERAL"
92 > <A
93 HREF="config.html#FILTERFILE"
94 >filterfile</A
95 ></TT
96 > config
97  option.</P
98 ><P
99 > Typical reasons for doing such substitutions are to eliminate
100  common annoyances in HTML and JavaScript, such as pop-up windows,
101  exit consoles, crippled windows without navigation tools, the
102  infamous &#60;BLINK&#62; tag etc, to suppress images with certain
103  width and height attributes (standard banner sizes or web-bugs),
104  or just to have fun. The possibilities are endless.</P
105 ><P
106 > Filtering works on any text-based document type, including plain
107  text, HTML, JavaScript, CSS etc. (all <TT
108 CLASS="LITERAL"
109 >text/*</TT
110 >
111  MIME types). Substitutions are made at the source level, so if
112  you want to <SPAN
113 CLASS="QUOTE"
114 >"roll your own"</SPAN
115 > filters, you should be
116  familiar with HTML syntax.</P
117 ><P
118 > Just like the <A
119 HREF="actions-file.html"
120 >actions files</A
121 >, the
122  filter file is organized in sections, which are called <I
123 CLASS="EMPHASIS"
124 >filters</I
125 >
126  here. Each filter consists of a heading line, that starts with the
127  <I
128 CLASS="EMPHASIS"
129 >keyword</I
130 > <TT
131 CLASS="LITERAL"
132 >FILTER:</TT
133 >, followed by
134  the filter's <I
135 CLASS="EMPHASIS"
136 >name</I
137 >, and a short (one line) 
138  <I
139 CLASS="EMPHASIS"
140 >description</I
141 > of what it does. Below that line
142  come the <I
143 CLASS="EMPHASIS"
144 >jobs</I
145 >, i.e. lines that define the actual
146  text substitutions. By convention, the name of a filter
147  should describe what the filter <I
148 CLASS="EMPHASIS"
149 >eliminates</I
150 >. The
151  comment is used in the <A
152 HREF="http://config.privoxy.org/"
153 TARGET="_top"
154 >web-based
155  user interface</A
156 >.</P
157 ><P
158 > Once a filter called <TT
159 CLASS="REPLACEABLE"
160 ><I
161 >name</I
162 ></TT
163 > has been defined
164  in the filter file, it can be invoked by using an action of the form
165  +<TT
166 CLASS="LITERAL"
167 ><A
168 HREF="actions-file.html#FILTER"
169 >filter</A
170 >{<TT
171 CLASS="REPLACEABLE"
172 ><I
173 >name</I
174 ></TT
175 >}</TT
176 >
177  in any <A
178 HREF="actions-file.html"
179 >actions file</A
180 >.</P
181 ><P
182 > A filter header line for a filter called <SPAN
183 CLASS="QUOTE"
184 >"foo"</SPAN
185 > could look
186  like this:</P
187 ><P
188 > <TABLE
189 BORDER="0"
190 BGCOLOR="#E0E0E0"
191 WIDTH="100%"
192 ><TR
193 ><TD
194 ><PRE
195 CLASS="SCREEN"
196 >FILTER: foo Replace all "foo" with "bar"</PRE
197 ></TD
198 ></TR
199 ></TABLE
200 ></P
201 ><P
202 > Below that line, and up to the next header line, come the jobs that
203  define what text replacements the filter executes. They are specified
204  in a syntax that imitates <A
205 HREF="http://www.perl.org/"
206 TARGET="_top"
207 >Perl</A
208 >'s
209  <TT
210 CLASS="LITERAL"
211 >s///</TT
212 > operator. If you are familiar with Perl, you
213  will find this to be quite intuitive, and may want to look at the
214  <A
215 HREF="http://www.oesterhelt.org/pcrs/pcrs.1.html"
216 TARGET="_top"
217 >PCRS man page</A
218 >
219  for the subtle differences to Perl behaviour. Most notably, the non-standard
220  option letter <TT
221 CLASS="LITERAL"
222 >U</TT
223 > is supported, which turns the default
224  to ungreedy matching.</P
225 ><P
226 > If you are new to regular expressions, you might want to take a look at
227  the <A
228 HREF="appendix.html#REGEX"
229 >Appendix on regular expressions</A
230 >, and
231  see the <A
232 HREF="http://perldoc.com/perl5.6.1/pod/perl.html"
233 TARGET="_top"
234 >Perl
235  manual</A
236 > for
237  <A
238 HREF="http://perldoc.com/perl5.6.1/pod/perlop.html#s-PATTERN-REPLACEMENT-egimosx"
239 TARGET="_top"
240 >the 
241  <TT
242 CLASS="LITERAL"
243 >s///</TT
244 > operator's syntax</A
245 > and <A
246 HREF="http://perldoc.com/perl5.6.1/pod/perlre.html"
247 TARGET="_top"
248 >Perl-style regular
249  expressions</A
250 > in general.
251  The below examples might also help to get you started.</P
252 ><DIV
253 CLASS="SECT2"
254 ><H2
255 CLASS="SECT2"
256 ><A
257 NAME="AEN2902"
258 >9.1. Filter File Tutorial</A
259 ></H2
260 ><P
261 > Now, let's complete our <SPAN
262 CLASS="QUOTE"
263 >"foo"</SPAN
264 > filter. We have already defined
265  the heading, but the jobs are still missing. Since all it does is to replace
266  <SPAN
267 CLASS="QUOTE"
268 >"foo"</SPAN
269 > with <SPAN
270 CLASS="QUOTE"
271 >"bar"</SPAN
272 >, there is only one (trivial) job
273  needed:</P
274 ><P
275 > <TABLE
276 BORDER="0"
277 BGCOLOR="#E0E0E0"
278 WIDTH="100%"
279 ><TR
280 ><TD
281 ><PRE
282 CLASS="SCREEN"
283 >s/foo/bar/</PRE
284 ></TD
285 ></TR
286 ></TABLE
287 ></P
288 ><P
289 > But wait! Didn't the comment say that <I
290 CLASS="EMPHASIS"
291 >all</I
292 > occurrences
293  of <SPAN
294 CLASS="QUOTE"
295 >"foo"</SPAN
296 > should be replaced? Our current job will only take
297  care of the first <SPAN
298 CLASS="QUOTE"
299 >"foo"</SPAN
300 > on each page. For global substitution,
301  we'll need to add the <TT
302 CLASS="LITERAL"
303 >g</TT
304 > option:</P
305 ><P
306 > <TABLE
307 BORDER="0"
308 BGCOLOR="#E0E0E0"
309 WIDTH="100%"
310 ><TR
311 ><TD
312 ><PRE
313 CLASS="SCREEN"
314 >s/foo/bar/g</PRE
315 ></TD
316 ></TR
317 ></TABLE
318 ></P
319 ><P
320 > Our complete filter now looks like this:</P
321 ><P
322 > <TABLE
323 BORDER="0"
324 BGCOLOR="#E0E0E0"
325 WIDTH="100%"
326 ><TR
327 ><TD
328 ><PRE
329 CLASS="SCREEN"
330 >FILTER: foo Replace all "foo" with "bar"
331 s/foo/bar/g</PRE
332 ></TD
333 ></TR
334 ></TABLE
335 ></P
336 ><P
337 > Let's look at some real filters for more interesting examples. Here you see
338  a filter that protects against some common annoyances that arise from JavaScript
339  abuse. Let's look at its jobs one after the other:</P
340 ><P
341 > <TABLE
342 BORDER="0"
343 BGCOLOR="#E0E0E0"
344 WIDTH="100%"
345 ><TR
346 ><TD
347 ><PRE
348 CLASS="SCREEN"
349 >FILTER: js-annoyances Get rid of particularly annoying JavaScript abuse
350
351 # Get rid of JavaScript referrer tracking. Test page: http://www.randomoddness.com/untitled.htm
352 #
353 s|(&#60;script.*)document\.referrer(.*&#60;/script&#62;)|$1"Not Your Business!"$2|Usg</PRE
354 ></TD
355 ></TR
356 ></TABLE
357 ></P
358 ><P
359 > Following the header line and a comment, you see the job. Note that it uses
360  <TT
361 CLASS="LITERAL"
362 >|</TT
363 > as the delimiter instead of <TT
364 CLASS="LITERAL"
365 >/</TT
366 >, because
367  the pattern contains a forward slash, which would otherwise have to be escaped
368  by a backslash (<TT
369 CLASS="LITERAL"
370 >\</TT
371 >).</P
372 ><P
373 > Now, let's examine the pattern: it starts with the text <TT
374 CLASS="LITERAL"
375 >&#60;script.*</TT
376 >
377  enclosed in parentheses. Since the dot matches any character, and <TT
378 CLASS="LITERAL"
379 >*</TT
380 >
381  means: <SPAN
382 CLASS="QUOTE"
383 >"Match an arbitrary number of the element left of myself"</SPAN
384 >, this
385  matches <SPAN
386 CLASS="QUOTE"
387 >"&#60;script"</SPAN
388 >, followed by <I
389 CLASS="EMPHASIS"
390 >any</I
391 > text, i.e.
392  it matches the whole page, from the start of the first &#60;script&#62; tag.</P
393 ><P
394 > That's more than we want, but the pattern continues: <TT
395 CLASS="LITERAL"
396 >document\.referrer</TT
397 >
398  matches only the exact string <SPAN
399 CLASS="QUOTE"
400 >"document.referrer"</SPAN
401 >. The dot needed to
402  be <I
403 CLASS="EMPHASIS"
404 >escaped</I
405 >, i.e. preceded by a backslash, to take away its
406  special meaning as a joker, and make it just a regular dot. So far, the meaning is:
407  Match from the start of the first &#60;script&#62; tag in a the page, up to, and including,
408  the text <SPAN
409 CLASS="QUOTE"
410 >"document.referrer"</SPAN
411 >, if <I
412 CLASS="EMPHASIS"
413 >both</I
414 > are present
415  in the page (and appear in that order).</P
416 ><P
417 > But there's still more pattern to go. The next element, again enclosed in parentheses,
418  is <TT
419 CLASS="LITERAL"
420 >.*&#60;/script&#62;</TT
421 >. You already know what <TT
422 CLASS="LITERAL"
423 >.*</TT
424 >
425  means, so the whole pattern translates to: Match from the start of the first  &#60;script&#62;
426  tag in a page to the end of the last &#60;script&#62; tag, provided that the text
427  <SPAN
428 CLASS="QUOTE"
429 >"document.referrer"</SPAN
430 > appears somewhere in between.</P
431 ><P
432 > This is still not the whole story, since we have ignored the options and the parentheses:
433  The portions of the page matched by sub-patterns that are enclosed in parentheses, will be
434  remembered and be available through the variables <TT
435 CLASS="LITERAL"
436 >$1, $2, ...</TT
437 > in
438  the substitute. The <TT
439 CLASS="LITERAL"
440 >U</TT
441 > option switches to ungreedy matching, which means
442  that the first <TT
443 CLASS="LITERAL"
444 >.*</TT
445 > in the pattern will only <SPAN
446 CLASS="QUOTE"
447 >"eat up"</SPAN
448 > all
449  text in between <SPAN
450 CLASS="QUOTE"
451 >"&#60;script"</SPAN
452 > and the <I
453 CLASS="EMPHASIS"
454 >first</I
455 > occurrence
456  of <SPAN
457 CLASS="QUOTE"
458 >"document.referrer"</SPAN
459 >, and that the second <TT
460 CLASS="LITERAL"
461 >.*</TT
462 > will
463  only span the text up to the <I
464 CLASS="EMPHASIS"
465 >first</I
466 > <SPAN
467 CLASS="QUOTE"
468 >"&#60;/script&#62;"</SPAN
469 >
470  tag. Furthermore, the <TT
471 CLASS="LITERAL"
472 >s</TT
473 > option says that the match may span
474  multiple lines in the page, and the <TT
475 CLASS="LITERAL"
476 >g</TT
477 > option again means that the
478  substitution is global.</P
479 ><P
480 > So, to summarize, the pattern means: Match all scripts that contain the text
481  <SPAN
482 CLASS="QUOTE"
483 >"document.referrer"</SPAN
484 >. Remember the parts of the script from
485  (and including) the start tag up to (and excluding) the string
486  <SPAN
487 CLASS="QUOTE"
488 >"document.referrer"</SPAN
489 > as <TT
490 CLASS="LITERAL"
491 >$1</TT
492 >, and the part following
493  that string, up to and including the closing tag, as <TT
494 CLASS="LITERAL"
495 >$2</TT
496 >.</P
497 ><P
498 > Now the pattern is deciphered, but wasn't this about substituting things? So
499  lets look at the substitute: <TT
500 CLASS="LITERAL"
501 >$1"Not Your Business!"$2</TT
502 > is
503  easy to read: The text remembered as <TT
504 CLASS="LITERAL"
505 >$1</TT
506 >, followed by 
507  <TT
508 CLASS="LITERAL"
509 >"Not Your Business!"</TT
510 > (<I
511 CLASS="EMPHASIS"
512 >including</I
513 >
514  the quotation marks!), followed by the text remembered as <TT
515 CLASS="LITERAL"
516 >$2</TT
517 >.
518  This produces an exact copy of the original string, with the middle part
519  (the <SPAN
520 CLASS="QUOTE"
521 >"document.referrer"</SPAN
522 >) replaced by <TT
523 CLASS="LITERAL"
524 >"Not Your
525  Business!"</TT
526 >.</P
527 ><P
528 > The whole job now reads: Replace <SPAN
529 CLASS="QUOTE"
530 >"document.referrer"</SPAN
531 > by
532  <TT
533 CLASS="LITERAL"
534 >"Not Your Business!"</TT
535 > wherever it appears inside a
536  &#60;script&#62; tag. Note that this job won't break JavaScript syntax,
537  since both the original and the replacement are syntactically valid
538  string objects. The script just won't have access to the referrer
539  information anymore.</P
540 ><P
541 > We'll show you two other jobs from the JavaScript taming department, but
542  this time only point out the constructs of special interest:</P
543 ><P
544 > <TABLE
545 BORDER="0"
546 BGCOLOR="#E0E0E0"
547 WIDTH="100%"
548 ><TR
549 ><TD
550 ><PRE
551 CLASS="SCREEN"
552 ># The status bar is for displaying link targets, not pointless blahblah
553 #
554 s/window\.status\s*=\s*['"].*?['"]/dUmMy=1/ig</PRE
555 ></TD
556 ></TR
557 ></TABLE
558 ></P
559 ><P
560 > <TT
561 CLASS="LITERAL"
562 >\s</TT
563 > stands for whitespace characters (space, tab, newline,
564  carriage return, form feed), so that <TT
565 CLASS="LITERAL"
566 >\s*</TT
567 > means: <SPAN
568 CLASS="QUOTE"
569 >"zero
570  or more whitespace"</SPAN
571 >. The <TT
572 CLASS="LITERAL"
573 >?</TT
574 > in <TT
575 CLASS="LITERAL"
576 >.*?</TT
577 >
578  makes this matching of arbitrary text ungreedy. (Note that the <TT
579 CLASS="LITERAL"
580 >U</TT
581 >
582  option is not set). The <TT
583 CLASS="LITERAL"
584 >['"]</TT
585 > construct means: <SPAN
586 CLASS="QUOTE"
587 >"a single
588  <I
589 CLASS="EMPHASIS"
590 >or</I
591 > a double quote"</SPAN
592 >.</P
593 ><P
594 > So what does this job do? It replaces assignments of single- or double-quoted
595  strings to the <SPAN
596 CLASS="QUOTE"
597 >"window.status"</SPAN
598 > object with a dummy assignment
599  (using a variable name that is hopefully odd enough not to conflict with
600  real variables in scripts). Thus, it catches many cases where e.g. pointless
601  descriptions are displayed in the status bar instead of the link target when
602  you move your mouse over links.</P
603 ><P
604 > <TABLE
605 BORDER="0"
606 BGCOLOR="#E0E0E0"
607 WIDTH="100%"
608 ><TR
609 ><TD
610 ><PRE
611 CLASS="SCREEN"
612 ># Kill OnUnload popups. Yummy. Test: http://www.zdnet.com/zdsubs/yahoo/tree/yfs.html
613 #
614 s/(&#60;body .*)onunload(.*&#62;)/$1never$2/iU</PRE
615 ></TD
616 ></TR
617 ></TABLE
618 ></P
619 ><P
620 > Including the
621  <A
622 HREF="http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html#Events-eventgroupings-htmlevents"
623 TARGET="_top"
624 >OnUnload
625  event binding</A
626 > in the HTML DOM was a <I
627 CLASS="EMPHASIS"
628 >CRIME</I
629 >.
630  When I close a browser window, I want it to close and die. Basta.
631  This job replaces the <SPAN
632 CLASS="QUOTE"
633 >"onunload"</SPAN
634 > attribute in
635  <SPAN
636 CLASS="QUOTE"
637 >"&#60;body&#62;"</SPAN
638 > tags with the dummy word <TT
639 CLASS="LITERAL"
640 >never</TT
641 >.
642  Note that the <TT
643 CLASS="LITERAL"
644 >i</TT
645 > option makes the pattern matching
646  case-insensitive.</P
647 ><P
648 > The last example is from the fun department:</P
649 ><P
650 > <TABLE
651 BORDER="0"
652 BGCOLOR="#E0E0E0"
653 WIDTH="100%"
654 ><TR
655 ><TD
656 ><PRE
657 CLASS="SCREEN"
658 >FILTER: fun Fun text replacements
659
660 # Spice the daily news:
661 #
662 s/microsoft(?!\.com)/MicroSuck/ig</PRE
663 ></TD
664 ></TR
665 ></TABLE
666 ></P
667 ><P
668 > Note the <TT
669 CLASS="LITERAL"
670 >(?!\.com)</TT
671 > part (a so-called negative lookahead)
672  in the job's pattern, which means: Don't match, if the string 
673  <SPAN
674 CLASS="QUOTE"
675 >".com"</SPAN
676 > appears directly following <SPAN
677 CLASS="QUOTE"
678 >"microsoft"</SPAN
679 >
680  in the page. This prevents links to microsoft.com from being messed, while
681  still replacing the word everywhere else.</P
682 ><P
683 > <TABLE
684 BORDER="0"
685 BGCOLOR="#E0E0E0"
686 WIDTH="100%"
687 ><TR
688 ><TD
689 ><PRE
690 CLASS="SCREEN"
691 ># Buzzword Bingo (example for extended regex syntax)
692 #
693 s* industry[ -]leading \
694 |  cutting[ -]edge \
695 |  award[ -]winning # Comments are OK, too! \
696 |  high[ -]performance \
697 |  solutions[ -]based \
698 |  unmatched \
699 |  unparalleled \
700 |  unrivalled \
701 *&#60;font color="red"&#62;&#60;b&#62;BINGO!&#60;/b&#62;&#60;/font&#62; \
702 *igx</PRE
703 ></TD
704 ></TR
705 ></TABLE
706 ></P
707 ><P
708 > The <TT
709 CLASS="LITERAL"
710 >x</TT
711 > option in this job turns on extended syntax, and allows for
712  e.g. the liberal use of (non-interpreted!) whitespace for nicer formatting.</P
713 ><P
714 > You get the idea?</P
715 ></DIV
716 ></DIV
717 ><DIV
718 CLASS="NAVFOOTER"
719 ><HR
720 ALIGN="LEFT"
721 WIDTH="100%"><TABLE
722 WIDTH="100%"
723 BORDER="0"
724 CELLPADDING="0"
725 CELLSPACING="0"
726 ><TR
727 ><TD
728 WIDTH="33%"
729 ALIGN="left"
730 VALIGN="top"
731 ><A
732 HREF="actions-file.html"
733 >Prev</A
734 ></TD
735 ><TD
736 WIDTH="34%"
737 ALIGN="center"
738 VALIGN="top"
739 ><A
740 HREF="index.html"
741 >Home</A
742 ></TD
743 ><TD
744 WIDTH="33%"
745 ALIGN="right"
746 VALIGN="top"
747 ><A
748 HREF="templates.html"
749 >Next</A
750 ></TD
751 ></TR
752 ><TR
753 ><TD
754 WIDTH="33%"
755 ALIGN="left"
756 VALIGN="top"
757 >Actions Files</TD
758 ><TD
759 WIDTH="34%"
760 ALIGN="center"
761 VALIGN="top"
762 >&nbsp;</TD
763 ><TD
764 WIDTH="33%"
765 ALIGN="right"
766 VALIGN="top"
767 >Templates</TD
768 ></TR
769 ></TABLE
770 ></DIV
771 ></BODY
772 ></HTML
773 >