wolfSSL: Use LIBWOLFSSL_VERSION_HEX to decide whether or not to use WOLFSSL_X509_V_OK master
authorFabian Keil <fk@fabiankeil.de>
Mon, 1 Apr 2024 15:19:06 +0000 (17:19 +0200)
committerFabian Keil <fk@fabiankeil.de>
Mon, 1 Apr 2024 15:22:14 +0000 (17:22 +0200)
As Roland pointed out, in older wolfSSL releases X509_V_OK
is an enum so the previous commit 838bc3c0e did not work
as expected there.

454 files changed:
AUTHORS
ChangeLog
GNUmakefile.in
INSTALL
Makefile
README
TODO
acconfig.h
actionlist.h
actions.c
cgi.c
cgiedit.c
cgisimple.c
client-tags.c
config
configure.in
deanimate.c
debian/changelog
debian/control
debian/copyright
debian/maintscript
debian/po/it.po [new file with mode: 0644]
debian/po/ro.po [new file with mode: 0644]
debian/privoxy-cleanup.service [new file with mode: 0644]
debian/privoxy-cleanup.timer [new file with mode: 0644]
debian/privoxy.cron.daily
debian/rules
debian/source/lintian-overrides [deleted file]
debian/tests/conditional-defines [new file with mode: 0755]
debian/tests/conditional-defines.pl [new file with mode: 0755]
debian/tests/control
debian/tests/privoxy-regression-test
default.action.master
default.filter
doc/source/authors.sgml
doc/source/changelog.sgml
doc/source/config.sgml
doc/source/copyright.sgml
doc/source/developer-manual.sgml
doc/source/faq.sgml
doc/source/install.sgml
doc/source/license.sgml
doc/source/p-authors.sgml
doc/source/p-config.sgml
doc/source/privoxy-man-page.sgml
doc/source/readme.sgml
doc/source/supported.sgml
doc/source/user-manual.sgml
doc/source/webserver/index.sgml
doc/webserver/announce.txt
doc/webserver/developer-manual/documentation.html
doc/webserver/developer-manual/index.html
doc/webserver/developer-manual/newrelease.html
doc/webserver/faq/copyright.html
doc/webserver/faq/general.html
doc/webserver/faq/index.html
doc/webserver/faq/installation.html
doc/webserver/feeds/privoxy-releases.xml
doc/webserver/index.html
doc/webserver/man-page/privoxy-man-page.html
doc/webserver/privoxy-index.html
doc/webserver/sponsors/index.html
doc/webserver/user-manual/actions-file.html
doc/webserver/user-manual/appendix.html
doc/webserver/user-manual/config.html
doc/webserver/user-manual/configuration.html
doc/webserver/user-manual/contact.html
doc/webserver/user-manual/copyright.html
doc/webserver/user-manual/filter-file.html
doc/webserver/user-manual/howto.html [new file with mode: 0644]
doc/webserver/user-manual/index.html
doc/webserver/user-manual/installation.html
doc/webserver/user-manual/introduction.html
doc/webserver/user-manual/quickstart.html
doc/webserver/user-manual/seealso.html
doc/webserver/user-manual/startup.html
doc/webserver/user-manual/templates.html
doc/webserver/user-manual/whatsnew.html
errlog.c
filters.c
filters.h
gateway.c
jbsockets.c
jcc.c
jcc.h
loadcfg.c
loaders.c
miscutil.c
miscutil.h
openssl.c
pcrs.c
pcrs.h
privoxy.8
project.h
regression-tests.action
ssl.c
ssl_common.c
ssl_common.h
templates/blocked
templates/edit-actions-remove-url-form
templates/edit-actions-url-form
templates/show-status
templates/untrusted
tests/cts/README [new file with mode: 0644]
tests/cts/acl-destination-denied/data/test1 [new file with mode: 0644]
tests/cts/acl-destination-denied/privoxy.conf [new file with mode: 0644]
tests/cts/acl-destination-permitted/data/test1 [new file with mode: 0644]
tests/cts/acl-destination-permitted/privoxy.conf [new file with mode: 0644]
tests/cts/acl-ip-address-denied/data/test1 [new file with mode: 0644]
tests/cts/acl-ip-address-denied/privoxy.conf [new file with mode: 0644]
tests/cts/acl-ip-address-permitted/data/test1 [new file with mode: 0644]
tests/cts/acl-ip-address-permitted/privoxy.conf [new file with mode: 0644]
tests/cts/blocked-https-requests/data/test1 [new file with mode: 0644]
tests/cts/blocked-https-requests/https-inspection.action [new file with mode: 0644]
tests/cts/blocked-https-requests/privoxy.conf [new file with mode: 0644]
tests/cts/ca-directory/privoxy-test-cacert.crt [new file with mode: 0644]
tests/cts/ca-directory/privoxy-test-cakey.pem [new file with mode: 0644]
tests/cts/certs/.gitignore [new file with mode: 0644]
tests/cts/chunked-transfer-encoding-https/chunked-transfer-encoding.action [new file with mode: 0644]
tests/cts/chunked-transfer-encoding-https/data/test1 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding-https/data/test10 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding-https/data/test11 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding-https/data/test12 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding-https/data/test13 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding-https/data/test14 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding-https/data/test15 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding-https/data/test16 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding-https/data/test17 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding-https/data/test18 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding-https/data/test19 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding-https/data/test2 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding-https/data/test20 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding-https/data/test21 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding-https/data/test22 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding-https/data/test3 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding-https/data/test4 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding-https/data/test5 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding-https/data/test6 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding-https/data/test7 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding-https/data/test8 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding-https/data/test9 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding-https/privoxy.conf [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/chunked-transfer-encoding.action [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test1 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test10 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test11 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test12 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test13 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test14 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test15 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test16 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test17 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test18 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test19 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test2 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test20 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test21 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test22 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test23 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test24 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test25 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test26 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test27 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test28 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test29 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test3 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test30 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test31 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test32 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test33 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test34 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test35 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test36 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test37 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test38 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test39 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test4 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test40 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test41 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test42 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test43 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test44 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test45 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test5 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test6 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test7 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test8 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/data/test9 [new file with mode: 0644]
tests/cts/chunked-transfer-encoding/privoxy.conf [new file with mode: 0644]
tests/cts/client-body-filter-https/client-body-filter.action [new file with mode: 0644]
tests/cts/client-body-filter-https/client-body-filter.filter [new file with mode: 0644]
tests/cts/client-body-filter-https/data/test1 [new file with mode: 0644]
tests/cts/client-body-filter-https/data/test10 [new file with mode: 0644]
tests/cts/client-body-filter-https/data/test12 [new file with mode: 0644]
tests/cts/client-body-filter-https/data/test13 [new file with mode: 0644]
tests/cts/client-body-filter-https/data/test14 [new file with mode: 0644]
tests/cts/client-body-filter-https/data/test15 [new file with mode: 0644]
tests/cts/client-body-filter-https/data/test16 [new file with mode: 0644]
tests/cts/client-body-filter-https/data/test17 [new file with mode: 0644]
tests/cts/client-body-filter-https/data/test2 [new file with mode: 0644]
tests/cts/client-body-filter-https/data/test3 [new file with mode: 0644]
tests/cts/client-body-filter-https/data/test4 [new file with mode: 0644]
tests/cts/client-body-filter-https/data/test5 [new file with mode: 0644]
tests/cts/client-body-filter-https/data/test6 [new file with mode: 0644]
tests/cts/client-body-filter-https/data/test7 [new file with mode: 0644]
tests/cts/client-body-filter-https/data/test8 [new file with mode: 0644]
tests/cts/client-body-filter-https/data/test9 [new file with mode: 0644]
tests/cts/client-body-filter-https/privoxy.conf [new file with mode: 0644]
tests/cts/client-body-filter/client-body-filter.action [new file with mode: 0644]
tests/cts/client-body-filter/client-body-filter.filter [new file with mode: 0644]
tests/cts/client-body-filter/data/test1 [new file with mode: 0644]
tests/cts/client-body-filter/data/test10 [new file with mode: 0644]
tests/cts/client-body-filter/data/test11 [new file with mode: 0644]
tests/cts/client-body-filter/data/test12 [new file with mode: 0644]
tests/cts/client-body-filter/data/test2 [new file with mode: 0644]
tests/cts/client-body-filter/data/test3 [new file with mode: 0644]
tests/cts/client-body-filter/data/test4 [new file with mode: 0644]
tests/cts/client-body-filter/data/test5 [new file with mode: 0644]
tests/cts/client-body-filter/data/test6 [new file with mode: 0644]
tests/cts/client-body-filter/data/test7 [new file with mode: 0644]
tests/cts/client-body-filter/data/test8 [new file with mode: 0644]
tests/cts/client-body-filter/data/test9 [new file with mode: 0644]
tests/cts/client-body-filter/privoxy.conf [new file with mode: 0644]
tests/cts/client-body-tagger-https/client-body-tagger.action [new file with mode: 0644]
tests/cts/client-body-tagger-https/client-body-tagger.filter [new file with mode: 0644]
tests/cts/client-body-tagger-https/data/test1 [new file with mode: 0644]
tests/cts/client-body-tagger-https/data/test10 [new file with mode: 0644]
tests/cts/client-body-tagger-https/data/test11 [new file with mode: 0644]
tests/cts/client-body-tagger-https/data/test12 [new file with mode: 0644]
tests/cts/client-body-tagger-https/data/test13 [new file with mode: 0644]
tests/cts/client-body-tagger-https/data/test14 [new file with mode: 0644]
tests/cts/client-body-tagger-https/data/test15 [new file with mode: 0644]
tests/cts/client-body-tagger-https/data/test16 [new file with mode: 0644]
tests/cts/client-body-tagger-https/data/test2 [new file with mode: 0644]
tests/cts/client-body-tagger-https/data/test3 [new file with mode: 0644]
tests/cts/client-body-tagger-https/data/test4 [new file with mode: 0644]
tests/cts/client-body-tagger-https/data/test5 [new file with mode: 0644]
tests/cts/client-body-tagger-https/data/test6 [new file with mode: 0644]
tests/cts/client-body-tagger-https/data/test7 [new file with mode: 0644]
tests/cts/client-body-tagger-https/data/test8 [new file with mode: 0644]
tests/cts/client-body-tagger-https/data/test9 [new file with mode: 0644]
tests/cts/client-body-tagger-https/privoxy.conf [new file with mode: 0644]
tests/cts/client-body-tagger/client-body-tagger.action [new file with mode: 0644]
tests/cts/client-body-tagger/client-body-tagger.filter [new file with mode: 0644]
tests/cts/client-body-tagger/data/test1 [new file with mode: 0644]
tests/cts/client-body-tagger/data/test2 [new file with mode: 0644]
tests/cts/client-body-tagger/data/test3 [new file with mode: 0644]
tests/cts/client-body-tagger/data/test4 [new file with mode: 0644]
tests/cts/client-body-tagger/data/test5 [new file with mode: 0644]
tests/cts/client-body-tagger/data/test6 [new file with mode: 0644]
tests/cts/client-body-tagger/data/test7 [new file with mode: 0644]
tests/cts/client-body-tagger/data/test8 [new file with mode: 0644]
tests/cts/client-body-tagger/privoxy.conf [new file with mode: 0644]
tests/cts/client-header-order-https/data/test332 [new file with mode: 0644]
tests/cts/client-header-order-https/data/test333 [new file with mode: 0644]
tests/cts/client-header-order-https/data/test334 [new file with mode: 0644]
tests/cts/client-header-order-https/data/test335 [new file with mode: 0644]
tests/cts/client-header-order-https/https-inspection.action [new file with mode: 0644]
tests/cts/client-header-order-https/privoxy.conf [new file with mode: 0644]
tests/cts/client-header-order/data/test332 [new file with mode: 0644]
tests/cts/client-header-order/data/test333 [new file with mode: 0644]
tests/cts/client-header-order/data/test334 [new file with mode: 0644]
tests/cts/client-header-order/data/test335 [new file with mode: 0644]
tests/cts/client-header-order/privoxy.conf [new file with mode: 0644]
tests/cts/client-tags/client-tags.action [new file with mode: 0644]
tests/cts/client-tags/data/test1 [new file with mode: 0644]
tests/cts/client-tags/data/test2 [new file with mode: 0644]
tests/cts/client-tags/data/test3 [new file with mode: 0644]
tests/cts/client-tags/data/test4 [new file with mode: 0644]
tests/cts/client-tags/data/test5 [new file with mode: 0644]
tests/cts/client-tags/data/test6 [new file with mode: 0644]
tests/cts/client-tags/data/test7 [new file with mode: 0644]
tests/cts/client-tags/privoxy.conf [new file with mode: 0644]
tests/cts/content-filters/content-filters.action [new file with mode: 0644]
tests/cts/content-filters/data/test1 [new file with mode: 0644]
tests/cts/content-filters/data/test10 [new file with mode: 0644]
tests/cts/content-filters/data/test11 [new file with mode: 0644]
tests/cts/content-filters/data/test12 [new file with mode: 0644]
tests/cts/content-filters/data/test13 [new file with mode: 0644]
tests/cts/content-filters/data/test14 [new file with mode: 0644]
tests/cts/content-filters/data/test15 [new file with mode: 0644]
tests/cts/content-filters/data/test16 [new file with mode: 0644]
tests/cts/content-filters/data/test17 [new file with mode: 0644]
tests/cts/content-filters/data/test18 [new file with mode: 0644]
tests/cts/content-filters/data/test19 [new file with mode: 0644]
tests/cts/content-filters/data/test2 [new file with mode: 0644]
tests/cts/content-filters/data/test200 [new file with mode: 0644]
tests/cts/content-filters/data/test201 [new file with mode: 0644]
tests/cts/content-filters/data/test202 [new file with mode: 0644]
tests/cts/content-filters/data/test203 [new file with mode: 0644]
tests/cts/content-filters/data/test204 [new file with mode: 0644]
tests/cts/content-filters/data/test21 [new file with mode: 0644]
tests/cts/content-filters/data/test22 [new file with mode: 0644]
tests/cts/content-filters/data/test23 [new file with mode: 0644]
tests/cts/content-filters/data/test24 [new file with mode: 0644]
tests/cts/content-filters/data/test25 [new file with mode: 0644]
tests/cts/content-filters/data/test3 [new file with mode: 0644]
tests/cts/content-filters/data/test300 [new file with mode: 0644]
tests/cts/content-filters/data/test301 [new file with mode: 0644]
tests/cts/content-filters/data/test302 [new file with mode: 0644]
tests/cts/content-filters/data/test310 [new file with mode: 0644]
tests/cts/content-filters/data/test311 [new file with mode: 0644]
tests/cts/content-filters/data/test312 [new file with mode: 0644]
tests/cts/content-filters/data/test320 [new file with mode: 0644]
tests/cts/content-filters/data/test321 [new file with mode: 0644]
tests/cts/content-filters/data/test322 [new file with mode: 0644]
tests/cts/content-filters/data/test33 [new file with mode: 0644]
tests/cts/content-filters/data/test34 [new file with mode: 0644]
tests/cts/content-filters/data/test35 [new file with mode: 0644]
tests/cts/content-filters/data/test36 [new file with mode: 0644]
tests/cts/content-filters/data/test37 [new file with mode: 0644]
tests/cts/content-filters/data/test38 [new file with mode: 0644]
tests/cts/content-filters/data/test390 [new file with mode: 0644]
tests/cts/content-filters/data/test391 [new file with mode: 0644]
tests/cts/content-filters/data/test392 [new file with mode: 0644]
tests/cts/content-filters/data/test393 [new file with mode: 0644]
tests/cts/content-filters/data/test4 [new file with mode: 0644]
tests/cts/content-filters/data/test5 [new file with mode: 0644]
tests/cts/content-filters/data/test6 [new file with mode: 0644]
tests/cts/content-filters/data/test7 [new file with mode: 0644]
tests/cts/content-filters/data/test8 [new file with mode: 0644]
tests/cts/content-filters/data/test9 [new file with mode: 0644]
tests/cts/content-filters/privoxy.conf [new file with mode: 0644]
tests/cts/curl-test-manifest-for-privoxy [new file with mode: 0644]
tests/cts/forward-to-http-proxy/data/test1 [new file with mode: 0644]
tests/cts/forward-to-http-proxy/data/test2 [new file with mode: 0644]
tests/cts/forward-to-http-proxy/data/test3 [new file with mode: 0644]
tests/cts/forward-to-http-proxy/data/test4 [new file with mode: 0644]
tests/cts/forward-to-http-proxy/forward-to-http-proxy.action [new file with mode: 0644]
tests/cts/forward-to-http-proxy/privoxy.conf [new file with mode: 0644]
tests/cts/forward-to-socks-proxy/data/test1 [new file with mode: 0644]
tests/cts/forward-to-socks-proxy/data/test2 [new file with mode: 0644]
tests/cts/forward-to-socks-proxy/data/test3 [new file with mode: 0644]
tests/cts/forward-to-socks-proxy/data/test4 [new file with mode: 0644]
tests/cts/forward-to-socks-proxy/data/test5 [new file with mode: 0644]
tests/cts/forward-to-socks-proxy/data/test6 [new file with mode: 0644]
tests/cts/forward-to-socks-proxy/privoxy.conf [new file with mode: 0644]
tests/cts/gen-skip-reasons.pl [new file with mode: 0755]
tests/cts/gif-deanimation/data/test1 [new file with mode: 0644]
tests/cts/gif-deanimation/data/test10 [new file with mode: 0644]
tests/cts/gif-deanimation/data/test11 [new file with mode: 0644]
tests/cts/gif-deanimation/data/test12 [new file with mode: 0644]
tests/cts/gif-deanimation/data/test13 [new file with mode: 0644]
tests/cts/gif-deanimation/data/test14 [new file with mode: 0644]
tests/cts/gif-deanimation/data/test15 [new file with mode: 0644]
tests/cts/gif-deanimation/data/test16 [new file with mode: 0644]
tests/cts/gif-deanimation/data/test17 [new file with mode: 0644]
tests/cts/gif-deanimation/data/test18 [new file with mode: 0644]
tests/cts/gif-deanimation/data/test19 [new file with mode: 0644]
tests/cts/gif-deanimation/data/test2 [new file with mode: 0644]
tests/cts/gif-deanimation/data/test20 [new file with mode: 0644]
tests/cts/gif-deanimation/data/test21 [new file with mode: 0644]
tests/cts/gif-deanimation/data/test22 [new file with mode: 0644]
tests/cts/gif-deanimation/data/test23 [new file with mode: 0644]
tests/cts/gif-deanimation/data/test3 [new file with mode: 0644]
tests/cts/gif-deanimation/data/test4 [new file with mode: 0644]
tests/cts/gif-deanimation/data/test5 [new file with mode: 0644]
tests/cts/gif-deanimation/data/test6 [new file with mode: 0644]
tests/cts/gif-deanimation/data/test7 [new file with mode: 0644]
tests/cts/gif-deanimation/data/test8 [new file with mode: 0644]
tests/cts/gif-deanimation/data/test9 [new file with mode: 0644]
tests/cts/gif-deanimation/deanimate-gifs.action [new file with mode: 0644]
tests/cts/gif-deanimation/privoxy.conf [new file with mode: 0644]
tests/cts/gzip-compression/data/test1 [new file with mode: 0644]
tests/cts/gzip-compression/data/test10 [new file with mode: 0644]
tests/cts/gzip-compression/data/test11 [new file with mode: 0644]
tests/cts/gzip-compression/data/test12 [new file with mode: 0644]
tests/cts/gzip-compression/data/test13 [new file with mode: 0644]
tests/cts/gzip-compression/data/test14 [new file with mode: 0644]
tests/cts/gzip-compression/data/test15 [new file with mode: 0644]
tests/cts/gzip-compression/data/test16 [new file with mode: 0644]
tests/cts/gzip-compression/data/test17 [new file with mode: 0644]
tests/cts/gzip-compression/data/test18 [new file with mode: 0644]
tests/cts/gzip-compression/data/test19 [new file with mode: 0644]
tests/cts/gzip-compression/data/test2 [new file with mode: 0644]
tests/cts/gzip-compression/data/test20 [new file with mode: 0644]
tests/cts/gzip-compression/data/test21 [new file with mode: 0644]
tests/cts/gzip-compression/data/test22 [new file with mode: 0644]
tests/cts/gzip-compression/data/test23 [new file with mode: 0644]
tests/cts/gzip-compression/data/test24 [new file with mode: 0644]
tests/cts/gzip-compression/data/test25 [new file with mode: 0644]
tests/cts/gzip-compression/data/test26 [new file with mode: 0644]
tests/cts/gzip-compression/data/test27 [new file with mode: 0644]
tests/cts/gzip-compression/data/test28 [new file with mode: 0644]
tests/cts/gzip-compression/data/test3 [new file with mode: 0644]
tests/cts/gzip-compression/data/test4 [new file with mode: 0644]
tests/cts/gzip-compression/data/test5 [new file with mode: 0644]
tests/cts/gzip-compression/data/test6 [new file with mode: 0644]
tests/cts/gzip-compression/data/test7 [new file with mode: 0644]
tests/cts/gzip-compression/data/test8 [new file with mode: 0644]
tests/cts/gzip-compression/data/test9 [new file with mode: 0644]
tests/cts/gzip-compression/gzip-compression.action [new file with mode: 0644]
tests/cts/gzip-compression/privoxy.conf [new file with mode: 0644]
tests/cts/header-filters/data/test1 [new file with mode: 0644]
tests/cts/header-filters/data/test2 [new file with mode: 0644]
tests/cts/header-filters/data/test3 [new file with mode: 0644]
tests/cts/header-filters/data/test4 [new file with mode: 0644]
tests/cts/header-filters/data/test5 [new file with mode: 0644]
tests/cts/header-filters/data/test6 [new file with mode: 0644]
tests/cts/header-filters/data/test7 [new file with mode: 0644]
tests/cts/header-filters/header-filters.action [new file with mode: 0644]
tests/cts/header-filters/privoxy.conf [new file with mode: 0644]
tests/cts/logs/.gitignore [new file with mode: 0644]
tests/cts/pac-file-delivery/data/test1 [new file with mode: 0644]
tests/cts/pac-file-delivery/privoxy.conf [new file with mode: 0644]
tests/cts/privoxy-runtests.pm [new file with mode: 0644]
tests/cts/redirects-https/data/test1 [new file with mode: 0644]
tests/cts/redirects-https/data/test2 [new file with mode: 0644]
tests/cts/redirects-https/data/test3 [new file with mode: 0644]
tests/cts/redirects-https/data/test4 [new file with mode: 0644]
tests/cts/redirects-https/data/test5 [new file with mode: 0644]
tests/cts/redirects-https/privoxy.conf [new file with mode: 0644]
tests/cts/redirects-https/redirects.action [new file with mode: 0644]
tests/cts/redirects/data/test1 [new file with mode: 0644]
tests/cts/redirects/data/test2 [new file with mode: 0644]
tests/cts/redirects/data/test3 [new file with mode: 0644]
tests/cts/redirects/data/test4 [new file with mode: 0644]
tests/cts/redirects/privoxy.conf [new file with mode: 0644]
tests/cts/redirects/redirects.action [new file with mode: 0644]
tests/cts/rewrite-behind-client-back-https/data/test1 [new file with mode: 0644]
tests/cts/rewrite-behind-client-back-https/data/test2 [new file with mode: 0644]
tests/cts/rewrite-behind-client-back-https/data/test3 [new file with mode: 0644]
tests/cts/rewrite-behind-client-back-https/data/test4 [new file with mode: 0644]
tests/cts/rewrite-behind-client-back-https/data/test5 [new file with mode: 0644]
tests/cts/rewrite-behind-client-back-https/privoxy.conf [new file with mode: 0644]
tests/cts/rewrite-behind-client-back-https/rewrites.action [new file with mode: 0644]
tests/cts/rewrite-behind-client-back-https/rewrites.filter [new file with mode: 0644]
tests/cts/rewrite-behind-client-back/data/test1 [new file with mode: 0644]
tests/cts/rewrite-behind-client-back/data/test2 [new file with mode: 0644]
tests/cts/rewrite-behind-client-back/data/test3 [new file with mode: 0644]
tests/cts/rewrite-behind-client-back/data/test4 [new file with mode: 0644]
tests/cts/rewrite-behind-client-back/data/test5 [new file with mode: 0644]
tests/cts/rewrite-behind-client-back/privoxy.conf [new file with mode: 0644]
tests/cts/rewrite-behind-client-back/rewrites.action [new file with mode: 0644]
tests/cts/rewrite-behind-client-back/rewrites.filter [new file with mode: 0644]
tests/cts/run-privoxy-tests.sh [new file with mode: 0755]
tests/cts/runtests-wrapper.sh [new file with mode: 0755]
tests/cts/upstream-tests/privoxy.conf [new file with mode: 0644]
tests/cts/user-manual-http/data/test1 [new file with mode: 0644]
tests/cts/user-manual-http/privoxy.conf [new file with mode: 0644]
tests/cts/user-manual-https/data/test1 [new file with mode: 0644]
tests/cts/user-manual-https/privoxy.conf [new file with mode: 0644]
tools/privoxy-log-parser.pl
tools/privoxy-regression-test.pl
tools/uagen.pl
trust
urlmatch.c
urlmatch.h
user.action
win32.c
windows/MYconfigure
windows/WinMessages.nsh
windows/privoxy_winthreads.nsi
wolfssl.c [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
index 16ad8b1..e61a0b2 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -50,6 +50,7 @@ include (in alphabetical order):
  Anatoly Arzhnikov
  Ken Arromdee
  Natxo Asenjo
+ avoidr
  Devin Bayer
  Havard Berland
  David Binderman
@@ -62,6 +63,8 @@ include (in alphabetical order):
  Andrew J. Caines
  Clifford Caoile
  Edward Carrel
+ Celejar
+ Chakib Benziane
  Pak Chan
  Wan-Teh Chang
  Sam Chen
@@ -166,6 +169,7 @@ include (in alphabetical order):
  Andreas Rutkauskas
  Sam
  Saperski
+ Andrew Savchenko
  Bart Schelstraete
  Richard Schneidt
  Gregory Seidman
index f399120..a1964be 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,157 @@
 --------------------------------------------------------------------
 ChangeLog for Privoxy
 --------------------------------------------------------------------
-*** Version 3.0.33 UNRELEASED ***
+*** Version 3.0.34 stable ***
+
+- Bug fixes:
+  - Improve the handling of chunk-encoded responses by buffering the data
+    even if filters are disabled and properly keeping track of where the
+    various chunks are supposed to start and end. Previously Privoxy would
+    merely check the last bytes received to see if they looked like the
+    last-chunk. This failed to work if the last-chunk wasn't received in one
+    read and could also result in actual data being misdetected
+    as last-chunk.
+    Should fix: SF support request #1739.
+    Reported by: withoutname.
+  - remove_chunked_transfer_coding(): Refuse to de-chunk invalid data
+    Previously the data could get corrupted even further.
+    Now we simply pass the unmodified data to the client.
+  - gif_deanimate(): Tolerate multiple image extensions in a row.
+    This allows to deanimate all the gifs on:
+    https://commons.wikimedia.org/wiki/Category:Animated_smilies
+    Fixes SF bug #795 reported by Celejar.
+  - OpenSSL generate_host_certificate(): Use X509_get_subject_name()
+    instead of X509_get_issuer_name() to get the issuer for generated
+    website certificates so there are no warnings in the browser when using
+    an intermediate CA certificate instead of a self-signed root certificate.
+    Problem reported and patch submitted by Chakib Benziane.
+  - can_filter_request_body(): Fix a log message that contained a spurious u.
+  - handle_established_connection(): Check for pending TLS data from the client
+    before checking if data is available on the connection.
+    The TLS library may have already consumed all the data from the client
+    response in which case poll() and select() will not detect that data is
+    available to be read.
+    Sponsored by: Robert Klemme.
+  - ssl_send_certificate_error(): Don't crash if there's no certificate
+    information available. This is only relevant when Privoxy is built with
+    wolfSSL 5.0.0 or later (code not yet published). Earlier wolfSSL versions
+    or the other TLS backends don't seem to trigger the crash.
+  - socks5_connect(): Add support for target hosts specified as IPv4 address
+    Previously the IP address was sent as domain.
+
+- General improvements:
+  - Add a client-body-tagger action which creates tags based on
+    the content of the request body.
+    Sponsored by: Robert Klemme.
+  - When client-body filters are enabled, buffer the whole request
+    before opening a connection to the server.
+    Makes it less likely that the server connection times out
+    and we don't open a connection if the buffering fails anyway.
+    Sponsored by: Robert Klemme.
+  - Add periods to a couple of log messages.
+  - accept_connection(): Add missing space to a log message.
+  - Initialize ca-related defaults with strdup_or_die() so errors
+    aren't silently ignored.
+  - make_path: Use malloc_or_die() in cases where allocation errors
+    were already fatal anyway.
+  - handle_established_connection(): Improve an error message slightly.
+  - receive_client_request(): Reject https URLs without CONNECT request.
+  - Include all requests in the statistics if mutexes are available.
+    Previously in case of reused connections only the last request got
+    counted. The statistics still aren't perfect but it's an improvement.
+  - Add read_socks_reply() and start using it in socks5_connect()
+    to apply the socket timeout more consistently.
+  - socks5_connect(): Deal with domain names in the socks reply
+  - Add a filter for bundeswehr.de that hides the cookie and
+    privacy info banner.
+
+- Action file improvements:
+  - Disable filter{banners-by-size} for .freiheitsfoo.de/.
+  - Disable filter{banners-by-size} for freebsdfoundation.org/.
+  - Disable fast-redirects for consent.youtube.com/.
+  - Block requests to ups.xplosion.de/.
+  - Block requests for elsa.memoinsights.com/t.
+  - Fix a typo in a test.
+  - Disable fast-redirects for launchpad.net/.
+  - Unblock .eff.org/.
+  - Stop unblocking .org/.*(image|banner) which appears to be too generous
+    It let requests like:
+    https://stats.noblogs.org/piwik.php?action_name=anti%20gentrifizierungs%20fest&idsite=10175&rec=1&r=220192&h=17&m=7&s=44&url=https%3A%2F%2Fmuellemcalling.noblogs.org%2F&urlref=https%3A%2F%2Fmuellemcalling.noblogs.org%2Finfostande%2F&_id=&_idn=1&_refts=0&send_image=0&cookie=1&res=1366x768&pv_id=eqr7jX&pf_net=7&pf_srv=3&pf_tfr=2281&pf_dm1=156
+    pass.
+    The example URL http://www.gnu.org/graphics/gnu-head-banner.png is
+    already unblocked due to .gnu.org being unblocked.
+  - Unblock adfd.org/.
+  - Disable filter{banners-by-link} for .eff.org/.
+  - Block requests to odb.outbrain.com/.
+  - Disable fast-redirects for .gandi.net/.
+  - Disable fast-redirects{} for .onion/.*/status/.
+  - Disable fast-redirects{} for twitter.com/.*/status/.
+  - Unblock pinkstinks.de/.
+  - Disable fast-redirects for .hagalil.com/.
+
+- Privoxy-Log-Parser:
+  - Bump version to 0.9.5.
+  - Highlight more log messages.
+  - Highlight the Crunch reason only once. Previously the "crunch reason"
+    could also be highlighted when the URL contained a matching string.
+    The real crunch reason only occurs once per line, so there's no need
+    to continue looking for it after it has been found once.
+    While at it, add a comment with an example log line.
+
+- uagen:
+  - Bump version to 1.2.4.
+  - Update BROWSER_VERSION and BROWSER_REVISION to 102.0
+    to match the User-Agent of the current Firefox ESR.
+  - Explicitly document that changing the 'Gecko token' is suspicious.
+  - Consistently use a lower-case 'c' as copyright symbol.
+  - Bump copyright.
+  - Add 'aarch64' as Linux architecture.
+  - Add OpenBSD architecture 'arm64'.
+  - Stop using sparc64 as FreeBSD architecture.
+    It hasn't been supported for a while now.
+
+- Build system:
+  - Makefile: Add a 'dok' target that depends on the 'error' target
+    to show the "You are not using GNU make or did nor run configure"
+    message.
+  - configure: Fix --with-msan option.
+    Also (probably) reported by Andrew Savchenko.
+
+- macOS build system:
+  - Enable HTTPS inspection when building the macOS binary
+    (using OpenSSL as TLS library).
+
+- Documentation:
+  - Add OpenSSL to the list of libraries that may be licensed under the
+    Apache 2.0 license in which case the linked Privoxy binary has to be
+    distributed under the GPLv3 or later.
+  - config: Fix the documented ca-directory default value.
+    Reported by avoidr.
+  - Rebuild developer-manual and tidy with 'HTML Tidy for FreeBSD version 5.8.0'.
+  - Update developer manual with new macOS packaging instructions.
+  - Note that the FreeBSD installation instructions work for
+    ElectroBSD as well.
+  - Note that FreeBSD/ElectroBSD users can try to install Privoxy
+    as binary package using 'pkg'.
+
+*** Version 3.0.33 stable ***
+- Security/Reliability:
+  - cgi_error_no_template(): Encode the template name to prevent
+    XSS (cross-site scripting) when Privoxy is configured to servce
+    the user-manual itself.
+    Commit 0e668e9409c. OVE-20211102-0001. CVE-2021-44543.
+    Reported by: Artem Ivanov
+  - get_url_spec_param(): Free memory of compiled pattern spec
+    before bailing.
+    Reported by Joshua Rogers (Opera) who also provided the fix.
+    Commit 652b4b7cb0. OVE-20211201-0003. CVE-2021-44540.
+  - process_encrypted_request_headers(): Free header memory when
+    failing to get the request destination.
+    Reported by Joshua Rogers (Opera) who also provided the fix.
+    Commit 0509c58045. OVE-20211201-0002. CVE-2021-44541.
+  - send_http_request(): Prevent memory leaks when handling errors
+    Reported by Joshua Rogers (Opera) who also provided the fix.
+    Commit c48d1d6d08. OVE-20211201-0001. CVE-2021-44542.
 
 - Bug fixes:
   - handle_established_connection(): Skip the poll()/select() calls
@@ -18,39 +168,159 @@ ChangeLog for Privoxy
     when unloading an action file with a TAG pattern while
     Privoxy has been compiled without FEATURE_PCRE_HOST_PATTERNS.
     Closes: SF patch request #147. Patch by Maxim Antonov.
-  - Establish the TLS connection with the client earlier and decide
-    how to route the request afterwards. This allows to change the
-    forwarding settings based on information from the https-inspected
-    request, for example the path.
-    Adjust build_request_line() to create a CONNECT request line when
+  - Adjust build_request_line() to create a CONNECT request line when
     https-inspecting and forwarding to a HTTP proxy.
     Fixes SF bug #925 reported by Wen Yue.
   - load_config(): Add a space that was missing in a log message.
+  - read_http_request_body(): Fix two error messages that used an
+    incorrect variable.
+  - If the the response is chunk-encoded, ignore the Content-Length
+    header sent by the server.
+    Allows to load https://redmine.lighttpd.net/ with filtering enabled.
 
 - General improvements:
+  - Allow to edit the add-header action through the CGI editor by
+    generalizing the code that got added with the suppress-tag action.
+    Closes SF patch request #146. Patch by Maxim Antonov.
+  - Add a CGI handler for /wpad.dat that returns a
+    Proxy Auto-Configuration (PAC) file.
+    Among other things, it can be used to instruct clients
+    through DHCP to use Privoxy as proxy.
+    For example with the dnsmasq option:
+    dhcp-option=252,http://config.privoxy.org/wpad.dat
+    Initial patch by Richard Schneidt.
+  - Don't log the applied actions in process_encrypted_request()
+    Log them in continue_https_chat() instead to mirror chat().
+    Prevents the applied actions from getting logged twice
+    for the first request on an https-inspected connection.
+  - OpenSSL generate_host_certificate(): Use config.privoxy.org as Common Name
+    Org and Org Unit if the real host name is too long to get accepted by OpenSSL.
+    Clients should only care about the Subject Alternative Name
+    anyway and we can continue to use the real host name for it.
+    Reported by Miles Wen on privoxy-users@.
+  - Establish the TLS connection with the client earlier and decide
+    how to route the request afterwards. This allows to change the
+    forwarding settings based on information from the https-inspected
+    request, for example the path.
+  - listen_loop(): When shutting down gracefully, close listening ports
+    before waiting for the threads to exit. Allows to start a second
+    Privoxy with the same config file while the first Privoxy is still
+    running.
   - serve(): Close the client socket as well if the server socket
     for an inspected connection has been closed. Privoxy currently
     can't establish a new server connection when the client socket
     is reused and would drop the connection in continue_https_chat()
     anyway.
-  - Don't disable redirect checkers in redirect_url()
+  - Don't disable redirect checkers in redirect_url().
     Disable them in handle_established_connection() instead.
     Doing it in redirect_url() prevented the +redirect{} and
     +fast-redirects{} actions from being logged with LOG_LEVEL_ACTIONS.
-  - handle_established_connection(): Slightly improve a comment
-  - handle_established_connection(): Fix a comment
+  - handle_established_connection(): Slightly improve a comment.
+  - handle_established_connection(): Fix a comment.
   - socks5_connect(): Fix indentation.
-  - handle_established_connection(): Improve an error message
-  - create_pattern_spec(): Fix ifdef indentation
-  - Fix comment typos
+  - handle_established_connection(): Improve an error message.
+  - create_pattern_spec(): Fix ifdef indentation.
+  - Fix comment typos.
+  - process_encrypted_request(): Improve a log message.
+    The function only processes request headers and there
+    may still be unread request body data left to process.
+  - chat(): Log the applied actions before deciding how to forward the request.
+  - parse_time_header(): Silence a coverity complaint when building without assertions.
+  - receive_encrypted_request_headers(): Improve a log message.
+  - mbedTLS get_ciphersuites_from_string(): Use strlcpy() instead of strncpy().
+    Previously the terminating NUL wasn't copied which resulted
+    in a compiler warning. This didn't cause actual problems as
+    the target buffer was initialized by zalloc_or_die() so the
+    last byte of the target buffer was NUL already.
+    Actually copying the terminating NUL seems clearer, though.
+  - Remove compiler warnings. "log_error(LOG_LEVEL_FATAL, ..."
+    doesn't return but apparently the compiler doesn't know that.
+    Get rid of several "this statement may fall through
+    [-Wimplicit-fallthrough=]" warnings.
+  - Store the PEM certificate in a dynamically allocated buffer
+    when https-inspecting. Should prevent errors like:
+    2021-03-16 22:36:19.148 7f47bbfff700 Error: X509 PEM cert len 16694 is larger than buffer len 16383
+    As a bonus it should slightly reduce the memory usage as most
+    certificates are smaller than the previously used fixed buffer.
+    Reported by: Wen Yue
+  - OpenSSL generate_host_certificate(): Fix two error messsages.
+  - Improve description of handle_established_connection()
+  - OpenSSL ssl_store_cert(): Translate EVP_PKEY_EC to a string.
+  - OpenSSL ssl_store_cert(): Remove pointless variable initialization.
+  - OpenSSL ssl_store_cert(): Initialize pointer with NULL instead of 0.
 
 - Action file improvements:
   - Disable fast-redirects for .microsoftonline.com/.
   - Disable fast-redirects for idp.springer.com/.
+  - Disable fast-redirects for .zeit.de/zustimmung.
+  - Unblock adv-archiv.dfn-cert.de/.
+  - Block requests to eu-tlp01.kameleoon.eu/.
+  - Block requests to fpa-events.arstechnica.com/.
+  - Unblock nlnet.nl/.
+  - Unblock adguard.com/.
+
+- Privoxy-Log-Parser:
+  - Highlight 'Socket timeout 3 reached: http://127.0.0.1:20000/no-filter/chunked-content/36'.
+  - Improve documentation for inactivity-detection mode.
+  - Detect date changes when looking for inactivity.
+  - Add a --passed-request-statistics-threshold option
+    that can be set to get statistics for requests that
+    were passed.
+  - Add a "inactivity detection" mode which can be useful
+    for debugging purposes.
+  - Bump version to 0.9.4.
+  - Only run print_intro() and print_outro() when syntax highlighting.
+  - Rephrase a sentence in the documentation.
+  - Highlight 'Client socket 7 is no longer usable. The server socket has been closed.'.
+  - Clarify --statistics output by explicitly mentioning that
+    the status codes sent by the server may differ from the ones
+    in "debug 512" messages.
+  - Fix typo in the --statistics output.
+  - Remove an unused variable.
+  - Highlight 'The peer notified us that the connection on socket 11 is going to be closed'.
 
 - Privoxy-Regression-Test:
   - Remove duplicated word in a comment.
 
+- regression-tests.action:
+  - Add fetch test for http://p.p/wpad.dat.
+  - Bump for-privoxy-version to 3.0.33 which introduced the wpad.dat support.
+  - Add more tests for the '/send-banner' code.
+  - Add test for OVE-20210203-0001.
+  - Add a test for CVE-2021-20217.
+
+- uagen:
+  - Bump generated Firefox version to 91 (ESR).
+  - Bump version to 1.2.3.
+  - Bump copyright.
+
+- Build system:
+  - configure: Bump SOURCE_DATE_EPOCH.
+  - GNUmakefile.in: Fix typo.
+  - configure: Add another warning in case --disable-pthread
+    is used while POSIX threads are available.
+    Various features don't even compile when not using threads.
+  - Add configure option to enable MemorySanitizer.
+  - Add configure option to enable UndefinedBehaviorSanitizer.
+  - Add configure option to enable AddressSanitizer.
+  - Bump copyright.
+  - Add a configure option to disable pcre JIT compilation.
+    While JIT compilation makes filtering faster it can
+    cause false-positive valgrind complaints.
+    As reported by Gwyn Ciesla in SF bug 924 it also can
+    cause problems when the SELinux policy does not grant
+    Privoxy "execmem" privileges.
+  - configure: Remove obsolete RPM_BASE check.
+
+- Windows build system:
+  - Update the build script to use mbed tls version 2.6.11.
+  - Update build script to use the final 8.45 pcre library.
+  - Put all the '--enable-xxx' options in the configure call together.
+
+- macOS build system:
+  - The OSXPackageBuilder repository has been updated and
+    can be used to create macOS packages again.
+
 - Documentation:
   - contacting: Remove obsolete reference to announce.sgml.
   - contacting: Request that the browser cache is cleared before
@@ -61,6 +331,24 @@ ChangeLog for Privoxy
     filter https responses.
   - developer-manual: Mention that announce.txt should be updated
     when doing a release.
+  - config: Explicitly mention that the CGI pages disclosing the
+    ca-password can be blocked and upgrade the disclosure paragraphs
+    to a warning.
+  - Put all the requested debug options in the config file.
+    Section 11.1 of the Privoxy user manual lists all the debug
+    options that should be enabled when reporting problems or requesting support.
+    Make it easier for users to do the right thing by having all those
+    options present in the config.
+  - Update TODO list item #184 to note that WolfSSL support will
+    (hopefully) appear after the 3.0.34 release.
+  - Update max-client-connections's description.
+    On modern systems other than Windows Privoxy should
+    use poll() in which case the FD_SETSIZE value isn't
+    releveant.
+  - Add a warning that the socket-timeout does not apply
+    to operations done by TLS libraries.
+  - Make documentation slightly less "offensive" for some people
+    by avoiding the word "hell".
 
 *** Version 3.0.32 stable ***
 
@@ -3241,7 +3529,7 @@ being a mix of "U.S. English", "U.K. English" and "Irish English".
 
 
 ----------------------------------------------------------------------
-Copyright   :  Written by and Copyright (C) 2001-2021 the
+Copyright   :  Written by and Copyright (C) 2001-2023 the
                Privoxy team. https://www.privoxy.org/
 
                Based on the Internet Junkbuster originally written
index 9476426..cf79aae 100644 (file)
@@ -243,6 +243,10 @@ OPENSSL_SRC      = @FEATURE_HTTPS_INSPECTION_ONLY_OPENSSL@openssl.c
 OPENSSL_OBJS     = @FEATURE_HTTPS_INSPECTION_ONLY_OPENSSL@$(OPENSSL_SRC:.c=.o)
 OPENSSL_HDRS     = @FEATURE_HTTPS_INSPECTION_ONLY_OPENSSL@$(OPENSSL_SRC:.c=.h)
 
+WOLFSSL_SRC      = @FEATURE_HTTPS_INSPECTION_ONLY_WOLFSSL@wolfssl.c
+WOLFSSL_OBJS     = @FEATURE_HTTPS_INSPECTION_ONLY_WOLFSSL@$(WOLFSSL_SRC:.c=.o)
+WOLFSSL_HDRS     = @FEATURE_HTTPS_INSPECTION_ONLY_WOLFSSL@$(WOLFSSL_SRC:.c=.h)
+
 PCRS_SRC     = @STATIC_PCRS_ONLY@pcrs.c
 PCRS_OBJS    = @STATIC_PCRS_ONLY@$(PCRS_SRC:.c=.@OBJEXT@)
 PCRS_HDRS    = @STATIC_PCRS_ONLY@$(PCRS_SRC:.c=.h)
@@ -262,9 +266,9 @@ SOCKET_LIB   = @SOCKET_LIB@
 # PThreads library, if needed.
 PTHREAD_LIB  = @PTHREAD_ONLY@@PTHREAD_LIB@
 
-SRCS         = $(C_SRC) $(CLIENT_TAG_SRC) $(FUZZ_SRC) $(W32_SRC) $(PCRS_SRC) $(REGEX_SRC) $(SSL_SRC) $(MBEDTLS_SRC) $(OPENSSL_SRC)
-OBJS         = $(C_OBJS) $(CLIENT_TAG_OBJS) $(FUZZ_OBJS) $(W32_OBJS) $(PCRS_OBJS) $(REGEX_OBJS) $(SSL_OBJS) $(MBEDTLS_OBJS) $(OPENSSL_OBJS)
-HDRS         = $(C_HDRS) $(W32_HDRS) $(PCRS_HDRS) $(REGEX_HDRS) $(SSL_HDRS) $(MBEDTLS_HDRS) $(OPENSSL_HDRS)
+SRCS         = $(C_SRC) $(CLIENT_TAG_SRC) $(FUZZ_SRC) $(W32_SRC) $(PCRS_SRC) $(REGEX_SRC) $(SSL_SRC) $(MBEDTLS_SRC) $(OPENSSL_SRC) $(WOLFSSL_SRC)
+OBJS         = $(C_OBJS) $(CLIENT_TAG_OBJS) $(FUZZ_OBJS) $(W32_OBJS) $(PCRS_OBJS) $(REGEX_OBJS) $(SSL_OBJS) $(MBEDTLS_OBJS) $(OPENSSL_OBJS) $(WOLFSSL_OBJS)
+HDRS         = $(C_HDRS) $(W32_HDRS) $(PCRS_HDRS) $(REGEX_HDRS) $(SSL_HDRS) $(MBEDTLS_HDRS) $(OPENSSL_HDRS) $(WOLFSSL_HDRS)
 LIBS         = @LIBS@ $(W32_LIB) $(SOCKET_LIB) $(PTHREAD_LIB)
 
 
@@ -440,7 +444,7 @@ tarball-dist: dist-check clean clobber
        for i in `find . -type f -a -not \( -path "*/CVS*" -o -name ".*" \
        -o -path "*/debian/*" -o -path "*/actions/*" -o -name "*.php" -o \
        -name "PACKAGERS" -o -path "*.git/*" \
-       -o -path "*/doc/webserver/feeds*" \) | sort`; do \
+       -o -path "*/doc/webserver/feeds*" \) | sort | $(SED) 's@^\./@@'`; do \
           files="$$files privoxy-$(VERSION)-$(CODE_STATUS)/$$i"; \
        done &&  \
        cd .. && $(TAR) -cvhf privoxy-$(VERSION)-$(CODE_STATUS)-src.tar $$files ; \
@@ -923,7 +927,6 @@ install: CONF_DEST LOG_DEST PID_DEST check_doc GROUP_T
                                        $(ECHO)  " and to install the config files as that user and/or group!" ;\
                                        $(ECHO)  " Please read INSTALL, and create a privoxy user and group!" ;\
                                        $(ECHO)  "*******************************************************************" ;\
-                                       exit 1 ;\
                                fi ;\
                        else \
                                GROUP_T=$(GROUP) ;\
diff --git a/INSTALL b/INSTALL
index c8e1f96..cdc5cb2 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -39,8 +39,8 @@ compiler like gcc are required.
 
 When building from a source tarball, first unpack the source:
 
-  tar xzvf privoxy-3.0.33-stable-src.tar.gz
-  cd privoxy-3.0.33-stable
+  tar xzvf privoxy-3.0.35-beta-src.tar.gz
+  cd privoxy-3.0.35-beta
 
 To build the development version, you can get the source code by doing:
 
index 493643f..2dc8180 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -70,6 +70,8 @@ error:
 
 .PHONY: error
 
+dok: error
+
 #############################################################################
 
 ## Local Variables:
diff --git a/README b/README
index 2b03991..7078748 100644 (file)
--- a/README
+++ b/README
@@ -32,8 +32,9 @@
  *
  *********************************************************************/
 
-This README is included with Privoxy 3.0.33. See https://www.privoxy.org/ for
-more information. The current code maturity level is "stable".
+This README is included with the development version of Privoxy 3.0.35. See
+https://www.privoxy.org/ for more information. The current code maturity level
+is "UNRELEASED", but seems stable to us :).
 
 -------------------------------------------------------------------------------
 
@@ -104,16 +105,22 @@ try it with FTP or other protocols for the simple reason it does not work.
 The actions list can be configured via the web interface accessed via http://
 p.p/, as well other options.
 
+All configuration files are subject to unannounced changes during the
+development process.
+
 -------------------------------------------------------------------------------
 
 5. DOCUMENTATION
 
-There should be documentation in the 'doc' subdirectory. In particular, see the
-User Manual there, the FAQ, and those interested in Privoxy development, should
-look at developer-manual.
+There should be documentation in the 'doc' subdirectory, but it may not be
+completed at this point. In particular, see the User Manual there, the FAQ, and
+those interested in Privoxy development, should look at developer-manual.
 
-The source and configuration files are all well commented. The main
-configuration files are: 'config', 'default.action', and 'default.filter'.
+The most up to date source of information on the current development version,
+may still be either comments in the source code, or the included configuration
+files. The source and configuration files are all well commented. The main
+configuration files are: 'config', 'default.action', and 'default.filter' in
+the top-level source directory.
 
 Included documentation may vary according to platform and packager. All
 documentation is posted on https://www.privoxy.org, in case you don't have it,
diff --git a/TODO b/TODO
index 11b4d80..f6c839f 100644 (file)
--- a/TODO
+++ b/TODO
@@ -377,7 +377,7 @@ https://www.privoxy.org/donate
      currently can result in client requests to config.privoxy.org on the
      Internet which may not be desirable.
 
-150) Add blacklistd support.
+150) Add blocklistd support (https://man.netbsd.org/blocklistd.8).
 
 151) Let the dok-tidy target work cross-platform without introducing
      a ton of white-space changes that hide the content changes.
@@ -422,10 +422,6 @@ https://www.privoxy.org/donate
 163) Use subdirectories in the certificate-directory to lower the number
      of files per directory.
 
-164) Evaluate switching from pcreposix(3) to pcre's native api
-     for URL matching which allows to compile the patterns once
-     at load-time.
-
 165) Add a max-connections-per-client directive.
 
 167) Set up a public Privoxy-Filter-Test instance.
@@ -532,6 +528,22 @@ https://www.privoxy.org/donate
 200) Add a config directive that causes Privoxy to remove all
      host certificates before exiting.
 
+201) Add an action to change the trusted-cas-file for a section.
+     This should be useful in countries where a person-in-the-middle
+     attack is known to happen on some domains but should not be tolerated
+     on others. It would also allow to limit the accepted CA certificates
+     for given domains instead of accepting all that are specified with
+     the trusted-cas-file directive.
+
+202) Allow to use multiple log files with different debug settings.
+     Suggested by Jonathan Marten in FR#607.
+
+203) Add HTTP/2 support.
+
+204) Make the Privoxy website available over IPv6.
+
+205) Document how commit messages should look like.
+
 ##########################################################################
 
 Hosting wish list (relevant for #53)
index dbf443b..9fbe5a7 100644 (file)
 /* Define if pcre.h must be included as <pcre/pcre.h>
  */
 #undef PCRE_H_IN_SUBDIR
+#undef PCRE2_H_IN_SUBDIR
+
+#undef HAVE_PCRE2
+#undef HAVE_PCRE2POSIX
 
 /* Define if pcreposix.h must be included as <pcre/pcreposix.h>
  */
 #undef PCREPOSIX_H_IN_SUBDIR
 
+#undef PCRE2POSIX_H_IN_SUBDIR
+
 @BOTTOM@
 
 /*
index fc7f514..d95b822 100644 (file)
@@ -57,6 +57,7 @@ DEFINE_ACTION_STRING     ("change-x-forwarded-for",     ACTION_CHANGE_X_FORWARDE
 DEFINE_CGI_PARAM_RADIO   ("change-x-forwarded-for",     ACTION_CHANGE_X_FORWARDED_FOR,  ACTION_STRING_CHANGE_X_FORWARDED_FOR, "block", 0)
 DEFINE_CGI_PARAM_RADIO   ("change-x-forwarded-for",     ACTION_CHANGE_X_FORWARDED_FOR,  ACTION_STRING_CHANGE_X_FORWARDED_FOR, "add", 1)
 DEFINE_ACTION_MULTI      ("client-body-filter",         ACTION_MULTI_CLIENT_BODY_FILTER)
+DEFINE_ACTION_MULTI      ("client-body-tagger",         ACTION_MULTI_CLIENT_BODY_TAGGER)
 DEFINE_ACTION_MULTI      ("client-header-filter",       ACTION_MULTI_CLIENT_HEADER_FILTER)
 DEFINE_ACTION_MULTI      ("client-header-tagger",       ACTION_MULTI_CLIENT_HEADER_TAGGER)
 DEFINE_ACTION_STRING     ("content-type-overwrite",     ACTION_CONTENT_TYPE_OVERWRITE, ACTION_STRING_CONTENT_TYPE)
index a80ee64..9fd3249 100644 (file)
--- a/actions.c
+++ b/actions.c
@@ -829,7 +829,7 @@ int update_action_bits_for_tag(struct client_state *csp, const char *tag)
          }
 
          /* and check if one of the tag patterns matches the tag, */
-         if (0 == regexec(b->url->pattern.tag_regex, tag, 0, NULL, 0))
+         if (regex_matches(b->url->pattern.tag_regex, tag))
          {
             /* if it does, update the action bit map, */
             if (merge_current_action(csp->action, b->action))
@@ -884,7 +884,7 @@ jb_err check_negative_tag_patterns(struct client_state *csp, unsigned int flag)
          }
          for (tag = csp->tags->first; NULL != tag; tag = tag->next)
          {
-            if (0 == regexec(b->url->pattern.tag_regex, tag->str, 0, NULL, 0))
+            if (regex_matches(b->url->pattern.tag_regex, tag->str))
             {
                /*
                 * The pattern matches at least one tag, thus the action
@@ -1115,6 +1115,8 @@ static const char *filter_type_to_string(enum filter_type filter_type)
       return "suppress tag filter";
    case FT_CLIENT_BODY_FILTER:
       return "client body filter";
+   case FT_CLIENT_BODY_TAGGER:
+      return "client body tagger";
    case FT_ADD_HEADER:
       return "add-header action";
 #ifdef FEATURE_EXTERNAL_FILTERS
diff --git a/cgi.c b/cgi.c
index cb1f072..d60166f 100644 (file)
--- a/cgi.c
+++ b/cgi.c
@@ -7,7 +7,7 @@
  *                This only contains the framework functions, the
  *                actual handler functions are declared elsewhere.
  *
- * Copyright   :  Written by and Copyright (C) 2001-2020
+ * Copyright   :  Written by and Copyright (C) 2001-2021
  *                members of the Privoxy team. https://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
@@ -1199,7 +1199,8 @@ jb_err cgi_error_no_template(const struct client_state *csp,
       ").</p>\n"
       "</body>\n"
       "</html>\n";
-   const size_t body_size = strlen(body_prefix) + strlen(template_name) + strlen(body_suffix) + 1;
+   size_t body_size = strlen(body_prefix) + strlen(body_suffix) + 1;
+   const char *encoded_template_name;
 
    assert(csp);
    assert(rsp);
@@ -1213,9 +1214,17 @@ jb_err cgi_error_no_template(const struct client_state *csp,
    rsp->head_length = 0;
    rsp->is_static = 0;
 
+   encoded_template_name = html_encode(template_name);
+   if (encoded_template_name == NULL)
+   {
+      return JB_ERR_MEMORY;
+   }
+
+   body_size += strlen(encoded_template_name);
    rsp->body = malloc_or_die(body_size);
    strlcpy(rsp->body, body_prefix, body_size);
-   strlcat(rsp->body, template_name, body_size);
+   strlcat(rsp->body, encoded_template_name, body_size);
+   freez(encoded_template_name);
    strlcat(rsp->body, body_suffix, body_size);
 
    rsp->status = strdup(status);
@@ -2014,7 +2023,7 @@ jb_err template_fill(char **template_ptr, const struct map *exports)
    char buf[BUFFER_SIZE];
    char *tmp_out_buffer;
    char *file_buffer;
-   size_t size;
+   size_t buffer_size, new_size;
    int error;
    const char *flags;
 
@@ -2023,7 +2032,7 @@ jb_err template_fill(char **template_ptr, const struct map *exports)
    assert(exports);
 
    file_buffer = *template_ptr;
-   size = strlen(file_buffer) + 1;
+   buffer_size = strlen(file_buffer) + 1;
 
    /*
     * Assemble pcrs joblist from exports map
@@ -2073,7 +2082,10 @@ jb_err template_fill(char **template_ptr, const struct map *exports)
       }
       else
       {
-         error = pcrs_execute(job, file_buffer, size, &tmp_out_buffer, &size);
+         error = pcrs_execute(job, file_buffer, buffer_size, &tmp_out_buffer,
+            &new_size);
+
+         buffer_size = new_size;
 
          pcrs_free_job(job);
          if (NULL == tmp_out_buffer)
index 3b8b12c..80f20d8 100644 (file)
--- a/cgiedit.c
+++ b/cgiedit.c
@@ -12,7 +12,7 @@
  *
  *                Stick to the short names in this file for consistency.
  *
- * Copyright   :  Written by and Copyright (C) 2001-2014 the
+ * Copyright   :  Written by and Copyright (C) 2001-2023 the
  *                Privoxy team. https://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
@@ -252,6 +252,12 @@ static const struct action_type_info action_type_info[] =
       "client-body-filter-all", "client_body_filter_all",
       "P", "CLIENT-BODY-FILTER"
    },
+   {
+      ACTION_MULTI_CLIENT_BODY_TAGGER,
+      "client-body-tagger-params", "client-body-tagger",
+      "client-body-tagger-all", "client_body_tagger_all",
+      "Q", "CLIENT-BODY-TAGGER"
+   },
    {
       ACTION_MULTI_ADD_HEADER,
       "add-header-params", "add-header",
@@ -363,38 +369,6 @@ static jb_err get_file_name_param(struct client_state *csp,
                                           const char *param_name,
                                           const char **pfilename);
 
-/* Internal convenience functions */
-static char *section_target(const unsigned sectionid);
-
-/*********************************************************************
- *
- * Function    :  section_target
- *
- * Description :  Given an unsigned (section id) n, produce a dynamically
- *                allocated string of the form #l<n>, for use in link
- *                targets.
- *
- *                XXX: The hash should be moved into the templates
- *                to make this function more generic and render
- *                stringify() obsolete.
- *
- * Parameters  :
- *          1  :  sectionid = start line number of section
- *
- * Returns     :  String with link target, or NULL if out of
- *                memory
- *
- *********************************************************************/
-static char *section_target(const unsigned sectionid)
-{
-   char buf[30];
-
-   snprintf(buf, sizeof(buf), "#l%u", sectionid);
-   return(strdup(buf));
-
-}
-
-
 /*********************************************************************
  *
  * Function    :  stringify
@@ -552,7 +526,7 @@ jb_err cgi_edit_actions_url_form(struct client_state *csp,
    if (!err) err = map(exports, "v", 1, file->version_str, 1);
    if (!err) err = map(exports, "p", 1, url_encode(lookup(parameters, "p")), 0);
    if (!err) err = map(exports, "u", 1, html_encode(cur_line->unprocessed), 0);
-   if (!err) err = map(exports, "jumptarget", 1, section_target(section_start_line_number), 0);
+   if (!err) err = map(exports, "jumptarget", 1, stringify(section_start_line_number), 0);
 
    edit_free_file(file);
 
@@ -712,7 +686,7 @@ jb_err cgi_edit_actions_remove_url_form(struct client_state *csp,
    if (!err) err = map(exports, "v", 1, file->version_str, 1);
    if (!err) err = map(exports, "p", 1, url_encode(lookup(parameters, "p")), 0);
    if (!err) err = map(exports, "u", 1, html_encode(cur_line->unprocessed), 0);
-   if (!err) err = map(exports, "jumptarget", 1, section_target(section_start_line_number), 0);
+   if (!err) err = map(exports, "jumptarget", 1, stringify(section_start_line_number), 0);
    if (!err) err = map(exports, "actions-file", 1, html_encode(file->filename), 0);
 
    edit_free_file(file);
@@ -1899,12 +1873,12 @@ static jb_err get_url_spec_param(struct client_state *csp,
    }
    err = create_pattern_spec(compiled, s);
    free(s);
+   free_pattern_spec(compiled);
    if (err)
    {
       free(param);
       return (err == JB_ERR_MEMORY) ? JB_ERR_MEMORY : JB_ERR_CGI_PARAMS;
    }
-   free_pattern_spec(compiled);
 
    if (param[strlen(param) - 1] == '\\')
    {
@@ -1935,12 +1909,12 @@ static jb_err get_url_spec_param(struct client_state *csp,
       }
       err = create_pattern_spec(compiled, s);
       free(s);
+      free_pattern_spec(compiled);
       if (err)
       {
          free(param);
          return (err == JB_ERR_MEMORY) ? JB_ERR_MEMORY : JB_ERR_CGI_PARAMS;
       }
-      free_pattern_spec(compiled);
    }
 
    *pvalue = param;
@@ -2797,8 +2771,8 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp,
 
    for (i = 0; !err && i < SZ(string_action_type_info); i++)
    {
-      err = action_render_string_actions_template(exports, cur_line->data.action, filter_template,
-                                                  &string_action_type_info[i]);
+      err = action_render_string_actions_template(exports,
+         cur_line->data.action, filter_template, &string_action_type_info[i]);
    }
    freez(filter_template);
 
@@ -2891,7 +2865,7 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp,
          if ((csp->rlist[i] != NULL) && (csp->rlist[i]->f != NULL))
          {
             filter_group = csp->rlist[i]->f;
-            for (;(!err) && (filter_group != NULL); filter_group = filter_group->next)
+            for (; (!err) && (filter_group != NULL); filter_group = filter_group->next)
             {
                char current_mode = 'x';
                char number[20];
@@ -2901,6 +2875,7 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp,
                const int multi_action_index = action_type_info[type].multi_action_index;
 
                assert(type < MAX_FILTER_TYPES);
+               assert(multi_action_index < ACTION_MULTI_COUNT);
 
                filter_name = cur_line->data.action->multi_add[multi_action_index]->first;
                while ((filter_name != NULL)
@@ -4487,8 +4462,9 @@ static jb_err actions_to_radio(struct map * exports,
  *
  * Function    :  action_render_string_actions_template
  *
- * Description :  Converts a actionsfile entry into HTML template for actions with string
- *                filters (currently SUPPRESS-TAG actions only)
+ * Description : Converts an actionsfile entry into HTML template for
+ *               actions with string filters (currently SUPPRESS-TAG
+ *               actions only)
  *
  * Parameters  :
  *          1  :  exports = List of substitutions to add to.
@@ -4500,9 +4476,9 @@ static jb_err actions_to_radio(struct map * exports,
  *                JB_ERR_MEMORY on out-of-memory
  *
  *********************************************************************/
-static jb_err action_render_string_actions_template(struct map * exports,
+static jb_err action_render_string_actions_template(struct map *exports,
                                        const struct action_spec *action,
-                                       const charaction_template,
+                                       const char *action_template,
                                        const struct string_action_type_info *string_action_type)
 {
    jb_err err = JB_ERR_OK;
@@ -4516,6 +4492,8 @@ static jb_err action_render_string_actions_template(struct map * exports,
        struct list_entry *list;
    };
 
+   assert(type->multi_action_index < ACTION_MULTI_COUNT);
+
    struct action_multi desc[] = {
        { 'y', action->multi_add[type->multi_action_index][0].first },
        { 'n', action->multi_remove[type->multi_action_index][0].first }
index 9650627..961510f 100644 (file)
@@ -5,7 +5,7 @@
  * Purpose     :  Simple CGIs to get information about Privoxy's
  *                status.
  *
- * Copyright   :  Written by and Copyright (C) 2001-2021 the
+ * Copyright   :  Written by and Copyright (C) 2001-2022 the
  *                Privoxy team. https://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
@@ -1262,9 +1262,15 @@ jb_err cgi_show_status(struct client_state *csp,
 
    char buf[BUFFER_SIZE];
 #ifdef FEATURE_STATISTICS
+#ifdef MUTEX_LOCKS_AVAILABLE
+   float percentage_blocked;
+   unsigned long long local_number_of_requests_received;
+   unsigned long long local_number_of_requests_blocked;
+#else
    float perc_rej;   /* Percentage of http requests rejected */
    int local_urls_read;
    int local_urls_rejected;
+#endif
 #endif /* ndef FEATURE_STATISTICS */
    jb_err err = JB_ERR_OK;
 
@@ -1302,9 +1308,15 @@ jb_err cgi_show_status(struct client_state *csp,
    }
 
 #ifdef FEATURE_STATISTICS
+#ifdef MUTEX_LOCKS_AVAILABLE
+   privoxy_mutex_lock(&block_statistics_mutex);
+   local_number_of_requests_received = number_of_requests_received;
+   local_number_of_requests_blocked = number_of_requests_blocked;
+   privoxy_mutex_unlock(&block_statistics_mutex);
+#else
    local_urls_read     = urls_read;
    local_urls_rejected = urls_rejected;
-
+#endif
    /*
     * Need to alter the stats not to include the fetch of this
     * page.
@@ -1315,7 +1327,11 @@ jb_err cgi_show_status(struct client_state *csp,
     * urls_rejected--; * This will be incremented subsequently *
     */
 
+#ifdef MUTEX_LOCKS_AVAILABLE
+   if (local_number_of_requests_received == 0)
+#else
    if (local_urls_read == 0)
+#endif
    {
       if (!err) err = map_block_killer(exports, "have-stats");
    }
@@ -1323,6 +1339,19 @@ jb_err cgi_show_status(struct client_state *csp,
    {
       if (!err) err = map_block_killer(exports, "have-no-stats");
 
+#ifdef MUTEX_LOCKS_AVAILABLE
+      percentage_blocked = (float)local_number_of_requests_blocked * 100.0F /
+            (float)local_number_of_requests_received;
+
+      snprintf(buf, sizeof(buf), "%llu", local_number_of_requests_received);
+      if (!err) err = map(exports, "requests-received", 1, buf, 1);
+
+      snprintf(buf, sizeof(buf), "%llu", local_number_of_requests_blocked);
+      if (!err) err = map(exports, "requests-blocked", 1, buf, 1);
+
+      snprintf(buf, sizeof(buf), "%6.2f", percentage_blocked);
+      if (!err) err = map(exports, "percent-blocked", 1, buf, 1);
+#else
       perc_rej = (float)local_urls_rejected * 100.0F /
             (float)local_urls_read;
 
@@ -1334,6 +1363,7 @@ jb_err cgi_show_status(struct client_state *csp,
 
       snprintf(buf, sizeof(buf), "%6.2f", perc_rej);
       if (!err) err = map(exports, "percent-blocked", 1, buf, 1);
+#endif
    }
 
 #else /* ndef FEATURE_STATISTICS */
index 51e8a9c..d8cbb35 100644 (file)
@@ -43,6 +43,7 @@
 #include "miscutil.h"
 #include "errlog.h"
 #include "parsers.h"
+#include "urlmatch.h"
 
 struct client_specific_tag
 {
@@ -658,7 +659,7 @@ int client_tag_match(const struct pattern_spec *pattern,
 
    for (tag = tags->first; tag != NULL; tag = tag->next)
    {
-      if (0 == regexec(pattern->pattern.tag_regex, tag->str, 0, NULL, 0))
+      if (regex_matches(pattern->pattern.tag_regex, tag->str))
       {
          log_error(LOG_LEVEL_TAGGING, "Client tag '%s' matches.", tag->str);
          return 1;
diff --git a/config b/config
index c38b7f5..779a216 100644 (file)
--- a/config
+++ b/config
@@ -1,6 +1,6 @@
-#        Sample Configuration File for Privoxy 3.0.33
+#        Sample Configuration File for Privoxy 3.0.34
 #
-# Copyright (C) 2001-2021 Privoxy Developers https://www.privoxy.org/
+# Copyright (C) 2001-2023 Privoxy Developers https://www.privoxy.org/
 #
 #####################################################################
 #                                                                   #
@@ -15,7 +15,7 @@
 #        4. ACCESS CONTROL AND SECURITY                             #
 #        5. FORWARDING                                              #
 #        6. MISCELLANEOUS                                           #
-#        7. HTTPS INSPECTION (EXPERIMENTAL)                         #
+#        7. HTTPS INSPECTION                                        #
 #        8. WINDOWS GUI OPTIONS                                     #
 #                                                                   #
 #####################################################################
 #
 #  Notes:
 #
-#      The value of this option only matters if the experimental
-#      trust mechanism has been activated. (See trustfile below.)
+#      The value of this option only matters if the trust mechanism
+#      has been activated. (See trustfile below.)
 #
 #      If you use the trust mechanism, it is a good idea to write up
 #      some on-line documentation about your trust policy and to
@@ -2442,8 +2442,8 @@ socket-timeout 300
 #            receive-buffer-size 32768
 #
 #
-#  7. HTTPS INSPECTION (EXPERIMENTAL)
-#  ===================================
+#  7. HTTPS INSPECTION
+#  ====================
 #
 #  HTTPS inspection allows to filter encrypted requests and
 #  responses. This is only supported when Privoxy has been built with
@@ -2465,7 +2465,7 @@ socket-timeout 300
 #
 #  Default value:
 #
-#      Empty string
+#      ./CA
 #
 #  Effect if unset:
 #
index 10cf704..1f7256d 100644 (file)
@@ -1,6 +1,6 @@
 dnl Process this file with autoconf to produce a configure script.
 dnl
-dnl Written by and Copyright (C) 2001-2021 the
+dnl Written by and Copyright (C) 2001-2023 the
 dnl Privoxy team. https://www.privoxy.org/
 dnl
 dnl Based on the Internet Junkbuster originally written
@@ -80,12 +80,12 @@ dnl release and no new release is near.
 
 VERSION_MAJOR=3
 VERSION_MINOR=0
-VERSION_POINT=33
-CODE_STATUS="stable"
+VERSION_POINT=35
+CODE_STATUS="UNRELEASED"
 
 dnl Timestamp (date +%s) used by the mtree-spec target.
 dnl Should be updated before releases but forgetting it isn't critical.
-SOURCE_DATE_EPOCH=1636218132
+SOURCE_DATE_EPOCH=1672586827
 
 dnl =================================================================
 dnl Substitute the version numbers
@@ -168,7 +168,7 @@ if test "x$with_asan" = "xyes"; then
     LDFLAGS="$LDFLAGS -fsanitize=address"
 fi
 
-AC_ARG_WITH(asan, [  --with-msan       Enable MemorySanitizer. Requires compiler support.])
+AC_ARG_WITH(msan, [  --with-msan       Enable MemorySanitizer. Requires compiler support.])
 if test "x$with_msan" = "xyes"; then
     CFLAGS="$CFLAGS -fsanitize=memory"
     LDFLAGS="$LDFLAGS -fsanitize=memory"
@@ -216,7 +216,7 @@ else
         ],
         [
           if test $ID = no ; then
-            AC_MSG_ERROR(There is no 'id' programm on this system)
+            AC_MSG_ERROR(There is no 'id' program on this system)
           else
             AC_MSG_RESULT(none specified)
             USER=$with_user
@@ -255,7 +255,7 @@ else
         ],
         [
           if test $BGROUPS = no ; then
-            AC_MSG_ERROR(There is no 'groups' programm on this system)
+            AC_MSG_ERROR(There is no 'groups' program on this system)
           else
             AC_MSG_RESULT(none specified)
             GROUP=$with_group;
@@ -615,9 +615,9 @@ AC_CHECK_FUNC(gmtime_r, [
   AC_TRY_COMPILE([
 #   include <time.h>
   ], [
-    struct time *t;
-    struct tm *tm;
-    (void) gmtime_r(t, tm)
+    time_t t;
+    struct tm tm;
+    (void) gmtime_r(&t, &tm)
   ], [
     AC_MSG_RESULT(ok)
     AC_DEFINE(HAVE_GMTIME_R)
@@ -633,9 +633,9 @@ AC_CHECK_FUNC(localtime_r, [
   AC_TRY_COMPILE([
 #   include <time.h>
   ], [
-    struct time *t;
-    struct tm *tm;
-    (void) localtime_r(t, tm)
+    time_t t;
+    struct tm tm;
+    (void) localtime_r(&t, &tm)
   ], [
     AC_MSG_RESULT(ok)
     AC_DEFINE(HAVE_LOCALTIME_R)
@@ -863,12 +863,48 @@ else
   ])
 fi
 
+AC_ARG_ENABLE(pcre2,
+[  --disable-pcre2                  Don't try to use pcre2 even if it's available],
+[enableval2=$enableval],
+[enableval2=yes])
+if test $enableval2 = yes; then
+  try_pcre2=yes
+else
+  AC_MSG_WARN([Ignoring pcre2 even if it's available])
+  try_pcre2=no
+  have_pcre2=no
+fi
+
+if test $try_pcre2 != no; then
 dnl =================================================================
 dnl Checks for libraries.
 dnl =================================================================
 dnl Note: Some systems may have the library but not the system header
 dnl       file, so we must check for both.
 dnl       Also check for correct version
+AC_CHECK_LIB(pcre2-8, pcre2_compile_8, [
+   AC_CHECK_HEADER(pcre2.h, [
+      AC_EGREP_HEADER(pcre2_pattern_info, pcre2.h,[have_pcre2=yes; AC_DEFINE(HAVE_PCRE2)], [AC_MSG_WARN([[pcre2 old version installed]]); have_pcre2=no])
+   ], [
+      AC_CHECK_HEADER(pcre2/pcre2.h, [
+         AC_EGREP_HEADER(pcre2_pattern_info, pcre2/pcre2.h, [have_pcre2=yes; AC_DEFINE(PCRE2_H_IN_SUBDIR)], [AC_MSG_WARN([[pcre2 old version installed]]); have_pcre2=no])
+      ], [have_pcre2=no])
+   ], [#define PCRE2_CODE_UNIT_WIDTH 8])
+], [have_pcre2=no])
+
+AC_CHECK_LIB(pcre2-posix, regcomp, [
+   AC_CHECK_HEADER(pcre2posix.h, [
+      AC_EGREP_HEADER(pcre2_regerror, pcre2posix.h, [have_pcre2posix=yes],[AC_MSG_WARN([[pcre2posix old version installed]]); have_pcre2posix=no])
+   ], [
+      AC_CHECK_HEADER(pcre/pcre2posix.h, [
+         AC_EGREP_HEADER(pcre2_regerror, pcre2/pcre2posix.h,  [have_pcre2posix=yes; AC_DEFINE(PCRE2POSIX_H_IN_SUBDIR)],[AC_MSG_WARN([[pcre2posix old version installed]]); have_pcre2posix=no])
+      ], [have_pcre2posix=no])
+   ])
+], [have_pcre2posix=no], -lpcre2-8)
+fi
+
+if test $have_pcre2 = "no"; then
+
 AC_CHECK_LIB(pcre, pcre_compile, [
    AC_CHECK_HEADER(pcre.h, [
       AC_EGREP_HEADER(pcre_fullinfo, pcre.h, [have_pcre=yes], [AC_MSG_WARN([[pcre old version installed]]); have_pcre=no])
@@ -889,6 +925,7 @@ AC_CHECK_LIB(pcreposix, regcomp, [
    ])
 ], [have_pcreposix=no], -lpcre)
 
+fi
 dnl ================================================================
 dnl libpcrs is temporarily disabled.
 dnl
@@ -1095,6 +1132,33 @@ fi
 # we don't need pcreposix, then link pcre dynamically; else
 # build it and link statically
 #
+
+#check for libpcre2 first. then regular pcre
+
+if test $have_pcre2 = "yes"; then
+  echo "using libpcre2"
+  STATIC_PCRE_ONLY=#
+  LIBS="$LIBS -lpcre2-8 -lpcre2-posix"
+  if test "$use_static_pcre" = "yes"; then
+    pcre_dyn=no
+    AC_DEFINE(PCRE2_STATIC,1,[Define to statically link to the pcre2 library on Windows.])
+#     see pcre2-10.42/src/pcre2.h line 54
+#       #if defined(_WIN32) && !defined(PCRE2_STATIC)
+#       #  ifndef PCRE2_EXP_DECL
+#       #    define PCRE2_EXP_DECL  extern __declspec(dllimport)
+#       #  endif
+#       #endif
+#     If you want to statically link a program against a PCRE2 library in the form of
+#     a non-dll .a file, you must define PCRE2_STATIC before including src/pcre2.h.
+#     Otherwise the exported functions will be declared __declspec(dllimport),
+#     with unwanted results.  eg: build failures with error messages like
+#       undefined reference to `_imp__pcre2_compile_8'
+  else
+    pcre_dyn=yes
+    AC_DEFINE(FEATURE_DYNAMIC_PCRE,1,[Define to dynamically link to pcre.])
+  fi
+else
+
 if test $have_pcre = "yes"; then
   echo "using libpcre"
   STATIC_PCRE_ONLY=#
@@ -1116,7 +1180,8 @@ if test $have_pcre = "yes"; then
     AC_DEFINE(FEATURE_DYNAMIC_PCRE,1,[Define to dynamically link to pcre.])
   fi
 else
-  AC_MSG_ERROR(pcre library not detected.)
+  AC_MSG_ERROR(Detected neither pcre2 nor pcre library.)
+fi
 fi
 
 AC_DEFINE(FEATURE_CONNECTION_KEEP_ALIVE)
@@ -1230,6 +1295,45 @@ if test X"$OPT_OPENSSL" != Xno; then
 fi
 AC_SUBST(FEATURE_HTTPS_INSPECTION_ONLY_OPENSSL)
 
+dnl ========================================================
+dnl check for wolfSSL which can be used for https inspection
+dnl ========================================================
+FEATURE_HTTPS_INSPECTION_ONLY_WOLFSSL=#
+OPT_WOLFSSL=no
+AC_ARG_WITH(wolfssl,dnl
+AC_HELP_STRING([--with-wolfssl], [Enable Wolfssl/LibreSSL detection for https inspection.])
+AC_HELP_STRING([--without-wolfssl], [Disable Wolfssl/LibreSSL detection]),
+  OPT_WOLFSSL=$withval)
+
+if test X"$OPT_WOLFSSL" != Xno; then
+    if test X"$OPT_MBEDTLS" != Xno; then
+        AC_MSG_ERROR([wolfSSL and mbedTLS support can't be enabled at the same time])
+    fi
+    if test X"$OPT_OPENSSL" != Xno; then
+        AC_MSG_ERROR([wolfSSL and OpenSSL support can't be enabled at the same time])
+    fi
+
+    AC_CHECK_LIB(wolfssl, wolfSSL_Init, [HAVE_WOLFSSL_INIT="yes"])
+
+    if test "x$HAVE_WOLFSSL_INIT" = "xyes"; then
+        AC_DEFINE(FEATURE_HTTPS_INSPECTION, 1, [if SSL/TLS is enabled])
+        AC_DEFINE(FEATURE_HTTPS_INSPECTION_WOLFSSL, 1, [if Wolfssl is enabled])
+        AC_SUBST(FEATURE_HTTPS_INSPECTION_WOLFSSL, [1])
+        FEATURE_HTTPS_INSPECTION="yes"
+        FEATURE_HTTPS_INSPECTION_WOLFSSL="yes"
+    fi
+
+    if test "x$FEATURE_HTTPS_INSPECTION_WOLFSSL" = "xyes"; then
+    AC_MSG_NOTICE([Detected wolfSSL. Enabling https inspection.])
+
+    LIBS="$LIBS -lwolfssl"
+
+    FEATURE_HTTPS_INSPECTION_ONLY=
+    FEATURE_HTTPS_INSPECTION_ONLY_WOLFSSL=
+  fi
+fi
+AC_SUBST(FEATURE_HTTPS_INSPECTION_ONLY_WOLFSSL)
+
 AC_SUBST(FEATURE_HTTPS_INSPECTION_ONLY)
 
 dnl ========================================================
index a6759da..ae13d89 100644 (file)
@@ -6,7 +6,7 @@
  *                fly.  High-level functions include:
  *                  - Deanimation of GIF images
  *
- * Copyright   :  Written by and Copyright (C) 2001 - 2004, 2006 by the
+ * Copyright   :  Written by and Copyright (C) 2001-2021 by the
  *                Privoxy team. https://www.privoxy.org/
  *
  *                Based on the GIF file format specification (see
@@ -328,6 +328,7 @@ int gif_deanimate(struct binbuffer *src, struct binbuffer *dst, int get_first_im
 {
    unsigned char c;
    struct binbuffer *image;
+   int image_buffered = 0;
 
    if (NULL == src || NULL == dst)
    {
@@ -382,9 +383,9 @@ int gif_deanimate(struct binbuffer *src, struct binbuffer *dst, int get_first_im
     * Parse the GIF block by block and copy the relevant
     * parts to dst
     */
-   while(src->offset < src->size)
+   while (src->offset < src->size)
    {
-      switch(buf_getbyte(src, 0))
+      switch (buf_getbyte(src, 0))
       {
          /*
           * End-of-GIF Marker: Append current image if we got
@@ -398,8 +399,14 @@ int gif_deanimate(struct binbuffer *src, struct binbuffer *dst, int get_first_im
           * Image block: Extract to current image buffer.
           */
       case 0x2c:
-         image->offset = 0;
+         if (image_buffered == 1)
+         {
+            /* Discard previous image. */
+            image->offset = 0;
+            image_buffered = 0;
+         }
          if (gif_extract_image(src, image)) goto failed;
+         image_buffered = 1;
          if (get_first_image) goto write;
          continue;
 
@@ -410,14 +417,16 @@ int gif_deanimate(struct binbuffer *src, struct binbuffer *dst, int get_first_im
          switch (buf_getbyte(src, 1))
          {
             /*
-             * Image extension: Copy extension  header and image
-             *                  to the current image buffer
+             * Image extension: Copy extension header
+             * and continue looking for new blocks.
              */
          case 0xf9:
-            image->offset = 0;
-            if (buf_copy(src, image, 8) || buf_getbyte(src, 0) != 0x2c) goto failed;
-            if (gif_extract_image(src, image)) goto failed;
-            if (get_first_image) goto write;
+            if (image_buffered == 1)
+            {
+               image->offset = 0;
+               image_buffered = 0;
+            }
+            if (buf_copy(src, image, 8)) goto failed;
             continue;
 
             /*
index 97814c5..3d95a93 100644 (file)
@@ -1,10 +1,75 @@
-privoxy (3.0.33~gitsnapshot-1) UNRELEASED; urgency=medium
+privoxy (3.0.35~gitsnapshot-1) UNRELEASED; urgency=medium
 
   * Unreleased GIT snapshot.
-  * Adapt Debian patches to GIT changes.
+  * The following patches are now incorporated upstream: 35_pcre2-support,
+    36_pcre2-patternfix.
+
+ -- Roland Rosenfeld <roland@debian.org>  Sun, 05 Feb 2023 10:58:57 +0100
+
+privoxy (3.0.34-3) unstable; urgency=medium
+
+  * 35_pcre2-support: Update patch based on upstream GIT.
+  * 36_pcre2-patternfix: Fix using anchored pattern in pcre2.
+
+ -- Roland Rosenfeld <roland@debian.org>  Sun, 27 Aug 2023 16:20:57 +0200
+
+privoxy (3.0.34-2) unstable; urgency=medium
+
+  * Add ro debconf translation.  Thanks to Remus-Gabriel Chelu
+    (Closes: #1033443).
+  * 35_pcre2-support: Build with libpcre2-dev instead of obsolete pcre3
+    (Closes: #999981).
+
+ -- Roland Rosenfeld <roland@debian.org>  Fri, 30 Jun 2023 09:28:22 +0200
+
+privoxy (3.0.34-1) unstable; urgency=medium
+
+  * New upstream version 3.0.34.
+  * The following patches are now incorporated upstream: 35_gif_deanimate,
+    36_pending_tls, 37_https_connect.
+
+ -- Roland Rosenfeld <roland@debian.org>  Sun, 05 Feb 2023 10:41:26 +0100
+
+privoxy (3.0.33-4) unstable; urgency=medium
+
+  * Add it debconf translation.  Thanks to Ceppo <ceppo@oziosi.org>
+    (Closes: #1024071).
+  * Update to Standards-Version 4.6.2 (no changes).
+  * Remove lsb-base dependency, since it is essential.
+  * 35_gif_deanimate: Tolerate multiple image extensions in a row.
+  * 36_pending_tls: Check for pending TLS data from the client before
+    checking if data is available on the connection.
+  * 37_https_connect: Reject https URLs without CONNECT request.
+  * d/maintscript: fix version numbers.
+
+ -- Roland Rosenfeld <roland@debian.org>  Sat, 28 Jan 2023 15:46:54 +0100
+
+privoxy (3.0.33-3) unstable; urgency=medium
+
+  * d/tests/conditional-defines: ignore 32-bit time_t on 32bit systems.
+
+ -- Roland Rosenfeld <roland@debian.org>  Sun, 25 Sep 2022 19:49:17 +0200
+
+privoxy (3.0.33-2) unstable; urgency=medium
+
+  * d/maintscript: Remove orphaned
+    templates/edit-actions-for-url-string-filter (Closes: #1001501).
+  * d/tests/conditional-defines: Check that expected #defines are enabled.
+  * d/rules: --enable-compression at build time (still disabled in config).
+  * d/tests/privoxy-regression-tests: 2 pass check with different options.
+  * Update to Standards-Version 4.6.1 (no changes).
+  * Add systemd timer support for cert cleanup.
+
+ -- Roland Rosenfeld <roland@debian.org>  Sun, 25 Sep 2022 11:52:25 +0200
+
+privoxy (3.0.33-1) unstable; urgency=medium
+
+  * New upstream version 3.0.33.
+  * Adapt all patches to new version.
+  * Remove pcre dir from copyright and debian/source/lintian-overrides.
   * Undo lintian override for bug 992465.
 
- -- Roland Rosenfeld <roland@debian.org>  Thu, 02 Dec 2021 09:04:45 +0100
+ -- Roland Rosenfeld <roland@debian.org>  Wed, 08 Dec 2021 16:29:31 +0100
 
 privoxy (3.0.32-3) unstable; urgency=medium
 
index 9e7bde5..0396f09 100644 (file)
@@ -11,14 +11,14 @@ Build-Depends: autoconf,
                groff <!nodoc>,
                libbrotli-dev,
                libmbedtls-dev,
-               libpcre3-dev,
+               libpcre2-dev,
                man2html <!nodoc>,
                opensp:native <!nodoc>,
                po-debconf,
                sgmlspl <!nodoc>,
                w3m <!nodoc>,
                zlib1g-dev
-Standards-Version: 4.6.0
+Standards-Version: 4.6.2
 Homepage: https://www.privoxy.org/
 Vcs-Git: https://salsa.debian.org/debian/privoxy.git
 Vcs-Browser: https://salsa.debian.org/debian/privoxy
@@ -29,7 +29,6 @@ Architecture: any
 Depends: adduser,
          debconf,
          logrotate,
-         lsb-base (>= 3.2-13),
          ucf,
          ${misc:Depends},
          ${perl:Depends},
index 00a73b0..917e794 100644 (file)
@@ -6,7 +6,7 @@ Source: https://sourceforge.net/projects/ijbswa/files/Sources/
 Files: *
 Copyright:
  Copyright (C) 2001-2021 by the Privoxy team. https://www.privoxy.org/
- Copyright (C) 2001-2021 by Privoxy Developers <privoxy-devel@lists.privoxy.org>
+ Copyright (C) 2001-2023 by Privoxy Developers <privoxy-devel@lists.privoxy.org>
  Parts Copyright (c) 1997 by Anonymous Coders and Junkbusters, Inc.
  Parts Copyright (C) 1999 Adam Lock <locka@iol.ie>
  Parts Copyright (C) 1998-1999 Steve Cheng <steve@ggi-project.org>
@@ -58,35 +58,9 @@ License: GPL-2+
 
 Files: debian/*
 Copyright:
- 2002-2021  Roland Rosenfeld <roland@debian.org>
+ 2002-2023  Roland Rosenfeld <roland@debian.org>
 License: GPL-2+
 
-Files: ./pcre/*
-Copyright: Copyright (c) 1997-2000 University of Cambridge
-Comment:
- Written by: Philip Hazel <ph10@cam.ac.uk>
- .
- University of Cambridge Computing Service,
- Cambridge, England. Phone: +44 1223 334714.
-License: BSD-like
- Permission is granted to anyone to use this software for any purpose on any
- computer system, and to redistribute it freely, subject to the following
- restrictions:
- .
- 1. This software is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- .
- 2. The origin of this software must not be misrepresented, either by
-    explicit claim or by omission.
- .
- 3. Altered versions must be plainly marked as such, and must not be
-    misrepresented as being the original software.
- .
- 4. If PCRE is embedded in any software that is released under the GNU
-    General Purpose Licence (GPL), then the terms of that licence shall
-    supersede any condition above with which it is incompatible.
-
 License: GPL-2+
  This program is free software; you can redistribute it
  and/or modify it under the terms of the GNU General
index 77e4ed9..051d518 100644 (file)
@@ -1,3 +1,4 @@
-rm_conffile /etc/privoxy/global.action 3.0.11-1~ privoxy
-rm_conffile /etc/privoxy/standard.action 3.0.11-1~ privoxy
-rm_conffile /etc/privoxy/templates/show-version 3.0.28-2~ privoxy
+rm_conffile /etc/privoxy/global.action 3.0.33-4~ privoxy
+rm_conffile /etc/privoxy/standard.action 3.0.33-4~ privoxy
+rm_conffile /etc/privoxy/templates/show-version 3.0.33-4~ privoxy
+rm_conffile /etc/privoxy/templates/edit-actions-for-url-string-filter 3.0.33-3~ privoxy
diff --git a/debian/po/it.po b/debian/po/it.po
new file mode 100644 (file)
index 0000000..32fca70
--- /dev/null
@@ -0,0 +1,33 @@
+# privoxy po-debconf italian translation
+# Copyright (C) 2022 privoxy's copyright holder
+# This file is distributed under the same license as the privoxy package.
+# Ceppo <ceppo@oziosi.org, 2022.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: privoxy\n"
+"Report-Msgid-Bugs-To: privoxy@packages.debian.org\n"
+"POT-Creation-Date: 2016-04-08 17:17+0200\n"
+"PO-Revision-Date: 2022-10-28 00:00+0000\n"
+"Last-Translator: Ceppo <ceppo@oziosi.org>\n"
+"Language-Team: Italian <debian-l10n-italian@lists.debian.org>\n"
+"Language: it\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. Type: string
+#. Description
+#: ../templates:1001
+msgid "Adresses on with Privoxy listens:"
+msgstr "Indirizzi su cui Privoxy deve ascoltare:"
+
+#. Type: string
+#. Description
+#: ../templates:1001
+msgid ""
+"Please enter a space separated list of address:port combinations on which "
+"Privoxy will listen for client requests."
+msgstr ""
+"Inserire una lista separata da spazi di combinazioni indirizzo:porta su cui "
+"Privoxy resterà in ascolto per le richieste dei client."
diff --git a/debian/po/ro.po b/debian/po/ro.po
new file mode 100644 (file)
index 0000000..6549093
--- /dev/null
@@ -0,0 +1,43 @@
+# Mesajele în limba română pentru pachetul privoxy.
+# Romanian translation of privoxy.
+# Copyright © 2023 THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the privoxy package.
+#
+# Remus-Gabriel Chelu <remusgabriel.chelu@disroot.org>, 2023.
+#
+# Cronologia traducerii fișierului „privoxy”:
+# Traducerea inițială, făcută de R-GC, pentru versiunea privoxy 3.0.34-1(2006-11-01).
+# Actualizare a traducerii pentru versiunea Y, făcută de X, Y(anul).
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: privoxy 3.0.34-1\n"
+"Report-Msgid-Bugs-To: privoxy@packages.debian.org\n"
+"POT-Creation-Date: 2016-04-08 17:17+0200\n"
+"PO-Revision-Date: 2023-03-19 08:06+0100\n"
+"Last-Translator: Remus-Gabriel Chelu <remusgabriel.chelu@disroot.org>\n"
+"Language-Team: Romanian <debian-l10n-romanian@lists.debian.org>\n"
+"Language: ro\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n==0 || (n!=1 && n%100>=1 && "
+"n%100<=19) ? 1 : 2);\n"
+"X-Bugs: Report translation errors to the Language-Team address.\n"
+"X-Generator: Poedit 3.2.2\n"
+
+#. Type: string
+#. Description
+#: ../templates:1001
+msgid "Adresses on with Privoxy listens:"
+msgstr "Adresele pe care Privoxy ascultă:"
+
+#. Type: string
+#. Description
+#: ../templates:1001
+msgid ""
+"Please enter a space separated list of address:port combinations on which "
+"Privoxy will listen for client requests."
+msgstr ""
+"Introduceți o listă de combinații de adresă:port, separată de spații, pe care "
+"Privoxy va asculta cererile clienților."
diff --git a/debian/privoxy-cleanup.service b/debian/privoxy-cleanup.service
new file mode 100644 (file)
index 0000000..8887181
--- /dev/null
@@ -0,0 +1,14 @@
+[Unit]
+Description=privoxy certificate cleanup
+Documentation=man:privoxy(8) https://www.privoxy.org/user-manual/
+ConditionACPower=true
+
+[Service]
+Type=oneshot
+ExecStart=/etc/cron.daily/privoxy systemd-timer
+
+# performance options
+Nice=19
+IOSchedulingClass=best-effort
+IOSchedulingPriority=7
+
diff --git a/debian/privoxy-cleanup.timer b/debian/privoxy-cleanup.timer
new file mode 100644 (file)
index 0000000..28b254f
--- /dev/null
@@ -0,0 +1,12 @@
+[Unit]
+Description=privoxy certificate cleanup
+Documentation=man:privoxy(8) https://www.privoxy.org/user-manual/
+Before=logrotate.timer
+
+[Timer]
+OnCalendar=daily
+AccuracySec=12h
+Persistent=true
+
+[Install]
+WantedBy=timers.target
index 114fd41..97eff8a 100644 (file)
@@ -4,9 +4,15 @@
 
 set -e
 
+# skip in favour of systemd timer if called from cron.daily
+if [ -d /run/systemd/system ] && [ "$1" != "systemd-timer" ]; then
+    exit 0
+fi
+
+
 CERTDIR=/var/lib/privoxy/certs
 EXPIREDAYS=90
 
 if [ -d $CERTDIR ]; then
-    find $CERTDIR -type f -mtime +$EXPIREDAYS | xargs -r rm -f
+    find $CERTDIR -type f -mtime +$EXPIREDAYS -print0 | xargs -0 -r rm -f
 fi
index d6c23b3..5b49300 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/make -f
 #
-# (c) 2002-2021 Roland Rosenfeld <roland@debian.org>
+# (c) 2002-2022 Roland Rosenfeld <roland@debian.org>
 #
 # Uncomment this to turn on verbose mode.
 #export DH_VERBOSE=1
@@ -25,6 +25,7 @@ override_dh_auto_configure:
                --enable-external-filters \
                --enable-extended-statistics \
                --enable-pcre-host-patterns \
+               --enable-compression \
                --with-mbedtls \
                --with-brotli \
                --with-docbook=/usr/share/sgml/docbook/stylesheet/dsssl/modular
@@ -116,3 +117,7 @@ endif
 override_dh_perl:
 #      We only need perl-base:
        dh_perl -d
+
+override_dh_installsystemd:
+       dh_installsystemd
+       dh_installsystemd --name privoxy-cleanup
diff --git a/debian/source/lintian-overrides b/debian/source/lintian-overrides
deleted file mode 100644 (file)
index 3ddafbb..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-# we don't use the local pcre source but use the ones from libpcre3-dev,
-# so we can ignore the warnings about old libtool versions:
-privoxy source: ancient-libtool pcre/ltconfig
-privoxy source: ancient-libtool pcre/ltmain.sh 1.3.4
diff --git a/debian/tests/conditional-defines b/debian/tests/conditional-defines
new file mode 100755 (executable)
index 0000000..0f00d33
--- /dev/null
@@ -0,0 +1,41 @@
+#!/bin/sh
+#
+# Check http://config.privoxy.org/show-status for Conditional #defines enabled
+# This wrapper starts privoxy on port 8119 and runs conditional-defines.pl
+#
+# (c) 2022 Roland Rosenfeld <roland@debian.org>
+
+PORT=8119
+
+TESTSDIR=$(dirname "$0")
+
+if [ -z "$AUTOPKGTEST_TMP" ]; then
+    AUTOPKGTEST_TMP=$(mktemp -d)
+fi
+
+trap 'rm -rf "$AUTOPKGTEST_TMP"' EXIT
+
+CONFIG=$AUTOPKGTEST_TMP/config
+PIDFILE=$AUTOPKGTEST_TMP/privoxy.pid
+PRIVOXY=$AUTOPKGTEST_TMP/privoxy
+
+sed -e "s/^listen-address.*/listen-address 127.0.0.1:$PORT/" \
+    -e "s%^logdir.*%logdir $AUTOPKGTEST_TMP%" \
+    < /usr/share/privoxy/config > "$CONFIG"
+
+cp /usr/sbin/privoxy "$PRIVOXY"
+
+echo "Starting privoxy on port $PORT"
+$PRIVOXY --pidfile "$PIDFILE" "$CONFIG"
+
+http_proxy=http://127.0.0.1:$PORT/
+export http_proxy
+
+"$TESTSDIR"/conditional-defines.pl
+EXITVAL=$?
+
+echo "Stopping privoxy on port $PORT"
+# shellcheck disable=SC2046
+kill $(cat "$PIDFILE")
+
+exit $EXITVAL
diff --git a/debian/tests/conditional-defines.pl b/debian/tests/conditional-defines.pl
new file mode 100755 (executable)
index 0000000..693f4fb
--- /dev/null
@@ -0,0 +1,75 @@
+#!/usr/bin/perl
+#
+# Check http://config.privoxy.org/show-status for Conditional #defines enabled
+#
+# (c) 2022 Roland Rosenfeld <roland@debian.org>
+
+use strict;
+use warnings;
+use LWP::UserAgent ();
+use HTML::TreeBuilder 5 -weak;
+
+my $exitcode = 0;
+
+my $ua = LWP::UserAgent->new(timeout => 10);
+$ua->env_proxy;
+my $response = $ua->get('http://config.privoxy.org/show-status');
+if (!$response->is_success) {
+   die $response->status_line;
+}
+my $tree = HTML::TreeBuilder->new;
+$tree->parse($response->decoded_content);
+
+# Search for "Conditional #defines:" table:
+my $summary = 'The state of some ./configure options and what they do.';
+my $table = $tree->look_down('_tag' => 'table',
+                             'summary' => $summary);
+unless (defined $table) {
+   die "summary '$summary' not found in tables";
+}
+
+# These features are intentionaly disabled, all others should be enabled:
+my %disabled_features = ('FEATURE_ACCEPT_FILTER' => 1, # BSD only
+                         'FEATURE_STRPTIME_SANITY_CHECKS' =>1, # BSD libc only
+                         'FEATURE_GRACEFUL_TERMINATION' =>1, # devel only
+                        );
+
+my $enabled = 0;
+my $disabled_ok = 0;
+my $disabled_nok = 0;
+foreach my $tr ($table->look_down('_tag' => 'tr')) {
+   my $td2 = ($tr->look_down('_tag' => 'td')) [1];
+   next unless defined $td2;
+   my $code = $tr->look_down('_tag' => 'code');
+   my $feature = $code->detach_content;
+   my $value = $td2->detach_content;
+   if ($value !~ /Yes/) {
+      # feature disabled, check whitelist
+      if ($feature eq 'FEATURE_64_BIT_TIME_T') {
+         # See https://en.wikipedia.org/wiki/Year_2038_problem
+         # On Linux >= 5.6 time_t should be 64bit, too.
+         printf "%s is disabled, which is ok on 32bit systems", $feature;
+         $disabled_ok++;
+      } elsif (! defined $disabled_features{$feature}) {
+         printf "%s is disabled, but should be enabled\n", $feature;
+         $exitcode = 1;
+         $disabled_nok++;
+      } else {
+         $disabled_ok++;
+      }
+   } else {
+      $enabled++;
+   }
+}
+
+printf "%d features enabled\n", $enabled;
+printf "%d features intentionally disabled\n", $disabled_ok;
+printf "%d features unintentionally disabled\n", $disabled_nok;
+
+if ($enabled < 10) {
+   printf STDERR "Found only %d Conditional #defines, seems test ist broken\n",
+                 $enabled;
+   $exitcode = 1;
+}
+
+exit $exitcode;
index 1566c8f..6ff73cf 100644 (file)
@@ -1,2 +1,5 @@
 Tests: privoxy-regression-test
 Depends: curl, @
+
+Tests: conditional-defines
+Depends: privoxy, libwww-perl, libhtml-tree-perl
index 1c29fa0..e8fdd9d 100755 (executable)
@@ -3,7 +3,7 @@
 # Run privoxy-regression-test.pl on a configuration extended by
 # regression-tests.action.
 #
-# (c) 2018-2021 Roland Rosenfeld <roland@debian.org>
+# (c) 2018-2022 Roland Rosenfeld <roland@debian.org>
 
 PORT=8119
 
@@ -11,37 +11,57 @@ if [ -z "$AUTOPKGTEST_TMP" ]; then
     AUTOPKGTEST_TMP=$(mktemp -d)
 fi
 
-trap "rm -rf $AUTOPKGTEST_TMP" EXIT
+trap 'rm -rf "$AUTOPKGTEST_TMP"' EXIT
 
 CONFIG=$AUTOPKGTEST_TMP/config
 PIDFILE=$AUTOPKGTEST_TMP/privoxy.pid
 PRIVOXY=$AUTOPKGTEST_TMP/privoxy
 
+cp /usr/sbin/privoxy "$PRIVOXY"
+
+http_proxy=http://127.0.0.1:$PORT/
+export http_proxy
+
+OUTFILE=$AUTOPKGTEST_TMP/output
+
+
+echo "#### pass 1: some optiones disabled"
+
 sed -e "s/^listen-address.*/listen-address 127.0.0.1:$PORT/" \
     -e "s%^logdir.*%logdir $AUTOPKGTEST_TMP%" \
-    -e "s/^enable-edit-actions.*/enable-edit-actions 1/" \
     -e "s/^keep-alive-timeout.*/keep-alive-timeout 21/" \
-    -e "s/^#connection-sharing.*/connection-sharing 1/" \
-    < /usr/share/privoxy/config > $CONFIG
-echo "actionsfile regression-tests.action" >> $CONFIG
-
-cp /usr/sbin/privoxy $PRIVOXY
+    -e "s/^#connection-sharing.*/connection-sharing 0/" \
+    < /usr/share/privoxy/config > "$CONFIG"
+echo "actionsfile regression-tests.action" >> "$CONFIG"
 
 echo "Starting privoxy on port $PORT"
-$PRIVOXY --pidfile $PIDFILE $CONFIG
+$PRIVOXY --pidfile "$PIDFILE" "$CONFIG"
 
-http_proxy=http://127.0.0.1:$PORT/
-export http_proxy
+/usr/bin/privoxy-regression-test --max-level 200 --show-skipped-tests \
+    | tee "$OUTFILE" 2>&1
 
-OUTFILE=$AUTOPKGTEST_TMP/output
+
+echo "#### pass 2 with some more options enabled"
+
+sed -e "s/^listen-address.*/listen-address 127.0.0.1:$PORT/" \
+    -e "s%^logdir.*%logdir $AUTOPKGTEST_TMP%" \
+    -e "s/^enable-remote-toggle.*/enable-remote-toggle 1/" \
+    -e "s/^enable-edit-actions.*/enable-edit-actions 1/" \
+    -e "s/^enable-proxy-authentication-forwarding.*/enable-proxy-authentication-forwarding 1/" \
+    -e "s/^keep-alive-timeout.*/keep-alive-timeout 21/" \
+    -e "s/^#connection-sharing.*/connection-sharing 1/" \
+    < /usr/share/privoxy/config > "$CONFIG"
+echo "actionsfile regression-tests.action" >> "$CONFIG"
 
 /usr/bin/privoxy-regression-test --max-level 200 --show-skipped-tests \
-    | tee $OUTFILE 2>&1
+    | tee -a "$OUTFILE" 2>&1
+
 
 echo "Stopping privoxy on port $PORT"
-kill $(cat $PIDFILE)
+kill "$(cat "$PIDFILE")"
 
-if grep -q 'Executed.*, 0 failures.' $OUTFILE
+# Check that 2 passes have both 0 failures:
+if [ "$(grep -c 'Executed.*, 0 failures' "$OUTFILE")" = 2 ]
 then
     exit 0
 else
index f0b7622..98d9550 100644 (file)
@@ -21,7 +21,7 @@
 #                 and enhancements are better placed in user.action,
 #                 the match-all section has been moved to match-all.action.
 #
-#  Copyright   :  Written by and Copyright (C) 2001-2021 the
+#  Copyright   :  Written by and Copyright (C) 2001-2023 the
 #                 Privoxy team. https://www.privoxy.org/
 #
 # Feedback welcome, for details please have a look at:
 # the domain syntax above. A comprehensive discussion of regular expressions
 # wouldn't fit here.
 #
-# Perl compatible regular expressions are used. See the pcre/docs/ direcory or
+# Perl compatible regular expressions are used. See the pcre/docs/ directory or
 # man perlre (also available at http://perldoc.perl.org/perlre.html) for
 # details. The appendix to our User Manual also has some detail.
 #
 #    not pixels!)
 #    If the option "first" is given, the first frame of the animation
 #    is used as the replacement. If "last" is given, the last frame of
-#    the animation is used instead, which propably makes more sense for
+#    the animation is used instead, which probably makes more sense for
 #    most banner animations, but also has the risk of not showing the
 #    entire last frame (if it is only a delta to an earlier frame).
 #
@@ -712,8 +712,8 @@ ada*.
 adri*.
 # URL = https://adguard.com/
 adguard.com/
-# URL = https://adv-archiv.dfn-cert.de/adv/2021-2222/
-adv-archiv.dfn-cert.de/
+# URL = https://adfd.org/austausch/
+adfd.org/
 
 #############################################################################
 # Generic block patterns by path:
@@ -773,9 +773,6 @@ support./(.*/)?track
 .gov
 .hs-*.de
 .fh-*.de
-#MASTER# REMARKS: Try to avoid harmless names in non-commercial organizations. Added 10/24/06
-# URL = http://www.gnu.org/graphics/gnu-head-banner.png
-.org/.*(image|banner)
 
 #############################################################################
 # Catch-all for false-positives that are just TOO obvious to let go
@@ -956,6 +953,20 @@ ih.adscale.de/
 #MASTER# BLOCK-REFERRER: https://www.ksta.de/ratgeber/digital/plattform-moodle-streikt-viele-schueler-koennen-nicht-arbeiten---gebauer-weiss-von-nichts-37913640
 # Blocked URL = https://api.theadex.com/collector/v1/d/285/5184/cmframe/Lw0EHAiwAxA2GAIUhAK0AXaMBA?c=4248866896491805402
 api.theadex.com/
+# Blocked URL = https://odb.outbrain.com/utils/get?url=https%3A%2F%2Fwww.ksta.de%2Fratgeber%2Fgesundheit%2Fhausaerztin-erklaert-milder-verlauf-bei-einer-omikron-infektion---was-heisst-das--39393164&idx=0&rand=18368&key=NANOWDGT01&widgetJSId=AR_2&va=true&et=true&format=html&pdobuid=-1&adblck=false&abwl=false&px=205&py=1389&vpd=0&cw=940&activeTab=true&darkMode=false&settings=true&recs=true&version=2000570&sig=bvSz55IV&apv=false&osLang=en-CA&winW=1350&winH=621&scrW=1366&scrH=768&dpr=1&secured=true&cnsntv2=CPSvfxSPSvfxSAGABCENB9CgAP_AAEAAAAYgIXBVJD7dTWlAMHZ5GNpkCYAU1sAUIOQCCBCAAwAFAEGA8IAC0SACEEQABAACAQAAgRABAAAEEABUAECgQAAEAQEkAAQAhAAIAAJEAAEQAgAQAAoIAAAAAAAIAAABCgSAkBiQQ8LGRGAghIAwQgAQwAABgIACAAMASAAYABAAAAIAAABAAgIEEELoAIELgEQkC0ABAAFQAMgAcgA8AEAAMgAaQBEAEUAJgATwArABvADmAH4AQgAhoBEAESAJYAUoAtwBhwD7AP0AgYBFACNAEpALmAYoA2gBuADiAHoAPkAhsBIgCdgFDgLzAYMAyQBpwDWQHBAPHAhCEACAAkAXQAyECBgaAOAFYALgAhgB-AHyASIAnYMABAOoIgDABWAEMAPwA-QCRAE7CAAIAJBUAUAJgAXAB-AJBAXmMgBgBMgH2AfgC8xgAEAsQ6BsABUADIAHIAPgBAADIAGgAPoAiACKAEwAJ4AVgAuABfADeAHMAPwAhoBEAESAJYATAAowBSgCxAFuAMMAaMA-wD9AIGARQAiwBKQCxAFzAMUAbQA3ABxADqAHoAQ2Ai8BIICRAE7AKHAXmAwYBiQDJAGWANOAcWA8cB-I4AeAAgAC4AJAAyABoAIiAXoAwAB5AD5AIQAXQAyEBpoDbCEBQADIATAAuABfADeALGAfYB-AEUAJSAXMAxQBtADqAHoASCAkQBbQDEgHjgQoIABgAEABoALEAYABdADbCUBYABAAGQAOAAfACIAEwALgAXwBDQCIAIkAUYApQBbgD8AMUAbgA6gB8gEXgJEAXmAywkADAAuAGQBdBSBOABUADIAHIAPgBAADIAGkARABFACYAE8AKQAXwA5gB-AENAIgAiQBRgClAFiALcAaMA-wD9AIsASkAuYBigDaAG4APQAi8BIgCdgFDgLzAZIAywBrIDggHjgQhKACgALgAkACsAGQAsQBgADyALoAaaBAwAAA.YAAAAAAAAAAA&cmpStat=1&ccpaStat=0&ref=https%3A%2F%2Fwww.ksta.de%2Fhtml%2Fdumont-consent%2Findex.html%3Fparam%3DeyJyZWRpcmVjdFVybCI6Ii9yYXRnZWJlci9nZXN1bmRoZWl0L2hhdXNhZXJ6dGluLWVya2xhZXJ0LW1pbGRlci12ZXJsYXVmLWJlaS1laW5lci1vbWlrcm9uLWluZmVrdGlvbi0tLXdhcy1oZWlzc3QtZGFzLS0zOTM5MzE2ND9jYj0xNjQzMDgyNTMxNDU5JmRtY2lkPXNtX3R3X3B1IiwicmVmZXJyZXIiOiIiLCJzdWJkb21haW4iOiJ3d3cifQ%3D%3D
+odb.outbrain.com/
+# Blocked URL = https://elsa.memoinsights.com/t?pid=62012a7a19351c07620394e0&url=https%3A%2F%2Farstechnica.com%2Ftech-policy%2F2022%2F08%2Fthe-women-calling-out-apples-handling-of-misconduct-claims%2F&author%5B%5D=Financial%20Times&title=The%20women%20calling%20out%20Apple%E2%80%99s%20handling%20of%20misconduct%20claims&date=2022-08-04T13%3A39%3A42Z&referrer=&ref_url=&page_url=https%3A%2F%2Farstechnica.com%2Ftech-policy%2F2022%2F08%2Fthe-women-calling-out-apples-handling-of-misconduct-claims%2F%3Fcomments%3D1&cb=MEMO.API.callbacks.cbakynzcplf&v=v3.0.6&t=5000&e=5000&s=7362
+elsa.memoinsights.com/t
+# Blocked URL = https://ups.xplosion.de/ctx?event_id=ctx_json&_sid=24141&hostSiteUrl=https://www.presseportal.de/blaulicht/pm/12415/5302821&referrer=&userAgent=Mozilla/5.0%20(X11;%20FreeBSD%20amd64;%20rv:91.0)%20Gecko/20100101%20Firefox/91.0&userLang=en-CA&gdpr=1&gdpr_consent=[...]
+ups.xplosion.de/
+# Blocked URL = https://s.cpx.to/fire.js?pid=13058&ref=https%3A%2F%2Fexplosm.net%2Fcomics%2Fnewyears-2008&url=https%3A%2F%2Fexplosm.net%2Fcomics%2Fdave-shortnew-8%23comic&hn_ver=57&fid=715e92a0-477c-4ef4-b655-6ed9edc0e94b&gcv=CPuOj0APuOj0AAKAvAENDFCsAP_AAH_AAAwIJbtX_H__bW9r8f5_aft0eY1P9_j77uQzDhfNk-4F3L_W_JwX52E7NF36tq4KmR4Eu3LBIUNlHNHUTVmwaokVryHsak2cpTNKJ6BEkHMRO2dYGF5umxtjeQKY5_p_d3fx2D-t_dv-39z3z81Xn3dZf-_0-PCdU5_9Dfn9fRfb-9IL9_78v8v8_9_rk2_eX_3_79_7_H9-f_84JcAEmGrcQBdmUODNoGEUCIEYVhARQKACCgGFogIAHBwU7IwCfWESAFAKAIwIgQ4AoyIBAAAJAEhEAEgRYIAAABAIAAQAIBEIAGBgEFABYCAQAAgOgYohQACBIQJEREQpgQFQJBAS2VCCUF0hphAFWWAFAIjYKABEEgIrAAEBYOAYIkBKxYIEmINogAGAFAKJUK1FJ6aAhYzMAAAA.YAAAAAAAAAAA
+s.cpx.to/
+# Blocked URL = https://track.venatusmedia.com/dual/track_enc
+track.venatusmedia.com/
+# Blocked URL = https://o2.mouseflow.com/init?v=17.96&p=bd33e8bf-4f45-437f-9bda...&s=a6ac920f1ba63b3...&page=090...2f0d2&ret=0&u=62...fa1&href=https%3A%2F%2Fauth.leaseweb.com%2FloginCustomer&url=auth.leaseweb.com%2Flogincustomer&ref=https%3A%2F%2Fsecure.leaseweb.com%2F&title=Leaseweb%20Authorization%20Server&res=1366x768&tz=-60&to=0&dnt=1&ori=&dw=1362&dh=621&time=727&pxr=1&gdpr=1
+o2.mouseflow.com/
+# Blocked URL = https://secure-eu.nmrodam.com/cgi-bin/gn?prd=dcr&ci=de-910483&ch=de-910483_b01__vermischtes__P&asn=_vermischtes_&fp_id=&fp_cr_tm=&fp_acc_tm=&fp_emm_tm=&ve_id=&sessionId=vu0qoho115ipzkihhkxsztnvalijv1695918791&prv=1&c6=vc,b01&ca=NA&c13=asid,PE3FB63C1-D0BE-4D42-95B5-7B383C43C5F8&c32=segA,a_vermischtes_article&c33=segB,CPI&c34=segC,Firefox%20102&c15=apn,&sup=1&segment2=&segment1=&forward=0&plugv=&playerv=&ad=0&cr=D&c9=devid,&enc=true&c1=nuid,999&at=timer&rt=text&c16=sdkv,bj.6.0.0&c27=cln,30&crs=&lat=&lon=&c29=plid,16959187913574064&c30=bldv,6.0.0.673&st=dcragf&c7=osgrp,&c8=devgrp,&c10=plt,&c40=adbid,&c14=osver,NA&c26=dmap,1&dd=&hrd=&wkd=&c35=adrsid,&c36=cref1,&c37=cref2,&c11=agg,1&c12=apv,&c51=adl,0&c52=noad,0&pc=NA&c53=fef,n&c54=oad,&c55=cref3,&c57=adldf,2&ai=247660590&c3=st,c&c64=starttm,1695918795&adid=247660590&c58=isLive,false&c59=sesid,&c61=createtm,1695918850&c63=pipMode,&uoo=&c68=bndlid,&nodeTM=&logTM=&c73=phtype,&c74=dvcnm,&c76=adbsnid,&c44=progen,&davty=2&si=https%3A%2F%2Fwww.welt.de%2Fvermischtes%2Farticle247660590%2FBerlin-Mann-traegt-islamische-Muetze-als-Mode-Accessoire-und-wird-attackiert.html%3Fsource%3Dpuerto-reco-2_ABC-V32.7.C_already_read&c66=mediaurl,&sdd=&c62=sendTime,1695918850&rnd=889711
+secure-eu.nmrodam.com/
 
 {+block{Might be a web-bug that is an image.} -handle-as-empty-document +handle-as-image}
 #MASTER# BLOCK-REFERRER: http://versiontracker.com and many others. 10/20/06
@@ -1022,6 +1033,8 @@ eu-tlp01.kameleoon.eu/
 #MASTER# BLOCK-REFERRER: https://arstechnica.com/gadgets/2021/04/xinuos-finishes-picking-up-scos-mantle-by-suing-red-hat-and-ibm/
 # Blocked URL = https://fpa-events.arstechnica.com/plogger/?rand=1617351238373&plid=36453403&idsite=arstechnica.com&url=https%3A%2F%2Farstechnica.com%2Fgadgets%2F2021%2F04%2Fxinuos-finishes-picking-up-scos-mantle-by-suing-red-hat-and-ibm%2F&urlref=&screen=1366x768%7C1366x768%7C24&data=%7B%7D&sid=1&surl=https%3A%2F%2Farstechnica.com%2Fgadgets%2F2021%2F04%2Fxinuos-finishes-picking-up-scos-mantle-by-suing-red-hat-and-ibm%2F&sref=&sts=1617351085989&slts=0&date=Fri+Apr+02+2021+10%3A13%3A58+GMT%2B0200+(CEST)&action=heartbeat&inc=4&tt=4371&pvid=50890683&u=pid%3Df5e180d3fca67aa29521f1510e59850b
 fpa-events.arstechnica.com/
+# Blocked URL = https://i.clean.gg/1a
+i.clean.gg/
 
 
 #############################################################################
@@ -1953,7 +1966,7 @@ www.peereboom.us/adsuck/
 #MASTER# REMARKS: Ebay enlarge picture function doesn't work.
 # URL = http://include.ebaystatic.com/v4js/en_GB/e637i/SYS-LIGER_Omniture_e637i10177164_5_en_GB.js
 include.ebaystatic.com/.*omniture.*\.js
-#MASTER# REMARKS: Allow Yahoo news and mail javascipt pages
+#MASTER# REMARKS: Allow Yahoo news and mail javascript pages
 # URL = http://l.yimg.com/d/combo?news/p/common/generic/news/p/common/generic/popular-searches-min-12622.js&news/p/common/generic/ads-min-11050.js&news/p/common/generic/foundation/popup-min-12622.js
 .yimg.com/d/combo\?
 #MASTER# REMARKS: Page formatting problems when .css files are blocked
@@ -2042,6 +2055,14 @@ belco24.de/
 metrics.sr.ht/
 # URL = https://nlnet.nl/logo/banner.png
 nlnet.nl/
+# URL = https://adv-archiv.dfn-cert.de/adv/2021-2222/
+adv-archiv.dfn-cert.de/
+# URL = https://pinkstinks.de/werbung-ohne-diskriminierung/
+pinkstinks.de/
+# URL = https://www.eff.org/files/styles/teaser/public/banner_library/repro-rights-hd-3b.jpg?itok=uCnCHOj5
+.eff.org/
+# URL = https://www.datenschmutz.de/banner-square.png
+.datenschmutz.de/
 
 
 #############################################################################
@@ -2265,6 +2286,25 @@ idp.springer.com/
 .microsoftonline.com/
 # URL = https://www.zeit.de/zustimmung?url=https%3A%2F%2Fwww.zeit.de%2F2021%2F46%2Fchristian-drosten-coronavirus-virologie-pandemie-wissenschaft-impfung%2Fseite-4
 .zeit.de/zustimmung
+# URL = https://07.hagalil.com/www/delivery/ajs.php?zoneid=14&cb=35782002576&charset=UTF-8&loc=https%3A//www.hagalil.com/2021/12/rechtes-von-a-z-5/
+.hagalil.com/
+# URL = https://twitter.com/mariowitte/status/1479481418887663624?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1479481418887663624%7Ctwgr%5E%7Ctwcon%5Es1_&ref_url=https%3A%2F%2Ffuturezone.at%2Fprodukte%2Fcanon-toner-kopierschutz-gefaelscht-chips-chipmangel%2F401865218
+twitter.com/.*/status/
+#MASTER# REMARKS: There are lots of Nitter instances with onion addresses ...
+# URL = http://vfaomgh4jxphpbdfizkm5gbtjahmei234giqj4facbwhrfjtcldauqad.onion/mariowitte/status/1479481418887663624?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1479481418887663624%7Ctwgr%5E%7Ctwcon%5Es1_&ref_url=https%3A%2F%2Ffuturezone.at%2Fprodukte%2Fcanon-toner-kopierschutz-gefaelscht-chips-chipmangel%2F401865218
+.onion/.*/status/
+# URL = https://admin.gandi.net/dashboard/api/v5/login?redirect=https%3A%2F%2Fadmin.gandi.net%2Fdashboard%3Flocale%3Dde
+.gandi.net/
+# URL = https://launchpad.net/+openid-callback?starting_url=https%3A%2F%2Fanswers.launchpad.net%2Fdvdbackup%2F%2Bquestion%2F702512&janrain_nonce=2022-08-03T13%3A11%3A13ZnhmdLK...
+launchpad.net/
+# URL = https://consent.youtube.com/m?continue=https%3A%2F%2Fwww.youtube.com%2Fplaylist%3Flist%3DPLeF8ZihVdpFfttOtsot131byFrDVztt8T%26cbrd%3D1%26cbrd%3D1&gl=AT&m=0&pc=yt&hl=en&src=1
+consent.youtube.com/
+# URL = https://services.akteneinsichtsportal.de/oauth/authorize?client_id=ae-portal&redirect_uri=https%3A%2F%2Fwww.akteneinsichtsportal.de%2Fweb%2Fguest%2Faktenuebersicht&response_type=code&scope=read&state=0yT8EN
+services.akteneinsichtsportal.de/
+# URL = https://bpe-online.de/wp-content/plugins/pdf-viewer-for-elementor/assets/pdfjs/web/viewer.html?file=https://bpe-online.de/wp-content/uploads/2020/11/HarmReductionLeitfadenzumrisikoarmenAbsetzenvonPsychopharmaka2EdOnline.pdf&embedded=true
+/wp-content/plugins/pdf-viewer-for-elementor
+# URL = https://syndication.twitter.com/i/jot/embeds?l=%7B%22_category_%22%3A%22tfw_client_event%22%2C%22triggered_on%22%3A1709138733184%2C%22event_namespace%22%3A%7B%22client%22%3A%22tfw%22%2C%22page%22%3A%22tweet%22%2C%22action%22%3A%22seen%22%2C%22section%22%3A%22main%22%2C%22component%22%3A%22privacy-notice%22%7D%2C%22context%22%3A%22horizon%22%2C%22client_version%22%3A%222615f7e52b7e0%3A1702314776716%22%2C%22dnt%22%3Afalse%2C%22widget_id%22%3A%22twitter-widget-6%22%2C%22widget_origin%22%3A%22https%3A%2F%2Fwww.danisch.de%2Fblog%2F2024%2F01%2F31%2Fwas-ist-faschismus%2F%22%2C%22widget_frame%22%3A%22false%22%2C%22widget_partner%22%3A%22%22%2C%22widget_site_screen_name%22%3A%22%22%2C%22widget_site_user_id%22%3A%22%22%2C%22widget_creator_screen_name%22%3A%22%22%2C%22widget_creator_user_id%22%3A%22%22%2C%22widget_iframe_version%22%3A%22da31e07063cce%3A1708130301554%22%2C%22item_ids%22%3A%5B%221752320689309143351%22%5D%2C%22item_details%22%3A%7B%221752320689309143351%22%3A%7B%22item_type%22%3A0%7D%7D%7D
+syndication.twitter.com/
 
 {+redirect{s@.*url=@http://@} -block}
 # Sticky Actions = +redirect -block
@@ -2436,11 +2476,17 @@ kggp.de/
 .plasmaservice.de/
 # URL = http://www.black-mosquito.org/index.php/kein-mensch-ist-illegal-fight-racism-now-40-aufkleber.html
 .black-mosquito.org/
+# URL = https://freebsdfoundation.org/about-us/board-of-directors/
+freebsdfoundation.org/
+# URL = https://freiheitsfoo.de/2022/10/03/wahlplakat-show-nds-ltw-2022/
+.freiheitsfoo.de/
 
 {-filter{banners-by-link}}
 # Sticky Actions = -filter{banners-by-link}
 # URL = http://www.encyclopediadramatica.com/Advertisement
 .encyclopediadramatica.com/
+# URL = https://www.eff.org/deeplinks/2022/03/eff-investigation-mystery-gps-tracker-supporters-car
+.eff.org/
 
 #----------------------------------------------------------------------------
 # These don't work without the referrer information:
index e19f6cf..aaf70a3 100644 (file)
@@ -4,7 +4,7 @@
 #
 #  Purpose     :  Rules to process the content of web pages
 #
-#  Copyright   :  Written by and Copyright (C) 2001-2021 the
+#  Copyright   :  Written by and Copyright (C) 2001-2022 the
 #                 Privoxy team. https://www.privoxy.org/
 #
 #                 This program is free software; you can redistribute it
@@ -718,6 +718,17 @@ s@(background:\#[a-f\d]{3})( url\(\"http://www.blogblog.com/rounders[^\"]*\"\).*
 s@<title(?:\s+type=\'text\')?>([^<]*)(?:\.\.\.)?\s*</title>\s*\
 (<content(?:\s+type=\'(?:html|text)\')?>\s*\1)@<title></title>$2@ig
 
+
+#################################################################################
+#
+# bundeswehr.de: Hide the cookie and privacy info banner on bundeswehr.de.
+#
+#                The relevant parts of the page work without accepting cookies.
+#
+#################################################################################
+FILTER: bundeswehr.de Hide the cookie and privacy info banner on bundeswehr.de
+s@<div class="privacy-protection-banner__container"@$0 style="display: none"@
+
 #################################################################################
 #
 # sourceforge: Reduces the amount of ads for proprietary software on SourceForge.
index e8fbc61..95c3c84 100644 (file)
 <!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V3.1//EN" [
 <!entity % dummy "IGNORE">
 <!entity authors SYSTEM "p-authors.sgml">
-<!entity p-version "3.0.33">
-<!entity p-status "stable">
-<!entity % p-not-stable "IGNORE">
-<!entity % p-stable "INCLUDE">
+<!entity p-version "3.0.35">
+<!entity p-status "UNRELEASED">
+<!entity % p-not-stable "INCLUDE">
+<!entity % p-stable "IGNORE">
 <!entity % p-text "INCLUDE">           <!-- define we are a text only doc -->
 <!entity % p-authors-formal "INCLUDE"> <!-- include additional text, etc  -->
 ]>
index 48b759d..f4d6e00 100644 (file)
@@ -3,7 +3,7 @@
 
  Purpose     :  Entity included in other project documents.
 
- Copyright (C) 2013-2021 Privoxy Developers https://www.privoxy.org/
+ Copyright (C) 2013-2023 Privoxy Developers https://www.privoxy.org/
  See LICENSE.
 
  ======================================================================
 -->
 
 <para>
-  <application>Privoxy 3.0.32</application> fixes multiple DoS issues
-  and a couple of other bugs. The issues also affect earlier Privoxy
-  releases.
+  <application>Privoxy 3.0.34</application> fixes a few
+  minor bugs and comes with a couple of general improvements
+  and new features.
 </para>
- <para>
-  Changes in <application>Privoxy 3.0.32</application> stable:
- </para>
- <para>
+<para>
+  Changes in <application>Privoxy 3.0.34</application> stable:
+</para>
+<para>
  <itemizedlist>
   <listitem>
    <para>
-    Security/Reliability:
+    Bug fixes:
     <itemizedlist>
     <listitem>
      <para>
-      ssplit(): Remove an assertion that could be triggered with a
-      crafted CGI request.
-      Commit 2256d7b4d67. OVE-20210203-0001.
-      Reported by: Joshua Rogers (Opera)
+      Improve the handling of chunk-encoded responses by buffering the data
+      even if filters are disabled and properly keeping track of where the
+      various chunks are supposed to start and end. Previously Privoxy would
+      merely check the last bytes received to see if they looked like the
+      last-chunk. This failed to work if the last-chunk wasn't received in one
+      read and could also result in actual data being misdetected
+      as last-chunk.
+      Should fix: SF support request #1739.
+      Reported by: withoutname.
      </para>
     </listitem>
     <listitem>
      <para>
-      cgi_send_banner(): Overrule invalid image types. Prevents a
-      crash with a crafted CGI request if Privoxy is toggled off.
-      Commit e711c505c48. OVE-20210206-0001.
-      Reported by: Joshua Rogers (Opera)
+      remove_chunked_transfer_coding(): Refuse to de-chunk invalid data
+      Previously the data could get corrupted even further.
+      Now we simply pass the unmodified data to the client.
      </para>
     </listitem>
     <listitem>
      <para>
-      socks5_connect(): Don't try to send credentials when none are
-      configured. Fixes a crash due to a NULL-pointer dereference
-      when the socks server misbehaves.
-      Commit 85817cc55b9. OVE-20210207-0001.
-      Reported by: Joshua Rogers (Opera)
+      gif_deanimate(): Tolerate multiple image extensions in a row.
+      This allows to deanimate all the gifs on:
+      https://commons.wikimedia.org/wiki/Category:Animated_smilies
+      Fixes SF bug #795 reported by Celejar.
      </para>
     </listitem>
     <listitem>
      <para>
-      chunked_body_is_complete(): Prevent an invalid read of size two.
-      Commit a912ba7bc9c. OVE-20210205-0001.
-      Reported by: Joshua Rogers (Opera)
+      OpenSSL generate_host_certificate(): Use X509_get_subject_name()
+      instead of X509_get_issuer_name() to get the issuer for generated
+      website certificates so there are no warnings in the browser when using
+      an intermediate CA certificate instead of a self-signed root certificate.
+      Problem reported and patch submitted by Chakib Benziane.
      </para>
     </listitem>
     <listitem>
      <para>
-      Obsolete pcre: Prevent invalid memory accesses with an invalid
-      pattern passed to pcre_compile(). Note that the obsolete pcre code
-      is scheduled to be removed before the 3.0.33 release. There has been
-      a warning since 2008 already.
-      Commit 28512e5b624. OVE-20210222-0001.
-      Reported by: Joshua Rogers (Opera)
+      can_filter_request_body(): Fix a log message that contained a spurious u.
      </para>
-     </listitem>
-    </itemizedlist>
-   </para>
-  </listitem>
-  <listitem>
-   <para>
-    Bug fixes:
-    <itemizedlist>
+    </listitem>
     <listitem>
      <para>
-      Properly parse the client-tag-lifetime directive. Previously it was
-      not accepted as an obsolete hash value was being used.
-      Reported by: Joshua Rogers (Opera)
+      handle_established_connection(): Check for pending TLS data from the client
+      before checking if data is available on the connection.
+      The TLS library may have already consumed all the data from the client
+      response in which case poll() and select() will not detect that data is
+      available to be read.
+      Sponsored by: Robert Klemme.
      </para>
     </listitem>
     <listitem>
      <para>
-      decompress_iob(): Prevent reading of uninitialized data.
-      Reported by: Joshua Rogers (Opera).
+      ssl_send_certificate_error(): Don't crash if there's no certificate
+      information available. This is only relevant when Privoxy is built with
+      wolfSSL 5.0.0 or later (code not yet published). Earlier wolfSSL versions
+      or the other TLS backends don't seem to trigger the crash.
      </para>
     </listitem>
     <listitem>
      <para>
-      decompress_iob(): Don't advance cur past eod when looking
-      for the end of the file name and comment.
+      socks5_connect(): Add support for target hosts specified as IPv4 address
+      Previously the IP address was sent as domain.
+     </para>
+     </listitem>
+    </itemizedlist>
+   </para>
+  </listitem>
+  <listitem>
+   <para>
+    General improvements:
+    <itemizedlist>
+    <listitem>
+     <para>
+      Add a client-body-tagger action which creates tags based on
+      the content of the request body.
+      Sponsored by: Robert Klemme.
      </para>
     </listitem>
     <listitem>
      <para>
-      decompress_iob(): Cast value to unsigned char before shifting.
-      Prevents a left-shift of a negative value which is undefined behaviour.
-      Reported by: Joshua Rogers (Opera)
+      When client-body filters are enabled, buffer the whole request
+      before opening a connection to the server.
+      Makes it less likely that the server connection times out
+      and we don't open a connection if the buffering fails anyway.
+      Sponsored by: Robert Klemme.
      </para>
     </listitem>
     <listitem>
      <para>
-      gif_deanimate(): Confirm that that we have enough data before doing
-      any work. Fixes a crash when fuzzing with an empty document.
-      Reported by: Joshua Rogers (Opera).
+      Add periods to a couple of log messages.
      </para>
     </listitem>
     <listitem>
      <para>
-      buf_copy(): Fail if there's no data to write or nothing to do.
-      Prevents undefined behaviour "applying zero offset to null pointer".
-      Reported by: Joshua Rogers (Opera)
+      accept_connection(): Add missing space to a log message.
      </para>
     </listitem>
     <listitem>
      <para>
-      log_error(): Treat LOG_LEVEL_FATAL as fatal even when --stfu is
-      being used while fuzzing.
-      Reported by: Joshua Rogers (Opera).
+      Initialize ca-related defaults with strdup_or_die() so errors
+      aren't silently ignored.
      </para>
     </listitem>
     <listitem>
      <para>
-      Respect DESTDIR when considering whether or not to install
-      config files with ".new" extension.
+      make_path: Use malloc_or_die() in cases where allocation errors
+      were already fatal anyway.
      </para>
     </listitem>
     <listitem>
      <para>
-      OpenSSL ssl_store_cert(): Fix two error messages.
+      handle_established_connection(): Improve an error message slightly.
      </para>
     </listitem>
     <listitem>
      <para>
-      Fix a couple of format specifiers.
+      receive_client_request(): Reject https URLs without CONNECT request.
      </para>
     </listitem>
     <listitem>
      <para>
-      Silence compiler warnings when compiling with NDEBUG.
+      Include all requests in the statistics if mutexes are available.
+      Previously in case of reused connections only the last request got
+      counted. The statistics still aren't perfect but it's an improvement.
      </para>
     </listitem>
     <listitem>
      <para>
-      fuzz_server_header(): Fix compiler warning.
+      Add read_socks_reply() and start using it in socks5_connect()
+      to apply the socket timeout more consistently.
      </para>
     </listitem>
     <listitem>
      <para>
-      fuzz_client_header(): Fix compiler warning.
+      socks5_connect(): Deal with domain names in the socks reply
      </para>
     </listitem>
     <listitem>
      <para>
-      cgi_send_user_manual(): Also reject requests if the user-manual
-      directive specifies a https:// URL. Previously Privoxy would try and
-      fail to open a local file.
+      Add a filter for bundeswehr.de that hides the cookie and
+      privacy info banner.
      </para>
      </listitem>
     </itemizedlist>
   </listitem>
   <listitem>
    <para>
-    General improvements:
+    Action file improvements:
     <itemizedlist>
     <listitem>
      <para>
-      Log the TLS version and the the cipher when debug 2 is enabled.
+      Disable filter{banners-by-size} for .freiheitsfoo.de/.
      </para>
     </listitem>
     <listitem>
      <para>
-      ssl_send_certificate_error(): Respect HEAD requests by not sending a body.
+      Disable filter{banners-by-size} for freebsdfoundation.org/.
      </para>
     </listitem>
     <listitem>
      <para>
-      ssl_send_certificate_error(): End the body with a single new line.
+      Disable fast-redirects for consent.youtube.com/.
      </para>
     </listitem>
     <listitem>
      <para>
-      serve(): Increase the chances that the host is logged when closing
-      a server socket.
+      Block requests to ups.xplosion.de/.
      </para>
     </listitem>
     <listitem>
      <para>
-      handle_established_connection(): Add parentheses to clarify an expression
-      Suggested by: David Binderman
+      Block requests for elsa.memoinsights.com/t.
      </para>
     </listitem>
     <listitem>
      <para>
-      continue_https_chat(): Explicitly unset CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE
-      if process_encrypted_request() fails. This makes it more obvious that the
-      connection will not be reused. Previously serve() relied on
-      CSP_FLAG_SERVER_CONTENT_LENGTH_SET and CSP_FLAG_CHUNKED being unset.
-      Inspired by a patch from Joshua Rogers (Opera).
+      Fix a typo in a test.
      </para>
     </listitem>
     <listitem>
      <para>
-      decompress_iob(): Add periods to a couple of log messages
+      Disable fast-redirects for launchpad.net/.
      </para>
     </listitem>
     <listitem>
      <para>
-      Terminate the body of the HTTP snipplets with a single new line
-      instead of "\r\n".
+      Unblock .eff.org/.
      </para>
     </listitem>
     <listitem>
      <para>
-      configure: Add --with-assertions option and only enable assertions
-      when it is used
+      Stop unblocking .org/.*(image|banner) which appears to be too generous
+      The example URL http://www.gnu.org/graphics/gnu-head-banner.png is
+      already unblocked due to .gnu.org being unblocked.
      </para>
     </listitem>
     <listitem>
      <para>
-      windows build: Use --with-brotli and --with-mbedtls by default and
-      enable dynamic error checking.
+      Unblock adfd.org/.
      </para>
     </listitem>
     <listitem>
      <para>
-      gif_deanimate(): Confirm we've got an image before trying to write it
-      Saves a pointless buf_copy() call.
+      Disable filter{banners-by-link} for .eff.org/.
      </para>
     </listitem>
     <listitem>
      <para>
-      OpenSSL ssl_store_cert(): Remove a superfluous space before the serial number.
+      Block requests to odb.outbrain.com/.
      </para>
-     </listitem>
-    </itemizedlist>
-   </para>
-  </listitem>
-  <listitem>
-   <para>
-    Action file improvements:
-    <itemizedlist>
+    </listitem>
     <listitem>
      <para>
-      Disable fast-redirects for .golem.de/
+      Disable fast-redirects for .gandi.net/.
      </para>
     </listitem>
     <listitem>
      <para>
-      Unblock requests to adri*.
+      Disable fast-redirects{} for .onion/.*/status/.
      </para>
     </listitem>
     <listitem>
      <para>
-      Block requests for trc*.taboola.com/
+      Disable fast-redirects{} for twitter.com/.*/status/.
      </para>
     </listitem>
     <listitem>
      <para>
-      Disable fast-redirects for .linkedin.com/
+      Unblock pinkstinks.de/.
+     </para>
+    </listitem>
+    <listitem>
+     <para>
+      Disable fast-redirects for .hagalil.com/.
      </para>
      </listitem>
     </itemizedlist>
   </listitem>
   <listitem>
    <para>
-    Filter file improvements:
+    Privoxy-Log-Parser:
     <itemizedlist>
     <listitem>
      <para>
-      Make the second pcrs job of the img-reorder filter greedy again.
-      The ungreedy version broke the img tags on:
-      https://bulk.fefe.de/scalability/.
+      Bump version to 0.9.5.
      </para>
     </listitem>
+    <listitem>
+     <para>
+      Highlight more log messages.
+     </para>
+    </listitem>
+    <listitem>
+     <para>
+      Highlight the Crunch reason only once. Previously the "crunch reason"
+      could also be highlighted when the URL contained a matching string.
+      The real crunch reason only occurs once per line, so there's no need
+      to continue looking for it after it has been found once.
+      While at it, add a comment with an example log line.
+     </para>
+     </listitem>
     </itemizedlist>
    </para>
   </listitem>
   <listitem>
    <para>
-    Privoxy-Log-Parser:
+    uagen:
     <itemizedlist>
     <listitem>
      <para>
-      Highlight a few more messages.
+      Bump version to 1.2.4.
+     </para>
+    </listitem>
+    <listitem>
+     <para>
+      Update BROWSER_VERSION and BROWSER_REVISION to 102.0
+      to match the User-Agent of the current Firefox ESR.
      </para>
     </listitem>
     <listitem>
      <para>
-      Clarify the --statistics output. The shown "Reused connections"
-      are server connections so name them appropriately.
+      Explicitly document that changing the 'Gecko token' is suspicious.
      </para>
     </listitem>
     <listitem>
      <para>
-      Bump version to 0.9.3.
+      Consistently use a lower-case 'c' as copyright symbol.
+     </para>
+    </listitem>
+    <listitem>
+     <para>
+      Bump copyright.
+     </para>
+    </listitem>
+    <listitem>
+     <para>
+      Add 'aarch64' as Linux architecture.
+     </para>
+    </listitem>
+    <listitem>
+     <para>
+      Add OpenBSD architecture 'arm64'.
+     </para>
+    </listitem>
+    <listitem>
+     <para>
+      Stop using sparc64 as FreeBSD architecture.
+      It hasn't been supported for a while now.
      </para>
      </listitem>
     </itemizedlist>
   </listitem>
   <listitem>
    <para>
-    Privoxy-Regression-Test:
+    Build system:
     <itemizedlist>
     <listitem>
      <para>
-      Add the --check-bad-ssl option to the --help output.
+      Makefile: Add a 'dok' target that depends on the 'error' target
+      to show the "You are not using GNU make or did nor run configure"
+      message.
      </para>
     </listitem>
     <listitem>
      <para>
-      Bump version to 0.7.3.
+      configure: Fix --with-msan option.
+      Also (probably) reported by Andrew Savchenko.
+     </para>
+     </listitem>
+    </itemizedlist>
+   </para>
+  </listitem>
+  <listitem>
+   <para>
+    macOS build system:
+    <itemizedlist>
+    <listitem>
+     <para>
+      Enable HTTPS inspection when building the macOS binary
+      (using OpenSSL as TLS library).
      </para>
      </listitem>
     </itemizedlist>
     <itemizedlist>
     <listitem>
      <para>
-      Add pushing the created tag to the release steps in the developer manual.
+      Add OpenSSL to the list of libraries that may be licensed under the
+      Apache 2.0 license in which case the linked Privoxy binary has to be
+      distributed under the GPLv3 or later.
      </para>
     </listitem>
     <listitem>
      <para>
-      Clarify that 'debug 32768' should be used in addition to the other debug
-      directives when reporting problems.
+      config: Fix the documented ca-directory default value.
+      Reported by avoidr.
      </para>
-     </listitem>
+    </listitem>
     <listitem>
      <para>
-      Add a 'Third-party licenses and copyrights' section to the user manual.
+      Rebuild developer-manual and tidy with 'HTML Tidy for FreeBSD version 5.8.0'.
      </para>
     </listitem>
+    <listitem>
+     <para>
+      Update developer manual with new macOS packaging instructions.
+     </para>
+    </listitem>
+    <listitem>
+     <para>
+      Note that the FreeBSD installation instructions work for
+      ElectroBSD as well.
+     </para>
+    </listitem>
+    <listitem>
+     <para>
+      Note that FreeBSD/ElectroBSD users can try to install Privoxy
+      as binary package using 'pkg'.
+     </para>
+     </listitem>
     </itemizedlist>
    </para>
   </listitem>
index e38d26c..127bd45 100644 (file)
@@ -1,9 +1,9 @@
 <!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V3.1//EN"[
 <!entity % dummy "IGNORE">
 <!entity config SYSTEM "p-config.sgml">
-<!entity p-version "3.0.33">
-<!entity p-status "stable">
-<!entity % p-not-stable "IGNORE">
+<!entity p-version "3.0.35">
+<!entity p-status "UNRELEASED">
+<!entity % p-not-stable "INCLUDE">
 <!entity % user-man "IGNORE">
 <!entity % config-file "IGNORE">
 <!entity  my-app "<application>Privoxy</application>">
index d00546c..7b05168 100644 (file)
@@ -29,7 +29,7 @@
 -->
 
 <para>
- Copyright &my-copy; 2001-2021 by Privoxy Developers <email>privoxy-devel@lists.privoxy.org</email>
+ Copyright &my-copy; 2001-2023 by Privoxy Developers <email>privoxy-devel@lists.privoxy.org</email>
 </para>
 
 <para>
index bf09236..e17e675 100644 (file)
@@ -5,10 +5,10 @@
 <!entity p-intro SYSTEM "privoxy.sgml">
 <!entity history SYSTEM "history.sgml">
 <!entity seealso SYSTEM "seealso.sgml">
-<!entity p-version "3.0.33">
-<!entity p-status "stable">
-<!entity % p-not-stable "IGNORE">
-<!entity % p-stable "INCLUDE">
+<!entity p-version "3.0.35">
+<!entity p-status "UNRELEASED">
+<!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 % seealso-extra "INCLUDE"> <!-- extra stuff from seealso.sgml    -->
@@ -19,7 +19,7 @@
 
  Purpose     :  developer manual
 
- Copyright (C) 2001-2021 Privoxy Developers https://www.privoxy.org/
+ Copyright (C) 2001-2023 Privoxy Developers https://www.privoxy.org/
  See LICENSE.
 
  ========================================================================
@@ -39,7 +39,7 @@
     <!-- Completely the wrong markup, but very little is allowed  -->
     <!-- in this part of an article. FIXME -->
       <ulink url="https://www.privoxy.org/user-manual/copyright.html">Copyright</ulink>
-      &my-copy; 2001-2021 by
+      &my-copy; 2001-2023 by
       <ulink url="https://www.privoxy.org/">Privoxy Developers</ulink>
      </subscript>
     </pubdate>
@@ -2602,8 +2602,8 @@ make tarball-dist
         Check that you have the current versions of the
         <ulink url="https://sourceforge.net/projects/nsis/files/NSIS%203/">
                     NSIS installer</ulink>,
-        <ulink url="https://ftp.pcre.org/pub/pcre/">PCRE library</ulink>,
-        <ulink url="https://tls.mbed.org/download">MBED TLS library</ulink>,
+        <ulink url="https://sourceforge.net/projects/pcre/files/pcre/">PCRE library</ulink>,
+        <ulink url="https://github.com/Mbed-TLS/mbedtls/tags">MBED TLS library</ulink>,
         <ulink url="https://github.com/google/brotli/releases">
                     Brotli library</ulink>,
         and that the <emphasis>MAKENSIS</emphasis> evar in
@@ -2813,107 +2813,32 @@ git clean -fd
     </sect4>
     </sect3>
 
-    <sect3 id="newrelease-macosx"><title>Mac OS X</title>
+    <sect3 id="newrelease-macosx"><title>macOS / OS X</title>
       <para>
         First, <emphasis>make sure that you have freshly exported the right
         version into an empty directory</emphasis>. (See "Building and releasing
         packages" above).
       </para>
       <para>
-        There are three modules available in the CVS repository backups for use on Mac
-        OS X, though technically only two of them generate a release (the other
-        can be used to install from source).
+        The OSXPackageBuilder module can generate OS X installer packages
+        supporting all Macs running OS X 10.4 and above. Obtain it from Git as
+        follows into a folder parallel to the exported privoxy source:
       </para>
-      <sect4 id="OS-X-OSXPackageBuilder-module">
-      <title>OSXPackageBuilder module (Documentation out of date)</title>
-        <para>
-          The OSXPackageBuilder module generates OS X installer packages
-          supporting all Macs running OS X 10.4 and above. Obtain it from CVS as
-          follows into a folder parallel to the exported privoxy source:
-        </para>
-          <programlisting>
-cvs -z3 -d:pserver:anonymous@ijbswa.cvs.sourceforge.net:/cvsroot/ijbswa co OSXPackageBuilder
-</programlisting>
-<!-- FIXME  cvs is no more!!! -->
-        <para>
-          The module contains complete instructions on its usage in the file
-          <filename>OS X Package Builder HOWTO.txt</filename>.
-        </para>
-        <para>
-          Once the package(s) have been generated, you can then upload them
-          directly to the Files section of the Sourceforge project in the
-          Macintosh (OS X) folder. Each new version release of Privoxy should
-          have a new subfolder created in which to store its files. Please
-          ensure that the folder contains a readme file that makes it clear
-          which package is for whichversion of OS X.
-        </para>
-      </sect4>
-      <sect4 id="OS-X-osxsetup-module">
-      <title>osxsetup module (DEPRECATED) (Documentation out of date)</title>
-        <para>
-          <emphasis>This module is deprecated since the installer it generates
-          places all Privoxy files in one folder in a non-standard location, and
-          supports only Intel Macs running OS X 10.6 or higher.</emphasis>
-        </para>
-        <para>
-          Check out the module from CVS as follows into a folder parallel to the
-          exported privoxy source:
-        </para>
-          <programlisting>
-cvs -z3 -d:pserver:anonymous@ijbswa.cvs.sourceforge.net:/cvsroot/ijbswa co osxsetup
-</programlisting>
-<!--  FIXME  cvs is no more -->
-        <para>
-          Then run:
-        </para>
-          <programlisting>
-cd osxsetup
-build
-</programlisting>
-        <para>
-          This will run <filename>autoheader</filename>, <filename>autoconf</filename>
-          and <filename>configure</filename> as well as <filename>make</filename>.
-          Finally, it will copy over the necessary files to the ./osxsetup/files
-          directory for further processing by <filename>PackageMaker</filename>.
-        </para>
-        <para>
-        Bring up PackageMaker with the PrivoxyPackage.pmsp definition file,
-        modify the package name to match the release, and hit the "Create
-        package" button. If you specify ./Privoxy.pkg as the output package
-        name, you can then create the distributable zip file with the command:
-        </para>
-          <programlisting>
-zip -r privoxyosx_setup_x.y.z.zip Privoxy.pkg
-</programlisting>
-        <para>
-          You can then upload this file directly to the Files section of the
-          Sourceforge project in the Macintosh (OS X) folder. Each new version
-          release of Privoxy should have a new subfolder created in which to
-          store its files.
-          Please ensure that the folder contains a readme file that makes it
-          clear which version(s) of OS X the package supports.
-        </para>
-      </sect4>
-      <sect4 id="OS-X-macsetup-module">
-      <title>macsetup module (Documentation out of date)</title>
-        <para>
-          The macsetup module is ideal if you wish to build and install Privoxy
-          from source on a single machine.
-        </para>
-        <para>
-          Check out the module from CVS as follows into a folder parallel to the
-          exported privoxy source:
-        </para>
-          <programlisting>
-cvs -z3 -d:pserver:anonymous@ijbswa.cvs.sourceforge.net:/cvsroot/ijbswa co macsetup
+        <programlisting>
+git clone ssh://git@git.privoxy.org:23/git/OSXPackageBuilder.git
 </programlisting>
-<!-- FIXME  cvs is no more -->
-        <para>
-          The module contains complete instructions on its usage in its
-          <filename>README</filename> file. The end result will be the
-          exported version of Privoxy installed on the build machine.
-        </para>
-      </sect4>
+      <para>
+        The module contains complete instructions on its usage in the file
+        <filename>OS X Package Builder HOWTO.txt</filename>.
+      </para>
+      <para>
+        Once the package(s) have been generated, you can then upload them
+        directly to the Files section of the Sourceforge project in the
+        Macintosh (OS X) folder. Each new version release of Privoxy should
+        have a new subfolder created in which to store its files. Please
+        ensure that the folder contains a readme file that makes it clear
+        which package is for which version of OS X.
+      </para>
     </sect3>
 
     <sect3 id="newrelease-freebsd"><title>FreeBSD</title>
@@ -2952,6 +2877,31 @@ cvs -z3 -d:pserver:anonymous@ijbswa.cvs.sourceforge.net:/cvsroot/ijbswa co macse
     </para>
    </sect2>
 
+   <sect2 id="update-rss-feed">
+    <title>Updating the RSS feed</title>
+    <para>
+     Once the packages are uploaded to SourceForge they should be
+     mirrored on the Privoxy websites
+     (<ulink url="https://www.privoxy.org/">https://www.privoxy.org/</ulink>
+      and
+      <ulink url="http://l3tczdiiwoo63iwxty4lhs6p7eaxop5micbn7vbliydgv63x5zrrrfyd.onion/">http://l3tczdiiwoo63iwxty4lhs6p7eaxop5micbn7vbliydgv63x5zrrrfyd.onion/</ulink>).
+     This is usually done by Fabian who uses a couple of shell functions
+     for this that aren't documented or published yet.
+    </para>
+    <para>
+     Once the packages are uploaded to the mirror the RSS feed has to
+     be regenerated with a command like:
+    </para>
+    <programlisting>
+     fk@t520 ~/git/privoxy $utils/create-package-feed.pl /tank/backups/sourceforge/frs/project/ijbswa/ doc/webserver/feeds/privoxy-releases.xm
+    </programlisting>
+    <para>
+     The updated RSS feed then has to be uploaded to the SourceForge webserver
+     and mirrored on the Privoxy websites again. This, too, is usually done
+     by Fabian with undocumented and unpublished shell functions.
+    </para>
+   </sect2>
+
     <sect2 id="afterrelease">
     <title>After the Release</title>
      <para>
index af3027e..ff2c4c5 100644 (file)
@@ -8,10 +8,10 @@
 <!entity history SYSTEM "history.sgml">
 <!entity copyright SYSTEM "copyright.sgml">
 <!entity license SYSTEM "license.sgml">
-<!entity p-version "3.0.33">
-<!entity p-status "stable">
-<!entity % p-not-stable "IGNORE">
-<!entity % p-stable "INCLUDE">
+<!entity p-version "3.0.35">
+<!entity p-status "UNRELEASED">
+<!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-supp-userman "INCLUDE"> <!-- Include all from supported.sgml -->
@@ -25,7 +25,7 @@
 
  Purpose     :  FAQ
 
- Copyright (C) 2001-2021 Privoxy Developers https://www.privoxy.org/
+ Copyright (C) 2001-2023 Privoxy Developers https://www.privoxy.org/
  See LICENSE.
 
  Based partially on the Internet Junkbuster FAQ originally written by and
@@ -69,7 +69,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-2021 by
+ <link linkend="copyright">Copyright</link> &my-copy; 2001-2023 by
  <ulink url="https://www.privoxy.org/">Privoxy Developers</ulink>
  </subscript>
 </pubdate>
@@ -567,6 +567,10 @@ warranty? Registration?</title>
  The details may change over time but changes will only affect new sponsors
  (or existing sponsors that explicitly agreed to the changes).
 </para>
+<para>
+ Thanks to <ulink url="https://www.spi-inc.org/">Software in the Public Interest (SPI)</ulink>
+ <application>Privoxy</application> sponsors can get a proper invoice.
+</para>
 <para>
  If you want to become a sponsor, please contact
  <ulink url="mailto:fk@fabiankeil.de">Fabian Keil</ulink>
index 7a64742..3f84812 100644 (file)
@@ -1,10 +1,10 @@
 <!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V3.1//EN" [
 <!entity % dummy "IGNORE">
 <!entity buildsource SYSTEM "buildsource.sgml">
-<!entity p-version "3.0.33">
-<!entity p-status "stable">
-<!entity % p-stable "INCLUDE">
-<!entity % p-not-stable "IGNORE">
+<!entity p-version "3.0.35">
+<!entity p-status "UNRELEASED">
+<!entity % p-stable "IGNORE">
+<!entity % p-not-stable "INCLUDE">
 <!entity % p-alpha "IGNORE">
 <!entity % p-beta "IGNORE">
 <!entity % p-text "INCLUDE">       <!-- define we are a text only doc    -->
index 6015748..48aff0b 100644 (file)
@@ -3,7 +3,7 @@
 
  Purpose     :  Entity included in other project documents.
 
- Copyright (C) 2001-2020 the Privoxy Developers https://www.privoxy.org/
+ Copyright (C) 2001-2022 the Privoxy Developers https://www.privoxy.org/
  See LICENSE.
 
  ======================================================================
@@ -34,7 +34,8 @@
 <para>
  The same is true for <application>Privoxy</application> binaries
  unless they are linked with a
- <ulink url="https://tls.mbed.org/">mbed TLS</ulink> version
+ <ulink url="https://www.trustedfirmware.org/projects/mbed-tls/">mbed TLS</ulink> or
+ <ulink url="https://www.openssl.org/">OpenSSL</ulink> version
  that is licensed under the Apache 2.0 license in which
  case you can redistribute and/or modify the <application>Privoxy</application>
  binaries under the terms of the <citetitle>GNU General Public License</citetitle>
index 883432e..c82129d 100644 (file)
@@ -3,7 +3,7 @@
 
  Purpose     :  Entity included in other project documents.
 
- Copyright (C) 2001-2021 Privoxy Developers https://www.privoxy.org/
+ Copyright (C) 2001-2023 Privoxy Developers https://www.privoxy.org/
  See LICENSE.
 
  ======================================================================
@@ -84,9 +84,11 @@ Current Privoxy Team:
  Anatoly Arzhnikov
  Ken Arromdee
  Natxo Asenjo
+ avoidr
  Devin Bayer
  Havard Berland
  David Binderman
+ Ingo Blechschmidt
  David Bo
  Gergely Bor
  Francois Botha
@@ -96,6 +98,8 @@ Current Privoxy Team:
  Andrew J. Caines
  Clifford Caoile
  Edward Carrel
+ Celejar
+ Chakib Benziane
  Pak Chan
  Wan-Teh Chang
  Sam Chen
@@ -116,6 +120,7 @@ Current Privoxy Team:
  Markus Elfring
  Ryan Farmer
  Matthew Fischer
+ Fabrice Fontaine
  T Ford
  Dean Gaudet
  Stephen Gildea
@@ -156,6 +161,7 @@ Current Privoxy Team:
  Zeno Kugy
  David Laight
  Bert van Leeuwen
+ Aaron Li
  Don Libes
  Paul Lieverse
  Adele Lime
@@ -200,6 +206,7 @@ Current Privoxy Team:
  Andreas Rutkauskas
  Sam
  Saperski
+ Andrew Savchenko
  Bart Schelstraete
  Richard Schneidt
  Gregory Seidman
@@ -207,8 +214,10 @@ Current Privoxy Team:
  Mark Seward
  Franz Schwartau
  Chung-chieh Shan
+ Gagan Sidhu
  Johan Sintorn
  Benjamin C. Wiley Sittler
+ Juliusz Sosinowicz
  DRS David Soft
  Simon South
  Dan Stahlke
@@ -235,6 +244,7 @@ Current Privoxy Team:
  David Wagner
  Glenn Washburn
  Song Weijia
+ Florian Weimer
  J&ouml;rg Weinmann
  Darren Wiebe
  Anduin Withers
index 0a9330d..f328827 100644 (file)
@@ -3,7 +3,7 @@
 
  Purpose     :  Used with other docs and files only.
 
- Copyright (C) 2001-2021 Privoxy Developers https://www.privoxy.org/
+ Copyright (C) 2001-2023 Privoxy Developers https://www.privoxy.org/
  See LICENSE.
 
  ========================================================================
@@ -90,7 +90,7 @@
  Sample Configuration File for Privoxy &p-version;
 </title>
 <para>
-Copyright (C) 2001-2021 Privoxy Developers https://www.privoxy.org/
+Copyright (C) 2001-2023 Privoxy Developers https://www.privoxy.org/
 </para>
 
 <literallayout>
@@ -107,7 +107,7 @@ Copyright (C) 2001-2021 Privoxy Developers https://www.privoxy.org/
       4. ACCESS CONTROL AND SECURITY                             #
       5. FORWARDING                                              #
       6. MISCELLANEOUS                                           #
-      7. HTTPS INSPECTION (EXPERIMENTAL)                         #
+      7. HTTPS INSPECTION                                        #
       8. WINDOWS GUI OPTIONS                                     #
                                                                  #
 ##################################################################
@@ -336,7 +336,7 @@ II. FORMAT OF THE CONFIGURATION FILE
   <term>Notes:</term>
   <listitem>
    <para>
-    The value of this option only matters if the experimental trust mechanism has been
+    The value of this option only matters if the trust mechanism has been
     activated. (See <link linkend="trustfile"><emphasis>trustfile</emphasis></link> below.)
    </para>
    <para>
@@ -3913,7 +3913,7 @@ compression-level 0
 
 
 <sect2 id="https-inspection-directives">
-<title>HTTPS Inspection (Experimental)</title>
+<title>HTTPS Inspection</title>
 
 <para>
   HTTPS inspection allows to filter encrypted requests and responses.
@@ -3946,7 +3946,7 @@ compression-level 0
  <varlistentry>
   <term>Default value:</term>
   <listitem>
-   <para><emphasis>Empty string</emphasis></para>
+   <para><emphasis>./CA</emphasis></para>
   </listitem>
  </varlistentry>
  <varlistentry>
index 141dd4a..3879f59 100644 (file)
 <!entity copyright SYSTEM "copyright.sgml">
 <!entity license SYSTEM "license.sgml">
 <!entity authors SYSTEM "p-authors.sgml">
-<!entity p-version "3.0.33">
-<!entity p-status "stable">
-<!entity % p-not-stable "IGNORE">
-<!entity % p-stable "INCLUDE">
+<!entity p-version "3.0.35">
+<!entity p-status "UNRELEASED">
+<!entity % p-not-stable "INCLUDE">
+<!entity % p-stable "IGNORE">
 <!entity % p-text "IGNORE">           <!-- define we are not a text only doc -->
 <!entity % p-authors-formal "IGNORE"> <!-- exclude additional formatting      -->
 <!entity my-copy "(C)">               <!-- db2man barfs on copyright symbol  -->
index 9e34fe7..e0e93a5 100644 (file)
@@ -4,10 +4,10 @@
 <!entity p-intro SYSTEM "privoxy.sgml">
 <!entity contacting SYSTEM "contacting.sgml">
 <!entity buildsource SYSTEM "buildsource.sgml">
-<!entity p-version "3.0.33">
-<!entity p-status "stable">
-<!entity % p-not-stable "IGNORE">
-<!entity % p-stable "INCLUDE">
+<!entity p-version "3.0.35">
+<!entity p-status "UNRELEASED">
+<!entity % p-not-stable "INCLUDE">
+<!entity % p-stable "IGNORE">
 <!entity % p-text "INCLUDE">       <!-- define we are a text only doc    -->
 <!entity % p-doc "IGNORE">         <!-- and never a text doc             -->
 <!entity % p-readme "INCLUDE">     <!-- all your README belong to us     -->
index 420c065..bc45663 100644 (file)
   user-manual
   faq
   newfeatures
-  announce
 
 -->
 <para>
  At present, <application>Privoxy</application> is known to run on
- Windows 95 and later versions (98, ME, 2000, XP, Vista, Windows 7, Windows 10 etc.),
+ Windows 95 and later versions (98, ME, 2000, XP, Vista, Windows 7, Windows 10,
+ Windows 11 etc.),
  GNU/Linux (RedHat, SuSE, Debian, Fedora, Gentoo, Slackware and others),
  Mac OS X (10.4 and upwards on PPC and Intel processors),
  Haiku,
  and various other flavors of Unix.
 </para>
 
+<para>
+ The binaries provided by members of the Privoxy team have the following
+ testing platforms, earliest supported OS versions and processor architectures.
+ Be aware that down-level versions of Privoxy contain known security issues.
+ <emphasis>It is preferable to build the latest code to target earlier OS releases
+ than use an earlier Privoxy release</emphasis>:
+
+ <table frame='all'><title>Operating system support for binaries provided by Privoxy team members</title>
+ <tgroup cols='5' align='left' colsep='1' rowsep='1'>
+ <thead>
+ <row>
+  <entry>Operating System</entry>
+  <entry>Privoxy Release</entry>
+  <entry>Testing Platforms</entry>
+  <entry>Earliest OS Version Supported</entry>
+  <entry>Processor Architectures</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+  <entry>Windows</entry>
+  <entry>3.0.33</entry>
+  <entry>Windows 10</entry>
+  <entry>Windows Vista</entry>
+  <entry>Intel 32 and 64 bit</entry>
+ </row>
+ <row>
+  <entry> </entry>
+  <entry>3.0.32</entry>
+  <entry>Windows 10</entry>
+  <entry>Windows XP</entry>
+  <entry>Intel 32 and 64 bit</entry>
+ </row>
+ <row>
+  <entry>macOS</entry>
+  <entry>3.0.33</entry>
+  <entry>El Capitan (10.11.6)</entry>
+  <entry>Snow Leopard (10.6.1)</entry>
+  <entry>Intel 64 bit</entry>
+ </row>
+ <row>
+  <entry> </entry>
+  <entry>3.0.26</entry>
+  <entry>El Capitan (10.11.6), Tiger (10.4.1) PPC</entry>
+  <entry>Tiger (10.4.1)</entry>
+  <entry>Intel 32 & 64 bit, PowerPC</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+</para>
+
 <![%p-supp-userman;[
 <para>
But any operating system that runs TCP/IP, can conceivably take advantage of
Any operating system that runs TCP/IP, can conceivably take advantage of
  <application>Privoxy</application> in a networked situation where
  <application>Privoxy</application> would run as a server on a LAN gateway.
  Then only the <quote>gateway</quote> needs to be running one of the above
@@ -43,6 +95,7 @@
 
 <para>
  Source code is freely available, so porting to other operating systems
- is always a possibility.
+ is always a possibility, as is compiling for older versions of supported
+ operating systems.
 </para>
 ]]>
index 3927c4b..a1b86b1 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.33">
-<!entity p-status "stable">
+<!entity p-version "3.0.35">
+<!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-2021 Privoxy Developers https://www.privoxy.org/
+ Copyright (C) 2001-2023 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-2021 by
+ <link linkend="copyright">Copyright</link> &my-copy; 2001-2023 by
  <ulink url="https://www.privoxy.org/">Privoxy Developers</ulink>
  </subscript>
 </pubdate>
@@ -302,12 +302,16 @@ How to install the binary packages depends on your operating system:
 </sect3>
 
 <!--   ~~~~~       New section      ~~~~~     -->
-<sect3 id="installation-freebsd"><title>FreeBSD</title>
+<sect3 id="installation-freebsd"><title>FreeBSD and ElectroBSD</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 your system is configured to install binary packages you can
+ try to install &my-app; with <literal>pkg install privoxy</literal>.
+</para>
 </sect3>
 
 </sect2>
@@ -409,8 +413,8 @@ MAKENSIS = /&lt;root-dir>/nsis/makensis.exe
 
       <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>
+        <ulink url="https://sourceforge.net/projects/pcre/files/pcre/">PCRE
+                    https://sourceforge.net/projects/pcre/files/pcre/</ulink>
         and build the static PCRE libraries with
 
         <screen>
@@ -437,9 +441,9 @@ export CPPFLAGS="-DPCRE_STATIC"
 
       <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>,
+        2.28.x MBED-TLS library source code from
+        <ulink url="https://github.com/Mbed-TLS/mbedtls/tags">
+                    https://github.com/Mbed-TLS/mbedtls/tags</ulink>,
         extract the tar file into <literal>&lt;root-dir&gt;</literal>
         and build the static libraries with
         <programlisting>
@@ -2536,12 +2540,6 @@ media.example.com/.*banners
 <!-- XXX: This section contains duplicates content from the
           client-specific-tag documentation. -->
 
-<warning>
-<para>
- This is an experimental feature. The syntax is likely to change in future versions.
-</para>
-</warning>
-
 <para>
  Client tag patterns are not set based on HTTP headers but based on
  the client's IP address. Users can enable them themselves, but the
@@ -3135,6 +3133,85 @@ adserver.example.net/.*\.js$
 </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">
 <title>client-header-tagger</title>
@@ -4026,6 +4103,12 @@ problem-host.example.com</screen>
     linkend="external-filter-syntax">syntax</link></literal>
     may change in the future.
    </para>
+   <para>
+    If you want to apply external filters to images or other content
+    that isn't text-based, enable the
+    <literal><link linkend="force-text-mode">force-text-mode</link></literal>
+    action as well.
+   </para>
 
   </listitem>
  </varlistentry>
@@ -4386,6 +4469,10 @@ another.example.com/testing
     <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-bundeswehr.de">
+   </para>
+    <screen>+filter{bundeswehr.de}      # Hide the cookie and privacy info banner on bundeswehr.de.</screen>
    <para>
     <anchor id="filter-github">
    </para>
@@ -5371,9 +5458,6 @@ new action
     a pattern with path doesn't work as the path is only seen
     by &my-app; if the action is already enabled.
    </para>
-   <para>
-    This is an experimental feature.
-   </para>
   </listitem>
  </varlistentry>
 
@@ -7107,8 +7191,9 @@ webmail.example.com
 </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
@@ -7642,9 +7727,9 @@ pre-defined filters for your convenience:
   <term><emphasis>banners-by-link</emphasis></term>
   <listitem>
    <para>
-    This is an experimental filter that attempts to kill any banners if
-    their URLs seem to point to known or suspected click trackers. It is currently
-    not of much value and is not recommended for use by default.
+    This filter attempts to kill any banners if their URLs seem to point
+    to known or suspected click trackers. It is currently not of much value
+    and is not recommended for use by default.
    </para>
   </listitem>
  </varlistentry>
@@ -8093,6 +8178,340 @@ EXTERNAL-FILTER: citation-needed Adds a "[citation needed]" tag to an image. The
 <!--  ~  End section  ~  -->
 
 
+<!--   ~~~~~       New section      ~~~~~     -->
+
+<sect1 id="howto"><title>HOWTOs</title>
+
+<!--   ~~~~~~~~       New section Header    ~~~~~~~~~     -->
+<sect2 id="h2-https-inspection"><title>HTTPS-Inspection HOWTO</title>
+<sect3 id="h2-hi-tls"><title>How TLS Certificates for websites work
+</title>
+<para>
+ The website owner generates a (private) TLS key and a Certificate
+ Signing Request (CSR).
+</para>
+<para>
+ The CSR is then sent to a Certification Authority (CA), which
+ verifies that the owner is the actual owner of the website.  This can
+ be done by proving that the owner has technical write access to the
+ site or the site's DNS, or by verifying the identity of the
+ organization running the site using telephone and public databases.
+</para>
+<para>
+ If the verification is successful, the CA signs the CSR and creates a
+ certificate that certifies that the private TLS key actually belongs
+ to the website name and/or organization that owns the domain.
+</para>
+<para>
+ This TLS certificate is then added to the web server configuration,
+ and when a browser accesses the website, it verifies that the TLS
+ certificate presented to the browser is valid for that domain.
+</para>
+<para>
+ To do this, each browser has the certificates of multiple CAs in its
+ trust store.  Only if the certificate of the CA, that signed the web
+ server is in the trust store, the browser will accept the
+ certificate, otherwise the browser will complain about a broken
+ certificate.
+</para>
+<para>
+ If this check passes, the browser sends a random number encrypted
+ with the server's public key to the server, and both compute a shared
+ secret using the Diffie-Hellman key exchange algorithm.  Now server
+ and browser can communicate, but no one else can break that
+ communication because it's encrypted between them.
+</para>
+</sect3>
+
+<sect3 id="h2-hi-works"><title>How HTTPS inspection works</title>
+<para>
+ When we try to inspect HTTPS traffic, we have to break the TLS
+ encryption between browser and web server without being the browser
+ or the web server.  This is exactly what TLS tries to avoid, as it's
+ a man-in-the-middle-attack.
+</para>
+<para>
+ To do this, Privoxy uses it's own (private) CA (let's call it
+ "Privoxy CA"), which has to be added to the trust store of every
+ single browser that should be used with Privoxy and HTTPS inspection.
+</para>
+<para>
+ Now Privoxy breaks the connection between browser and webserver by
+ acting as a browser/client when talking to the webserver (including
+ checking the webserver's TLS certificate against it's own trust
+ store).  Now Privoxy can read and modify the traffic from the
+ webserver.
+</para>
+<para>
+ On the other hand, Privoxy itself encrypts the traffic it sends to
+ the browser using an on the fly self-created TLS server certificate
+ that is signed by Privoxy CA.
+</para>
+</sect3>
+
+<sect3 id="h2-hi-invalid-cert"><title>What happens, if the original
+ certificate is invalid?</title>
+<para>
+ If Privoxy detects, that a TLS certificate is not valid, because the
+ certificate is expired, doesn't match the hostname, is self signed or
+ similar, Privoxy blocks the requests and returns an error message
+ explaining the problem to avoid that the user/browser communicates
+ over an insecure communication channel.
+</para>
+<para>
+ To check this behavior, simply go to
+ <ulink url="https://badssl.com/">https://badssl.com/</ulink>
+</para>
+</sect3>
+
+<sect3 id="h2-hi-prerequisites"><title>HTTPS inspection prerequisites
+</title>
+<para>
+ HTTPS inspection in Privoxy can only be used, if Privoxy is built
+ with FEATURE_HTTPS_INSPECTION.  You can check if this feature
+ is enabled at
+ <ulink url="http://config.privoxy.org/show-status">http://config.privoxy.org/show-status</ulink>
+ in the "Conditional #defines" section.
+</para>
+<para>
+ If the feature is not enabled, you may need to
+ <link linkend="installation-source">build Privoxy from source</link>
+ to enable it.  You can use either
+ <ulink url="https://www.trustedfirmware.org/projects/mbed-tls/">MbedTLS</ulink>
+ or <ulink url="https://www.openssl.org/">OpenSSL</ulink>.  It's up to
+ you, which one to use, they both behave the same for HTTPS inspection.
+</para>
+<para>
+ After installing the development libraries for either OpenSSL or
+ MbedTLS, you can run <command>./configure</command> with
+ either the <command>--with-openssl</command> or
+ <command>--with-mbedtls</command> option.
+</para>
+<para>
+ Check the output of <command>./configure</command>, it must contain
+ one of these the following two lines, otherwise HTTPS inspection will
+ not work:
+</para>
+ <screen>
+configure: Detected OpenSSL. Enabling https inspection.
+configure: Detected mbedTLS. Enabling https inspection.
+</screen>
+<para>
+ If you do not find any of these lines, the output of
+ <command>./configure</command> will tell you what went wrong.
+</para>
+<para>
+ You should then proceed with the
+ <link linkend="installation-source">source install</link>.
+ Finally, check the FEATURE_HTTPS_INSPECTION status in
+ <ulink url="http://config.privoxy.org/show-status">http://config.privoxy.org/show-status</ulink>
+ again.
+</para>
+</sect3>
+
+<sect3 id="h2-hi-config"><title>Configuring HTTPS inspection in Privoxy
+</title>
+<para>
+ First, you need to create the private key and certificate for the
+ "Privoxy CA".  This can be done using openssl with the following
+ command:
+ <screen>
+openssl req -new -x509 -extensions v3_ca -keyout privoxy.pem -out privoxy.crt -days 3650
+</screen>
+</para>
+<para>
+ Here we have defined a CA validity of 10 years (3650 days).  You
+ should decide for yourself what is a good validity.  A shorter
+ validity makes your system more secure (it doesn't hurt that long if
+ the key gets lost to an attacker), but if the certificate expires
+ before you have replaced it with a new one in Privoxy and in all
+ browsers, the communication will fail.
+</para>
+<para>
+ During the key generation you will be asked for a "pass phrase".
+ This pass phrase will appear in the Privoxy config CGI, so don't
+ reuse it elsewhere!
+</para>
+<para>
+ Then you will be asked for Country Name, State/Province, Locality,
+ Orginzation Name, Common Name, and Email Address.  You should add
+ some useful data here, because these entries are shown by the browser
+ as "Issuer Name" when you inspect a certificate from an
+ https-inspection site.  Especially the "Common Name" will be shown as
+ the name of your CA, so it's good if you (and other users of your
+ Privoxy instance) are able to identify this CA.
+</para>
+<para>
+ Copy the private key (<filename>privoxy.pem</filename>) and the CA
+ certificate (<filename>privoxy.crt</filename>) into
+ the <link linkend="ca-directory">ca-directory</link> (defined
+ in <link linkend="config">config</link>).
+</para>
+<para>
+ Make sure that the private key (<filename>privoxy.pem</filename> in
+ the above example) is only accessible to the user running Privoxy
+ (usually named "privoxy"):
+</para>
+ <screen>
+chmod 600 privoxy.pem
+chown privoxy privoxy.pem
+</screen>
+<para>
+ Now adjust your Privoxy <link linkend="config">configuration</link>:
+</para>
+ <screen>
+<link linkend="ca-directory">ca-directory</link> /etc/privoxy/CA # read-only
+<link linkend="ca-cert-file">ca-cert-file</link> privoxy.crt     # in ca-directory
+<link linkend="ca-key-file">ca-key-file</link> privoxy.pem      # in ca-directory
+<link linkend="ca-password">ca-password</link> passphrasefromabove
+<link linkend="certificate-directory">certificate-directory</link> /var/lib/privoxy/certs
+<link linkend="trusted-cas-file">trusted-cas-file</link> /etc/ssl/certs/ca-certificates.crt
+</screen>
+<para>
+ <link linkend="certificate-directory">certificate-directory</link>
+ contains the (on the fly) created webserver keys and certificates.
+ It should only be readable by the privoxy user only:
+</para>
+ <screen>
+chown privoxy /var/lib/privoxy/certs
+chmod 700 /var/lib/privoxy/certs.
+</screen>
+<para>
+ <link linkend="trusted-cas-file">trusted-cas-file</link> is the trust
+ store containing the certificates of all CAs that should be accepted.
+ Each browser comes with it's own trust store.  Most Unix systems also
+ ship with a truststore.  Debian ships it's truststore
+ in <filename>/etc/ssl/certs/ca-certificates.crt</filename>, which is
+ installed by the ca-certificates package and can be updated using
+ update-ca-certificates(8).  Alternatively, such a file (extracted
+ from Mozilla) can be downloaded
+ from <ulink url="https://curl.se/docs/caextract.html">https://curl.se/docs/caextract.html</ulink>.
+</para>
+</sect3>
+
+<sect3 id="h2-hi-browser"><title>Browser configuration</title>
+<para>
+ As written above, each browser you use must now trust the newly
+ created Privoxy CA certificate (<filename>privoxy.crt</filename>).
+</para>
+<para>
+ In Firefox you can do this by opening the preferences "Edit" ->
+ "Settings" -> "Privacy & Security" or by typing
+ <ulink url="about:preferences#privacy">about:preferences#privacy</ulink>
+ in the URL.  Then go down to the "Certificates" section and click on
+ "View Certificates". Click on the "Authorities" tab and "Import..."
+ your <filename>privoxy.crt</filename>.  In the "CA certificate trust
+ settings" select "This certificate can identify websites".
+</para>
+<para>
+ In Chrome based browsers, go to the settings and select "Privacy and
+ security"
+ (<ulink url="chrome://settings/privacy">chrome://settings/privacy</ulink>).
+ Click on "Security" and on the opened sub-page on "Manage
+ certificates".  Now go to the "Authorities" tab and
+ import <filename>privoxy.crt</filename> and configure that you trust
+ the certificate for website identification.
+</para>
+</sect3>
+
+<sect3 id="h2-hi-enable"><title>Enabeling HTTPS inspection</title>
+<para>
+ Currently no pages use HTTPS inspection, you need to enable this for
+ some (or all) domains first
+ using <link linkend="user-action">user.action</link> (either by editing
+ the file by hand or via the CGI (this requires
+ <link linkend="enable-edit-actions">enable-edit-actions</link>
+ to be enabled in config) at
+ <ulink url="http://config.privoxy.org/show-status">http://config.privoxy.org/show-status</ulink>
+ (click on user.action Edit button).
+</para>
+<para>
+ Here you can enable HTTPS inspection for individual sites:
+</para>
+ <screen>
+{+<link linkend="https-inspection">https-inspection</link>}
+.badssl.com
+clienttest.ssllabs.com
+</screen>
+<para>
+ You can add more individual sites or wildcards (one per line).
+</para>
+<para>
+ Alternatively, you can use a client-tag to dynamically enable/disable
+ this feature via the browser, as described in the next chapter.
+</para>
+</sect3>
+
+</sect2>
+
+<!--   ~~~~~~~~       New section Header    ~~~~~~~~~     -->
+<sect2 id="h2-client-tags"><title>Client Tags HOWTO</title>
+<para>
+ Client-Tags are a mechanism to dynamically/temporarily enable/disable
+ features in Privoxy per browser.
+</para>
+<para>
+ In our example, we use this for the following two use cases:
+ <itemizedlist>
+  <listitem><para>Enable TOR anonymous proxy</para></listitem>
+  <listitem><para>Enable https-inspection</para></listitem>
+ </itemizedlist>
+</para>
+<para>
+ To use this feature, you must first define a tag name and a tag
+ description for each client-tag in <link linkend="config">config</link>,
+ like this:
+</para>
+ <screen>
+<link linkend="client-specific-tag">client-specific-tag</link> tor Use Tor anonymous proxy
+<link linkend="client-specific-tag">client-specific-tag</link> https-inspection Enable https-inspection
+</screen>
+<para>
+ Now you can open <ulink
+ url="http://config.privoxy.org/client-tags">http://config.privoxy.org/client-tags</ulink>
+ or <ulink url="http://p.p/client-tags">http://p.p/client-tags</ulink>
+ and can enable/disable the tag there (you may want to add a bookmark
+ for this in your browser for quick access, but it's also available as
+ a link at <ulink url="http://p.p">http://p.p</ulink>).
+</para>
+<para>
+ It's also possible to temporarily enable a tag, which by default
+ means 3 minutes (=180 seconds) (and can be changed via the
+ <link linkend="client-tag-lifetime">client-tag-lifetime</link> option
+ in <link linkend="config">config</link>).
+</para>
+<para>
+ But before this has any effect, you have to use the client tag in
+ your <link linkend="user-action">user.action</link> like this:
+</para>
+ <screen>
+{+<link linkend="forward-override">forward-override</link>{<link linkend="socks">forward-socks5t</link> 127.0.0.1:9050 .} }
+<link linkend="client-tag-pattern">CLIENT-TAG</link>:^tor$
+</screen>
+<para>
+ This means, that if the "tor" client tag is enabled, all traffic is
+ forwarded by Privoxy through socks5t to a locally installed tor proxy
+ listening on port 9050.
+</para>
+<para>
+ Similarly, you can specify to use the https-inspection client tag to
+ enable https-inspection:
+</para>
+ <screen>
+{+<link linkend="https-inspection">https-inspection</link>}
+<link linkend="client-tag-pattern">CLIENT-TAG</link>:^https-inspection$
+</screen>
+<para>
+ The tag will be set for all requests coming from clients that have
+ requested it to be set.  Note that "clients" are distinguished by IP
+ address, if the IP address changes, the tag must be requested again.
+</para>
+</sect2>
+
+</sect1>
+
+<!--  ~  End section  ~  -->
+
 
 <!--   ~~~~~       New section      ~~~~~     -->
 
@@ -8126,7 +8545,7 @@ Requests</title>
 <para>
  The same is true for <application>Privoxy</application> binaries
  unless they are linked with a
- <ulink url="https://tls.mbed.org/">mbed TLS</ulink> version
+ <ulink url="https://www.trustedfirmware.org/projects/mbed-tls/">mbed TLS</ulink> version
  that is licensed under the Apache 2.0 license in which
  case you can redistribute and/or modify the <application>Privoxy</application>
  binaries under the terms of the <citetitle>GNU General Public License</citetitle>
@@ -8166,8 +8585,9 @@ Requests</title>
  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>.
+ <ulink url="https://github.com/Mbed-TLS/mbedtls/tags">mbed TLS 2.28.x</ulink> and
+ <ulink url="https://www.openssl.org/">OpenSSL</ulink> and
+ <ulink url="https://www.wolfssl.com/">wolfSSL</ulink>.
 </para>
 <para>
  When compiled with FEATURE_ZLIB (optional),
index 3ff671c..d77e57b 100644 (file)
@@ -5,10 +5,10 @@
 <!entity history SYSTEM "history.sgml">
 <!entity copyright SYSTEM "copyright.sgml">
 <!entity license SYSTEM "license.sgml">
-<!entity p-version "3.0.33">
-<!entity p-status "stable">
-<!entity % p-not-stable "IGNORE">
-<!entity % p-stable "INCLUDE">
+<!entity p-version "3.0.35">
+<!entity p-status "UNRELEASED">
+<!entity % p-not-stable "INCLUDE">
+<!entity % p-stable "IGNORE">
 <!entity  my-copy "&copy;">        <!-- kludge for docbook2man            -->
 <!entity % p-homepage "IGNORE">    <!-- toggle for webserver index.html   -->
 <!entity % p-index "IGNORE">       <!-- toggle for local doc index        -->
@@ -18,7 +18,7 @@
 
  Purpose     :  Index file of the project's homepage and also documentation index
                 
- Copyright (C) 2001-2020 Privoxy developers <privoxy-devel@lists.privoxy.org>
+ Copyright (C) 2001-2023 Privoxy developers <privoxy-devel@lists.privoxy.org>
  See LICENSE.
 
  ========================================================================
 <!-- GNUMakefile is inserting this now -->
 <para>
  <subscript>
-  Copyright __copy 2001-2021 by Privoxy Developers
+  Copyright __copy 2001-2023 by Privoxy Developers
  </subscript>
 </para>
 
index 20cdfd4..446acf2 100644 (file)
-               Announcing Privoxy 3.0.32 stable
+               Announcing Privoxy 3.0.34 stable
 --------------------------------------------------------------------
 
-Privoxy 3.0.32 fixes multiple DoS issues and a couple of other bugs.
-The issues also affect earlier Privoxy releases.
+Privoxy 3.0.34 fixes a few minor bugs and comes with a couple of
+general improvements and new features.
+
+Please note that Google started to bounce messages from the Privoxy
+mailing lists a couple of months ago. As a result gmail users have
+been unsubscribed by Mailman. If you are affected by this, please
+resubscribe with a different mail address. The Privoxy project has
+limited resources and limited time to investigate an issue that
+only affects gmail addresses.
 
 --------------------------------------------------------------------
-ChangeLog for Privoxy 3.0.32
+ChangeLog for Privoxy 3.0.34
 --------------------------------------------------------------------
-- Security/Reliability:
-  - ssplit(): Remove an assertion that could be triggered with a
-    crafted CGI request.
-    Commit 2256d7b4d67. OVE-20210203-0001.
-    Reported by: Joshua Rogers (Opera)
-  - cgi_send_banner(): Overrule invalid image types. Prevents a
-    crash with a crafted CGI request if Privoxy is toggled off.
-    Commit e711c505c48. OVE-20210206-0001.
-    Reported by: Joshua Rogers (Opera)
-  - socks5_connect(): Don't try to send credentials when none are
-    configured. Fixes a crash due to a NULL-pointer dereference
-    when the socks server misbehaves.
-    Commit 85817cc55b9. OVE-20210207-0001.
-    Reported by: Joshua Rogers (Opera)
-  - chunked_body_is_complete(): Prevent an invalid read of size two.
-    Commit a912ba7bc9c. OVE-20210205-0001.
-    Reported by: Joshua Rogers (Opera)
-  - Obsolete pcre: Prevent invalid memory accesses with an invalid
-    pattern passed to pcre_compile(). Note that the obsolete pcre code
-    is scheduled to be removed before the 3.0.33 release. There has been
-    a warning since 2008 already.
-    Commit 28512e5b624. OVE-20210222-0001.
-    Reported by: Joshua Rogers (Opera)
-
 - Bug fixes:
-  - Properly parse the client-tag-lifetime directive. Previously it was
-    not accepted as an obsolete hash value was being used.
-    Reported by: Joshua Rogers (Opera)
-  - decompress_iob(): Prevent reading of uninitialized data.
-    Reported by: Joshua Rogers (Opera).
-  - decompress_iob(): Don't advance cur past eod when looking
-    for the end of the file name and comment.
-  - decompress_iob(): Cast value to unsigned char before shifting.
-    Prevents a left-shift of a negative value which is undefined behaviour.
-    Reported by: Joshua Rogers (Opera)
-  - gif_deanimate(): Confirm that that we have enough data before doing
-    any work. Fixes a crash when fuzzing with an empty document.
-    Reported by: Joshua Rogers (Opera).
-  - buf_copy(): Fail if there's no data to write or nothing to do.
-    Prevents undefined behaviour "applying zero offset to null pointer".
-    Reported by: Joshua Rogers (Opera)
-  - log_error(): Treat LOG_LEVEL_FATAL as fatal even when --stfu is
-    being used while fuzzing.
-    Reported by: Joshua Rogers (Opera).
-  - Respect DESTDIR when considering whether or not to install
-    config files with ".new" extension.
-  - OpenSSL ssl_store_cert(): Fix two error messages.
-  - Fix a couple of format specifiers.
-  - Silence compiler warnings when compiling with NDEBUG.
-  - fuzz_server_header(): Fix compiler warning.
-  - fuzz_client_header(): Fix compiler warning.
-  - cgi_send_user_manual(): Also reject requests if the user-manual
-    directive specifies a https:// URL. Previously Privoxy would try and
-    fail to open a local file.
+  - Improve the handling of chunk-encoded responses by buffering the data
+    even if filters are disabled and properly keeping track of where the
+    various chunks are supposed to start and end. Previously Privoxy would
+    merely check the last bytes received to see if they looked like the
+    last-chunk. This failed to work if the last-chunk wasn't received in one
+    read and could also result in actual data being misdetected
+    as last-chunk.
+    Should fix: SF support request #1739.
+    Reported by: withoutname.
+  - remove_chunked_transfer_coding(): Refuse to de-chunk invalid data
+    Previously the data could get corrupted even further.
+    Now we simply pass the unmodified data to the client.
+  - gif_deanimate(): Tolerate multiple image extensions in a row.
+    This allows to deanimate all the gifs on:
+    https://commons.wikimedia.org/wiki/Category:Animated_smilies
+    Fixes SF bug #795 reported by Celejar.
+  - OpenSSL generate_host_certificate(): Use X509_get_subject_name()
+    instead of X509_get_issuer_name() to get the issuer for generated
+    website certificates so there are no warnings in the browser when using
+    an intermediate CA certificate instead of a self-signed root certificate.
+    Problem reported and patch submitted by Chakib Benziane.
+  - can_filter_request_body(): Fix a log message that contained a spurious u.
+  - handle_established_connection(): Check for pending TLS data from the client
+    before checking if data is available on the connection.
+    The TLS library may have already consumed all the data from the client
+    response in which case poll() and select() will not detect that data is
+    available to be read.
+    Sponsored by: Robert Klemme.
+  - ssl_send_certificate_error(): Don't crash if there's no certificate
+    information available. This is only relevant when Privoxy is built with
+    wolfSSL 5.0.0 or later (code not yet published). Earlier wolfSSL versions
+    or the other TLS backends don't seem to trigger the crash.
+  - socks5_connect(): Add support for target hosts specified as IPv4 address
+    Previously the IP address was sent as domain.
 
 - General improvements:
-  - Log the TLS version and the the cipher when debug 2 is enabled.
-  - ssl_send_certificate_error(): Respect HEAD requests by not sending a body.
-  - ssl_send_certificate_error(): End the body with a single new line.
-  - serve(): Increase the chances that the host is logged when closing
-    a server socket.
-  - handle_established_connection(): Add parentheses to clarify an expression
-    Suggested by: David Binderman
-  - continue_https_chat(): Explicitly unset CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE
-    if process_encrypted_request() fails. This makes it more obvious that the
-    connection will not be reused. Previously serve() relied on
-    CSP_FLAG_SERVER_CONTENT_LENGTH_SET and CSP_FLAG_CHUNKED being unset.
-    Inspired by a patch from Joshua Rogers (Opera).
-  - decompress_iob(): Add periods to a couple of log messages
-  - Terminate the body of the HTTP snipplets with a single new line
-    instead of "\r\n".
-  - configure: Add --with-assertions option and only enable assertions
-    when it is used
-  - windows build: Use --with-brotli and --with-mbedtls by default and
-    enable dynamic error checking.
-  - gif_deanimate(): Confirm we've got an image before trying to write it
-    Saves a pointless buf_copy() call.
-  - OpenSSL ssl_store_cert(): Remove a superfluous space before the serial number.
+  - Add a client-body-tagger action which creates tags based on
+    the content of the request body.
+    Sponsored by: Robert Klemme.
+  - When client-body filters are enabled, buffer the whole request
+    before opening a connection to the server.
+    Makes it less likely that the server connection times out
+    and we don't open a connection if the buffering fails anyway.
+    Sponsored by: Robert Klemme.
+  - Add periods to a couple of log messages.
+  - accept_connection(): Add missing space to a log message.
+  - Initialize ca-related defaults with strdup_or_die() so errors
+    aren't silently ignored.
+  - make_path: Use malloc_or_die() in cases where allocation errors
+    were already fatal anyway.
+  - handle_established_connection(): Improve an error message slightly.
+  - receive_client_request(): Reject https URLs without CONNECT request.
+  - Include all requests in the statistics if mutexes are available.
+    Previously in case of reused connections only the last request got
+    counted. The statistics still aren't perfect but it's an improvement.
+  - Add read_socks_reply() and start using it in socks5_connect()
+    to apply the socket timeout more consistently.
+  - socks5_connect(): Deal with domain names in the socks reply
+  - Add a filter for bundeswehr.de that hides the cookie and
+    privacy info banner.
 
 - Action file improvements:
-  - Disable fast-redirects for .golem.de/
-  - Unblock requests to adri*.
-  - Block requests for trc*.taboola.com/
-  - Disable fast-redirects for .linkedin.com/
-
-- Filter file improvements:
-  - Make the second pcrs job of the img-reorder filter greedy again.
-    The ungreedy version broke the img tags on:
-    https://bulk.fefe.de/scalability/.
+  - Disable filter{banners-by-size} for .freiheitsfoo.de/.
+  - Disable filter{banners-by-size} for freebsdfoundation.org/.
+  - Disable fast-redirects for consent.youtube.com/.
+  - Block requests to ups.xplosion.de/.
+  - Block requests for elsa.memoinsights.com/t.
+  - Fix a typo in a test.
+  - Disable fast-redirects for launchpad.net/.
+  - Unblock .eff.org/.
+  - Stop unblocking .org/.*(image|banner) which appears to be too generous
+    It let requests like:
+    https://stats.noblogs.org/piwik.php?action_name=anti%20gentrifizierungs%20fest&idsite=10175&rec=1&r=220192&h=17&m=7&s=44&url=https%3A%2F%2Fmuellemcalling.noblogs.org%2F&urlref=https%3A%2F%2Fmuellemcalling.noblogs.org%2Finfostande%2F&_id=&_idn=1&_refts=0&send_image=0&cookie=1&res=1366x768&pv_id=eqr7jX&pf_net=7&pf_srv=3&pf_tfr=2281&pf_dm1=156
+    pass.
+    The example URL http://www.gnu.org/graphics/gnu-head-banner.png is
+    already unblocked due to .gnu.org being unblocked.
+  - Unblock adfd.org/.
+  - Disable filter{banners-by-link} for .eff.org/.
+  - Block requests to odb.outbrain.com/.
+  - Disable fast-redirects for .gandi.net/.
+  - Disable fast-redirects{} for .onion/.*/status/.
+  - Disable fast-redirects{} for twitter.com/.*/status/.
+  - Unblock pinkstinks.de/.
+  - Disable fast-redirects for .hagalil.com/.
 
 - Privoxy-Log-Parser:
-  - Highlight a few more messages.
-  - Clarify the --statistics output. The shown "Reused connections"
-    are server connections so name them appropriately.
-  - Bump version to 0.9.3.
-
-- Privoxy-Regression-Test:
-  - Add the --check-bad-ssl option to the --help output.
-  - Bump version to 0.7.3.
+  - Bump version to 0.9.5.
+  - Highlight more log messages.
+  - Highlight the Crunch reason only once. Previously the "crunch reason"
+    could also be highlighted when the URL contained a matching string.
+    The real crunch reason only occurs once per line, so there's no need
+    to continue looking for it after it has been found once.
+    While at it, add a comment with an example log line.
+
+- uagen:
+  - Bump version to 1.2.4.
+  - Update BROWSER_VERSION and BROWSER_REVISION to 102.0
+    to match the User-Agent of the current Firefox ESR.
+  - Explicitly document that changing the 'Gecko token' is suspicious.
+  - Consistently use a lower-case 'c' as copyright symbol.
+  - Bump copyright.
+  - Add 'aarch64' as Linux architecture.
+  - Add OpenBSD architecture 'arm64'.
+  - Stop using sparc64 as FreeBSD architecture.
+    It hasn't been supported for a while now.
+
+- Build system:
+  - Makefile: Add a 'dok' target that depends on the 'error' target
+    to show the "You are not using GNU make or did nor run configure"
+    message.
+  - configure: Fix --with-msan option.
+    Also (probably) reported by Andrew Savchenko.
+
+- macOS build system:
+  - Enable HTTPS inspection when building the macOS binary
+    (using OpenSSL as TLS library).
 
 - Documentation:
-  - Add pushing the created tag to the release steps in the developer manual.
-  - Clarify that 'debug 32768' should be used in addition to the other debug
-    directives when reporting problems.
-  - Add a 'Third-party licenses and copyrights' section to the user manual.
+  - Add OpenSSL to the list of libraries that may be licensed under the
+    Apache 2.0 license in which case the linked Privoxy binary has to be
+    distributed under the GPLv3 or later.
+  - config: Fix the documented ca-directory default value.
+    Reported by avoidr.
+  - Rebuild developer-manual and tidy with 'HTML Tidy for FreeBSD version 5.8.0'.
+  - Update developer manual with new macOS packaging instructions.
+  - Note that the FreeBSD installation instructions work for
+    ElectroBSD as well.
+  - Note that FreeBSD/ElectroBSD users can try to install Privoxy
+    as binary package using 'pkg'.
 
 -----------------------------------------------------------------
 About Privoxy:
@@ -124,7 +156,7 @@ flexible configuration and can be customized to suit individual needs and
 tastes. It has application for both stand-alone systems and multi-user
 networks.
 
-Privoxy is Free Software and licensed under the GNU GPLv2.
+Privoxy is Free Software and licensed under the GNU GPLv2 or later.
 
 Our TODO list is rather long. Helping hands and donations are welcome:
 
index 5a670cf..a29bd90 100644 (file)
             <tbody>
               <tr>
                 <td><span class="emphasis"><i class="EMPHASIS">p-version</i></span>: the <span class=
-                "APPLICATION">Privoxy</span> version string, e.g. <span class="QUOTE">"3.0.33"</span>.</td>
+                "APPLICATION">Privoxy</span> version string, e.g. <span class="QUOTE">"3.0.35"</span>.</td>
               </tr>
               <tr>
                 <td><span class="emphasis"><i class="EMPHASIS">p-status</i></span>: the project status, either
index a511667..be4ecc0 100644 (file)
@@ -13,7 +13,7 @@
     <div class="TITLEPAGE">
       <h1 class="TITLE"><a name="AEN2" id="AEN2">Privoxy Developer Manual</a></h1>
       <p class="PUBDATE"><sub><a href="https://www.privoxy.org/user-manual/copyright.html" target="_top">Copyright</a>
-      &copy; 2001-2021 by <a href="https://www.privoxy.org/" target="_top">Privoxy Developers</a></sub><br></p>
+      &copy; 2001-2023 by <a href="https://www.privoxy.org/" target="_top">Privoxy Developers</a></sub><br></p>
       <div>
         <div class="ABSTRACT">
           <a name="AEN8" id="AEN8"></a>
@@ -22,7 +22,7 @@
           helpful!) reading for anyone who wants to join the team. Note that it's currently out of date and may not be
           entirely correct. As always, patches are welcome.</p>
           <p>Please note that this document is constantly evolving. This copy represents the state at the release of
-          version 3.0.33. You can find the latest version of the this manual at <a href=
+          version 3.0.35. You can find the latest version of the this manual at <a href=
           "https://www.privoxy.org/developer-manual/" target="_top">https://www.privoxy.org/developer-manual/</a>.
           Please have a look at the <a href="https://www.privoxy.org/user-manual/contact.html" target="_top">contact
           section in the user manual</a> if you are interested in contacting the developers.</p>
                 <dt>6.3.2. <a href="newrelease.html#NEWRELEASE-TARBALL">Source Tarball</a></dt>
                 <dt>6.3.3. <a href="newrelease.html#NEWRELEASE-WINDOWS">Windows</a></dt>
                 <dt>6.3.4. <a href="newrelease.html#NEWRELEASE-DEBIAN">Debian</a></dt>
-                <dt>6.3.5. <a href="newrelease.html#NEWRELEASE-MACOSX">Mac OS X</a></dt>
+                <dt>6.3.5. <a href="newrelease.html#NEWRELEASE-MACOSX">macOS / OS X</a></dt>
                 <dt>6.3.6. <a href="newrelease.html#NEWRELEASE-FREEBSD">FreeBSD</a></dt>
               </dl>
             </dd>
             <dt>6.4. <a href="newrelease.html#RELEASING">Uploading and Releasing Your Package</a></dt>
-            <dt>6.5. <a href="newrelease.html#AFTERRELEASE">After the Release</a></dt>
+            <dt>6.5. <a href="newrelease.html#UPDATE-RSS-FEED">Updating the RSS feed</a></dt>
+            <dt>6.6. <a href="newrelease.html#AFTERRELEASE">After the Release</a></dt>
           </dl>
         </dd>
         <dt>7. <a href="webserver-update.html">Update the Webserver</a></dt>
index 0b33e7b..f973801 100644 (file)
         into an empty directory</i></span>. (See "Building and releasing packages" above).</p>
         <p>Check that you have the current versions of the <a href=
         "https://sourceforge.net/projects/nsis/files/NSIS%203/" target="_top">NSIS installer</a>, <a href=
-        "https://ftp.pcre.org/pub/pcre/" target="_top">PCRE library</a>, <a href="https://tls.mbed.org/download"
-        target="_top">MBED TLS library</a>, <a href="https://github.com/google/brotli/releases" target="_top">Brotli
-        library</a>, and that the <span class="emphasis"><i class="EMPHASIS">MAKENSIS</i></span> evar in <tt class=
-        "FILENAME">windows/GNUMakefile</tt> points to the NSIS installer program. (See the <a href=
-        "../user-manual/installation.html#WINBUILD-CYGWIN" target="_top"><span class="emphasis"><i class=
-        "EMPHASIS">Building from Source / Windows</i></span></a> section of the User Manual for details.)</p>
+        "https://sourceforge.net/projects/pcre/files/pcre/" target="_top">PCRE library</a>, <a href=
+        "https://github.com/Mbed-TLS/mbedtls/tags" target="_top">MBED TLS library</a>, <a href=
+        "https://github.com/google/brotli/releases" target="_top">Brotli library</a>, and that the <span class=
+        "emphasis"><i class="EMPHASIS">MAKENSIS</i></span> evar in <tt class="FILENAME">windows/GNUMakefile</tt> points
+        to the NSIS installer program. (See the <a href="../user-manual/installation.html#WINBUILD-CYGWIN" target=
+        "_top"><span class="emphasis"><i class="EMPHASIS">Building from Source / Windows</i></span></a> section of the
+        User Manual for details.)</p>
         <p>Then you can build the package. This is fully automated, and is controlled by <tt class=
         "FILENAME">windows/GNUmakefile</tt>. All you need to do is:</p>
         <table border="0" bgcolor="#E0E0E0" width="100%">
         <table border="0" bgcolor="#E0E0E0" width="100%">
           <tr>
             <td>
-              <pre class="PROGRAMLISTING">  dch -v 3.0.33-1</pre>
+              <pre class="PROGRAMLISTING">  dch -v 3.0.35-1</pre>
             </td>
           </tr>
         </table>
         <table border="0" bgcolor="#E0E0E0" width="100%">
           <tr>
             <td>
-              <pre class="PROGRAMLISTING">  lintian -iI ../build-area/privoxy_3.0.33-1_amd64.changes</pre>
+              <pre class="PROGRAMLISTING">  lintian -iI ../build-area/privoxy_3.0.35-1_amd64.changes</pre>
             </td>
           </tr>
         </table>
           <tr>
             <td>
               <pre class=
-              "PROGRAMLISTING">  sudo cowbuilder --build --basepath /var/cache/pbuilder/base.cow ../build-area/privoxy_3.0.33-1.dsc</pre>
+              "PROGRAMLISTING">  sudo cowbuilder --build --basepath /var/cache/pbuilder/base.cow ../build-area/privoxy_3.0.35-1.dsc</pre>
             </td>
           </tr>
         </table>
           <tr>
             <td>
               <pre class=
-              "PROGRAMLISTING">  autopkgtest /var/cache/pbuilder/result/privoxy_3.0.33-1_amd64.changes -s -- schroot sid</pre>
+              "PROGRAMLISTING">  autopkgtest /var/cache/pbuilder/result/privoxy_3.0.35-1_amd64.changes -s -- schroot sid</pre>
             </td>
           </tr>
         </table>
         <p>Or just push the changes to salsa.debian.org, where a CI pipeline is defined for the package, that builds
         and tests it.</p>
         <p>If everything is okay, run cowbuilder with i386 and amd64 environments for current Debian stable release and
-        build privoxy_3.0.33-1_i386.deb and privoxy_3.0.33-1_amd64.deb. Then sign both files:</p>
+        build privoxy_3.0.35-1_i386.deb and privoxy_3.0.35-1_amd64.deb. Then sign both files:</p>
         <table border="0" bgcolor="#E0E0E0" width="100%">
           <tr>
             <td>
-              <pre class="PROGRAMLISTING">  gpg --detach-sign --armor privoxy_3.0.33-1_i386.deb
-  gpg --detach-sign --armor privoxy_3.0.33-1_amd64.deb</pre>
+              <pre class="PROGRAMLISTING">  gpg --detach-sign --armor privoxy_3.0.35-1_i386.deb
+  gpg --detach-sign --armor privoxy_3.0.35-1_amd64.deb</pre>
             </td>
           </tr>
         </table>
         </div>
       </div>
       <div class="SECT3">
-        <h3 class="SECT3"><a name="NEWRELEASE-MACOSX" id="NEWRELEASE-MACOSX">6.3.5. Mac OS X</a></h3>
+        <h3 class="SECT3"><a name="NEWRELEASE-MACOSX" id="NEWRELEASE-MACOSX">6.3.5. macOS / OS X</a></h3>
         <p>First, <span class="emphasis"><i class="EMPHASIS">make sure that you have freshly exported the right version
         into an empty directory</i></span>. (See "Building and releasing packages" above).</p>
-        <p>There are three modules available in the CVS repository backups for use on Mac OS X, though technically only
-        two of them generate a release (the other can be used to install from source).</p>
-        <div class="SECT4">
-          <h4 class="SECT4"><a name="OS-X-OSXPACKAGEBUILDER-MODULE" id="OS-X-OSXPACKAGEBUILDER-MODULE">6.3.5.1.
-          OSXPackageBuilder module (Documentation out of date)</a></h4>
-          <p>The OSXPackageBuilder module generates OS X installer packages supporting all Macs running OS X 10.4 and
-          above. Obtain it from CVS as follows into a folder parallel to the exported privoxy source:</p>
-          <table border="0" bgcolor="#E0E0E0" width="100%">
-            <tr>
-              <td>
-                <pre class=
-                "PROGRAMLISTING">  cvs -z3 -d:pserver:anonymous@ijbswa.cvs.sourceforge.net:/cvsroot/ijbswa co OSXPackageBuilder</pre>
-              </td>
-            </tr>
-          </table>
-          <p>The module contains complete instructions on its usage in the file <tt class="FILENAME">OS X Package
-          Builder HOWTO.txt</tt>.</p>
-          <p>Once the package(s) have been generated, you can then upload them directly to the Files section of the
-          Sourceforge project in the Macintosh (OS X) folder. Each new version release of Privoxy should have a new
-          subfolder created in which to store its files. Please ensure that the folder contains a readme file that
-          makes it clear which package is for whichversion of OS X.</p>
-        </div>
-        <div class="SECT4">
-          <h4 class="SECT4"><a name="OS-X-OSXSETUP-MODULE" id="OS-X-OSXSETUP-MODULE">6.3.5.2. osxsetup module
-          (DEPRECATED) (Documentation out of date)</a></h4>
-          <p><span class="emphasis"><i class="EMPHASIS">This module is deprecated since the installer it generates
-          places all Privoxy files in one folder in a non-standard location, and supports only Intel Macs running OS X
-          10.6 or higher.</i></span></p>
-          <p>Check out the module from CVS as follows into a folder parallel to the exported privoxy source:</p>
-          <table border="0" bgcolor="#E0E0E0" width="100%">
-            <tr>
-              <td>
-                <pre class=
-                "PROGRAMLISTING">  cvs -z3 -d:pserver:anonymous@ijbswa.cvs.sourceforge.net:/cvsroot/ijbswa co osxsetup</pre>
-              </td>
-            </tr>
-          </table>
-          <p>Then run:</p>
-          <table border="0" bgcolor="#E0E0E0" width="100%">
-            <tr>
-              <td>
-                <pre class="PROGRAMLISTING">  cd osxsetup
-  build</pre>
-              </td>
-            </tr>
-          </table>
-          <p>This will run <tt class="FILENAME">autoheader</tt>, <tt class="FILENAME">autoconf</tt> and <tt class=
-          "FILENAME">configure</tt> as well as <tt class="FILENAME">make</tt>. Finally, it will copy over the necessary
-          files to the ./osxsetup/files directory for further processing by <tt class="FILENAME">PackageMaker</tt>.</p>
-          <p>Bring up PackageMaker with the PrivoxyPackage.pmsp definition file, modify the package name to match the
-          release, and hit the "Create package" button. If you specify ./Privoxy.pkg as the output package name, you
-          can then create the distributable zip file with the command:</p>
-          <table border="0" bgcolor="#E0E0E0" width="100%">
-            <tr>
-              <td>
-                <pre class="PROGRAMLISTING">  zip -r privoxyosx_setup_x.y.z.zip Privoxy.pkg</pre>
-              </td>
-            </tr>
-          </table>
-          <p>You can then upload this file directly to the Files section of the Sourceforge project in the Macintosh
-          (OS X) folder. Each new version release of Privoxy should have a new subfolder created in which to store its
-          files. Please ensure that the folder contains a readme file that makes it clear which version(s) of OS X the
-          package supports.</p>
-        </div>
-        <div class="SECT4">
-          <h4 class="SECT4"><a name="OS-X-MACSETUP-MODULE" id="OS-X-MACSETUP-MODULE">6.3.5.3. macsetup module
-          (Documentation out of date)</a></h4>
-          <p>The macsetup module is ideal if you wish to build and install Privoxy from source on a single machine.</p>
-          <p>Check out the module from CVS as follows into a folder parallel to the exported privoxy source:</p>
-          <table border="0" bgcolor="#E0E0E0" width="100%">
-            <tr>
-              <td>
-                <pre class=
-                "PROGRAMLISTING">  cvs -z3 -d:pserver:anonymous@ijbswa.cvs.sourceforge.net:/cvsroot/ijbswa co macsetup</pre>
-              </td>
-            </tr>
-          </table>
-          <p>The module contains complete instructions on its usage in its <tt class="FILENAME">README</tt> file. The
-          end result will be the exported version of Privoxy installed on the build machine.</p>
-        </div>
+        <p>The OSXPackageBuilder module can generate OS X installer packages supporting all Macs running OS X 10.4 and
+        above. Obtain it from Git as follows into a folder parallel to the exported privoxy source:</p>
+        <table border="0" bgcolor="#E0E0E0" width="100%">
+          <tr>
+            <td>
+              <pre class="PROGRAMLISTING">  git clone ssh://git@git.privoxy.org:23/git/OSXPackageBuilder.git</pre>
+            </td>
+          </tr>
+        </table>
+        <p>The module contains complete instructions on its usage in the file <tt class="FILENAME">OS X Package Builder
+        HOWTO.txt</tt>.</p>
+        <p>Once the package(s) have been generated, you can then upload them directly to the Files section of the
+        Sourceforge project in the Macintosh (OS X) folder. Each new version release of Privoxy should have a new
+        subfolder created in which to store its files. Please ensure that the folder contains a readme file that makes
+        it clear which package is for which version of OS X.</p>
       </div>
       <div class="SECT3">
         <h3 class="SECT3"><a name="NEWRELEASE-FREEBSD" id="NEWRELEASE-FREEBSD">6.3.6. FreeBSD</a></h3>
       <tt class="LITERAL">Edit Release</tt>, instead of <tt class="LITERAL">Add Release</tt>.</p>
     </div>
     <div class="SECT2">
-      <h2 class="SECT2"><a name="AFTERRELEASE" id="AFTERRELEASE">6.5. After the Release</a></h2>
+      <h2 class="SECT2"><a name="UPDATE-RSS-FEED" id="UPDATE-RSS-FEED">6.5. Updating the RSS feed</a></h2>
+      <p>Once the packages are uploaded to SourceForge they should be mirrored on the Privoxy websites (<a href=
+      "https://www.privoxy.org/" target="_top">https://www.privoxy.org/</a> and <a href=
+      "http://l3tczdiiwoo63iwxty4lhs6p7eaxop5micbn7vbliydgv63x5zrrrfyd.onion/" target=
+      "_top">http://l3tczdiiwoo63iwxty4lhs6p7eaxop5micbn7vbliydgv63x5zrrrfyd.onion/</a>). This is usually done by
+      Fabian who uses a couple of shell functions for this that aren't documented or published yet.</p>
+      <p>Once the packages are uploaded to the mirror the RSS feed has to be regenerated with a command like:</p>
+      <table border="0" bgcolor="#E0E0E0" width="100%">
+        <tr>
+          <td>
+            <pre class=
+            "PROGRAMLISTING">       fk@t520 ~/git/privoxy $utils/create-package-feed.pl /tank/backups/sourceforge/frs/project/ijbswa/ doc/webserver/feeds/privoxy-releases.xm
+      </pre>
+          </td>
+        </tr>
+      </table>
+      <p>The updated RSS feed then has to be uploaded to the SourceForge webserver and mirrored on the Privoxy websites
+      again. This, too, is usually done by Fabian with undocumented and unpublished shell functions.</p>
+    </div>
+    <div class="SECT2">
+      <h2 class="SECT2"><a name="AFTERRELEASE" id="AFTERRELEASE">6.6. After the Release</a></h2>
       <p>When all (or: most of the) packages have been uploaded and made available, send an email to the <a href=
       "mailto:privoxy-announce@lists.privoxy.org" target="_top">announce mailing list</a>, Subject: "Announcing Privoxy
       X.Y.Z $CODE_STATUS". Be sure to include the <a href="https://sourceforge.net/projects/ijbswa/files/" target=
index bd338c2..571906e 100644 (file)
@@ -25,7 +25,7 @@
   </div>
   <div class="SECT1">
     <h1 class="SECT1"><a name="COPYRIGHT" id="COPYRIGHT">7. Privoxy Copyright, License and History</a></h1>
-    <p>Copyright &copy; 2001-2021 by Privoxy Developers <code class="EMAIL">&#60;<a href=
+    <p>Copyright &copy; 2001-2023 by Privoxy Developers <code class="EMAIL">&#60;<a href=
     "mailto:privoxy-devel@lists.privoxy.org">privoxy-devel@lists.privoxy.org</a>&#62;</code></p>
     <p>Some source code is based on code Copyright &copy; 1997 by Anonymous Coders and Junkbusters, Inc.</p>
     <p>Portions of this document are <span class="QUOTE">"borrowed"</span> from the original <span class=
       under the terms of the <i class="CITETITLE">GNU General Public License</i> as published by the Free Software
       Foundation, either version 2 of the license, or (at your option) any later version.</p>
       <p>The same is true for <span class="APPLICATION">Privoxy</span> binaries unless they are linked with a <a href=
-      "https://tls.mbed.org/" target="_top">mbed TLS</a> version that is licensed under the Apache 2.0 license in which
-      case you can redistribute and/or modify the <span class="APPLICATION">Privoxy</span> binaries under the terms of
-      the <i class="CITETITLE">GNU General Public License</i> as published by the Free Software Foundation, either
-      version 3 of the license, or (at your option) any later version.</p>
+      "https://www.trustedfirmware.org/projects/mbed-tls/" target="_top">mbed TLS</a> or <a href=
+      "https://www.openssl.org/" target="_top">OpenSSL</a> version that is licensed under the Apache 2.0 license in
+      which case you can redistribute and/or modify the <span class="APPLICATION">Privoxy</span> binaries under the
+      terms of the <i class="CITETITLE">GNU General Public License</i> as published by the Free Software Foundation,
+      either version 3 of the license, or (at your option) any later version.</p>
       <p><span class="APPLICATION">Privoxy</span> is distributed in the hope that it will be useful, but WITHOUT ANY
       WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
       <a href="https://www.privoxy.org/user-manual/copyright.html#LICENSE" target="_top"><i class=
index 08ccc57..1c17ac4 100644 (file)
       "QUOTE">"https://www.example.org/seo/keyword/spam/"</span>).</p>
       <p>The details may change over time but changes will only affect new sponsors (or existing sponsors that
       explicitly agreed to the changes).</p>
+      <p>Thanks to <a href="https://www.spi-inc.org/" target="_top">Software in the Public Interest (SPI)</a>
+      <span class="APPLICATION">Privoxy</span> sponsors can get a proper invoice.</p>
       <p>If you want to become a sponsor, please contact <a href="mailto:fk@fabiankeil.de" target="_top">Fabian
       Keil</a> and include the link target in the mail. New sponsors are only accepted if no <a href=
       "../user-manual/copyright.html#AUTHORS" target="_top">Privoxy team</a> member objects.</p>
index a1cba64..e45c45f 100644 (file)
@@ -12,7 +12,7 @@
   <div class="ARTICLE">
     <div class="TITLEPAGE">
       <h1 class="TITLE"><a name="AEN2" id="AEN2">Privoxy Frequently Asked Questions</a></h1>
-      <p class="PUBDATE"><sub><a href="copyright.html">Copyright</a> &copy; 2001-2021 by <a href=
+      <p class="PUBDATE"><sub><a href="copyright.html">Copyright</a> &copy; 2001-2023 by <a href=
       "https://www.privoxy.org/" target="_top">Privoxy Developers</a></sub><br></p>
       <div>
         <div class="ABSTRACT">
@@ -38,7 +38,7 @@
             </li>
           </ul>
           <p>Please note that this document is a work in progress. This copy represents the state at the release of
-          version 3.0.33. You can find the latest version of the document at <a href="https://www.privoxy.org/faq/"
+          version 3.0.35. You can find the latest version of the document at <a href="https://www.privoxy.org/faq/"
           target="_top">https://www.privoxy.org/faq/</a>. Please see the <a href="contact.html">Contact section</a> if
           you want to contact the developers.</p>
         </div>
index e47a94b..3b3fb75 100644 (file)
     <div class="SECT2">
       <h3 class="SECT2"><a name="WHICHOS" id="WHICHOS">2.2. Which operating systems are supported?</a></h3>
       <p>At present, <span class="APPLICATION">Privoxy</span> is known to run on Windows 95 and later versions (98, ME,
-      2000, XP, Vista, Windows 7, Windows 10 etc.), GNU/Linux (RedHat, SuSE, Debian, Fedora, Gentoo, Slackware and
-      others), Mac OS X (10.4 and upwards on PPC and Intel processors), Haiku, DragonFly, ElectroBSD, FreeBSD, NetBSD,
-      OpenBSD, Solaris, and various other flavors of Unix.</p>
-      <p>But any operating system that runs TCP/IP, can conceivably take advantage of <span class=
+      2000, XP, Vista, Windows 7, Windows 10, Windows 11 etc.), GNU/Linux (RedHat, SuSE, Debian, Fedora, Gentoo,
+      Slackware and others), Mac OS X (10.4 and upwards on PPC and Intel processors), Haiku, DragonFly, ElectroBSD,
+      FreeBSD, NetBSD, OpenBSD, Solaris, and various other flavors of Unix.</p>
+      <p>The binaries provided by members of the Privoxy team have the following testing platforms, earliest supported
+      OS versions and processor architectures. Be aware that down-level versions of Privoxy contain known security
+      issues. <span class="emphasis"><i class="EMPHASIS">It is preferable to build the latest code to target earlier OS
+      releases than use an earlier Privoxy release</i></span>:</p>
+      <div class="TABLE">
+        <a name="AEN296" id="AEN296"></a>
+        <p><b>Table 1. Operating system support for binaries provided by Privoxy team members</b></p>
+        <table border="1" frame="border" rules="all" class="CALSTABLE">
+          <col>
+          <col>
+          <col>
+          <col>
+          <col>
+          <thead>
+            <tr>
+              <th>Operating System</th>
+              <th>Privoxy Release</th>
+              <th>Testing Platforms</th>
+              <th>Earliest OS Version Supported</th>
+              <th>Processor Architectures</th>
+            </tr>
+          </thead>
+          <tbody>
+            <tr>
+              <td>Windows</td>
+              <td>3.0.33</td>
+              <td>Windows 10</td>
+              <td>Windows Vista</td>
+              <td>Intel 32 and 64 bit</td>
+            </tr>
+            <tr>
+              <td>&nbsp;</td>
+              <td>3.0.32</td>
+              <td>Windows 10</td>
+              <td>Windows XP</td>
+              <td>Intel 32 and 64 bit</td>
+            </tr>
+            <tr>
+              <td>macOS</td>
+              <td>3.0.33</td>
+              <td>El Capitan (10.11.6)</td>
+              <td>Snow Leopard (10.6.1)</td>
+              <td>Intel 64 bit</td>
+            </tr>
+            <tr>
+              <td>&nbsp;</td>
+              <td>3.0.26</td>
+              <td>El Capitan (10.11.6), Tiger (10.4.1) PPC</td>
+              <td>Tiger (10.4.1)</td>
+              <td>Intel 32 &#38; 64 bit, PowerPC</td>
+            </tr>
+          </tbody>
+        </table>
+      </div>
+      <p>Any operating system that runs TCP/IP, can conceivably take advantage of <span class=
       "APPLICATION">Privoxy</span> in a networked situation where <span class="APPLICATION">Privoxy</span> would run as
       a server on a LAN gateway. Then only the <span class="QUOTE">"gateway"</span> needs to be running one of the
       above operating systems.</p>
-      <p>Source code is freely available, so porting to other operating systems is always a possibility.</p>
+      <p>Source code is freely available, so porting to other operating systems is always a possibility, as is
+      compiling for older versions of supported operating systems.</p>
     </div>
     <div class="SECT2">
       <h3 class="SECT2"><a name="EMAIL-CLIENT" id="EMAIL-CLIENT">2.3. Can I use Privoxy with my email client?</a></h3>
index fe20ff5..b89a96f 100644 (file)
@@ -4,7 +4,42 @@
    <title>Privoxy Releases</title>
    <link>https://www.privoxy.org/announce.txt</link>
    <description><![CDATA[Privoxy Releases RSS feed]]></description>
-   <pubDate>Sun, 28 Feb 2021 8:30:51 GMT</pubDate>
+   <pubDate>Mon, 6 Feb 2023 7:20:47 GMT</pubDate>
+<item><title><![CDATA[Win32/3.0.34 (stable)/privoxy_setup_3.0.34.exe]]></title><description><![CDATA[Win32/3.0.34 (stable)/privoxy_setup_3.0.34.exe (SHA-256: ec67cad4c1c755aaf73fbca6ffa9011a7e926f566cf47829c43edb44eb12a177)]]></description><link>https://www.privoxy.org/sf-download-mirror/Win32/3.0.34%20(stable)/privoxy_setup_3.0.34.exe</link><guid>https://www.privoxy.org/sf-download-mirror/Win32/3.0.34%20(stable)/privoxy_setup_3.0.34.exe</guid><pubDate>Mon, 6 Feb 2023 02:21:14 GMT</pubDate></item>
+<item><title><![CDATA[Win32/3.0.34 (stable)/privoxy_3.0.34.zip]]></title><description><![CDATA[Win32/3.0.34 (stable)/privoxy_3.0.34.zip (SHA-256: 0e361e54780e292f7a249752471b9c55af7bd342fd345cd2d0f3ec2bbe7650a4)]]></description><link>https://www.privoxy.org/sf-download-mirror/Win32/3.0.34%20(stable)/privoxy_3.0.34.zip</link><guid>https://www.privoxy.org/sf-download-mirror/Win32/3.0.34%20(stable)/privoxy_3.0.34.zip</guid><pubDate>Mon, 6 Feb 2023 02:21:13 GMT</pubDate></item>
+<item><title><![CDATA[Win32/3.0.34 (stable)/privoxy_setup_3.0.34.exe.asc]]></title><description><![CDATA[Win32/3.0.34 (stable)/privoxy_setup_3.0.34.exe.asc (SHA-256: 1b594807a5d0471a3ba387be5f8e85dd20536c296c166e2a3e4865f7404116f2)]]></description><link>https://www.privoxy.org/sf-download-mirror/Win32/3.0.34%20(stable)/privoxy_setup_3.0.34.exe.asc</link><guid>https://www.privoxy.org/sf-download-mirror/Win32/3.0.34%20(stable)/privoxy_setup_3.0.34.exe.asc</guid><pubDate>Mon, 6 Feb 2023 02:21:12 GMT</pubDate></item>
+<item><title><![CDATA[Win32/3.0.34 (stable)/privoxy_3.0.34.zip.asc]]></title><description><![CDATA[Win32/3.0.34 (stable)/privoxy_3.0.34.zip.asc (SHA-256: c5a849b1dd2df04a60bec3f4b33112efac2b748fbae4bffbff303777da008b52)]]></description><link>https://www.privoxy.org/sf-download-mirror/Win32/3.0.34%20(stable)/privoxy_3.0.34.zip.asc</link><guid>https://www.privoxy.org/sf-download-mirror/Win32/3.0.34%20(stable)/privoxy_3.0.34.zip.asc</guid><pubDate>Mon, 6 Feb 2023 02:21:12 GMT</pubDate></item>
+<item><title><![CDATA[Macintosh (OS X)/3.0.34 (stable)/Privoxy 3.0.34 64 bit.pkg]]></title><description><![CDATA[Macintosh (OS X)/3.0.34 (stable)/Privoxy 3.0.34 64 bit.pkg (SHA-256: b3d3be3f7667520f8ae49847eaa37430466d79cc662cdb2e9582f375a0a96063)]]></description><link>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.34%20(stable)/Privoxy%203.0.34%2064%20bit.pkg</link><guid>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.34%20(stable)/Privoxy%203.0.34%2064%20bit.pkg</guid><pubDate>Sun, 5 Feb 2023 20:29:06 GMT</pubDate></item>
+<item><title><![CDATA[Macintosh (OS X)/3.0.34 (stable)/README]]></title><description><![CDATA[Macintosh (OS X)/3.0.34 (stable)/README (SHA-256: dea49e1fddbea873ac1dd44865b5452db5235a0ce566d4f33f1175f65a45c116)]]></description><link>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.34%20(stable)/README</link><guid>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.34%20(stable)/README</guid><pubDate>Sun, 5 Feb 2023 20:29:03 GMT</pubDate></item>
+<item><title><![CDATA[Macintosh (OS X)/3.0.34 (stable)/Privoxy 3.0.34 64 bit.pkg.asc]]></title><description><![CDATA[Macintosh (OS X)/3.0.34 (stable)/Privoxy 3.0.34 64 bit.pkg.asc (SHA-256: 5e1a4a95d8a7b8396b3da3d493264369b452ca451ed881b66a31ba5caa2e57db)]]></description><link>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.34%20(stable)/Privoxy%203.0.34%2064%20bit.pkg.asc</link><guid>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.34%20(stable)/Privoxy%203.0.34%2064%20bit.pkg.asc</guid><pubDate>Sun, 5 Feb 2023 20:29:03 GMT</pubDate></item>
+<item><title><![CDATA[Debian/3.0.34 (stable) bullseye/privoxy_3.0.34-1~pp+1_i386.deb.asc]]></title><description><![CDATA[Debian/3.0.34 (stable) bullseye/privoxy_3.0.34-1~pp+1_i386.deb.asc (SHA-256: d47f39ed3d94705f3f72d07ef07ab7684d66bcc293e1cbd9da9b53c6750474ab)]]></description><link>https://www.privoxy.org/sf-download-mirror/Debian/3.0.34%20(stable)%20bullseye/privoxy_3.0.34-1~pp+1_i386.deb.asc</link><guid>https://www.privoxy.org/sf-download-mirror/Debian/3.0.34%20(stable)%20bullseye/privoxy_3.0.34-1~pp+1_i386.deb.asc</guid><pubDate>Sun, 5 Feb 2023 09:39:46 GMT</pubDate></item>
+<item><title><![CDATA[Debian/3.0.34 (stable) bullseye/privoxy_3.0.34-1~pp+1_i386.deb]]></title><description><![CDATA[Debian/3.0.34 (stable) bullseye/privoxy_3.0.34-1~pp+1_i386.deb (SHA-256: d40824b5b27d749481143e2bb9bc9d455b6393e9c02193bd2da670699f61d738)]]></description><link>https://www.privoxy.org/sf-download-mirror/Debian/3.0.34%20(stable)%20bullseye/privoxy_3.0.34-1~pp+1_i386.deb</link><guid>https://www.privoxy.org/sf-download-mirror/Debian/3.0.34%20(stable)%20bullseye/privoxy_3.0.34-1~pp+1_i386.deb</guid><pubDate>Sun, 5 Feb 2023 09:39:46 GMT</pubDate></item>
+<item><title><![CDATA[Debian/3.0.34 (stable) bullseye/privoxy_3.0.34-1~pp+1_amd64.deb.asc]]></title><description><![CDATA[Debian/3.0.34 (stable) bullseye/privoxy_3.0.34-1~pp+1_amd64.deb.asc (SHA-256: 3805139fe0efd77e6684632d37d23447e3706ef0b3e40b1ed431068852bdb00c)]]></description><link>https://www.privoxy.org/sf-download-mirror/Debian/3.0.34%20(stable)%20bullseye/privoxy_3.0.34-1~pp+1_amd64.deb.asc</link><guid>https://www.privoxy.org/sf-download-mirror/Debian/3.0.34%20(stable)%20bullseye/privoxy_3.0.34-1~pp+1_amd64.deb.asc</guid><pubDate>Sun, 5 Feb 2023 09:39:46 GMT</pubDate></item>
+<item><title><![CDATA[Debian/3.0.34 (stable) bullseye/privoxy_3.0.34-1~pp+1_amd64.deb]]></title><description><![CDATA[Debian/3.0.34 (stable) bullseye/privoxy_3.0.34-1~pp+1_amd64.deb (SHA-256: 73ec4853d0772c774303619bbe085f71166e7a06fe2b90bf65ecdf8919b47958)]]></description><link>https://www.privoxy.org/sf-download-mirror/Debian/3.0.34%20(stable)%20bullseye/privoxy_3.0.34-1~pp+1_amd64.deb</link><guid>https://www.privoxy.org/sf-download-mirror/Debian/3.0.34%20(stable)%20bullseye/privoxy_3.0.34-1~pp+1_amd64.deb</guid><pubDate>Sun, 5 Feb 2023 09:39:38 GMT</pubDate></item>
+<item><title><![CDATA[Debian/3.0.34 (stable) bullseye/README]]></title><description><![CDATA[Debian/3.0.34 (stable) bullseye/README (SHA-256: 2be842acceb788bceaeb3a5b9eb18404f71f176110028eb70cf5902295cccaed)]]></description><link>https://www.privoxy.org/sf-download-mirror/Debian/3.0.34%20(stable)%20bullseye/README</link><guid>https://www.privoxy.org/sf-download-mirror/Debian/3.0.34%20(stable)%20bullseye/README</guid><pubDate>Sun, 5 Feb 2023 09:39:33 GMT</pubDate></item>
+<item><title><![CDATA[Sources/3.0.34 (stable)/privoxy-3.0.34-stable-src.tar.gz]]></title><description><![CDATA[Sources/3.0.34 (stable)/privoxy-3.0.34-stable-src.tar.gz (SHA-256: e6ccbca1656f4e616b4657f8514e33a70f6697e9d7294356577839322a3c5d2c)]]></description><link>https://www.privoxy.org/sf-download-mirror/Sources/3.0.34%20(stable)/privoxy-3.0.34-stable-src.tar.gz</link><guid>https://www.privoxy.org/sf-download-mirror/Sources/3.0.34%20(stable)/privoxy-3.0.34-stable-src.tar.gz</guid><pubDate>Sun, 5 Feb 2023 05:01:04 GMT</pubDate></item>
+<item><title><![CDATA[Sources/3.0.34 (stable)/privoxy-3.0.34-stable-src.tar.gz.asc]]></title><description><![CDATA[Sources/3.0.34 (stable)/privoxy-3.0.34-stable-src.tar.gz.asc (SHA-256: 25c0af221d3d3498c3f25202255a098d8f3654ff4ca5c44e17e297d1aada0ede)]]></description><link>https://www.privoxy.org/sf-download-mirror/Sources/3.0.34%20(stable)/privoxy-3.0.34-stable-src.tar.gz.asc</link><guid>https://www.privoxy.org/sf-download-mirror/Sources/3.0.34%20(stable)/privoxy-3.0.34-stable-src.tar.gz.asc</guid><pubDate>Sun, 5 Feb 2023 05:01:01 GMT</pubDate></item>
+<item><title><![CDATA[Sources/3.0.34 (stable)/announce.txt]]></title><description><![CDATA[Sources/3.0.34 (stable)/announce.txt (SHA-256: 553f14ed2a30551c3757d8a0b2e36b1080b962dee09e5e8c338e09988ab8b042)]]></description><link>https://www.privoxy.org/sf-download-mirror/Sources/3.0.34%20(stable)/announce.txt</link><guid>https://www.privoxy.org/sf-download-mirror/Sources/3.0.34%20(stable)/announce.txt</guid><pubDate>Sun, 5 Feb 2023 05:01:00 GMT</pubDate></item>
+<item><title><![CDATA[Macintosh (OS X)/3.0.33 (stable)/Privoxy 3.0.33 64 bit.pkg.asc]]></title><description><![CDATA[Macintosh (OS X)/3.0.33 (stable)/Privoxy 3.0.33 64 bit.pkg.asc (SHA-256: 755ca9d00d9346bc9231a3939f7af7dd6583aaaf814dfdc4c8cd9f40e8172b9a)]]></description><link>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.33%20(stable)/Privoxy%203.0.33%2064%20bit.pkg.asc</link><guid>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.33%20(stable)/Privoxy%203.0.33%2064%20bit.pkg.asc</guid><pubDate>Sun, 19 Dec 2021 18:05:52 GMT</pubDate></item>
+<item><title><![CDATA[Macintosh (OS X)/3.0.33 (stable)/README]]></title><description><![CDATA[Macintosh (OS X)/3.0.33 (stable)/README (SHA-256: d1c59323eb3416916b7b7006cee4d50538e4b5f79a5183d6f9cd132a8c61a031)]]></description><link>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.33%20(stable)/README</link><guid>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.33%20(stable)/README</guid><pubDate>Sat, 18 Dec 2021 22:42:51 GMT</pubDate></item>
+<item><title><![CDATA[Macintosh (OS X)/3.0.33 (stable)/Privoxy 3.0.33 64 bit.pkg]]></title><description><![CDATA[Macintosh (OS X)/3.0.33 (stable)/Privoxy 3.0.33 64 bit.pkg (SHA-256: 6f4ab61776d768673ee7a7ec9687fe732902a73be018e28bfdccc5c2a52c64c7)]]></description><link>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.33%20(stable)/Privoxy%203.0.33%2064%20bit.pkg</link><guid>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.33%20(stable)/Privoxy%203.0.33%2064%20bit.pkg</guid><pubDate>Sat, 18 Dec 2021 22:42:50 GMT</pubDate></item>
+<item><title><![CDATA[Win32/3.0.33 (stable)/privoxy_setup_3.0.33.exe]]></title><description><![CDATA[Win32/3.0.33 (stable)/privoxy_setup_3.0.33.exe (SHA-256: 61cf249aa564dd5790b1e2f8a27ff5cb0376a0926ebe983429b5b9d9861d74f3)]]></description><link>https://www.privoxy.org/sf-download-mirror/Win32/3.0.33%20(stable)/privoxy_setup_3.0.33.exe</link><guid>https://www.privoxy.org/sf-download-mirror/Win32/3.0.33%20(stable)/privoxy_setup_3.0.33.exe</guid><pubDate>Wed, 8 Dec 2021 19:06:22 GMT</pubDate></item>
+<item><title><![CDATA[Win32/3.0.33 (stable)/privoxy_setup_3.0.33.exe.asc]]></title><description><![CDATA[Win32/3.0.33 (stable)/privoxy_setup_3.0.33.exe.asc (SHA-256: cc6b17979384c7c3da362b4a2b2997aa8e8b8d4291dcf8e2a523ed4dade8f317)]]></description><link>https://www.privoxy.org/sf-download-mirror/Win32/3.0.33%20(stable)/privoxy_setup_3.0.33.exe.asc</link><guid>https://www.privoxy.org/sf-download-mirror/Win32/3.0.33%20(stable)/privoxy_setup_3.0.33.exe.asc</guid><pubDate>Wed, 8 Dec 2021 19:06:22 GMT</pubDate></item>
+<item><title><![CDATA[Win32/3.0.33 (stable)/privoxy_3.0.33.zip]]></title><description><![CDATA[Win32/3.0.33 (stable)/privoxy_3.0.33.zip (SHA-256: fd6502fe14c98bf9a03f784b2894d163f4081d09c99821d5f4a0c9edd476475a)]]></description><link>https://www.privoxy.org/sf-download-mirror/Win32/3.0.33%20(stable)/privoxy_3.0.33.zip</link><guid>https://www.privoxy.org/sf-download-mirror/Win32/3.0.33%20(stable)/privoxy_3.0.33.zip</guid><pubDate>Wed, 8 Dec 2021 19:06:13 GMT</pubDate></item>
+<item><title><![CDATA[Win32/3.0.33 (stable)/privoxy_3.0.33.zip.asc]]></title><description><![CDATA[Win32/3.0.33 (stable)/privoxy_3.0.33.zip.asc (SHA-256: 9bd8a4b5518436c903fcc4db993e5e4d37cf59120d8b56816b8bd6aa612f2b4c)]]></description><link>https://www.privoxy.org/sf-download-mirror/Win32/3.0.33%20(stable)/privoxy_3.0.33.zip.asc</link><guid>https://www.privoxy.org/sf-download-mirror/Win32/3.0.33%20(stable)/privoxy_3.0.33.zip.asc</guid><pubDate>Wed, 8 Dec 2021 19:06:12 GMT</pubDate></item>
+<item><title><![CDATA[Win32/3.0.33 (stable)/announce.txt]]></title><description><![CDATA[Win32/3.0.33 (stable)/announce.txt (SHA-256: 0ca4fa05ad8da22b25bed264b575d9051a0a1fb99fe7263511c3b64ca66b30a9)]]></description><link>https://www.privoxy.org/sf-download-mirror/Win32/3.0.33%20(stable)/announce.txt</link><guid>https://www.privoxy.org/sf-download-mirror/Win32/3.0.33%20(stable)/announce.txt</guid><pubDate>Wed, 8 Dec 2021 19:06:01 GMT</pubDate></item>
+<item><title><![CDATA[Win32/3.0.33 (stable)/README.txt]]></title><description><![CDATA[Win32/3.0.33 (stable)/README.txt (SHA-256: 49c3eef48119cce7bf82c9fe03e9a18e31657b0d15bd702ef5bb01120256b3b0)]]></description><link>https://www.privoxy.org/sf-download-mirror/Win32/3.0.33%20(stable)/README.txt</link><guid>https://www.privoxy.org/sf-download-mirror/Win32/3.0.33%20(stable)/README.txt</guid><pubDate>Wed, 8 Dec 2021 19:05:49 GMT</pubDate></item>
+<item><title><![CDATA[Debian/3.0.33 (stable) bullseye/privoxy_3.0.33-1~pp+1_i386.deb]]></title><description><![CDATA[Debian/3.0.33 (stable) bullseye/privoxy_3.0.33-1~pp+1_i386.deb (SHA-256: c5ee601cfcf317df14ea610bf87dc703f7347eaab6a9de24dadcd9b55b4953a6)]]></description><link>https://www.privoxy.org/sf-download-mirror/Debian/3.0.33%20(stable)%20bullseye/privoxy_3.0.33-1~pp+1_i386.deb</link><guid>https://www.privoxy.org/sf-download-mirror/Debian/3.0.33%20(stable)%20bullseye/privoxy_3.0.33-1~pp+1_i386.deb</guid><pubDate>Wed, 8 Dec 2021 15:10:21 GMT</pubDate></item>
+<item><title><![CDATA[Debian/3.0.33 (stable) bullseye/privoxy_3.0.33-1~pp+1_amd64.deb.asc]]></title><description><![CDATA[Debian/3.0.33 (stable) bullseye/privoxy_3.0.33-1~pp+1_amd64.deb.asc (SHA-256: 3e8e3835293091a3adf819685dbd31a8ffe9b9a1d19c33874a488c51e457d7ad)]]></description><link>https://www.privoxy.org/sf-download-mirror/Debian/3.0.33%20(stable)%20bullseye/privoxy_3.0.33-1~pp+1_amd64.deb.asc</link><guid>https://www.privoxy.org/sf-download-mirror/Debian/3.0.33%20(stable)%20bullseye/privoxy_3.0.33-1~pp+1_amd64.deb.asc</guid><pubDate>Wed, 8 Dec 2021 15:10:19 GMT</pubDate></item>
+<item><title><![CDATA[Debian/3.0.33 (stable) bullseye/privoxy_3.0.33-1~pp+1_i386.deb.asc]]></title><description><![CDATA[Debian/3.0.33 (stable) bullseye/privoxy_3.0.33-1~pp+1_i386.deb.asc (SHA-256: fd968c7b33b8063bc80a98c88f049f42539d03b17e1f1bf7b379a95155ad8442)]]></description><link>https://www.privoxy.org/sf-download-mirror/Debian/3.0.33%20(stable)%20bullseye/privoxy_3.0.33-1~pp+1_i386.deb.asc</link><guid>https://www.privoxy.org/sf-download-mirror/Debian/3.0.33%20(stable)%20bullseye/privoxy_3.0.33-1~pp+1_i386.deb.asc</guid><pubDate>Wed, 8 Dec 2021 15:10:19 GMT</pubDate></item>
+<item><title><![CDATA[Debian/3.0.33 (stable) bullseye/privoxy_3.0.33-1~pp+1_amd64.deb]]></title><description><![CDATA[Debian/3.0.33 (stable) bullseye/privoxy_3.0.33-1~pp+1_amd64.deb (SHA-256: 64d1602b3f84a86ecb030148c666f27238a6e278933ca6de50f99b1758857be2)]]></description><link>https://www.privoxy.org/sf-download-mirror/Debian/3.0.33%20(stable)%20bullseye/privoxy_3.0.33-1~pp+1_amd64.deb</link><guid>https://www.privoxy.org/sf-download-mirror/Debian/3.0.33%20(stable)%20bullseye/privoxy_3.0.33-1~pp+1_amd64.deb</guid><pubDate>Wed, 8 Dec 2021 15:10:05 GMT</pubDate></item>
+<item><title><![CDATA[Debian/3.0.33 (stable) bullseye/README]]></title><description><![CDATA[Debian/3.0.33 (stable) bullseye/README (SHA-256: 7c7654bf8f6b65c219d624f6cb9d81243f6211b208203bee2b1a42ff4f0947d5)]]></description><link>https://www.privoxy.org/sf-download-mirror/Debian/3.0.33%20(stable)%20bullseye/README</link><guid>https://www.privoxy.org/sf-download-mirror/Debian/3.0.33%20(stable)%20bullseye/README</guid><pubDate>Wed, 8 Dec 2021 15:10:05 GMT</pubDate></item>
+<item><title><![CDATA[Sources/3.0.33 (stable)/privoxy-3.0.33-stable-src.tar.gz]]></title><description><![CDATA[Sources/3.0.33 (stable)/privoxy-3.0.33-stable-src.tar.gz (SHA-256: 04b104e70dac61561b9dd110684b250fafc8c13dbe437a60fae18ddd9a881fae)]]></description><link>https://www.privoxy.org/sf-download-mirror/Sources/3.0.33%20(stable)/privoxy-3.0.33-stable-src.tar.gz</link><guid>https://www.privoxy.org/sf-download-mirror/Sources/3.0.33%20(stable)/privoxy-3.0.33-stable-src.tar.gz</guid><pubDate>Wed, 8 Dec 2021 11:31:33 GMT</pubDate></item>
+<item><title><![CDATA[Sources/3.0.33 (stable)/announce.txt]]></title><description><![CDATA[Sources/3.0.33 (stable)/announce.txt (SHA-256: 9aefb00845c2cd754d98d4d14294cf8d02cbb9e7ab016d921a39ffef14bd9e7d)]]></description><link>https://www.privoxy.org/sf-download-mirror/Sources/3.0.33%20(stable)/announce.txt</link><guid>https://www.privoxy.org/sf-download-mirror/Sources/3.0.33%20(stable)/announce.txt</guid><pubDate>Wed, 8 Dec 2021 11:31:27 GMT</pubDate></item>
+<item><title><![CDATA[Sources/3.0.33 (stable)/privoxy-3.0.33-stable-src.tar.gz.asc]]></title><description><![CDATA[Sources/3.0.33 (stable)/privoxy-3.0.33-stable-src.tar.gz.asc (SHA-256: aebc92ffb1a6fd6d2bafd8985a72ab84be98f40d33e5a7563129ed7ea9a11a3d)]]></description><link>https://www.privoxy.org/sf-download-mirror/Sources/3.0.33%20(stable)/privoxy-3.0.33-stable-src.tar.gz.asc</link><guid>https://www.privoxy.org/sf-download-mirror/Sources/3.0.33%20(stable)/privoxy-3.0.33-stable-src.tar.gz.asc</guid><pubDate>Wed, 8 Dec 2021 11:31:27 GMT</pubDate></item>
+<item><title><![CDATA[Macintosh (OS X)/3.0.32 (stable)/Privoxy 3.0.32 64 bit.pkg]]></title><description><![CDATA[Macintosh (OS X)/3.0.32 (stable)/Privoxy 3.0.32 64 bit.pkg (SHA-256: 63329a91de6a427de54885d35802c4b7b9db831f315b657d453b69ff8d2bc76b)]]></description><link>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.32%20(stable)/Privoxy%203.0.32%2064%20bit.pkg</link><guid>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.32%20(stable)/Privoxy%203.0.32%2064%20bit.pkg</guid><pubDate>Wed, 22 Sep 2021 18:48:41 GMT</pubDate></item>
+<item><title><![CDATA[Macintosh (OS X)/3.0.32 (stable)/README]]></title><description><![CDATA[Macintosh (OS X)/3.0.32 (stable)/README (SHA-256: 032700a02a3fd5e81571f5208a89584905352dd0b4ad0b165caf741ee346f9a3)]]></description><link>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.32%20(stable)/README</link><guid>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.32%20(stable)/README</guid><pubDate>Wed, 22 Sep 2021 18:48:36 GMT</pubDate></item>
+<item><title><![CDATA[Macintosh (OS X)/3.0.32 (stable)/Privoxy 3.0.32 64 bit.pkg.asc]]></title><description><![CDATA[Macintosh (OS X)/3.0.32 (stable)/Privoxy 3.0.32 64 bit.pkg.asc (SHA-256: 9ee928f8bb2d0a5eef94c5b2ce56fc15dfaa4f464eeb7c60a394cdcdfa21c6a0)]]></description><link>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.32%20(stable)/Privoxy%203.0.32%2064%20bit.pkg.asc</link><guid>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.32%20(stable)/Privoxy%203.0.32%2064%20bit.pkg.asc</guid><pubDate>Wed, 22 Sep 2021 18:48:36 GMT</pubDate></item>
 <item><title><![CDATA[Win32/3.0.32 (stable)/README.txt]]></title><description><![CDATA[Win32/3.0.32 (stable)/README.txt (SHA-256: 7559bb89c06b49da34731a77eebf01f701a22a0829be891a5dbb53409c5f0885)]]></description><link>https://www.privoxy.org/sf-download-mirror/Win32/3.0.32%20(stable)/README.txt</link><guid>https://www.privoxy.org/sf-download-mirror/Win32/3.0.32%20(stable)/README.txt</guid><pubDate>Sat, 27 Feb 2021 17:20:26 GMT</pubDate></item>
 <item><title><![CDATA[Win32/3.0.32 (stable)/privoxy_3.0.32.zip.asc]]></title><description><![CDATA[Win32/3.0.32 (stable)/privoxy_3.0.32.zip.asc (SHA-256: 49b3aa93559744cc3ad82f64d2a71144148ba51c274114459657f84a49ea56d9)]]></description><link>https://www.privoxy.org/sf-download-mirror/Win32/3.0.32%20(stable)/privoxy_3.0.32.zip.asc</link><guid>https://www.privoxy.org/sf-download-mirror/Win32/3.0.32%20(stable)/privoxy_3.0.32.zip.asc</guid><pubDate>Sat, 27 Feb 2021 17:18:52 GMT</pubDate></item>
 <item><title><![CDATA[Win32/3.0.32 (stable)/privoxy_3.0.32.zip]]></title><description><![CDATA[Win32/3.0.32 (stable)/privoxy_3.0.32.zip (SHA-256: de9b1249500c69e8050bcfffff278fc5d6761184ffd3078a48be76b18d37f25f)]]></description><link>https://www.privoxy.org/sf-download-mirror/Win32/3.0.32%20(stable)/privoxy_3.0.32.zip</link><guid>https://www.privoxy.org/sf-download-mirror/Win32/3.0.32%20(stable)/privoxy_3.0.32.zip</guid><pubDate>Sat, 27 Feb 2021 17:18:41 GMT</pubDate></item>
 <item><title><![CDATA[Sources/3.0.27 (stable)/privoxy-3.0.27-stable-src.tar.gz]]></title><description><![CDATA[Sources/3.0.27 (stable)/privoxy-3.0.27-stable-src.tar.gz (SHA-256: 67540360e28c881c892481d1a224632f5b58569e003285467fea6e4b59316378)]]></description><link>https://www.privoxy.org/sf-download-mirror/Sources/3.0.27%20(stable)/privoxy-3.0.27-stable-src.tar.gz</link><guid>https://www.privoxy.org/sf-download-mirror/Sources/3.0.27%20(stable)/privoxy-3.0.27-stable-src.tar.gz</guid><pubDate>Sat, 29 Dec 2018 18:22:34 GMT</pubDate></item>
 <item><title><![CDATA[Sources/3.0.27 (stable)/privoxy-3.0.27-stable-src.tar.gz.asc]]></title><description><![CDATA[Sources/3.0.27 (stable)/privoxy-3.0.27-stable-src.tar.gz.asc (SHA-256: b21c902c790b413eb2d377878553a312de1897d1fb6dbf605d82f37ed74b69ae)]]></description><link>https://www.privoxy.org/sf-download-mirror/Sources/3.0.27%20(stable)/privoxy-3.0.27-stable-src.tar.gz.asc</link><guid>https://www.privoxy.org/sf-download-mirror/Sources/3.0.27%20(stable)/privoxy-3.0.27-stable-src.tar.gz.asc</guid><pubDate>Sat, 29 Dec 2018 18:22:19 GMT</pubDate></item>
 <item><title><![CDATA[Macintosh (OS X)/3.0.26 (stable)/Privoxy 3.0.26 PPC.tar.bz2.asc]]></title><description><![CDATA[Macintosh (OS X)/3.0.26 (stable)/Privoxy 3.0.26 PPC.tar.bz2.asc (SHA-256: eea766757809f228f7a0ff8afd55f180c69bfd3b325a9f99943b25b086250a8d)]]></description><link>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.26%20(stable)/Privoxy%203.0.26%20PPC.tar.bz2.asc</link><guid>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.26%20(stable)/Privoxy%203.0.26%20PPC.tar.bz2.asc</guid><pubDate>Tue, 3 Jan 2017 03:49:53 GMT</pubDate></item>
-<item><title><![CDATA[Macintosh (OS X)/3.0.26 (stable)/Privoxy 3.0.26 PPC.tar.bz2]]></title><description><![CDATA[Macintosh (OS X)/3.0.26 (stable)/Privoxy 3.0.26 PPC.tar.bz2 (SHA-256: 70b74e66e9b9099909e7ac5f3864aa68083c862dabde67bc4ae4666f95e54f1e)]]></description><link>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.26%20(stable)/Privoxy%203.0.26%20PPC.tar.bz2</link><guid>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.26%20(stable)/Privoxy%203.0.26%20PPC.tar.bz2</guid><pubDate>Sat, 31 Dec 2016 20:52:47 GMT</pubDate></item>
-<item><title><![CDATA[Macintosh (OS X)/3.0.26 (stable)/releases readme.txt]]></title><description><![CDATA[Macintosh (OS X)/3.0.26 (stable)/releases readme.txt (SHA-256: ab0beba3b01a9f7061ebd142c183f325064ff98268e8f3e628cb8ea52051ed8f)]]></description><link>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.26%20(stable)/releases%20readme.txt</link><guid>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.26%20(stable)/releases%20readme.txt</guid><pubDate>Sat, 31 Dec 2016 20:52:46 GMT</pubDate></item>
-<item><title><![CDATA[Macintosh (OS X)/3.0.26 (stable)/Privoxy 3.0.26 64 bit.pkg]]></title><description><![CDATA[Macintosh (OS X)/3.0.26 (stable)/Privoxy 3.0.26 64 bit.pkg (SHA-256: c95d93f18f8ddee754129c5cefaf9c4816e22bd25908f64b5fb447428ac84888)]]></description><link>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.26%20(stable)/Privoxy%203.0.26%2064%20bit.pkg</link><guid>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.26%20(stable)/Privoxy%203.0.26%2064%20bit.pkg</guid><pubDate>Tue, 25 Oct 2016 21:24:37 GMT</pubDate></item>
-<item><title><![CDATA[Macintosh (OS X)/3.0.26 (stable)/Privoxy 3.0.26 64 bit.pkg.asc]]></title><description><![CDATA[Macintosh (OS X)/3.0.26 (stable)/Privoxy 3.0.26 64 bit.pkg.asc (SHA-256: a6c4a260f5f96334a0b3349c5c543927c5b173e7945bb0a85a1f07e51caedfb9)]]></description><link>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.26%20(stable)/Privoxy%203.0.26%2064%20bit.pkg.asc</link><guid>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.26%20(stable)/Privoxy%203.0.26%2064%20bit.pkg.asc</guid><pubDate>Tue, 25 Oct 2016 21:24:33 GMT</pubDate></item>
-<item><title><![CDATA[Macintosh (OS X)/3.0.26 (stable)/Privoxy 3.0.26 32 bit.mpkg.zip]]></title><description><![CDATA[Macintosh (OS X)/3.0.26 (stable)/Privoxy 3.0.26 32 bit.mpkg.zip (SHA-256: 5fb14315fdab0453b279eda522ed7a7636bf8e18d368d83b826cbe7296d48e0b)]]></description><link>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.26%20(stable)/Privoxy%203.0.26%2032%20bit.mpkg.zip</link><guid>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.26%20(stable)/Privoxy%203.0.26%2032%20bit.mpkg.zip</guid><pubDate>Tue, 25 Oct 2016 21:24:32 GMT</pubDate></item>
-<item><title><![CDATA[Macintosh (OS X)/3.0.26 (stable)/Privoxy 3.0.26 32 bit.mpkg.zip.asc]]></title><description><![CDATA[Macintosh (OS X)/3.0.26 (stable)/Privoxy 3.0.26 32 bit.mpkg.zip.asc (SHA-256: 7406a023733785f13ad6ca81ceb8e5baf32d9603d0914f9ab0d24e6049fe92c5)]]></description><link>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.26%20(stable)/Privoxy%203.0.26%2032%20bit.mpkg.zip.asc</link><guid>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.26%20(stable)/Privoxy%203.0.26%2032%20bit.mpkg.zip.asc</guid><pubDate>Tue, 25 Oct 2016 21:24:31 GMT</pubDate></item>
-<item><title><![CDATA[Android/3.0.26 (stable)/privoxy-3.0.26.zip]]></title><description><![CDATA[Android/3.0.26 (stable)/privoxy-3.0.26.zip (SHA-256: f18a4ec0ceb3bf9f7e4aee84baf04ae21521593cefb54b1d3dfe00dcd9ad05a8)]]></description><link>https://www.privoxy.org/sf-download-mirror/Android/3.0.26%20(stable)/privoxy-3.0.26.zip</link><guid>https://www.privoxy.org/sf-download-mirror/Android/3.0.26%20(stable)/privoxy-3.0.26.zip</guid><pubDate>Mon, 29 Aug 2016 01:38:24 GMT</pubDate></item>
-<item><title><![CDATA[Android/3.0.26 (stable)/privoxy readme.txt]]></title><description><![CDATA[Android/3.0.26 (stable)/privoxy readme.txt (SHA-256: 5d04ed443d62e291ff0f143114c3d51c2733f87f64ecad6ccdfcf9b4b7c62acc)]]></description><link>https://www.privoxy.org/sf-download-mirror/Android/3.0.26%20(stable)/privoxy%20readme.txt</link><guid>https://www.privoxy.org/sf-download-mirror/Android/3.0.26%20(stable)/privoxy%20readme.txt</guid><pubDate>Mon, 29 Aug 2016 01:37:58 GMT</pubDate></item>
-<item><title><![CDATA[Win32/3.0.26 (stable)/privoxy-3.0.26.zip.asc]]></title><description><![CDATA[Win32/3.0.26 (stable)/privoxy-3.0.26.zip.asc (SHA-256: 9364a32ca7bcfe8cb43af413572cc9c93ccbad1b5b22e0edf435987bcf96355e)]]></description><link>https://www.privoxy.org/sf-download-mirror/Win32/3.0.26%20(stable)/privoxy-3.0.26.zip.asc</link><guid>https://www.privoxy.org/sf-download-mirror/Win32/3.0.26%20(stable)/privoxy-3.0.26.zip.asc</guid><pubDate>Sun, 28 Aug 2016 01:20:03 GMT</pubDate></item>
-<item><title><![CDATA[Win32/3.0.26 (stable)/privoxy-3.0.26.zip]]></title><description><![CDATA[Win32/3.0.26 (stable)/privoxy-3.0.26.zip (SHA-256: 80c45bc51bff0a05f928a4cebe7639464470c6fcc95983242c271cccc3e47f1a)]]></description><link>https://www.privoxy.org/sf-download-mirror/Win32/3.0.26%20(stable)/privoxy-3.0.26.zip</link><guid>https://www.privoxy.org/sf-download-mirror/Win32/3.0.26%20(stable)/privoxy-3.0.26.zip</guid><pubDate>Sun, 28 Aug 2016 01:19:55 GMT</pubDate></item>
-<item><title><![CDATA[Win32/3.0.26 (stable)/privoxy_setup_3.0.26.exe.asc]]></title><description><![CDATA[Win32/3.0.26 (stable)/privoxy_setup_3.0.26.exe.asc (SHA-256: 4d081c65361cef82a6367fb4c0ec761b44faa8937f10035a2cffc2367b2ce2af)]]></description><link>https://www.privoxy.org/sf-download-mirror/Win32/3.0.26%20(stable)/privoxy_setup_3.0.26.exe.asc</link><guid>https://www.privoxy.org/sf-download-mirror/Win32/3.0.26%20(stable)/privoxy_setup_3.0.26.exe.asc</guid><pubDate>Sun, 28 Aug 2016 01:19:42 GMT</pubDate></item>
-<item><title><![CDATA[Win32/3.0.26 (stable)/privoxy_setup_3.0.26.exe]]></title><description><![CDATA[Win32/3.0.26 (stable)/privoxy_setup_3.0.26.exe (SHA-256: 9d7a960a3adc757b8d8f59604b6e5c2be1b668c2aad11620be1448fa5657d178)]]></description><link>https://www.privoxy.org/sf-download-mirror/Win32/3.0.26%20(stable)/privoxy_setup_3.0.26.exe</link><guid>https://www.privoxy.org/sf-download-mirror/Win32/3.0.26%20(stable)/privoxy_setup_3.0.26.exe</guid><pubDate>Sun, 28 Aug 2016 01:19:32 GMT</pubDate></item>
-<item><title><![CDATA[Debian/3.0.26 (stable) jessie/README]]></title><description><![CDATA[Debian/3.0.26 (stable) jessie/README (SHA-256: 00932c5c0458adf85c4eef2ddaede64ccdfb86fa4cf5d5721a207e1bca3f6ef6)]]></description><link>https://www.privoxy.org/sf-download-mirror/Debian/3.0.26%20(stable)%20jessie/README</link><guid>https://www.privoxy.org/sf-download-mirror/Debian/3.0.26%20(stable)%20jessie/README</guid><pubDate>Sat, 27 Aug 2016 20:43:52 GMT</pubDate></item>
-<item><title><![CDATA[Debian/3.0.26 (stable) jessie/privoxy_3.0.26-1_amd64.deb.asc]]></title><description><![CDATA[Debian/3.0.26 (stable) jessie/privoxy_3.0.26-1_amd64.deb.asc (SHA-256: 86379e7f0fb517f84550d8bdd49bdc0db952b9d2d324bb7b86997f51c82e1c66)]]></description><link>https://www.privoxy.org/sf-download-mirror/Debian/3.0.26%20(stable)%20jessie/privoxy_3.0.26-1_amd64.deb.asc</link><guid>https://www.privoxy.org/sf-download-mirror/Debian/3.0.26%20(stable)%20jessie/privoxy_3.0.26-1_amd64.deb.asc</guid><pubDate>Sat, 27 Aug 2016 20:43:47 GMT</pubDate></item>
-<item><title><![CDATA[Debian/3.0.26 (stable) jessie/privoxy_3.0.26-1_amd64.deb]]></title><description><![CDATA[Debian/3.0.26 (stable) jessie/privoxy_3.0.26-1_amd64.deb (SHA-256: c8671e461c38e9d747cc005c32c103bd1fc53bfb37ecee19a8b1687a5804d6c8)]]></description><link>https://www.privoxy.org/sf-download-mirror/Debian/3.0.26%20(stable)%20jessie/privoxy_3.0.26-1_amd64.deb</link><guid>https://www.privoxy.org/sf-download-mirror/Debian/3.0.26%20(stable)%20jessie/privoxy_3.0.26-1_amd64.deb</guid><pubDate>Sat, 27 Aug 2016 20:43:41 GMT</pubDate></item>
-<item><title><![CDATA[Debian/3.0.26 (stable) jessie/privoxy_3.0.26-1_i386.deb.asc]]></title><description><![CDATA[Debian/3.0.26 (stable) jessie/privoxy_3.0.26-1_i386.deb.asc (SHA-256: 789dae9b39b4aab23fbc3aff51e4812cd0450090cf7f9c81a765dfee0a40eaf0)]]></description><link>https://www.privoxy.org/sf-download-mirror/Debian/3.0.26%20(stable)%20jessie/privoxy_3.0.26-1_i386.deb.asc</link><guid>https://www.privoxy.org/sf-download-mirror/Debian/3.0.26%20(stable)%20jessie/privoxy_3.0.26-1_i386.deb.asc</guid><pubDate>Sat, 27 Aug 2016 20:43:32 GMT</pubDate></item>
-<item><title><![CDATA[Debian/3.0.26 (stable) jessie/privoxy_3.0.26-1_i386.deb]]></title><description><![CDATA[Debian/3.0.26 (stable) jessie/privoxy_3.0.26-1_i386.deb (SHA-256: 2a3cd0d47c13436ec28954e0b1ba7f41464bcbbe9042f98b88158cd18503a978)]]></description><link>https://www.privoxy.org/sf-download-mirror/Debian/3.0.26%20(stable)%20jessie/privoxy_3.0.26-1_i386.deb</link><guid>https://www.privoxy.org/sf-download-mirror/Debian/3.0.26%20(stable)%20jessie/privoxy_3.0.26-1_i386.deb</guid><pubDate>Sat, 27 Aug 2016 20:42:58 GMT</pubDate></item>
-<item><title><![CDATA[Sources/3.0.26 (stable)/privoxy-3.0.26-stable-src.tar.gz]]></title><description><![CDATA[Sources/3.0.26 (stable)/privoxy-3.0.26-stable-src.tar.gz (SHA-256: 57e415b43ee5dfdca74685cc034053eaae962952fdabd086171551a86abf9cd8)]]></description><link>https://www.privoxy.org/sf-download-mirror/Sources/3.0.26%20(stable)/privoxy-3.0.26-stable-src.tar.gz</link><guid>https://www.privoxy.org/sf-download-mirror/Sources/3.0.26%20(stable)/privoxy-3.0.26-stable-src.tar.gz</guid><pubDate>Sat, 27 Aug 2016 11:11:46 GMT</pubDate></item>
-<item><title><![CDATA[Sources/3.0.26 (stable)/privoxy-3.0.26-stable-src.tar.gz.asc]]></title><description><![CDATA[Sources/3.0.26 (stable)/privoxy-3.0.26-stable-src.tar.gz.asc (SHA-256: f0b7b4c515ee9ddaad1c6324a62ef76b84d674cdc0fa6af4c2fa0cccf284746a)]]></description><link>https://www.privoxy.org/sf-download-mirror/Sources/3.0.26%20(stable)/privoxy-3.0.26-stable-src.tar.gz.asc</link><guid>https://www.privoxy.org/sf-download-mirror/Sources/3.0.26%20(stable)/privoxy-3.0.26-stable-src.tar.gz.asc</guid><pubDate>Sat, 27 Aug 2016 11:11:35 GMT</pubDate></item>
-<item><title><![CDATA[Sources/3.0.26 (stable)/announce.txt]]></title><description><![CDATA[Sources/3.0.26 (stable)/announce.txt (SHA-256: e482115d5aadaa041a7d20ab90b82021e1a65c6c37dcdde556668611200d41f6)]]></description><link>https://www.privoxy.org/sf-download-mirror/Sources/3.0.26%20(stable)/announce.txt</link><guid>https://www.privoxy.org/sf-download-mirror/Sources/3.0.26%20(stable)/announce.txt</guid><pubDate>Sat, 27 Aug 2016 11:11:31 GMT</pubDate></item>
-<item><title><![CDATA[Macintosh (OS X)/3.0.19 (stable)/old versions]]></title><description><![CDATA[Macintosh (OS X)/3.0.19 (stable)/old versions (SHA-256: 9d9f290527a6be626a8f5985b26e19b237b44872b03631811df4416fc1713178)]]></description><link>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.19%20(stable)/old%20versions</link><guid>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.19%20(stable)/old%20versions</guid><pubDate>Thu, 25 Aug 2016 20:58:53 GMT</pubDate></item>
-<item><title><![CDATA[Android/3.0.25 (beta)/privoxy readme.txt]]></title><description><![CDATA[Android/3.0.25 (beta)/privoxy readme.txt (SHA-256: 40a338ec8874d9f63f2abef527cc85d1ed1f80d8b07ca5ac2b5a27551c3b4262)]]></description><link>https://www.privoxy.org/sf-download-mirror/Android/3.0.25%20(beta)/privoxy%20readme.txt</link><guid>https://www.privoxy.org/sf-download-mirror/Android/3.0.25%20(beta)/privoxy%20readme.txt</guid><pubDate>Fri, 3 Jun 2016 18:42:15 GMT</pubDate></item>
-<item><title><![CDATA[Android/3.0.25 (beta)/privoxy-3.0.25_beta.zip]]></title><description><![CDATA[Android/3.0.25 (beta)/privoxy-3.0.25_beta.zip (SHA-256: e66968b1d11c416fb765f787bfffff597c2c73aa771eef14581377efc56ffc34)]]></description><link>https://www.privoxy.org/sf-download-mirror/Android/3.0.25%20(beta)/privoxy-3.0.25_beta.zip</link><guid>https://www.privoxy.org/sf-download-mirror/Android/3.0.25%20(beta)/privoxy-3.0.25_beta.zip</guid><pubDate>Fri, 3 Jun 2016 18:42:08 GMT</pubDate></item>
-<item><title><![CDATA[Macintosh (OS X)/3.0.25 (beta)/releases readme.txt]]></title><description><![CDATA[Macintosh (OS X)/3.0.25 (beta)/releases readme.txt (SHA-256: 2337ca4e9a4bc88e717f54492296b1c9cd8d20bffd1c2e6b9db8a501f674bf81)]]></description><link>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.25%20(beta)/releases%20readme.txt</link><guid>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.25%20(beta)/releases%20readme.txt</guid><pubDate>Mon, 30 May 2016 20:30:22 GMT</pubDate></item>
-<item><title><![CDATA[Macintosh (OS X)/3.0.25 (beta)/Privoxy 3.0.25 64 bit.pkg.asc]]></title><description><![CDATA[Macintosh (OS X)/3.0.25 (beta)/Privoxy 3.0.25 64 bit.pkg.asc (SHA-256: 20844490aa5089cccfe659949ddc38364c3990f8170111d453d1c64cac640ff2)]]></description><link>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.25%20(beta)/Privoxy%203.0.25%2064%20bit.pkg.asc</link><guid>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.25%20(beta)/Privoxy%203.0.25%2064%20bit.pkg.asc</guid><pubDate>Mon, 30 May 2016 20:29:42 GMT</pubDate></item>
-<item><title><![CDATA[Macintosh (OS X)/3.0.25 (beta)/Privoxy 3.0.25 32 bit.mpkg.zip.asc]]></title><description><![CDATA[Macintosh (OS X)/3.0.25 (beta)/Privoxy 3.0.25 32 bit.mpkg.zip.asc (SHA-256: d874a13474edba9ea0c3688387cfc94a9179b0c99e8c6f0bd281d0b297be21b2)]]></description><link>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.25%20(beta)/Privoxy%203.0.25%2032%20bit.mpkg.zip.asc</link><guid>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.25%20(beta)/Privoxy%203.0.25%2032%20bit.mpkg.zip.asc</guid><pubDate>Mon, 30 May 2016 20:29:42 GMT</pubDate></item>
-<item><title><![CDATA[Macintosh (OS X)/3.0.25 (beta)/Privoxy 3.0.25 32 bit.mpkg.zip]]></title><description><![CDATA[Macintosh (OS X)/3.0.25 (beta)/Privoxy 3.0.25 32 bit.mpkg.zip (SHA-256: a2db71a7976971023e97c3ad3db66a1902dd93ad0d236eda055a455af8dbae0c)]]></description><link>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.25%20(beta)/Privoxy%203.0.25%2032%20bit.mpkg.zip</link><guid>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.25%20(beta)/Privoxy%203.0.25%2032%20bit.mpkg.zip</guid><pubDate>Mon, 30 May 2016 20:21:21 GMT</pubDate></item>
-<item><title><![CDATA[Macintosh (OS X)/3.0.25 (beta)/Privoxy 3.0.25 64 bit.pkg]]></title><description><![CDATA[Macintosh (OS X)/3.0.25 (beta)/Privoxy 3.0.25 64 bit.pkg (SHA-256: 41216eb2ab7d4f56084636c5ecf856bb58b960ee7e5a69177d965efc863e68e0)]]></description><link>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.25%20(beta)/Privoxy%203.0.25%2064%20bit.pkg</link><guid>https://www.privoxy.org/sf-download-mirror/Macintosh%20(OS%20X)/3.0.25%20(beta)/Privoxy%203.0.25%2064%20bit.pkg</guid><pubDate>Mon, 30 May 2016 20:12:11 GMT</pubDate></item>
-<item><title><![CDATA[Win32/3.0.25 (beta)/privoxy-3.0.25-beta-announce.txt]]></title><description><![CDATA[Win32/3.0.25 (beta)/privoxy-3.0.25-beta-announce.txt (SHA-256: 801cae8d5f7bf9f5cfa7deb7f1e25d5ffc6ab6e0ea3dc5e61af945f0cfb8e9b8)]]></description><link>https://www.privoxy.org/sf-download-mirror/Win32/3.0.25%20(beta)/privoxy-3.0.25-beta-announce.txt</link><guid>https://www.privoxy.org/sf-download-mirror/Win32/3.0.25%20(beta)/privoxy-3.0.25-beta-announce.txt</guid><pubDate>Sun, 29 May 2016 02:11:27 GMT</pubDate></item>
-<item><title><![CDATA[Win32/3.0.25 (beta)/privoxy-3.0.25.zip.asc]]></title><description><![CDATA[Win32/3.0.25 (beta)/privoxy-3.0.25.zip.asc (SHA-256: 4aef5031184cb793f41df0c5d3fbc8ec17758d147aa3c019130ebe07c3ad0243)]]></description><link>https://www.privoxy.org/sf-download-mirror/Win32/3.0.25%20(beta)/privoxy-3.0.25.zip.asc</link><guid>https://www.privoxy.org/sf-download-mirror/Win32/3.0.25%20(beta)/privoxy-3.0.25.zip.asc</guid><pubDate>Sun, 29 May 2016 02:11:26 GMT</pubDate></item>
-<item><title><![CDATA[Win32/3.0.25 (beta)/privoxy-3.0.25.zip]]></title><description><![CDATA[Win32/3.0.25 (beta)/privoxy-3.0.25.zip (SHA-256: 9b3889d982abd401ba6b5567a4d4738d8de21b95ab28650cd87a3594d4b0d29d)]]></description><link>https://www.privoxy.org/sf-download-mirror/Win32/3.0.25%20(beta)/privoxy-3.0.25.zip</link><guid>https://www.privoxy.org/sf-download-mirror/Win32/3.0.25%20(beta)/privoxy-3.0.25.zip</guid><pubDate>Sun, 29 May 2016 02:11:25 GMT</pubDate></item>
-<item><title><![CDATA[Win32/3.0.25 (beta)/privoxy_setup_3.0.25.exe]]></title><description><![CDATA[Win32/3.0.25 (beta)/privoxy_setup_3.0.25.exe (SHA-256: 92a37199bf4fa80cedc41094e1621ad2687da3b588f56366a8953f3d2f3fc534)]]></description><link>https://www.privoxy.org/sf-download-mirror/Win32/3.0.25%20(beta)/privoxy_setup_3.0.25.exe</link><guid>https://www.privoxy.org/sf-download-mirror/Win32/3.0.25%20(beta)/privoxy_setup_3.0.25.exe</guid><pubDate>Sun, 29 May 2016 02:11:22 GMT</pubDate></item>
-<item><title><![CDATA[Win32/3.0.25 (beta)/privoxy_setup_3.0.25.exe.asc]]></title><description><![CDATA[Win32/3.0.25 (beta)/privoxy_setup_3.0.25.exe.asc (SHA-256: ffc4a5426074fb23ae75853164edef3c2c98c095b130e659164d1c1631f8aee8)]]></description><link>https://www.privoxy.org/sf-download-mirror/Win32/3.0.25%20(beta)/privoxy_setup_3.0.25.exe.asc</link><guid>https://www.privoxy.org/sf-download-mirror/Win32/3.0.25%20(beta)/privoxy_setup_3.0.25.exe.asc</guid><pubDate>Sun, 29 May 2016 02:11:22 GMT</pubDate></item>
-<item><title><![CDATA[Debian/3.0.25 (beta) jessie/privoxy_3.0.25-1_amd64.deb]]></title><description><![CDATA[Debian/3.0.25 (beta) jessie/privoxy_3.0.25-1_amd64.deb (SHA-256: 12b53a016761fb57b9c0a3558faf5d12135d76bd3e497653ac1920b2e58b13ff)]]></description><link>https://www.privoxy.org/sf-download-mirror/Debian/3.0.25%20(beta)%20jessie/privoxy_3.0.25-1_amd64.deb</link><guid>https://www.privoxy.org/sf-download-mirror/Debian/3.0.25%20(beta)%20jessie/privoxy_3.0.25-1_amd64.deb</guid><pubDate>Sat, 28 May 2016 16:15:02 GMT</pubDate></item>
-<item><title><![CDATA[Debian/3.0.25 (beta) jessie/README]]></title><description><![CDATA[Debian/3.0.25 (beta) jessie/README (SHA-256: 8ecd16b730c04961ad203973fa49da1f869cbfea0956437ac2ec4a1e490544c0)]]></description><link>https://www.privoxy.org/sf-download-mirror/Debian/3.0.25%20(beta)%20jessie/README</link><guid>https://www.privoxy.org/sf-download-mirror/Debian/3.0.25%20(beta)%20jessie/README</guid><pubDate>Sat, 28 May 2016 16:12:20 GMT</pubDate></item>
   </channel>
    </rss>
\ No newline at end of file
index a06c65c..7159850 100644 (file)
@@ -32,7 +32,7 @@
               <p><a href="https://www.privoxy.org/donate" target="_top">https://www.privoxy.org/donate</a></p>
             </li>
           </ul>
-          <p>The most recent release is <a href="announce.txt" target="_top">3.0.33 (stable)</a>.</p>
+          <p>The most recent release is <a href="announce.txt" target="_top">3.0.34 (stable)</a>.</p>
         </div>
       </div>
       <hr>
@@ -93,7 +93,7 @@
       <p style="text-align: center"><sub>The Privoxy website is also available as <a href=
       "http://l3tczdiiwoo63iwxty4lhs6p7eaxop5micbn7vbliydgv63x5zrrrfyd.onion/" target="_top">Tor onion
       service</a>.</sub></p>
-      <p style="text-align: center"><sub>Copyright &copy; 2001-2021 by Privoxy Developers</sub></p>
+      <p style="text-align: center"><sub>Copyright &copy; 2001-2023 by Privoxy Developers</sub></p>
       <p style="text-align: center"><sub>Hosting and development is funded in part by:</sub></p>
       <p style="text-align: center"><sub><a href="https://www.lalal.ai/"><img src="images/sponsors/lalal.ai_logo.png"
       align="middle" alt="Vocal Remover by Lalal.ai"></a></sub></p>
index dd99a52..6232262 100644 (file)
-<!-- Creator     : groff version 1.19.2 -->
-<!-- CreationDate: Wed Feb 24 02:41:14 2021 -->
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
-"http://www.w3.org/TR/html4/loose.dtd">
+<!DOCTYPE html>
 <html>
 <head>
-  <meta name="generator" content="groff -Thtml, see www.gnu.org">
-  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-  <meta name="Content-Style" content="text/css">
-  <style type="text/css">
-       p     { margin-top: 0; margin-bottom: 0; }
-       pre   { margin-top: 0; margin-bottom: 0; }
-       table { margin-top: 0; margin-bottom: 0; }
-  </style>
-  <title>PRIVOXY</title>
-  <link rel="STYLESHEET" type="text/css" href="../p_doc.css">
+  <title>Privoxy Man page</title>
+  <link rel="stylesheet" type="text/css" href="../p_web.css">
 </head>
 <body>
-  <h1 align="center">PRIVOXY</h1><a href="#NAME">NAME</a><br>
-  <a href="#SYNOPSIS">SYNOPSIS</a><br>
-  <a href="#OPTIONS">OPTIONS</a><br>
-  <a href="#DESCRIPTION">DESCRIPTION</a><br>
-  <a href="#INSTALLATION%20AND%20USAGE">INSTALLATION AND USAGE</a><br>
-  <a href="#CONFIGURATION">CONFIGURATION</a><br>
-  <a href="#FILES">FILES</a><br>
-  <a href="#SIGNALS">SIGNALS</a><br>
-  <a href="#NOTES">NOTES</a><br>
-  <a href="#SEE%20ALSO">SEE ALSO</a><br>
-  <a href="#DEVELOPMENT%20TEAM">DEVELOPMENT TEAM</a><br>
-  <a href="#COPYRIGHT%20AND%20LICENSE">COPYRIGHT AND LICENSE</a><br>
-  <hr>
-  <a name="NAME"></a>
   <h2>NAME</h2>
-  <p style="margin-left:11%; margin-top: 1em">privoxy &minus; Privacy Enhancing Proxy</p><a name="SYNOPSIS"></a>
-  <h2>SYNOPSIS</h2>
-  <p style="margin-left:11%; margin-top: 1em"><b>privoxy</b> [<b>&minus;&minus;chroot</b> ]
-  [<b>&minus;&minus;config-test</b> ] [<b>&minus;&minus;help</b> ] [<b>&minus;&minus;no-daemon</b> ]
-  [<b>&minus;&minus;pidfile</b> <i>pidfile</i> ] [<b>&minus;&minus;pre-chroot-nslookup</b> <i>hostname</i> ]
-  [<b>&minus;&minus;user</b> <i>user[.group]</i> ] [<b>&minus;&minus;version</b> ] [<i>configfile</i> ]</p><a name=
-  "OPTIONS"></a>
+  <pre>
+       [<b>--pidfile</b> <i>pidfile</i> ] [<b>--pre-chroot-nslookup</b> <i>hostname</i> ] [<b>--user</b>
+       <i>user[.group]</i> ] [<b>--version</b> ] [<i>configfile</i> ]
+
+
+
+</pre>
   <h2>OPTIONS</h2>
-  <p style="margin-left:11%; margin-top: 1em"><b>Privoxy</b> may be invoked with the following command line options:
-  <b><br>
-  &minus;&minus;chroot</b></p>
-  <p style="margin-left:22%;">Before changing to the user ID given in the &minus;&minus;user option, chroot to that
-  user&rsquo;s home directory, i.e. make the kernel pretend to the <b>Privoxy</b> process that the directory tree
-  starts there. If set up carefully, this can limit the impact of possible vulnerabilities in <b>Privoxy</b> to the
-  files contained in that hierarchy.</p>
-  <p style="margin-left:11%;"><b>&minus;&minus;config-test</b></p>
-  <p style="margin-left:22%;">Exit after loading the configuration files before binding to the listen address. The exit
-  code signals whether or not the configuration files have been successfully loaded.</p>
-  <p style="margin-left:22%; margin-top: 1em">If the exit code is 1, at least one of the configuration files is
-  invalid, if it is 0, all the configuration files have been successfully loaded (but may still contain errors that can
-  currently only be detected at run time).</p>
-  <p style="margin-left:22%; margin-top: 1em">This option doesn&rsquo;t affect the log setting, combination with
-  &quot;--no-daemon&quot; is recommended if a configured log file shouldn&rsquo;t be used.</p>
-  <table width="100%" border="0" rules="none" frame="void" cellspacing="0" cellpadding="0">
-    <tr valign="top" align="left">
-      <td width="11%"></td>
-      <td width="9%">
-        <p style="margin-top: 1em" valign="top"><b>&minus;&minus;help</b></p>
-      </td>
-      <td width="2%"></td>
-      <td width="49%">
-        <p style="margin-top: 1em" valign="top">Print brief usage info and exit.</p>
-      </td>
-      <td width="29%"></td>
-    </tr>
-  </table>
-  <p style="margin-left:11%;"><b>&minus;&minus;no-daemon</b></p>
-  <p style="margin-left:22%;">Don&rsquo;t become a daemon, i.e. don&rsquo;t fork and become process group leader,
-  don&rsquo;t detach from controlling tty, and do all logging there.</p>
-  <p style="margin-left:11%;"><b>&minus;&minus;pidfile</b> <i>pidfile</i></p>
-  <p style="margin-left:22%;">On startup, write the process ID to <i>pidfile</i>. Delete the <i>pidfile</i> on exit.
-  Failure to create or delete the <i>pidfile</i> is non-fatal. If no <b>&minus;&minus;pidfile</b> option is given, no
-  PID file will be used.</p>
-  <p style="margin-left:11%;"><b>&minus;&minus;pre-chroot-nslookup</b> <i>hostname</i></p>
-  <p style="margin-left:22%;">Initialize the resolver library using <i>hostname</i> before chroot&rsquo;ing. On some
-  systems this reduces the number of files that must be copied into the chroot tree.</p>
-  <p style="margin-left:11%;"><b>&minus;&minus;user</b> <i>user[.group]</i></p>
-  <p style="margin-left:22%;">After (optionally) writing the PID file, assume the user ID of <i>user</i> and the GID of
-  <i>group</i>, or, if the optional <i>group</i> was not given, the default group of <i>user</i>. Exit if the
-  privileges are not sufficient to do so.</p>
-  <p style="margin-left:11%;"><b>&minus;&minus;version</b></p>
-  <p style="margin-left:22%;">Print version info and exit.</p>
-  <p style="margin-left:11%; margin-top: 1em">If the <i>configfile</i> is not specified on the command line,
-  <b>Privoxy</b> will look for a file named <i>config</i> in the current directory. If no <i>configfile</i> is found,
-  <b>Privoxy</b> will fail to start.</p><a name="DESCRIPTION"></a>
-  <h2>DESCRIPTION</h2>
-  <p style="margin-left:11%; margin-top: 1em">Privoxy is a non-caching web proxy with advanced filtering capabilities
-  for enhancing privacy, modifying web page data and HTTP headers, controlling access, and removing ads and other
-  obnoxious Internet junk. Privoxy has a flexible configuration and can be customized to suit individual needs and
-  tastes. It has application for both stand-alone systems and multi-user networks.</p>
-  <p style="margin-left:11%; margin-top: 1em">Privoxy is Free Software and licensed under the GNU GPLv2 or later.</p>
-  <p style="margin-left:11%; margin-top: 1em">Privoxy is an associated project of Software in the Public Interest
-  (SPI).</p>
-  <p style="margin-left:11%; margin-top: 1em">Helping hands and donations are welcome:</p>
-  <table width="100%" border="0" rules="none" frame="void" cellspacing="0" cellpadding="0">
-    <tr valign="top" align="left">
-      <td width="11%"></td>
-      <td width="1%">
-        <p style="margin-top: 1em" valign="top">&bull;</p>
-      </td>
-      <td width="2%"></td>
-      <td width="54%">
-        <p style="margin-top: 1em" valign="top">https://www.privoxy.org/participate</p>
-      </td>
-      <td width="32%"></td>
-    </tr>
-    <tr valign="top" align="left">
-      <td width="11%"></td>
-      <td width="1%">
-        <p style="margin-top: 1em" valign="top">&bull;</p>
-      </td>
-      <td width="2%"></td>
-      <td width="54%">
-        <p style="margin-top: 1em" valign="top">https://www.privoxy.org/donate</p>
-      </td>
-      <td width="32%"></td>
-    </tr>
-  </table><a name="INSTALLATION AND USAGE"></a>
+  <pre>
+       <b>Privoxy</b> may be invoked with the following command line options:
+
+       <b>--chroot</b>
+              Before changing to the user ID given in the --user option,
+              chroot to that user's home directory, i.e. make the kernel
+              pretend to the <b>Privoxy</b> process that the directory tree starts
+              there. If set up carefully, this can limit the impact of
+              possible vulnerabilities in <b>Privoxy</b> to the files contained in
+              that hierarchy.
+
+       <b>--config-test</b>
+              Exit after loading the configuration files before binding to the
+              listen address. The exit code signals whether or not the
+              configuration files have been successfully loaded.
+
+              If the exit code is 1, at least one of the configuration files
+              is invalid, if it is 0, all the configuration files have been
+              successfully loaded (but may still contain errors that can
+              currently only be detected at run time).
+
+              This option doesn't affect the log setting, combination with
+              "--no-daemon" is recommended if a configured log file shouldn't
+              be used.
+
+       <b>--help</b> Print brief usage info and exit.
+
+       <b>--no-daemon</b>
+              Don't  become  a daemon, i.e. don't fork and become process
+              group leader, don't detach from controlling tty, and do all
+              logging there.
+
+       <b>--pidfile</b> <i>pidfile</i>
+              On startup, write the process ID to <i>pidfile</i>.  Delete the <i>pidfile</i>
+              on exit.  Failure to create or delete the <i>pidfile</i> is non-fatal.
+              If no <b>--pidfile</b> option is given, no PID file will be used.
+
+       <b>--pre-chroot-nslookup</b> <i>hostname</i>
+              Initialize the resolver library using <i>hostname</i> before
+              chroot'ing. On some systems this reduces the number of files
+              that must be copied into the chroot tree.
+
+       <b>--user</b> <i>user[.group]</i>
+              After (optionally) writing the PID file, assume the user ID of
+              <i>user</i> and the GID of <i>group</i>, or, if the optional <i>group</i> was not
+              given, the default group of <i>user</i>. Exit if the privileges are not
+              sufficient to do so.
+
+
+       Privoxy is Free Software and licensed under the GNU GPLv2 or later.
+
+       Privoxy is an associated project of Software in the Public Interest
+       (SPI).
+
+       Helping hands and donations are welcome:
+
+       â&euro;¢ https://www.privoxy.org/participate
+
+       â&euro;¢ https://www.privoxy.org/donate
+
+
+</pre>
   <h2>INSTALLATION AND USAGE</h2>
-  <p style="margin-left:11%; margin-top: 1em">Browsers can either be individually configured to use <b>Privoxy</b> as a
-  HTTP proxy (recommended), or <b>Privoxy</b> can be combined with a packet filter to build an intercepting proxy (see
-  <i>config</i>). The default setting is for localhost, on port 8118 (configurable in the main config file). To set the
-  HTTP proxy in Firefox, go through: <b>Tools</b>; <b>Options</b>; <b>General</b>; <b>Connection Settings</b>;
-  <b>Manual Proxy Configuration</b>.</p>
-  <p style="margin-left:11%; margin-top: 1em">For Internet Explorer, go through: <b>Tools</b>; <b>Internet
-  Properties</b>; <b>Connections</b>; <b>LAN Settings</b>.</p>
-  <p style="margin-left:11%; margin-top: 1em">The Secure (SSL) Proxy should also be set to the same values, otherwise
-  https: URLs will not be proxied. Note: <b>Privoxy</b> can only proxy HTTP and HTTPS traffic. Do not try it with FTP
-  or other protocols. HTTPS presents some limitations, and not all features will work with HTTPS connections.</p>
-  <p style="margin-left:11%; margin-top: 1em">For other browsers, check the documentation.</p><a name=
-  "CONFIGURATION"></a>
+  <pre>
+       Browsers can either be individually configured to use <b>Privoxy</b> as a HTTP
+       proxy (recommended), or <b>Privoxy</b> can be combined with a packet filter to
+       build an intercepting proxy (see <i>config</i>).  The default setting is  for
+       localhost,  on port  8118 (configurable in the main config file).  To
+       set the HTTP proxy in Firefox, go through: <b>Tools</b>; <b>Options</b>; <b>General</b>;
+       <b>Connection</b> <b>Settings</b>; <b>Manual</b> <b>Proxy</b> <b>Configuration</b>.
+
+       For Internet Explorer, go through: <b>Tools</b>; <b>Internet</b> <b>Properties</b>;
+       <b>Connections</b>; <b>LAN</b> <b>Settings</b>.
+
+       The Secure (SSL) Proxy should also be set to the same values, otherwise
+       https: URLs will not be proxied. Note: <b>Privoxy</b> can only proxy HTTP and
+       HTTPS traffic. Do not try it with FTP or other protocols.  HTTPS
+       presents some limitations, and not all features will work with HTTPS
+       connections.
+
+       For other browsers, check the documentation.
+
+
+</pre>
   <h2>CONFIGURATION</h2>
-  <p style="margin-left:11%; margin-top: 1em"><b>Privoxy</b> can be configured with the various configuration files.
-  The default configuration files are: <i>config</i>, <i>default.filter</i>, <i>default.action</i> and
-  <i>default.action</i>. <i>user.action</i> should be used for locally defined exceptions to the default rules in
-  <i>match-all.action</i> and <i>default.action</i>, and <i>user.filter</i> for locally defined filters. These are well
-  commented. On Unix and Unix-like systems, these are located in <i>/etc/privoxy/</i> by default.</p>
-  <p style="margin-left:11%; margin-top: 1em"><b>Privoxy</b> uses the concept of <b>actions</b> in order to manipulate
-  the data stream between the browser and remote sites. There are various actions available with specific functions for
-  such things as blocking web sites, managing cookies, etc. These actions can be invoked individually or combined, and
-  used against individual URLs, or groups of URLs that can be defined using wildcards and regular expressions. The
-  result is that the user has greatly enhanced control and freedom.</p>
-  <p style="margin-left:11%; margin-top: 1em">The actions list (ad blocks, etc) can also be configured with your web
-  browser at http://config.privoxy.org/ (assuming the configuration allows it). <b>Privoxy&rsquo;s</b> configuration
-  parameters can also be viewed at the same page. In addition, <b>Privoxy</b> can be toggled on/off. This is an
-  internal page, and does not require Internet access.</p>
-  <p style="margin-left:11%; margin-top: 1em">See the <i>User Manual</i> for a detailed explanation of installation,
-  general usage, all configuration options, new features and notes on upgrading.</p><a name="FILES"></a>
-  <h2>FILES</h2>
-  <p style="margin-left:11%; margin-top: 1em"><i>/usr/sbin/privoxy<br>
-  /etc/privoxy/config<br>
-  /etc/privoxy/match-all.action<br>
-  /etc/privoxy/default.action<br>
-  /etc/privoxy/user.action<br>
-  /etc/privoxy/default.filter<br>
-  /etc/privoxy/user.filter<br>
-  /etc/privoxy/trust<br>
-  /etc/privoxy/templates/*<br>
-  /var/log/privoxy/logfile</i></p>
-  <p style="margin-left:11%; margin-top: 1em">Various other files should be included, but may vary depending on
-  platform and build configuration. Additional documentation should be included in the local documentation
-  directory.</p><a name="SIGNALS"></a>
+  <pre>
+       <b>Privoxy</b> can be configured with the various configuration files. The
+       default configuration files are: <i>config</i>, <i>default.filter</i>, <i>default.action</i>
+       and <i>default.action</i>. <i>user.action</i> should be used for locally defined
+       exceptions to the default rules in <i>match-all.action</i> and <i>default.action</i>,
+       and <i>user.filter</i> for locally defined filters. These are well commented.
+       On Unix and Unix-like systems, these are located in <i>/etc/privoxy/</i> by
+       default.
+
+       <b>Privoxy</b> uses the concept of <b>actions</b> in order to manipulate the data
+       stream between the browser and remote sites.  There are various actions
+       available with specific functions for such things as blocking web
+       sites, managing cookies, etc. These actions can be invoked individually
+       or combined, and used against individual URLs, or groups of URLs that
+       can be defined using wildcards and regular expressions. The result is
+       that the user has greatly enhanced control and freedom.
+
+       The actions list (ad blocks, etc) can also be configured with your web
+       browser at http://config.privoxy.org/ (assuming the configuration
+       allows it).  <b>Privoxy's</b> configuration parameters  can also  be viewed at
+       the same page. In addition, <b>Privoxy</b> can be toggled on/off.  This is an
+        <i>/etc/privoxy/templates/*</i>
+        <i>/var/log/privoxy/logfile</i>
+
+       Various other files should be included, but may vary depending on
+       platform and build configuration. Additional documentation should be
+       included in the local documentation directory.
+
+
+</pre>
   <h2>SIGNALS</h2>
-  <p style="margin-left:11%; margin-top: 1em"><b>Privoxy</b> terminates on the <b>SIGINT</b> and <b>SIGTERM</b>
-  signals. Log rotation scripts may cause a re-opening of the logfile by sending a <b>SIGHUP</b> to <b>Privoxy</b>.
-  Note that unlike other daemons, <b>Privoxy</b> does not need to be made aware of config file changes by <b>SIGHUP</b>
-  -- it will detect them automatically. Signals other than the ones listed above aren&rsquo;t explicitly handled and
-  result in the default action defined by the operating system.</p><a name="NOTES"></a>
+  <pre>
+       <b>Privoxy</b> terminates on the <b>SIGINT</b> and <b>SIGTERM</b> signals. Log rotation
+       scripts may cause a re-opening of the logfile by sending a <b>SIGHUP</b> to
+       <b>Privoxy</b>. Note that unlike other daemons,  <b>Privoxy</b> does not need to be
+       made aware of config file changes by <b>SIGHUP</b> -- it will detect them
+       automatically. Signals other than the ones listed above aren't
+       explicitly handled and result in the default action defined by the
+       operating system.
+
+
+</pre>
   <h2>NOTES</h2>
-  <p style="margin-left:11%; margin-top: 1em">Please see the <i>User Manual</i> on how to contact the developers, for
-  feature requests, reporting problems, and other questions.</p><a name="SEE ALSO"></a>
+  <pre>
+       Please see the <i>User</i> <i>Manual</i> on how to contact the developers, for
+       feature requests, reporting problems, and other questions.
+
+
+</pre>
   <h2>SEE ALSO</h2>
-  <p style="margin-left:11%; margin-top: 1em">Other references and sites of interest to <b>Privoxy</b> users:</p>
-  <p style="margin-left:11%; margin-top: 1em">https://www.privoxy.org/, the <b>Privoxy</b> Home page.</p>
-  <p style="margin-left:11%; margin-top: 1em">https://www.privoxy.org/faq/, the <b>Privoxy</b> FAQ.</p>
-  <p style="margin-left:11%; margin-top: 1em">https://www.privoxy.org/developer-manual/, the <b>Privoxy</b> developer
-  manual.</p>
-  <p style="margin-left:11%; margin-top: 1em">https://sourceforge.net/projects/ijbswa/, the Project Page for
-  <b>Privoxy</b> on SourceForge.</p>
-  <p style="margin-left:11%; margin-top: 1em">http://config.privoxy.org/, the web-based user interface. <b>Privoxy</b>
-  must be running for this to work. Shortcut: http://p.p/</p>
-  <p style="margin-left:11%; margin-top: 1em">https://sourceforge.net/p/ijbswa/actionsfile-feedback/, to submit
-  &lsquo;&lsquo;misses&rsquo;&rsquo; and other configuration related suggestions to the developers.</p><a name=
-  "DEVELOPMENT TEAM"></a>
+  <pre>
+       Other references and sites of interest to <b>Privoxy</b> users:
+
+       https://www.privoxy.org/, the <b>Privoxy</b> Home page.
+
+       https://www.privoxy.org/faq/, the <b>Privoxy</b> FAQ.
+
+       https://www.privoxy.org/developer-manual/, the <b>Privoxy</b> developer
+       manual.
+
+       https://sourceforge.net/projects/ijbswa/, the Project Page for <b>Privoxy</b>
+       on SourceForge.
+
+       http://config.privoxy.org/, the web-based user interface. <b>Privoxy</b> must
+       be running for this to work. Shortcut: http://p.p/
+
+       https://sourceforge.net/p/ijbswa/actionsfile-feedback/, to submit
+       ``misses'' and other configuration related suggestions to the
+       developers.
+
+
+</pre>
   <h2>DEVELOPMENT TEAM</h2>
-  <p style="margin-left:11%; margin-top: 1em">Fabian Keil, lead developer<br>
-  David Schmidt<br>
-  Lee Rian<br>
-  Roland Rosenfeld<br>
-  Ian Silvester</p><a name="COPYRIGHT AND LICENSE"></a>
+  <pre>
+        Fabian Keil, lead developer
+        David Schmidt
+        Lee Rian
+        Roland Rosenfeld
+        Ian Silvester
+
+
+</pre>
   <h2>COPYRIGHT AND LICENSE</h2>
-  <p style="margin-left:11%; margin-top: 1em"><b>COPYRIGHT</b><br>
-  Copyright (C) 2001-2021 by Privoxy Developers &lt;privoxy-devel@lists.privoxy.org&gt;</p>
-  <p style="margin-left:11%; margin-top: 1em">Some source code is based on code Copyright (C) 1997 by Anonymous Coders
-  and Junkbusters, Inc.</p>
-  <p style="margin-left:11%; margin-top: 1em"><b>LICENSE<br>
-  Privoxy</b> is free software; you can redistribute and/or modify its source code under the terms of the <i>GNU
-  General Public License</i> as published by the Free Software Foundation, either version 2 of the license, or (at your
-  option) any later version.</p>
-  <p style="margin-left:11%; margin-top: 1em">The same is true for <b>Privoxy</b> binaries unless they are linked with
-  a mbed TLS version that is licensed under the Apache 2.0 license in which case you can redistribute and/or modify the
-  <b>Privoxy</b> binaries under the terms of the <i>GNU General Public License</i> as published by the Free Software
-  Foundation, either version 3 of the license, or (at your option) any later version.</p>
-  <p style="margin-left:11%; margin-top: 1em"><b>Privoxy</b> is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
-  the <i>license</i> for details.</p>
-  <hr>
+  <pre>
+
+</pre>
+  <h3>COPYRIGHT</h3>
+  <pre>
+       Copyright (C) 2001-2023 by Privoxy Developers &lt;privoxy-
+       devel@lists.privoxy.org&gt;
+
+       (at your option) any later version.
+
+       <b>Privoxy</b> is distributed in the hope that it will be useful, but WITHOUT
+       ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+       FITNESS FOR A PARTICULAR PURPOSE.  See the  <i>license</i> for details.
+
+Privoxy 3.0.34                 05 February 2023                     <b>PRIVOXY(8)</b>
+</pre>
 </body>
 </html>
index 1e18e12..8b680da 100644 (file)
@@ -12,7 +12,7 @@
   <div class="ARTICLE">
     <div class="TITLEPAGE">
       <h1 class="TITLE"><a name="AEN2" id="AEN2">Privoxy - The Privacy Enhancing Proxy</a></h1>
-      <h2 class="SUBTITLE">Project Index Page v3.0.33</h2>
+      <h2 class="SUBTITLE">Project Index Page v3.0.35</h2>
       <div>
         <div class="ABSTRACT">
           <a name="AEN5" id="AEN5"></a>
@@ -89,7 +89,7 @@
     <div class="SECT1">
       <hr>
       <h2 class="SECT1"><a name="AEN62" id="AEN62"></a></h2>
-      <p><sub>Copyright &copy; 2001-2021 by Privoxy Developers</sub></p>
+      <p><sub>Copyright &copy; 2001-2023 by Privoxy Developers</sub></p>
     </div>
   </div>
 </body>
index a412aa0..a4c800c 100644 (file)
   <h1>Privoxy sponsors</h1>
   <p>This page lists <a href="../">Privoxy</a> sponsors and their <a href="../faq/general.html#SPONSOR">sponsor
   level</a> with the exception of sponsors that preferred not to be listed here.</p>
-  <h3>Silver sponsors</h3><a href="https://www.lalal.ai/"><img src="../images/sponsors/lalal.ai_logo.png" alt=
-  "Vocal Remover by Lalal.ai"></a>
+  <h3>Silver sponsors</h3>
+  <p><a href="https://scrubtheweb.com/">https://scrubtheweb.com/</a></p>
+  <p><a href="https://www.lalal.ai/"><img src="../images/sponsors/lalal.ai_logo.png" alt=
+  "Vocal Remover by Lalal.ai"></a></p>
   <h3>Bronze sponsors</h3>
   <p><a href="https://www.betrugstest.com/">https://www.betrugstest.com/</a></p>
-  <p><a href="https://www.vpncompare.co.uk/">https://www.vpncompare.co.uk/</a></p>
+  <p><a href="https://moneybanker.fr/">https://moneybanker.fr/</a></p>
+  <p><a href="https://vpnxpert.com/">https://vpnxpert.com/</a></p>
   <h3>Becoming a Privoxy sponsor</h3>
   <p>If you want to become a sponsor, please have a look at the <a title=
   "FAQ: How can I become a sponsor and get my logo or link on privoxy.org?" href="../faq/general.html#SPONSOR">sponsor
index ed626d7..f718b15 100644 (file)
@@ -4,7 +4,7 @@
 <head>
   <title>Actions Files</title>
   <meta name="GENERATOR" content="Modular DocBook HTML Stylesheet Version 1.79">
-  <link rel="HOME" title="Privoxy 3.0.33 User Manual" href="index.html">
+  <link rel="HOME" title="Privoxy 3.0.35 User Manual" href="index.html">
   <link rel="PREVIOUS" title="The Main Configuration File" href="config.html">
   <link rel="NEXT" title="Filter Files" href="filter-file.html">
   <link rel="STYLESHEET" type="text/css" href="../p_doc.css">
@@ -15,7 +15,7 @@
   <div class="NAVHEADER">
     <table summary="Header navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
       <tr>
-        <th colspan="3" align="center">Privoxy 3.0.33 User Manual</th>
+        <th colspan="3" align="center">Privoxy 3.0.35 User Manual</th>
       </tr>
       <tr>
         <td width="10%" align="left" valign="bottom"><a href="config.html" accesskey="P">Prev</a></td>
       </div>
       <div class="SECT3">
         <h3 class="SECT3"><a name="CLIENT-TAG-PATTERN" id="CLIENT-TAG-PATTERN">8.4.5. The Client Tag Pattern</a></h3>
-        <div class="WARNING">
-          <table class="WARNING" border="1" width="100%">
-            <tr>
-              <td align="center"><b>Warning</b></td>
-            </tr>
-            <tr>
-              <td align="left">
-                <p>This is an experimental feature. The syntax is likely to change in future versions.</p>
-              </td>
-            </tr>
-          </table>
-        </div>
         <p>Client tag patterns are not set based on HTTP headers but based on the client's IP address. Users can enable
         them themselves, but the Privoxy admin controls which tags are available and what their effect is.</p>
         <p>After a client-specific tag has been defined with the <a href=
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="CLIENT-HEADER-TAGGER" id="CLIENT-HEADER-TAGGER">8.5.6. client-header-tagger</a></h4>
+        <h4 class="SECT3"><a name="CLIENT-BODY-TAGGER" id="CLIENT-BODY-TAGGER">8.5.6. client-body-tagger</a></h4>
+        <div class="VARIABLELIST">
+          <dl>
+            <dt>Typical use:</dt>
+            <dd>
+              <p>Block requests based on the content of the body data.</p>
+            </dd>
+            <dt>Effect:</dt>
+            <dd>
+              <p>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.</p>
+            </dd>
+            <dt>Type:</dt>
+            <dd>
+              <p>Multi-value.</p>
+            </dd>
+            <dt>Parameter:</dt>
+            <dd>
+              <p>The name of a client-body tagger, as defined in one of the <a href="filter-file.html">filter
+              files</a>.</p>
+            </dd>
+            <dt>Notes:</dt>
+            <dd>
+              <p>Please refer to the <a href="filter-file.html">filter file chapter</a> to learn how to create your own
+              client-body tagger.</p>
+              <p>Client-body taggers are applied to each request body on its own, and as the body isn't modified, each
+              tagger "sees" the original.</p>
+              <p>Chunk-encoded request bodies currently can't be tagged. Request bodies larger than the buffer-limit
+              can't be tagged either.</p>
+            </dd>
+            <dt>Example usage (section):</dt>
+            <dd>
+              <table border="0" bgcolor="#E0E0E0" width="90%">
+                <tr>
+                  <td>
+                    <pre class="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$</pre>
+                  </td>
+                </tr>
+              </table>
+            </dd>
+          </dl>
+        </div>
+      </div>
+      <div class="SECT3">
+        <h4 class="SECT3"><a name="CLIENT-HEADER-TAGGER" id="CLIENT-HEADER-TAGGER">8.5.7. client-header-tagger</a></h4>
         <div class="VARIABLELIST">
           <dl>
             <dt>Typical use:</dt>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="CONTENT-TYPE-OVERWRITE" id="CONTENT-TYPE-OVERWRITE">8.5.7.
+        <h4 class="SECT3"><a name="CONTENT-TYPE-OVERWRITE" id="CONTENT-TYPE-OVERWRITE">8.5.8.
         content-type-overwrite</a></h4>
         <div class="VARIABLELIST">
           <dl>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="CRUNCH-CLIENT-HEADER" id="CRUNCH-CLIENT-HEADER">8.5.8. crunch-client-header</a></h4>
+        <h4 class="SECT3"><a name="CRUNCH-CLIENT-HEADER" id="CRUNCH-CLIENT-HEADER">8.5.9. crunch-client-header</a></h4>
         <div class="VARIABLELIST">
           <dl>
             <dt>Typical use:</dt>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="CRUNCH-IF-NONE-MATCH" id="CRUNCH-IF-NONE-MATCH">8.5.9. crunch-if-none-match</a></h4>
+        <h4 class="SECT3"><a name="CRUNCH-IF-NONE-MATCH" id="CRUNCH-IF-NONE-MATCH">8.5.10.
+        crunch-if-none-match</a></h4>
         <div class="VARIABLELIST">
           <dl>
             <dt>Typical use:</dt>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="CRUNCH-INCOMING-COOKIES" id="CRUNCH-INCOMING-COOKIES">8.5.10.
+        <h4 class="SECT3"><a name="CRUNCH-INCOMING-COOKIES" id="CRUNCH-INCOMING-COOKIES">8.5.11.
         crunch-incoming-cookies</a></h4>
         <div class="VARIABLELIST">
           <dl>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="CRUNCH-SERVER-HEADER" id="CRUNCH-SERVER-HEADER">8.5.11.
+        <h4 class="SECT3"><a name="CRUNCH-SERVER-HEADER" id="CRUNCH-SERVER-HEADER">8.5.12.
         crunch-server-header</a></h4>
         <div class="VARIABLELIST">
           <dl>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="CRUNCH-OUTGOING-COOKIES" id="CRUNCH-OUTGOING-COOKIES">8.5.12.
+        <h4 class="SECT3"><a name="CRUNCH-OUTGOING-COOKIES" id="CRUNCH-OUTGOING-COOKIES">8.5.13.
         crunch-outgoing-cookies</a></h4>
         <div class="VARIABLELIST">
           <dl>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="DEANIMATE-GIFS" id="DEANIMATE-GIFS">8.5.13. deanimate-gifs</a></h4>
+        <h4 class="SECT3"><a name="DEANIMATE-GIFS" id="DEANIMATE-GIFS">8.5.14. deanimate-gifs</a></h4>
         <div class="VARIABLELIST">
           <dl>
             <dt>Typical use:</dt>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="DELAY-RESPONSE" id="DELAY-RESPONSE">8.5.14. delay-response</a></h4>
+        <h4 class="SECT3"><a name="DELAY-RESPONSE" id="DELAY-RESPONSE">8.5.15. delay-response</a></h4>
         <div class="VARIABLELIST">
           <dl>
             <dt>Typical use:</dt>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="DOWNGRADE-HTTP-VERSION" id="DOWNGRADE-HTTP-VERSION">8.5.15.
+        <h4 class="SECT3"><a name="DOWNGRADE-HTTP-VERSION" id="DOWNGRADE-HTTP-VERSION">8.5.16.
         downgrade-http-version</a></h4>
         <div class="VARIABLELIST">
           <dl>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="EXTERNAL-FILTER" id="EXTERNAL-FILTER">8.5.16. external-filter</a></h4>
+        <h4 class="SECT3"><a name="EXTERNAL-FILTER" id="EXTERNAL-FILTER">8.5.17. external-filter</a></h4>
         <div class="VARIABLELIST">
           <dl>
             <dt>Typical use:</dt>
               </div>
               <p>This feature is experimental, the <tt class="LITERAL"><a href=
               "filter-file.html#EXTERNAL-FILTER-SYNTAX">syntax</a></tt> may change in the future.</p>
+              <p>If you want to apply external filters to images or other content that isn't text-based, enable the
+              <tt class="LITERAL"><a href="actions-file.html#FORCE-TEXT-MODE">force-text-mode</a></tt> action as
+              well.</p>
             </dd>
             <dt>Example usage:</dt>
             <dd>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="FAST-REDIRECTS" id="FAST-REDIRECTS">8.5.17. fast-redirects</a></h4>
+        <h4 class="SECT3"><a name="FAST-REDIRECTS" id="FAST-REDIRECTS">8.5.18. fast-redirects</a></h4>
         <div class="VARIABLELIST">
           <dl>
             <dt>Typical use:</dt>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="FILTER" id="FILTER">8.5.18. filter</a></h4>
+        <h4 class="SECT3"><a name="FILTER" id="FILTER">8.5.19. filter</a></h4>
         <div class="VARIABLELIST">
           <dl>
             <dt>Typical use:</dt>
                   </td>
                 </tr>
               </table>
+              <p><a name="FILTER-BUNDESWEHR.DE" id="FILTER-BUNDESWEHR.DE"></a></p>
+              <table border="0" bgcolor="#E0E0E0" width="90%">
+                <tr>
+                  <td>
+                    <pre class=
+                    "SCREEN">  +filter{bundeswehr.de}      # Hide the cookie and privacy info banner on bundeswehr.de.</pre>
+                  </td>
+                </tr>
+              </table>
               <p><a name="FILTER-GITHUB" id="FILTER-GITHUB"></a></p>
               <table border="0" bgcolor="#E0E0E0" width="90%">
                 <tr>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="FORCE-TEXT-MODE" id="FORCE-TEXT-MODE">8.5.19. force-text-mode</a></h4>
+        <h4 class="SECT3"><a name="FORCE-TEXT-MODE" id="FORCE-TEXT-MODE">8.5.20. force-text-mode</a></h4>
         <div class="VARIABLELIST">
           <dl>
             <dt>Typical use:</dt>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="FORWARD-OVERRIDE" id="FORWARD-OVERRIDE">8.5.20. forward-override</a></h4>
+        <h4 class="SECT3"><a name="FORWARD-OVERRIDE" id="FORWARD-OVERRIDE">8.5.21. forward-override</a></h4>
         <div class="VARIABLELIST">
           <dl>
             <dt>Typical use:</dt>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="HANDLE-AS-EMPTY-DOCUMENT" id="HANDLE-AS-EMPTY-DOCUMENT">8.5.21.
+        <h4 class="SECT3"><a name="HANDLE-AS-EMPTY-DOCUMENT" id="HANDLE-AS-EMPTY-DOCUMENT">8.5.22.
         handle-as-empty-document</a></h4>
         <div class="VARIABLELIST">
           <dl>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="HANDLE-AS-IMAGE" id="HANDLE-AS-IMAGE">8.5.22. handle-as-image</a></h4>
+        <h4 class="SECT3"><a name="HANDLE-AS-IMAGE" id="HANDLE-AS-IMAGE">8.5.23. handle-as-image</a></h4>
         <div class="VARIABLELIST">
           <dl>
             <dt>Typical use:</dt>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="HIDE-ACCEPT-LANGUAGE" id="HIDE-ACCEPT-LANGUAGE">8.5.23.
+        <h4 class="SECT3"><a name="HIDE-ACCEPT-LANGUAGE" id="HIDE-ACCEPT-LANGUAGE">8.5.24.
         hide-accept-language</a></h4>
         <div class="VARIABLELIST">
           <dl>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="HIDE-CONTENT-DISPOSITION" id="HIDE-CONTENT-DISPOSITION">8.5.24.
+        <h4 class="SECT3"><a name="HIDE-CONTENT-DISPOSITION" id="HIDE-CONTENT-DISPOSITION">8.5.25.
         hide-content-disposition</a></h4>
         <div class="VARIABLELIST">
           <dl>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="HIDE-IF-MODIFIED-SINCE" id="HIDE-IF-MODIFIED-SINCE">8.5.25.
+        <h4 class="SECT3"><a name="HIDE-IF-MODIFIED-SINCE" id="HIDE-IF-MODIFIED-SINCE">8.5.26.
         hide-if-modified-since</a></h4>
         <div class="VARIABLELIST">
           <dl>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="HIDE-FROM-HEADER" id="HIDE-FROM-HEADER">8.5.26. hide-from-header</a></h4>
+        <h4 class="SECT3"><a name="HIDE-FROM-HEADER" id="HIDE-FROM-HEADER">8.5.27. hide-from-header</a></h4>
         <div class="VARIABLELIST">
           <dl>
             <dt>Typical use:</dt>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="HIDE-REFERRER" id="HIDE-REFERRER">8.5.27. hide-referrer</a></h4><a name=
+        <h4 class="SECT3"><a name="HIDE-REFERRER" id="HIDE-REFERRER">8.5.28. hide-referrer</a></h4><a name=
         "HIDE-REFERER" id="HIDE-REFERER"></a>
         <div class="VARIABLELIST">
           <dl>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="HIDE-USER-AGENT" id="HIDE-USER-AGENT">8.5.28. hide-user-agent</a></h4>
+        <h4 class="SECT3"><a name="HIDE-USER-AGENT" id="HIDE-USER-AGENT">8.5.29. hide-user-agent</a></h4>
         <div class="VARIABLELIST">
           <dl>
             <dt>Typical use:</dt>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="HTTPS-INSPECTION" id="HTTPS-INSPECTION">8.5.29. https-inspection</a></h4>
+        <h4 class="SECT3"><a name="HTTPS-INSPECTION" id="HTTPS-INSPECTION">8.5.30. https-inspection</a></h4>
         <div class="VARIABLELIST">
           <dl>
             <dt>Typical use:</dt>
               <p>Note that the action has to be enabled based on the CONNECT request which doesn't contain a path.
               Enabling it based on a pattern with path doesn't work as the path is only seen by <span class=
               "APPLICATION">Privoxy</span> if the action is already enabled.</p>
-              <p>This is an experimental feature.</p>
             </dd>
             <dt>Example usage (section):</dt>
             <dd>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="IGNORE-CERTIFICATE-ERRORS" id="IGNORE-CERTIFICATE-ERRORS">8.5.30.
+        <h4 class="SECT3"><a name="IGNORE-CERTIFICATE-ERRORS" id="IGNORE-CERTIFICATE-ERRORS">8.5.31.
         ignore-certificate-errors</a></h4>
         <div class="VARIABLELIST">
           <dl>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="LIMIT-CONNECT" id="LIMIT-CONNECT">8.5.31. limit-connect</a></h4>
+        <h4 class="SECT3"><a name="LIMIT-CONNECT" id="LIMIT-CONNECT">8.5.32. limit-connect</a></h4>
         <div class="VARIABLELIST">
           <dl>
             <dt>Typical use:</dt>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="LIMIT-COOKIE-LIFETIME" id="LIMIT-COOKIE-LIFETIME">8.5.32.
+        <h4 class="SECT3"><a name="LIMIT-COOKIE-LIFETIME" id="LIMIT-COOKIE-LIFETIME">8.5.33.
         limit-cookie-lifetime</a></h4>
         <div class="VARIABLELIST">
           <dl>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="PREVENT-COMPRESSION" id="PREVENT-COMPRESSION">8.5.33. prevent-compression</a></h4>
+        <h4 class="SECT3"><a name="PREVENT-COMPRESSION" id="PREVENT-COMPRESSION">8.5.34. prevent-compression</a></h4>
         <div class="VARIABLELIST">
           <dl>
             <dt>Typical use:</dt>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="OVERWRITE-LAST-MODIFIED" id="OVERWRITE-LAST-MODIFIED">8.5.34.
+        <h4 class="SECT3"><a name="OVERWRITE-LAST-MODIFIED" id="OVERWRITE-LAST-MODIFIED">8.5.35.
         overwrite-last-modified</a></h4>
         <div class="VARIABLELIST">
           <dl>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="REDIRECT" id="REDIRECT">8.5.35. redirect</a></h4>
+        <h4 class="SECT3"><a name="REDIRECT" id="REDIRECT">8.5.36. redirect</a></h4>
         <div class="VARIABLELIST">
           <dl>
             <dt>Typical use:</dt>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="SERVER-HEADER-FILTER" id="SERVER-HEADER-FILTER">8.5.36.
+        <h4 class="SECT3"><a name="SERVER-HEADER-FILTER" id="SERVER-HEADER-FILTER">8.5.37.
         server-header-filter</a></h4>
         <div class="VARIABLELIST">
           <dl>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="SERVER-HEADER-TAGGER" id="SERVER-HEADER-TAGGER">8.5.37.
+        <h4 class="SECT3"><a name="SERVER-HEADER-TAGGER" id="SERVER-HEADER-TAGGER">8.5.38.
         server-header-tagger</a></h4>
         <div class="VARIABLELIST">
           <dl>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="SUPPRESS-TAG" id="SUPPRESS-TAG">8.5.38. suppress-tag</a></h4>
+        <h4 class="SECT3"><a name="SUPPRESS-TAG" id="SUPPRESS-TAG">8.5.39. suppress-tag</a></h4>
         <div class="VARIABLELIST">
           <dl>
             <dt>Typical use:</dt>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="SESSION-COOKIES-ONLY" id="SESSION-COOKIES-ONLY">8.5.39.
+        <h4 class="SECT3"><a name="SESSION-COOKIES-ONLY" id="SESSION-COOKIES-ONLY">8.5.40.
         session-cookies-only</a></h4>
         <div class="VARIABLELIST">
           <dl>
         </div>
       </div>
       <div class="SECT3">
-        <h4 class="SECT3"><a name="SET-IMAGE-BLOCKER" id="SET-IMAGE-BLOCKER">8.5.40. set-image-blocker</a></h4>
+        <h4 class="SECT3"><a name="SET-IMAGE-BLOCKER" id="SET-IMAGE-BLOCKER">8.5.41. set-image-blocker</a></h4>
         <div class="VARIABLELIST">
           <dl>
             <dt>Typical use:</dt>
         </div>
       </div>
       <div class="SECT3">
-        <h3 class="SECT3"><a name="SUMMARY" id="SUMMARY">8.5.41. Summary</a></h3>
+        <h3 class="SECT3"><a name="SUMMARY" id="SUMMARY">8.5.42. Summary</a></h3>
         <p>Note that many of these actions have the potential to cause a page to misbehave, possibly even not to
         display at all. There are many ways a site designer may choose to design his site, and what HTTP header
         content, and other criteria, he may depend on. There is no way to have hard and fast rules for all sites. See
index 7e47f06..7efbff0 100644 (file)
@@ -4,7 +4,7 @@
 <head>
   <title>Appendix</title>
   <meta name="GENERATOR" content="Modular DocBook HTML Stylesheet Version 1.79">
-  <link rel="HOME" title="Privoxy 3.0.33 User Manual" href="index.html">
+  <link rel="HOME" title="Privoxy 3.0.35 User Manual" href="index.html">
   <link rel="PREVIOUS" title="See Also" href="seealso.html">
   <link rel="STYLESHEET" type="text/css" href="../p_doc.css">
   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
@@ -14,7 +14,7 @@
   <div class="NAVHEADER">
     <table summary="Header navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
       <tr>
-        <th colspan="3" align="center">Privoxy 3.0.33 User Manual</th>
+        <th colspan="3" align="center">Privoxy 3.0.35 User Manual</th>
       </tr>
       <tr>
         <td width="10%" align="left" valign="bottom"><a href="seealso.html" accesskey="P">Prev</a></td>
@@ -25,9 +25,9 @@
     <hr align="left" width="100%">
   </div>
   <div class="SECT1">
-    <h1 class="SECT1"><a name="APPENDIX" id="APPENDIX">14. Appendix</a></h1>
+    <h1 class="SECT1"><a name="APPENDIX" id="APPENDIX">15. Appendix</a></h1>
     <div class="SECT2">
-      <h2 class="SECT2"><a name="REGEX" id="REGEX">14.1. Regular Expressions</a></h2>
+      <h2 class="SECT2"><a name="REGEX" id="REGEX">15.1. Regular Expressions</a></h2>
       <p><span class="APPLICATION">Privoxy</span> uses Perl-style <span class="QUOTE">"regular expressions"</span> in
       its <a href="actions-file.html">actions files</a> and <a href="filter-file.html">filter file</a>, through the
       <a href="http://www.pcre.org/" target="_top">PCRE</a> and <span class="APPLICATION">PCRS</span> libraries.</p>
       <a href="filter-file.html">filter file tutorial</a> in this manual.</p>
     </div>
     <div class="SECT2">
-      <h2 class="SECT2"><a name="INTERNAL-PAGES" id="INTERNAL-PAGES">14.2. Privoxy's Internal Pages</a></h2>
+      <h2 class="SECT2"><a name="INTERNAL-PAGES" id="INTERNAL-PAGES">15.2. Privoxy's Internal Pages</a></h2>
       <p>Since <span class="APPLICATION">Privoxy</span> proxies each requested web page, it is easy for <span class=
       "APPLICATION">Privoxy</span> to trap certain special URLs. In this way, we can talk directly to <span class=
       "APPLICATION">Privoxy</span>, and see how it is configured, see how our rules are being applied, change these
       these. If not, you will get a friendly error message. Internet access is not necessary either.</p>
       <ul>
         <li>
-          <p>Privoxy main page:</p><a name="AEN6368" id="AEN6368"></a>
+          <p>Privoxy main page:</p><a name="AEN6566" id="AEN6566"></a>
           <blockquote class="BLOCKQUOTE">
             <p><a href="http://config.privoxy.org/" target="_top">http://config.privoxy.org/</a></p>
           </blockquote>
           "APPLICATION">Privoxy</span>)</p>
         </li>
         <li>
-          <p>View and toggle client tags:</p><a name="AEN6376" id="AEN6376"></a>
+          <p>View and toggle client tags:</p><a name="AEN6574" id="AEN6574"></a>
           <blockquote class="BLOCKQUOTE">
             <p><a href="http://config.privoxy.org/client-tags" target=
             "_top">http://config.privoxy.org/client-tags</a></p>
         </li>
         <li>
           <p>Show information about the current configuration, including viewing and editing of actions
-          files:</p><a name="AEN6381" id="AEN6381"></a>
+          files:</p><a name="AEN6579" id="AEN6579"></a>
           <blockquote class="BLOCKQUOTE">
             <p><a href="http://config.privoxy.org/show-status" target=
             "_top">http://config.privoxy.org/show-status</a></p>
           </blockquote>
         </li>
         <li>
-          <p>Show the browser's request headers:</p><a name="AEN6386" id="AEN6386"></a>
+          <p>Show the browser's request headers:</p><a name="AEN6584" id="AEN6584"></a>
           <blockquote class="BLOCKQUOTE">
             <p><a href="http://config.privoxy.org/show-request" target=
             "_top">http://config.privoxy.org/show-request</a></p>
           </blockquote>
         </li>
         <li>
-          <p>Show which actions apply to a URL and why:</p><a name="AEN6391" id="AEN6391"></a>
+          <p>Show which actions apply to a URL and why:</p><a name="AEN6589" id="AEN6589"></a>
           <blockquote class="BLOCKQUOTE">
             <p><a href="http://config.privoxy.org/show-url-info" target=
             "_top">http://config.privoxy.org/show-url-info</a></p>
         <li>
           <p>Toggle Privoxy on or off. This feature can be turned off/on in the main <tt class="FILENAME">config</tt>
           file. When toggled <span class="QUOTE">"off"</span>, <span class="QUOTE">"Privoxy"</span> continues to run,
-          but only as a pass-through proxy, with no actions taking place:</p><a name="AEN6399" id="AEN6399"></a>
+          but only as a pass-through proxy, with no actions taking place:</p><a name="AEN6597" id="AEN6597"></a>
           <blockquote class="BLOCKQUOTE">
             <p><a href="http://config.privoxy.org/toggle" target="_top">http://config.privoxy.org/toggle</a></p>
           </blockquote>
-          <p>Short cuts. Turn off, then on:</p><a name="AEN6403" id="AEN6403"></a>
+          <p>Short cuts. Turn off, then on:</p><a name="AEN6601" id="AEN6601"></a>
           <blockquote class="BLOCKQUOTE">
             <p><a href="http://config.privoxy.org/toggle?set=disable" target=
             "_top">http://config.privoxy.org/toggle?set=disable</a></p>
-          </blockquote><a name="AEN6406" id="AEN6406"></a>
+          </blockquote><a name="AEN6604" id="AEN6604"></a>
           <blockquote class="BLOCKQUOTE">
             <p><a href="http://config.privoxy.org/toggle?set=enable" target=
             "_top">http://config.privoxy.org/toggle?set=enable</a></p>
       </ul>
     </div>
     <div class="SECT2">
-      <h2 class="SECT2"><a name="CHAIN" id="CHAIN">14.3. Chain of Events</a></h2>
+      <h2 class="SECT2"><a name="CHAIN" id="CHAIN">15.3. Chain of Events</a></h2>
       <p>Let's take a quick look at how some of <span class="APPLICATION">Privoxy's</span> core features are triggered,
       and the ensuing sequence of events when a web page is requested by your browser:</p>
       <ul>
       and simplicity, we have focused on <span class="APPLICATION">Privoxy's</span> core features only.</p>
     </div>
     <div class="SECT2">
-      <h2 class="SECT2"><a name="ACTIONSANAT" id="ACTIONSANAT">14.4. Troubleshooting: Anatomy of an Action</a></h2>
+      <h2 class="SECT2"><a name="ACTIONSANAT" id="ACTIONSANAT">15.4. Troubleshooting: Anatomy of an Action</a></h2>
       <p>The way <span class="APPLICATION">Privoxy</span> applies <a href="actions-file.html#ACTIONS">actions</a> and
       <a href="actions-file.html#FILTER">filters</a> to any given URL can be complex, and not always so easy to
       understand what is happening. And sometimes we need to be able to <span class="emphasis"><i class=
index e5d4703..f540320 100644 (file)
@@ -4,7 +4,7 @@
 <head>
   <title>The Main Configuration File</title>
   <meta name="GENERATOR" content="Modular DocBook HTML Stylesheet Version 1.79">
-  <link rel="HOME" title="Privoxy 3.0.33 User Manual" href="index.html">
+  <link rel="HOME" title="Privoxy 3.0.35 User Manual" href="index.html">
   <link rel="PREVIOUS" title="Privoxy Configuration" href="configuration.html">
   <link rel="NEXT" title="Actions Files" href="actions-file.html">
   <link rel="STYLESHEET" type="text/css" href="../p_doc.css">
@@ -15,7 +15,7 @@
   <div class="NAVHEADER">
     <table summary="Header navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
       <tr>
-        <th colspan="3" align="center">Privoxy 3.0.33 User Manual</th>
+        <th colspan="3" align="center">Privoxy 3.0.35 User Manual</th>
       </tr>
       <tr>
         <td width="10%" align="left" valign="bottom"><a href="configuration.html" accesskey="P">Prev</a></td>
             </dd>
             <dt>Notes:</dt>
             <dd>
-              <p>The value of this option only matters if the experimental trust mechanism has been activated. (See
-              <a href="config.html#TRUSTFILE"><span class="emphasis"><i class="EMPHASIS">trustfile</i></span></a>
-              below.)</p>
+              <p>The value of this option only matters if the trust mechanism has been activated. (See <a href=
+              "config.html#TRUSTFILE"><span class="emphasis"><i class="EMPHASIS">trustfile</i></span></a> below.)</p>
               <p>If you use the trust mechanism, it is a good idea to write up some on-line documentation about your
               trust policy and to specify the URL(s) here. Use multiple times for multiple URLs.</p>
               <p>The URL(s) should be added to the trustfile as well, so users don't end up locked out from the
       </div>
     </div>
     <div class="SECT2">
-      <h2 class="SECT2"><a name="HTTPS-INSPECTION-DIRECTIVES" id="HTTPS-INSPECTION-DIRECTIVES">7.7. HTTPS Inspection
-      (Experimental)</a></h2>
+      <h2 class="SECT2"><a name="HTTPS-INSPECTION-DIRECTIVES" id="HTTPS-INSPECTION-DIRECTIVES">7.7. HTTPS
+      Inspection</a></h2>
       <p>HTTPS inspection allows to filter encrypted requests and responses. This is only supported when <span class=
       "APPLICATION">Privoxy</span> has been built with FEATURE_HTTPS_INSPECTION. If you aren't sure if your version
       supports it, have a look at <a href="http://config.privoxy.org/show-status" target=
             </dd>
             <dt>Default value:</dt>
             <dd>
-              <p><span class="emphasis"><i class="EMPHASIS">Empty string</i></span></p>
+              <p><span class="emphasis"><i class="EMPHASIS">./CA</i></span></p>
             </dd>
             <dt>Effect if unset:</dt>
             <dd>
index 92f55cd..6ef0bf6 100644 (file)
@@ -4,7 +4,7 @@
 <head>
   <title>Privoxy Configuration</title>
   <meta name="GENERATOR" content="Modular DocBook HTML Stylesheet Version 1.79">
-  <link rel="HOME" title="Privoxy 3.0.33 User Manual" href="index.html">
+  <link rel="HOME" title="Privoxy 3.0.35 User Manual" href="index.html">
   <link rel="PREVIOUS" title="Starting Privoxy" href="startup.html">
   <link rel="NEXT" title="The Main Configuration File" href="config.html">
   <link rel="STYLESHEET" type="text/css" href="../p_doc.css">
@@ -15,7 +15,7 @@
   <div class="NAVHEADER">
     <table summary="Header navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
       <tr>
-        <th colspan="3" align="center">Privoxy 3.0.33 User Manual</th>
+        <th colspan="3" align="center">Privoxy 3.0.35 User Manual</th>
       </tr>
       <tr>
         <td width="10%" align="left" valign="bottom"><a href="startup.html" accesskey="P">Prev</a></td>
@@ -40,7 +40,7 @@
         <tr>
           <td>
             <pre class="SCREEN">   </pre>
-            <h2 class="BRIDGEHEAD"><a name="AEN842"></a>&nbsp;&nbsp;&nbsp;&nbsp;Privoxy Menu</h2>
+            <h2 class="BRIDGEHEAD"><a name="AEN874"></a>&nbsp;&nbsp;&nbsp;&nbsp;Privoxy Menu</h2>
             <pre><br></pre>
             <table border="0">
               <tbody>
@@ -69,7 +69,7 @@
                 </tr>
                 <tr>
                   <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&squf;&nbsp;&nbsp;<a href=
-                  "https://www.privoxy.org/3.0.33/user-manual/" target="_top">Documentation</a></td>
+                  "https://www.privoxy.org/3.0.35/user-manual/" target="_top">Documentation</a></td>
                 </tr>
               </tbody>
             </table>
@@ -94,7 +94,8 @@
       <h2 class="SECT2"><a name="CONFOVERVIEW">6.2. Configuration Files Overview</a></h2>
       <p>For Unix, *BSD and GNU/Linux, all configuration files are located in <tt class="FILENAME">/etc/privoxy/</tt>
       by default. For MS Windows these are all in the same directory as the <span class="APPLICATION">Privoxy</span>
-      executable.</p>
+      executable. The name and number of configuration files has changed from previous versions, and is subject to
+      change as development progresses.</p>
       <p>The installed defaults provide a reasonable starting point, though some settings may be aggressive by some
       standards. For the time being, the principle configuration files are:</p>
       <ul>
       listening address of <span class="APPLICATION">Privoxy</span>, these <span class="QUOTE">"wake up"</span>
       requests must obviously be sent to the <span class="emphasis"><i class="EMPHASIS">old</i></span> listening
       address.</p>
+      <p>While under development, the configuration content is subject to change. The below documentation may not be
+      accurate by the time you read this. Also, what constitutes a <span class="QUOTE">"default"</span> setting, may
+      change, so please check all your configuration files on important issues.</p>
     </div>
   </div>
   <div class="NAVFOOTER">
index 790331f..32e6813 100644 (file)
@@ -4,8 +4,8 @@
 <head>
   <title>Contacting the Developers, Bug Reporting and Feature Requests</title>
   <meta name="GENERATOR" content="Modular DocBook HTML Stylesheet Version 1.79">
-  <link rel="HOME" title="Privoxy 3.0.33 User Manual" href="index.html">
-  <link rel="PREVIOUS" title="Privoxy's Template Files" href="templates.html">
+  <link rel="HOME" title="Privoxy 3.0.35 User Manual" href="index.html">
+  <link rel="PREVIOUS" title="HOWTOs" href="howto.html">
   <link rel="NEXT" title="Privoxy Copyright, License and History" href="copyright.html">
   <link rel="STYLESHEET" type="text/css" href="../p_doc.css">
   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
   <div class="NAVHEADER">
     <table summary="Header navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
       <tr>
-        <th colspan="3" align="center">Privoxy 3.0.33 User Manual</th>
+        <th colspan="3" align="center">Privoxy 3.0.35 User Manual</th>
       </tr>
       <tr>
-        <td width="10%" align="left" valign="bottom"><a href="templates.html" accesskey="P">Prev</a></td>
+        <td width="10%" align="left" valign="bottom"><a href="howto.html" accesskey="P">Prev</a></td>
         <td width="80%" align="center" valign="bottom"></td>
         <td width="10%" align="right" valign="bottom"><a href="copyright.html" accesskey="N">Next</a></td>
       </tr>
     <hr align="left" width="100%">
   </div>
   <div class="SECT1">
-    <h1 class="SECT1"><a name="CONTACT" id="CONTACT">11. Contacting the Developers, Bug Reporting and Feature
+    <h1 class="SECT1"><a name="CONTACT" id="CONTACT">12. Contacting the Developers, Bug Reporting and Feature
     Requests</a></h1>
     <p>We value your feedback. In fact, we rely on it to improve <span class="APPLICATION">Privoxy</span> and its
     configuration. However, please note the following hints, so we can provide you with the best support.</p>
     <div class="SECT2">
-      <h2 class="SECT2"><a name="SUFFICIENT-INFORMATION" id="SUFFICIENT-INFORMATION">11.1. Please provide sufficient
+      <h2 class="SECT2"><a name="SUFFICIENT-INFORMATION" id="SUFFICIENT-INFORMATION">12.1. Please provide sufficient
       information</a></h2>
       <p>A lot of support requests don't contain enough information and can't be solved without a lot of back and forth
       which causes unnecessary delays. Reading this section should help to prevent that.</p>
       <tt class="LITERAL">action</tt> debugging.</p>
     </div>
     <div class="SECT2">
-      <h2 class="SECT2"><a name="CONTACT-SUPPORT" id="CONTACT-SUPPORT">11.2. Get Support</a></h2>
+      <h2 class="SECT2"><a name="CONTACT-SUPPORT" id="CONTACT-SUPPORT">12.2. Get Support</a></h2>
       <p>All users are welcome to discuss their issues on the <a href=
       "https://lists.privoxy.org/mailman/listinfo/privoxy-users" target="_top">users mailing list</a>, where the
       developers also hang around.</p>
       mailing list only, and you won't see them.</p>
     </div>
     <div class="SECT2">
-      <h2 class="SECT2"><a name="REPORTING" id="REPORTING">11.3. Reporting Problems</a></h2>
+      <h2 class="SECT2"><a name="REPORTING" id="REPORTING">12.3. Reporting Problems</a></h2>
       <p><span class="QUOTE">"Problems"</span> for our purposes, come in two forms:</p>
       <ul>
         <li>
         </li>
       </ul>
       <div class="SECT3">
-        <h3 class="SECT3"><a name="CONTACT-ADS" id="CONTACT-ADS">11.3.1. Reporting Ads or Other Configuration
+        <h3 class="SECT3"><a name="CONTACT-ADS" id="CONTACT-ADS">12.3.1. Reporting Ads or Other Configuration
         Problems</a></h3>
         <p>Please send feedback on ads that slipped through, innocent images that were blocked, sites that don't work
         properly, and other configuration related problem of <tt class="FILENAME">default.action</tt> file, to <a href=
         "_top">https://sourceforge.net/p/ijbswa/actionsfile-feedback/</a>, the Actions File Tracker.</p>
       </div>
       <div class="SECT3">
-        <h3 class="SECT3"><a name="CONTACT-BUGS" id="CONTACT-BUGS">11.3.2. Reporting Bugs</a></h3>
+        <h3 class="SECT3"><a name="CONTACT-BUGS" id="CONTACT-BUGS">12.3.2. Reporting Bugs</a></h3>
         <p>Before reporting bugs, please make sure that the bug has <span class="emphasis"><i class="EMPHASIS">not
         already been submitted</i></span> and observe the additional hints at the top of the <a href=
         "https://sourceforge.net/p/ijbswa/bugs/" target="_top">submit form</a>. If already submitted, please feel free
       </div>
     </div>
     <div class="SECT2">
-      <h2 class="SECT2"><a name="SECURITY-CONTACT" id="SECURITY-CONTACT">11.4. Reporting security problems</a></h2>
+      <h2 class="SECT2"><a name="SECURITY-CONTACT" id="SECURITY-CONTACT">12.4. Reporting security problems</a></h2>
       <p>If you discovered a security problem or merely suspect that a bug might be a security issue, please mail
       Fabian Keil &lt;fk@fabiankeil.de&#62; (OpenPGP fingerprint: 4F36 C17F 3816 9136 54A1 E850 6918 2291 8BA2
       371C).</p>
       didn't make it. If that happens, please mail to the developer list to request a status update.</p>
     </div>
     <div class="SECT2">
-      <h2 class="SECT2"><a name="MAILING-LISTS" id="MAILING-LISTS">11.5. Mailing Lists</a></h2>
+      <h2 class="SECT2"><a name="MAILING-LISTS" id="MAILING-LISTS">12.5. Mailing Lists</a></h2>
       <p>If you prefer to communicate through email, instead of using a web interface, feel free to use one of the
       mailing lists. To discuss issues that haven't been completely diagnosed yet, please use the Privoxy users list.
       Technically interested users and people who wish to contribute to the project are always welcome on the
       "https://sourceforge.net/p/ijbswa/mailman/" target="_top">https://sourceforge.net/p/ijbswa/mailman/</a>.</p>
     </div>
     <div class="SECT2">
-      <h2 class="SECT2"><a name="SF-TRACKERS" id="SF-TRACKERS">11.6. SourceForge support trackers</a></h2>
+      <h2 class="SECT2"><a name="SF-TRACKERS" id="SF-TRACKERS">12.6. SourceForge support trackers</a></h2>
       <p>The <a href="https://sourceforge.net/p/ijbswa/support-requests/" target="_top">SourceForge support
       trackers</a> may be used as well, but have various technical problems that are unlikely to be fixed anytime soon.
       If you don't get a timely response, please try the mailing list as well.</p>
     <hr align="left" width="100%">
     <table summary="Footer navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
       <tr>
-        <td width="33%" align="left" valign="top"><a href="templates.html" accesskey="P">Prev</a></td>
+        <td width="33%" align="left" valign="top"><a href="howto.html" accesskey="P">Prev</a></td>
         <td width="34%" align="center" valign="top"><a href="index.html" accesskey="H">Home</a></td>
         <td width="33%" align="right" valign="top"><a href="copyright.html" accesskey="N">Next</a></td>
       </tr>
       <tr>
-        <td width="33%" align="left" valign="top">Privoxy's Template Files</td>
+        <td width="33%" align="left" valign="top">HOWTOs</td>
         <td width="34%" align="center" valign="top">&nbsp;</td>
         <td width="33%" align="right" valign="top">Privoxy Copyright, License and History</td>
       </tr>
index a3dd365..d40237c 100644 (file)
@@ -4,7 +4,7 @@
 <head>
   <title>Privoxy Copyright, License and History</title>
   <meta name="GENERATOR" content="Modular DocBook HTML Stylesheet Version 1.79">
-  <link rel="HOME" title="Privoxy 3.0.33 User Manual" href="index.html">
+  <link rel="HOME" title="Privoxy 3.0.35 User Manual" href="index.html">
   <link rel="PREVIOUS" title="Contacting the Developers, Bug Reporting and Feature Requests" href="contact.html">
   <link rel="NEXT" title="See Also" href="seealso.html">
   <link rel="STYLESHEET" type="text/css" href="../p_doc.css">
@@ -15,7 +15,7 @@
   <div class="NAVHEADER">
     <table summary="Header navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
       <tr>
-        <th colspan="3" align="center">Privoxy 3.0.33 User Manual</th>
+        <th colspan="3" align="center">Privoxy 3.0.35 User Manual</th>
       </tr>
       <tr>
         <td width="10%" align="left" valign="bottom"><a href="contact.html" accesskey="P">Prev</a></td>
     <hr align="left" width="100%">
   </div>
   <div class="SECT1">
-    <h1 class="SECT1"><a name="COPYRIGHT">12. Privoxy Copyright, License and History</a></h1>
-    <p>Copyright &copy; 2001-2021 by Privoxy Developers <code class="EMAIL">&#60;<a href=
+    <h1 class="SECT1"><a name="COPYRIGHT">13. Privoxy Copyright, License and History</a></h1>
+    <p>Copyright &copy; 2001-2023 by Privoxy Developers <code class="EMAIL">&#60;<a href=
     "mailto:privoxy-devel@lists.privoxy.org">privoxy-devel@lists.privoxy.org</a>&#62;</code></p>
     <p>Some source code is based on code Copyright &copy; 1997 by Anonymous Coders and Junkbusters, Inc.</p>
     <p><span class="APPLICATION">Privoxy</span> is free software; you can redistribute and/or modify its source code
     under the terms of the <i class="CITETITLE">GNU General Public License</i> as published by the Free Software
     Foundation, either version 2 of the license, or (at your option) any later version.</p>
     <p>The same is true for <span class="APPLICATION">Privoxy</span> binaries unless they are linked with a <a href=
-    "https://tls.mbed.org/" target="_top">mbed TLS</a> version that is licensed under the Apache 2.0 license in which
-    case you can redistribute and/or modify the <span class="APPLICATION">Privoxy</span> binaries under the terms of
-    the <i class="CITETITLE">GNU General Public License</i> as published by the Free Software Foundation, either
-    version 3 of the license, or (at your option) any later version.</p>
+    "https://www.trustedfirmware.org/projects/mbed-tls/" target="_top">mbed TLS</a> version that is licensed under the
+    Apache 2.0 license in which case you can redistribute and/or modify the <span class="APPLICATION">Privoxy</span>
+    binaries under the terms of the <i class="CITETITLE">GNU General Public License</i> as published by the Free
+    Software Foundation, either version 3 of the license, or (at your option) any later version.</p>
     <p>Both licenses are included in the next section.</p>
     <div class="SECT2">
-      <h2 class="SECT2"><a name="LICENSE">12.1. License</a></h2>
+      <h2 class="SECT2"><a name="LICENSE">13.1. License</a></h2>
       <div class="SECT3">
-        <h3 class="SECT3"><a name="GPLV2">12.1.1. GNU General Public License version 2</a></h3>
+        <h3 class="SECT3"><a name="GPLV2">13.1.1. GNU General Public License version 2</a></h3>
         <table border="0" bgcolor="#E0E0E0" width="100%">
           <tr>
             <td>
@@ -391,7 +391,7 @@ Public License instead of this License.
         </table>
       </div>
       <div class="SECT3">
-        <h3 class="SECT3"><a name="GPLV3">12.1.2. GNU General Public License version 3</a></h3>
+        <h3 class="SECT3"><a name="GPLV3">13.1.2. GNU General Public License version 3</a></h3>
         <table border="0" bgcolor="#E0E0E0" width="100%">
           <tr>
             <td>
@@ -1075,21 +1075,22 @@ Public License instead of this License.  But first, please read
         </table>
       </div>
       <div class="SECT3">
-        <h3 class="SECT3"><a name="THIRD-PARTY-LICENSES">12.1.3. Third-party licenses and copyrights</a></h3>
+        <h3 class="SECT3"><a name="THIRD-PARTY-LICENSES">13.1.3. Third-party licenses and copyrights</a></h3>
         <p>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.</p>
         <p>Privoxy depends on <a href="https://pcre.org/" target="_top">pcre</a>.</p>
         <p>When compiled with FEATURE_BROTLI (optional), Privoxy depends on <a href="https://www.brotli.org/" target=
         "_top">brotli</a>.</p>
         <p>When compiled with FEATURE_HTTPS_INSPECTION (optional), Privoxy depends on a TLS library. The supported
-        libraries are <a href="https://www.openssl.org/" target="_top">LibreSSL</a>, <a href="https://tls.mbed.org/"
-        target="_top">mbed TLS</a> and <a href="https://www.openssl.org/" target="_top">OpenSSL</a>.</p>
+        libraries are <a href="https://www.openssl.org/" target="_top">LibreSSL</a>, <a href=
+        "https://github.com/Mbed-TLS/mbedtls/tags" target="_top">mbed TLS 2.28.x</a> and <a href=
+        "https://www.openssl.org/" target="_top">OpenSSL</a>.</p>
         <p>When compiled with FEATURE_ZLIB (optional), Privoxy depends on <a href="https://zlib.net/" target=
         "_top">zlib</a>.</p>
       </div>
     </div>
     <div class="SECT2">
-      <h2 class="SECT2"><a name="HISTORY">12.2. History</a></h2>
+      <h2 class="SECT2"><a name="HISTORY">13.2. History</a></h2>
       <p>A long time ago, there was the <span class="APPLICATION">Internet Junkbuster</span>, by Anonymous Coders and
       Junkbusters Corporation. This saved many users a lot of pain in the early days of web advertising and user
       tracking.</p>
@@ -1114,7 +1115,7 @@ Public License instead of this License.  But first, please read
       is still actively maintained.</p>
     </div>
     <div class="SECT2">
-      <h2 class="SECT2"><a name="AUTHORS">12.3. Authors</a></h2>
+      <h2 class="SECT2"><a name="AUTHORS">13.3. Authors</a></h2>
       <p>Current Privoxy Team:</p>
       <p class="LITERALLAYOUT">&nbsp;Fabian&nbsp;Keil,&nbsp;lead&nbsp;developer<br>
       &nbsp;David&nbsp;Schmidt<br>
@@ -1158,6 +1159,7 @@ Public License instead of this License.  But first, please read
       &nbsp;Anatoly&nbsp;Arzhnikov<br>
       &nbsp;Ken&nbsp;Arromdee<br>
       &nbsp;Natxo&nbsp;Asenjo<br>
+      &nbsp;avoidr<br>
       &nbsp;Devin&nbsp;Bayer<br>
       &nbsp;Havard&nbsp;Berland<br>
       &nbsp;David&nbsp;Binderman<br>
@@ -1170,6 +1172,8 @@ Public License instead of this License.  But first, please read
       &nbsp;Andrew&nbsp;J.&nbsp;Caines<br>
       &nbsp;Clifford&nbsp;Caoile<br>
       &nbsp;Edward&nbsp;Carrel<br>
+      &nbsp;Celejar<br>
+      &nbsp;Chakib&nbsp;Benziane<br>
       &nbsp;Pak&nbsp;Chan<br>
       &nbsp;Wan-Teh&nbsp;Chang<br>
       &nbsp;Sam&nbsp;Chen<br>
@@ -1274,6 +1278,7 @@ Public License instead of this License.  But first, please read
       &nbsp;Andreas&nbsp;Rutkauskas<br>
       &nbsp;Sam<br>
       &nbsp;Saperski<br>
+      &nbsp;Andrew&nbsp;Savchenko<br>
       &nbsp;Bart&nbsp;Schelstraete<br>
       &nbsp;Richard&nbsp;Schneidt<br>
       &nbsp;Gregory&nbsp;Seidman<br>
index d89138d..8b625a8 100644 (file)
@@ -4,7 +4,7 @@
 <head>
   <title>Filter Files</title>
   <meta name="GENERATOR" content="Modular DocBook HTML Stylesheet Version 1.79">
-  <link rel="HOME" title="Privoxy 3.0.33 User Manual" href="index.html">
+  <link rel="HOME" title="Privoxy 3.0.35 User Manual" href="index.html">
   <link rel="PREVIOUS" title="Actions Files" href="actions-file.html">
   <link rel="NEXT" title="Privoxy's Template Files" href="templates.html">
   <link rel="STYLESHEET" type="text/css" href="../p_doc.css">
@@ -15,7 +15,7 @@
   <div class="NAVHEADER">
     <table summary="Header navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
       <tr>
-        <th colspan="3" align="center">Privoxy 3.0.33 User Manual</th>
+        <th colspan="3" align="center">Privoxy 3.0.35 User Manual</th>
       </tr>
       <tr>
         <td width="10%" align="left" valign="bottom"><a href="actions-file.html" accesskey="P">Prev</a></td>
@@ -36,8 +36,9 @@
     "actions-file.html#SERVER-HEADER-FILTER">server-header-filter</a></tt> to rewrite headers that are send by the
     server, and <tt class="LITERAL"><a href="actions-file.html#CLIENT-BODY-FILTER">client-body-filter</a></tt> to
     rewrite client request body.</p>
-    <p><span class="APPLICATION">Privoxy</span> also supports two tagger actions: <tt class="LITERAL"><a href=
-    "actions-file.html#CLIENT-HEADER-TAGGER">client-header-tagger</a></tt> and <tt class="LITERAL"><a href=
+    <p><span class="APPLICATION">Privoxy</span> also supports three tagger actions: <tt class="LITERAL"><a href=
+    "actions-file.html#CLIENT-HEADER-TAGGER">client-header-tagger</a></tt>, <tt class="LITERAL"><a href=
+    "actions-file.html#CLIENT-BODY-TAGGER">client-body-tagger</a></tt> and <tt class="LITERAL"><a href=
     "actions-file.html#SERVER-HEADER-TAGGER">server-header-tagger</a></tt>. 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
           </dd>
           <dt><span class="emphasis"><i class="EMPHASIS">banners-by-link</i></span></dt>
           <dd>
-            <p>This is an experimental filter that attempts to kill any banners if their URLs seem to point to known or
-            suspected click trackers. It is currently not of much value and is not recommended for use by default.</p>
+            <p>This filter attempts to kill any banners if their URLs seem to point to known or suspected click
+            trackers. It is currently not of much value and is not recommended for use by default.</p>
           </dd>
           <dt><span class="emphasis"><i class="EMPHASIS">webbugs</i></span></dt>
           <dd>
diff --git a/doc/webserver/user-manual/howto.html b/doc/webserver/user-manual/howto.html
new file mode 100644 (file)
index 0000000..f33daee
--- /dev/null
@@ -0,0 +1,277 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+"http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+  <title>HOWTOs</title>
+  <meta name="GENERATOR" content="Modular DocBook HTML Stylesheet Version 1.79">
+  <link rel="HOME" title="Privoxy 3.0.35 User Manual" href="index.html">
+  <link rel="PREVIOUS" title="Privoxy's Template Files" href="templates.html">
+  <link rel="NEXT" title="Contacting the Developers, Bug Reporting and Feature Requests" href="contact.html">
+  <link rel="STYLESHEET" type="text/css" href="../p_doc.css">
+  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+  <link rel="STYLESHEET" type="text/css" href="p_doc.css">
+</head>
+<body class="SECT1" bgcolor="#EEEEEE" text="#000000" link="#0000FF" vlink="#840084" alink="#0000FF">
+  <div class="NAVHEADER">
+    <table summary="Header navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
+      <tr>
+        <th colspan="3" align="center">Privoxy 3.0.35 User Manual</th>
+      </tr>
+      <tr>
+        <td width="10%" align="left" valign="bottom"><a href="templates.html" accesskey="P">Prev</a></td>
+        <td width="80%" align="center" valign="bottom"></td>
+        <td width="10%" align="right" valign="bottom"><a href="contact.html" accesskey="N">Next</a></td>
+      </tr>
+    </table>
+    <hr align="left" width="100%">
+  </div>
+  <div class="SECT1">
+    <h1 class="SECT1"><a name="HOWTO" id="HOWTO">11. HOWTOs</a></h1>
+    <div class="SECT2">
+      <h2 class="SECT2"><a name="H2-HTTPS-INSPECTION" id="H2-HTTPS-INSPECTION">11.1. HTTPS-Inspection HOWTO</a></h2>
+      <div class="SECT3">
+        <h3 class="SECT3"><a name="H2-HI-TLS" id="H2-HI-TLS">11.1.1. How TLS Certificates for websites work</a></h3>
+        <p>The website owner generates a (private) TLS key and a Certificate Signing Request (CSR).</p>
+        <p>The CSR is then sent to a Certification Authority (CA), which verifies that the owner is the actual owner of
+        the website. This can be done by proving that the owner has technical write access to the site or the site's
+        DNS, or by verifying the identity of the organization running the site using telephone and public
+        databases.</p>
+        <p>If the verification is successful, the CA signs the CSR and creates a certificate that certifies that the
+        private TLS key actually belongs to the website name and/or organization that owns the domain.</p>
+        <p>This TLS certificate is then added to the web server configuration, and when a browser accesses the website,
+        it verifies that the TLS certificate presented to the browser is valid for that domain.</p>
+        <p>To do this, each browser has the certificates of multiple CAs in its trust store. Only if the certificate of
+        the CA, that signed the web server is in the trust store, the browser will accept the certificate, otherwise
+        the browser will complain about a broken certificate.</p>
+        <p>If this check passes, the browser sends a random number encrypted with the server's public key to the
+        server, and both compute a shared secret using the Diffie-Hellman key exchange algorithm. Now server and
+        browser can communicate, but no one else can break that communication because it's encrypted between them.</p>
+      </div>
+      <div class="SECT3">
+        <h3 class="SECT3"><a name="H2-HI-WORKS" id="H2-HI-WORKS">11.1.2. How HTTPS inspection works</a></h3>
+        <p>When we try to inspect HTTPS traffic, we have to break the TLS encryption between browser and web server
+        without being the browser or the web server. This is exactly what TLS tries to avoid, as it's a
+        man-in-the-middle-attack.</p>
+        <p>To do this, Privoxy uses it's own (private) CA (let's call it "Privoxy CA"), which has to be added to the
+        trust store of every single browser that should be used with Privoxy and HTTPS inspection.</p>
+        <p>Now Privoxy breaks the connection between browser and webserver by acting as a browser/client when talking
+        to the webserver (including checking the webserver's TLS certificate against it's own trust store). Now Privoxy
+        can read and modify the traffic from the webserver.</p>
+        <p>On the other hand, Privoxy itself encrypts the traffic it sends to the browser using an on the fly
+        self-created TLS server certificate that is signed by Privoxy CA.</p>
+      </div>
+      <div class="SECT3">
+        <h3 class="SECT3"><a name="H2-HI-INVALID-CERT" id="H2-HI-INVALID-CERT">11.1.3. What happens, if the original
+        certificate is invalid?</a></h3>
+        <p>If Privoxy detects, that a TLS certificate is not valid, because the certificate is expired, doesn't match
+        the hostname, is self signed or similar, Privoxy blocks the requests and returns an error message explaining
+        the problem to avoid that the user/browser communicates over an insecure communication channel.</p>
+        <p>To check this behavior, simply go to <a href="https://badssl.com/" target="_top">https://badssl.com/</a></p>
+      </div>
+      <div class="SECT3">
+        <h3 class="SECT3"><a name="H2-HI-PREREQUISITES" id="H2-HI-PREREQUISITES">11.1.4. HTTPS inspection
+        prerequisites</a></h3>
+        <p>HTTPS inspection in Privoxy can only be used, if Privoxy is built with FEATURE_HTTPS_INSPECTION. You can
+        check if this feature is enabled at <a href="http://config.privoxy.org/show-status" target=
+        "_top">http://config.privoxy.org/show-status</a> in the "Conditional #defines" section.</p>
+        <p>If the feature is not enabled, you may need to <a href="installation.html#INSTALLATION-SOURCE">build Privoxy
+        from source</a> to enable it. You can use either <a href="https://www.trustedfirmware.org/projects/mbed-tls/"
+        target="_top">MbedTLS</a> or <a href="https://www.openssl.org/" target="_top">OpenSSL</a>. It's up to you,
+        which one to use, they both behave the same for HTTPS inspection.</p>
+        <p>After installing the development libraries for either OpenSSL or MbedTLS, you can run <b class=
+        "COMMAND">./configure</b> with either the <b class="COMMAND">--with-openssl</b> or <b class=
+        "COMMAND">--with-mbedtls</b> option.</p>
+        <p>Check the output of <b class="COMMAND">./configure</b>, it must contain one of these the following two
+        lines, otherwise HTTPS inspection will not work:</p>
+        <table border="0" bgcolor="#E0E0E0" width="100%">
+          <tr>
+            <td>
+              <pre class="SCREEN">  configure: Detected OpenSSL. Enabling https inspection.
+  configure: Detected mbedTLS. Enabling https inspection.</pre>
+            </td>
+          </tr>
+        </table>
+        <p>If you do not find any of these lines, the output of <b class="COMMAND">./configure</b> will tell you what
+        went wrong.</p>
+        <p>You should then proceed with the <a href="installation.html#INSTALLATION-SOURCE">source install</a>.
+        Finally, check the FEATURE_HTTPS_INSPECTION status in <a href="http://config.privoxy.org/show-status" target=
+        "_top">http://config.privoxy.org/show-status</a> again.</p>
+      </div>
+      <div class="SECT3">
+        <h3 class="SECT3"><a name="H2-HI-CONFIG" id="H2-HI-CONFIG">11.1.5. Configuring HTTPS inspection in
+        Privoxy</a></h3>
+        <p>First, you need to create the private key and certificate for the "Privoxy CA". This can be done using
+        openssl with the following command:</p>
+        <table border="0" bgcolor="#E0E0E0" width="100%">
+          <tr>
+            <td>
+              <pre class=
+              "SCREEN">  openssl req -new -x509 -extensions v3_ca -keyout privoxy.pem -out privoxy.crt -days 3650</pre>
+            </td>
+          </tr>
+        </table>
+        <p>Here we have defined a CA validity of 10 years (3650 days). You should decide for yourself what is a good
+        validity. A shorter validity makes your system more secure (it doesn't hurt that long if the key gets lost to
+        an attacker), but if the certificate expires before you have replaced it with a new one in Privoxy and in all
+        browsers, the communication will fail.</p>
+        <p>During the key generation you will be asked for a "pass phrase". This pass phrase will appear in the Privoxy
+        config CGI, so don't reuse it elsewhere!</p>
+        <p>Then you will be asked for Country Name, State/Province, Locality, Orginzation Name, Common Name, and Email
+        Address. You should add some useful data here, because these entries are shown by the browser as "Issuer Name"
+        when you inspect a certificate from an https-inspection site. Especially the "Common Name" will be shown as the
+        name of your CA, so it's good if you (and other users of your Privoxy instance) are able to identify this
+        CA.</p>
+        <p>Copy the private key (<tt class="FILENAME">privoxy.pem</tt>) and the CA certificate (<tt class=
+        "FILENAME">privoxy.crt</tt>) into the <a href="config.html#CA-DIRECTORY">ca-directory</a> (defined in <a href=
+        "config.html">config</a>).</p>
+        <p>Make sure that the private key (<tt class="FILENAME">privoxy.pem</tt> in the above example) is only
+        accessible to the user running Privoxy (usually named "privoxy"):</p>
+        <table border="0" bgcolor="#E0E0E0" width="100%">
+          <tr>
+            <td>
+              <pre class="SCREEN">  chmod 600 privoxy.pem
+  chown privoxy privoxy.pem</pre>
+            </td>
+          </tr>
+        </table>
+        <p>Now adjust your Privoxy <a href="config.html">configuration</a>:</p>
+        <table border="0" bgcolor="#E0E0E0" width="100%">
+          <tr>
+            <td>
+              <pre class="SCREEN">  <a href="config.html#CA-DIRECTORY">ca-directory</a> /etc/privoxy/CA # read-only
+  <a href="config.html#CA-CERT-FILE">ca-cert-file</a> privoxy.crt     # in ca-directory
+  <a href="config.html#CA-KEY-FILE">ca-key-file</a> privoxy.pem      # in ca-directory
+  <a href="config.html#CA-PASSWORD">ca-password</a> passphrasefromabove
+  <a href="config.html#CERTIFICATE-DIRECTORY">certificate-directory</a> /var/lib/privoxy/certs
+  <a href="config.html#TRUSTED-CAS-FILE">trusted-cas-file</a> /etc/ssl/certs/ca-certificates.crt</pre>
+            </td>
+          </tr>
+        </table>
+        <p><a href="config.html#CERTIFICATE-DIRECTORY">certificate-directory</a> contains the (on the fly) created
+        webserver keys and certificates. It should only be readable by the privoxy user only:</p>
+        <table border="0" bgcolor="#E0E0E0" width="100%">
+          <tr>
+            <td>
+              <pre class="SCREEN">  chown privoxy /var/lib/privoxy/certs
+  chmod 700 /var/lib/privoxy/certs.</pre>
+            </td>
+          </tr>
+        </table>
+        <p><a href="config.html#TRUSTED-CAS-FILE">trusted-cas-file</a> is the trust store containing the certificates
+        of all CAs that should be accepted. Each browser comes with it's own trust store. Most Unix systems also ship
+        with a truststore. Debian ships it's truststore in <tt class=
+        "FILENAME">/etc/ssl/certs/ca-certificates.crt</tt>, which is installed by the ca-certificates package and can
+        be updated using update-ca-certificates(8). Alternatively, such a file (extracted from Mozilla) can be
+        downloaded from <a href="https://curl.se/docs/caextract.html" target=
+        "_top">https://curl.se/docs/caextract.html</a>.</p>
+      </div>
+      <div class="SECT3">
+        <h3 class="SECT3"><a name="H2-HI-BROWSER" id="H2-HI-BROWSER">11.1.6. Browser configuration</a></h3>
+        <p>As written above, each browser you use must now trust the newly created Privoxy CA certificate (<tt class=
+        "FILENAME">privoxy.crt</tt>).</p>
+        <p>In Firefox you can do this by opening the preferences "Edit" -&#62; "Settings" -&#62; "Privacy &#38;
+        Security" or by typing <a href="about:preferences#privacy" target="_top">about:preferences#privacy</a> in the
+        URL. Then go down to the "Certificates" section and click on "View Certificates". Click on the "Authorities"
+        tab and "Import..." your <tt class="FILENAME">privoxy.crt</tt>. In the "CA certificate trust settings" select
+        "This certificate can identify websites".</p>
+        <p>In Chrome based browsers, go to the settings and select "Privacy and security" (<a href=
+        "chrome://settings/privacy" target="_top">chrome://settings/privacy</a>). Click on "Security" and on the opened
+        sub-page on "Manage certificates". Now go to the "Authorities" tab and import <tt class=
+        "FILENAME">privoxy.crt</tt> and configure that you trust the certificate for website identification.</p>
+      </div>
+      <div class="SECT3">
+        <h3 class="SECT3"><a name="H2-HI-ENABLE" id="H2-HI-ENABLE">11.1.7. Enabeling HTTPS inspection</a></h3>
+        <p>Currently no pages use HTTPS inspection, you need to enable this for some (or all) domains first using
+        <a href="actions-file.html#USER-ACTION">user.action</a> (either by editing the file by hand or via the CGI
+        (this requires <a href="config.html#ENABLE-EDIT-ACTIONS">enable-edit-actions</a> to be enabled in config) at
+        <a href="http://config.privoxy.org/show-status" target="_top">http://config.privoxy.org/show-status</a> (click
+        on user.action Edit button).</p>
+        <p>Here you can enable HTTPS inspection for individual sites:</p>
+        <table border="0" bgcolor="#E0E0E0" width="100%">
+          <tr>
+            <td>
+              <pre class="SCREEN">  {+<a href="actions-file.html#HTTPS-INSPECTION">https-inspection</a>}
+  .badssl.com
+  clienttest.ssllabs.com</pre>
+            </td>
+          </tr>
+        </table>
+        <p>You can add more individual sites or wildcards (one per line).</p>
+        <p>Alternatively, you can use a client-tag to dynamically enable/disable this feature via the browser, as
+        described in the next chapter.</p>
+      </div>
+    </div>
+    <div class="SECT2">
+      <h2 class="SECT2"><a name="H2-CLIENT-TAGS" id="H2-CLIENT-TAGS">11.2. Client Tags HOWTO</a></h2>
+      <p>Client-Tags are a mechanism to dynamically/temporarily enable/disable features in Privoxy per browser.</p>
+      <p>In our example, we use this for the following two use cases:</p>
+      <ul>
+        <li>
+          <p>Enable TOR anonymous proxy</p>
+        </li>
+        <li>
+          <p>Enable https-inspection</p>
+        </li>
+      </ul>
+      <p>To use this feature, you must first define a tag name and a tag description for each client-tag in <a href=
+      "config.html">config</a>, like this:</p>
+      <table border="0" bgcolor="#E0E0E0" width="100%">
+        <tr>
+          <td>
+            <pre class="SCREEN">  <a href=
+            "config.html#CLIENT-SPECIFIC-TAG">client-specific-tag</a> tor Use Tor anonymous proxy
+  <a href="config.html#CLIENT-SPECIFIC-TAG">client-specific-tag</a> https-inspection Enable https-inspection</pre>
+          </td>
+        </tr>
+      </table>
+      <p>Now you can open <a href="http://config.privoxy.org/client-tags" target=
+      "_top">http://config.privoxy.org/client-tags</a> or <a href="http://p.p/client-tags" target=
+      "_top">http://p.p/client-tags</a> and can enable/disable the tag there (you may want to add a bookmark for this
+      in your browser for quick access, but it's also available as a link at <a href="http://p.p" target=
+      "_top">http://p.p</a>).</p>
+      <p>It's also possible to temporarily enable a tag, which by default means 3 minutes (=180 seconds) (and can be
+      changed via the <a href="config.html#CLIENT-TAG-LIFETIME">client-tag-lifetime</a> option in <a href=
+      "config.html">config</a>).</p>
+      <p>But before this has any effect, you have to use the client tag in your <a href=
+      "actions-file.html#USER-ACTION">user.action</a> like this:</p>
+      <table border="0" bgcolor="#E0E0E0" width="100%">
+        <tr>
+          <td>
+            <pre class="SCREEN">  {+<a href="actions-file.html#FORWARD-OVERRIDE">forward-override</a>{<a href=
+            "config.html#SOCKS">forward-socks5t</a> 127.0.0.1:9050 .} }
+  <a href="actions-file.html#CLIENT-TAG-PATTERN">CLIENT-TAG</a>:^tor$</pre>
+          </td>
+        </tr>
+      </table>
+      <p>This means, that if the "tor" client tag is enabled, all traffic is forwarded by Privoxy through socks5t to a
+      locally installed tor proxy listening on port 9050.</p>
+      <p>Similarly, you can specify to use the https-inspection client tag to enable https-inspection:</p>
+      <table border="0" bgcolor="#E0E0E0" width="100%">
+        <tr>
+          <td>
+            <pre class="SCREEN">  {+<a href="actions-file.html#HTTPS-INSPECTION">https-inspection</a>}
+  <a href="actions-file.html#CLIENT-TAG-PATTERN">CLIENT-TAG</a>:^https-inspection$</pre>
+          </td>
+        </tr>
+      </table>
+      <p>The tag will be set for all requests coming from clients that have requested it to be set. Note that "clients"
+      are distinguished by IP address, if the IP address changes, the tag must be requested again.</p>
+    </div>
+  </div>
+  <div class="NAVFOOTER">
+    <hr align="left" width="100%">
+    <table summary="Footer navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
+      <tr>
+        <td width="33%" align="left" valign="top"><a href="templates.html" accesskey="P">Prev</a></td>
+        <td width="34%" align="center" valign="top"><a href="index.html" accesskey="H">Home</a></td>
+        <td width="33%" align="right" valign="top"><a href="contact.html" accesskey="N">Next</a></td>
+      </tr>
+      <tr>
+        <td width="33%" align="left" valign="top">Privoxy's Template Files</td>
+        <td width="34%" align="center" valign="top">&nbsp;</td>
+        <td width="33%" align="right" valign="top">Contacting the Developers, Bug Reporting and Feature Requests</td>
+      </tr>
+    </table>
+  </div>
+</body>
+</html>
index 4ea0d0a..6bf8acc 100644 (file)
@@ -2,7 +2,7 @@
 "http://www.w3.org/TR/html4/loose.dtd">
 <html>
 <head>
-  <title>Privoxy 3.0.33 User Manual</title>
+  <title>Privoxy 3.0.35 User Manual</title>
   <meta name="GENERATOR" content="Modular DocBook HTML Stylesheet Version 1.79">
   <link rel="NEXT" title="Introduction" href="introduction.html">
   <link rel="STYLESHEET" type="text/css" href="../p_doc.css">
@@ -12,8 +12,8 @@
 <body class="ARTICLE" bgcolor="#EEEEEE" text="#000000" link="#0000FF" vlink="#840084" alink="#0000FF">
   <div class="ARTICLE">
     <div class="TITLEPAGE">
-      <h1 class="TITLE"><a name="AEN2" id="AEN2">Privoxy 3.0.33 User Manual</a></h1>
-      <p class="PUBDATE"><sub><a href="copyright.html">Copyright</a> &copy; 2001-2021 by <a href=
+      <h1 class="TITLE"><a name="AEN2" id="AEN2">Privoxy 3.0.35 User Manual</a></h1>
+      <p class="PUBDATE"><sub><a href="copyright.html">Copyright</a> &copy; 2001-2023 by <a href=
       "https://www.privoxy.org/" target="_top">Privoxy Developers</a></sub><br></p>
       <div>
         <div class="ABSTRACT">
@@ -64,7 +64,7 @@
                 <dt>2.1.4. <a href="installation.html#OS-X-INSTALL-FROM-PACKAGE">Installation from ready-built
                 package</a></dt>
                 <dt>2.1.5. <a href="installation.html#OS-X-INSTALL-FROM-SOURCE">Installation from source</a></dt>
-                <dt>2.1.6. <a href="installation.html#INSTALLATION-FREEBSD">FreeBSD</a></dt>
+                <dt>2.1.6. <a href="installation.html#INSTALLATION-FREEBSD">FreeBSD and ElectroBSD</a></dt>
               </dl>
             </dd>
             <dt>2.2. <a href="installation.html#INSTALLATION-SOURCE">Building from Source</a></dt>
                 <dt>7.6.19. <a href="config.html#RECEIVE-BUFFER-SIZE">receive-buffer-size</a></dt>
               </dl>
             </dd>
-            <dt>7.7. <a href="config.html#HTTPS-INSPECTION-DIRECTIVES">HTTPS Inspection (Experimental)</a></dt>
+            <dt>7.7. <a href="config.html#HTTPS-INSPECTION-DIRECTIVES">HTTPS Inspection</a></dt>
             <dd>
               <dl>
                 <dt>7.7.1. <a href="config.html#CA-DIRECTORY">ca-directory</a></dt>
                 <dt>8.5.3. <a href="actions-file.html#CHANGE-X-FORWARDED-FOR">change-x-forwarded-for</a></dt>
                 <dt>8.5.4. <a href="actions-file.html#CLIENT-HEADER-FILTER">client-header-filter</a></dt>
                 <dt>8.5.5. <a href="actions-file.html#CLIENT-BODY-FILTER">client-body-filter</a></dt>
-                <dt>8.5.6. <a href="actions-file.html#CLIENT-HEADER-TAGGER">client-header-tagger</a></dt>
-                <dt>8.5.7. <a href="actions-file.html#CONTENT-TYPE-OVERWRITE">content-type-overwrite</a></dt>
-                <dt>8.5.8. <a href="actions-file.html#CRUNCH-CLIENT-HEADER">crunch-client-header</a></dt>
-                <dt>8.5.9. <a href="actions-file.html#CRUNCH-IF-NONE-MATCH">crunch-if-none-match</a></dt>
-                <dt>8.5.10. <a href="actions-file.html#CRUNCH-INCOMING-COOKIES">crunch-incoming-cookies</a></dt>
-                <dt>8.5.11. <a href="actions-file.html#CRUNCH-SERVER-HEADER">crunch-server-header</a></dt>
-                <dt>8.5.12. <a href="actions-file.html#CRUNCH-OUTGOING-COOKIES">crunch-outgoing-cookies</a></dt>
-                <dt>8.5.13. <a href="actions-file.html#DEANIMATE-GIFS">deanimate-gifs</a></dt>
-                <dt>8.5.14. <a href="actions-file.html#DELAY-RESPONSE">delay-response</a></dt>
-                <dt>8.5.15. <a href="actions-file.html#DOWNGRADE-HTTP-VERSION">downgrade-http-version</a></dt>
-                <dt>8.5.16. <a href="actions-file.html#EXTERNAL-FILTER">external-filter</a></dt>
-                <dt>8.5.17. <a href="actions-file.html#FAST-REDIRECTS">fast-redirects</a></dt>
-                <dt>8.5.18. <a href="actions-file.html#FILTER">filter</a></dt>
-                <dt>8.5.19. <a href="actions-file.html#FORCE-TEXT-MODE">force-text-mode</a></dt>
-                <dt>8.5.20. <a href="actions-file.html#FORWARD-OVERRIDE">forward-override</a></dt>
-                <dt>8.5.21. <a href="actions-file.html#HANDLE-AS-EMPTY-DOCUMENT">handle-as-empty-document</a></dt>
-                <dt>8.5.22. <a href="actions-file.html#HANDLE-AS-IMAGE">handle-as-image</a></dt>
-                <dt>8.5.23. <a href="actions-file.html#HIDE-ACCEPT-LANGUAGE">hide-accept-language</a></dt>
-                <dt>8.5.24. <a href="actions-file.html#HIDE-CONTENT-DISPOSITION">hide-content-disposition</a></dt>
-                <dt>8.5.25. <a href="actions-file.html#HIDE-IF-MODIFIED-SINCE">hide-if-modified-since</a></dt>
-                <dt>8.5.26. <a href="actions-file.html#HIDE-FROM-HEADER">hide-from-header</a></dt>
-                <dt>8.5.27. <a href="actions-file.html#HIDE-REFERRER">hide-referrer</a></dt>
-                <dt>8.5.28. <a href="actions-file.html#HIDE-USER-AGENT">hide-user-agent</a></dt>
-                <dt>8.5.29. <a href="actions-file.html#HTTPS-INSPECTION">https-inspection</a></dt>
-                <dt>8.5.30. <a href="actions-file.html#IGNORE-CERTIFICATE-ERRORS">ignore-certificate-errors</a></dt>
-                <dt>8.5.31. <a href="actions-file.html#LIMIT-CONNECT">limit-connect</a></dt>
-                <dt>8.5.32. <a href="actions-file.html#LIMIT-COOKIE-LIFETIME">limit-cookie-lifetime</a></dt>
-                <dt>8.5.33. <a href="actions-file.html#PREVENT-COMPRESSION">prevent-compression</a></dt>
-                <dt>8.5.34. <a href="actions-file.html#OVERWRITE-LAST-MODIFIED">overwrite-last-modified</a></dt>
-                <dt>8.5.35. <a href="actions-file.html#REDIRECT">redirect</a></dt>
-                <dt>8.5.36. <a href="actions-file.html#SERVER-HEADER-FILTER">server-header-filter</a></dt>
-                <dt>8.5.37. <a href="actions-file.html#SERVER-HEADER-TAGGER">server-header-tagger</a></dt>
-                <dt>8.5.38. <a href="actions-file.html#SUPPRESS-TAG">suppress-tag</a></dt>
-                <dt>8.5.39. <a href="actions-file.html#SESSION-COOKIES-ONLY">session-cookies-only</a></dt>
-                <dt>8.5.40. <a href="actions-file.html#SET-IMAGE-BLOCKER">set-image-blocker</a></dt>
-                <dt>8.5.41. <a href="actions-file.html#SUMMARY">Summary</a></dt>
+                <dt>8.5.6. <a href="actions-file.html#CLIENT-BODY-TAGGER">client-body-tagger</a></dt>
+                <dt>8.5.7. <a href="actions-file.html#CLIENT-HEADER-TAGGER">client-header-tagger</a></dt>
+                <dt>8.5.8. <a href="actions-file.html#CONTENT-TYPE-OVERWRITE">content-type-overwrite</a></dt>
+                <dt>8.5.9. <a href="actions-file.html#CRUNCH-CLIENT-HEADER">crunch-client-header</a></dt>
+                <dt>8.5.10. <a href="actions-file.html#CRUNCH-IF-NONE-MATCH">crunch-if-none-match</a></dt>
+                <dt>8.5.11. <a href="actions-file.html#CRUNCH-INCOMING-COOKIES">crunch-incoming-cookies</a></dt>
+                <dt>8.5.12. <a href="actions-file.html#CRUNCH-SERVER-HEADER">crunch-server-header</a></dt>
+                <dt>8.5.13. <a href="actions-file.html#CRUNCH-OUTGOING-COOKIES">crunch-outgoing-cookies</a></dt>
+                <dt>8.5.14. <a href="actions-file.html#DEANIMATE-GIFS">deanimate-gifs</a></dt>
+                <dt>8.5.15. <a href="actions-file.html#DELAY-RESPONSE">delay-response</a></dt>
+                <dt>8.5.16. <a href="actions-file.html#DOWNGRADE-HTTP-VERSION">downgrade-http-version</a></dt>
+                <dt>8.5.17. <a href="actions-file.html#EXTERNAL-FILTER">external-filter</a></dt>
+                <dt>8.5.18. <a href="actions-file.html#FAST-REDIRECTS">fast-redirects</a></dt>
+                <dt>8.5.19. <a href="actions-file.html#FILTER">filter</a></dt>
+                <dt>8.5.20. <a href="actions-file.html#FORCE-TEXT-MODE">force-text-mode</a></dt>
+                <dt>8.5.21. <a href="actions-file.html#FORWARD-OVERRIDE">forward-override</a></dt>
+                <dt>8.5.22. <a href="actions-file.html#HANDLE-AS-EMPTY-DOCUMENT">handle-as-empty-document</a></dt>
+                <dt>8.5.23. <a href="actions-file.html#HANDLE-AS-IMAGE">handle-as-image</a></dt>
+                <dt>8.5.24. <a href="actions-file.html#HIDE-ACCEPT-LANGUAGE">hide-accept-language</a></dt>
+                <dt>8.5.25. <a href="actions-file.html#HIDE-CONTENT-DISPOSITION">hide-content-disposition</a></dt>
+                <dt>8.5.26. <a href="actions-file.html#HIDE-IF-MODIFIED-SINCE">hide-if-modified-since</a></dt>
+                <dt>8.5.27. <a href="actions-file.html#HIDE-FROM-HEADER">hide-from-header</a></dt>
+                <dt>8.5.28. <a href="actions-file.html#HIDE-REFERRER">hide-referrer</a></dt>
+                <dt>8.5.29. <a href="actions-file.html#HIDE-USER-AGENT">hide-user-agent</a></dt>
+                <dt>8.5.30. <a href="actions-file.html#HTTPS-INSPECTION">https-inspection</a></dt>
+                <dt>8.5.31. <a href="actions-file.html#IGNORE-CERTIFICATE-ERRORS">ignore-certificate-errors</a></dt>
+                <dt>8.5.32. <a href="actions-file.html#LIMIT-CONNECT">limit-connect</a></dt>
+                <dt>8.5.33. <a href="actions-file.html#LIMIT-COOKIE-LIFETIME">limit-cookie-lifetime</a></dt>
+                <dt>8.5.34. <a href="actions-file.html#PREVENT-COMPRESSION">prevent-compression</a></dt>
+                <dt>8.5.35. <a href="actions-file.html#OVERWRITE-LAST-MODIFIED">overwrite-last-modified</a></dt>
+                <dt>8.5.36. <a href="actions-file.html#REDIRECT">redirect</a></dt>
+                <dt>8.5.37. <a href="actions-file.html#SERVER-HEADER-FILTER">server-header-filter</a></dt>
+                <dt>8.5.38. <a href="actions-file.html#SERVER-HEADER-TAGGER">server-header-tagger</a></dt>
+                <dt>8.5.39. <a href="actions-file.html#SUPPRESS-TAG">suppress-tag</a></dt>
+                <dt>8.5.40. <a href="actions-file.html#SESSION-COOKIES-ONLY">session-cookies-only</a></dt>
+                <dt>8.5.41. <a href="actions-file.html#SET-IMAGE-BLOCKER">set-image-blocker</a></dt>
+                <dt>8.5.42. <a href="actions-file.html#SUMMARY">Summary</a></dt>
               </dl>
             </dd>
             <dt>8.6. <a href="actions-file.html#ALIASES">Aliases</a></dt>
           </dl>
         </dd>
         <dt>10. <a href="templates.html">Privoxy's Template Files</a></dt>
-        <dt>11. <a href="contact.html">Contacting the Developers, Bug Reporting and Feature Requests</a></dt>
+        <dt>11. <a href="howto.html">HOWTOs</a></dt>
         <dd>
           <dl>
-            <dt>11.1. <a href="contact.html#SUFFICIENT-INFORMATION">Please provide sufficient information</a></dt>
-            <dt>11.2. <a href="contact.html#CONTACT-SUPPORT">Get Support</a></dt>
-            <dt>11.3. <a href="contact.html#REPORTING">Reporting Problems</a></dt>
+            <dt>11.1. <a href="howto.html#H2-HTTPS-INSPECTION">HTTPS-Inspection HOWTO</a></dt>
             <dd>
               <dl>
-                <dt>11.3.1. <a href="contact.html#CONTACT-ADS">Reporting Ads or Other Configuration Problems</a></dt>
-                <dt>11.3.2. <a href="contact.html#CONTACT-BUGS">Reporting Bugs</a></dt>
+                <dt>11.1.1. <a href="howto.html#H2-HI-TLS">How TLS Certificates for websites work</a></dt>
+                <dt>11.1.2. <a href="howto.html#H2-HI-WORKS">How HTTPS inspection works</a></dt>
+                <dt>11.1.3. <a href="howto.html#H2-HI-INVALID-CERT">What happens, if the original certificate is
+                invalid?</a></dt>
+                <dt>11.1.4. <a href="howto.html#H2-HI-PREREQUISITES">HTTPS inspection prerequisites</a></dt>
+                <dt>11.1.5. <a href="howto.html#H2-HI-CONFIG">Configuring HTTPS inspection in Privoxy</a></dt>
+                <dt>11.1.6. <a href="howto.html#H2-HI-BROWSER">Browser configuration</a></dt>
+                <dt>11.1.7. <a href="howto.html#H2-HI-ENABLE">Enabeling HTTPS inspection</a></dt>
               </dl>
             </dd>
-            <dt>11.4. <a href="contact.html#SECURITY-CONTACT">Reporting security problems</a></dt>
-            <dt>11.5. <a href="contact.html#MAILING-LISTS">Mailing Lists</a></dt>
-            <dt>11.6. <a href="contact.html#SF-TRACKERS">SourceForge support trackers</a></dt>
+            <dt>11.2. <a href="howto.html#H2-CLIENT-TAGS">Client Tags HOWTO</a></dt>
           </dl>
         </dd>
-        <dt>12. <a href="copyright.html">Privoxy Copyright, License and History</a></dt>
+        <dt>12. <a href="contact.html">Contacting the Developers, Bug Reporting and Feature Requests</a></dt>
         <dd>
           <dl>
-            <dt>12.1. <a href="copyright.html#LICENSE">License</a></dt>
+            <dt>12.1. <a href="contact.html#SUFFICIENT-INFORMATION">Please provide sufficient information</a></dt>
+            <dt>12.2. <a href="contact.html#CONTACT-SUPPORT">Get Support</a></dt>
+            <dt>12.3. <a href="contact.html#REPORTING">Reporting Problems</a></dt>
             <dd>
               <dl>
-                <dt>12.1.1. <a href="copyright.html#GPLV2">GNU General Public License version 2</a></dt>
-                <dt>12.1.2. <a href="copyright.html#GPLV3">GNU General Public License version 3</a></dt>
-                <dt>12.1.3. <a href="copyright.html#THIRD-PARTY-LICENSES">Third-party licenses and copyrights</a></dt>
+                <dt>12.3.1. <a href="contact.html#CONTACT-ADS">Reporting Ads or Other Configuration Problems</a></dt>
+                <dt>12.3.2. <a href="contact.html#CONTACT-BUGS">Reporting Bugs</a></dt>
               </dl>
             </dd>
-            <dt>12.2. <a href="copyright.html#HISTORY">History</a></dt>
-            <dt>12.3. <a href="copyright.html#AUTHORS">Authors</a></dt>
+            <dt>12.4. <a href="contact.html#SECURITY-CONTACT">Reporting security problems</a></dt>
+            <dt>12.5. <a href="contact.html#MAILING-LISTS">Mailing Lists</a></dt>
+            <dt>12.6. <a href="contact.html#SF-TRACKERS">SourceForge support trackers</a></dt>
           </dl>
         </dd>
-        <dt>13. <a href="seealso.html">See Also</a></dt>
-        <dt>14. <a href="appendix.html">Appendix</a></dt>
+        <dt>13. <a href="copyright.html">Privoxy Copyright, License and History</a></dt>
         <dd>
           <dl>
-            <dt>14.1. <a href="appendix.html#REGEX">Regular Expressions</a></dt>
-            <dt>14.2. <a href="appendix.html#INTERNAL-PAGES">Privoxy's Internal Pages</a></dt>
-            <dt>14.3. <a href="appendix.html#CHAIN">Chain of Events</a></dt>
-            <dt>14.4. <a href="appendix.html#ACTIONSANAT">Troubleshooting: Anatomy of an Action</a></dt>
+            <dt>13.1. <a href="copyright.html#LICENSE">License</a></dt>
+            <dd>
+              <dl>
+                <dt>13.1.1. <a href="copyright.html#GPLV2">GNU General Public License version 2</a></dt>
+                <dt>13.1.2. <a href="copyright.html#GPLV3">GNU General Public License version 3</a></dt>
+                <dt>13.1.3. <a href="copyright.html#THIRD-PARTY-LICENSES">Third-party licenses and copyrights</a></dt>
+              </dl>
+            </dd>
+            <dt>13.2. <a href="copyright.html#HISTORY">History</a></dt>
+            <dt>13.3. <a href="copyright.html#AUTHORS">Authors</a></dt>
+          </dl>
+        </dd>
+        <dt>14. <a href="seealso.html">See Also</a></dt>
+        <dt>15. <a href="appendix.html">Appendix</a></dt>
+        <dd>
+          <dl>
+            <dt>15.1. <a href="appendix.html#REGEX">Regular Expressions</a></dt>
+            <dt>15.2. <a href="appendix.html#INTERNAL-PAGES">Privoxy's Internal Pages</a></dt>
+            <dt>15.3. <a href="appendix.html#CHAIN">Chain of Events</a></dt>
+            <dt>15.4. <a href="appendix.html#ACTIONSANAT">Troubleshooting: Anatomy of an Action</a></dt>
           </dl>
         </dd>
       </dl>
index c36322e..07bc924 100644 (file)
@@ -4,7 +4,7 @@
 <head>
   <title>Installation</title>
   <meta name="GENERATOR" content="Modular DocBook HTML Stylesheet Version 1.79">
-  <link rel="HOME" title="Privoxy 3.0.33 User Manual" href="index.html">
+  <link rel="HOME" title="Privoxy 3.0.35 User Manual" href="index.html">
   <link rel="PREVIOUS" title="Introduction" href="introduction.html">
   <link rel="NEXT" title="What's New in this Release" href="whatsnew.html">
   <link rel="STYLESHEET" type="text/css" href="../p_doc.css">
@@ -15,7 +15,7 @@
   <div class="NAVHEADER">
     <table summary="Header navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
       <tr>
-        <th colspan="3" align="center">Privoxy 3.0.33 User Manual</th>
+        <th colspan="3" align="center">Privoxy 3.0.35 User Manual</th>
       </tr>
       <tr>
         <td width="10%" align="left" valign="bottom"><a href="introduction.html" accesskey="P">Prev</a></td>
         <p>To uninstall, run the macsetup module's uninstall.sh as sudo from an administrator account.</p>
       </div>
       <div class="SECT3">
-        <h3 class="SECT3"><a name="INSTALLATION-FREEBSD" id="INSTALLATION-FREEBSD">2.1.6. FreeBSD</a></h3>
+        <h3 class="SECT3"><a name="INSTALLATION-FREEBSD" id="INSTALLATION-FREEBSD">2.1.6. FreeBSD and
+        ElectroBSD</a></h3>
         <p>Privoxy is part of FreeBSD's Ports Collection, you can build and install it with <tt class="LITERAL">cd
         /usr/ports/www/privoxy; make install clean</tt>.</p>
+        <p>If your system is configured to install binary packages you can try to install <span class=
+        "APPLICATION">Privoxy</span> with <tt class="LITERAL">pkg install privoxy</tt>.</p>
       </div>
     </div>
     <div class="SECT2">
       <table border="0" bgcolor="#E0E0E0" width="100%">
         <tr>
           <td>
-            <pre class="SCREEN">  tar xzvf privoxy-3.0.33-stable-src.tar.gz
-  cd privoxy-3.0.33-stable</pre>
+            <pre class="SCREEN">  tar xzvf privoxy-3.0.35-beta-src.tar.gz
+  cd privoxy-3.0.35-beta</pre>
           </td>
         </tr>
       </table>
               </td>
             </tr>
           </table>
-          <p>Get the latest 8.x PCRE code from <a href="https://ftp.pcre.org/pub/pcre/" target="_top">PCRE
-          https://ftp.pcre.org/pub/pcre/</a> and build the static PCRE libraries with</p>
+          <p>Get the latest 8.x PCRE code from <a href="https://sourceforge.net/projects/pcre/files/pcre/" target=
+          "_top">PCRE https://sourceforge.net/projects/pcre/files/pcre/</a> and build the static PCRE libraries
+          with</p>
           <table border="0" bgcolor="#E0E0E0" width="100%">
             <tr>
               <td>
               </td>
             </tr>
           </table>
-          <p>If you want to be able to have Privoxy do TLS Inspection, get the latest 2.16.x MBED-TLS library source
-          code from <a href="https://github.com/ARMmbed/mbedtls/tags" target=
-          "_top">https://github.com/ARMmbed/mbedtls/tags</a>, extract the tar file into <tt class=
+          <p>If you want to be able to have Privoxy do TLS Inspection, get the latest 2.28.x MBED-TLS library source
+          code from <a href="https://github.com/Mbed-TLS/mbedtls/tags" target=
+          "_top">https://github.com/Mbed-TLS/mbedtls/tags</a>, extract the tar file into <tt class=
           "LITERAL">&lt;root-dir&gt;</tt> and build the static libraries with</p>
           <table border="0" bgcolor="#E0E0E0" width="100%">
             <tr>
index 858d3f6..50a8a30 100644 (file)
@@ -4,8 +4,8 @@
 <head>
   <title>Introduction</title>
   <meta name="GENERATOR" content="Modular DocBook HTML Stylesheet Version 1.79">
-  <link rel="HOME" title="Privoxy 3.0.33 User Manual" href="index.html">
-  <link rel="PREVIOUS" title="Privoxy 3.0.33 User Manual" href="index.html">
+  <link rel="HOME" title="Privoxy 3.0.35 User Manual" href="index.html">
+  <link rel="PREVIOUS" title="Privoxy 3.0.35 User Manual" href="index.html">
   <link rel="NEXT" title="Installation" href="installation.html">
   <link rel="STYLESHEET" type="text/css" href="../p_doc.css">
   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
@@ -15,7 +15,7 @@
   <div class="NAVHEADER">
     <table summary="Header navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
       <tr>
-        <th colspan="3" align="center">Privoxy 3.0.33 User Manual</th>
+        <th colspan="3" align="center">Privoxy 3.0.35 User Manual</th>
       </tr>
       <tr>
         <td width="10%" align="left" valign="bottom"><a href="index.html" accesskey="P">Prev</a></td>
   </div>
   <div class="SECT1">
     <h1 class="SECT1"><a name="INTRODUCTION" id="INTRODUCTION">1. Introduction</a></h1>
-    <p>This documentation is included with the current stable version of <span class="APPLICATION">Privoxy</span>,
-    3.0.33.</p>
+    <p>This documentation is included with the current UNRELEASED version of <span class="APPLICATION">Privoxy</span>,
+    3.0.35, 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 completion, and includes significant changes and enhancements over earlier versions.</p>
+    <p>Since this is a UNRELEASED version, not all new features are well tested. This documentation may be slightly out
+    of sync as a result (especially with <a href="https://www.privoxy.org/gitweb/?p=privoxy.git;a=summary" target=
+    "_top">git sources</a>). And there <span class="emphasis"><i class="EMPHASIS">may be</i></span> bugs, though
+    hopefully not many!</p>
     <div class="SECT2">
       <h2 class="SECT2"><a name="FEATURES" id="FEATURES">1.1. Features</a></h2>
       <p>In addition to the core features of ad blocking and <a href="https://en.wikipedia.org/wiki/Browser_cookie"
       target="_top">cookie</a> management, <span class="APPLICATION">Privoxy</span> provides many supplemental
-      features, that give the end-user more control, more privacy and more freedom:</p>
+      features, some of them currently under development, that give the end-user more control, more privacy and more
+      freedom:</p>
       <ul>
         <li>
           <p>Supports "Connection: keep-alive". Outgoing connections can be kept alive independently from the
         <td width="33%" align="right" valign="top"><a href="installation.html" accesskey="N">Next</a></td>
       </tr>
       <tr>
-        <td width="33%" align="left" valign="top">Privoxy 3.0.33 User Manual</td>
+        <td width="33%" align="left" valign="top">Privoxy 3.0.35 User Manual</td>
         <td width="34%" align="center" valign="top">&nbsp;</td>
         <td width="33%" align="right" valign="top">Installation</td>
       </tr>
index d7aa9de..7ff309c 100644 (file)
@@ -4,7 +4,7 @@
 <head>
   <title>Quickstart to Using Privoxy</title>
   <meta name="GENERATOR" content="Modular DocBook HTML Stylesheet Version 1.79">
-  <link rel="HOME" title="Privoxy 3.0.33 User Manual" href="index.html">
+  <link rel="HOME" title="Privoxy 3.0.35 User Manual" href="index.html">
   <link rel="PREVIOUS" title="What's New in this Release" href="whatsnew.html">
   <link rel="NEXT" title="Starting Privoxy" href="startup.html">
   <link rel="STYLESHEET" type="text/css" href="../p_doc.css">
@@ -15,7 +15,7 @@
   <div class="NAVHEADER">
     <table summary="Header navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
       <tr>
-        <th colspan="3" align="center">Privoxy 3.0.33 User Manual</th>
+        <th colspan="3" align="center">Privoxy 3.0.35 User Manual</th>
       </tr>
       <tr>
         <td width="10%" align="left" valign="bottom"><a href="whatsnew.html" accesskey="P">Prev</a></td>
           <p>Find <tt class="FILENAME">user.action</tt> in the top section, and click on <span class=
           "QUOTE">"<span class="GUIBUTTON">Edit</span>"</span>:</p>
           <div class="FIGURE">
-            <a name="AEN609" id="AEN609"></a>
+            <a name="AEN641" id="AEN641"></a>
             <p><b>Figure 1. Actions Files in Use</b></p>
             <div class="MEDIAOBJECT">
               <p><img src="files-in-use.jpg"></p>
index f92f422..57e74a2 100644 (file)
@@ -4,7 +4,7 @@
 <head>
   <title>See Also</title>
   <meta name="GENERATOR" content="Modular DocBook HTML Stylesheet Version 1.79">
-  <link rel="HOME" title="Privoxy 3.0.33 User Manual" href="index.html">
+  <link rel="HOME" title="Privoxy 3.0.35 User Manual" href="index.html">
   <link rel="PREVIOUS" title="Privoxy Copyright, License and History" href="copyright.html">
   <link rel="NEXT" title="Appendix" href="appendix.html">
   <link rel="STYLESHEET" type="text/css" href="../p_doc.css">
@@ -15,7 +15,7 @@
   <div class="NAVHEADER">
     <table summary="Header navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
       <tr>
-        <th colspan="3" align="center">Privoxy 3.0.33 User Manual</th>
+        <th colspan="3" align="center">Privoxy 3.0.35 User Manual</th>
       </tr>
       <tr>
         <td width="10%" align="left" valign="bottom"><a href="copyright.html" accesskey="P">Prev</a></td>
@@ -26,7 +26,7 @@
     <hr align="left" width="100%">
   </div>
   <div class="SECT1">
-    <h1 class="SECT1"><a name="SEEALSO" id="SEEALSO">13. See Also</a></h1>
+    <h1 class="SECT1"><a name="SEEALSO" id="SEEALSO">14. See Also</a></h1>
     <p>Other references and sites of interest to <span class="APPLICATION">Privoxy</span> users:</p>
     <table border="0">
       <tbody>
index 610c3e6..fa07939 100644 (file)
@@ -4,7 +4,7 @@
 <head>
   <title>Starting Privoxy</title>
   <meta name="GENERATOR" content="Modular DocBook HTML Stylesheet Version 1.79">
-  <link rel="HOME" title="Privoxy 3.0.33 User Manual" href="index.html">
+  <link rel="HOME" title="Privoxy 3.0.35 User Manual" href="index.html">
   <link rel="PREVIOUS" title="Quickstart to Using Privoxy" href="quickstart.html">
   <link rel="NEXT" title="Privoxy Configuration" href="configuration.html">
   <link rel="STYLESHEET" type="text/css" href="../p_doc.css">
@@ -15,7 +15,7 @@
   <div class="NAVHEADER">
     <table summary="Header navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
       <tr>
-        <th colspan="3" align="center">Privoxy 3.0.33 User Manual</th>
+        <th colspan="3" align="center">Privoxy 3.0.35 User Manual</th>
       </tr>
       <tr>
         <td width="10%" align="left" valign="bottom"><a href="quickstart.html" accesskey="P">Prev</a></td>
@@ -35,7 +35,7 @@
     <p>Please note that <span class="APPLICATION">Privoxy</span> can only proxy HTTP and HTTPS traffic. It will not
     work with FTP or other protocols.</p>
     <div class="FIGURE">
-      <a name="AEN663" id="AEN663"></a>
+      <a name="AEN695" id="AEN695"></a>
       <p><b>Figure 2. Proxy Configuration Showing Mozilla Firefox HTTP and HTTPS (SSL) Settings</b></p>
       <div class="MEDIAOBJECT">
         <p><img src="proxy_setup.jpg"></p>
@@ -66,7 +66,7 @@
     protocols"</span> is <span class="emphasis"><i class="EMPHASIS">UNCHECKED</i></span>. You want only HTTP and HTTPS
     (SSL)!</p>
     <div class="FIGURE">
-      <a name="AEN705" id="AEN705"></a>
+      <a name="AEN737" id="AEN737"></a>
       <p><b>Figure 3. Proxy Configuration Showing Internet Explorer HTTP and HTTPS (Secure) Settings</b></p>
       <div class="MEDIAOBJECT">
         <p><img src="proxy2.jpg"></p>
index 51eb143..c7d5eaa 100644 (file)
@@ -4,9 +4,9 @@
 <head>
   <title>Privoxy's Template Files</title>
   <meta name="GENERATOR" content="Modular DocBook HTML Stylesheet Version 1.79">
-  <link rel="HOME" title="Privoxy 3.0.33 User Manual" href="index.html">
+  <link rel="HOME" title="Privoxy 3.0.35 User Manual" href="index.html">
   <link rel="PREVIOUS" title="Filter Files" href="filter-file.html">
-  <link rel="NEXT" title="Contacting the Developers, Bug Reporting and Feature Requests" href="contact.html">
+  <link rel="NEXT" title="HOWTOs" href="howto.html">
   <link rel="STYLESHEET" type="text/css" href="../p_doc.css">
   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
   <link rel="STYLESHEET" type="text/css" href="p_doc.css">
   <div class="NAVHEADER">
     <table summary="Header navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
       <tr>
-        <th colspan="3" align="center">Privoxy 3.0.33 User Manual</th>
+        <th colspan="3" align="center">Privoxy 3.0.35 User Manual</th>
       </tr>
       <tr>
         <td width="10%" align="left" valign="bottom"><a href="filter-file.html" accesskey="P">Prev</a></td>
         <td width="80%" align="center" valign="bottom"></td>
-        <td width="10%" align="right" valign="bottom"><a href="contact.html" accesskey="N">Next</a></td>
+        <td width="10%" align="right" valign="bottom"><a href="howto.html" accesskey="N">Next</a></td>
       </tr>
     </table>
     <hr align="left" width="100%">
       <tr>
         <td width="33%" align="left" valign="top"><a href="filter-file.html" accesskey="P">Prev</a></td>
         <td width="34%" align="center" valign="top"><a href="index.html" accesskey="H">Home</a></td>
-        <td width="33%" align="right" valign="top"><a href="contact.html" accesskey="N">Next</a></td>
+        <td width="33%" align="right" valign="top"><a href="howto.html" accesskey="N">Next</a></td>
       </tr>
       <tr>
         <td width="33%" align="left" valign="top">Filter Files</td>
         <td width="34%" align="center" valign="top">&nbsp;</td>
-        <td width="33%" align="right" valign="top">Contacting the Developers, Bug Reporting and Feature Requests</td>
+        <td width="33%" align="right" valign="top">HOWTOs</td>
       </tr>
     </table>
   </div>
index dceb2ed..954b9e5 100644 (file)
@@ -4,7 +4,7 @@
 <head>
   <title>What's New in this Release</title>
   <meta name="GENERATOR" content="Modular DocBook HTML Stylesheet Version 1.79">
-  <link rel="HOME" title="Privoxy 3.0.33 User Manual" href="index.html">
+  <link rel="HOME" title="Privoxy 3.0.35 User Manual" href="index.html">
   <link rel="PREVIOUS" title="Installation" href="installation.html">
   <link rel="NEXT" title="Quickstart to Using Privoxy" href="quickstart.html">
   <link rel="STYLESHEET" type="text/css" href="../p_doc.css">
@@ -15,7 +15,7 @@
   <div class="NAVHEADER">
     <table summary="Header navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
       <tr>
-        <th colspan="3" align="center">Privoxy 3.0.33 User Manual</th>
+        <th colspan="3" align="center">Privoxy 3.0.35 User Manual</th>
       </tr>
       <tr>
         <td width="10%" align="left" valign="bottom"><a href="installation.html" accesskey="P">Prev</a></td>
   </div>
   <div class="SECT1">
     <h1 class="SECT1"><a name="WHATSNEW" id="WHATSNEW">3. What's New in this Release</a></h1>
-    <p><span class="APPLICATION">Privoxy 3.0.32</span> fixes multiple DoS issues and a couple of other bugs. The issues
-    also affect earlier Privoxy releases.</p>
-    <p>Changes in <span class="APPLICATION">Privoxy 3.0.32</span> stable:</p>
+    <p><span class="APPLICATION">Privoxy 3.0.34</span> fixes a few minor bugs and comes with a couple of general
+    improvements and new features.</p>
+    <p>Changes in <span class="APPLICATION">Privoxy 3.0.34</span> stable:</p>
     <ul>
       <li>
-        <p>Security/Reliability:</p>
+        <p>Bug fixes:</p>
         <ul>
           <li>
-            <p>ssplit(): Remove an assertion that could be triggered with a crafted CGI request. Commit 2256d7b4d67.
-            OVE-20210203-0001. Reported by: Joshua Rogers (Opera)</p>
+            <p>Improve the handling of chunk-encoded responses by buffering the data even if filters are disabled and
+            properly keeping track of where the various chunks are supposed to start and end. Previously Privoxy would
+            merely check the last bytes received to see if they looked like the last-chunk. This failed to work if the
+            last-chunk wasn't received in one read and could also result in actual data being misdetected as
+            last-chunk. Should fix: SF support request #1739. Reported by: withoutname.</p>
           </li>
           <li>
-            <p>cgi_send_banner(): Overrule invalid image types. Prevents a crash with a crafted CGI request if Privoxy
-            is toggled off. Commit e711c505c48. OVE-20210206-0001. Reported by: Joshua Rogers (Opera)</p>
+            <p>remove_chunked_transfer_coding(): Refuse to de-chunk invalid data Previously the data could get
+            corrupted even further. Now we simply pass the unmodified data to the client.</p>
           </li>
           <li>
-            <p>socks5_connect(): Don't try to send credentials when none are configured. Fixes a crash due to a
-            NULL-pointer dereference when the socks server misbehaves. Commit 85817cc55b9. OVE-20210207-0001. Reported
-            by: Joshua Rogers (Opera)</p>
+            <p>gif_deanimate(): Tolerate multiple image extensions in a row. This allows to deanimate all the gifs on:
+            https://commons.wikimedia.org/wiki/Category:Animated_smilies Fixes SF bug #795 reported by Celejar.</p>
           </li>
           <li>
-            <p>chunked_body_is_complete(): Prevent an invalid read of size two. Commit a912ba7bc9c. OVE-20210205-0001.
-            Reported by: Joshua Rogers (Opera)</p>
+            <p>OpenSSL generate_host_certificate(): Use X509_get_subject_name() instead of X509_get_issuer_name() to
+            get the issuer for generated website certificates so there are no warnings in the browser when using an
+            intermediate CA certificate instead of a self-signed root certificate. Problem reported and patch submitted
+            by Chakib Benziane.</p>
           </li>
           <li>
-            <p>Obsolete pcre: Prevent invalid memory accesses with an invalid pattern passed to pcre_compile(). Note
-            that the obsolete pcre code is scheduled to be removed before the 3.0.33 release. There has been a warning
-            since 2008 already. Commit 28512e5b624. OVE-20210222-0001. Reported by: Joshua Rogers (Opera)</p>
+            <p>can_filter_request_body(): Fix a log message that contained a spurious u.</p>
           </li>
-        </ul>
-      </li>
-      <li>
-        <p>Bug fixes:</p>
-        <ul>
           <li>
-            <p>Properly parse the client-tag-lifetime directive. Previously it was not accepted as an obsolete hash
-            value was being used. Reported by: Joshua Rogers (Opera)</p>
+            <p>handle_established_connection(): Check for pending TLS data from the client before checking if data is
+            available on the connection. The TLS library may have already consumed all the data from the client
+            response in which case poll() and select() will not detect that data is available to be read. Sponsored by:
+            Robert Klemme.</p>
           </li>
           <li>
-            <p>decompress_iob(): Prevent reading of uninitialized data. Reported by: Joshua Rogers (Opera).</p>
+            <p>ssl_send_certificate_error(): Don't crash if there's no certificate information available. This is only
+            relevant when Privoxy is built with wolfSSL 5.0.0 or later (code not yet published). Earlier wolfSSL
+            versions or the other TLS backends don't seem to trigger the crash.</p>
           </li>
           <li>
-            <p>decompress_iob(): Don't advance cur past eod when looking for the end of the file name and comment.</p>
+            <p>socks5_connect(): Add support for target hosts specified as IPv4 address Previously the IP address was
+            sent as domain.</p>
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>General improvements:</p>
+        <ul>
+          <li>
+            <p>Add a client-body-tagger action which creates tags based on the content of the request body. Sponsored
+            by: Robert Klemme.</p>
           </li>
           <li>
-            <p>decompress_iob(): Cast value to unsigned char before shifting. Prevents a left-shift of a negative value
-            which is undefined behaviour. Reported by: Joshua Rogers (Opera)</p>
+            <p>When client-body filters are enabled, buffer the whole request before opening a connection to the
+            server. Makes it less likely that the server connection times out and we don't open a connection if the
+            buffering fails anyway. Sponsored by: Robert Klemme.</p>
           </li>
           <li>
-            <p>gif_deanimate(): Confirm that that we have enough data before doing any work. Fixes a crash when fuzzing
-            with an empty document. Reported by: Joshua Rogers (Opera).</p>
+            <p>Add periods to a couple of log messages.</p>
           </li>
           <li>
-            <p>buf_copy(): Fail if there's no data to write or nothing to do. Prevents undefined behaviour "applying
-            zero offset to null pointer". Reported by: Joshua Rogers (Opera)</p>
+            <p>accept_connection(): Add missing space to a log message.</p>
           </li>
           <li>
-            <p>log_error(): Treat LOG_LEVEL_FATAL as fatal even when --stfu is being used while fuzzing. Reported by:
-            Joshua Rogers (Opera).</p>
+            <p>Initialize ca-related defaults with strdup_or_die() so errors aren't silently ignored.</p>
           </li>
           <li>
-            <p>Respect DESTDIR when considering whether or not to install config files with ".new" extension.</p>
+            <p>make_path: Use malloc_or_die() in cases where allocation errors were already fatal anyway.</p>
           </li>
           <li>
-            <p>OpenSSL ssl_store_cert(): Fix two error messages.</p>
+            <p>handle_established_connection(): Improve an error message slightly.</p>
           </li>
           <li>
-            <p>Fix a couple of format specifiers.</p>
+            <p>receive_client_request(): Reject https URLs without CONNECT request.</p>
           </li>
           <li>
-            <p>Silence compiler warnings when compiling with NDEBUG.</p>
+            <p>Include all requests in the statistics if mutexes are available. Previously in case of reused
+            connections only the last request got counted. The statistics still aren't perfect but it's an
+            improvement.</p>
           </li>
           <li>
-            <p>fuzz_server_header(): Fix compiler warning.</p>
+            <p>Add read_socks_reply() and start using it in socks5_connect() to apply the socket timeout more
+            consistently.</p>
           </li>
           <li>
-            <p>fuzz_client_header(): Fix compiler warning.</p>
+            <p>socks5_connect(): Deal with domain names in the socks reply</p>
           </li>
           <li>
-            <p>cgi_send_user_manual(): Also reject requests if the user-manual directive specifies a https:// URL.
-            Previously Privoxy would try and fail to open a local file.</p>
+            <p>Add a filter for bundeswehr.de that hides the cookie and privacy info banner.</p>
           </li>
         </ul>
       </li>
       <li>
-        <p>General improvements:</p>
+        <p>Action file improvements:</p>
         <ul>
           <li>
-            <p>Log the TLS version and the the cipher when debug 2 is enabled.</p>
+            <p>Disable filter{banners-by-size} for .freiheitsfoo.de/.</p>
           </li>
           <li>
-            <p>ssl_send_certificate_error(): Respect HEAD requests by not sending a body.</p>
+            <p>Disable filter{banners-by-size} for freebsdfoundation.org/.</p>
           </li>
           <li>
-            <p>ssl_send_certificate_error(): End the body with a single new line.</p>
+            <p>Disable fast-redirects for consent.youtube.com/.</p>
           </li>
           <li>
-            <p>serve(): Increase the chances that the host is logged when closing a server socket.</p>
+            <p>Block requests to ups.xplosion.de/.</p>
           </li>
           <li>
-            <p>handle_established_connection(): Add parentheses to clarify an expression Suggested by: David
-            Binderman</p>
+            <p>Block requests for elsa.memoinsights.com/t.</p>
           </li>
           <li>
-            <p>continue_https_chat(): Explicitly unset CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE if
-            process_encrypted_request() fails. This makes it more obvious that the connection will not be reused.
-            Previously serve() relied on CSP_FLAG_SERVER_CONTENT_LENGTH_SET and CSP_FLAG_CHUNKED being unset. Inspired
-            by a patch from Joshua Rogers (Opera).</p>
+            <p>Fix a typo in a test.</p>
           </li>
           <li>
-            <p>decompress_iob(): Add periods to a couple of log messages</p>
+            <p>Disable fast-redirects for launchpad.net/.</p>
           </li>
           <li>
-            <p>Terminate the body of the HTTP snipplets with a single new line instead of "\r\n".</p>
+            <p>Unblock .eff.org/.</p>
           </li>
           <li>
-            <p>configure: Add --with-assertions option and only enable assertions when it is used</p>
+            <p>Stop unblocking .org/.*(image|banner) which appears to be too generous The example URL
+            http://www.gnu.org/graphics/gnu-head-banner.png is already unblocked due to .gnu.org being unblocked.</p>
           </li>
           <li>
-            <p>windows build: Use --with-brotli and --with-mbedtls by default and enable dynamic error checking.</p>
+            <p>Unblock adfd.org/.</p>
           </li>
           <li>
-            <p>gif_deanimate(): Confirm we've got an image before trying to write it Saves a pointless buf_copy()
-            call.</p>
+            <p>Disable filter{banners-by-link} for .eff.org/.</p>
           </li>
           <li>
-            <p>OpenSSL ssl_store_cert(): Remove a superfluous space before the serial number.</p>
+            <p>Block requests to odb.outbrain.com/.</p>
+          </li>
+          <li>
+            <p>Disable fast-redirects for .gandi.net/.</p>
           </li>
-        </ul>
-      </li>
-      <li>
-        <p>Action file improvements:</p>
-        <ul>
           <li>
-            <p>Disable fast-redirects for .golem.de/</p>
+            <p>Disable fast-redirects{} for .onion/.*/status/.</p>
           </li>
           <li>
-            <p>Unblock requests to adri*.</p>
+            <p>Disable fast-redirects{} for twitter.com/.*/status/.</p>
           </li>
           <li>
-            <p>Block requests for trc*.taboola.com/</p>
+            <p>Unblock pinkstinks.de/.</p>
           </li>
           <li>
-            <p>Disable fast-redirects for .linkedin.com/</p>
+            <p>Disable fast-redirects for .hagalil.com/.</p>
           </li>
         </ul>
       </li>
       <li>
-        <p>Filter file improvements:</p>
+        <p>Privoxy-Log-Parser:</p>
         <ul>
           <li>
-            <p>Make the second pcrs job of the img-reorder filter greedy again. The ungreedy version broke the img tags
-            on: https://bulk.fefe.de/scalability/.</p>
+            <p>Bump version to 0.9.5.</p>
+          </li>
+          <li>
+            <p>Highlight more log messages.</p>
+          </li>
+          <li>
+            <p>Highlight the Crunch reason only once. Previously the "crunch reason" could also be highlighted when the
+            URL contained a matching string. The real crunch reason only occurs once per line, so there's no need to
+            continue looking for it after it has been found once. While at it, add a comment with an example log
+            line.</p>
           </li>
         </ul>
       </li>
       <li>
-        <p>Privoxy-Log-Parser:</p>
+        <p>uagen:</p>
         <ul>
           <li>
-            <p>Highlight a few more messages.</p>
+            <p>Bump version to 1.2.4.</p>
+          </li>
+          <li>
+            <p>Update BROWSER_VERSION and BROWSER_REVISION to 102.0 to match the User-Agent of the current Firefox
+            ESR.</p>
+          </li>
+          <li>
+            <p>Explicitly document that changing the 'Gecko token' is suspicious.</p>
+          </li>
+          <li>
+            <p>Consistently use a lower-case 'c' as copyright symbol.</p>
+          </li>
+          <li>
+            <p>Bump copyright.</p>
+          </li>
+          <li>
+            <p>Add 'aarch64' as Linux architecture.</p>
           </li>
           <li>
-            <p>Clarify the --statistics output. The shown "Reused connections" are server connections so name them
-            appropriately.</p>
+            <p>Add OpenBSD architecture 'arm64'.</p>
           </li>
           <li>
-            <p>Bump version to 0.9.3.</p>
+            <p>Stop using sparc64 as FreeBSD architecture. It hasn't been supported for a while now.</p>
           </li>
         </ul>
       </li>
       <li>
-        <p>Privoxy-Regression-Test:</p>
+        <p>Build system:</p>
         <ul>
           <li>
-            <p>Add the --check-bad-ssl option to the --help output.</p>
+            <p>Makefile: Add a 'dok' target that depends on the 'error' target to show the "You are not using GNU make
+            or did nor run configure" message.</p>
           </li>
           <li>
-            <p>Bump version to 0.7.3.</p>
+            <p>configure: Fix --with-msan option. Also (probably) reported by Andrew Savchenko.</p>
+          </li>
+        </ul>
+      </li>
+      <li>
+        <p>macOS build system:</p>
+        <ul>
+          <li>
+            <p>Enable HTTPS inspection when building the macOS binary (using OpenSSL as TLS library).</p>
           </li>
         </ul>
       </li>
         <p>Documentation:</p>
         <ul>
           <li>
-            <p>Add pushing the created tag to the release steps in the developer manual.</p>
+            <p>Add OpenSSL to the list of libraries that may be licensed under the Apache 2.0 license in which case the
+            linked Privoxy binary has to be distributed under the GPLv3 or later.</p>
+          </li>
+          <li>
+            <p>config: Fix the documented ca-directory default value. Reported by avoidr.</p>
+          </li>
+          <li>
+            <p>Rebuild developer-manual and tidy with 'HTML Tidy for FreeBSD version 5.8.0'.</p>
+          </li>
+          <li>
+            <p>Update developer manual with new macOS packaging instructions.</p>
           </li>
           <li>
-            <p>Clarify that 'debug 32768' should be used in addition to the other debug directives when reporting
-            problems.</p>
+            <p>Note that the FreeBSD installation instructions work for ElectroBSD as well.</p>
           </li>
           <li>
-            <p>Add a 'Third-party licenses and copyrights' section to the user manual.</p>
+            <p>Note that FreeBSD/ElectroBSD users can try to install Privoxy as binary package using 'pkg'.</p>
           </li>
         </ul>
       </li>
index e1d9925..27bb4e0 100644 (file)
--- a/errlog.c
+++ b/errlog.c
@@ -659,11 +659,11 @@ void log_error(int loglevel, const char *fmt, ...)
 
 #if defined(_WIN32) && !defined(_WIN_CONSOLE)
    /*
-    * Irrespective of debug setting, a GET/POST/CONNECT makes
-    * the taskbar icon animate.  (There is an option to disable
-    * this but checking that is handled inside LogShowActivity()).
+    * Irrespective of debug setting, a request makes the taskbar icon
+    * animate. (There is an option to disable this but checking that is
+    * handled inside LogShowActivity()).
     */
-   if ((loglevel == LOG_LEVEL_REQUEST) || (loglevel == LOG_LEVEL_CRUNCH))
+   if (loglevel == LOG_LEVEL_REQUEST)
    {
       LogShowActivity();
    }
index ab20038..9915bf5 100644 (file)
--- a/filters.c
+++ b/filters.c
@@ -74,7 +74,7 @@
 #include "win32.h"
 #endif
 
-typedef char *(*filter_function_ptr)();
+typedef char *(*filter_function_ptr)(struct client_state *csp);
 static filter_function_ptr get_filter_function(const struct client_state *csp);
 static jb_err prepare_for_filtering(struct client_state *csp);
 static void apply_url_actions(struct current_action_spec *action,
@@ -173,6 +173,14 @@ static int match_sockaddr(const struct sockaddr_storage *network,
    in_port_t *network_port, *netmask_port, *address_port;
    int i;
 
+   network_addr = NULL;
+   netmask_addr = NULL;
+   address_addr = NULL;
+   addr_len = 0;
+   network_port = NULL;
+   netmask_port = NULL;
+   address_port = NULL;
+
    if (network->ss_family != netmask->ss_family)
    {
       /* This should never happen */
@@ -334,6 +342,10 @@ int acl_addr(const char *aspec, struct access_control_addr *aca)
    char *p;
    char *acl_spec = NULL;
 
+   mask_data = NULL;
+   mask_port = NULL;
+   addr_len = 0;
+
 #ifdef HAVE_RFC2553
    /* XXX: Depend on ai_family */
    masklength = 128;
@@ -2113,6 +2125,172 @@ static filter_function_ptr get_filter_function(const struct client_state *csp)
 }
 
 
+/*********************************************************************
+ *
+ * Function    :  get_bytes_to_next_chunk_start
+ *
+ * Description :  Returns the number of bytes to the start of the
+ *                next chunk in the buffer.
+ *
+ * Parameters  :
+ *          1  :  buffer = Pointer to the text buffer
+ *          2  :  size = Number of bytes in the buffer.
+ *          3  :  offset = Where to expect the beginning of the next chunk.
+ *
+ * Returns     :  -1 if the size can't be determined or data is missing,
+ *                otherwise the number of bytes to the start of the next chunk
+ *                or 0 if the last chunk has been fully buffered.
+ *
+ *********************************************************************/
+static int get_bytes_to_next_chunk_start(char *buffer, size_t size, size_t offset)
+{
+   char *chunk_start;
+   char *p;
+   unsigned int chunk_size = 0;
+   int bytes_to_skip;
+
+   if (size <= offset || size < 5)
+   {
+      /*
+       * Not enough bytes bufferd to figure
+       * out the size of the next chunk.
+       */
+      return -1;
+   }
+
+   chunk_start = buffer + offset;
+
+   p = strstr(chunk_start, "\r\n");
+   if (NULL == p)
+   {
+      /*
+       * The line with the chunk-size hasn't been completely received
+       * yet (or is invalid).
+       */
+      log_error(LOG_LEVEL_RE_FILTER,
+         "Not enough or invalid data in buffer in chunk size line.");
+      return -1;
+   }
+
+   if (sscanf(chunk_start, "%x", &chunk_size) != 1)
+   {
+      /* XXX: Write test case to trigger this. */
+      log_error(LOG_LEVEL_ERROR, "Failed to parse chunk size. "
+         "Size: %lu, offset: %lu. Chunk size start: %N", size, offset,
+         (size - offset), chunk_start);
+      return -1;
+   }
+
+   /*
+    * To get to the start of the next chunk size we have to skip
+    * the line with the current chunk size followed by "\r\n" followd
+    * by the actual data and another "\r\n" following the data.
+    */
+   bytes_to_skip = (int)(p - chunk_start) + 2 + (int)chunk_size + 2;
+
+   if (bytes_to_skip <= 0)
+   {
+      log_error(LOG_LEVEL_ERROR,
+         "Failed to figure out chunk offset. %u and %d seem dubious.",
+         chunk_size, bytes_to_skip);
+      return -1;
+   }
+   if (chunk_size == 0)
+   {
+      if (bytes_to_skip <= (size - offset))
+      {
+         return 0;
+      }
+      else
+      {
+         log_error(LOG_LEVEL_INFO,
+            "Last chunk detected but we're still missing data.");
+         return -1;
+      }
+   }
+
+   return bytes_to_skip;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  get_bytes_missing_from_chunked_data
+ *
+ * Description :  Figures out how many bytes of data we need to get
+ *                to the start of the next chunk of data (XXX: terminology).
+ *                Due to the nature of chunk-encoded data we can only see
+ *                how many data is missing according to the last chunk size
+ *                buffered.
+ *
+ * Parameters  :
+ *          1  :  buffer = Pointer to the text buffer
+ *          2  :  size = Number of bytes in the buffer.
+ *          3  :  offset = Where to expect the beginning of the next chunk.
+ *
+ * Returns     :  -1 if the data can't be parsed (yet),
+ *                 0 if the buffer is complete or a
+ *                 number of bytes that is missing.
+ *
+ *********************************************************************/
+int get_bytes_missing_from_chunked_data(char *buffer, size_t size, size_t offset)
+{
+   int ret = -1;
+   int last_valid_offset = -1;
+
+   if (size < offset || size < 5)
+   {
+      /* Not enough data buffered yet */
+      return -1;
+   }
+
+   do
+   {
+      ret = get_bytes_to_next_chunk_start(buffer, size, offset);
+      if (ret == -1)
+      {
+         return last_valid_offset;
+      }
+      if (ret == 0)
+      {
+         return 0;
+      }
+      if (offset != 0)
+      {
+         last_valid_offset = (int)offset;
+      }
+      offset += (size_t)ret;
+   } while (offset < size);
+
+   return (int)offset;
+
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  chunked_data_is_complete
+ *
+ * Description :  Detects if a buffer with chunk-encoded data looks
+ *                complete.
+ *
+ * Parameters  :
+ *          1  :  buffer = Pointer to the text buffer
+ *          2  :  size = Number of bytes in the buffer.
+ *          3  :  offset = Where to expect the beginning of the
+ *                         first complete chunk.
+ *
+ * Returns     :  TRUE if it looks like the data is complete,
+ *                FALSE otherwise.
+ *
+ *********************************************************************/
+int chunked_data_is_complete(char *buffer, size_t size, size_t offset)
+{
+   return (0 == get_bytes_missing_from_chunked_data(buffer, size, offset));
+
+}
+
+
 /*********************************************************************
  *
  * Function    :  remove_chunked_transfer_coding
@@ -2151,6 +2329,18 @@ static jb_err remove_chunked_transfer_coding(char *buffer, size_t *size)
    assert(buffer);
    from_p = to_p = buffer;
 
+#ifndef FUZZ
+   /*
+    * Refuse to de-chunk invalid or incomplete data unless we're fuzzing.
+    */
+   if (!chunked_data_is_complete(buffer, *size, 0))
+   {
+      log_error(LOG_LEVEL_ERROR,
+         "Chunk-encoding appears to be invalid. Content can't be filtered.");
+      return JB_ERR_PARSE;
+   }
+#endif
+
    if (sscanf(buffer, "%x", &chunksize) != 1)
    {
       log_error(LOG_LEVEL_ERROR, "Invalid first chunksize while stripping \"chunked\" transfer coding");
@@ -2180,7 +2370,9 @@ static jb_err remove_chunked_transfer_coding(char *buffer, size_t *size)
        */
       if (NULL == (from_p = strstr(from_p, "\r\n")))
       {
-         log_error(LOG_LEVEL_ERROR, "Parse error while stripping \"chunked\" transfer coding");
+         log_error(LOG_LEVEL_ERROR,
+            "Failed to strip \"chunked\" transfer coding. "
+            "Line with chunk size doesn't seem to end properly.");
          return JB_ERR_PARSE;
       }
       from_p += 2;
@@ -2195,7 +2387,8 @@ static jb_err remove_chunked_transfer_coding(char *buffer, size_t *size)
       if (from_p + chunksize >= end_of_buffer)
       {
          log_error(LOG_LEVEL_ERROR,
-            "End of chunk is beyond the end of the buffer.");
+            "Failed to decode content for filtering. "
+            "One chunk end is beyond the end of the buffer.");
          return JB_ERR_PARSE;
       }
 
@@ -2347,8 +2540,10 @@ char *execute_content_filters(struct client_state *csp)
    if (JB_ERR_OK != prepare_for_filtering(csp))
    {
       /*
-       * failed to de-chunk or decompress.
+       * We failed to de-chunk or decompress, don't accept
+       * another request on the client connection.
        */
+      csp->flags &= ~CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE;
       return NULL;
    }
 
@@ -2404,21 +2599,20 @@ char *execute_content_filters(struct client_state *csp)
  * Function    :  execute_client_body_filters
  *
  * Description :  Executes client body filters for the request that is buffered
- *                in the client_iob. Upon success moves client_iob cur pointer
- *                to the end of the processed data.
+ *                in the client_iob. The client_iob is updated with the filtered
+ *                content.
  *
  * Parameters  :
  *          1  :  csp = Current client state (buffers, headers, etc...)
  *          2  :  content_length = content length. Upon successful filtering
  *                the passed value is updated with the new content length.
  *
- * Returns     :  Pointer to the modified buffer, or
- *                NULL if filtering failed or wasn't necessary.
+ * Returns     :  1 if the content has been filterd. 0 if it hasn't.
  *
  *********************************************************************/
-char *execute_client_body_filters(struct client_state *csp, size_t *content_length)
+int execute_client_body_filters(struct client_state *csp, size_t *content_length)
 {
-   char *ret;
+   char *filtered_content;
 
    assert(client_body_filters_enabled(csp->action));
 
@@ -2427,15 +2621,193 @@ char *execute_client_body_filters(struct client_state *csp, size_t *content_leng
       /*
        * No content, no filtering necessary.
        */
-      return NULL;
+      return 0;
+   }
+
+   filtered_content = pcrs_filter_request_body(csp, csp->client_iob->cur, content_length);
+   if (filtered_content != NULL)
+   {
+      freez(csp->client_iob->buf);
+      csp->client_iob->buf  = filtered_content;
+      csp->client_iob->cur  = csp->client_iob->buf;
+      csp->client_iob->eod  = csp->client_iob->cur + *content_length;
+      csp->client_iob->size = *content_length;
+
+      return 1;
    }
+   
+   return 0;
+}
 
-   ret = pcrs_filter_request_body(csp, csp->client_iob->cur, content_length);
-   if (ret != NULL)
+
+/*********************************************************************
+ *
+ * Function    :  execute_client_body_taggers
+ *
+ * Description :  Executes client body taggers for the request that is
+ *                buffered in the client_iob.
+ *                XXX: Lots of code shared with header_tagger
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  content_length = content length.
+ *
+ * Returns     :  XXX
+ *
+ *********************************************************************/
+jb_err execute_client_body_taggers(struct client_state *csp, size_t content_length)
+{
+   enum filter_type wanted_filter_type = FT_CLIENT_BODY_TAGGER;
+   int multi_action_index = ACTION_MULTI_CLIENT_BODY_TAGGER;
+   pcrs_job *job;
+
+   struct re_filterfile_spec *b;
+   struct list_entry *tag_name;
+
+   assert(client_body_taggers_enabled(csp->action));
+
+   if (content_length == 0)
    {
-      csp->client_iob->cur = csp->client_iob->eod;
+      /*
+       * No content, no tagging necessary.
+       */
+      return JB_ERR_OK;
    }
-   return ret;
+
+   log_error(LOG_LEVEL_INFO, "Got to execute tagger on %N",
+      content_length, csp->client_iob->cur);
+
+   if (list_is_empty(csp->action->multi[multi_action_index])
+      || filters_available(csp) == FALSE)
+   {
+      /* Return early if no taggers apply or if none are available. */
+      return JB_ERR_OK;
+   }
+
+   /* Execute all applying taggers */
+   for (tag_name = csp->action->multi[multi_action_index]->first;
+        NULL != tag_name; tag_name = tag_name->next)
+   {
+      char *modified_tag = NULL;
+      char *tag = csp->client_iob->cur;
+      size_t size = content_length;
+      pcrs_job *joblist;
+
+      b = get_filter(csp, tag_name->str, wanted_filter_type);
+      if (b == NULL)
+      {
+         continue;
+      }
+
+      joblist = b->joblist;
+
+      if (b->dynamic) joblist = compile_dynamic_pcrs_job_list(csp, b);
+
+      if (NULL == joblist)
+      {
+         log_error(LOG_LEVEL_TAGGING,
+            "Tagger %s has empty joblist. Nothing to do.", b->name);
+         continue;
+      }
+
+      /* execute their pcrs_joblist on the body. */
+      for (job = joblist; NULL != job; job = job->next)
+      {
+         const int hits = pcrs_execute(job, tag, size, &modified_tag, &size);
+
+         if (0 < hits)
+         {
+            /* Success, continue with the modified version. */
+            if (tag != csp->client_iob->cur)
+            {
+               freez(tag);
+            }
+            tag = modified_tag;
+         }
+         else
+         {
+            /* Tagger doesn't match */
+            if (0 > hits)
+            {
+               /* Regex failure, log it but continue anyway. */
+               log_error(LOG_LEVEL_ERROR,
+                  "Problems with tagger \'%s\': %s",
+                  b->name, pcrs_strerror(hits));
+            }
+            freez(modified_tag);
+         }
+      }
+
+      if (b->dynamic) pcrs_free_joblist(joblist);
+
+      /* If this tagger matched */
+      if (tag != csp->client_iob->cur)
+      {
+         if (0 == size)
+         {
+            /*
+             * There is no technical limitation which makes
+             * it impossible to use empty tags, but I assume
+             * no one would do it intentionally.
+             */
+            freez(tag);
+            log_error(LOG_LEVEL_TAGGING,
+               "Tagger \'%s\' created an empty tag. Ignored.", b->name);
+            continue;
+         }
+
+         if (list_contains_item(csp->action->multi[ACTION_MULTI_SUPPRESS_TAG], tag))
+         {
+            log_error(LOG_LEVEL_TAGGING,
+               "Tagger \'%s\' didn't add tag \'%s\': suppressed",
+               b->name, tag);
+            freez(tag);
+            continue;
+         }
+
+         if (!list_contains_item(csp->tags, tag))
+         {
+            if (JB_ERR_OK != enlist(csp->tags, tag))
+            {
+               log_error(LOG_LEVEL_ERROR,
+                  "Insufficient memory to add tag \'%s\', "
+                  "based on tagger \'%s\'",
+                  tag, b->name);
+            }
+            else
+            {
+               char *action_message;
+               /*
+                * update the action bits right away, to make
+                * tagging based on tags set by earlier taggers
+                * of the same kind possible.
+                */
+               if (update_action_bits_for_tag(csp, tag))
+               {
+                  action_message = "Action bits updated accordingly.";
+               }
+               else
+               {
+                  action_message = "No action bits update necessary.";
+               }
+
+               log_error(LOG_LEVEL_TAGGING,
+                  "Tagger \'%s\' added tag \'%s\'. %s",
+                  b->name, tag, action_message);
+            }
+         }
+         else
+         {
+            /* XXX: Is this log-worthy? */
+            log_error(LOG_LEVEL_TAGGING,
+               "Tagger \'%s\' didn't add tag \'%s\'. Tag already present",
+               b->name, tag);
+         }
+         freez(tag);
+      }
+   }
+
+   return JB_ERR_OK;
 }
 
 
@@ -2881,6 +3253,24 @@ int client_body_filters_enabled(const struct current_action_spec *action)
 }
 
 
+/*********************************************************************
+ *
+ * Function    :  client_body_taggers_enabled
+ *
+ * Description :  Checks whether there are any client body taggers
+ *                enabled for the current request.
+ *
+ * Parameters  :
+ *          1  :  action = Action spec to check.
+ *
+ * Returns     :  TRUE for yes, FALSE otherwise
+ *
+ *********************************************************************/
+int client_body_taggers_enabled(const struct current_action_spec *action)
+{
+   return !list_is_empty(action->multi[ACTION_MULTI_CLIENT_BODY_TAGGER]);
+}
+
 /*********************************************************************
  *
  * Function    :  filters_available
@@ -3082,14 +3472,14 @@ void register_block_reason_for_statistics(const char *block_reason)
 {
    struct block_statistics_entry *entry;
 
-   privoxy_mutex_lock(&block_statistics_mutex);
+   privoxy_mutex_lock(&block_reason_statistics_mutex);
 
    if (block_statistics == NULL)
    {
       block_statistics = zalloc_or_die(sizeof(struct block_statistics_entry));
       entry = block_statistics;
       entry->block_reason = strdup_or_die(block_reason);
-      privoxy_mutex_unlock(&block_statistics_mutex);
+      privoxy_mutex_unlock(&block_reason_statistics_mutex);
       return;
    }
    entry = block_statistics;
@@ -3109,7 +3499,7 @@ void register_block_reason_for_statistics(const char *block_reason)
       entry = entry->next;
    }
 
-   privoxy_mutex_unlock(&block_statistics_mutex);
+   privoxy_mutex_unlock(&block_reason_statistics_mutex);
 
 }
 
@@ -3130,7 +3520,7 @@ static void increment_block_reason_counter(const char *block_reason)
 {
    struct block_statistics_entry *entry;
 
-   privoxy_mutex_lock(&block_statistics_mutex);
+   privoxy_mutex_lock(&block_reason_statistics_mutex);
 
    entry = block_statistics;
    while (entry != NULL)
@@ -3143,7 +3533,7 @@ static void increment_block_reason_counter(const char *block_reason)
       entry = entry->next;
    }
 
-   privoxy_mutex_unlock(&block_statistics_mutex);
+   privoxy_mutex_unlock(&block_reason_statistics_mutex);
 
 }
 
@@ -3166,7 +3556,7 @@ void get_block_reason_count(const char *block_reason, unsigned long long *count)
 {
    struct block_statistics_entry *entry;
 
-   privoxy_mutex_lock(&block_statistics_mutex);
+   privoxy_mutex_lock(&block_reason_statistics_mutex);
 
    entry = block_statistics;
    while (entry != NULL)
@@ -3179,7 +3569,7 @@ void get_block_reason_count(const char *block_reason, unsigned long long *count)
       entry = entry->next;
    }
 
-   privoxy_mutex_unlock(&block_statistics_mutex);
+   privoxy_mutex_unlock(&block_reason_statistics_mutex);
 
 }
 
index e16a3ea..54873af 100644 (file)
--- a/filters.h
+++ b/filters.h
@@ -84,7 +84,8 @@ extern const struct forward_spec *forward_url(struct client_state *csp,
  * Content modification
  */
 extern char *execute_content_filters(struct client_state *csp);
-extern char *execute_client_body_filters(struct client_state *csp, size_t *filtered_data_len);
+extern int execute_client_body_filters(struct client_state *csp, size_t *content_length);
+extern jb_err execute_client_body_taggers(struct client_state *csp, size_t content_length);
 extern char *execute_single_pcrs_command(char *subject, const char *pcrs_command, int *hits);
 extern char *rewrite_url(char *old_url, const char *pcrs_command);
 
@@ -93,6 +94,7 @@ extern pcrs_job *compile_dynamic_pcrs_job_list(const struct client_state *csp, c
 extern int content_requires_filtering(struct client_state *csp);
 extern int content_filters_enabled(const struct current_action_spec *action);
 extern int client_body_filters_enabled(const struct current_action_spec *action);
+extern int client_body_taggers_enabled(const struct current_action_spec *action);
 extern int filters_available(const struct client_state *csp);
 
 /*
@@ -100,6 +102,9 @@ extern int filters_available(const struct client_state *csp);
  */
 extern struct http_response *direct_response(struct client_state *csp);
 
+extern int get_bytes_missing_from_chunked_data(char *buffer, size_t size, size_t offset);
+extern int chunked_data_is_complete(char *buffer, size_t size, size_t offset);
+
 #ifdef FUZZ
 extern char *gif_deanimate_response(struct client_state *csp);
 extern jb_err remove_chunked_transfer_coding(char *buffer, size_t *size);
index f1a2074..f2cc2ee 100644 (file)
--- a/gateway.c
+++ b/gateway.c
@@ -6,7 +6,7 @@
  *                using a "forwarder" (i.e. HTTP proxy and/or a SOCKS4
  *                or SOCKS5 proxy).
  *
- * Copyright   :  Written by and Copyright (C) 2001-2020 the
+ * Copyright   :  Written by and Copyright (C) 2001-2023 the
  *                Privoxy team. https://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
@@ -837,7 +837,13 @@ static jb_socket socks4_connect(const struct forward_spec *fwd,
 
    /* build a socks request for connection to the web server */
 
-   strlcpy(&(c->userid), socks_userid, sizeof(buf) - sizeof(struct socks_op));
+   /*
+    * The more straightforward &(c->userid) destination pointer can
+    * cause some gcc versions to misidentify the size of the destination
+    * buffer, tripping the runtime check of glibc's source fortification.
+    */
+   strlcpy(buf + offsetof(struct socks_op, userid), socks_userid,
+      sizeof(buf) - sizeof(struct socks_op));
 
    csiz = sizeof(*c) + sizeof(socks_userid) - sizeof(c->userid) - sizeof(c->padding);
 
@@ -1029,6 +1035,101 @@ static const char *translate_socks5_error(int socks_error)
 }
 
 
+/*********************************************************************
+ *
+ * Function    :  convert_ipv4_address_to_bytes
+ *
+ * Description :  Converts an IPv4 address from string to bytes.
+ *
+ * Parameters  :
+ *          1  :  address = The IPv4 address string to convert.
+ *          2  :  buf = The buffer to write the bytes to.
+ *                      Must be at least four bytes long.
+ *
+ * Returns     :  JB_ERR_OK on success, JB_ERR_PARSE otherwise.
+ *
+ *********************************************************************/
+static jb_err convert_ipv4_address_to_bytes(const char *address, char *buf)
+{
+   int i;
+   const char *p = address;
+
+   for (i = 0; i < 4; i++)
+   {
+      unsigned byte;
+      if (1 != sscanf(p, "%u", &byte))
+      {
+         return JB_ERR_PARSE;
+      }
+      if (byte > 255)
+      {
+         return JB_ERR_PARSE;
+      }
+      buf[i] = (char)byte;
+      if (i < 3)
+      {
+         p = strstr(p, ".");
+         if (p == NULL)
+         {
+            return JB_ERR_PARSE;
+         }
+         p++;
+      }
+   }
+
+   return JB_ERR_OK;
+
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  read_socks_reply
+ *
+ * Description :  Read from a socket connected to a socks server.
+ *
+ * Parameters  :
+ *          1  :  sfd = file descriptor of the socket to read
+ *          2  :  buf = pointer to buffer where data will be written
+ *                Must be >= len bytes long.
+ *          3  :  len = maximum number of bytes to read
+ *          4  :  timeout = Number of seconds to wait.
+ *
+ * Returns     :  On success, the number of bytes read is returned (zero
+ *                indicates end of file), and the file position is advanced
+ *                by this number.  It is not an error if this number is
+ *                smaller than the number of bytes requested; this may hap-
+ *                pen for example because fewer bytes are actually available
+ *                right now (maybe because we were close to end-of-file, or
+ *                because we are reading from a pipe, or from a terminal,
+ *                or because read() was interrupted by a signal).  On error,
+ *                -1 is returned, and errno is set appropriately.  In this
+ *                case it is left unspecified whether the file position (if
+ *                any) changes.
+ *
+ *********************************************************************/
+static int read_socks_reply(jb_socket sfd, char *buf, int len, int timeout)
+{
+   if (!data_is_available(sfd, timeout))
+   {
+      if (socket_is_still_alive(sfd))
+      {
+         log_error(LOG_LEVEL_ERROR,
+            "The socks connection timed out after %d seconds.", timeout);
+      }
+      else
+      {
+         log_error(LOG_LEVEL_ERROR, "The socks server hung "
+            "up the connection without sending a response.");
+      }
+      return -1;
+   }
+
+   return read_socket(sfd, buf, len);
+
+}
+
+
 /*********************************************************************
  *
  * Function    :  socks5_connect
@@ -1055,10 +1156,11 @@ static jb_socket socks5_connect(const struct forward_spec *fwd,
 {
 #define SIZE_SOCKS5_REPLY_IPV4 10
 #define SIZE_SOCKS5_REPLY_IPV6 22
+#define SIZE_SOCKS5_REPLY_DOMAIN 300
 #define SOCKS5_REPLY_DIFFERENCE (SIZE_SOCKS5_REPLY_IPV6 - SIZE_SOCKS5_REPLY_IPV4)
    int err = 0;
    char cbuf[300];
-   char sbuf[SIZE_SOCKS5_REPLY_IPV6];
+   char sbuf[SIZE_SOCKS5_REPLY_DOMAIN];
    size_t client_pos = 0;
    int server_size = 0;
    size_t hostlen = 0;
@@ -1146,20 +1248,8 @@ static jb_socket socks5_connect(const struct forward_spec *fwd,
       close_socket(sfd);
       return(JB_INVALID_SOCKET);
    }
-   if (!data_is_available(sfd, csp->config->socket_timeout))
-   {
-      if (socket_is_still_alive(sfd))
-      {
-         errstr = "SOCKS5 negotiation timed out";
-      }
-      else
-      {
-         errstr = "SOCKS5 negotiation got aborted by the server";
-      }
-      err = 1;
-   }
-
-   if (!err && read_socket(sfd, sbuf, sizeof(sbuf)) != 2)
+   if (read_socks_reply(sfd, sbuf, sizeof(sbuf),
+         csp->config->socket_timeout) != 2)
 #endif
    {
       errstr = "SOCKS5 negotiation read failed";
@@ -1218,7 +1308,8 @@ static jb_socket socks5_connect(const struct forward_spec *fwd,
             return(JB_INVALID_SOCKET);
          }
 
-         if (read_socket(sfd, sbuf, sizeof(sbuf)) != 2)
+         if (read_socks_reply(sfd, sbuf, sizeof(sbuf),
+               csp->config->socket_timeout) != 2)
          {
             errstr = "SOCKS5 negotiation auth read failed";
             err = 1;
@@ -1251,12 +1342,32 @@ static jb_socket socks5_connect(const struct forward_spec *fwd,
    cbuf[client_pos++] = '\x05'; /* Version */
    cbuf[client_pos++] = '\x01'; /* TCP connect */
    cbuf[client_pos++] = '\x00'; /* Reserved, must be 0x00 */
-   cbuf[client_pos++] = '\x03'; /* Address is domain name */
-   cbuf[client_pos++] = (char)(hostlen & 0xffu);
-   assert(sizeof(cbuf) - client_pos > (size_t)255);
-   /* Using strncpy because we really want the nul byte padding. */
-   strncpy(cbuf + client_pos, target_host, sizeof(cbuf) - client_pos - 1);
-   client_pos += (hostlen & 0xffu);
+   if (host_is_ip_address(target_host) && NULL == strstr(target_host, ":"))
+   {
+      cbuf[client_pos++] = '\x01'; /* Address is IPv4 address. */
+      if (JB_ERR_OK != convert_ipv4_address_to_bytes(target_host, &cbuf[client_pos]))
+      {
+         errstr = "SOCKS5 error. Failed to convert target address to IP address";
+         csp->error_message = strdup(errstr);
+         log_error(LOG_LEVEL_CONNECT, "%s", errstr);
+         close_socket(sfd);
+         errno = EINVAL;
+         return(JB_INVALID_SOCKET);
+      }
+      client_pos += 4;
+   }
+   else
+   {
+      /*
+       * XXX: This branch is currently also used for IPv6 addresses
+       */
+      cbuf[client_pos++] = '\x03'; /* Address is domain name. */
+      cbuf[client_pos++] = (char)(hostlen & 0xffu);
+      assert(sizeof(cbuf) - client_pos > (size_t)255);
+      /* Using strncpy because we really want the nul byte padding. */
+      strncpy(cbuf + client_pos, target_host, sizeof(cbuf) - client_pos - 1);
+      client_pos += (hostlen & 0xffu);
+   }
    cbuf[client_pos++] = (char)((target_port >> 8) & 0xff);
    cbuf[client_pos++] = (char)((target_port     ) & 0xff);
 
@@ -1286,13 +1397,13 @@ static jb_socket socks5_connect(const struct forward_spec *fwd,
 
       if (client_headers == NULL)
       {
-         log_error(LOG_LEVEL_FATAL, "Out of memory rebuilding client headers");
+         log_error(LOG_LEVEL_FATAL, "Out of memory rebuilding client headers.");
       }
       list_remove_all(csp->headers);
       header_length= strlen(client_headers);
 
       log_error(LOG_LEVEL_CONNECT,
-         "Optimistically sending %lu bytes of client headers intended for %s",
+         "Optimistically sending %lu bytes of client headers intended for %s.",
          header_length, csp->http->hostport);
 
       if (write_socket(sfd, client_headers, header_length))
@@ -1308,7 +1419,7 @@ static jb_socket socks5_connect(const struct forward_spec *fwd,
          unsigned long long buffered_request_bytes =
             (unsigned long long)(csp->client_iob->eod - csp->client_iob->cur);
          log_error(LOG_LEVEL_CONNECT,
-            "Optimistically sending %llu bytes of client body. Expected %llu",
+            "Optimistically sending %llu bytes of client body. Expected %llu.",
             csp->expected_client_content_length, buffered_request_bytes);
          assert(csp->expected_client_content_length == buffered_request_bytes);
          if (write_socket(sfd, csp->client_iob->cur, buffered_request_bytes))
@@ -1323,7 +1434,8 @@ static jb_socket socks5_connect(const struct forward_spec *fwd,
    }
 #endif
 
-   server_size = read_socket(sfd, sbuf, SIZE_SOCKS5_REPLY_IPV4);
+   server_size = read_socks_reply(sfd, sbuf, SIZE_SOCKS5_REPLY_IPV4,
+      csp->config->socket_timeout);
    if (server_size != SIZE_SOCKS5_REPLY_IPV4)
    {
       errstr = "SOCKS5 negotiation read failed";
@@ -1352,12 +1464,37 @@ static jb_socket socks5_connect(const struct forward_spec *fwd,
              * yet. Read and discard the rest of it to make
              * sure it isn't treated as HTTP data later on.
              */
-            server_size = read_socket(sfd, sbuf, SOCKS5_REPLY_DIFFERENCE);
+            server_size = read_socks_reply(sfd, sbuf, SOCKS5_REPLY_DIFFERENCE,
+               csp->config->socket_timeout);
             if (server_size != SOCKS5_REPLY_DIFFERENCE)
             {
                errstr = "SOCKS5 negotiation read failed (IPv6 address)";
             }
          }
+         else if (sbuf[3] == '\x03')
+         {
+            /*
+             * The address field contains a domain name
+             * which means we didn't get the whole reply
+             * yet. Read and discard the rest of it to make
+             * sure it isn't treated as HTTP data later on.
+             */
+            unsigned domain_length = (unsigned)sbuf[4];
+            int bytes_left_to_read = 5 + (int)domain_length + 2 - SIZE_SOCKS5_REPLY_IPV4;
+            if (bytes_left_to_read <= 0 || sizeof(sbuf) < bytes_left_to_read)
+            {
+               errstr = "SOCKS5 negotiation read failed (Invalid domain length)";
+            }
+            else
+            {
+               server_size = read_socks_reply(sfd, sbuf, bytes_left_to_read,
+                  csp->config->socket_timeout);
+               if (server_size != bytes_left_to_read)
+               {
+                  errstr = "SOCKS5 negotiation read failed (Domain name)";
+               }
+            }
+         }
          else if (sbuf[3] != '\x01')
          {
             errstr = "SOCKS5 reply contains unsupported address type";
index f3f5750..1c4db68 100644 (file)
@@ -7,7 +7,7 @@
  *                OS-independent.  Contains #ifdefs to make this work
  *                on many platforms.
  *
- * Copyright   :  Written by and Copyright (C) 2001-2017 the
+ * Copyright   :  Written by and Copyright (C) 2001-2022 the
  *                Privoxy team. https://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
@@ -850,7 +850,7 @@ void drain_and_close_socket(jb_socket fd)
             bytes_drained_total += bytes_drained;
             if (bytes_drained_total > ARBITRARY_DRAIN_LIMIT)
             {
-               log_error(LOG_LEVEL_CONNECT, "Giving up draining socket %d", fd);
+               log_error(LOG_LEVEL_CONNECT, "Giving up draining socket %d.", fd);
                break;
             }
          }
@@ -858,7 +858,7 @@ void drain_and_close_socket(jb_socket fd)
       if (bytes_drained_total != 0)
       {
          log_error(LOG_LEVEL_CONNECT,
-            "Drained %d bytes before closing socket %d", bytes_drained_total, fd);
+            "Drained %d bytes before closing socket %d.", bytes_drained_total, fd);
       }
    }
 
@@ -912,7 +912,7 @@ int bind_port(const char *hostnam, int portnum, int backlog, jb_socket *pfd)
    if ((-1 == retval) || (sizeof(servnam) <= retval))
    {
       log_error(LOG_LEVEL_ERROR,
-         "Port number (%d) ASCII decimal representation doesn't fit into 6 bytes",
+         "Port number (%d) ASCII decimal representation doesn't fit into 6 bytes.",
          portnum);
       return -1;
    }
@@ -1439,7 +1439,7 @@ int accept_connection(struct client_state * csp, jb_socket fds[])
    if ((-1 == retval) || listen_addr_size <= retval)
    {
       log_error(LOG_LEVEL_ERROR,
-         "Server name (%s) and port number (%d) ASCII decimal representation"
+         "Server name (%s) and port number (%d) ASCII decimal representation "
          "don't fit into %lu bytes",
          host_addr, csp->config->hport[i], listen_addr_size);
       return 0;
diff --git a/jcc.c b/jcc.c
index 659521c..0e110a3 100644 (file)
--- a/jcc.c
+++ b/jcc.c
@@ -5,7 +5,7 @@
  * Purpose     :  Main file.  Contains main() method, main loop, and
  *                the main connection-handling function.
  *
- * Copyright   :  Written by and Copyright (C) 2001-2021 the
+ * Copyright   :  Written by and Copyright (C) 2001-2023 the
  *                Privoxy team. https://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
@@ -127,6 +127,10 @@ struct file_list     files[1];
 #ifdef FEATURE_STATISTICS
 int urls_read     = 0;     /* total nr of urls read inc rejected */
 int urls_rejected = 0;     /* total nr of urls rejected */
+#ifdef MUTEX_LOCKS_AVAILABLE
+unsigned long long number_of_requests_received = 0;
+unsigned long long number_of_requests_blocked = 0;
+#endif
 #endif /* def FEATURE_STATISTICS */
 
 #ifdef FEATURE_GRACEFUL_TERMINATION
@@ -191,9 +195,12 @@ privoxy_mutex_t external_filter_mutex;
 #ifdef FEATURE_CLIENT_TAGS
 privoxy_mutex_t client_tags_mutex;
 #endif
+#ifdef FEATURE_STATISTICS
+privoxy_mutex_t block_statistics_mutex;
+#endif
 #ifdef FEATURE_EXTENDED_STATISTICS
 privoxy_mutex_t filter_statistics_mutex;
-privoxy_mutex_t block_statistics_mutex;
+privoxy_mutex_t block_reason_statistics_mutex;
 #endif
 
 #if !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_GETHOSTBYNAME_R)
@@ -281,6 +288,13 @@ static const char CLIENT_BODY_PARSE_ERROR_RESPONSE[] =
    "Connection: close\r\n\r\n"
    "Failed parsing or buffering the chunk-encoded client body.\n";
 
+static const char CLIENT_BODY_BUFFER_ERROR_RESPONSE[] =
+   "HTTP/1.1 400 Failed reading client body\r\n"
+   "Content-Type: text/plain\r\n"
+   "Connection: close\r\n\r\n"
+   "Failed to buffer the client body to apply content filters.\n"
+   "Could be caused by a socket timeout\n";
+
 static const char UNSUPPORTED_CLIENT_EXPECTATION_ERROR_RESPONSE[] =
    "HTTP/1.1 417 Expecting too much\r\n"
    "Content-Type: text/plain\r\n"
@@ -945,6 +959,11 @@ static int crunch_response_triggered(struct client_state *csp, const struct crun
 #ifdef FEATURE_STATISTICS
             if (c->flags & CF_COUNT_AS_REJECT)
             {
+#ifdef MUTEX_LOCKS_AVAILABLE
+               privoxy_mutex_lock(&block_statistics_mutex);
+               number_of_requests_blocked++;
+               privoxy_mutex_unlock(&block_statistics_mutex);
+#endif
                csp->flags |= CSP_FLAG_REJECTED;
             }
 #endif /* def FEATURE_STATISTICS */
@@ -1634,6 +1653,14 @@ extern int fuzz_chunked_transfer_encoding(struct client_state *csp, char *fuzz_i
    {
       log_error(LOG_LEVEL_INFO, "Chunked body is incomplete or invalid");
    }
+   if (get_bytes_missing_from_chunked_data(csp->iob->cur, size, 0) == 0)
+   {
+      if (CHUNK_STATUS_BODY_COMPLETE != status)
+      {
+         log_error(LOG_LEVEL_ERROR,
+            "There's disagreement about whether or not the chunked body is complete.");
+      }
+   }
 
    return (JB_ERR_OK == remove_chunked_transfer_coding(csp->iob->cur, &size));
 
@@ -1813,6 +1840,19 @@ static jb_err receive_client_request(struct client_state *csp)
       free_http_request(http);
       return JB_ERR_PARSE;
    }
+   if (http->ssl && strcmpic(http->gpc, "CONNECT"))
+   {
+      write_socket_delayed(csp->cfd, CHEADER, strlen(CHEADER),
+         get_write_delay(csp));
+      /* XXX: Use correct size */
+      log_error(LOG_LEVEL_CLF, "%s - - [%T] \"Invalid request\" 400 0",
+         csp->ip_addr_str);
+      log_error(LOG_LEVEL_ERROR, "Client %s tried to send a https "
+         "URL without sending a CONNECT request first",
+         csp->ip_addr_str);
+      free_http_request(http);
+      return JB_ERR_PARSE;
+   }
 
    /* grab the rest of the client's headers */
    init_list(headers);
@@ -1835,7 +1875,8 @@ static jb_err receive_client_request(struct client_state *csp)
          if (!data_is_available(csp->cfd, csp->config->socket_timeout))
          {
             log_error(LOG_LEVEL_ERROR,
-               "Stopped grabbing the client headers.");
+               "Client headers did not arrive in time. Timeout: %d",
+               csp->config->socket_timeout);
             destroy_list(headers);
             return JB_ERR_PARSE;
          }
@@ -2081,12 +2122,12 @@ static int read_http_request_body(struct client_state *csp)
    if (to_read != 0)
    {
       log_error(LOG_LEVEL_CONNECT,
-         "Not enough request body has been read: expected %lu more bytes",
+         "Not enough request body has been read: expected %lu more bytes.",
          to_read);
       return 1;
    }
    log_error(LOG_LEVEL_CONNECT,
-      "The last %d bytes of the request body have been read", len);
+      "The last %d bytes of the request body have been read.", len);
    return 0;
 }
 
@@ -2140,7 +2181,7 @@ static int update_client_headers(struct client_state *csp, size_t new_content_le
 
 /*********************************************************************
  *
- * Function    : can_filter_request_body
+ * Function    : can_buffer_request_body
  *
  * Description : Checks if the current request body can be stored in
  *               the client_iob without hitting buffer limit.
@@ -2152,14 +2193,14 @@ static int update_client_headers(struct client_state *csp, size_t new_content_le
  *               FALSE otherwise.
  *
  *********************************************************************/
-static int can_filter_request_body(const struct client_state *csp)
+static int can_buffer_request_body(const struct client_state *csp)
 {
    if (!can_add_to_iob(csp->client_iob, csp->config->buffer_limit,
                        csp->expected_client_content_length))
    {
       log_error(LOG_LEVEL_INFO,
          "Not filtering request body from %s: buffer limit %lu will be exceeded "
-         "(content length %lluu)", csp->ip_addr_str, csp->config->buffer_limit,
+         "(content length %llu)", csp->ip_addr_str, csp->config->buffer_limit,
          csp->expected_client_content_length);
       return FALSE;
    }
@@ -2177,39 +2218,13 @@ static int can_filter_request_body(const struct client_state *csp)
  * Parameters  :
  *          1  :  csp = Current client state (buffers, headers, etc...)
  *
- * Returns     :  0 on success, anything else is an error.
+ * Returns     :  0 on success, 1 on error, 2 if the request got crunched.
  *
  *********************************************************************/
 static int send_http_request(struct client_state *csp)
 {
    char *hdr;
    int write_failure;
-   const char *to_send;
-   size_t to_send_len;
-   int filter_client_body = csp->expected_client_content_length != 0 &&
-      client_body_filters_enabled(csp->action) && can_filter_request_body(csp);
-
-   if (filter_client_body)
-   {
-      if (read_http_request_body(csp))
-      {
-         return 1;
-      }
-      to_send_len = csp->expected_client_content_length;
-      to_send = execute_client_body_filters(csp, &to_send_len);
-      if (to_send == NULL)
-      {
-         /* just flush client_iob */
-         filter_client_body = FALSE;
-      }
-      else if (to_send_len != csp->expected_client_content_length &&
-         update_client_headers(csp, to_send_len))
-      {
-         log_error(LOG_LEVEL_HEADER, "Error updating client headers");
-         return 1;
-      }
-      csp->expected_client_content_length = 0;
-   }
 
    hdr = list_to_text(csp->headers);
    if (hdr == NULL)
@@ -2233,18 +2248,7 @@ static int send_http_request(struct client_state *csp)
       return 1;
    }
 
-   if (filter_client_body)
-   {
-      write_failure = 0 != write_socket(csp->server_connection.sfd, to_send, to_send_len);
-      freez(to_send);
-      if (write_failure)
-      {
-         log_error(LOG_LEVEL_CONNECT, "Failed sending filtered request body to: %s: %E",
-            csp->http->hostport);
-         return 1;
-      }
-   }
-
+   /* XXX: Filtered data is not sent if there's a pipelined request? */
    if (((csp->flags & CSP_FLAG_PIPELINED_REQUEST_WAITING) == 0)
       && (flush_iob(csp->server_connection.sfd, csp->client_iob, 0) < 0))
    {
@@ -2291,13 +2295,15 @@ static int read_https_request_body(struct client_state *csp)
       size_t max_bytes_to_read = to_read < sizeof(buf) ? to_read : sizeof(buf);
 
       log_error(LOG_LEVEL_CONNECT,
-         "Waiting for up to %lu bytes of request body from the client.",
+         "Buffering encrypted client body. Prepared to read up to %lu bytes.",
          max_bytes_to_read);
       len = ssl_recv_data(&(csp->ssl_client_attr), buf,
          (unsigned)max_bytes_to_read);
       if (len <= 0)
       {
-         log_error(LOG_LEVEL_CONNECT, "Failed receiving request body from %s", csp->ip_addr_str);
+         log_error(LOG_LEVEL_CONNECT,
+            "Did not receive the whole encrypted request body from %s.",
+            csp->ip_addr_str);
          return 1;
       }
       if (add_to_iob(csp->client_iob, csp->config->buffer_limit, (char *)buf, len))
@@ -2310,13 +2316,13 @@ static int read_https_request_body(struct client_state *csp)
    if (to_read != 0)
    {
       log_error(LOG_LEVEL_CONNECT,
-         "Not enough request body has been read: expected %lu more bytes",
+         "Not enough encrypted request body has been read: expected %lu more bytes.",
          to_read);
       return 1;
    }
 
    log_error(LOG_LEVEL_CONNECT,
-      "The last %llu bytes of the request body have been read",
+      "The last %llu bytes of the encrypted request body have been read.",
       csp->expected_client_content_length);
    return 0;
 }
@@ -2351,7 +2357,7 @@ static int receive_and_send_encrypted_post_data(struct client_state *csp)
          max_bytes_to_read = (int)csp->expected_client_content_length;
       }
       log_error(LOG_LEVEL_CONNECT,
-         "Waiting for up to %d bytes of request body from the client.",
+         "Prepared to read up to %d bytes of encrypted request body from the client.",
          max_bytes_to_read);
       len = ssl_recv_data(&(csp->ssl_client_attr), buf,
          (unsigned)max_bytes_to_read);
@@ -2364,7 +2370,7 @@ static int receive_and_send_encrypted_post_data(struct client_state *csp)
          /* XXX: Does this actually happen? */
          break;
       }
-      log_error(LOG_LEVEL_CONNECT, "Forwarding %d bytes of encrypted request body",
+      log_error(LOG_LEVEL_CONNECT, "Forwarding %d bytes of encrypted request body.",
          len);
       len = ssl_send_data(&(csp->ssl_server_attr), buf, (size_t)len);
       if (len == -1)
@@ -2379,13 +2385,13 @@ static int receive_and_send_encrypted_post_data(struct client_state *csp)
          }
          if (csp->expected_client_content_length == 0)
          {
-            log_error(LOG_LEVEL_CONNECT, "Forwarded the last %d bytes", len);
+            log_error(LOG_LEVEL_CONNECT, "Forwarded the last %d bytes.", len);
             break;
          }
       }
    }
 
-   log_error(LOG_LEVEL_CONNECT, "Done forwarding encrypted request body");
+   log_error(LOG_LEVEL_CONNECT, "Done forwarding encrypted request body.");
 
    return 0;
 
@@ -2410,38 +2416,12 @@ static int send_https_request(struct client_state *csp)
    char *hdr;
    int ret;
    long flushed = 0;
-   const char *to_send;
-   size_t to_send_len;
-   int filter_client_body = csp->expected_client_content_length != 0 &&
-      client_body_filters_enabled(csp->action) && can_filter_request_body(csp);
-
-   if (filter_client_body)
-   {
-      if (read_https_request_body(csp))
-      {
-         return 1;
-      }
-      to_send_len = csp->expected_client_content_length;
-      to_send = execute_client_body_filters(csp, &to_send_len);
-      if (to_send == NULL)
-      {
-         /* just flush client_iob */
-         filter_client_body = FALSE;
-      }
-      else if (to_send_len != csp->expected_client_content_length &&
-         update_client_headers(csp, to_send_len))
-      {
-         log_error(LOG_LEVEL_HEADER, "Error updating client headers");
-         return 1;
-      }
-      csp->expected_client_content_length = 0;
-   }
 
    hdr = list_to_text(csp->https_headers);
    if (hdr == NULL)
    {
       /* FIXME Should handle error properly */
-      log_error(LOG_LEVEL_FATAL, "Out of memory parsing client header");
+      log_error(LOG_LEVEL_FATAL, "Out of memory parsing client header.");
    }
    list_remove_all(csp->https_headers);
 
@@ -2462,18 +2442,7 @@ static int send_https_request(struct client_state *csp)
       return 1;
    }
 
-   if (filter_client_body)
-   {
-      ret = ssl_send_data(&(csp->ssl_server_attr), (const unsigned char *)to_send, to_send_len);
-      freez(to_send);
-      if (ret < 0)
-      {
-         log_error(LOG_LEVEL_CONNECT, "Failed sending filtered request body to: %s",
-            csp->http->hostport);
-         return 1;
-      }
-   }
-
+   /* XXX: Client body isn't sent if there's pipelined data? */
    if (((csp->flags & CSP_FLAG_PIPELINED_REQUEST_WAITING) == 0)
       && ((flushed = ssl_flush_socket(&(csp->ssl_server_attr),
             csp->client_iob)) < 0))
@@ -2489,14 +2458,14 @@ static int send_https_request(struct client_state *csp)
          if (csp->expected_client_content_length < flushed)
          {
             log_error(LOG_LEVEL_ERROR,
-               "Flushed %ld bytes of request body while only expecting %llu",
+               "Flushed %ld bytes of request body while only expecting %llu.",
                flushed, csp->expected_client_content_length);
             csp->expected_client_content_length = 0;
          }
          else
          {
             log_error(LOG_LEVEL_CONNECT,
-               "Flushed %ld bytes of request body while expecting %llu",
+               "Flushed %ld bytes of request body while expecting %llu.",
                flushed, csp->expected_client_content_length);
             csp->expected_client_content_length -= (unsigned)flushed;
             if (receive_and_send_encrypted_post_data(csp))
@@ -2508,11 +2477,11 @@ static int send_https_request(struct client_state *csp)
       else
       {
          log_error(LOG_LEVEL_CONNECT,
-            "Flushed %ld bytes of request body", flushed);
+            "Flushed %ld bytes of request body.", flushed);
       }
    }
 
-   log_error(LOG_LEVEL_CONNECT, "Encrypted request sent");
+   log_error(LOG_LEVEL_CONNECT, "Encrypted request sent.");
 
    return 0;
 
@@ -2541,12 +2510,12 @@ static jb_err receive_encrypted_request_headers(struct client_state *csp)
 
    do
    {
-      log_error(LOG_LEVEL_HEADER, "Waiting for encrypted client headers");
+      log_error(LOG_LEVEL_HEADER, "Waiting for encrypted client headers.");
       if (!is_ssl_pending(&(csp->ssl_client_attr)) &&
           !data_is_available(csp->cfd, csp->config->socket_timeout))
       {
          log_error(LOG_LEVEL_CONNECT,
-            "Socket %d timed out while waiting for client headers", csp->cfd);
+            "Socket %d timed out while waiting for client headers.", csp->cfd);
          return JB_ERR_PARSE;
       }
       len = ssl_recv_data(&(csp->ssl_client_attr),
@@ -2554,7 +2523,7 @@ static jb_err receive_encrypted_request_headers(struct client_state *csp)
       if (len == 0)
       {
          log_error(LOG_LEVEL_CONNECT,
-            "Socket %d closed while waiting for client headers", csp->cfd);
+            "Socket %d closed while waiting for client headers.", csp->cfd);
          return JB_ERR_PARSE;
       }
       if (len == -1)
@@ -2568,7 +2537,7 @@ static jb_err receive_encrypted_request_headers(struct client_state *csp)
       p = strstr(csp->client_iob->cur, "\r\n\r\n");
    } while (p == NULL);
 
-   log_error(LOG_LEVEL_HEADER, "Encrypted headers received completely");
+   log_error(LOG_LEVEL_HEADER, "Encrypted headers received completely.");
 
    return JB_ERR_OK;
 }
@@ -2801,6 +2770,8 @@ static jb_err process_encrypted_request_headers(struct client_state *csp)
          "Failed to get the encrypted request destination");
       ssl_send_data_delayed(&(csp->ssl_client_attr),
          (const unsigned char *)CHEADER, strlen(CHEADER), get_write_delay(csp));
+      destroy_list(headers);
+
       return JB_ERR_PARSE;
    }
 
@@ -2945,6 +2916,12 @@ static void continue_https_chat(struct client_state *csp)
       return;
    }
 
+#if defined(FEATURE_STATISTICS) && defined(MUTEX_LOCKS_AVAILABLE)
+   privoxy_mutex_lock(&block_statistics_mutex);
+   number_of_requests_received++;
+   privoxy_mutex_unlock(&block_statistics_mutex);
+#endif
+
    csp->requests_received_total++;
 
    /*
@@ -2968,6 +2945,46 @@ static void continue_https_chat(struct client_state *csp)
    }
    assert(csp->server_connection.sfd != JB_INVALID_SOCKET);
 
+   if (csp->expected_client_content_length != 0 &&
+      (client_body_filters_enabled(csp->action) ||
+       client_body_taggers_enabled(csp->action)) &&
+      can_buffer_request_body(csp))
+   {
+      int content_modified;
+
+      if (read_https_request_body(csp))
+      {
+         /* XXX: handle */
+         return;
+      }
+      if (client_body_taggers_enabled(csp->action))
+      {
+         execute_client_body_taggers(csp, csp->expected_client_content_length);
+         if (crunch_response_triggered(csp, crunchers_all))
+         {
+            /*
+             * Yes. The client got the crunch response and we're done here.
+             */
+            return;
+         }
+      }
+      if (client_body_filters_enabled(csp->action))
+      {
+         size_t modified_content_length = csp->expected_client_content_length;
+         content_modified = execute_client_body_filters(csp,
+            &modified_content_length);
+         if ((content_modified == 1) &&
+            (modified_content_length != csp->expected_client_content_length) &&
+            update_client_headers(csp, modified_content_length))
+         {
+            /* XXX: Send error response */
+            log_error(LOG_LEVEL_HEADER, "Error updating client headers");
+            return;
+         }
+      }
+      csp->expected_client_content_length = 0;
+   }
+
    fwd = forward_url(csp, csp->http);
    if (!connection_destination_matches(&csp->server_connection, csp->http, fwd))
    {
@@ -3008,6 +3025,67 @@ static void continue_https_chat(struct client_state *csp)
 #endif
 
 
+/*********************************************************************
+ *
+ * Function    :  send_server_headers
+ *
+ * Description :  Sends the server headers to the client.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *
+ * Returns     :  0 on succes, -1 on error.
+ *
+ *********************************************************************/
+static int send_server_headers(struct client_state *csp)
+{
+   char *server_headers;
+   int ret;
+
+   server_headers = list_to_text(csp->headers);
+   if (server_headers == NULL)
+   {
+      /*
+       * Memory is too tight to even generate the header.
+       * Send our static "Out-of-memory" page.
+       */
+      log_error(LOG_LEVEL_ERROR,
+         "Out of memory while trying to send server headers.");
+      send_crunch_response(csp, cgi_error_memory());
+      mark_server_socket_tainted(csp);
+#ifdef FEATURE_HTTPS_INSPECTION
+      close_client_and_server_ssl_connections(csp);
+#endif
+      return -1;
+   }
+#ifdef FEATURE_HTTPS_INSPECTION
+   if (client_use_ssl(csp))
+   {
+      ret = ssl_send_data_delayed(&(csp->ssl_client_attr),
+         (const unsigned char *)server_headers, strlen(server_headers),
+         get_write_delay(csp));
+   }
+   else
+#endif
+   {
+      ret = write_socket_delayed(csp->cfd, server_headers, strlen(server_headers),
+         get_write_delay(csp));
+   }
+   freez(server_headers);
+   if (ret < 0)
+   {
+      log_error(LOG_LEVEL_ERROR, "Failed to send server headers to the client.");
+      mark_server_socket_tainted(csp);
+#ifdef FEATURE_HTTPS_INSPECTION
+      close_client_and_server_ssl_connections(csp);
+#endif
+      return -1;
+   }
+
+   return 0;
+
+}
+
 /*********************************************************************
  *
  * Function    :  handle_established_connection
@@ -3024,7 +3102,6 @@ static void continue_https_chat(struct client_state *csp)
  *********************************************************************/
 static void handle_established_connection(struct client_state *csp)
 {
-   char *hdr;
    char *p;
    int n;
 #ifdef HAVE_POLL
@@ -3041,6 +3118,7 @@ static void handle_established_connection(struct client_state *csp)
    long len = 0; /* for buffer sizes (and negative error codes) */
    int buffer_and_filter_content = 0;
    unsigned int write_delay;
+   size_t chunk_offset = 0;
 #ifdef FEATURE_HTTPS_INSPECTION
    int ret = 0;
    int use_ssl_tunnel = 0;
@@ -3101,6 +3179,16 @@ static void handle_established_connection(struct client_state *csp)
           */
          goto server_wants_to_talk;
       }
+      if (watch_client_socket && client_use_ssl(csp) &&
+         is_ssl_pending(&(csp->ssl_client_attr)))
+      {
+         /*
+          * The TLS libray may also consume all of the remaining data
+          * from the client when we're shuffling the data from an
+          * unbuffered request body to the server.
+          */
+         goto client_wants_to_talk;
+      }
 #endif
 #ifndef HAVE_POLL
       FD_ZERO(&rfds);
@@ -3119,23 +3207,6 @@ static void handle_established_connection(struct client_state *csp)
 #endif /* ndef HAVE_POLL */
 
 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
-      if ((csp->flags & CSP_FLAG_CHUNKED)
-         && !(csp->flags & CSP_FLAG_CONTENT_LENGTH_SET)
-         && ((csp->iob->eod - csp->iob->cur) >= 5)
-         && !memcmp(csp->iob->eod-5, "0\r\n\r\n", 5))
-      {
-         /*
-          * XXX: This check should be obsolete now,
-          *      but let's wait a while to be sure.
-          */
-         log_error(LOG_LEVEL_CONNECT,
-            "Looks like we got the last chunk together with "
-            "the server headers but didn't detect it earlier. "
-            "We better stop reading.");
-         byte_count = (unsigned long long)(csp->iob->eod - csp->iob->cur);
-         csp->expected_content_length = byte_count;
-         csp->flags |= CSP_FLAG_CONTENT_LENGTH_SET;
-      }
       if (server_body && server_response_is_complete(csp, byte_count))
       {
          if (csp->expected_content_length == byte_count)
@@ -3242,7 +3313,13 @@ static void handle_established_connection(struct client_state *csp)
       if (FD_ISSET(csp->cfd, &rfds))
 #endif /* def HAVE_POLL*/
       {
-         int max_bytes_to_read = (int)csp->receive_buffer_size;
+         int max_bytes_to_read;
+
+#ifdef FEATURE_HTTPS_INSPECTION
+         client_wants_to_talk:
+#endif
+
+         max_bytes_to_read = (int)csp->receive_buffer_size;
 
 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
          if ((csp->flags & CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ))
@@ -3366,8 +3443,6 @@ static void handle_established_connection(struct client_state *csp)
 
       /*
        * The server wants to talk. It could be the header or the body.
-       * If `hdr' is null, then it's the header otherwise it's the body.
-       * FIXME: Does `hdr' really mean `host'? No.
        */
 #ifdef HAVE_POLL
       if (poll_fds[1].revents != 0)
@@ -3463,18 +3538,6 @@ static void handle_established_connection(struct client_state *csp)
          }
 
 #ifdef FEATURE_CONNECTION_KEEP_ALIVE
-         if (csp->flags & CSP_FLAG_CHUNKED)
-         {
-            if ((len >= 5) && !memcmp(csp->receive_buffer+len-5, "0\r\n\r\n", 5))
-            {
-               /* XXX: this is a temporary hack */
-               log_error(LOG_LEVEL_CONNECT,
-                  "Looks like we reached the end of the last chunk. "
-                  "We better stop reading.");
-               csp->expected_content_length = byte_count + (unsigned long long)len;
-               csp->flags |= CSP_FLAG_CONTENT_LENGTH_SET;
-            }
-         }
          reading_done:
 #endif  /* FEATURE_CONNECTION_KEEP_ALIVE */
 
@@ -3562,11 +3625,9 @@ static void handle_established_connection(struct client_state *csp)
                         "Failed to update server headers. after filtering.");
                   }
 
-                  hdr = list_to_text(csp->headers);
-                  if (hdr == NULL)
+                  if (send_server_headers(csp))
                   {
-                     /* FIXME Should handle error properly */
-                     log_error(LOG_LEVEL_FATAL, "Out of memory parsing server header");
+                     return;
                   }
 
 #ifdef FEATURE_HTTPS_INSPECTION
@@ -3575,16 +3636,12 @@ static void handle_established_connection(struct client_state *csp)
                    */
                   if (client_use_ssl(csp))
                   {
-                     if ((ssl_send_data_delayed(&(csp->ssl_client_attr),
-                              (const unsigned char *)hdr, strlen(hdr),
-                              get_write_delay(csp)) < 0)
-                        || (ssl_send_data_delayed(&(csp->ssl_client_attr),
+                     if (ssl_send_data_delayed(&(csp->ssl_client_attr),
                               (const unsigned char *) ((p != NULL) ? p : csp->iob->cur),
-                              csp->content_length, get_write_delay(csp)) < 0))
+                              csp->content_length, get_write_delay(csp)) < 0)
                      {
                         log_error(LOG_LEVEL_ERROR,
                            "Failed to send the modified content to the client over TLS");
-                        freez(hdr);
                         freez(p);
                         mark_server_socket_tainted(csp);
                         close_client_and_server_ssl_connections(csp);
@@ -3594,19 +3651,16 @@ static void handle_established_connection(struct client_state *csp)
                   else
 #endif /* def FEATURE_HTTPS_INSPECTION */
                   {
-                     if (write_socket_delayed(csp->cfd, hdr, strlen(hdr), write_delay)
-                      || write_socket_delayed(csp->cfd, ((p != NULL) ? p : csp->iob->cur),
+                     if (write_socket_delayed(csp->cfd, ((p != NULL) ? p : csp->iob->cur),
                          (size_t)csp->content_length, write_delay))
                      {
                         log_error(LOG_LEVEL_ERROR, "write modified content to client failed: %E");
-                        freez(hdr);
                         freez(p);
                         mark_server_socket_tainted(csp);
                         return;
                      }
                   }
 
-                  freez(hdr);
                   freez(p);
                }
 
@@ -3648,29 +3702,15 @@ static void handle_established_connection(struct client_state *csp)
                 */
                if (add_to_iob(csp->iob, csp->config->buffer_limit, csp->receive_buffer, len))
                {
-                  size_t hdrlen;
                   long flushed;
 
                   log_error(LOG_LEVEL_INFO,
                      "Flushing header and buffers. Stepping back from filtering.");
 
-                  hdr = list_to_text(csp->headers);
-                  if (hdr == NULL)
+                  if (send_server_headers(csp))
                   {
-                     /*
-                      * Memory is too tight to even generate the header.
-                      * Send our static "Out-of-memory" page.
-                      */
-                     log_error(LOG_LEVEL_ERROR, "Out of memory while trying to flush.");
-                     rsp = cgi_error_memory();
-                     send_crunch_response(csp, rsp);
-                     mark_server_socket_tainted(csp);
-#ifdef FEATURE_HTTPS_INSPECTION
-                     close_client_and_server_ssl_connections(csp);
-#endif
                      return;
                   }
-                  hdrlen = strlen(hdr);
 
 #ifdef FEATURE_HTTPS_INSPECTION
                   /*
@@ -3678,9 +3718,7 @@ static void handle_established_connection(struct client_state *csp)
                    */
                   if (client_use_ssl(csp))
                   {
-                     if ((ssl_send_data_delayed(&(csp->ssl_client_attr),
-                             (const unsigned char *)hdr, hdrlen, get_write_delay(csp)) < 0)
-                        || ((flushed = ssl_flush_socket(&(csp->ssl_client_attr),
+                     if (((flushed = ssl_flush_socket(&(csp->ssl_client_attr),
                                 csp->iob)) < 0)
                         || (ssl_send_data_delayed(&(csp->ssl_client_attr),
                               (const unsigned char *)csp->receive_buffer, (size_t)len,
@@ -3688,7 +3726,6 @@ static void handle_established_connection(struct client_state *csp)
                      {
                         log_error(LOG_LEVEL_CONNECT,
                            "Flush header and buffers to client failed");
-                        freez(hdr);
                         mark_server_socket_tainted(csp);
                         close_client_and_server_ssl_connections(csp);
                         return;
@@ -3697,26 +3734,43 @@ static void handle_established_connection(struct client_state *csp)
                   else
 #endif /* def FEATURE_HTTPS_INSPECTION */
                   {
-                     if (write_socket_delayed(csp->cfd, hdr, hdrlen, write_delay)
-                      || ((flushed = flush_iob(csp->cfd, csp->iob, write_delay)) < 0)
+                     if (((flushed = flush_iob(csp->cfd, csp->iob, write_delay)) < 0)
                       || write_socket_delayed(csp->cfd, csp->receive_buffer, (size_t)len,
                             write_delay))
                      {
                         log_error(LOG_LEVEL_CONNECT,
                            "Flush header and buffers to client failed: %E");
-                        freez(hdr);
                         mark_server_socket_tainted(csp);
                         return;
                      }
                   }
 
                   /*
-                   * Reset the byte_count to the amount of bytes
-                   * we just flushed. len will be added a few lines below,
-                   * hdrlen doesn't matter for LOG_LEVEL_CLF.
+                   * Reset the byte_count to the amount of bytes we just
+                   * flushed. len will be added a few lines below.
                    */
                   byte_count = (unsigned long long)flushed;
-                  freez(hdr);
+                  if ((csp->flags & CSP_FLAG_CHUNKED) && (chunk_offset != 0))
+                  {
+                     log_error(LOG_LEVEL_CONNECT,
+                        "Reducing chunk offset %lu by %ld to %lu.", chunk_offset, flushed,
+                        (chunk_offset - (unsigned)flushed));
+                     assert(chunk_offset >= flushed); /* XXX: Reachable with malicious input? */
+                     chunk_offset -= (unsigned)flushed;
+
+                     /* Make room in the iob. */
+                     csp->iob->cur = csp->iob->eod = csp->iob->buf;
+
+                     if (add_to_iob(csp->iob, csp->config->buffer_limit,
+                           csp->receive_buffer, len))
+                     {
+                        /* This is not supposed to happen but ... */
+                        csp->flags &= ~CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE;
+                        log_error(LOG_LEVEL_ERROR, "Failed to buffer %ld bytes of "
+                           "chunk-encoded data after resetting the buffer.", len);
+                        return;
+                     }
+                  }
                   buffer_and_filter_content = 0;
                   server_body = 1;
                }
@@ -3752,8 +3806,66 @@ static void handle_established_connection(struct client_state *csp)
                      return;
                   }
                }
+               if (csp->flags & CSP_FLAG_CHUNKED)
+               {
+                  /*
+                   * While we don't need the data to filter it, put it in the
+                   * buffer so we can keep track of the offset to the start of
+                   * the next chunk and detect when the response is finished.
+                   */
+                  size_t encoded_bytes = (size_t)(csp->iob->eod - csp->iob->cur);
+
+                  if (csp->config->buffer_limit / 4 < encoded_bytes)
+                  {
+                     /*
+                      * Reset the buffer to reduce the memory footprint.
+                      */
+                     log_error(LOG_LEVEL_CONNECT,
+                        "Reducing the chunk offset from %lu to %lu after "
+                        "discarding %lu bytes to make room in the buffer.",
+                        chunk_offset, (chunk_offset - encoded_bytes),
+                        encoded_bytes);
+                     chunk_offset -= encoded_bytes;
+                     csp->iob->cur = csp->iob->eod = csp->iob->buf;
+                  }
+                  if (add_to_iob(csp->iob, csp->config->buffer_limit,
+                     csp->receive_buffer, len))
+                  {
+                     /* This is not supposed to happen but ... */
+                     csp->flags &= ~CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE;
+                     log_error(LOG_LEVEL_ERROR,
+                        "Failed to buffer %ld bytes of chunk-encoded data.",
+                        len);
+                     return;
+                  }
+               }
             }
             byte_count += (unsigned long long)len;
+
+            if (csp->flags & CSP_FLAG_CHUNKED)
+            {
+               int rc;
+               size_t encoded_bytes = (size_t)(csp->iob->eod - csp->iob->cur);
+
+               rc = get_bytes_missing_from_chunked_data(csp->iob->cur, encoded_bytes,
+                  chunk_offset);
+               if (rc >= 0)
+               {
+                  if (rc != 0)
+                  {
+                     chunk_offset = (size_t)rc;
+                  }
+
+                  if (chunked_data_is_complete(csp->iob->cur, encoded_bytes, chunk_offset))
+                  {
+                     log_error(LOG_LEVEL_CONNECT,
+                        "We buffered the last chunk of the response.");
+                     csp->expected_content_length = byte_count;
+                     csp->flags |= CSP_FLAG_CONTENT_LENGTH_SET;
+                  }
+               }
+            }
+
             continue;
          }
          else
@@ -3952,26 +4064,32 @@ static void handle_established_connection(struct client_state *csp)
 #endif
                return;
             }
-            hdr = list_to_text(csp->headers);
-            if (hdr == NULL)
-            {
-               /* FIXME Should handle error properly */
-               log_error(LOG_LEVEL_FATAL, "Out of memory parsing server header");
-            }
 
             if ((csp->flags & CSP_FLAG_CHUNKED)
-               && !(csp->flags & CSP_FLAG_CONTENT_LENGTH_SET)
-               && ((csp->iob->eod - csp->iob->cur) >= 5)
-               && !memcmp(csp->iob->eod-5, "0\r\n\r\n", 5))
+               && !(csp->flags & CSP_FLAG_CONTENT_LENGTH_SET))
             {
-               log_error(LOG_LEVEL_CONNECT,
-                  "Looks like we got the last chunk together with "
-                  "the server headers. We better stop reading.");
-               byte_count = (unsigned long long)(csp->iob->eod - csp->iob->cur);
-               csp->expected_content_length = byte_count;
-               csp->flags |= CSP_FLAG_CONTENT_LENGTH_SET;
-            }
+               int rc;
+               size_t encoded_size = (size_t)(csp->iob->eod - csp->iob->cur);
 
+               rc = get_bytes_missing_from_chunked_data(csp->iob->cur, encoded_size,
+                  chunk_offset);
+               if (rc >= 0)
+               {
+                  if (rc != 0)
+                  {
+                     chunk_offset = (size_t)rc;
+                  }
+                  if (chunked_data_is_complete(csp->iob->cur, encoded_size, chunk_offset))
+                  {
+                     log_error(LOG_LEVEL_CONNECT,
+                        "Looks like we got the last chunk together with "
+                        "the server headers. We better stop reading.");
+                     byte_count = (unsigned long long)(csp->iob->eod - csp->iob->cur);
+                     csp->expected_content_length = byte_count;
+                     csp->flags |= CSP_FLAG_CONTENT_LENGTH_SET;
+                  }
+               }
+            }
             csp->server_connection.response_received = time(NULL);
 
             if (crunch_response_triggered(csp, crunchers_light))
@@ -3982,7 +4100,6 @@ static void handle_established_connection(struct client_state *csp)
                 * delivered the crunch response to the client
                 * and are done here after cleaning up.
                 */
-               freez(hdr);
                mark_server_socket_tainted(csp);
 #ifdef FEATURE_HTTPS_INSPECTION
                close_client_and_server_ssl_connections(csp);
@@ -4001,22 +4118,23 @@ static void handle_established_connection(struct client_state *csp)
                 * may be in the buffer). Use standard or secured
                 * connection.
                 */
+               if (send_server_headers(csp))
+               {
+                  return;
+               }
 #ifdef FEATURE_HTTPS_INSPECTION
                if (client_use_ssl(csp))
                {
-                  if ((ssl_send_data_delayed(&(csp->ssl_client_attr),
-                          (const unsigned char *)hdr, strlen(hdr),
-                          get_write_delay(csp)) < 0)
-                     || ((len = ssl_flush_socket(&(csp->ssl_client_attr),
-                            csp->iob)) < 0))
+                  if ((len = ssl_flush_socket(&(csp->ssl_client_attr),
+                           csp->iob)) < 0)
                   {
-                     log_error(LOG_LEVEL_CONNECT, "Write header to client failed");
+                     log_error(LOG_LEVEL_CONNECT,
+                        "Sending buffered bytes to the client failed");
 
                      /*
                       * The write failed, so don't bother mentioning it
                       * to the client... it probably can't hear us anyway.
                       */
-                     freez(hdr);
                      mark_server_socket_tainted(csp);
 #ifdef FEATURE_HTTPS_INSPECTION
                      close_client_and_server_ssl_connections(csp);
@@ -4027,25 +4145,48 @@ static void handle_established_connection(struct client_state *csp)
                else
 #endif /* def FEATURE_HTTPS_INSPECTION */
                {
-                  if (write_socket_delayed(csp->cfd, hdr, strlen(hdr), write_delay)
-                     || ((len = flush_iob(csp->cfd, csp->iob, write_delay)) < 0))
+                  if ((len = flush_iob(csp->cfd, csp->iob, write_delay)) < 0)
                   {
                      log_error(LOG_LEVEL_ERROR,
-                        "write header to client failed");
+                        "Sending buffered bytes to the client failed.");
                      /*
                       * The write failed, so don't bother mentioning it
                       * to the client... it probably can't hear us anyway.
                       */
-                     freez(hdr);
                      mark_server_socket_tainted(csp);
                      return;
                   }
+               }
+               if (csp->flags & CSP_FLAG_CHUNKED &&
+                 !(csp->flags & CSP_FLAG_CONTENT_LENGTH_SET))
+               {
+                  /*
+                   * In case of valid data we shouldn't flush more
+                   * data than chunk_offset but the data may be invalid.
+                   */
+                  if (chunk_offset >= len)
+                  {
+                     log_error(LOG_LEVEL_CONNECT, "Reducing the chunk offset "
+                        "from %lu to %lu after flushing %ld bytes.",
+                        chunk_offset, (chunk_offset - (unsigned)len), len);
+                     chunk_offset = chunk_offset - (unsigned)len;
+                  }
+                  else
+                  {
+                     log_error(LOG_LEVEL_CONNECT,
+                        "Keeping chunk offset at %lu despite flushing %ld bytes.",
+                        chunk_offset, len);
+                     /*
+                      * If we can't parse the chunk-encoded data we should
+                      * not reuse the server connection.
+                      */
+                     mark_server_socket_tainted(csp);
+                  }
                }
                                }
 
             /* we're finished with the server's header */
 
-            freez(hdr);
             server_body = 1;
 
             /*
@@ -4170,6 +4311,13 @@ static void chat(struct client_state *csp)
    {
       return;
    }
+
+#if defined(FEATURE_STATISTICS) && defined(MUTEX_LOCKS_AVAILABLE)
+   privoxy_mutex_lock(&block_statistics_mutex);
+   number_of_requests_received++;
+   privoxy_mutex_unlock(&block_statistics_mutex);
+#endif
+
    if (parse_client_request(csp) != JB_ERR_OK)
    {
       return;
@@ -4341,6 +4489,72 @@ static void chat(struct client_state *csp)
    }
 #endif
 
+   /* If we need to apply client body filters, buffer the whole request now. */
+   if (csp->expected_client_content_length != 0 &&
+      (client_body_filters_enabled(csp->action) ||
+         client_body_taggers_enabled(csp->action)) &&
+      can_buffer_request_body(csp))
+   {
+      int content_modified;
+      size_t modified_content_length;
+
+#ifdef FEATURE_HTTPS_INSPECTION
+      if (client_use_ssl(csp) && read_https_request_body(csp))
+      {
+         log_error(LOG_LEVEL_ERROR, "Failed to buffer the encrypted "
+            "request body to apply filters or taggers.");
+         log_error(LOG_LEVEL_CLF,
+            "%s - - [%T] \"%s\" 400 0", csp->ip_addr_str, csp->http->cmd);
+
+         ssl_send_data_delayed(&(csp->ssl_client_attr),
+            (const unsigned char *)CLIENT_BODY_BUFFER_ERROR_RESPONSE,
+            strlen(CLIENT_BODY_BUFFER_ERROR_RESPONSE),
+            get_write_delay(csp));
+
+         return;
+      }
+      else
+#endif
+      if (read_http_request_body(csp))
+      {
+         log_error(LOG_LEVEL_ERROR,
+            "Failed to buffer the request body to apply filters or taggers,");
+         log_error(LOG_LEVEL_CLF,
+            "%s - - [%T] \"%s\" 400 0", csp->ip_addr_str, csp->http->cmd);
+
+         write_socket_delayed(csp->cfd, CLIENT_BODY_BUFFER_ERROR_RESPONSE,
+            strlen(CLIENT_BODY_BUFFER_ERROR_RESPONSE), get_write_delay(csp));
+
+         return;
+      }
+      if (client_body_taggers_enabled(csp->action))
+      {
+         execute_client_body_taggers(csp, csp->expected_client_content_length);
+         if (crunch_response_triggered(csp, crunchers_all))
+         {
+            /*
+             * Yes. The client got the crunch response and we're done here.
+             */
+            return;
+         }
+      }
+      if (client_body_filters_enabled(csp->action))
+      {
+         modified_content_length = csp->expected_client_content_length;
+         content_modified = execute_client_body_filters(csp,
+            &modified_content_length);
+         if ((content_modified == 1) &&
+            (modified_content_length != csp->expected_client_content_length) &&
+            update_client_headers(csp, modified_content_length))
+         {
+            /* XXX: Send error response */
+            log_error(LOG_LEVEL_HEADER, "Error updating client headers");
+            return;
+         }
+      }
+      csp->expected_client_content_length = 0;
+   }
+
    log_applied_actions(csp->action);
 
    /* decide how to route the HTTP request */
@@ -4581,7 +4795,13 @@ static void chat(struct client_state *csp)
 #endif
            ))
    {
-      if (send_http_request(csp))
+      int status = send_http_request(csp);
+      if (status == 2)
+      {
+         /* The request got crunched, a response has been delivered. */
+         return;
+      }
+      if (status != 0)
       {
          rsp = error_response(csp, "connect-failed");
          if (rsp)
@@ -5244,9 +5464,12 @@ static void initialize_mutexes(void)
 #ifdef FEATURE_CLIENT_TAGS
    privoxy_mutex_init(&client_tags_mutex);
 #endif
+#ifdef FEATURE_STATISTICS
+   privoxy_mutex_init(&block_statistics_mutex);
+#endif
 #ifdef FEATURE_EXTENDED_STATISTICS
    privoxy_mutex_init(&filter_statistics_mutex);
-   privoxy_mutex_init(&block_statistics_mutex);
+   privoxy_mutex_init(&block_reason_statistics_mutex);
 #endif
 
    /*
@@ -6046,7 +6269,8 @@ static void listen_loop(void)
 
       if (!accept_connection(csp, bfds))
       {
-         log_error(LOG_LEVEL_CONNECT, "accept failed: %E");
+         log_error(LOG_LEVEL_CONNECT,
+            "Failed to accept() incoming connection: %E");
          freez(csp_list);
          continue;
       }
diff --git a/jcc.h b/jcc.h
index 3e17042..dbe05b7 100644 (file)
--- a/jcc.h
+++ b/jcc.h
@@ -41,8 +41,13 @@ struct file_list;
 /* Global variables */
 
 #ifdef FEATURE_STATISTICS
+#if defined(FEATURE_PTHREAD) || defined(_WIN32)
+extern unsigned long long number_of_requests_received;
+extern unsigned long long number_of_requests_blocked;
+#else
 extern int urls_read;
 extern int urls_rejected;
+#endif
 #endif /*def FEATURE_STATISTICS*/
 
 extern struct client_states clients[1];
@@ -86,9 +91,12 @@ extern privoxy_mutex_t external_filter_mutex;
 extern privoxy_mutex_t client_tags_mutex;
 #endif
 
+#ifdef FEATURE_STATISTICS
+extern privoxy_mutex_t block_statistics_mutex;
+#endif
 #ifdef FEATURE_EXTENDED_STATISTICS
 extern privoxy_mutex_t filter_statistics_mutex;
-extern privoxy_mutex_t block_statistics_mutex;
+extern privoxy_mutex_t block_reason_statistics_mutex;
 #endif
 
 #ifndef HAVE_GMTIME_R
index f98e084..188af09 100644 (file)
--- a/loadcfg.c
+++ b/loadcfg.c
@@ -7,7 +7,7 @@
  *                routine to load the configuration and the global
  *                variables it writes to.
  *
- * Copyright   :  Written by and Copyright (C) 2001-2017 the
+ * Copyright   :  Written by and Copyright (C) 2001-2022 the
  *                Privoxy team. https://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
@@ -430,7 +430,7 @@ static int parse_numeric_value(const char *name, const char *value)
       log_error(LOG_LEVEL_FATAL, "Directive %s used without argument", name);
    }
 
-   number = (int)strtol(value, &endptr, 0);
+   number = (int)strtol(value, &endptr, 10);
    if (*endptr != '\0')
    {
       log_error(LOG_LEVEL_FATAL,
@@ -634,12 +634,12 @@ struct configuration_spec * load_config(void)
    config->proxy_args                = strdup_or_die("");
    config->forwarded_connect_retries = 0;
 #ifdef FEATURE_HTTPS_INSPECTION
-   config->ca_password               = strdup("");
-   ca_cert_file                      = strdup("cacert.crt");
-   ca_key_file                       = strdup("cakey.pem");
-   ca_directory                      = strdup("./CA");
-   trusted_cas_file                  = strdup("trustedCAs.pem");
-   certificate_directory             = strdup("./certs");
+   config->ca_password               = strdup_or_die("");
+   ca_cert_file                      = strdup_or_die("cacert.crt");
+   ca_key_file                       = strdup_or_die("cakey.pem");
+   ca_directory                      = strdup_or_die("./CA");
+   trusted_cas_file                  = strdup_or_die("trustedCAs.pem");
+   certificate_directory             = strdup_or_die("./certs");
 #endif
 
 #ifdef FEATURE_CLIENT_TAGS
index 61d2763..a9820df 100644 (file)
--- a/loaders.c
+++ b/loaders.c
@@ -222,13 +222,13 @@ unsigned int sweep(void)
       {
          last_active->next = client_list->next;
 
-#ifdef FEATURE_STATISTICS
+#if defined(FEATURE_STATISTICS) && !defined(MUTEX_LOCKS_AVAILABLE)
          urls_read++;
          if (csp->flags & CSP_FLAG_REJECTED)
          {
             urls_rejected++;
          }
-#endif /* def FEATURE_STATISTICS */
+#endif /* defined(FEATURE_STATISTICS) && !defined(MUTEX_LOCKS_AVAILABLE) */
 
          freez(client_list);
 
@@ -1168,6 +1168,10 @@ int load_one_re_filterfile(struct client_state *csp, int fileid)
       {
          new_filter = FT_CLIENT_BODY_FILTER;
       }
+      else if (strncmp(buf, "CLIENT-BODY-TAGGER:", 19) == 0)
+      {
+         new_filter = FT_CLIENT_BODY_TAGGER;
+      }
 
       /*
        * If this is the head of a new filter block, make it a
@@ -1190,6 +1194,10 @@ int load_one_re_filterfile(struct client_state *csp, int fileid)
          {
             new_bl->name = chomp(buf + 19);
          }
+         else if (new_filter == FT_CLIENT_BODY_TAGGER)
+         {
+            new_bl->name = chomp(buf + 19);
+         }
          else
          {
             new_bl->name = chomp(buf + 21);
index 831f3c5..6298e9d 100644 (file)
@@ -7,7 +7,7 @@
  *                to deserve their own file but don't really fit in
  *                any other file.
  *
- * Copyright   :  Written by and Copyright (C) 2001-2020 the
+ * Copyright   :  Written by and Copyright (C) 2001-2022 the
  *                Privoxy team. https://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
@@ -700,8 +700,7 @@ char * make_path(const char * dir, const char * file)
           * Relative path, so start with the base directory.
           */
          path_size += strlen(basedir) + 1; /* +1 for the slash */
-         path = malloc(path_size);
-         if (!path) log_error(LOG_LEVEL_FATAL, "malloc failed!");
+         path = malloc_or_die(path_size);
          strlcpy(path, basedir, path_size);
          strlcat(path, "/", path_size);
          strlcat(path, dir, path_size);
@@ -709,8 +708,7 @@ char * make_path(const char * dir, const char * file)
       else
 #endif /* defined unix */
       {
-         path = malloc(path_size);
-         if (!path) log_error(LOG_LEVEL_FATAL, "malloc failed!");
+         path = malloc_or_die(path_size);
          strlcpy(path, dir, path_size);
       }
 
@@ -1002,6 +1000,49 @@ time_t timegm(struct tm *tm)
 #endif /* !defined(HAVE_TIMEGM) && defined(HAVE_TZSET) && defined(HAVE_PUTENV) */
 
 
+/*********************************************************************
+ *
+ * Function    :  host_is_ip_address
+ *
+ * Description :  Checks whether or not a host is specified by
+ *                IP address. Does not actually validate the
+ *                address.
+ *
+ * Parameters  :
+ *          1  :  host = The host name to check
+ *
+ * Returns     :   1 => Yes
+ *                 0 => No
+ *
+ *********************************************************************/
+extern int host_is_ip_address(const char *host)
+{
+   const char *p;
+
+   if (NULL != strstr(host, ":"))
+   {
+      /* Assume an IPv6 address. */
+      return 1;
+   }
+
+   for (p = host; *p; p++)
+   {
+      if ((*p != '.') && !privoxy_isdigit(*p))
+      {
+         /* Not a dot or digit so it can't be an IPv4 address. */
+         return 0;
+      }
+   }
+
+   /*
+    * Host only consists of dots and digits so
+    * assume that is an IPv4 address.
+    */
+   return 1;
+
+}
+
+
 /*
   Local Variables:
   tab-width: 3
index 7c5f7df..8f7c137 100644 (file)
@@ -91,6 +91,8 @@ size_t privoxy_strlcat(char *destination, const char *source, size_t size);
 extern int privoxy_millisleep(unsigned milliseconds);
 extern struct tm *privoxy_gmtime_r(const time_t *time_spec, struct tm *result);
 
+extern int host_is_ip_address(const char *host);
+
 #if defined(__cplusplus)
 }
 #endif
index a57cb32..39f4653 100644 (file)
--- a/openssl.c
+++ b/openssl.c
@@ -8,7 +8,7 @@
  *
  * Copyright   :  Written by and Copyright (c) 2020 Maxim Antonov <mantonov@gmail.com>
  *                Copyright (C) 2017 Vaclav Svec. FIT CVUT.
- *                Copyright (C) 2018-2020 by Fabian Keil <fk@fabiankeil.de>
+ *                Copyright (C) 2018-2022 by Fabian Keil <fk@fabiankeil.de>
  *
  *                This program is free software; you can redistribute it
  *                and/or modify it under the terms of the GNU General
 #include <openssl/pem.h>
 #include <openssl/md5.h>
 #include <openssl/x509v3.h>
+#ifdef _WIN32
+/* https://www.openssl.org/docs/faq.html
+   I’ve compiled a program under Windows and it crashes: Why?
+   tl,dr: because it needs this include:
+*/
+#include <openssl/applink.c>
+#endif /* _WIN32 */
 
 #include "config.h"
 #include "project.h"
@@ -790,17 +797,16 @@ extern int create_client_ssl_connection(struct client_state *csp)
     * certificate and key inconsistence must be locked.
     */
    privoxy_mutex_lock(&certificate_mutex);
-
    ret = generate_host_certificate(csp);
+   privoxy_mutex_unlock(&certificate_mutex);
+
    if (ret < 0)
    {
       log_error(LOG_LEVEL_ERROR,
-         "generate_host_certificate failed: %d", ret);
-      privoxy_mutex_unlock(&certificate_mutex);
+         "generate_host_certificate() failed: %d", ret);
       ret = -1;
       goto exit;
    }
-   privoxy_mutex_unlock(&certificate_mutex);
 
    if (!(ssl_attr->openssl_attr.ctx = SSL_CTX_new(SSLv23_server_method())))
    {
@@ -1155,6 +1161,11 @@ extern int create_server_ssl_connection(struct client_state *csp)
       goto exit;
    }
 
+   /*
+    * XXX: Do we really have to do this always?
+    *      Probably it's sufficient to do if the verification fails
+    *      in which case we're sending the certificates to the client.
+    */
    chain = SSL_get_peer_cert_chain(ssl);
    if (chain)
    {
@@ -1981,7 +1992,7 @@ static int generate_host_certificate(struct client_state *csp)
       goto exit;
    }
 
-   issuer_name = X509_get_issuer_name(issuer_cert);
+   issuer_name = X509_get_subject_name(issuer_cert);
 
    /*
     * Loading keys from file or from buffer
diff --git a/pcrs.c b/pcrs.c
index 007f7cc..eaeea62 100644 (file)
--- a/pcrs.c
+++ b/pcrs.c
@@ -57,7 +57,7 @@
  * Internal prototypes
  */
 
-static int              pcrs_parse_perl_options(const char *optstring, int *flags);
+static int              pcrs_parse_perl_options(const char *optstring, unsigned int *flags);
 static pcrs_substitute *pcrs_compile_replacement(const char *replacement, int trivialflag,
                         int capturecount, int *errptr);
 static int              is_hex_sequence(const char *sequence);
@@ -83,25 +83,25 @@ const char *pcrs_strerror(const int error)
       switch (error)
       {
          /* Passed-through PCRE error: */
-         case PCRE_ERROR_NOMEMORY:     return "(pcre:) No memory";
+         case PCREn(ERROR_NOMEMORY):     return "(pcre:) No memory";
 
          /* Shouldn't happen unless PCRE or PCRS bug, or user messed with compiled job: */
-         case PCRE_ERROR_NULL:         return "(pcre:) NULL code or subject or ovector";
-         case PCRE_ERROR_BADOPTION:    return "(pcre:) Unrecognized option bit";
-         case PCRE_ERROR_BADMAGIC:     return "(pcre:) Bad magic number in code";
+         case PCREn(ERROR_NULL):         return "(pcre:) NULL code or subject or ovector";
+         case PCREn(ERROR_BADOPTION):    return "(pcre:) Unrecognized option bit";
+         case PCREn(ERROR_BADMAGIC):     return "(pcre:) Bad magic number in code";
+#if defined(PCRE_ERROR_UNKNOWN_NODE)
          case PCRE_ERROR_UNKNOWN_NODE: return "(pcre:) Bad node in pattern";
-
+#endif
          /* Can't happen / not passed: */
-         case PCRE_ERROR_NOSUBSTRING:  return "(pcre:) Fire in power supply";
-         case PCRE_ERROR_NOMATCH:      return "(pcre:) Water in power supply";
+         case PCREn(ERROR_NOSUBSTRING):  return "(pcre:) Fire in power supply";
+         case PCREn(ERROR_NOMATCH):      return "(pcre:) Water in power supply";
 
 #ifdef PCRE_ERROR_MATCHLIMIT
          /*
           * Only reported by PCRE versions newer than our own.
           */
-         case PCRE_ERROR_MATCHLIMIT:   return "(pcre:) Match limit reached";
+         case PCREn(ERROR_MATCHLIMIT):   return "(pcre:) Match limit reached";
 #endif /* def PCRE_ERROR_MATCHLIMIT */
-
          /* PCRS errors: */
          case PCRS_ERR_NOMEM:          return "(pcrs:) No memory";
          case PCRS_ERR_CMDSYNTAX:      return "(pcrs:) Syntax error while parsing command";
@@ -111,16 +111,14 @@ const char *pcrs_strerror(const int error)
          case PCRS_WARN_TRUNCATION:
             return "(pcrs:) At least one variable was too big and has been truncated before compilation";
 
-         /*
-          * XXX: With the exception of PCRE_ERROR_MATCHLIMIT we
-          * only catch PCRE errors that can happen with our internal
-          * version. If Privoxy is linked against a newer
-          * PCRE version all bets are off ...
-          */
          default:
+#ifdef HAVE_PCRE2
+            pcre2_get_error_message(error, (PCRE2_UCHAR8*)buf, sizeof(buf));
+#else
             snprintf(buf, sizeof(buf),
                "Error code %d. For details, check the pcre documentation.",
                error);
+#endif
             return buf;
       }
    }
@@ -149,7 +147,7 @@ const char *pcrs_strerror(const int error)
  * Returns     :  option integer suitable for pcre
  *
  *********************************************************************/
-static int pcrs_parse_perl_options(const char *optstring, int *flags)
+static int pcrs_parse_perl_options(const char *optstring, unsigned int *flags)
 {
    size_t i;
    int rc = 0;
@@ -163,13 +161,13 @@ static int pcrs_parse_perl_options(const char *optstring, int *flags)
       {
          case 'e': break; /* ToDo ;-) */
          case 'g': *flags |= PCRS_GLOBAL; break;
-         case 'i': rc |= PCRE_CASELESS; break;
-         case 'm': rc |= PCRE_MULTILINE; break;
+         case 'i': rc |= PCREn(CASELESS); break;
+         case 'm': rc |= PCREn(MULTILINE); break;
          case 'o': break;
-         case 's': rc |= PCRE_DOTALL; break;
-         case 'x': rc |= PCRE_EXTENDED; break;
+         case 's': rc |= PCREn(DOTALL); break;
+         case 'x': rc |= PCREn(EXTENDED); break;
          case 'D': *flags |= PCRS_DYNAMIC; break;
-         case 'U': rc |= PCRE_UNGREEDY; break;
+         case 'U': rc |= PCREn(UNGREEDY); break;
          case 'T': *flags |= PCRS_TRIVIAL; break;
          default: break;
       }
@@ -471,7 +469,15 @@ pcrs_job *pcrs_free_job(pcrs_job *job)
    else
    {
       next = job->next;
-      if (job->pattern != NULL) free(job->pattern);
+      if (job->pattern != NULL)
+      {
+#ifdef HAVE_PCRE2
+         pcre2_code_free(job->pattern);
+#else
+         free(job->pattern);
+#endif
+      }
+#ifndef HAVE_PCRE2
       if (job->hints != NULL)
       {
 #ifdef PCRE_CONFIG_JIT
@@ -480,6 +486,7 @@ pcrs_job *pcrs_free_job(pcrs_job *job)
          free(job->hints);
 #endif
       }
+#endif
       if (job->substitute != NULL)
       {
          if (job->substitute->text != NULL) free(job->substitute->text);
@@ -626,10 +633,14 @@ pcrs_job *pcrs_compile_command(const char *command, int *errptr)
 pcrs_job *pcrs_compile(const char *pattern, const char *substitute, const char *options, int *errptr)
 {
    pcrs_job *newjob;
-   int flags;
+   unsigned int flags;
    int capturecount;
-   const char *error;
+#ifdef HAVE_PCRE2
+   int ret;
+#else
    int pcre_study_options = 0;
+   const char *error;
+#endif
 
    *errptr = 0;
 
@@ -661,25 +672,43 @@ pcrs_job *pcrs_compile(const char *pattern, const char *substitute, const char *
    /*
     * Compile the pattern
     */
+#ifdef HAVE_PCRE2
+   PCRE2_SIZE error_offset;
+   newjob->pattern = pcre2_compile((const unsigned char *)pattern,
+      PCRE2_ZERO_TERMINATED, (unsigned)newjob->options, errptr,
+      &error_offset, NULL);
+#else
    newjob->pattern = pcre_compile(pattern, newjob->options, &error, errptr, NULL);
+#endif
    if (newjob->pattern == NULL)
    {
       pcrs_free_job(newjob);
       return NULL;
    }
 
-
-#ifdef PCRE_STUDY_JIT_COMPILE
+#if defined(PCRE_STUDY_JIT_COMPILE) || defined(HAVE_PCRE2)
 #ifdef DISABLE_PCRE_JIT_COMPILATION
 #warning PCRE_STUDY_JIT_COMPILE is supported but Privoxy has been configured not to use it
 #else
    if (!(flags & PCRS_DYNAMIC))
    {
+#ifdef HAVE_PCRE2
+      /* Try to enable JIT compilation but continue if it's unsupported. */
+      if ((ret = pcre2_jit_compile(newjob->pattern, PCRE2_JIT_COMPLETE)) &&
+          (ret != PCRE2_ERROR_JIT_BADOPTION))
+      {
+         *errptr = ret;
+         pcrs_free_job(newjob);
+         return NULL;
+       }
+#else
       pcre_study_options = PCRE_STUDY_JIT_COMPILE;
+#endif
    }
 #endif
 #endif
 
+#ifndef HAVE_PCRE2
    /*
     * Generate hints. This has little overhead, since the
     * hints will be NULL for a boring pattern anyway.
@@ -691,13 +720,17 @@ pcrs_job *pcrs_compile(const char *pattern, const char *substitute, const char *
       pcrs_free_job(newjob);
       return NULL;
    }
-
+#endif
 
    /*
     * Determine the number of capturing subpatterns.
     * This is needed for handling $+ in the substitute.
     */
+#ifdef HAVE_PCRE2
+   if (0 > (*errptr = pcre2_pattern_info(newjob->pattern, PCRE2_INFO_CAPTURECOUNT, &capturecount)))
+#else
    if (0 > (*errptr = pcre_fullinfo(newjob->pattern, newjob->hints, PCRE_INFO_CAPTURECOUNT, &capturecount)))
+#endif
    {
       pcrs_free_job(newjob);
       return NULL;
@@ -809,14 +842,20 @@ int pcrs_execute_list(pcrs_job *joblist, char *subject, size_t subject_length, c
  *********************************************************************/
 int pcrs_execute(pcrs_job *job, const char *subject, size_t subject_length, char **result, size_t *result_length)
 {
-   int offsets[3 * PCRS_MAX_SUBMATCHES],
-       offset,
+   int offset,
        i, k,
        matches_found,
        submatches,
        max_matches = PCRS_MAX_MATCH_INIT;
    size_t newsize;
+#ifdef HAVE_PCRE2
+   pcrs_match *matches, *dummy;
+   pcre2_match_data *pcre2_matches;
+   size_t *offsets;
+#else
    pcrs_match *matches, *dummy;
+   int offsets[3 * PCRS_MAX_SUBMATCHES];
+#endif
    char *result_offset;
 
    offset = i = 0;
@@ -830,27 +869,38 @@ int pcrs_execute(pcrs_job *job, const char *subject, size_t subject_length, char
       return(PCRS_ERR_BADJOB);
    }
 
+#ifdef HAVE_PCRE2
+   if (NULL == (pcre2_matches = pcre2_match_data_create_from_pattern(job->pattern, NULL)))
+   {
+      return(PCRS_ERR_NOMEM);
+   }
+   offsets = pcre2_get_ovector_pointer(pcre2_matches);
+#endif
    if (NULL == (matches = (pcrs_match *)malloc((size_t)max_matches * sizeof(pcrs_match))))
    {
       return(PCRS_ERR_NOMEM);
    }
    memset(matches, '\0', (size_t)max_matches * sizeof(pcrs_match));
 
-
    /*
     * Find the pattern and calculate the space
     * requirements for the result
     */
    newsize = subject_length;
 
+#ifdef HAVE_PCRE2
+   while ((submatches = pcre2_match(job->pattern, (const unsigned char *)subject,
+                           subject_length, (size_t)offset, 0, pcre2_matches, NULL)) > 0)
+#else
    while ((submatches = pcre_exec(job->pattern, job->hints, subject, (int)subject_length, offset, 0, offsets, 3 * PCRS_MAX_SUBMATCHES)) > 0)
+#endif
    {
       job->flags |= PCRS_SUCCESS;
       matches[i].submatches = submatches;
 
       for (k = 0; k < submatches; k++)
       {
-         matches[i].submatch_offset[k] = offsets[2 * k];
+         matches[i].submatch_offset[k] = (int)offsets[2 * k];
 
          /* Note: Non-found optional submatches have length -1-(-1)==0 */
          matches[i].submatch_length[k] = (size_t)(offsets[2 * k + 1] - offsets[2 * k]);
@@ -867,7 +917,7 @@ int pcrs_execute(pcrs_job *job, const char *subject, size_t subject_length, char
       newsize += (size_t)offsets[0] * (size_t)job->substitute->backref_count[PCRS_MAX_SUBMATCHES];
 
       /* chunk after match */
-      matches[i].submatch_offset[PCRS_MAX_SUBMATCHES + 1] = offsets[1];
+      matches[i].submatch_offset[PCRS_MAX_SUBMATCHES + 1] = (int)offsets[1];
       matches[i].submatch_length[PCRS_MAX_SUBMATCHES + 1] = subject_length - (size_t)offsets[1] - 1;
       newsize += (subject_length - (size_t)offsets[1]) * (size_t)job->substitute->backref_count[PCRS_MAX_SUBMATCHES + 1];
 
@@ -894,12 +944,19 @@ int pcrs_execute(pcrs_job *job, const char *subject, size_t subject_length, char
             break;
       /* Go find the next one */
       else
-         offset = offsets[1];
+         offset = (int)offsets[1];
    }
    /* Pass pcre error through if (bad) failure */
+#ifdef HAVE_PCRE2
+   if (submatches < PCRE2_ERROR_NOMATCH)
+#else
    if (submatches < PCRE_ERROR_NOMATCH)
+#endif
    {
       free(matches);
+#ifdef HAVE_PCRE2
+      pcre2_match_data_free(pcre2_matches);
+#endif
       return submatches;
    }
    matches_found = i;
@@ -909,9 +966,19 @@ int pcrs_execute(pcrs_job *job, const char *subject, size_t subject_length, char
     * Get memory for the result (must be freed by caller!)
     * and append terminating null byte.
     */
-   if ((*result = (char *)malloc(newsize + 1)) == NULL)
+   if ((*result = (char *)malloc(newsize + 1
+#ifdef HAVE_PCRE2
+   /*
+    * Work around to prevent invalid reads in the jit code.
+    */
+                                             + 16
+#endif
+                                                 )) == NULL)
    {
       free(matches);
+#ifdef HAVE_PCRE2
+      pcre2_match_data_free(pcre2_matches);
+#endif
       return PCRS_ERR_NOMEM;
    }
    else
@@ -964,6 +1031,9 @@ int pcrs_execute(pcrs_job *job, const char *subject, size_t subject_length, char
    memcpy(result_offset, subject + offset, subject_length - (size_t)offset);
 
    *result_length = newsize;
+#ifdef HAVE_PCRE2
+   pcre2_match_data_free(pcre2_matches);
+#endif
    free(matches);
    return matches_found;
 
@@ -1101,7 +1171,7 @@ char pcrs_get_delimiter(const char *string)
  *********************************************************************/
 char *pcrs_execute_single_command(const char *subject, const char *pcrs_command, int *hits)
 {
-   size_t size;
+   size_t buffer_size, new_size;
    char *result = NULL;
    pcrs_job *job;
 
@@ -1109,12 +1179,12 @@ char *pcrs_execute_single_command(const char *subject, const char *pcrs_command,
    assert(pcrs_command);
 
    *hits = 0;
-   size = strlen(subject);
+   buffer_size = strlen(subject);
 
    job = pcrs_compile_command(pcrs_command, hits);
    if (NULL != job)
    {
-      *hits = pcrs_execute(job, subject, size, &result, &size);
+      *hits = pcrs_execute(job, subject, buffer_size, &result, &new_size);
       if (*hits < 0)
       {
          freez(result);
diff --git a/pcrs.h b/pcrs.h
index abff3ca..32cf37c 100644 (file)
--- a/pcrs.h
+++ b/pcrs.h
  *********************************************************************/
 
 
+#ifdef HAVE_PCRE2
+#define PCRE2_CODE_UNIT_WIDTH 8
+#define PCREn(x) PCRE2_ ## x
+#ifndef _PCRE2_H
+#include <pcre2.h>
+#endif
+#else
+#define PCREn(x) PCRE_ ## x
 #ifndef _PCRE_H
 #include <pcre.h>
 #endif
+#endif
 
 /*
  * Constants:
  * They are supposed to be handled together with PCRE error
  * codes and have to start with an offset to prevent overlaps.
  *
- * PCRE 6.7 uses error codes from -1 to -21, PCRS error codes
- * below -100 should be safe for a while.
+ * PCRE 6.7 uses error codes from -1 to -21,
+ * PCRE2 10.42 uses error codes from -66 to 101.
+ * PCRS error codes below -300 should be safe for a while.
  */
-#define PCRS_ERR_NOMEM           -100      /* Failed to acquire memory. */
-#define PCRS_ERR_CMDSYNTAX       -101      /* Syntax of s///-command */
-#define PCRS_ERR_STUDY           -102      /* pcre error while studying the pattern */
-#define PCRS_ERR_BADJOB          -103      /* NULL job pointer, pattern or substitute */
-#define PCRS_WARN_BADREF         -104      /* Backreference out of range */
-#define PCRS_WARN_TRUNCATION     -105      /* At least one pcrs variable was too big,
+#define PCRS_ERR_NOMEM           -300      /* Failed to acquire memory. */
+#define PCRS_ERR_CMDSYNTAX       -301      /* Syntax of s///-command */
+#define PCRS_ERR_STUDY           -302      /* pcre error while studying the pattern */
+#define PCRS_ERR_BADJOB          -303      /* NULL job pointer, pattern or substitute */
+#define PCRS_WARN_BADREF         -304      /* Backreference out of range */
+#define PCRS_WARN_TRUNCATION     -305      /* At least one pcrs variable was too big,
                                             * only the first part was used. */
 
 /* Flags */
-#define PCRS_GLOBAL          1      /* Job should be applied globally, as with perl's g option */
-#define PCRS_TRIVIAL         2      /* Backreferences in the substitute are ignored */
-#define PCRS_SUCCESS         4      /* Job did previously match */
-#define PCRS_DYNAMIC         8      /* Job is dynamic (used to disable JIT compilation) */
+#define PCRS_GLOBAL          0x08000000u      /* Job should be applied globally, as with perl's g option */
+#define PCRS_TRIVIAL         0x10000000u      /* Backreferences in the substitute are ignored */
+#define PCRS_SUCCESS         0x20000000u      /* Job did previously match */
+#define PCRS_DYNAMIC         0x40000000u      /* Job is dynamic (used to disable JIT compilation) */
 
 
 /*
@@ -107,10 +117,14 @@ typedef struct {
 /* A PCRS job */
 
 typedef struct PCRS_JOB {
+#ifdef HAVE_PCRE2
+    pcre2_code *pattern;
+#else
   pcre *pattern;                            /* The compiled pcre pattern */
   pcre_extra *hints;                        /* The pcre hints for the pattern */
+#endif
   int options;                              /* The pcre options (numeric) */
-  int flags;                                /* The pcrs and user flags (see "Flags" above) */
+  unsigned int flags;                       /* The pcrs and user flags (see "Flags" above) */
   pcrs_substitute *substitute;              /* The compiled pcrs substitute */
   struct PCRS_JOB *next;                    /* Pointer for chaining jobs to joblists */
 } pcrs_job;
index 27bd260..6ca56b4 100644 (file)
--- a/privoxy.8
+++ b/privoxy.8
@@ -1,6 +1,6 @@
 .\" This manpage has been generated by docbook2man-spec.pl
 .\" (included in the Privoxy source tarball) from a DocBook document.
-.TH "PRIVOXY" "8" "24 February 2021" "Privoxy 3.0.32" ""
+.TH "PRIVOXY" "8" "05 February 2023" "Privoxy 3.0.34" ""
 .SH NAME
 privoxy \- Privacy Enhancing Proxy
 .SH SYNOPSIS
@@ -210,7 +210,7 @@ configuration related suggestions to the developers.
 .SH "COPYRIGHT AND LICENSE"
 .SS "COPYRIGHT"
 .PP
-Copyright (C) 2001-2021 by Privoxy Developers <privoxy-devel@lists.privoxy.org>
+Copyright (C) 2001-2023 by Privoxy Developers <privoxy-devel@lists.privoxy.org>
 .PP
 Some source code is based on code Copyright (C) 1997 by Anonymous Coders
 and Junkbusters, Inc.
@@ -224,7 +224,8 @@ of the license, or (at your option) any later version.
 .PP
 The same is true for \fBPrivoxy\fR binaries
 unless they are linked with a
-mbed TLS version
+mbed TLS or
+OpenSSL version
 that is licensed under the Apache 2.0 license in which
 case you can redistribute and/or modify the \fBPrivoxy\fR
 binaries under the terms of the \fIGNU General Public License\fR
index 527a868..6aaefd7 100644 (file)
--- a/project.h
+++ b/project.h
 
 #ifdef FEATURE_HTTPS_INSPECTION_OPENSSL
 #ifdef _WIN32
+#include <windef.h>
+#include <minwindef.h>
+#include <basetsd.h>
+#include <minwinbase.h>
 #include <wincrypt.h>
 #undef X509_NAME
 #undef X509_EXTENSIONS
 #include <openssl/err.h>
 #endif /* FEATURE_HTTPS_INSPECTION_OPENSSL */
 
+#ifdef FEATURE_HTTPS_INSPECTION_WOLFSSL
+#include <wolfssl/options.h>
+#include <wolfssl/ssl.h>
+#endif /* FEATURE_HTTPS_INSPECTION_WOLFSSL */
+
 /* Need for struct sockaddr_storage */
 #ifdef HAVE_RFC2553
 #  ifndef _WIN32
  */
 
 #ifdef STATIC_PCRE
+#ifdef HAVE_PCRE2
+#  include "pcre2.h"
+#  include "pcre2posix.h"
+#else
 #  include "pcre.h"
+#  include "pcreposix.h"
+#endif
 #else
-#  ifdef PCRE_H_IN_SUBDIR
-#    include <pcre/pcre.h>
+#  ifdef HAVE_PCRE2
+#    ifdef PCRE2_H_IN_SUBDIR
+#      define PCRE2_CODE_UNIT_WIDTH 8
+#      include <pcre2/pcre2.h>
+#    else
+#      define PCRE2_CODE_UNIT_WIDTH 8
+#      include <pcre2.h>
+#    endif
+#    ifdef PCRE2POSIX_H_IN_SUBDIR
+#        include <pcre2/pcre2posix.h>
+#    else
+#        include <pcre2posix.h>
+#    endif
 #  else
-#    include <pcre.h>
+#    ifdef PCRE_H_IN_SUBDIR
+#      include <pcre/pcre.h>
+#    else
+#      include <pcre.h>
+#    endif
+#    ifdef PCREPOSIX_H_IN_SUBDIR
+#        include <pcre/pcreposix.h>
+#    else
+#        include <pcreposix.h>
+#    endif
 #  endif
 #endif
 
 #  include <pcrs.h>
 #endif
 
-#ifdef STATIC_PCRE
-#  include "pcreposix.h"
-#else
-#  ifdef PCRE_H_IN_SUBDIR
-#    include <pcre/pcreposix.h>
-#  else
-#    include <pcreposix.h>
-#  endif
-#endif
-
 #ifdef _WIN32
 /*
  * I don't want to have to #include all this just for the declaration
@@ -317,6 +342,17 @@ typedef struct {
    BIO *bio;
 } openssl_connection_attr;
 #endif /* FEATURE_HTTPS_INSPECTION_OPENSSL */
+
+#ifdef FEATURE_HTTPS_INSPECTION_WOLFSSL
+/*
+ * Struct of attributes necessary for TLS/SSL connection
+ */
+typedef struct {
+   WOLFSSL_CTX *ctx;
+   WOLFSSL *ssl;
+} wolfssl_connection_attr;
+#endif /* def FEATURE_HTTPS_INSPECTION_WOLFSSL */
+
 /**
  * A HTTP request.  This includes the method (GET, POST) and
  * the parsed URL.
@@ -404,10 +440,16 @@ struct http_response
   enum crunch_reason crunch_reason; /**< Why the response was generated in the first place. */
 };
 
+#ifdef HAVE_PCRE2
+#define REGEX_TYPE pcre2_code
+#else
+#define REGEX_TYPE regex_t
+#endif
+
 struct url_spec
 {
 #ifdef FEATURE_PCRE_HOST_PATTERNS
-   regex_t *host_regex;/**< Regex for host matching                          */
+   REGEX_TYPE *host_regex;/**< Regex for host matching                          */
    enum host_regex_type { VANILLA_HOST_PATTERN, PCRE_HOST_PATTERN } host_regex_type;
 #endif /* defined FEATURE_PCRE_HOST_PATTERNS */
    int    dcount;      /**< How many parts to this domain? (length of dvec)   */
@@ -417,7 +459,7 @@ struct url_spec
 
    char  *port_list;   /**< List of acceptable ports, or NULL to match all ports */
 
-   regex_t *preg;      /**< Regex for matching path part                      */
+  REGEX_TYPE *preg;    /**< Regex for matching path part                      */
 };
 
 /**
@@ -432,7 +474,7 @@ struct pattern_spec
    union
    {
       struct url_spec url_spec;
-      regex_t *tag_regex;
+      REGEX_TYPE *tag_regex;
    } pattern;
 
    unsigned int flags; /**< Bitmap with various pattern properties. */
@@ -642,8 +684,10 @@ struct iob
 #define ACTION_MULTI_SUPPRESS_TAG            7
 /** Index into current_action_spec::multi[] for client body filters to apply. */
 #define ACTION_MULTI_CLIENT_BODY_FILTER      8
+/** Index into current_action_spec::multi[] for client body taggers to apply. */
+#define ACTION_MULTI_CLIENT_BODY_TAGGER      9
 /** Number of multi-string actions. */
-#define ACTION_MULTI_COUNT                   9
+#define ACTION_MULTI_COUNT                  10
 
 
 /**
@@ -980,6 +1024,9 @@ struct ssl_attr {
 #ifdef FEATURE_HTTPS_INSPECTION_OPENSSL
    openssl_connection_attr  openssl_attr; /* OpenSSL atrrs */
 #endif /* FEATURE_HTTPS_INSPECTION_OPENSSL */
+#ifdef FEATURE_HTTPS_INSPECTION_WOLFSSL
+   wolfssl_connection_attr wolfssl_attr; /* wolfSSL atrrs */
+#endif /* FEATURE_HTTPS_INSPECTION_WOLFSSL */
 };
 /**
  * The state of a Privoxy processing thread.
@@ -1121,7 +1168,7 @@ struct client_state
 #define SSL_CERT_NOT_VERIFIED   0xFFFFFFFF
    uint32_t server_cert_verification_result;
 #endif /* FEATURE_HTTPS_INSPECTION_MBEDTLS */
-#ifdef FEATURE_HTTPS_INSPECTION_OPENSSL
+#if defined(FEATURE_HTTPS_INSPECTION_OPENSSL) || defined(FEATURE_HTTPS_INSPECTION_WOLFSSL)
 #define SSL_CERT_NOT_VERIFIED    ~0L
    long server_cert_verification_result;
 #endif /* FEATURE_HTTPS_INSPECTION_OPENSSL */
@@ -1296,17 +1343,18 @@ enum filter_type
    FT_SERVER_HEADER_TAGGER = 4,
    FT_SUPPRESS_TAG = 5,
    FT_CLIENT_BODY_FILTER = 6,
-   FT_ADD_HEADER = 7,
+   FT_CLIENT_BODY_TAGGER = 7,
+   FT_ADD_HEADER = 8,
 #ifdef FEATURE_EXTERNAL_FILTERS
-   FT_EXTERNAL_CONTENT_FILTER = 8,
+   FT_EXTERNAL_CONTENT_FILTER = 9,
 #endif
    FT_INVALID_FILTER       = 42,
 };
 
 #ifdef FEATURE_EXTERNAL_FILTERS
-#define MAX_FILTER_TYPES        9
+#define MAX_FILTER_TYPES        10
 #else
-#define MAX_FILTER_TYPES        8
+#define MAX_FILTER_TYPES        9
 #endif
 
 /**
index 939596a..92b4388 100644 (file)
@@ -9,7 +9,7 @@
 #
 #############################################################################
 #
-# Copyright (c) 2007-2021 Fabian Keil <fk@fabiankeil.de>
+# Copyright (c) 2007-2023 Fabian Keil <fk@fabiankeil.de>
 #
 # Permission to use, copy, modify, and distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
@@ -1141,6 +1141,11 @@ redirect.example.net/
 # Redirect Destination = http://redirected.example.net/&parameter1=part-of-the-redirected-url1&parameter2=part-of-the-redirected-url1
 redirect2.example.net/
 
+# Redirected URL = http://redirect3.example.net/01-02-03-04-05-06-07-08-09
+# Redirect Destination = http://redirect3.example.net/09-08-07-06-05-04-03-02-01
+{+redirect{s@/(\d+)-(\d+)-(\d+)-(\d+)-(\d+)-(\d+)-(\d+)-(\d+)-(\d+)@/$9-$8-$7-$6-$5-$4-$3-$2-$1@}}
+redirect3.example.net/01-02-03-04-05-06-07-08-09
+
 {+delay-response{1}}
 # Fetch Test = http://config.privoxy.org/show-url-info?url=http%3A%2F%2Fwww.example.com%2Fprivoxy-test-delay-response
 config.privoxy.org/show-url-info\?url=http%3A%2F%2Fwww\.example\.com%2Fprivoxy-test-delay-response
@@ -1152,3 +1157,8 @@ PCRE-HOST-PATTERN:^a{3}\.example\.org$
 # Blocked URL = http://bbb.example.org/
 # Level = 26
 PCRE-HOST-PATTERN:^(bbb|ccc|ddd)\.example\.org$
+
+{+block{Block should not apply because the path pattern is left-anchored}}
+# Sticky Actions = -block
+# URL = http://www.example.org/tralala/blafasel
+www.example.org/blafasel
diff --git a/ssl.c b/ssl.c
index afd9af4..0df7333 100644 (file)
--- a/ssl.c
+++ b/ssl.c
@@ -325,17 +325,16 @@ extern int create_client_ssl_connection(struct client_state *csp)
     * certificate and key inconsistence must be locked.
     */
    privoxy_mutex_lock(&certificate_mutex);
-
    ret = generate_host_certificate(csp);
+   privoxy_mutex_unlock(&certificate_mutex);
+
    if (ret < 0)
    {
       log_error(LOG_LEVEL_ERROR,
          "generate_host_certificate failed: %d", ret);
-      privoxy_mutex_unlock(&certificate_mutex);
       ret = -1;
       goto exit;
    }
-   privoxy_mutex_unlock(&certificate_mutex);
 
    /*
     * Seed the RNG
index 35970eb..45f1e76 100644 (file)
@@ -358,11 +358,22 @@ extern void ssl_send_certificate_error(struct client_state *csp)
    cert = &(csp->server_certs_chain);
    while (cert->next != NULL)
    {
-      size_t base64_len = 4 * ((strlen(cert->file_buf) + 2) / 3) + 1;
+      size_t base64_len;
 
-      message_len += strlen(cert->info_buf) + strlen("<pre></pre>\n")
-                     +  base64_len + strlen("<a href=\"data:application"
-                        "/x-x509-ca-cert;base64,\">Download certificate</a>");
+      if (cert->file_buf != NULL)
+      {
+         base64_len = 4 * ((strlen(cert->file_buf) + 2) / 3) + 1;
+
+         message_len += strlen(cert->info_buf) + strlen("<pre></pre>\n")
+            +  base64_len + strlen("<a href=\"data:application"
+            "/x-x509-ca-cert;base64,\">Download certificate</a>");
+      }
+      else
+      {
+         log_error(LOG_LEVEL_ERROR,
+            "Incomplete certificate information for %s.",
+            csp->http->hostport);
+      }
       cert = cert->next;
    }
 
@@ -379,31 +390,36 @@ extern void ssl_send_certificate_error(struct client_state *csp)
    cert = &(csp->server_certs_chain);
    while (cert->next != NULL)
    {
-      size_t olen = 0;
-      size_t base64_len = 4 * ((strlen(cert->file_buf) + 2) / 3) + 1; /* +1 for terminating null*/
-      char base64_buf[base64_len];
-      memset(base64_buf, 0, base64_len);
-
-      /* Encoding certificate into base64 code */
-      ret = ssl_base64_encode((unsigned char*)base64_buf,
-               base64_len, &olen, (const unsigned char*)cert->file_buf,
-               strlen(cert->file_buf));
-      if (ret != 0)
-      {
-         log_error(LOG_LEVEL_ERROR,
-            "Encoding to base64 failed, buffer is to small");
-      }
-
-      strlcat(message, "<pre>",        message_len);
-      strlcat(message, cert->info_buf, message_len);
-      strlcat(message, "</pre>\n",     message_len);
-
-      if (ret == 0)
+      if (cert->file_buf != NULL)
       {
-         strlcat(message, "<a href=\"data:application/x-x509-ca-cert;base64,",
-            message_len);
-         strlcat(message, base64_buf, message_len);
-         strlcat(message, "\">Download certificate</a>", message_len);
+                                           /* +1 for terminating null */
+         size_t base64_len = 4 * ((strlen(cert->file_buf) + 2) / 3) + 1;
+         size_t olen = 0;
+         char base64_buf[base64_len];
+
+         memset(base64_buf, 0, base64_len);
+
+         /* Encoding certificate into base64 code */
+         ret = ssl_base64_encode((unsigned char*)base64_buf,
+                  base64_len, &olen, (const unsigned char*)cert->file_buf,
+                  strlen(cert->file_buf));
+         if (ret != 0)
+         {
+            log_error(LOG_LEVEL_ERROR,
+               "Encoding to base64 failed, buffer is to small");
+         }
+
+         strlcat(message, "<pre>",        message_len);
+         strlcat(message, cert->info_buf, message_len);
+         strlcat(message, "</pre>\n",     message_len);
+
+         if (ret == 0)
+         {
+            strlcat(message, "<a href=\"data:application/x-x509-ca-cert;base64,",
+               message_len);
+            strlcat(message, base64_buf, message_len);
+            strlcat(message, "\">Download certificate</a>", message_len);
+         }
       }
 
       cert = cert->next;
@@ -673,49 +689,6 @@ extern int get_certificate_valid_to_date(char *buffer, size_t buffer_size, const
 }
 
 
-/*********************************************************************
- *
- * Function    :  host_is_ip_address
- *
- * Description :  Checks whether or not a host is specified by
- *                IP address. Does not actually validate the
- *                address.
- *
- * Parameters  :
- *          1  :  host = The host name to check
- *
- * Returns     :   1 => Yes
- *                 0 => No
- *
- *********************************************************************/
-extern int host_is_ip_address(const char *host)
-{
-   const char *p;
-
-   if (NULL != strstr(host, ":"))
-   {
-      /* Assume an IPv6 address. */
-      return 1;
-   }
-
-   for (p = host; *p; p++)
-   {
-      if ((*p != '.') && !privoxy_isdigit(*p))
-      {
-         /* Not a dot or digit so it can't be an IPv4 address. */
-         return 0;
-      }
-   }
-
-   /*
-    * Host only consists of dots and digits so
-    * assume that is an IPv4 address.
-    */
-   return 1;
-
-}
-
-
 /*********************************************************************
  *
  * Function    :  enforce_sane_certificate_state
index bd5ce0b..66fb537 100644 (file)
@@ -72,7 +72,6 @@ extern char *make_certs_path(const char *conf_dir, const char *file_name,
 extern unsigned long get_certificate_serial(struct client_state *csp);
 extern int get_certificate_valid_from_date(char *buffer, size_t buffer_size, const char *fmt);
 extern int get_certificate_valid_to_date(char *buffer, size_t buffer_size, const char *fmt);
-extern int host_is_ip_address(const char *host);
 extern int enforce_sane_certificate_state(const char *certificate, const char *key);
 
 #endif /* ndef SSL_COMMON_H_INCLUDED */
index 9fd6000..f53eae8 100644 (file)
@@ -81,7 +81,7 @@
 #  force-support:
 #    Privoxy has been compiled with support for forced loading
 #    of blocked content. In that case, the symbol "force-prefix" is
-#    avaiable, which translates to the FORCE_PREFIX
+#    available, which translates to the FORCE_PREFIX
 #
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 <html>
index 297d2bd..2e741c9 100644 (file)
@@ -49,7 +49,7 @@
 # section
 # pattern
 # oldval
-# jumptarget - append to eal URL to jump to relevant section
+# jumptarget - append anchor to eal URL to jump to relevant section
 #
 #############################################################################
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
@@ -96,7 +96,7 @@
         <p>
           <a class="cmd" href="edit-actions-remove-url?f=@f@&amp;v=@v@&amp;p=@p@">OK</a>
           &nbsp;
-          <a class="cmd" href="edit-actions-list?f=@f@@jumptarget@">Cancel</a>
+          <a class="cmd" href="edit-actions-list?f=@f@#@jumptarget@">Cancel</a>
         </p>
       </td>
     </tr>
index 1f49924..4af848e 100644 (file)
@@ -47,7 +47,7 @@
 # s - section
 # p - pattern
 # u - old value of URL
-# jumptarget - append to eal URL to jump to relevant section
+# jumptarget - append anchor to eal URL to jump to relevant section
 #
 #############################################################################
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
@@ -113,7 +113,7 @@ function validate(text)
             <input type="text" name="u" value="@u@" size="78" class="pattern"><br>
             <input type="submit" value="Submit"> &nbsp;
             <input type="reset" value="Reset"> &nbsp;
-            <a class="cmd" href="edit-actions-list?f=@f@@jumptarget@">Cancel</a>
+            <a class="cmd" href="edit-actions-list?f=@f@#@jumptarget@">Cancel</a>
           </p>
         </form>
       </td>
index 2336c06..a6aaf8b 100644 (file)
           which equals a block rate of @percent-blocked@%.
         </p>
         <p>
-          <strong>Note that the statistics currently don't work properly for
-          reused connections where only the last request gets counted.
-          You may want to look into Privoxy-Log-Parser's --statistics option,
-          which doesn't have this limitation.</strong>
+         For additional statistics you may want to look into Privoxy-Log-Parser's --statistics option.
 <!-- if-have-stats-end@ -->
 <!-- @if-have-no-stats-start -->
           There haven't been any requests so far.
             <tr>
               <td><code>FEATURE_DYNAMIC_PCRE</code></td>
               <td>@if-FEATURE_DYNAMIC_PCRE-then@ Yes @else-not-FEATURE_DYNAMIC_PCRE@ No @endif-FEATURE_DYNAMIC_PCRE@</td>
-              <td>Dynamically link to the PCRE library. This is set automatically
-               by <code>./configure</code> if you do not have libpcre installed.
-               Dynamically linking to an external libpcre is recommended as the one that is distributed
-               with Privoxy itself is outdated and lacks various features and bug-fixes you may be interested in.</td>
+              <td>Dynamically link to the PCRE(2) library (recommended).</td>
             </tr>
             <tr>
               <td><code>FEATURE_EXTENDED_STATISTICS</code></td>
             <tr>
               <td><code>FEATURE_HTTPS_INSPECTION</code></td>
               <td>@if-FEATURE_HTTPS_INSPECTION-then@ Yes @else-not-FEATURE_HTTPS_INSPECTION@ No @endif-FEATURE_HTTPS_INSPECTION@</td>
-              <td>Allows to intercept and filter HTTPS traffic. Experimental.</td>
+              <td>Allows to intercept and filter HTTPS traffic.</td>
             </tr>
             <tr>
               <td><code>FEATURE_IMAGE_BLOCKING</code></td>
index 1a55261..da30f68 100644 (file)
@@ -77,7 +77,7 @@
 #  force-support:
 #    Privoxy has been compiled with support for forced loading
 #    of blocked content. In that case, the symbol "force-prefix" is
-#    avaiable, which translates to the FORCE_PREFIX
+#    available, which translates to the FORCE_PREFIX
 #  have-trust-info:
 #    There were URLs with info on the trust policy defined in the config
 #    file. In this case the list of URLs is available through the
diff --git a/tests/cts/README b/tests/cts/README
new file mode 100644 (file)
index 0000000..831f37a
--- /dev/null
@@ -0,0 +1,52 @@
+This directory contains tests that leverage curl's test suite (cts).
+
+For details about curl see: https://curl.se/
+
+Some temporary hints are below:
+
+From the parent directory of the directory with the
+Privoxy sources do:
+
+ git clone https://github.com/curl/curl.git
+
+ cd curl
+ git checkout -b before-cts-regressions 073268a6de3
+
+ # Build curl as described in GIT-INFO. Note that the configure
+ # call needs to explicitly choose a TLS library. For example
+ # by adding "--with-openssl".
+
+ # Install stunnel
+
+ # Test that curl's tests are working without Privoxy
+ make test
+
+You can then cd back into privoxy/tests/cts and execute the
+tests by running:
+
+  run-privoxy-tests.sh
+
+The script takes care of starting Privoxy with a configuration expected
+by the tests. Note that unlike privoxy-regression-test.pl it currently
+does not automatically check that Privoxy has been built with all the
+features required for the tests to work and simply tries to execute
+all tests.
+
+The tests are divided into multiple test scenarios.
+
+Each test scenario has its own subdirectory with a Privoxy
+configuration file called privoxy.conf and a data directory
+containing the test files.
+
+The tests are written using the "curl test suite file format"
+described at:
+https://github.com/curl/curl/blob/master/tests/FILEFORMAT.md
+
+One extension made is that a <proxy-reply> section is supported
+which will be used when checking the test results instead of using
+the <reply> section that would be used otherwise.
+
+This extension is supported by loading a custom perl library
+(privoxy-runtests.pm) when running runtests.pl. Loading the library
+is done with runtests-wrapper.sh which also sets a couple of other
+required options and is normally called through run-privoxy-tests.sh.
diff --git a/tests/cts/acl-destination-denied/data/test1 b/tests/cts/acl-destination-denied/data/test1
new file mode 100644 (file)
index 0000000..cabad3b
--- /dev/null
@@ -0,0 +1,25 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<client>
+<server>
+none
+</server>
+<name>
+Request to denied destination IP address
+</name>
+<command>
+http://%HOSTIP/%TESTNUMBER
+</command>
+</client>
+<verify>
+<errorcode>
+56
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/acl-destination-denied/privoxy.conf b/tests/cts/acl-destination-denied/privoxy.conf
new file mode 100644 (file)
index 0000000..b4b233c
--- /dev/null
@@ -0,0 +1,18 @@
+listen-address 127.0.0.1:9119
+
+debug     1 # Log the destination for each request Privoxy let through. See also debug 1024.
+debug     2 # show each connection status
+debug     4 # show tagging-related messages
+debug     8 # show header parsing
+debug    32 # debug force feature
+debug    64 # debug regular expression filters
+debug   128 # debug redirects
+debug   256 # debug GIF de-animation
+debug   512 # Common Log Format
+debug  1024 # Log the destination for requests Privoxy didn't let through, and the reason why.
+debug  4096 # Startup banner and warnings.
+debug  8192 # Non-fatal errors
+
+deny-access 127.0.0.1 127.0.0.1
+permit-access 127.0.0.2
+
diff --git a/tests/cts/acl-destination-permitted/data/test1 b/tests/cts/acl-destination-permitted/data/test1
new file mode 100644 (file)
index 0000000..fb72645
--- /dev/null
@@ -0,0 +1,32 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+Content-Length: 14
+
+Blafaseldieda
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Request from permitted IP address to permitted destination address
+</name>
+<command>
+http://%HOSTIP:%HTTPPORT/%TESTNUMBER
+</command>
+</client>
+
+</testcase>
diff --git a/tests/cts/acl-destination-permitted/privoxy.conf b/tests/cts/acl-destination-permitted/privoxy.conf
new file mode 100644 (file)
index 0000000..d738cd8
--- /dev/null
@@ -0,0 +1,19 @@
+listen-address 127.0.0.1:9119
+
+debug     1 # Log the destination for each request Privoxy let through. See also debug 1024.
+debug     2 # show each connection status
+debug     4 # show tagging-related messages
+debug     8 # show header parsing
+debug    32 # debug force feature
+debug    64 # debug regular expression filters
+debug   128 # debug redirects
+debug   256 # debug GIF de-animation
+debug   512 # Common Log Format
+debug  1024 # Log the destination for requests Privoxy didn't let through, and the reason why.
+debug  4096 # Startup banner and warnings.
+debug  8192 # Non-fatal errors
+
+deny-access 127.0.0.1 127.0.0.2
+deny-access 127.0.0.2 127.0.0.1
+permit-access 127.0.0.1 127.0.0.1
+
diff --git a/tests/cts/acl-ip-address-denied/data/test1 b/tests/cts/acl-ip-address-denied/data/test1
new file mode 100644 (file)
index 0000000..354a8ad
--- /dev/null
@@ -0,0 +1,25 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<client>
+<server>
+none
+</server>
+<name>
+Request from denied IP address
+</name>
+<command>
+http://www.privoxy.org/%TESTNUMBER
+</command>
+</client>
+<verify>
+<errorcode>
+56
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/acl-ip-address-denied/privoxy.conf b/tests/cts/acl-ip-address-denied/privoxy.conf
new file mode 100644 (file)
index 0000000..b5ffdca
--- /dev/null
@@ -0,0 +1,18 @@
+listen-address 127.0.0.1:9119
+
+debug     1 # Log the destination for each request Privoxy let through. See also debug 1024.
+debug     2 # show each connection status
+debug     4 # show tagging-related messages
+debug     8 # show header parsing
+debug    32 # debug force feature
+debug    64 # debug regular expression filters
+debug   128 # debug redirects
+debug   256 # debug GIF de-animation
+debug   512 # Common Log Format
+debug  1024 # Log the destination for requests Privoxy didn't let through, and the reason why.
+debug  4096 # Startup banner and warnings.
+debug  8192 # Non-fatal errors
+
+deny-access 127.0.0.1
+permit-access 127.0.0.2
+
diff --git a/tests/cts/acl-ip-address-permitted/data/test1 b/tests/cts/acl-ip-address-permitted/data/test1
new file mode 100644 (file)
index 0000000..4c14cd6
--- /dev/null
@@ -0,0 +1,32 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+Content-Length: 14
+
+Blafaseldieda
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Request from permitted IP address
+</name>
+<command>
+http://%HOSTIP:%HTTPPORT/%TESTNUMBER
+</command>
+</client>
+
+</testcase>
diff --git a/tests/cts/acl-ip-address-permitted/privoxy.conf b/tests/cts/acl-ip-address-permitted/privoxy.conf
new file mode 100644 (file)
index 0000000..5e5fa4a
--- /dev/null
@@ -0,0 +1,18 @@
+listen-address 127.0.0.1:9119
+
+debug     1 # Log the destination for each request Privoxy let through. See also debug 1024.
+debug     2 # show each connection status
+debug     4 # show tagging-related messages
+debug     8 # show header parsing
+debug    32 # debug force feature
+debug    64 # debug regular expression filters
+debug   128 # debug redirects
+debug   256 # debug GIF de-animation
+debug   512 # Common Log Format
+debug  1024 # Log the destination for requests Privoxy didn't let through, and the reason why.
+debug  4096 # Startup banner and warnings.
+debug  8192 # Non-fatal errors
+
+deny-access 127.0.0.2
+permit-access 127.0.0.1
+
diff --git a/tests/cts/blocked-https-requests/data/test1 b/tests/cts/blocked-https-requests/data/test1
new file mode 100644 (file)
index 0000000..b5e2140
--- /dev/null
@@ -0,0 +1,58 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+Content-Length: 18
+
+Here's your data.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established
+
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+Content-Length: 18
+
+Here's your data.
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Blocked https request followed by unblocked request for the same host which means the connection can't be reused
+</name>
+<command>
+--insecure -s --write-out '%{stderr}%{response_code}\n' https://%HOSTIP:%HTTPSPORT/ads/%TESTNUMBER --output log/curl1.out https://%HOSTIP:%HTTPSPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<stderr>
+403
+200
+</stderr>
+</verify>
+</testcase>
diff --git a/tests/cts/blocked-https-requests/https-inspection.action b/tests/cts/blocked-https-requests/https-inspection.action
new file mode 100644 (file)
index 0000000..01b2181
--- /dev/null
@@ -0,0 +1,2 @@
+{+https-inspection +ignore-certificate-errors}
+/
diff --git a/tests/cts/blocked-https-requests/privoxy.conf b/tests/cts/blocked-https-requests/privoxy.conf
new file mode 100644 (file)
index 0000000..fb2304a
--- /dev/null
@@ -0,0 +1,31 @@
+listen-address 127.0.0.1:9119
+
+ca-directory          ../ca-directory
+ca-cert-file          privoxy-test-cacert.crt
+ca-key-file           privoxy-test-cakey.pem
+ca-password           blafasel
+# We don't check certificate anyway
+trusted-cas-file      privoxy-test-cacert.crt
+
+certificate-directory ../certs
+
+debug     1 # Log the destination for each request Privoxy let through. See also debug 1024.
+debug     2 # show each connection status
+debug     4 # show tagging-related messages
+debug     8 # show header parsing
+debug    32 # debug force feature
+debug    64 # debug regular expression filters
+debug   128 # debug redirects
+debug   256 # debug GIF de-animation
+debug   512 # Common Log Format
+debug  1024 # Log the destination for requests Privoxy didn't let through, and the reason why.
+debug  4096 # Startup banner and warnings.
+debug  8192 # Non-fatal errors
+
+actionsfile https-inspection.action
+actionsfile ../../../default.action.master
+filterfile  ../../../default.filter
+
+templdir ../../../templates
+
+keep-alive-timeout 15
diff --git a/tests/cts/ca-directory/privoxy-test-cacert.crt b/tests/cts/ca-directory/privoxy-test-cacert.crt
new file mode 100644 (file)
index 0000000..49d2963
--- /dev/null
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDVTCCAj2gAwIBAgIJAMn580TY7tn4MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV
+BAYTAkRFMRMwEQYDVQQIDApTb21lLVN0YXRlMR0wGwYDVQQKDBRQcml2b3h5IFRl
+c3QgQ29tcGFueTAeFw0yMTAxMDkxNjQxMzNaFw0zMTAxMDcxNjQxMzNaMEExCzAJ
+BgNVBAYTAkRFMRMwEQYDVQQIDApTb21lLVN0YXRlMR0wGwYDVQQKDBRQcml2b3h5
+IFRlc3QgQ29tcGFueTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMCG
+dyCmLX+UmlP0eN+4kWQsP0bVATlmfycSjgXwhdMfQ7pHrP5RUM+Mzy60vYfXVLCn
+O6evxqx2XcZnEk6QxXRaUZfmd4Zw9F1n39x9ERFXgDNseRyoebqfmgl05STxe3Co
+NSSvYRz6iX4grzx+LWikwxvMHvPZyntPXgFhwuo6j9mBm6XfN8zIghwlQQbcgb9m
+WDC/XbFDCQcrEnGaQNJ5T2406EZptm2MZ4xU4P5M7LmQws8p7VgLiYdPyouZ2YN7
+PkCcVGzVY3YiCg7W2ETZHHurn4XsRWXdr7tgH2RzzC1Eok8QtEyn9C3XtUNWQv3J
+LeRn5LAiF7CxJKUtI3sCAwEAAaNQME4wHQYDVR0OBBYEFB7YVII5luGzJXJKgYZh
+fVH8D7CXMB8GA1UdIwQYMBaAFB7YVII5luGzJXJKgYZhfVH8D7CXMAwGA1UdEwQF
+MAMBAf8wDQYJKoZIhvcNAQELBQADggEBAAoEtgyL3paPULfconAkzRRk74XDjsz8
+sz+eSsbf0pVS4CNEWa1jrgv5PfKMqquYkDJ7IY8dD9Kqmzd/82KNZSlYACwOSbPV
+1t98wNWvvVg7eMJD3IdKcSR3HAvR75eQFI7JVy0EG62o5fGplfAZxauBa5cPhgGd
+I1DJrp/XFTOvv/SfNBMXgLZq8b6SMwyqomflNSFEfiC8IO7gEcE7CBbkHN+Hd15W
+YvAbJraAeP0YR+r2HKCqUbIVxbBWZlkjS1alvwsgDgamTVyQvNiAPzVsNY0G7lWJ
+f10kaB7Gd8NoER7jKBs6nbQTvb5UapQa0G4i3RHlYBUyg8+znz2OXK0=
+-----END CERTIFICATE-----
diff --git a/tests/cts/ca-directory/privoxy-test-cakey.pem b/tests/cts/ca-directory/privoxy-test-cakey.pem
new file mode 100644 (file)
index 0000000..612e9ed
--- /dev/null
@@ -0,0 +1,30 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQI3FrXU0ecRrECAggA
+MBQGCCqGSIb3DQMHBAhSvq1gGYC2RQSCBMihUnjghKpYieBD+F25LE8xbT+hJn1D
+n91Ax+q/0zpGCiX8CCLVbfK9i6rCmnO1qEa7YNzKSUdEmWoMrpH7wdJG5AHgRv4g
+9IiFG8HOCNFit75cQX8Fu2XrkfCSzKa0vjKZLylSrjf3UPPD+Oiifq/FD6zZtKIv
+hDM9tq0+JXQBrM2YME6yyKhueg6g1LFs6Spk2EoOW5er6ztzuM5Tv0g7P2BtPnS5
+Gi/xIGUCA0Nm8UyzjumDNtmet2xq2viKs49Ditlubu6gAJq/wHiyY/SpyBnNVbKT
+jO4VJVlXLBc0qracLLPIvL894Sc3mTe4RGDpZ2qGLgkGISzvWK9BHJjK/C37KAbQ
+/0zJFkRqJ4MOgiVlYzsTqixsw0T5qbGbtZkjV/iLwoeGKR+pVezqmlt6PvYgrRBg
+rlVnDLHuR3UKXstww0/Iyy8yON0jQYfzvSTFhsMEwv9eph/M9vwbND2oxrHY4SgY
+3Dm/alM3Bg/ZT4i7zwTMFTBC9SsJZvhAZ09Jvp1sStCmdKh1OQzeKDXZwjfbQKBC
+QYFJkXsTZkCANoHNHVVWH31KUGMc4YAR+JMYSMJFre1IG1zxGITZ3T3oULwd/Ym7
+1cWifrLWqXvZnm+xJFuvKR+pZxkPPeCmRcFA6K9U6CFEBpDHNFxYQv7Dbsv8GBpn
+PqYDegtB8v2ZLr50u2p4sdQxsqKwiTvO8Ok9DU7cKx0JqGti/owi+1e2kJAj6b++
+dwwrfExrfy50BiAQeTtDx/5Urq7N+U1gfGNkVvXLO7UBCgy4irkOZtTy+akETrkG
+gZiZz+d/4n/B5x6PP6JxWSX/FhRA4BCywTKV2WQqFNjVEx9QTe6dZPvJ+f1qUEUY
+yavQZTisiOnyCTFb/oDRAOcRBcUKhZYlDhfujAoiMQi9YHPmwywNiLcEJgVZcM/j
+OJmAzlGR1RA/9IjcJAp63OyfqwIUwMGx61shGv0yuApiKib/tBhQdc6MGZ/kqKMd
+qMy2/YK0IeAtq+E5yuHwh5XcoU8zff2+WWKdiygA6fiBHAp7ct5HD8HvpvM5cuyz
+yBkZKrd2vxrADEw14cCKeZ++8MoHGgAENtnwOEzZZzH0QLNgB2FiNsBCF/YFIQAZ
+RXPp/ltox/fQcT2XNiZK7B818Dsu2JD7TIXdI/cQPCToYwCKOvSGWsh7lLml86wE
+cXj07Rn8asWJUan/UlTHJLydHjMa0eQm9pCBwhpZLOOmvxXrBRlPAQdcly9uNCso
+SwjyY4hb8F6L2BY61mmC84F5wShFdxEtyhF+icYjj2wdiA6PWAHacHpuDN/pivEX
+oWM4m9NQTHqO+vujLuLOIyZ4Kz8uK5QkMveSdYP8Hitc8DfCGwatpbDbrZ/dh/jC
+8znnrmkglkNb/C7DMyJLFRWU4QAjAa6HCGCzzH2QEU7DgTYPB+q+/umr5/WcVu5N
+av2mfyRwTWvMiYQvbG7R9lOd8pHMP6NEaeeKJvjuDfdDv/7klu/wMEngns+JNlS+
+uqhLYlvDVkOph9423radHtirk97fdzn1fQuWAt0AphQKtvExNEmVs3dQEKcwHJmh
+KGKprXEq1xVAkhv+MA7H5XuYAXsJ+MOc7V2SlA/ccavWRFjPUuHQu08ksc7rcJUa
+vGw=
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/cts/certs/.gitignore b/tests/cts/certs/.gitignore
new file mode 100644 (file)
index 0000000..b9913c1
--- /dev/null
@@ -0,0 +1,3 @@
+# Ignore the certificates and keys in this directory
+*.crt
+*.pem
diff --git a/tests/cts/chunked-transfer-encoding-https/chunked-transfer-encoding.action b/tests/cts/chunked-transfer-encoding-https/chunked-transfer-encoding.action
new file mode 100644 (file)
index 0000000..efb0b96
--- /dev/null
@@ -0,0 +1,5 @@
+{+https-inspection +ignore-certificate-errors}
+/
+
+{+filter{img-reorder}}
+/chunked-transfer-encoding/
diff --git a/tests/cts/chunked-transfer-encoding-https/data/test1 b/tests/cts/chunked-transfer-encoding-https/data/test1
new file mode 100644 (file)
index 0000000..9c2331b
--- /dev/null
@@ -0,0 +1,65 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+6\r
+AAAAA
+\r
+0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+AAAAA
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Chunked transfer encoding - One chunk delivered through https.
+</name>
+<features>
+proxy
+</features>
+<command>
+--insecure --raw https://%HOSTIP:%HTTPSPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding-https/data/test10 b/tests/cts/chunked-transfer-encoding-https/data/test10
new file mode 100644 (file)
index 0000000..34515ac
--- /dev/null
@@ -0,0 +1,83 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+100\r
+%repeat[255 x A]%
+\r
+100\r
+%repeat[255 x B]%
+\r
+100\r
+%repeat[255 x C]%
+\r
+Bogus data.\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+100\r
+%repeat[255 x A]%
+\r
+100\r
+%repeat[255 x B]%
+\r
+100\r
+%repeat[255 x C]%
+\r
+Bogus data.\r
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Chunked transfer encoding - Multiple chunks, bogus data instead of last chunk.
+</name>
+<features>
+proxy
+</features>
+<command>
+--insecure --raw https://%HOSTIP:%HTTPSPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+18
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding-https/data/test11 b/tests/cts/chunked-transfer-encoding-https/data/test11
new file mode 100644 (file)
index 0000000..cbed307
--- /dev/null
@@ -0,0 +1,85 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+100\r
+%repeat[255 x A]%
+\r
+100\r
+%repeat[255 x B]%
+\r
+100\r
+%repeat[255 x C]%
+\r
+100\r
+%repeat[1000 x D]%
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+100\r
+%repeat[255 x A]%
+\r
+100\r
+%repeat[255 x B]%
+\r
+100\r
+%repeat[255 x C]%
+\r
+100\r
+%repeat[1000 x D]%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Chunked transfer encoding - Multiple chunks, chunk at the end too big.
+</name>
+<features>
+proxy
+</features>
+<command>
+--insecure --raw https://%HOSTIP:%HTTPSPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+56
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding-https/data/test12 b/tests/cts/chunked-transfer-encoding-https/data/test12
new file mode 100644 (file)
index 0000000..aa089ec
--- /dev/null
@@ -0,0 +1,80 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+100\r
+%repeat[255 x A]%
+\r
+100\r
+%repeat[255 x B]%
+\r
+100\r
+%repeat[255 x C]%
+\r
+100\r
+%repeat[255 x 0]%
+\r
+0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+%repeat[255 x A]%
+%repeat[255 x B]%
+%repeat[255 x C]%
+%repeat[255 x 0]%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Chunked transfer encoding - Multiple chunks, chunk at the end contains zeros but is valid
+</name>
+<features>
+proxy
+</features>
+<command>
+--insecure --raw https://%HOSTIP:%HTTPSPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding-https/data/test13 b/tests/cts/chunked-transfer-encoding-https/data/test13
new file mode 100644 (file)
index 0000000..1a545c0
--- /dev/null
@@ -0,0 +1,80 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+100\r
+%repeat[255 x A]%
+\r
+100\r
+%repeat[255 x B]%
+\r
+100\r
+%repeat[255 x C]%
+\r
+100\r
+%repeat[255 x %01]%
+\r
+0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+%repeat[255 x A]%
+%repeat[255 x B]%
+%repeat[255 x C]%
+%repeat[255 x %01]%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Chunked transfer encoding - Multiple chunks, chunk at the end contains binary ones and is valid
+</name>
+<features>
+proxy
+</features>
+<command>
+--insecure --raw https://%HOSTIP:%HTTPSPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding-https/data/test14 b/tests/cts/chunked-transfer-encoding-https/data/test14
new file mode 100644 (file)
index 0000000..71d0c09
--- /dev/null
@@ -0,0 +1,80 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+100\r
+%repeat[255 x A]%
+\r
+100\r
+%repeat[255 x B]%
+\r
+100\r
+%repeat[255 x C]%
+\r
+100\r
+%repeat[255 x %hex[%00]hex%]%
+\r
+0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+%repeat[255 x A]%
+%repeat[255 x B]%
+%repeat[255 x C]%
+%repeat[255 x %hex[%00]hex%]%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Chunked transfer encoding - Multiple chunks, chunk at the end contains binary zeroes and is valid.
+</name>
+<features>
+proxy
+</features>
+<command>
+--insecure https://%HOSTIP:%HTTPSPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding-https/data/test15 b/tests/cts/chunked-transfer-encoding-https/data/test15
new file mode 100644 (file)
index 0000000..99163a0
--- /dev/null
@@ -0,0 +1,80 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+100\r
+%repeat[255 x A]%
+\r
+100\r
+%repeat[255 x B]%
+\r
+100\r
+%repeat[255 x C]%
+\r
+100\r
+%repeat[255 x %hex[%00]hex%]%
+\r
+0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+%repeat[255 x A]%
+%repeat[255 x B]%
+%repeat[255 x C]%
+%repeat[255 x %hex[%00]hex%]%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Chunked transfer encoding - Multiple chunks, chunk at the end contains binary zeroes and is valid.
+</name>
+<features>
+proxy
+</features>
+<command>
+--insecure --raw https://%HOSTIP:%HTTPSPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding-https/data/test16 b/tests/cts/chunked-transfer-encoding-https/data/test16
new file mode 100644 (file)
index 0000000..95731bc
--- /dev/null
@@ -0,0 +1,68 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+2\r
+%hex[%00]hex%
+\r
+0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+%hex[%00]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Chunked transfer encoding - Single chunk with binary zeroes that is valid.
+</name>
+<features>
+proxy
+</features>
+<command>
+--insecure https://%HOSTIP:%HTTPSPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding-https/data/test17 b/tests/cts/chunked-transfer-encoding-https/data/test17
new file mode 100644 (file)
index 0000000..e78c6f0
--- /dev/null
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+%hex[%FF%00%01]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+%hex[%FF%00%01]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Binary data test. XXX: Not actually a chunked test.
+</name>
+<features>
+proxy
+</features>
+<command>
+--insecure https://%HOSTIP:%HTTPSPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding-https/data/test18 b/tests/cts/chunked-transfer-encoding-https/data/test18
new file mode 100644 (file)
index 0000000..12b4310
--- /dev/null
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+%hex[%00]hex%Blafasel
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+%hex[%00]hex%Blafasel
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Binary zero test. XXX: Not actually a chunked-transfer-encoding test.
+</name>
+<features>
+proxy
+</features>
+<command>
+--insecure https://%HOSTIP:%HTTPSPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding-https/data/test19 b/tests/cts/chunked-transfer-encoding-https/data/test19
new file mode 100644 (file)
index 0000000..40ff92b
--- /dev/null
@@ -0,0 +1,80 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+100\r
+%repeat[255 x %00]%
+\r
+100\r
+%repeat[255 x %00]%
+\r
+100\r
+%repeat[255 x %00]%
+\r
+100\r
+%repeat[255 x %00]%
+\r
+0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+%repeat[255 x %00]%
+%repeat[255 x %00]%
+%repeat[255 x %00]%
+%repeat[255 x %00]%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Chunked transfer encoding - Multiple valid chunks with binary zeros.
+</name>
+<features>
+proxy
+</features>
+<command>
+--insecure https://%HOSTIP:%HTTPSPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding-https/data/test2 b/tests/cts/chunked-transfer-encoding-https/data/test2
new file mode 100644 (file)
index 0000000..4ec49b8
--- /dev/null
@@ -0,0 +1,77 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+6\r
+AAAAA
+\r
+100\r
+%repeat[255 x B]%
+\r
+1000\r
+%repeat[4095 x C]%
+\r
+10000\r
+%repeat[65535 x D]%
+\r
+0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established
+
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: close
+Content-Type: text/html
+X-Control: swsclose
+
+AAAAA
+%repeat[255 x B]%
+%repeat[4095 x C]%
+%repeat[65535 x D]%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Chunked transfer encoding - Multiple chunks delivered through https.
+</name>
+<features>
+proxy
+</features>
+<command>
+--insecure --raw https://%HOSTIP:%HTTPSPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding-https/data/test20 b/tests/cts/chunked-transfer-encoding-https/data/test20
new file mode 100644 (file)
index 0000000..5b933b9
--- /dev/null
@@ -0,0 +1,86 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+100\r
+%repeat[255 x A]%
+\r
+100\r
+%repeat[255 x B]%
+\r
+100 blafasel %hex[%00]hex%\r
+%repeat[255 x C]%
+\r
+0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+100\r
+%repeat[255 x A]%
+\r
+100\r
+%repeat[255 x B]%
+\r
+100 blafasel %hex[%00]hex%\r
+%repeat[255 x C]%
+\r
+0\r
+\r
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Chunked transfer encoding - Multiple chunks, invalid binary zero in chunk extension.
+</name>
+<features>
+proxy
+</features>
+<command>
+--insecure --raw https://%HOSTIP:%HTTPSPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+# XXX: Why does curl not detect this?
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding-https/data/test21 b/tests/cts/chunked-transfer-encoding-https/data/test21
new file mode 100644 (file)
index 0000000..91cc78c
--- /dev/null
@@ -0,0 +1,76 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+12345\r
+%repeat[74564 x A]%
+\r
+67891\r
+%repeat[424080 x B]%
+\r
+31337\r
+%repeat[201526 x C]%
+\r
+0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+%repeat[74564 x A]%
+%repeat[424080 x B]%
+%repeat[201526 x C]%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Chunked transfer encoding - Multiple largish chunks.
+</name>
+<features>
+proxy
+</features>
+<command>
+--insecure https://%HOSTIP:%HTTPSPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding-https/data/test22 b/tests/cts/chunked-transfer-encoding-https/data/test22
new file mode 100644 (file)
index 0000000..320fbf8
--- /dev/null
@@ -0,0 +1,64 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Chunked transfer encoding - Only last chunk, no actual data.
+</name>
+<features>
+proxy
+</features>
+<command>
+--insecure https://%HOSTIP:%HTTPSPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding-https/data/test3 b/tests/cts/chunked-transfer-encoding-https/data/test3
new file mode 100644 (file)
index 0000000..c51b1f6
--- /dev/null
@@ -0,0 +1,77 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+6 Oh noes\r
+AAAAA
+\r
+100 there is\r
+%repeat[255 x B]%
+\r
+1000 bogus data\r
+%repeat[4095 x C]%
+\r
+10000 here \r
+%repeat[65535 x D]%
+\r
+0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+AAAAA
+%repeat[255 x B]%
+%repeat[4095 x C]%
+%repeat[65535 x D]%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Chunked transfer encoding - Multiple chunks with garbage after chunk-sizes deliverd through https.
+</name>
+<features>
+proxy
+</features>
+<command>
+--insecure --raw https://%HOSTIP:%HTTPSPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding-https/data/test4 b/tests/cts/chunked-transfer-encoding-https/data/test4
new file mode 100644 (file)
index 0000000..5505caa
--- /dev/null
@@ -0,0 +1,72 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+123\r
+This chunk is too small
+0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+123\r
+This chunk is too small
+0\r
+\r
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Chunked transfer encoding - Single chunk that is too small delivered through https.
+</name>
+<features>
+proxy
+</features>
+<command>
+--insecure --raw https://%HOSTIP:%HTTPSPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+18
+</errorcode>
+</verify>
+
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding-https/data/test5 b/tests/cts/chunked-transfer-encoding-https/data/test5
new file mode 100644 (file)
index 0000000..a881897
--- /dev/null
@@ -0,0 +1,84 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+3\r
+AA
+\r
+4\r
+BBB
+\r
+123\r
+This chunk is too small
+0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+3\r
+AA
+\r
+4\r
+BBB
+\r
+123\r
+This chunk is too small
+0\r
+\r
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Chunked transfer encoding - Multiple small chunks, last one too small.
+</name>
+<features>
+proxy
+</features>
+<command>
+--insecure --raw https://%HOSTIP:%HTTPSPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+18
+</errorcode>
+</verify>
+
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding-https/data/test6 b/tests/cts/chunked-transfer-encoding-https/data/test6
new file mode 100644 (file)
index 0000000..c5a29ae
--- /dev/null
@@ -0,0 +1,88 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+3\r
+AA
+\r
+4\r
+BBB
+\r
+123\r
+This chunk is too small
+4\r
+DDD
+0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+3\r
+AA
+\r
+4\r
+BBB
+\r
+123\r
+This chunk is too small
+4\r
+DDD
+0\r
+\r
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Chunked transfer encoding - Multiple small chunks, chunk in the middle too small.
+</name>
+<features>
+proxy
+</features>
+<command>
+--insecure --raw https://%HOSTIP:%HTTPSPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+18
+</errorcode>
+</verify>
+
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding-https/data/test7 b/tests/cts/chunked-transfer-encoding-https/data/test7
new file mode 100644 (file)
index 0000000..2a2dfb3
--- /dev/null
@@ -0,0 +1,88 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+100\r
+%repeat[255 x A]%
+\r
+1000\r
+%repeat[4095 x B]%
+\r
+10000\r
+%repeat[65535 x C]%
+123\r
+This chunk is too small
+0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+100\r
+%repeat[255 x A]%
+\r
+1000\r
+%repeat[4095 x B]%
+\r
+10000\r
+%repeat[65535 x C]%
+123\r
+This chunk is too small
+0\r
+\r
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Chunked transfer encoding - Multiple chunks, some of them large, last chunk too small.
+</name>
+<features>
+proxy
+</features>
+<command>
+--insecure --raw https://%HOSTIP:%HTTPSPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+56
+</errorcode>
+</verify>
+
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding-https/data/test8 b/tests/cts/chunked-transfer-encoding-https/data/test8
new file mode 100644 (file)
index 0000000..61df2c5
--- /dev/null
@@ -0,0 +1,71 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+100\r
+%repeat[255 x A]%
+\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+100\r
+%repeat[255 x A]%
+\r
+\r
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Chunked transfer encoding - One data chunk, last chunk missing. Delivered through https.
+</name>
+<features>
+proxy
+</features>
+<command>
+--insecure --raw https://%HOSTIP:%HTTPSPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+56
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding-https/data/test9 b/tests/cts/chunked-transfer-encoding-https/data/test9
new file mode 100644 (file)
index 0000000..88f64fb
--- /dev/null
@@ -0,0 +1,81 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+100\r
+%repeat[255 x A]%
+\r
+100\r
+%repeat[255 x B]%
+\r
+100\r
+%repeat[255 x C]%
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+100\r
+%repeat[255 x A]%
+\r
+100\r
+%repeat[255 x B]%
+\r
+100\r
+%repeat[255 x C]%
+\r
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Chunked transfer encoding - Multiple chunks, last chunk missing.
+</name>
+<features>
+proxy
+</features>
+<command>
+--insecure --raw https://%HOSTIP:%HTTPSPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+18
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding-https/privoxy.conf b/tests/cts/chunked-transfer-encoding-https/privoxy.conf
new file mode 100644 (file)
index 0000000..47abfe6
--- /dev/null
@@ -0,0 +1,27 @@
+listen-address 127.0.0.1:9119
+
+ca-directory          ../ca-directory
+ca-cert-file          privoxy-test-cacert.crt
+ca-key-file           privoxy-test-cakey.pem
+ca-password           blafasel
+# We don't check certificate anyway
+trusted-cas-file      privoxy-test-cacert.crt
+
+certificate-directory ../certs
+
+debug     1 # Log the destination for each request Privoxy let through. See also debug 1024.
+debug     2 # show each connection status
+debug     4 # show tagging-related messages
+debug     8 # show header parsing
+debug    32 # debug force feature
+debug    64 # debug regular expression filters
+debug   128 # debug redirects
+debug   256 # debug GIF de-animation
+debug   512 # Common Log Format
+debug  1024 # Log the destination for requests Privoxy didn't let through, and the reason why.
+debug  4096 # Startup banner and warnings.
+debug  8192 # Non-fatal errors
+
+filterfile ../../../default.filter
+actionsfile ./chunked-transfer-encoding.action
+
diff --git a/tests/cts/chunked-transfer-encoding/chunked-transfer-encoding.action b/tests/cts/chunked-transfer-encoding/chunked-transfer-encoding.action
new file mode 100644 (file)
index 0000000..749a627
--- /dev/null
@@ -0,0 +1,5 @@
+{+filter{img-reorder}}
+/chunked-transfer-encoding/
+
+{-filter}
+/no-filter/
diff --git a/tests/cts/chunked-transfer-encoding/data/test1 b/tests/cts/chunked-transfer-encoding/data/test1
new file mode 100644 (file)
index 0000000..8256c35
--- /dev/null
@@ -0,0 +1,64 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+6\r
+AAAAA
+\r
+0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 6\r
+\r
+AAAAA
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - One chunk
+</name>
+<features>
+proxy
+</features>
+<command>
+--raw http://%HOSTIP:%HTTPPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test10 b/tests/cts/chunked-transfer-encoding/data/test10
new file mode 100644 (file)
index 0000000..1311e01
--- /dev/null
@@ -0,0 +1,59 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+100\r
+%repeat[255 x A]%
+\r
+100\r
+%repeat[255 x B]%
+\r
+100\r
+%repeat[255 x C]%
+\r
+Bogus data.\r
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Multiple chunks, bogus data instead of last chunk.
+</name>
+<features>
+proxy
+</features>
+<command>
+--raw http://%HOSTIP:%HTTPPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+18
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test11 b/tests/cts/chunked-transfer-encoding/data/test11
new file mode 100644 (file)
index 0000000..14301dc
--- /dev/null
@@ -0,0 +1,60 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+100\r
+%repeat[255 x A]%
+\r
+100\r
+%repeat[255 x B]%
+\r
+100\r
+%repeat[255 x C]%
+\r
+100\r
+%repeat[1000 x D]%
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Multiple chunks, chunk at the end too big.
+</name>
+<features>
+proxy
+</features>
+<command>
+--raw http://%HOSTIP:%HTTPPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+56
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test12 b/tests/cts/chunked-transfer-encoding/data/test12
new file mode 100644 (file)
index 0000000..cbc6d97
--- /dev/null
@@ -0,0 +1,79 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+100\r
+%repeat[255 x A]%
+\r
+100\r
+%repeat[255 x B]%
+\r
+100\r
+%repeat[255 x C]%
+\r
+100\r
+%repeat[255 x 0]%
+\r
+0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 1024\r
+\r
+%repeat[255 x A]%
+%repeat[255 x B]%
+%repeat[255 x C]%
+%repeat[255 x 0]%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Multiple chunks, chunk at the end contains zeros but is valid
+</name>
+<features>
+proxy
+</features>
+<command>
+--raw http://%HOSTIP:%HTTPPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test13 b/tests/cts/chunked-transfer-encoding/data/test13
new file mode 100644 (file)
index 0000000..f998d63
--- /dev/null
@@ -0,0 +1,79 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+100\r
+%repeat[255 x A]%
+\r
+100\r
+%repeat[255 x B]%
+\r
+100\r
+%repeat[255 x C]%
+\r
+100\r
+%repeat[255 x %01]%
+\r
+0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 1024\r
+\r
+%repeat[255 x A]%
+%repeat[255 x B]%
+%repeat[255 x C]%
+%repeat[255 x %01]%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Multiple chunks, chunk at the end contains binary ones and is valid
+</name>
+<features>
+proxy
+</features>
+<command>
+--raw http://%HOSTIP:%HTTPPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test14 b/tests/cts/chunked-transfer-encoding/data/test14
new file mode 100644 (file)
index 0000000..842ba8b
--- /dev/null
@@ -0,0 +1,79 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+100\r
+%repeat[255 x A]%
+\r
+100\r
+%repeat[255 x B]%
+\r
+100\r
+%repeat[255 x C]%
+\r
+100\r
+%repeat[255 x %hex[%00]hex%]%
+\r
+0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 1024\r
+\r
+%repeat[255 x A]%
+%repeat[255 x B]%
+%repeat[255 x C]%
+%repeat[255 x %hex[%00]hex%]%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Multiple chunks, chunk at the end contains binary zeroes and is valid. XXX: Requires runtests.pl patch.
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test15 b/tests/cts/chunked-transfer-encoding/data/test15
new file mode 100644 (file)
index 0000000..995e061
--- /dev/null
@@ -0,0 +1,79 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+100\r
+%repeat[255 x A]%
+\r
+100\r
+%repeat[255 x B]%
+\r
+100\r
+%repeat[255 x C]%
+\r
+100\r
+%repeat[255 x %hex[%00]hex%]%
+\r
+0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 1024\r
+\r
+%repeat[255 x A]%
+%repeat[255 x B]%
+%repeat[255 x C]%
+%repeat[255 x %hex[%00]hex%]%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Multiple chunks, chunk at the end contains binary zeroes and is valid. XXX: Requires runtests.pl patch to work.
+</name>
+<features>
+proxy
+</features>
+<command>
+--raw http://%HOSTIP:%HTTPPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test16 b/tests/cts/chunked-transfer-encoding/data/test16
new file mode 100644 (file)
index 0000000..bd9520e
--- /dev/null
@@ -0,0 +1,67 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+2\r
+%hex[%00]hex%
+\r
+0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 2\r
+\r
+%hex[%00]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Single chunk with binary zeroes that is valid. XXX: Requires patched runtests.pl
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test17 b/tests/cts/chunked-transfer-encoding/data/test17
new file mode 100644 (file)
index 0000000..aae49cf
--- /dev/null
@@ -0,0 +1,60 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+%hex[%FF%00%01]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+%hex[%FF%00%01]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Binary data test - Requires runtests.pl patch. XXX: Not actually a chunked test.
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test18 b/tests/cts/chunked-transfer-encoding/data/test18
new file mode 100644 (file)
index 0000000..2d7a093
--- /dev/null
@@ -0,0 +1,60 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+%hex[%00]hex%Blafasel
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+%hex[%00]hex%Blafasel
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Binary zero test. XXX: Not actually a chunked-transfer-encoding test.
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test19 b/tests/cts/chunked-transfer-encoding/data/test19
new file mode 100644 (file)
index 0000000..6b68be7
--- /dev/null
@@ -0,0 +1,79 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+100\r
+%repeat[255 x %00]%
+\r
+100\r
+%repeat[255 x %00]%
+\r
+100\r
+%repeat[255 x %00]%
+\r
+100\r
+%repeat[255 x %00]%
+\r
+0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 1024\r
+\r
+%repeat[255 x %00]%
+%repeat[255 x %00]%
+%repeat[255 x %00]%
+%repeat[255 x %00]%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Multiple valid chunks with binary zeros. Requires runtests.pl patch.
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test2 b/tests/cts/chunked-transfer-encoding/data/test2
new file mode 100644 (file)
index 0000000..0fd69b4
--- /dev/null
@@ -0,0 +1,76 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+6\r
+AAAAA
+\r
+100\r
+%repeat[255 x B]%
+\r
+1000\r
+%repeat[4095 x C]%
+\r
+10000\r
+%repeat[65535 x D]%
+\r
+0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: close
+Content-Type: text/html
+X-Control: swsclose
+Content-Length: 69894
+
+AAAAA
+%repeat[255 x B]%
+%repeat[4095 x C]%
+%repeat[65535 x D]%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Multiple chunks
+</name>
+<features>
+proxy
+</features>
+<command>
+--raw http://%HOSTIP:%HTTPPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test20 b/tests/cts/chunked-transfer-encoding/data/test20
new file mode 100644 (file)
index 0000000..6a3dd71
--- /dev/null
@@ -0,0 +1,61 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+100\r
+%repeat[255 x A]%
+\r
+100\r
+%repeat[255 x B]%
+\r
+100 blafasel %hex[%00]hex%\r
+%repeat[255 x C]%
+\r
+0\r
+\r
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Multiple chunks, invalid binary zero in chunk extension. XXX: Privoxy could simply ignore this.
+</name>
+<features>
+proxy
+</features>
+<command>
+--raw http://%HOSTIP:%HTTPPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+# XXX: Why does curl not consider this an error?
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test21 b/tests/cts/chunked-transfer-encoding/data/test21
new file mode 100644 (file)
index 0000000..7893ab3
--- /dev/null
@@ -0,0 +1,75 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+12345\r
+%repeat[74564 x A]%
+\r
+67891\r
+%repeat[424080 x B]%
+\r
+31337\r
+%repeat[201526 x C]%
+\r
+0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 700173\r
+\r
+%repeat[74564 x A]%
+%repeat[424080 x B]%
+%repeat[201526 x C]%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Multiple largish valid chunks.
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test22 b/tests/cts/chunked-transfer-encoding/data/test22
new file mode 100644 (file)
index 0000000..d6aa047
--- /dev/null
@@ -0,0 +1,63 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 0\r
+\r
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Only last chunk, no actual data.
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test23 b/tests/cts/chunked-transfer-encoding/data/test23
new file mode 100644 (file)
index 0000000..50178c8
--- /dev/null
@@ -0,0 +1,70 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+# This reply specifies a Content-Length header even though the response is chunk-encoded.
+# Per RFC 2616 4.4 3 the Content-Length header must be ignored.
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+Content-Length: 12345\r
+X-Control: swsclose\r
+\r
+6\r
+AAAAA
+\r
+0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Length: 6\r
+X-Control: swsclose\r
+\r
+AAAAA
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding with Content-Lenght header set
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test24 b/tests/cts/chunked-transfer-encoding/data/test24
new file mode 100644 (file)
index 0000000..9d9d8b9
--- /dev/null
@@ -0,0 +1,80 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: keep-alive\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+\r
+6\r
+AAAAA
+\r
+6\r
+BBBBB
+\r
+0\r
+\r
+</data>
+<servercmd>
+writedelay: 20
+</servercmd>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: keep-alive\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+\r
+6\r
+AAAAA
+\r
+6\r
+BBBBB
+\r
+0\r
+\r
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Multiple small chunks send delayed. Connection kept alive.
+</name>
+<features>
+proxy
+</features>
+<command>
+ --max-time 10 --raw http://%HOSTIP:%HTTPPORT/no-filter/%TESTNUMBER --next --max-time 10 --raw http://%HOSTIP:%HTTPPORT/no-filter/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /no-filter/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+GET /no-filter/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test25 b/tests/cts/chunked-transfer-encoding/data/test25
new file mode 100644 (file)
index 0000000..ac0dc05
--- /dev/null
@@ -0,0 +1,116 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: keep-alive\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+\r
+12345\r
+%repeat[74564 x A]%
+\r
+67891\r
+%repeat[424080 x B]%
+\r
+31337\r
+%repeat[201526 x C]%
+\r
+31337\r
+%repeat[201526 x D]%
+\r
+31337\r
+%repeat[201526 x E]%
+\r
+0\r
+\r
+</data>
+<data1>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+X-Connection: swsclose\r
+Content-Type: text/html\r
+\r
+Here's your unchunked data.
+</data1>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: keep-alive\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+\r
+12345\r
+%repeat[74564 x A]%
+\r
+67891\r
+%repeat[424080 x B]%
+\r
+31337\r
+%repeat[201526 x C]%
+\r
+31337\r
+%repeat[201526 x D]%
+\r
+31337\r
+%repeat[201526 x E]%
+\r
+0\r
+\r
+</data>
+<data1>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+X-Connection: swsclose\r
+Content-Type: text/html\r
+\r
+Here's your unchunked data.
+</data1>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Multiple largish chunks on connection that is kept alive. Content too large to buffer. Filtering disabled.
+</name>
+<features>
+proxy
+</features>
+<command>
+--max-time 20 --raw http://%HOSTIP:%HTTPPORT/no-filter/chunked-content/%TESTNUMBER0000 --raw http://%HOSTIP:%HTTPPORT/no-filter/unchunked-content/%TESTNUMBER0001
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /no-filter/chunked-content/%TESTNUMBER0000 HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+GET /no-filter/unchunked-content/%TESTNUMBER0001 HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test26 b/tests/cts/chunked-transfer-encoding/data/test26
new file mode 100644 (file)
index 0000000..c5f2c46
--- /dev/null
@@ -0,0 +1,116 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+# XXX: Test requires "writesize" support that hasn't been upstreamed yet
+skip
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: keep-alive\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+\r
+12345\r
+%repeat[74564 x A]%
+\r
+67891\r
+%repeat[424080 x B]%
+\r
+31337\r
+%repeat[201526 x C]%
+\r
+31337\r
+%repeat[201526 x D]%
+\r
+0\r
+\r
+</data>
+<data1>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+X-Connection: swsclose\r
+Content-Type: text/html\r
+\r
+Here's your unchunked data.
+</data1>
+<servercmd>
+writesize: 10000
+writedelay: 5
+</servercmd>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: keep-alive\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+\r
+12345\r
+%repeat[74564 x A]%
+\r
+67891\r
+%repeat[424080 x B]%
+\r
+31337\r
+%repeat[201526 x C]%
+\r
+31337\r
+%repeat[201526 x D]%
+\r
+0\r
+\r
+</data>
+<data1>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+X-Connection: swsclose\r
+Content-Type: text/html\r
+\r
+Here's your unchunked data.
+</data1>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Multiple largish chunks on a connection that is kept alive. Filtering disabled.
+</name>
+<features>
+proxy
+</features>
+<command>
+--raw http://%HOSTIP:%HTTPPORT/no-filter/chunked-content/%TESTNUMBER0000 --max-time 2 --raw http://%HOSTIP:%HTTPPORT/no-filter/unchunked-content/%TESTNUMBER0001
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /no-filter/chunked-content/%TESTNUMBER0000 HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+GET /no-filter/unchunked-content/%TESTNUMBER0001 HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test27 b/tests/cts/chunked-transfer-encoding/data/test27
new file mode 100644 (file)
index 0000000..22ec1f4
--- /dev/null
@@ -0,0 +1,95 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: keep-alive\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+\r
+10\r
+%repeat[9 x A]%
+\r
+0\r
+\r
+</data>
+<data1>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+X-Connection: swsclose\r
+Content-Type: text/html\r
+\r
+Here's your unchunked data.
+</data1>
+<servercmd>
+writesize: 10000
+</servercmd>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: keep-alive\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+\r
+10\r
+%repeat[9 x A]%
+\r
+0\r
+\r
+</data>
+<data1>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+X-Connection: swsclose\r
+Content-Type: text/html\r
+\r
+Here's your unchunked data.
+</data1>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Small chunks that are received together with the sever headers. Filtering disabled.
+</name>
+<features>
+proxy
+</features>
+<command>
+--raw http://%HOSTIP:%HTTPPORT/no-filter/chunked-content/%TESTNUMBER0000 --max-time 2 --raw http://%HOSTIP:%HTTPPORT/no-filter/unchunked-content/%TESTNUMBER0001
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /no-filter/chunked-content/%TESTNUMBER0000 HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+GET /no-filter/unchunked-content/%TESTNUMBER0001 HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test28 b/tests/cts/chunked-transfer-encoding/data/test28
new file mode 100644 (file)
index 0000000..ddc4ccb
--- /dev/null
@@ -0,0 +1,78 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+# XXX: Test requires "writesize" support that hasn't been upstreamed yet.
+skip
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: keep-alive\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+\r
+FB\r
+%repeat[50 x 0%0d%0a%0d%0a]%
+\r
+0\r
+\r
+</data>
+<data1>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+X-Connection: swsclose\r
+Content-Type: text/html\r
+\r
+Here's your unchunked data.
+</data1>
+# The write size is chosen so that Privoxy's first read
+# gets data that ends in 0\r\n\r\n but does not actually
+# contain the last chunk.
+<servercmd>
+writesize: 202
+writedelay: 100
+</servercmd>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Chunk that contains lots of potential "last-chunks" as data. Filtering disabled.
+</name>
+<features>
+proxy
+</features>
+# Set a custom User-Agent so the request size does
+# not depend on whether or not curl is a debug build.
+<command>
+--user-agent "Blafasel/1 beta" --raw http://%HOSTIP:%HTTPPORT/no-filter/chunked-content/%TESTNUMBER0000 --max-time 2 --raw http://%HOSTIP:%HTTPPORT/no-filter/unchunked-content/%TESTNUMBER0001
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /no-filter/chunked-content/%TESTNUMBER0000 HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: Blafasel/1 beta\r
+Accept: */*\r
+\r
+GET /no-filter/unchunked-content/%TESTNUMBER0001 HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: Blafasel/1 beta\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test29 b/tests/cts/chunked-transfer-encoding/data/test29
new file mode 100644 (file)
index 0000000..be06f4b
--- /dev/null
@@ -0,0 +1,81 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+# XXX: Test requires "writesize" support that hasn't been upstreamed yet.
+skip
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: keep-alive\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+\r
+FE\r
+%repeat[253 x A]%
+\r
+FB\r
+%repeat[50 x 0%0d%0a%0d%0a]%
+\r
+0\r
+\r
+</data>
+<data1>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+X-Connection: swsclose\r
+Content-Type: text/html\r
+\r
+Here's your unchunked data.
+</data1>
+# The write size is chosen so that Privoxy's second read
+# gets data that ends in 0\r\n\r\n but does not actually
+# contain the last chunk.
+<servercmd>
+writesize: 306
+writedelay: 100
+</servercmd>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Chunk that contains lots of potential "last-chunks" as data. Filtering disabled.
+</name>
+<features>
+proxy
+</features>
+# Set a custom User-Agent so the request size does
+# not depend on whether or not curl is a debug build.
+<command>
+--user-agent "Blafasel/1 beta" --raw http://%HOSTIP:%HTTPPORT/no-filter/chunked-content/%TESTNUMBER0000 --max-time 2 --raw http://%HOSTIP:%HTTPPORT/no-filter/unchunked-content/%TESTNUMBER0001
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /no-filter/chunked-content/%TESTNUMBER0000 HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: Blafasel/1 beta\r
+Accept: */*\r
+\r
+GET /no-filter/unchunked-content/%TESTNUMBER0001 HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: Blafasel/1 beta\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test3 b/tests/cts/chunked-transfer-encoding/data/test3
new file mode 100644 (file)
index 0000000..35445ea
--- /dev/null
@@ -0,0 +1,76 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+6 Oh noes\r
+AAAAA
+\r
+100 there is\r
+%repeat[255 x B]%
+\r
+1000 bogus data\r
+%repeat[4095 x C]%
+\r
+10000 here \r
+%repeat[65535 x D]%
+\r
+0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 69894\r
+\r
+AAAAA
+%repeat[255 x B]%
+%repeat[4095 x C]%
+%repeat[65535 x D]%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Multiple chunks with garbage after chunk-sizes
+</name>
+<features>
+proxy
+</features>
+<command>
+--raw http://%HOSTIP:%HTTPPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test30 b/tests/cts/chunked-transfer-encoding/data/test30
new file mode 100644 (file)
index 0000000..c69888c
--- /dev/null
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+# XXX: Test requires "writesize" support that hasn't been upstreamed yet.
+skip
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+\r
+6\r
+AAAAA
+\r
+A\r
+%repeat[9 x B]%
+\r
+FF\r
+%repeat[254 x C]%
+\r
+0\r
+\r
+</data>
+<servercmd>
+writesize: 20
+writedelay: 50
+</servercmd>
+</reply>
+
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Multiple small chunks
+</name>
+<features>
+proxy
+</features>
+<command>
+--raw http://%HOSTIP:%HTTPPORT/no-filter/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /no-filter/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test31 b/tests/cts/chunked-transfer-encoding/data/test31
new file mode 100644 (file)
index 0000000..7ae9176
--- /dev/null
@@ -0,0 +1,57 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+# XXX: Test requires "writesize" support that hasn't been upstreamed yet.
+skip
+</keywords>
+</info>
+
+<reply>
+# Note that the %hex sequence is invalid and will not be transformed.
+# At first it was an accident but as it triggered
+# a bug in test build the test has been kept as is.
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+\r
+%hex[1%0d%0a%0a%0d%0a0%0d%0a%0d%0a]
+</data>
+<servercmd>
+writesize: 1000
+</servercmd>
+</reply>
+
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Chunk with invalid chunk size received with the server headers
+</name>
+<features>
+proxy
+</features>
+<command>
+--raw http://%HOSTIP:%HTTPPORT/no-filter/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /no-filter/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+56
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test32 b/tests/cts/chunked-transfer-encoding/data/test32
new file mode 100644 (file)
index 0000000..b638914
--- /dev/null
@@ -0,0 +1,51 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+# XXX: Test requires "writesize" support that hasn't been upstreamed yet.
+skip
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+\r
+%hex[1%0d%0a%0a%0d%0a0%0d%0a%0d%0a]hex%
+</data>
+<servercmd>
+writesize: 1000
+</servercmd>
+</reply>
+
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Multiple small chunks received with the server headers.
+</name>
+<features>
+proxy
+</features>
+<command>
+--raw http://%HOSTIP:%HTTPPORT/no-filter/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /no-filter/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test33 b/tests/cts/chunked-transfer-encoding/data/test33
new file mode 100644 (file)
index 0000000..cd65cad
--- /dev/null
@@ -0,0 +1,68 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+# XXX: Test requires "writesize" support that hasn't been upstreamed yet.
+skip
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+\r
+2\r
+A
+\r
+3\r
+BB
+\r
+4\r
+CCC
+\r
+5\r
+DDDD
+\r
+FF\r
+%repeat[254 x F]%
+\r
+0\r
+\r
+</data>
+<servercmd>
+writesize: 200
+writedelay: 20
+</servercmd>
+</reply>
+
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Multiple small chunks received with the server headers, other chunks received separately.
+</name>
+<features>
+proxy
+</features>
+<command>
+--raw http://%HOSTIP:%HTTPPORT/no-filter/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /no-filter/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test34 b/tests/cts/chunked-transfer-encoding/data/test34
new file mode 100644 (file)
index 0000000..ee27dc0
--- /dev/null
@@ -0,0 +1,2253 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+# XXX: Test requires "writesize" support that hasn't been upstreamed yet.
+skip
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Tue, 30 Mar 2021 08:22:13 GMT\r
+Server: Apache\r
+Expires: Fri, 01 Jan 1980 00:00:00 GMT\r
+Pragma: no-cache\r
+Cache-Control: no-cache, max-age=0, must-revalidate\r
+X-Content-Type-Options: nosniff\r
+X-Frame-Options: sameorigin\r
+X-Xss-Protection: 1\r
+Referrer-Policy: no-referrer\r
+Strict-Transport-Security: max-age=15768000; preload\r
+Transfer-Encoding: chunked\r
+Content-Type: application/x-git-upload-pack-advertisement\r
+\r
+22\r
+001e# service=git-upload-pack
+0000\r
+fa\r
+00fa769d54c5d7933ccb4c8638e71ce4b928298ac66a HEAD%hex[%00]hex%multi_ack thin-pack side-band side-band-64k ofs-delta shallow deepen-since deepen-not deepen-relative no-progress include-tag multi_ack_detailed no-done symref=HEAD:refs/heads/master agent=git/2.20.1
+\r
+110\r
+00448608e6823e12856f0c3ca432587c950e0ddb3044 refs/heads/maint-0.1.2
+0044b1859cab2568fa27360a35f2cd906a7dfa4a38c8 refs/heads/maint-0.2.0
+00444180624a7d5a3e528be2cf2fe7f9f673b3964a23 refs/heads/maint-0.2.1
+00443b0265198fc8a55279f2a8501104d2c54900c9d0 refs/heads/maint-0.2.2
+\r
+44\r
+0044e5907e94c225cabec1f5cf94870c424fc1767c7e refs/heads/maint-0.2.3
+\r
+15a\r
+00446199e27a2b4ce4d56a1de9cf35ff09f79c9b6624 refs/heads/maint-0.2.4
+00441fa396b0a49448103ad16cb411163e6f5d741cc0 refs/heads/maint-0.2.5
+00446862eada65a6f41304b32c3d4fca3da9c240d5bd refs/heads/maint-0.2.6
+0044e6376a8004072fde832da77aa6369075dcdcbe8b refs/heads/maint-0.2.7
+004aa48ae2aa67b31cc97942ac2c7fd6f29beba59e3b refs/heads/maint-0.2.7-redux
+\r
+cc\r
+00447d845976e3897fac8e78a4a26688ac57b660151b refs/heads/maint-0.2.8
+004437b04aeed7d6c7acb8b7edf2bcd6ee08f9c3a54c refs/heads/maint-0.2.9
+0044b39c50cde8b1d7e3e27d5a6fc2e58ff208982637 refs/heads/maint-0.3.0
+\r
+44\r
+00442968c716d7689eafcf32a1f5327af7b1ad1582ce refs/heads/maint-0.3.1
+\r
+44\r
+00445b04392c1553e2a3e278a48f8d0e071181c0444f refs/heads/maint-0.3.2
+\r
+44\r
+00440c9cd7c487ac75d9505f46e5ff42087d383eb1b4 refs/heads/maint-0.3.3
+\r
+44\r
+0044a521c427883697fcfa027ffd72bb38f3aee5aceb refs/heads/maint-0.3.4
+\r
+44\r
+00443271c0bde782769ba30685ca8907240328f771c9 refs/heads/maint-0.3.5
+\r
+154\r
+0044f3fa22bf1b52dfce65a37e6a84bac8635916e8c2 refs/heads/maint-0.4.0
+0044768ffb8f43575baac0970659b01e0a484d6bd6de refs/heads/maint-0.4.1
+004445d983049382e09d14d5047f9eef941d089e9fb7 refs/heads/maint-0.4.2
+00448a17999da3626a5f9e8922277151624cd0526fba refs/heads/maint-0.4.3
+00449ca2394d6b51242bb5cf380757be5869d2a44c3c refs/heads/maint-0.4.4
+\r
+c9\r
+0044c359c3056b2dbf17987a8955af30884ee438108e refs/heads/maint-0.4.5
+003f769d54c5d7933ccb4c8638e71ce4b928298ac66a refs/heads/master
+00467da1ae7adf150271a947997a1340f62b990c974d refs/heads/release-0.2.1
+\r
+8c\r
+0046bec76476efb715498b86282d4969c096df336140 refs/heads/release-0.2.2
+004643836f6f0ab7c25b0c8c9fab366ec664ebd0b0ee refs/heads/release-0.2.3
+\r
+118\r
+0046af082895ec3ca700a329d22c46ec454a65b31703 refs/heads/release-0.2.4
+0046279fa65d34bbb41d1428eb62f6172b218598644e refs/heads/release-0.2.5
+00463ae8b32cc97431ff29f1a0dab2b30c7f35038ac9 refs/heads/release-0.2.6
+0046e83affb56fa001d1c27f16e30e6c23c88ff165f5 refs/heads/release-0.2.7
+\r
+4c\r
+004cb05bb04a829250d795e4e81c9228dff57cbad7a5 refs/heads/release-0.2.7-redux
+\r
+8c\r
+004689f40ba97a752f125ef7dbb057d64dd5e06a95db refs/heads/release-0.2.8
+004638cc3a45b655a07f8834ddcd1514f04b09bd80a0 refs/heads/release-0.2.9
+\r
+46\r
+0046d07e069c97ac5f9e0c9a593b7ec84c540b310f0f refs/heads/release-0.3.0
+\r
+46\r
+004601baad0a63780d42e01629777058c3b7f240a9bd refs/heads/release-0.3.1
+\r
+46\r
+0046bf2ffd39781664b6b29a57a1dd1d110368f120ce refs/heads/release-0.3.2
+\r
+8c\r
+00460e74894c5db305a75914bea769d5b1db00d8f792 refs/heads/release-0.3.3
+0046e2dde342b240039c9d4a254a2313fa9ab53d49d7 refs/heads/release-0.3.4
+\r
+46\r
+00461693b6151e1369ce0938761cac95e7a0a524f5f3 refs/heads/release-0.3.5
+\r
+46\r
+0046ed2cbbf71680fd2be67eb7b74c44572e58895d72 refs/heads/release-0.4.0
+\r
+46\r
+0046d97fd7f0762603702179bf2742e0fe5fc66bedbf refs/heads/release-0.4.1
+\r
+46\r
+00465b345c693e73ad636a3dce9ca1e8622e1df8ed26 refs/heads/release-0.4.2
+\r
+46\r
+00461c5dd021a7666806284b851ecb1879704df8020e refs/heads/release-0.4.3
+\r
+46\r
+004644df63e591feec5d5ae5c4a838664997bc64f489 refs/heads/release-0.4.4
+\r
+46\r
+0046c40b729c85ff45501523cbcd37f603aceeea4774 refs/heads/release-0.4.5
+\r
+b5\r
+0059e9313d995ba058b8a1edacbd6b3504f3551d0c76 refs/tags/debian-version-0.0.1+0.0.2pre19-1
+005c9c8876be146a6f8566891fa84e05e1b60238508a refs/tags/debian-version-0.0.1+0.0.2pre19-1^{}
+\r
+b5\r
+0059ff70bb7b40bc104aee55cefa2e298a8e62b2d91e refs/tags/debian-version-0.0.1+0.0.2pre20-1
+005c4e7a2a01741d4ffb4bbe3385e20282a738331aef refs/tags/debian-version-0.0.1+0.0.2pre20-1^{}
+\r
+b5\r
+005905963d37bcbab56bc71448c03b4a347f90676a33 refs/tags/debian-version-0.0.1+0.0.2pre20-2
+005ccb34be367fd9722885d02fcaf65338a270478c08 refs/tags/debian-version-0.0.1+0.0.2pre20-2^{}
+\r
+59\r
+005938270f20bc917516a9ee69be785194a75928b4c6 refs/tags/debian-version-0.0.1+0.0.2pre21-1
+\r
+5c\r
+005ca1b6ce0580ab1330ffd0bdc6ec2f32eabac01057 refs/tags/debian-version-0.0.1+0.0.2pre21-1^{}
+\r
+10e\r
+0059e6c1eb4b697896d21ffb9428986b161d877cfff4 refs/tags/debian-version-0.0.1+0.0.2pre22-1
+005c2849ff13e286b773a483849ad374aaa63d0e5bca refs/tags/debian-version-0.0.1+0.0.2pre22-1^{}
+0059e34683c4b24bf9dec299764d0ed7de9e7c68be57 refs/tags/debian-version-0.0.1+0.0.2pre23-1
+\r
+5c\r
+005c247fe31af2f88ebb687ee08eeb8d7942b52ba853 refs/tags/debian-version-0.0.1+0.0.2pre23-1^{}
+\r
+16a\r
+0059dd3e677ca2d9b40b807d0db68b60a308736267f3 refs/tags/debian-version-0.0.1+0.0.2pre24-1
+005c3e452fed5446f3e744bf7ea321f6b24e01c97578 refs/tags/debian-version-0.0.1+0.0.2pre24-1^{}
+00590ac579c5780021c57e7e15fa59eaea8571093a96 refs/tags/debian-version-0.0.1+0.0.2pre25-1
+005ce0b1aaabe769b8f8c773d964d00936e1c20126d7 refs/tags/debian-version-0.0.1+0.0.2pre25-1^{}
+\r
+10e\r
+00591050e2af36656e480ce429a053ee1451c3fc6268 refs/tags/debian-version-0.0.1+0.0.2pre26-1
+005cea0c5db22892ab11a7a743713438121e295941a1 refs/tags/debian-version-0.0.1+0.0.2pre26-1^{}
+0059c10dbc774a2d017367383a33c1d7ecccb78e9554 refs/tags/debian-version-0.0.1+0.0.2pre27-1
+\r
+5c\r
+005c39835dd9f69c3244f7d2e371196752939f19c638 refs/tags/debian-version-0.0.1+0.0.2pre27-1^{}
+\r
+13e\r
+004e88c086d403ea690346855eca70c8d7a8389608c0 refs/tags/debian-version-0.0.2-1
+005151750ae09a162bd9de70e9163213d3a07788ea9d refs/tags/debian-version-0.0.2-1^{}
+004edc59d84c4cc17cf541fb62bcc96aca693b8507a0 refs/tags/debian-version-0.0.3-1
+0051c940e2644a8629711ba8d33703a40f70b0e76ee2 refs/tags/debian-version-0.0.3-1^{}
+\r
+f6\r
+004e88a02d21ed0463c733cdd1d843ac78fa536f449d refs/tags/debian-version-0.0.4-1
+0051d324e835207432cdfc9ede2d309051d97c57066d refs/tags/debian-version-0.0.4-1^{}
+005739da29283eece63134bc11191b11879dd57bd8b4 refs/tags/debian-version-0.0.5+0.0.6rc2-1
+\r
+5a\r
+005a2b1441e49faf75133fc2a4db900a3f0f01075b65 refs/tags/debian-version-0.0.5+0.0.6rc2-1^{}
+\r
+b1\r
+0057e8df6c4e8dcf298c28bf9eeb3525b0a0e2225510 refs/tags/debian-version-0.0.5+0.0.6rc3-1
+005a3c2659e763d7eed65bd898a868bd7614d4a0d7d9 refs/tags/debian-version-0.0.5+0.0.6rc3-1^{}
+\r
+b1\r
+00574d068d9761666be76d4298db4d22839e13700d2e refs/tags/debian-version-0.0.5+0.0.6rc4-1
+005a334fb4e8f64097417dc31c18cb6d7038ad37f5ce refs/tags/debian-version-0.0.5+0.0.6rc4-1^{}
+\r
+9f\r
+004e358b9a26f4b7cc65d6ea6938d1c5a3baa94fd86d refs/tags/debian-version-0.0.5-1
+0051b1e98321365bd3080f176d38d4e71b6114d6517d refs/tags/debian-version-0.0.5-1^{}
+\r
+142\r
+004e2ff0ef7e1cda1aa77c4fb867f5e0e3a97602e85c refs/tags/debian-version-0.0.6-1
+00516b112c9f2d30b3bbe5b0dd82ff270b885395b215 refs/tags/debian-version-0.0.6-1^{}
+0050e7c66ffc8f80bea640b63587fc9c41328b3354c2 refs/tags/debian-version-0.0.6.1-1
+0053f77be323b12cc765857f5d2a9c324d0f9caf9159 refs/tags/debian-version-0.0.6.1-1^{}
+\r
+a3\r
+00509b1a83af7f5d01413da8415bc68697951149e8ec refs/tags/debian-version-0.0.6.2-1
+0053c2182701de1e34c6109ccbdd79d65df3baa9bb28 refs/tags/debian-version-0.0.6.2-1^{}
+\r
+b1\r
+0057ae3b184def9cbffec7d31b4698e4501cf4209dbd refs/tags/debian-version-0.0.7+0.0.8rc1-1
+005ae5c4c0fbbe4a44cf57345cc35a2b2343ee66a43e refs/tags/debian-version-0.0.7+0.0.8rc1-1^{}
+\r
+9f\r
+004e69576f144f75ee0a8071104a61f5bf0ec44c5504 refs/tags/debian-version-0.0.7-1
+00518b455120b7001443f2c565a03b847ca78dcdf115 refs/tags/debian-version-0.0.7-1^{}
+\r
+a3\r
+005083f4787a0f384bd49bc2a0b039da3a2e656f4151 refs/tags/debian-version-0.0.7.1-1
+0053948a1ad4de18eeb45ed6757bb26a3f0c62dc16ed refs/tags/debian-version-0.0.7.1-1^{}
+\r
+b7\r
+005afea2abbdad4b2c6c8ac3c6b3ae24c77bc1d8a398 refs/tags/debian-version-0.0.7.2+0.0.8pre2-1
+005d6a022bdcdc7416bde405df1cab5cb399d1546227 refs/tags/debian-version-0.0.7.2+0.0.8pre2-1^{}
+\r
+b7\r
+005a9ffe417645e4cdf6c804ebd169acb31b1399e5f3 refs/tags/debian-version-0.0.7.2+0.0.8pre3-1
+005db154f100ff56478dfaf115215c9514c13d5c7638 refs/tags/debian-version-0.0.7.2+0.0.8pre3-1^{}
+\r
+b3\r
+0058bdafa7bc46fd89c1b56cbf87a0dcfeb7d098373c refs/tags/debian-version-0.0.8+0.0.9pre1-1
+005b929475e3b14fddf1efe2f5cbb539ddb9823c0fa2 refs/tags/debian-version-0.0.8+0.0.9pre1-1^{}
+\r
+10b\r
+005895eb0c670492970d415f7fc538cb6a79817e8c20 refs/tags/debian-version-0.0.8+0.0.9pre2-1
+005bfcee963b35c061b4eeb5a7339a1b4b9530ac8089 refs/tags/debian-version-0.0.8+0.0.9pre2-1^{}
+0058a030ca43d9489c033a64c9ebf72f3383b9f5dba4 refs/tags/debian-version-0.0.8+0.0.9pre3-1
+\r
+5b\r
+005b96816bab06f5c17d618b59457468d02fffb28091 refs/tags/debian-version-0.0.8+0.0.9pre3-1^{}
+\r
+b3\r
+005841e86877ae92dbeb50c8e1ab39090b2e6297785c refs/tags/debian-version-0.0.8+0.0.9pre4-1
+005b029a0a4c33b9041366bf167dd0faf9d9e083b183 refs/tags/debian-version-0.0.8+0.0.9pre4-1^{}
+\r
+219\r
+0058e8bc68cf8a18192e231b7abe5476ded232921422 refs/tags/debian-version-0.0.8+0.0.9pre5-1
+005b40f463ec9f0a013ba3bbb43a2904ed70eaba1539 refs/tags/debian-version-0.0.8+0.0.9pre5-1^{}
+0058897348a3bb5986ffa2348f908b65f6ae2b66375a refs/tags/debian-version-0.0.8+0.0.9pre5-2
+005bad8e779db22078ca6b18bd6194bbceee538cb632 refs/tags/debian-version-0.0.8+0.0.9pre5-2^{}
+00587ca7dbd1a6a945068ad3c89b187f439e1c4e56b7 refs/tags/debian-version-0.0.8+0.0.9pre6-1
+005b82185d82839dd7db97b01d6dbd59aa897d757086 refs/tags/debian-version-0.0.8+0.0.9pre6-1^{}
+\r
+1b9\r
+00574abc4016c1be5a7fc791ee43f53a4d7c45f41a2c refs/tags/debian-version-0.0.8+0.0.9rc1-1
+005a0065066dbe8bc79a15f83eb8e3b4f7153001570f refs/tags/debian-version-0.0.8+0.0.9rc1-1^{}
+00571410ed9aac7e0a0f35b540b82bb93a56f486a0d7 refs/tags/debian-version-0.0.8+0.0.9rc2-1
+005acc0fbc0b1341a4de6232f4234ad3b9b9a2afa4cc refs/tags/debian-version-0.0.8+0.0.9rc2-1^{}
+00574e4568bcc20448cc82f32710170339d28d70a921 refs/tags/debian-version-0.0.8+0.0.9rc3-1
+\r
+5a\r
+005af910dc73d3a67ef559de0febb027a2df73eeaca4 refs/tags/debian-version-0.0.8+0.0.9rc3-1^{}
+\r
+b1\r
+0057f05828ae8c3bd94aa9346f2887675e6cdc21dae0 refs/tags/debian-version-0.0.8+0.0.9rc5-1
+005ad10679e2adc79a025fe1c95084bfd31afa159032 refs/tags/debian-version-0.0.8+0.0.9rc5-1^{}
+\r
+b1\r
+00571d4821366fd412bf3d36c1e06807bf8f1cbb8225 refs/tags/debian-version-0.0.8+0.0.9rc6-1
+005a82ed4acd3aa49661b56c4c18d14496df9d8066c1 refs/tags/debian-version-0.0.8+0.0.9rc6-1^{}
+\r
+b1\r
+005712cb8777dee7404ffcb1b66727028db5b027b7bc refs/tags/debian-version-0.0.8+0.0.9rc7-1
+005a90e91a4a4252f52f014673dbbb1b8794285a97e5 refs/tags/debian-version-0.0.8+0.0.9rc7-1^{}
+\r
+9f\r
+004ea2b5d76ebb7a54498c562a0fc372d0ad17d63d69 refs/tags/debian-version-0.0.8-1
+0051dccc4b74158f121d0f25a1328ed3da85203710f5 refs/tags/debian-version-0.0.8-1^{}
+\r
+a3\r
+0050e0c71813f2c9e3301874fc8cc11bfd341a824e7b refs/tags/debian-version-0.0.9.1-1
+0053a3922d0bdcc06a22131d26a4258590338b8cea12 refs/tags/debian-version-0.0.9.1-1^{}
+\r
+a5\r
+0051a2981a73420ab2913d61578f26d865755d943105 refs/tags/debian-version-0.0.9.10-1
+0054ba8690373adffdcac1106bcd298e7deb00329186 refs/tags/debian-version-0.0.9.10-1^{}
+\r
+a3\r
+0050c6ede6de2b946db84a8a858afe7406c2bb5eeadc refs/tags/debian-version-0.0.9.2-1
+0053ba8690373adffdcac1106bcd298e7deb00329186 refs/tags/debian-version-0.0.9.2-1^{}
+\r
+a3\r
+00509781f6b256df4f560e0d9f2e56c88246fce29732 refs/tags/debian-version-0.0.9.3-1
+0053ba8690373adffdcac1106bcd298e7deb00329186 refs/tags/debian-version-0.0.9.3-1^{}
+\r
+50\r
+00507e0fcd4951fb693c38ad419de2a730cde516c6df refs/tags/debian-version-0.0.9.4-1
+\r
+53\r
+0053ba8690373adffdcac1106bcd298e7deb00329186 refs/tags/debian-version-0.0.9.4-1^{}
+\r
+50\r
+0050716cbe4162c13eae22bf0a5141a4b4c126925b23 refs/tags/debian-version-0.0.9.5-1
+\r
+53\r
+0053ba8690373adffdcac1106bcd298e7deb00329186 refs/tags/debian-version-0.0.9.5-1^{}
+\r
+a3\r
+0050481181f4d1ab56f7748711fb728a78a377195f67 refs/tags/debian-version-0.0.9.6-1
+0053ba8690373adffdcac1106bcd298e7deb00329186 refs/tags/debian-version-0.0.9.6-1^{}
+\r
+50\r
+0050795b3a47c7db5f7b6113cd637c5abfbd3f65f603 refs/tags/debian-version-0.0.9.7-1
+\r
+53\r
+0053ba8690373adffdcac1106bcd298e7deb00329186 refs/tags/debian-version-0.0.9.7-1^{}
+\r
+a3\r
+005054ff484e7255de06b73a492308758915e192f8f3 refs/tags/debian-version-0.0.9.8-1
+0053ba8690373adffdcac1106bcd298e7deb00329186 refs/tags/debian-version-0.0.9.8-1^{}
+\r
+a3\r
+00500f59f9f472b9b1155711f7712614394240ccabdf refs/tags/debian-version-0.0.9.9-1
+0053ba8690373adffdcac1106bcd298e7deb00329186 refs/tags/debian-version-0.0.9.9-1^{}
+\r
+64\r
+006436f591b1d6a0f30850e775b8c0357fbb6ad629b9 refs/tags/debian-version-0.1.0.1-rc-cvs-200503310807-1
+\r
+67\r
+0067561cd28f99184a506ce50da157e3c10edcf90889 refs/tags/debian-version-0.1.0.1-rc-cvs-200503310807-1^{}
+\r
+64\r
+0064d567c044afd75a020308509791aadebe0b572b83 refs/tags/debian-version-0.1.0.1-rc-cvs-200504010815-1
+\r
+67\r
+0067b491467912ad9a7485042fbd798d76ce30ac0ce6 refs/tags/debian-version-0.1.0.1-rc-cvs-200504010815-1^{}
+\r
+b1\r
+005707a07226e0a58088a0722722cb5573784fc9a542 refs/tags/debian-version-0.1.0.10-0-pre.1
+005ac8ad2fc0031a3705708a5f1cdf9518f391df4d80 refs/tags/debian-version-0.1.0.10-0-pre.1^{}
+\r
+b1\r
+0057d745412f1acf4b07fd95947551dc9ab0a5cbbf41 refs/tags/debian-version-0.1.0.11-0-pre.1
+005ac8ad2fc0031a3705708a5f1cdf9518f391df4d80 refs/tags/debian-version-0.1.0.11-0-pre.1^{}
+\r
+a5\r
+00515efe9f7863896cdca665f637497e876dd1a46f59 refs/tags/debian-version-0.1.0.11-1
+0054c8ad2fc0031a3705708a5f1cdf9518f391df4d80 refs/tags/debian-version-0.1.0.11-1^{}
+\r
+a5\r
+005192b5bcc76483247225ecb026519ac10f6acc0df0 refs/tags/debian-version-0.1.0.12-1
+0054c8ad2fc0031a3705708a5f1cdf9518f391df4d80 refs/tags/debian-version-0.1.0.12-1^{}
+\r
+51\r
+00511a18bfb9456d03f0e70ea459439e539eecca775f refs/tags/debian-version-0.1.0.13-1
+\r
+54\r
+0054c8ad2fc0031a3705708a5f1cdf9518f391df4d80 refs/tags/debian-version-0.1.0.13-1^{}
+\r
+f6\r
+0051e42cfc72de0ade4e98983c65eff1fff3d969f603 refs/tags/debian-version-0.1.0.14-1
+0054c8ad2fc0031a3705708a5f1cdf9518f391df4d80 refs/tags/debian-version-0.1.0.14-1^{}
+00515ab56a7b330959e72b3b6437c2a0d1fd760dd9a8 refs/tags/debian-version-0.1.0.14-2
+\r
+54\r
+0054c8ad2fc0031a3705708a5f1cdf9518f391df4d80 refs/tags/debian-version-0.1.0.14-2^{}
+\r
+a5\r
+00513e452a736efa4b8d5caf63da30b029073dc600e9 refs/tags/debian-version-0.1.0.15-1
+0054d2795a6ed34b65f84a5b0e70795d4c8b3e55fe43 refs/tags/debian-version-0.1.0.15-1^{}
+\r
+f6\r
+00519858cd959d338d2b97dbab25fdfc9815e560325d refs/tags/debian-version-0.1.0.16-1
+0054d2795a6ed34b65f84a5b0e70795d4c8b3e55fe43 refs/tags/debian-version-0.1.0.16-1^{}
+0051d44c6adb769c11bc502c3e4cad785e022f7af711 refs/tags/debian-version-0.1.0.17-1
+\r
+54\r
+0054d2795a6ed34b65f84a5b0e70795d4c8b3e55fe43 refs/tags/debian-version-0.1.0.17-1^{}
+\r
+c3\r
+0060af13ba9003478d4fc5516b3a1444e6a18c7561b5 refs/tags/debian-version-0.1.0.2-rc-200504011500-1
+00635de85f54ba0c0d21f99cc1e1053da6076eeae4e4 refs/tags/debian-version-0.1.0.2-rc-200504011500-1^{}
+\r
+c3\r
+0060b5a39210925640b7bd24bdb55d273d662df96e8a refs/tags/debian-version-0.1.0.2-rc-200504011640-1
+00637d5411f51aaf35bec79286669ba76a8e4b08a8f1 refs/tags/debian-version-0.1.0.2-rc-200504011640-1^{}
+\r
+196\r
+006443e0acc2f7c7a0489fc97dfecbff3399e7a67aef refs/tags/debian-version-0.1.0.2-rc-cvs-200504031300-1
+0067f89ef9793e5d57a4dfdeb4f6c10e78b7621550f2 refs/tags/debian-version-0.1.0.2-rc-cvs-200504031300-1^{}
+0064be873419cf99306923bd627d596d7f40c5c341fa refs/tags/debian-version-0.1.0.2-rc-cvs-200504061620-1
+0067b16ff67fbf91a31eb530c2a89d03297b3a5dbe23 refs/tags/debian-version-0.1.0.2-rc-cvs-200504061620-1^{}
+\r
+64\r
+006425d228a83903a204e4abd42d10d09e56cee805a3 refs/tags/debian-version-0.1.0.2-rc-cvs-200504062112-1
+\r
+67\r
+0067b5a962bc2e6381ff0c5e5c405e80e172f02d5ce9 refs/tags/debian-version-0.1.0.2-rc-cvs-200504062112-1^{}
+\r
+c3\r
+006049f32646382d62de625179704715c9a4c4158283 refs/tags/debian-version-0.1.0.3-rc-200504080730-1
+00637529186b5adc025381a6e4248a10aaa3989a60d5 refs/tags/debian-version-0.1.0.3-rc-200504080730-1^{}
+\r
+c3\r
+0060dec07a590542399f55c7b3107b7db50edf613ac2 refs/tags/debian-version-0.1.0.3-rc-200504231430-1
+00635827e2e216ad759f240a0c332848cadf65794742 refs/tags/debian-version-0.1.0.3-rc-200504231430-1^{}
+\r
+12b\r
+0064056fdbd9da7b2bfceec196379ec9fa952bf667ab refs/tags/debian-version-0.1.0.3-rc-cvs-200504231630-1
+0067a2129c3a30eb8593ea1e193e8108564f0c9978d4 refs/tags/debian-version-0.1.0.3-rc-cvs-200504231630-1^{}
+00600ea1d05d038027715efaebd5e5d9524cb207c9cc refs/tags/debian-version-0.1.0.4-rc-200504232130-1
+\r
+63\r
+006392b70813ffba87ad63085e10c78cf45354bf2fe8 refs/tags/debian-version-0.1.0.4-rc-200504232130-1^{}
+\r
+60\r
+006074832b1bf93bba56d20e358774a72fb3d73d0f6f refs/tags/debian-version-0.1.0.5-rc-200504272000-1
+\r
+63\r
+006353607d3bb352e93b72360a7772cc60532810566b refs/tags/debian-version-0.1.0.5-rc-200504272000-1^{}
+\r
+16c\r
+00602225b75f9c5a9ef1f7d76dea9fecb9ee2b02e03f refs/tags/debian-version-0.1.0.7-rc-200505171420-1
+006317ba6e76118b11548e623fe22a32f54cba9f6535 refs/tags/debian-version-0.1.0.7-rc-200505171420-1^{}
+00538864cc5c7a5c65980a5ac447363ded6ef1327efd refs/tags/debian-version-0.1.0.8-rc-1
+0056c8ad2fc0031a3705708a5f1cdf9518f391df4d80 refs/tags/debian-version-0.1.0.8-rc-1^{}
+\r
+53\r
+0053339a4540076ba8521598503844170303baebd9a3 refs/tags/debian-version-0.1.0.9-rc-1
+\r
+56\r
+0056c8ad2fc0031a3705708a5f1cdf9518f391df4d80 refs/tags/debian-version-0.1.0.9-rc-1^{}
+\r
+213\r
+00579a0a847629783e5927c57c8f394a61acdd838956 refs/tags/debian-version-0.1.1.10-alpha-1
+005a5331ebd99de37780d4fc4b7272bf8faaae0e3f04 refs/tags/debian-version-0.1.1.10-alpha-1^{}
+005749e8494f56f47d0e430caf2c9360c575147e05b5 refs/tags/debian-version-0.1.1.11-alpha-1
+005a690338d2c4e599900c8623cfcd2c2935943b9561 refs/tags/debian-version-0.1.1.11-alpha-1^{}
+0057cfdf709ac398e2cbb259618fa012d0a871907c02 refs/tags/debian-version-0.1.1.12-alpha-1
+005a20bcce490a77d930228fd36053c2cb9400f348e5 refs/tags/debian-version-0.1.1.12-alpha-1^{}
+\r
+162\r
+0057b8984356c7cc1afd0d9d8b2796236c6f518b339e refs/tags/debian-version-0.1.1.13-alpha-1
+005ac03cf41ca5e2ccfc48ca3f680b6eb2e9a32e997f refs/tags/debian-version-0.1.1.13-alpha-1^{}
+005775cbc7b616490e76cf2f74ef50758777b6d73581 refs/tags/debian-version-0.1.1.14-alpha-1
+005a138676541974dc1188236bb7174b1c31c88fb555 refs/tags/debian-version-0.1.1.14-alpha-1^{}
+\r
+54\r
+00549cc7ea4b30464b1df904c1bb6cd1b4b18c2fc0f7 refs/tags/debian-version-0.1.1.15-rc-1
+\r
+57\r
+0057941fa7b7d979afa638c8552511e05ec350aac0c1 refs/tags/debian-version-0.1.1.15-rc-1^{}
+\r
+ab\r
+0054598259233c8356ba7486b6ce4a327c656669c614 refs/tags/debian-version-0.1.1.16-rc-1
+00575798bf03e0567d255345722841e8723d97b38a33 refs/tags/debian-version-0.1.1.16-rc-1^{}
+\r
+54\r
+00540a69e9b80b8f3006e8ed9adc0c31a29d7d91a097 refs/tags/debian-version-0.1.1.17-rc-1
+\r
+57\r
+00574f0d7b74243644fce7c20b47c3024cf2b622de8f refs/tags/debian-version-0.1.1.17-rc-1^{}
+\r
+ab\r
+0054a9327412b6f9fc57040786d6434477337e3ef464 refs/tags/debian-version-0.1.1.18-rc-1
+0057219dd9b183c138f4a63758251a1841dc94fd9d6c refs/tags/debian-version-0.1.1.18-rc-1^{}
+\r
+54\r
+0054f3f4890f0b54a94017c039f756afaadb2d432f3f refs/tags/debian-version-0.1.1.19-rc-1
+\r
+57\r
+00574f0d7b74243644fce7c20b47c3024cf2b622de8f refs/tags/debian-version-0.1.1.19-rc-1^{}
+\r
+51\r
+00518d775a274df64f3252bfcb2bbe9502334adab6f0 refs/tags/debian-version-0.1.1.20-1
+\r
+54\r
+00544f0d7b74243644fce7c20b47c3024cf2b622de8f refs/tags/debian-version-0.1.1.20-1^{}
+\r
+14a\r
+0051d70f71f58cca087879f4ff3ef93a0eb026efb3d8 refs/tags/debian-version-0.1.1.21-1
+00544f0d7b74243644fce7c20b47c3024cf2b622de8f refs/tags/debian-version-0.1.1.21-1^{}
+00514d94628e783ae082b9ea9e168d33a93187683890 refs/tags/debian-version-0.1.1.22-1
+00544f0d7b74243644fce7c20b47c3024cf2b622de8f refs/tags/debian-version-0.1.1.22-1^{}
+\r
+f4\r
+00504a7f20933dd9e56447ff749e71dd0284e56971d8 refs/tags/debian-version-0.1.1.23-
+0053ac09b3271b8b923df50dc43f67097a2aebade4e6 refs/tags/debian-version-0.1.1.23-^{}
+00519e67777424b6f8d8c92094405625b6d60a0a5976 refs/tags/debian-version-0.1.1.23-1
+\r
+54\r
+005423e2606f1d4484be52774a82660429f03f6d8945 refs/tags/debian-version-0.1.1.23-1^{}
+\r
+105\r
+005608c0218539f48d83371db9e5fe3a894fa597d6a5 refs/tags/debian-version-0.1.1.23-1@6359
+0059958b6e674245a45c00f3db6f07cc851caa34f004 refs/tags/debian-version-0.1.1.23-1@6359^{}
+005620992186b8d780a2af1ba04d2fc02cafc2a93ef1 refs/tags/debian-version-0.1.1.23-1@6967
+\r
+59\r
+00594741cc04b066743aeb3278ea42b9a6a6fb563e75 refs/tags/debian-version-0.1.1.23-1@6967^{}
+\r
+105\r
+00562c55ed425947aa13b1a3105e0766bd5a3e1ef02e refs/tags/debian-version-0.1.1.5-alpha-1
+0059ad1ff57705bf6023be3ad31d990ccc6c423a1ae0 refs/tags/debian-version-0.1.1.5-alpha-1^{}
+00569a50919b4132c868636444029b4634c4103237a0 refs/tags/debian-version-0.1.1.6-alpha-1
+\r
+59\r
+00597a61dbed77765fe6b71c4f1439cf6553b8e887f4 refs/tags/debian-version-0.1.1.6-alpha-1^{}
+\r
+15e\r
+00568149b8917578be2142f15dda372786b9b9901c13 refs/tags/debian-version-0.1.1.6-alpha-2
+0059e4ee8a006949843541ecadcd380d4d7536b0e536 refs/tags/debian-version-0.1.1.6-alpha-2^{}
+00560c040abbd4bfd8f41b625bf0b26b1ff7724a9a0b refs/tags/debian-version-0.1.1.7-alpha-1
+0059db27c322838caa9861b918a64630232bdc5d86e7 refs/tags/debian-version-0.1.1.7-alpha-1^{}
+\r
+af\r
+0056159c14d38f04b2b83c5c804f7a033c62bb572091 refs/tags/debian-version-0.1.1.8-alpha-1
+0059e459f6ee0f71f182718cfbbe6d0a551b1e1886b9 refs/tags/debian-version-0.1.1.8-alpha-1^{}
+\r
+56\r
+00563188b876d3624fa9d45e601fd1448eaec45e8f0e refs/tags/debian-version-0.1.1.9-alpha-1
+\r
+59\r
+0059929dc8dea99ccb8e82671b5b5b601c596765851e refs/tags/debian-version-0.1.1.9-alpha-1^{}
+\r
+49\r
+00493df9883eb290f7e3dcb2339e5d4ae7855f6bc717 refs/tags/imported-from-cvs
+\r
+4c\r
+004c9ee3d81f8bbd6384df71529a9e15f0e74b3a25c7 refs/tags/imported-from-cvs^{}
+\r
+9f\r
+004e89718a4e16b44125603e8fcf526ed6214533ef37 refs/tags/imported-from-cvs@6890
+0051a2d9cbb2e82f568a0d4410d6b93922cded44b689 refs/tags/imported-from-cvs@6890^{}
+\r
+1a3\r
+00412a017f9723be927ade4c3558f06a3483269f05bf refs/tags/tor-0.0.2
+0044161d7d19aeead874831c40c4824551204c6afe21 refs/tags/tor-0.0.2^{}
+00467a72ffda23a0860d6afd986cb82518eea02624d9 refs/tags/tor-0.0.2pre13
+0049b4117d2a37ba646765d85a01348849e614fd2bc2 refs/tags/tor-0.0.2pre13^{}
+0046969b0faf8e86fadc0ef58d21ea6f1ce920c50706 refs/tags/tor-0.0.2pre14
+00493b78f5cb0922a9d9547216f5bbbad1e9f89f6cf4 refs/tags/tor-0.0.2pre14^{}
+\r
+11e\r
+0046eac2fc2bec1a9427d1b015b13e4de3c142012446 refs/tags/tor-0.0.2pre16
+0049a0f16c619cca24d9904b3beb0902fdf7da4927df refs/tags/tor-0.0.2pre16^{}
+0046d62a0bdb2c64a8dacf74d6dfb5a92672ef17c0b7 refs/tags/tor-0.0.2pre17
+0049c2e37901be4187bb209581bab31db0c305bb53cd refs/tags/tor-0.0.2pre17^{}
+\r
+46\r
+0046cb47896649ee02c142bb48b30eab1f86f02eaaf7 refs/tags/tor-0.0.2pre18
+\r
+49\r
+00497622a80904e4b06935d69c38d4a0e9cfc8c8b066 refs/tags/tor-0.0.2pre18^{}
+\r
+d5\r
+00467bd276933b39722c2bc05d75e73a5149460619a1 refs/tags/tor-0.0.2pre19
+0049e47106745e1f987cfb9a06df104334a2ef648d55 refs/tags/tor-0.0.2pre19^{}
+004653cc640c51bb4cb2ae3ab083618bbb394c43ddf1 refs/tags/tor-0.0.2pre20
+\r
+49\r
+0049f00dc6fe1e576a82244b08f488553abfd3bf01a3 refs/tags/tor-0.0.2pre20^{}
+\r
+d5\r
+00462ef6b9a78eed4979f55ee125977706ed59654787 refs/tags/tor-0.0.2pre22
+00491e9a963094c8c83231460ae56bc051cde6937a7d refs/tags/tor-0.0.2pre22^{}
+0046db0f892ac34c4a1639b3791d1e8410c373a6338e refs/tags/tor-0.0.2pre23
+\r
+49\r
+00496ee357e64b45ea6a952743280fa3de2bb16f3896 refs/tags/tor-0.0.2pre23^{}
+\r
+46\r
+0046f856f833eb69020e23eefb82bfe89dac170e1332 refs/tags/tor-0.0.2pre24
+\r
+49\r
+0049476e21aa6ee395910391a1d90f23cb9a1473fe53 refs/tags/tor-0.0.2pre24^{}
+\r
+8f\r
+004651634e5ef96f44365bc54de479ce852ec0cbbbb3 refs/tags/tor-0.0.2pre25
+00499d00c4b81cb29f0c50c534696d7886b2d891805a refs/tags/tor-0.0.2pre25^{}
+\r
+46\r
+0046515bb3b3ee840b31aeee8d6d749bcbf254290178 refs/tags/tor-0.0.2pre27
+\r
+49\r
+00490b9c140102bcafccdd1d1ae080bf396817eb6777 refs/tags/tor-0.0.2pre27^{}
+\r
+112\r
+00451664bd62a972b5c236884f1b45966057467211a4 refs/tags/tor-0.0.2pre8
+00486f46316c319277d68ac44697221f1f9881c1d197 refs/tags/tor-0.0.2pre8^{}
+00412f4c4efc8cf4535ba91a241aabe74e6bdfd413c7 refs/tags/tor-0.0.3
+00444d747cd95492941151bbf6f0dc1c629b553590b5 refs/tags/tor-0.0.3^{}
+\r
+10a\r
+00410e6c6fea42b99dc02e3453cca369166856adf65c refs/tags/tor-0.0.4
+004445699bb5ee379a396cf8709d306a3a2f2e4930a5 refs/tags/tor-0.0.4^{}
+004111517746ee69e59d3944303a67f961f4d44d43b7 refs/tags/tor-0.0.5
+00443dad8557a6622f918f2c7dc68b4f469b0168792b refs/tags/tor-0.0.5^{}
+\r
+10e\r
+0041d7baf800e5242c781a3eb8f85e7a8d757ce10b61 refs/tags/tor-0.0.6
+0044a16ec39800744bab4bf127b5adb86821e2822bb1 refs/tags/tor-0.0.6^{}
+0043272874e41d61cd9c91a909c35b366e990ad91c0e refs/tags/tor-0.0.6.1
+0046a16ec39800744bab4bf127b5adb86821e2822bb1 refs/tags/tor-0.0.6.1^{}
+\r
+12c\r
+0043bf985162bed61bb809eb6d7111df2593ec73c546 refs/tags/tor-0.0.6.2
+0046a16ec39800744bab4bf127b5adb86821e2822bb1 refs/tags/tor-0.0.6.2^{}
+005001c47c7b048e6ab185a1b51e124fbc00c79df766 refs/tags/tor-0.0.6incompat-merged
+0053f36d7b8fea2b6b5dfb94c8d5ca85bccbac09a7a1 refs/tags/tor-0.0.6incompat-merged^{}
+\r
+10e\r
+004175c38e6270fde5c6f9b1779cadc1302e6febe01d refs/tags/tor-0.0.7
+004472ed3c2810e97143f66ac9c8f1771c281366da2a refs/tags/tor-0.0.7^{}
+0043b3f11afb7c78d761a518acd43672bcace79c8f49 refs/tags/tor-0.0.7.1
+0046e4f83de9eba07225abdd03c67bb5a257d6d3b059 refs/tags/tor-0.0.7.1^{}
+\r
+cd\r
+00431a610f3a52a714d05a13a0f215728dd1b30f58e4 refs/tags/tor-0.0.7.2
+0046e4f83de9eba07225abdd03c67bb5a257d6d3b059 refs/tags/tor-0.0.7.2^{}
+00446a44a00b7c93991f9a18324f251cf3be7d39346f refs/tags/tor-0.0.7rc1
+\r
+47\r
+004715f405c062746f44e93dc49063250ca7d583b69c refs/tags/tor-0.0.7rc1^{}
+\r
+c8\r
+0041afda61d54cd01e95ae7a499f4b9153ba1776821b refs/tags/tor-0.0.8
+00446e844ea7431d7cc1d5397cc424e1bd576c94dae0 refs/tags/tor-0.0.8^{}
+00432e35d0235929234bda4138e6a9c8a593b50e8b35 refs/tags/tor-0.0.8.1
+\r
+46\r
+00466e844ea7431d7cc1d5397cc424e1bd576c94dae0 refs/tags/tor-0.0.8.1^{}
+\r
+11a\r
+0045c517f66d40b4cfe9602b2abbb3646039a0ccded0 refs/tags/tor-0.0.8pre1
+0048e4ae4f43dd808b6e2928deb8877fc969986aba2e refs/tags/tor-0.0.8pre1^{}
+004523563f91fba8657df02b13d65eb16a628f186cb5 refs/tags/tor-0.0.8pre2
+0048c577fd497fd27456301d4a80f9f57ce664644ecf refs/tags/tor-0.0.8pre2^{}
+\r
+15c\r
+0045e1f86f1d3bfa3c5446eb47c50bdc58a58b257aea refs/tags/tor-0.0.8pre3
+00481e415817a3b63775a49db5581dd7971e5da659c2 refs/tags/tor-0.0.8pre3^{}
+00441e21132a6b1dc6b3fda515c6ab04fc4a61724339 refs/tags/tor-0.0.8rc1
+004789552dc217fe184faa3ce130d90764db914580c9 refs/tags/tor-0.0.8rc1^{}
+0044323bd57fbc9164d74b3c022e30f77c5e5cbdd3c8 refs/tags/tor-0.0.8rc2
+\r
+47\r
+00471e24d59aef618d859097cd9fe9ec5c3a43cbb9dc refs/tags/tor-0.0.8rc2^{}
+\r
+85\r
+004115dc66870718e22916a80c2b26a05d0e6a13067c refs/tags/tor-0.0.9
+0044c0cb8248579d3b35503412a4f8d835cf5f6f2f95 refs/tags/tor-0.0.9^{}
+\r
+43\r
+0043c0f45c06cecb3fb7b827da22c523d36b473b77bb refs/tags/tor-0.0.9.1
+\r
+46\r
+0046e327b2f3a6f3a9667f42826890d50c354c90fc9e refs/tags/tor-0.0.9.1^{}
+\r
+44\r
+0044f54010204506ee0b2e38294fbb3be6e4b53a3b82 refs/tags/tor-0.0.9.10
+\r
+47\r
+0047afec9f233596807b7464060cecfd256f42700e92 refs/tags/tor-0.0.9.10^{}
+\r
+89\r
+00436a89b2a64ed396584d4d0946ab60bc4907f63362 refs/tags/tor-0.0.9.2
+0046afec9f233596807b7464060cecfd256f42700e92 refs/tags/tor-0.0.9.2^{}
+\r
+224\r
+0043ced9af55adfca9188d1c64a1dc944906979ae116 refs/tags/tor-0.0.9.3
+0046afec9f233596807b7464060cecfd256f42700e92 refs/tags/tor-0.0.9.3^{}
+00435e7f247861bf3730fedd2fa0e7d297fbe73d05ff refs/tags/tor-0.0.9.5
+0046afec9f233596807b7464060cecfd256f42700e92 refs/tags/tor-0.0.9.5^{}
+00438722d0fa5538b268b47885e9904a2e5eae0dd002 refs/tags/tor-0.0.9.6
+0046afec9f233596807b7464060cecfd256f42700e92 refs/tags/tor-0.0.9.6^{}
+004376d9a2a6860788b9d4e92e6970311fab0c295a5a refs/tags/tor-0.0.9.7
+0046afec9f233596807b7464060cecfd256f42700e92 refs/tags/tor-0.0.9.7^{}
+\r
+89\r
+00432817a5c7dbb840ce3ea513ddecf0f73ddfb63b2c refs/tags/tor-0.0.9.9
+0046afec9f233596807b7464060cecfd256f42700e92 refs/tags/tor-0.0.9.9^{}
+\r
+15f\r
+004512153492e4243b6ba6e27fc3df64f5a483ec3489 refs/tags/tor-0.0.9pre1
+0048ce0c7c554da4288666352f2636a817409f7d7a60 refs/tags/tor-0.0.9pre1^{}
+00454a057f01096a915e0e378a1e6dcde7169ede144b refs/tags/tor-0.0.9pre2
+00489e8ae9766e5d4eb94972f2e7118ce8e9c2e09381 refs/tags/tor-0.0.9pre2^{}
+00454faf7e4a8e0431910dade8bbcbb43b658501572d refs/tags/tor-0.0.9pre3
+\r
+48\r
+0048e2dea1dd59064246e217a848808a5837830a066d refs/tags/tor-0.0.9pre3^{}
+\r
+8d\r
+00450f50c3bfdf8c857ba77ebd06f16af53e3b4f2e34 refs/tags/tor-0.0.9pre4
+00484c2595ca66c3dd66086ab1bee0297ca9beb3c556 refs/tags/tor-0.0.9pre4^{}
+\r
+8d\r
+0045d309a2a35a659afc37d4448c80142a0e75d85916 refs/tags/tor-0.0.9pre5
+0048c1bf171ed8c35f59724a18f9ccea8082fd1d7dfc refs/tags/tor-0.0.9pre5^{}
+\r
+8d\r
+00456d040ad2c7dd44962199ccc5bab06cf7ab58a3e3 refs/tags/tor-0.0.9pre6
+00483e4f30fbb99b851c6d3e1a750626c07b22858c43 refs/tags/tor-0.0.9pre6^{}
+\r
+cf\r
+0044db7b66641655f08a1a5b94c9a64f7dfc259f68c6 refs/tags/tor-0.0.9rc1
+0047c893403ed73642acbeea9276733088692718a2bf refs/tags/tor-0.0.9rc1^{}
+00441f05c2b625cd21edd2ad3f1af68d8efaf7b0c6a7 refs/tags/tor-0.0.9rc2
+\r
+47\r
+0047730f4dd52b5c808b06696ea0ec620210cbd15bbd refs/tags/tor-0.0.9rc2^{}
+\r
+cf\r
+0044abcedde859db065263171786390d68fcc316b309 refs/tags/tor-0.0.9rc3
+0047d254aeb09e09a744555b2cf183ab28bc56ee95ca refs/tags/tor-0.0.9rc3^{}
+004412d9506227bc7e3e0d8c75b24513dbeace9c62aa refs/tags/tor-0.0.9rc4
+\r
+47\r
+004767dc7baa59e2b38a6720d843b54257ca0dd9e722 refs/tags/tor-0.0.9rc4^{}
+\r
+cf\r
+00441a569f589746ef006232a7c586220d07f7c50ceb refs/tags/tor-0.0.9rc5
+0047e3f6f92cf7d3a2fedc387ed1084aa82815c911dd refs/tags/tor-0.0.9rc5^{}
+00443ff6eb4f812994bc46d5a59e6e05de69f70a1392 refs/tags/tor-0.0.9rc6
+\r
+47\r
+00474006246b9e38f03e75fdf8b87fd9c52241b5c0bd refs/tags/tor-0.0.9rc6^{}
+\r
+11a\r
+00447430dd6270dde3db44417388fb0412248cedd35b refs/tags/tor-0.0.9rc7
+0047470cdea7f8170738e44566f063426ce419f2e0dc refs/tags/tor-0.0.9rc7^{}
+004623ba8444b54870b28b2624de6c05fd121023dd42 refs/tags/tor-0.1.0.1-rc
+0049fddf560254da197b9e4726b6101f358f4b68e7af refs/tags/tor-0.1.0.1-rc^{}
+\r
+116\r
+00443f8f04c00ce10004f942c48f709fde5e0ea929f3 refs/tags/tor-0.1.0.10
+00474855990d378212d433f65ff960391ae56e5e1365 refs/tags/tor-0.1.0.10^{}
+00442549b54facbc50588926bcdc9317432f07d0eb40 refs/tags/tor-0.1.0.11
+00474855990d378212d433f65ff960391ae56e5e1365 refs/tags/tor-0.1.0.11^{}
+\r
+116\r
+00443d2918543fcd8519e4d65e06afe8f9262e7cedf9 refs/tags/tor-0.1.0.12
+00474855990d378212d433f65ff960391ae56e5e1365 refs/tags/tor-0.1.0.12^{}
+00442fada1bdca5add9df0cd54c99568cb8743260659 refs/tags/tor-0.1.0.13
+00474855990d378212d433f65ff960391ae56e5e1365 refs/tags/tor-0.1.0.13^{}
+\r
+116\r
+004487889f1b96e0b9fb48688f008bc7c5c044d4b7f9 refs/tags/tor-0.1.0.14
+00474855990d378212d433f65ff960391ae56e5e1365 refs/tags/tor-0.1.0.14^{}
+004483b8b9ae0bb0c42abcffd80b8440af11456b4518 refs/tags/tor-0.1.0.15
+0047f4a14410ad0a7941906d983b5134a25089094302 refs/tags/tor-0.1.0.15^{}
+\r
+cf\r
+004463136bfbf8786731fc9f14faf8aa961572310719 refs/tags/tor-0.1.0.16
+0047f4a14410ad0a7941906d983b5134a25089094302 refs/tags/tor-0.1.0.16^{}
+0044a0c517c407bd1545a9cf875cc5ee966e49e8592e refs/tags/tor-0.1.0.17
+\r
+47\r
+0047f4a14410ad0a7941906d983b5134a25089094302 refs/tags/tor-0.1.0.17^{}
+\r
+46\r
+0046d55ab111bf78778747c2d58bf5f53ea9b34026c7 refs/tags/tor-0.1.0.2-rc
+\r
+49\r
+004928fc34b1e21e98ee0deec77e318302a5dbab2909 refs/tags/tor-0.1.0.2-rc^{}
+\r
+164\r
+00460a89a43e8aeff22c59e34581d7a3b1b8245b5ca7 refs/tags/tor-0.1.0.4-rc
+004942d99ed77307243ca7ccd272d5ff1d4fa4f410bc refs/tags/tor-0.1.0.4-rc^{}
+00463bcfe44b232001064f68ba8e13977eee8768416b refs/tags/tor-0.1.0.5-rc
+0049d0a9a8bdd3538f626243daad52c7eb0ba6085507 refs/tags/tor-0.1.0.5-rc^{}
+00460fd0ca62c91ce0db5770f11361b8b3c2ab884db7 refs/tags/tor-0.1.0.6-rc
+\r
+49\r
+00495837711b0abcb43a43fb2573df598f7cbc9b82ba refs/tags/tor-0.1.0.6-rc^{}
+\r
+11e\r
+004645dfa751e07b3ad8b99002ddc5fbe91ad37f8e32 refs/tags/tor-0.1.0.7-rc
+0049356114c28e1170a269ef6a054b78f20f49eba4e4 refs/tags/tor-0.1.0.7-rc^{}
+004681ce93e46f5e6dd957bd1d1f8445b496c8089d8f refs/tags/tor-0.1.0.9-rc
+00494855990d378212d433f65ff960391ae56e5e1365 refs/tags/tor-0.1.0.9-rc^{}
+\r
+12c\r
+0049d8d87e17df319c21ee3af977da857578187540f5 refs/tags/tor-0.1.1.1-alpha
+004cdf56eea8f3f6c67191ecf5832674cb4c65797066 refs/tags/tor-0.1.1.1-alpha^{}
+004a05ab0d3ee49c6ef598f659756a891af5ed6e7ede refs/tags/tor-0.1.1.10-alpha
+004debacd3be0c66367b6a2cd18103b78db608981c4c refs/tags/tor-0.1.1.10-alpha^{}
+\r
+4a\r
+004aca2c2fef0f3128a3b46416c77108aa39b4d01be3 refs/tags/tor-0.1.1.11-alpha
+\r
+4d\r
+004d4f7749dd97a5c433a4f0f486a2e9452ecf9fc64b refs/tags/tor-0.1.1.11-alpha^{}
+\r
+e1\r
+004ae44119faa23ac468d3647d17d7e3b468200b7487 refs/tags/tor-0.1.1.12-alpha
+004d3c894809132137d799fd31c1714e900a2f42d2ab refs/tags/tor-0.1.1.12-alpha^{}
+004ad2652597fce0d66a15ae42073cd4f143fcabbbfa refs/tags/tor-0.1.1.13-alpha
+\r
+4d\r
+004dddb43de2d0bc016f85a56a76bfa1229a95173ea3 refs/tags/tor-0.1.1.13-alpha^{}
+\r
+4a\r
+004aca1f7bc3cd83e438f93cb45224e60b60e6db95d5 refs/tags/tor-0.1.1.14-alpha
+\r
+4d\r
+004df797ce5e597a4b03f725aab1d727a3efb00d1284 refs/tags/tor-0.1.1.14-alpha^{}
+\r
+d8\r
+00476c9ea9d54340d01fbafc66b7cf7f5180be3bf8f9 refs/tags/tor-0.1.1.15-rc
+004a941fa7b7d979afa638c8552511e05ec350aac0c1 refs/tags/tor-0.1.1.15-rc^{}
+00475aa0ac9a6647be3fa9d979f66e77e90f5a8c5d12 refs/tags/tor-0.1.1.16-rc
+\r
+4a\r
+004abcc19b0f837556221336c82c0860236d18448386 refs/tags/tor-0.1.1.16-rc^{}
+\r
+169\r
+00476bfcbe71c56d409866784f11e0ac1309f4bec424 refs/tags/tor-0.1.1.17-rc
+004a26eb815f7388742eab5722f5e2cac9baaae6eacf refs/tags/tor-0.1.1.17-rc^{}
+0047a6cd3dc3da0726ad9a672410483bd9d450f04a9f refs/tags/tor-0.1.1.18-rc
+004ab190c451b8ec438ffe43943f3db03b24a2aa5809 refs/tags/tor-0.1.1.18-rc^{}
+004741ee5235479fc07d1501e9c2328d052b036001d7 refs/tags/tor-0.1.1.19-rc
+\r
+4a\r
+004a53f7a1bb0c84d026cff0478aa8975c202ce84886 refs/tags/tor-0.1.1.19-rc^{}
+\r
+120\r
+00491aa4266193a860568bc48b2dc46f1b493ee543cc refs/tags/tor-0.1.1.2-alpha
+004c452c98058fc214444e726848dafa13447b013721 refs/tags/tor-0.1.1.2-alpha^{}
+00441111d6ecc29fe843eb973a02c3d6b7d8bead747e refs/tags/tor-0.1.1.20
+004753f7a1bb0c84d026cff0478aa8975c202ce84886 refs/tags/tor-0.1.1.20^{}
+\r
+116\r
+0044b9b3bb372883d66531625b5c309678d0c808993b refs/tags/tor-0.1.1.21
+004753f7a1bb0c84d026cff0478aa8975c202ce84886 refs/tags/tor-0.1.1.21^{}
+004451ea194d2d6c31b52204922957ec1624bf0ffd87 refs/tags/tor-0.1.1.22
+004753f7a1bb0c84d026cff0478aa8975c202ce84886 refs/tags/tor-0.1.1.22^{}
+\r
+116\r
+0044bedb349e2f1b21f38d80662b7c07ea99ebf309f0 refs/tags/tor-0.1.1.23
+0047e59976751bd79bba63d8f20dc03ba8b951c60fc8 refs/tags/tor-0.1.1.23^{}
+0044e4a6e5eac6cf0865a4762d12e82d076978a461f2 refs/tags/tor-0.1.1.24
+00471912d1a67c9fe1403d5f300cfbd3009d0476edd9 refs/tags/tor-0.1.1.24^{}
+\r
+44\r
+0044aa0a239041ccc75f9c072f1fb61284aa336a581f refs/tags/tor-0.1.1.25
+\r
+47\r
+004700f78af2d784c0096a1c757d307f7160db811539 refs/tags/tor-0.1.1.25^{}
+\r
+8b\r
+0044fd766e65fb577322f46f7e34f8c21662475545e8 refs/tags/tor-0.1.1.26
+0047fbb0f482637ea8c78729860e24df1f6be94edf6e refs/tags/tor-0.1.1.26^{}
+\r
+de\r
+0049b67d657c97ee61717dc72fe396347f3c51d71a72 refs/tags/tor-0.1.1.4-alpha
+004c3fa821d91127add1d08cba98b3011eed0f4d9be0 refs/tags/tor-0.1.1.4-alpha^{}
+0049ecde2169b900b7ef468029aee46483951500fcd5 refs/tags/tor-0.1.1.5-alpha
+\r
+4c\r
+004c1dd514f244cb1ab3ac44fcc6f6feebf9b1786e95 refs/tags/tor-0.1.1.5-alpha^{}
+\r
+12a\r
+00499ada8f7898267633a4d77b8f8b1d4a08aa86b1ff refs/tags/tor-0.1.1.6-alpha
+004c2ad3e4ff960617808b665d6e0590d31948b82b3b refs/tags/tor-0.1.1.6-alpha^{}
+00499db4cb4e4e4aa1d1ee9017b9b6e59fc08f694ddd refs/tags/tor-0.1.1.7-alpha
+004ce4ee8a006949843541ecadcd380d4d7536b0e536 refs/tags/tor-0.1.1.7-alpha^{}
+\r
+12a\r
+004978e7a370f495214a80065c132ccaaced98cd8877 refs/tags/tor-0.1.1.8-alpha
+004cd7b04a87886c9926b799e263f95b947a237e04cb refs/tags/tor-0.1.1.8-alpha^{}
+0049c188dc6379c8d0dd602bfd9951a2a27d201035db refs/tags/tor-0.1.1.9-alpha
+004cfe7b07754f5c52bc18e648edf32cc8672e1e0aa3 refs/tags/tor-0.1.1.9-alpha^{}
+\r
+126\r
+004972d1991f392d9d82d78e308a6eba88f29467f5a8 refs/tags/tor-0.1.2.1-alpha
+004ce744117d4da1f7cd938480fd9a1541e7377a5204 refs/tags/tor-0.1.2.1-alpha^{}
+0047be5e026cc3282f83b7ebe3d4204f6e7d4c86cd3a refs/tags/tor-0.1.2.10-rc
+004a0066174afa882043a015f75c07b961be6d51b36e refs/tags/tor-0.1.2.10-rc^{}
+\r
+122\r
+0047d2a3acc6647f78745eaa43db046186c591cb50dc refs/tags/tor-0.1.2.11-rc
+004a55aa184ac5da149943e8345e2ac66d2396b409cc refs/tags/tor-0.1.2.11-rc^{}
+004774eddd8c578dd97c8bdd4cfd5193cdd2ac6d5c8e refs/tags/tor-0.1.2.12-rc
+004a378e33a8dad1d2026dafcf9e2e5b1f876ac18911 refs/tags/tor-0.1.2.12-rc^{}
+\r
+cf\r
+0044da0ec14807fa4ae0b0001f06f25bf4f02c4253af refs/tags/tor-0.1.2.13
+0047e35659f66b817c2b7f6400202661687723befb55 refs/tags/tor-0.1.2.13^{}
+004447ad04ea9550fe20e9080e5a8d7fd06be44488e0 refs/tags/tor-0.1.2.14
+\r
+47\r
+0047de4263b450d96c0f29a4fca4f436860a124f4537 refs/tags/tor-0.1.2.14^{}
+\r
+cf\r
+0044043ee25b97f261bc9ae24eae9d225017f403e867 refs/tags/tor-0.1.2.15
+004756b099015ec442cbfa786be3e659980c661daab8 refs/tags/tor-0.1.2.15^{}
+0044ab0e8c911b4894f2e72316499ef88c324fd4d57d refs/tags/tor-0.1.2.16
+\r
+47\r
+00477f193e9edadd8640be8acc94b3000442cf920d90 refs/tags/tor-0.1.2.16^{}
+\r
+122\r
+004aba69074c7cf67c5133e85ca9f5a8aa53b72bfbe7 refs/tags/tor-0.1.2.16@11196
+004d474894b85d13a705c988cf04300f00241f9ed001 refs/tags/tor-0.1.2.16@11196^{}
+00440a25f737653f7969254aeb56f8eaca73c914e67e refs/tags/tor-0.1.2.17
+0047b597d0ee10ba08d01b32f10569285baed1b7fe6e refs/tags/tor-0.1.2.17^{}
+\r
+116\r
+0044be62da760518f7ade8403d8e5eda030e2934e98d refs/tags/tor-0.1.2.18
+0047443bb2c7717ace9497a65d806c2f9ec70ae6d0af refs/tags/tor-0.1.2.18^{}
+0044cfc9fa0dc4b68ad0cb8c46a02c914c4bb14863f7 refs/tags/tor-0.1.2.19
+0047fe4a6cd08e995fff73d36a1073531ef2d826604b refs/tags/tor-0.1.2.19^{}
+\r
+de\r
+0049b2cd414d3edce871c0e25020dbc9f23aae909dc8 refs/tags/tor-0.1.2.2-alpha
+004cf07f7a7a124ade0744afb636a8fd101113a6a7aa refs/tags/tor-0.1.2.2-alpha^{}
+00495bcf45365fa3fdef718cdfd06a206f5101a5df5b refs/tags/tor-0.1.2.3-alpha
+\r
+4c\r
+004cbc6eadd20e502d0fe420749d55f246970ca0e452 refs/tags/tor-0.1.2.3-alpha^{}
+\r
+49\r
+0049e133f8d2ec78d96d393feda0bdf4810602cb9899 refs/tags/tor-0.1.2.4-alpha
+\r
+4c\r
+004c5812a4096bca7015c8a7028a134eb73059c189da refs/tags/tor-0.1.2.4-alpha^{}
+\r
+95\r
+0049240d78ce83b7baa486176f2860fa9c0d8d9b8ccb refs/tags/tor-0.1.2.5-alpha
+004c7cd0495bf6cf6477203d90bed5e680762095dcd3 refs/tags/tor-0.1.2.5-alpha^{}
+\r
+95\r
+00492ed273734af7deb7f4e75ac0ec6ccbf07593a891 refs/tags/tor-0.1.2.6-alpha
+004cca66074106d0841848c51fafba6d6ef48fe6afa3 refs/tags/tor-0.1.2.6-alpha^{}
+\r
+95\r
+00491a4366cd15e920a386099ae51c2b2877c748e585 refs/tags/tor-0.1.2.7-alpha
+004cf1ca295d231f95d0f9d05576238af0e243259147 refs/tags/tor-0.1.2.7-alpha^{}
+\r
+48\r
+00487c90a355da383f5a6b6036224dc659e5cb3a064f refs/tags/tor-0.1.2.8-beta
+\r
+4b\r
+004b38f5fac846ab189f80fe7f10b0a07659f9de130d refs/tags/tor-0.1.2.8-beta^{}
+\r
+46\r
+00464b7df794f565c1cb5d5484cf6b69140ac59773f8 refs/tags/tor-0.1.2.9-rc
+\r
+49\r
+0049c4cf13a5a057b099c407bab4c44d580e06a90606 refs/tags/tor-0.1.2.9-rc^{}
+\r
+95\r
+0049720d70d45804affb62e6c48d046041f8a2a8fbf0 refs/tags/tor-0.2.0.1-alpha
+004c3431377d86e0891a41ce0882069c16f3f87d2142 refs/tags/tor-0.2.0.1-alpha^{}
+\r
+1c5\r
+004a2aedf99cd10114da21c053430ad03999baf481b1 refs/tags/tor-0.2.0.10-alpha
+004d7050df72454ef8f7e49f42d178ac6ef0ba19ec7c refs/tags/tor-0.2.0.10-alpha^{}
+004a17224d68d26ff8020b34ce8b9e24169e2a2eb9fd refs/tags/tor-0.2.0.11-alpha
+004db7024f0f3076c74c44c9422c5dd7e1fe07ed276a refs/tags/tor-0.2.0.11-alpha^{}
+004a0eebbf0da80e419d523112eff59cbb51e1c5b18b refs/tags/tor-0.2.0.12-alpha
+004d6514843026222fe42fa93b01dfb4ed754beeb282 refs/tags/tor-0.2.0.12-alpha^{}
+\r
+4a\r
+004ac5aa54ad438973d7cf03c81cf916fac68fca240c refs/tags/tor-0.2.0.13-alpha
+\r
+4d\r
+004d95daf3382e4f90c2e94ae2d6edc8ee785ddc5b50 refs/tags/tor-0.2.0.13-alpha^{}
+\r
+12e\r
+004a4fb7608c5c1d661de63645ebe3a8f04a1fb863bd refs/tags/tor-0.2.0.14-alpha
+004d2424449947eb06b878dd64bff1cb906f6604989d refs/tags/tor-0.2.0.14-alpha^{}
+004a6d366826b89e710c13631cefdb53e8ef30c35c0a refs/tags/tor-0.2.0.15-alpha
+004d58e429f079a70fe1f019308505bb4743a9fe801f refs/tags/tor-0.2.0.15-alpha^{}
+\r
+97\r
+004aee9e929fd8009abdcf4da39e297e824e881c6ae0 refs/tags/tor-0.2.0.16-alpha
+004d60a3df5a09ec071bc3a7eba1055986a178e46f98 refs/tags/tor-0.2.0.16-alpha^{}
+\r
+12e\r
+004ac1ba2ef6a4e41634e27a832d07fcedece68c50df refs/tags/tor-0.2.0.17-alpha
+004d92e4cfdeb47c0868c5f99caa68d9059d3d068912 refs/tags/tor-0.2.0.17-alpha^{}
+004ab94a19e4ffdadc89f41a99dd418fb3e8932a187e refs/tags/tor-0.2.0.18-alpha
+004d65ecbdad7658ca958fadb2848f4c6d2fa4605253 refs/tags/tor-0.2.0.18-alpha^{}
+\r
+12c\r
+004ac3766e4bceef491ee67faec81e7932d7102da775 refs/tags/tor-0.2.0.19-alpha
+004dd2528e6b48374b31ca07ba85c0caf2dc80fa86bf refs/tags/tor-0.2.0.19-alpha^{}
+0049e5473254ef6299ba03d1457ae4572040b2c22bb2 refs/tags/tor-0.2.0.2-alpha
+004c0b73569dc64d0479d9638ed71da280f752e3637e refs/tags/tor-0.2.0.2-alpha^{}
+\r
+47\r
+00479ac15772ffea5468afcf2bb771fd73cdb3ff39d5 refs/tags/tor-0.2.0.20-rc
+\r
+4a\r
+004a3dd9a3a23a0b8638bcfe0be3036c706e8b6d3eb8 refs/tags/tor-0.2.0.20-rc^{}
+\r
+122\r
+00479ddab1bc02e86009eb6477cb9b04942738307872 refs/tags/tor-0.2.0.21-rc
+004a1ff70f240285669b6072b8e058bd3018f0a5687a refs/tags/tor-0.2.0.21-rc^{}
+0047e9d1b1442416819ce8add75eeb118dcdc1896177 refs/tags/tor-0.2.0.22-rc
+004a77302e3578cb0b22e91b1ef29783d5f6aad7f5a9 refs/tags/tor-0.2.0.22-rc^{}
+\r
+122\r
+0047d6a6bcd2a04044d206b99e78f901c14eced07ecf refs/tags/tor-0.2.0.23-rc
+004a176d5c63b1056b73839ab3ba8bbd66a454dca340 refs/tags/tor-0.2.0.23-rc^{}
+004704bdd3b4b2537938c806d06e09b9dff57c188332 refs/tags/tor-0.2.0.24-rc
+004a94a9eaaf149b1b9fd5c066a3ed56cb0a1f69a16f refs/tags/tor-0.2.0.24-rc^{}
+\r
+d8\r
+0047cb3f34d13ece77af7e3fae45596d4123fffdac93 refs/tags/tor-0.2.0.25-rc
+004a4833d1a30a89efa22199099bd7686a348040d344 refs/tags/tor-0.2.0.25-rc^{}
+00478d04d65d39f2fd3f1488a59c895f93297d49a480 refs/tags/tor-0.2.0.26-rc
+\r
+4a\r
+004a9b87cfbdf8e3eb760d4db80e2edece321a125254 refs/tags/tor-0.2.0.26-rc^{}
+\r
+47\r
+0047a92b99c41a06f9d9a5a61e38f0abd71f5507fe5d refs/tags/tor-0.2.0.27-rc
+\r
+4a\r
+004aee60a8ddff5f5d2d429dd0687c0fafe542694997 refs/tags/tor-0.2.0.27-rc^{}
+\r
+122\r
+00475dcabc0cb419ad7c17732edb07557fabf5770ecc refs/tags/tor-0.2.0.28-rc
+004a3c31afb6c4b131355a75fb62272592af4a5bc40b refs/tags/tor-0.2.0.28-rc^{}
+0047ab7a7fb9c661991c39b4be2425043dc2964535ba refs/tags/tor-0.2.0.29-rc
+004a59b5df9b4e7c16e0a79fdf0c3cd4b6f502490f15 refs/tags/tor-0.2.0.29-rc^{}
+\r
+120\r
+00491a70f68a51aca12961faf86e11b22c639f626897 refs/tags/tor-0.2.0.3-alpha
+004cec1d599302891047d2bd2f722085e187661610f6 refs/tags/tor-0.2.0.3-alpha^{}
+0044323ee2bcd3879826474713e76f6e620ff7ae2a22 refs/tags/tor-0.2.0.30
+004748d9b654bdc9900f4da366213a525a1e6381f584 refs/tags/tor-0.2.0.30^{}
+\r
+116\r
+0044bcf2a83d1b0d92290e81cc8c502c70f9855e755b refs/tags/tor-0.2.0.31
+0047a03e48c541d48bed1ff15616d03880635d2ccb19 refs/tags/tor-0.2.0.31^{}
+00444f578d80c090e0ed9c90ed9f1945dcae47f6e3b3 refs/tags/tor-0.2.0.32
+0047686d30edb695f732d4397e363ed9d6e5163b7ce2 refs/tags/tor-0.2.0.32^{}
+\r
+116\r
+0044b57564db8f93e9006365658dd92aefbe67f4b09d refs/tags/tor-0.2.0.33
+004725290b32a3ecc0bd215ed35bc164f0273ea20a2d refs/tags/tor-0.2.0.33^{}
+0044aa5cff79ebbdae4030653607f1735381ec7c70e3 refs/tags/tor-0.2.0.34
+0047be9efc51c91bc2feb2eaea74d05f3cfccadba36f refs/tags/tor-0.2.0.34^{}
+\r
+8b\r
+00444f19383626d27264daff12943924357867686c1d refs/tags/tor-0.2.0.35
+0047935f457263b88e5d15bc29c84b944c8861d46f90 refs/tags/tor-0.2.0.35^{}
+\r
+49\r
+00497461169f5acd962db5f94a00ecb45a6df2a7f71d refs/tags/tor-0.2.0.4-alpha
+\r
+4c\r
+004ced5acf94d969ac4b0abfb43d76fc715f870d1449 refs/tags/tor-0.2.0.4-alpha^{}
+\r
+ea\r
+004f07a7c04e6f11827653f759039c6158f5b76942ff refs/tags/tor-0.2.0.4-alpha@11197
+005246c4f8ff426c555b05ecbf7cebfdee75dd090278 refs/tags/tor-0.2.0.4-alpha@11197^{}
+0049493fbe1221fca5b734a15bb00b557b963b6536bb refs/tags/tor-0.2.0.5-alpha
+\r
+4c\r
+004c84dddc5df48c5b297ffc4d69214f27d3d26161df refs/tags/tor-0.2.0.5-alpha^{}
+\r
+de\r
+0049d1251ad86f98e1c4ff1bdaffa86616436c5cc1f0 refs/tags/tor-0.2.0.6-alpha
+004cc4ee55ed266cfb8bf8ccd4958536f6eb1e276e5c refs/tags/tor-0.2.0.6-alpha^{}
+004917ea78e9d1694f128514b25784fea27619e496f3 refs/tags/tor-0.2.0.7-alpha
+\r
+4c\r
+004c991ebb42de888661a47512acec02d37f1db12685 refs/tags/tor-0.2.0.7-alpha^{}
+\r
+95\r
+0049570c6f68c70d51755085ff72c5d08f9deb213d4a refs/tags/tor-0.2.0.8-alpha
+004c575487ea9cddd70ea0bba6f0124c38a9830ef670 refs/tags/tor-0.2.0.8-alpha^{}
+\r
+12a\r
+0049b3cff1340528bcf93237c9856ac5a1b12ac32ac4 refs/tags/tor-0.2.0.9-alpha
+004cea4c3d6d1dfe75f14c6c8934c4e6fcfbc5afc204 refs/tags/tor-0.2.0.9-alpha^{}
+00494e182bcc82d449aa0b0513c3875dc5afc8a50961 refs/tags/tor-0.2.1.1-alpha
+004cb2cd61258e52b10d8003c4206f2bf2b56b5bfb38 refs/tags/tor-0.2.1.1-alpha^{}
+\r
+97\r
+004a6f2e1dc93a3aec25f55ccf12570d015f7b03edd9 refs/tags/tor-0.2.1.10-alpha
+004d2d9e8a75b854d10d0943841b0cf27b1cffc28cba refs/tags/tor-0.2.1.10-alpha^{}
+\r
+4a\r
+004aa4776e149d0f28c03b4cf0d5d5be45356098b3a4 refs/tags/tor-0.2.1.11-alpha
+\r
+4d\r
+004d3c668245b7a7e7665679c8fd5461e6efe3a1f166 refs/tags/tor-0.2.1.11-alpha^{}
+\r
+97\r
+004abfd6f7161c056e2967d30434ec516ae19a1821b9 refs/tags/tor-0.2.1.12-alpha
+004d8a555a0d836d27fb14ae22151aa4b10b7bac11e2 refs/tags/tor-0.2.1.12-alpha^{}
+\r
+16f\r
+004a0358f99a0998b2168ad101ccd5912b970f28fe3d refs/tags/tor-0.2.1.13-alpha
+004dd40cbda2cd9e8f41e827d01f99450c760f339dbf refs/tags/tor-0.2.1.13-alpha^{}
+004720fda287b6c9cc7c92d32616014976d3fe2bb396 refs/tags/tor-0.2.1.14-rc
+004a72e4d48c7a8a7722d01c914766a8a663f97c77ec refs/tags/tor-0.2.1.14-rc^{}
+004751ea47275e99022d0210e8ff59ca39ea35844879 refs/tags/tor-0.2.1.15-rc
+\r
+4a\r
+004a2f39eca28b113a18621d3ea3976ab12ceb60c41b refs/tags/tor-0.2.1.15-rc^{}
+\r
+91\r
+00472b14f95551431333d14800f760114de234ee2eb7 refs/tags/tor-0.2.1.16-rc
+004aac3dedacce44b306ec1a9372ee54b0aabaeac8fe refs/tags/tor-0.2.1.16-rc^{}
+\r
+47\r
+00474af8d9328042a9735d3b94ea9f7efc53bbd607d2 refs/tags/tor-0.2.1.17-rc
+\r
+4a\r
+004a32d40607246e357d905bdf17acc20f6c863afd2b refs/tags/tor-0.2.1.17-rc^{}
+\r
+44\r
+0044cef1b0d8e33843f7a025784c314bdd5ab10c23e2 refs/tags/tor-0.2.1.18
+\r
+8b\r
+004752b142219b9ed4b3de8fee4bc09b229cb3f7b410 refs/tags/tor-0.2.1.18^{}
+0044ce6c2ab3161665118ed54d50dc81a4c360196254 refs/tags/tor-0.2.1.19
+\r
+47\r
+004769706f99e80aec9414e6a54e76346d4cf89f1a4c refs/tags/tor-0.2.1.19^{}
+\r
+1ab\r
+0049eed22013dd2e733742e1656ccb6be1979a555847 refs/tags/tor-0.2.1.2-alpha
+004c21cc898a46eec529a74971b10aabf7dd933660dd refs/tags/tor-0.2.1.2-alpha^{}
+004408bb8744ea42d35938135c9636aca6338c70bdbb refs/tags/tor-0.2.1.20
+004716dc543851bb82c481d4319d557ffea5bef6cc50 refs/tags/tor-0.2.1.20^{}
+004479d358e249d2d3154c0077e87a7f96c8ed3cb35b refs/tags/tor-0.2.1.21
+00475201e05fc55d479d95a8b908f6c33d2b88eee26c refs/tags/tor-0.2.1.21^{}
+\r
+116\r
+0044fc9573a1a9bb009eebac943cff77584f7bfdf4a5 refs/tags/tor-0.2.1.22
+0047f43f87db5b945ea86cfb2bce316b46eb6fd9affd refs/tags/tor-0.2.1.22^{}
+0044f1affd4210b91420f2e96a458203781dc60c5bef refs/tags/tor-0.2.1.23
+0047c9a3781580cb0f56ec0b388f0fad41ddef844bb1 refs/tags/tor-0.2.1.23^{}
+\r
+44\r
+00444b5d8333c425dbf0ac8ee706887f45528be0d323 refs/tags/tor-0.2.1.24
+\r
+47\r
+00475e5bc8724edf28491c36fa2e9dd505967f21d45b refs/tags/tor-0.2.1.24^{}
+\r
+116\r
+0044eb4766d6af9a0b1f60d4bb1d4c7f7b86c83bf98c refs/tags/tor-0.2.1.25
+00476b7e5eb5f1ee9d6ef24cbe7d96fa5388f7a54bf0 refs/tags/tor-0.2.1.25^{}
+004464437110963eaf2c2084e20e2930dec1f6f7ada5 refs/tags/tor-0.2.1.26
+004777f30fb55b794b833b104b80504c3a2063e92809 refs/tags/tor-0.2.1.26^{}
+\r
+116\r
+004417d85eae332b54e875ab6bd27f1a5fe95829a857 refs/tags/tor-0.2.1.27
+0047924f7bf9a5c3c960d17c360c9f75a5a43e7b735c refs/tags/tor-0.2.1.27^{}
+0044ed276cafd69a91ff858c6fc62bb301481c2d83e5 refs/tags/tor-0.2.1.28
+00473936267fd9dbc4fed0a29d18c957396b21e10d92 refs/tags/tor-0.2.1.28^{}
+\r
+120\r
+00443c68460c9204de9f702848227ac29280f3ab42ef refs/tags/tor-0.2.1.29
+004741b60af271826162bae94cf6b91adf7f578b380e refs/tags/tor-0.2.1.29^{}
+004980be293f7756cd272d2161b377f72877717ca384 refs/tags/tor-0.2.1.3-alpha
+004cfd4a30d198e2ff166b0fcee9243923eb1b58fcd4 refs/tags/tor-0.2.1.3-alpha^{}
+\r
+116\r
+00447f88ae284afe29b91a22fa57e6c81b21387a4dfc refs/tags/tor-0.2.1.30
+00471855b4ebfdd63c0c3beeeed5eefb9b0c3f50a8bd refs/tags/tor-0.2.1.30^{}
+0044d978be06edad8b31eaade069aa203015c16ce8b3 refs/tags/tor-0.2.1.31
+0047e740ac08c63f68c00f91aeffcd15bef74208fb69 refs/tags/tor-0.2.1.31^{}
+\r
+120\r
+004451e59c71d84d632e84dc2abf2cdbe42075fdb993 refs/tags/tor-0.2.1.32
+0047887bddb7e7323334484c9651ae116e3d28e7b217 refs/tags/tor-0.2.1.32^{}
+00490aabb9e06bd79678c61bb337538510de95b57854 refs/tags/tor-0.2.1.4-alpha
+004cd01813a8ddcfb1db7c833cc42eea1ca98011c599 refs/tags/tor-0.2.1.4-alpha^{}
+\r
+12a\r
+004973a33565696925c8ab5b8e41e0795e2b34adf52d refs/tags/tor-0.2.1.5-alpha
+004ce5576a66dd708be890954a2c01eef5a2764212b1 refs/tags/tor-0.2.1.5-alpha^{}
+0049c7d95faaf2dba3075ae2573b6f2a3dca7ba133a2 refs/tags/tor-0.2.1.6-alpha
+004ca04baf14b6aa0260eb7bcc44e88df09826e3a82b refs/tags/tor-0.2.1.6-alpha^{}
+\r
+12a\r
+0049492958402c4d0787a62dc048043b32a1604dd54d refs/tags/tor-0.2.1.7-alpha
+004c5d19fe51247cab0f4990fe40196d526da1e7a505 refs/tags/tor-0.2.1.7-alpha^{}
+0049cb4cc56962ea87b986fa21ab9522991d4c82d0e6 refs/tags/tor-0.2.1.8-alpha
+004c07c8b2be214cc289f691c6fa5bbb96de7412a3b5 refs/tags/tor-0.2.1.8-alpha^{}
+\r
+49\r
+00496476f56a699ae2a157eb892073970f8c0f1d0d8f refs/tags/tor-0.2.1.9-alpha
+\r
+4c\r
+004c41aef35963efb37b85ac7ea1d24b3bd1dea936cb refs/tags/tor-0.2.1.9-alpha^{}
+\r
+df\r
+004915d2e1911f05c724c9ac6c067f81581498fe3aac refs/tags/tor-0.2.2.1-alpha
+004c1092fdca53ec0110b4e4c0bf51a5881ee68c4ac8 refs/tags/tor-0.2.2.1-alpha^{}
+004af6a31db576b7677ec31bd23e4c42c5ad4c918f3c refs/tags/tor-0.2.2.10-alpha
+\r
+4d\r
+004d81b84c0b017267b4279e18cb5143118efc43ed1c refs/tags/tor-0.2.2.10-alpha^{}
+\r
+12e\r
+004a9bd59f1b009d2cad9ed2cf052897b7a3e8356200 refs/tags/tor-0.2.2.11-alpha
+004d9cde5a4629769d422d28f4b4b71fa87e3d64aa09 refs/tags/tor-0.2.2.11-alpha^{}
+004a414b9ea0ffdd644dd85bebda27f7c66421422724 refs/tags/tor-0.2.2.12-alpha
+004d3d8879a04da79b014700b01f1ed2e8d685040dfb refs/tags/tor-0.2.2.12-alpha^{}
+\r
+12e\r
+004a662522f4390dc986cbe56bc160e250b76946cdf0 refs/tags/tor-0.2.2.13-alpha
+004dfeb8c1b5f67f2c6f4ffe049236e958d26ca5b376 refs/tags/tor-0.2.2.13-alpha^{}
+004a9bd8aace4ad9cfafef973ab9d89de5c674eb37b9 refs/tags/tor-0.2.2.14-alpha
+004d06a79233c57393bc500d27e93a057ebc874bf51d refs/tags/tor-0.2.2.14-alpha^{}
+\r
+12e\r
+004a5797b96f9f6e992ee068d4d854f2c72c14a35607 refs/tags/tor-0.2.2.15-alpha
+004deba3f37f17a2af4ff628dd5cbc653441e6dce6eb refs/tags/tor-0.2.2.15-alpha^{}
+004a17684cd591b8bc7b87caf0302cd85db4e6936cee refs/tags/tor-0.2.2.16-alpha
+004d61e0079ab25db6c31c0b68711e051738a7e5122a refs/tags/tor-0.2.2.16-alpha^{}
+\r
+12e\r
+004ac615c6d2ff1edd7b75a55572a251a06c59db0eab refs/tags/tor-0.2.2.17-alpha
+004ddadd9608d2720368c78e01f485fc2e2783e6a677 refs/tags/tor-0.2.2.17-alpha^{}
+004ab91dc93c1c43f6505cdfe99c6e2ce79e5f16b20e refs/tags/tor-0.2.2.18-alpha
+004d910de7dfac82f3148cff32005de8c0cb4c1042a6 refs/tags/tor-0.2.2.18-alpha^{}
+\r
+e0\r
+004aa2ff4819c3c25a36caef191f29ed4ae8cd8939df refs/tags/tor-0.2.2.19-alpha
+004de57cb6b9762a2f94818738b5790d09c292e1bc24 refs/tags/tor-0.2.2.19-alpha^{}
+0049b8c97b9ab5ec674e1e35daf8e9bb2242faad20de refs/tags/tor-0.2.2.2-alpha
+\r
+4c\r
+004c54ba86d9d0cff2ceef75d564ece3d7d2ea26af26 refs/tags/tor-0.2.2.2-alpha^{}
+\r
+4a\r
+004a3da07914a732f6df129b95ec2efab146a75395c9 refs/tags/tor-0.2.2.20-alpha
+\r
+4d\r
+004daae58deb2cdcaad0ccfbccf26be83a79aad41efa refs/tags/tor-0.2.2.20-alpha^{}
+\r
+12e\r
+004a0761be597f8effc3c707d56ae59c82fb180176fb refs/tags/tor-0.2.2.21-alpha
+004d5f63f0d6312d9f0d66b736f872657fd20f10551c refs/tags/tor-0.2.2.21-alpha^{}
+004aa2c6315e560a15994acb55bfffc7fbf65086a281 refs/tags/tor-0.2.2.22-alpha
+004de5e38e55b33b2cc037c483a38383ab7cfca741fe refs/tags/tor-0.2.2.22-alpha^{}
+\r
+4a\r
+004aa060e931b0655a76174817020a777487153e4c93 refs/tags/tor-0.2.2.23-alpha
+\r
+4d\r
+004db85eb949b528f4d7c6e6a07a550866bb334fd40b refs/tags/tor-0.2.2.23-alpha^{}
+\r
+97\r
+004a77b0a2a1eb310fa642c7b82b274f480738a705c1 refs/tags/tor-0.2.2.24-alpha
+004dc111adb5fe757ea9baf9aaca151af7e8cd5e5808 refs/tags/tor-0.2.2.24-alpha^{}
+\r
+4a\r
+004a2c35a188496d54b1bcc1a17f47ad69465ccd6ad1 refs/tags/tor-0.2.2.25-alpha
+\r
+4d\r
+004d10d45f8d45accdd920918e1980ee45fde1a3d8c4 refs/tags/tor-0.2.2.25-alpha^{}
+\r
+95\r
+004953993ff13eae541c16350dc4b585aa02433e91a2 refs/tags/tor-0.2.2.26-beta
+004cdb3cd62e97294fa14b5b4ecdb3cd1ab7b249b8a5 refs/tags/tor-0.2.2.26-beta^{}
+\r
+12a\r
+0049ee20e4ad993acde3efe6cba02253e8ecb9e2b4f7 refs/tags/tor-0.2.2.27-beta
+004ce3b8457eb38ee76a6912754530a255e4d05b6910 refs/tags/tor-0.2.2.27-beta^{}
+00492218ba7a0857c3a126b21899987fc39b39b59631 refs/tags/tor-0.2.2.28-beta
+004ce084c6fd14caba9567af19cf33f25c4d7a0ac323 refs/tags/tor-0.2.2.28-beta^{}
+\r
+de\r
+0049dfa3c6d03c89028299a737a1219b1f84bfd4dd28 refs/tags/tor-0.2.2.29-beta
+004c2ea53fc0478aaf91c2dd11d520e02da9b2bebd94 refs/tags/tor-0.2.2.29-beta^{}
+00499d213e44e45895f8259d7116f5c3d91d091ce0b3 refs/tags/tor-0.2.2.3-alpha
+\r
+4c\r
+004c0f3417d1dbffdf7a894cb02ac90ecf3de9d2cea7 refs/tags/tor-0.2.2.3-alpha^{}
+\r
+d8\r
+0047f29998d93baa6fa3952d407575def8d0e3cc5722 refs/tags/tor-0.2.2.30-rc
+004a085c9754ccae6caeea2db01e25a749786b6aa84b refs/tags/tor-0.2.2.30-rc^{}
+0047f4a33b9d49581e6e5386d4965350972f08720b3d refs/tags/tor-0.2.2.31-rc
+\r
+4a\r
+004add18fcbbae84a9ac234591ebeb9d88e24abb7158 refs/tags/tor-0.2.2.31-rc^{}
+\r
+cf\r
+0044959ea4eb3db80e2d70cd28cb9b9847b7f6082070 refs/tags/tor-0.2.2.32
+0047877e17749725ab88d7afef5654a3b6d4b668c6bb refs/tags/tor-0.2.2.32^{}
+0044430fd7a34b6f4ca722479a1384224f892b82dac6 refs/tags/tor-0.2.2.33
+\r
+47\r
+00478522652d8e9213d4adf6d1d712c233ad8c9190f7 refs/tags/tor-0.2.2.33^{}
+\r
+44\r
+0044491151cb6e728e47d90771486917d2087685ddeb refs/tags/tor-0.2.2.34
+\r
+47\r
+0047c4eae752f0d157ce1f0f820b4491ca33be86a2ba refs/tags/tor-0.2.2.34^{}
+\r
+cf\r
+004484d6665c4f168d5efcd3eb528b1d0d022754095b refs/tags/tor-0.2.2.35
+0047b04388f9e7546a9f0c77f0d72e41fefb4106d2b5 refs/tags/tor-0.2.2.35^{}
+00446bbdf8cfca2859a8faec46b49656ff52aebb7c07 refs/tags/tor-0.2.2.36
+\r
+47\r
+0047c1414cf70cbfcbb7ad053370f299e7159a85ffc3 refs/tags/tor-0.2.2.36^{}
+\r
+116\r
+0044ae59fc514638b7241891e356929489c516140f76 refs/tags/tor-0.2.2.37
+0047fce6eb1c44e87bc20e1cf62bd46d8fe6e356008e refs/tags/tor-0.2.2.37^{}
+0044b1e604f8394ba9cc867990be3acb2c6ef4746648 refs/tags/tor-0.2.2.38
+004749d150a9fad2cb8d3887af1e112b15365c11f4ba refs/tags/tor-0.2.2.38^{}
+\r
+120\r
+0044b506659865152603faf5fc9e709aa6881bbee19e refs/tags/tor-0.2.2.39
+0047bec76476efb715498b86282d4969c096df336140 refs/tags/tor-0.2.2.39^{}
+004907f9d858aa7bd55e82e60b7d67125b75f5c9618a refs/tags/tor-0.2.2.4-alpha
+004c2f760c54615f9044cad93392c030ef24119026e2 refs/tags/tor-0.2.2.4-alpha^{}
+\r
+12a\r
+0049b8ef9f12e3d7907963cf8d2155768090b3a65033 refs/tags/tor-0.2.2.5-alpha
+004c9d6c79cbbbd21fe685de7cb45f98636dac2f0b36 refs/tags/tor-0.2.2.5-alpha^{}
+00498d844f82849d94cb3ae06c5ea85eb84076ff840e refs/tags/tor-0.2.2.6-alpha
+004c1ee580407ccb91304cf7ae24c0d809f57e6b4ccc refs/tags/tor-0.2.2.6-alpha^{}
+\r
+12a\r
+00497329a658d0c84807adfd32fa06de72a34094d53c refs/tags/tor-0.2.2.7-alpha
+004cc939509051f90d7276355783b255d4a15730efab refs/tags/tor-0.2.2.7-alpha^{}
+00494910cb25694b3b5b6bc2572d790be2ad13a2b32d refs/tags/tor-0.2.2.8-alpha
+004cff88bc7db8edeb290d1905a34442ba7740a90a90 refs/tags/tor-0.2.2.8-alpha^{}
+\r
+de\r
+00499b92daa101835d09817224c94376044a6686c300 refs/tags/tor-0.2.2.9-alpha
+004c2e159967c9871477a20a7caeb6d73c83025ff7c1 refs/tags/tor-0.2.2.9-alpha^{}
+0049a1f41416734c8e4772d4c2037c5732743a1d215b refs/tags/tor-0.2.3.1-alpha
+\r
+4c\r
+004c5cabdc8f679c4124523a1cc02ac1e22ab86b8502 refs/tags/tor-0.2.3.1-alpha^{}
+\r
+4a\r
+004a7590a1315dd97b4b88a735b5b716fcfd61fc7d0c refs/tags/tor-0.2.3.10-alpha
+\r
+4d\r
+004d1fbce83f8c56d9c66eee9ac115c5d7f9211eefb5 refs/tags/tor-0.2.3.10-alpha^{}
+\r
+12e\r
+004a81983ede27cf8ef6a03c5298f73923e5436ec4e2 refs/tags/tor-0.2.3.11-alpha
+004d9ce9836f853d8a31cde1c6ddd7c4e865099a582a refs/tags/tor-0.2.3.11-alpha^{}
+004a61a9179a12ca83893060c07011f0c8bbbef3bd94 refs/tags/tor-0.2.3.12-alpha
+004d800942b4176ca31cbdc03edb6469fd56d2e1acdc refs/tags/tor-0.2.3.12-alpha^{}
+\r
+e1\r
+004aa4397f08bd065fc4bbba14e06242f0a91124252b refs/tags/tor-0.2.3.13-alpha
+004dde73e3692a6d83774027ac9d29e1ec8608076385 refs/tags/tor-0.2.3.13-alpha^{}
+004ade5f9bb4f5a39e5396ffb840f240858b259e5185 refs/tags/tor-0.2.3.14-alpha
+\r
+4d\r
+004d9ebf858824796a3d9cb97580d0970c7881b473e7 refs/tags/tor-0.2.3.14-alpha^{}
+\r
+97\r
+004a7b356a45adbe47f644b1e5af30068ed1b8eba702 refs/tags/tor-0.2.3.15-alpha
+004d2513a3e959b616126f2c0a050e9f8f9593721ef7 refs/tags/tor-0.2.3.15-alpha^{}
+\r
+97\r
+004a8f9966feadb060bcb253bc84066386736f9e4b1d refs/tags/tor-0.2.3.16-alpha
+004de94606a76b98752dac30f366a6eb6877e3438b51 refs/tags/tor-0.2.3.16-alpha^{}
+\r
+49\r
+00495dbef2784f48c34dd90af39e0a4c98e394f8eda0 refs/tags/tor-0.2.3.17-beta
+\r
+4c\r
+004c1e1c7d779eb47fd67e8e01592b434812ffcf134d refs/tags/tor-0.2.3.17-beta^{}
+\r
+d8\r
+0047f249b8e3b8c552e62b166a4e51bf1ee8ed86267e refs/tags/tor-0.2.3.18-rc
+004a64f8e68e65f32c742eab85d993da2a838f90dcf3 refs/tags/tor-0.2.3.18-rc^{}
+0047b9fb482bb2249824ba3fb370cdcb541fdb05d2d1 refs/tags/tor-0.2.3.19-rc
+\r
+4a\r
+004ad8d78f085adef4a3dd9d3c20983daa8571a44097 refs/tags/tor-0.2.3.19-rc^{}
+\r
+126\r
+004993c7136c01f1cc474f84f5908b9bac10dabdf97a refs/tags/tor-0.2.3.2-alpha
+004cbceb136840815bf5014b95adef52eb832fb0b99c refs/tags/tor-0.2.3.2-alpha^{}
+004733b24a09b080446d61e630002335a719f27b93f2 refs/tags/tor-0.2.3.20-rc
+004a24d7a06f04d701c4dd263b911906cb1e97672e99 refs/tags/tor-0.2.3.20-rc^{}
+\r
+47\r
+004769fcb6c76de6b9e66405afe88fdbb18bc86b2de7 refs/tags/tor-0.2.3.21-rc
+\r
+4a\r
+004a139a81c96d4af2f52b1f3d76adc4079403c8d2d7 refs/tags/tor-0.2.3.21-rc^{}
+\r
+d8\r
+0047919ea020348ad0d21c96f4881895079d2fcf93a7 refs/tags/tor-0.2.3.22-rc
+004a213ba1a70b41ea975f2e0119a746aa1bad6f1e22 refs/tags/tor-0.2.3.22-rc^{}
+0047146a84955bd7f9dffe3e509c9e9ee4d03a487be4 refs/tags/tor-0.2.3.23-rc
+\r
+4a\r
+004a3a2b86ef5d576e55defb3a9a1e37bee48b7b3d6a refs/tags/tor-0.2.3.23-rc^{}
+\r
+11c\r
+00478d00658584591cb04c3c4680a9b53dd74ea46ef7 refs/tags/tor-0.2.3.24-rc
+004a4f228f39ec74abfa1a806d944a2d84edb63a5757 refs/tags/tor-0.2.3.24-rc^{}
+0044e361312c50307a2279cda4c4aa884584697646e4 refs/tags/tor-0.2.3.25
+004717c24b3118224d6536c41fa4e1493a831fb29f0a refs/tags/tor-0.2.3.25^{}
+\r
+49\r
+0049f3fec4e995e1b4ea24ca73405972e9795331dcdd refs/tags/tor-0.2.3.3-alpha
+\r
+4c\r
+004c01357d6b163b1823811435871c92d6972b4eb65d refs/tags/tor-0.2.3.3-alpha^{}
+\r
+12a\r
+00496b0fd72197044b242846ee1b099d3e7794d2a16c refs/tags/tor-0.2.3.4-alpha
+004c5f4f727d58daa194656ec43880a6151e88f5c0a2 refs/tags/tor-0.2.3.4-alpha^{}
+004953f8c549015652e8c3444e5b1cb60e42baa9f586 refs/tags/tor-0.2.3.5-alpha
+004c1fac96f4c6c399561f80109e71b2441fa06ac808 refs/tags/tor-0.2.3.5-alpha^{}
+\r
+12a\r
+00490ea474bb10e9986dfcc3bb03a8225639f3ed4c73 refs/tags/tor-0.2.3.6-alpha
+004c47dff61061f4bfc2ad5f1992a11b48e5c7ad94af refs/tags/tor-0.2.3.6-alpha^{}
+0049fbf9b1af0e0cd0d9855b47f024bd7b0b2d3367bd refs/tags/tor-0.2.3.7-alpha
+004cc2d03beb65d0c82035be714666bfd0e9fc7c3060 refs/tags/tor-0.2.3.7-alpha^{}
+\r
+12a\r
+0049c855028e71c1d2a90287fe3e7abed1234d71be80 refs/tags/tor-0.2.3.8-alpha
+004c68475fc5c5a806ebbb5657de1667dab2c3e09b7c refs/tags/tor-0.2.3.8-alpha^{}
+00494bc8751e56a215d6b9dee4a8bccfda53b613791c refs/tags/tor-0.2.3.9-alpha
+004ce44205ee6c3816b8b1f31e62809a8ca053afb033 refs/tags/tor-0.2.3.9-alpha^{}
+\r
+12c\r
+00497f20f3c066b64cd1e58357dbe6318580b15002fd refs/tags/tor-0.2.4.1-alpha
+004c237129847b824925058975f8da665cd8cb1bed13 refs/tags/tor-0.2.4.1-alpha^{}
+004aeabac6f23896c8b25005986e68a2947dc7c9caa5 refs/tags/tor-0.2.4.10-alpha
+004d54f9a402c5f68633cc46c90364741fe1bd28e0da refs/tags/tor-0.2.4.10-alpha^{}
+\r
+12e\r
+004a7784d1d818af9bddeb39266159593b6539d7da59 refs/tags/tor-0.2.4.11-alpha
+004dfcd9248387249d68619734a73860ffaab12b021b refs/tags/tor-0.2.4.11-alpha^{}
+004a7daf1a4bd35cd975c6daa04ee63a439f2e7c33bb refs/tags/tor-0.2.4.12-alpha
+004d91b8bc26f160f172e2d358d20fc8a3bc150e092d refs/tags/tor-0.2.4.12-alpha^{}
+\r
+4a\r
+004a1ae021e420e10138298cf610b63cf536332a1fd8 refs/tags/tor-0.2.4.13-alpha
+\r
+4d\r
+004ddcb4f22506c7763dee9fbf6139df9dc11d41b184 refs/tags/tor-0.2.4.13-alpha^{}
+\r
+128\r
+004a6148d1bb786d249b80c68ffb636904d9893ae290 refs/tags/tor-0.2.4.14-alpha
+004df5729b8c1d45933f57e8df432c63197ecf8f266e refs/tags/tor-0.2.4.14-alpha^{}
+0047c0d6e2656218bdfd130018e149858fd077f13605 refs/tags/tor-0.2.4.15-rc
+004ae7b435872cce464fee8efa75cdb228f07a367c2b refs/tags/tor-0.2.4.15-rc^{}
+\r
+47\r
+0047ba9c51942df3ead71348ba163dff9507a043c4b0 refs/tags/tor-0.2.4.16-rc
+\r
+4a\r
+004a889e9bd5292972842eb6d02dbce2c6589dd3ccfe refs/tags/tor-0.2.4.16-rc^{}
+\r
+122\r
+0047c0b92122f0c0ba494002ca9973cc122a72174c74 refs/tags/tor-0.2.4.17-rc
+004a00fb525b23cf070fb229e1073caae47e6401f1e2 refs/tags/tor-0.2.4.17-rc^{}
+00479e7006bb0133357448a51697de5fa8f0f64c439e refs/tags/tor-0.2.4.18-rc
+004a1cda452bc136de6bad4f203cea8f195599aec242 refs/tags/tor-0.2.4.18-rc^{}
+\r
+8b\r
+0044d25dc5590dbc0f4a8484f4c9c49e8dcbc60c3e0a refs/tags/tor-0.2.4.19
+0047e719d05fd296a9dd59af9becb21ef3ff1c426b3c refs/tags/tor-0.2.4.19^{}
+\r
+49\r
+0049e5d5b8a46d0bd9e289c1ea760c95b380c58c221e refs/tags/tor-0.2.4.2-alpha
+\r
+4c\r
+004c77d17a360767d8a14ce42a1dd91a8c65973bb768 refs/tags/tor-0.2.4.2-alpha^{}
+\r
+cf\r
+00444576ffa537c684e0926bad413ba99b59f7897b57 refs/tags/tor-0.2.4.20
+00473cb5c70beec5bf46b9e70b1fc6287a1c1c7847ee refs/tags/tor-0.2.4.20^{}
+0044b0073f6099bad2d715e2f9a7bc67a637496026e4 refs/tags/tor-0.2.4.21
+\r
+47\r
+0047505962724c05445fa0f0354e990e6cb60ef193e9 refs/tags/tor-0.2.4.21^{}
+\r
+44\r
+004496440f47e07f2a3c7601576bf0630370b3b8ad25 refs/tags/tor-0.2.4.22
+\r
+47\r
+00472ee56e4c2c841a45418cfb826e1ce6689278382d refs/tags/tor-0.2.4.22^{}
+\r
+cf\r
+004492076ef657e2ea655b2f08992256d7a86fbb182f refs/tags/tor-0.2.4.23
+0047598c61362f1b3d3e3a93d15240c7306d955273be refs/tags/tor-0.2.4.23^{}
+004473561cd6745916a22d4eebcb4f5324118470d2d5 refs/tags/tor-0.2.4.24
+\r
+47\r
+0047f48def202c897758e3f1c65ae0773d71e5094158 refs/tags/tor-0.2.4.24^{}
+\r
+44\r
+0044ea7001cc910d4744523c1fe67da119c8cb7e5f84 refs/tags/tor-0.2.4.25
+\r
+47\r
+00476b2ed1a905ce2ca50a480d319368b676de124d6d refs/tags/tor-0.2.4.25^{}
+\r
+116\r
+004456f8b5f6107dfe9e8c8d262a20b7971a4d63a2ca refs/tags/tor-0.2.4.26
+0047d461e7036fe5cddf390be249436c66286ce992c3 refs/tags/tor-0.2.4.26^{}
+0044e497d616fce453059e6799f12c3ce28e8d2764c1 refs/tags/tor-0.2.4.27
+004785169a121e3b59d2032281e72e0e14a53b6085a2 refs/tags/tor-0.2.4.27^{}
+\r
+116\r
+0044f3cd3af5b38b6a0da7922f3da6e20b6c24f438ea refs/tags/tor-0.2.4.28
+004716bbbe82e42d02e2a251535de576c77d60e2a4bb refs/tags/tor-0.2.4.28^{}
+0044fe35d085e5ea98487ef7d0db44eda5ce4a6bb0f3 refs/tags/tor-0.2.4.29
+0047f833164576c3343ab0f20bda903544f7b4dafdfe refs/tags/tor-0.2.4.29^{}
+\r
+95\r
+0049f0cc6f62affc6c376cc2ad6ffc284a4c38684424 refs/tags/tor-0.2.4.3-alpha
+004c3355976bb472c9a5916b20c83ecdf03a9fde20f6 refs/tags/tor-0.2.4.3-alpha^{}
+\r
+12a\r
+0049d85a40e5e2fc0467e7fff55153a1d2b7b11246be refs/tags/tor-0.2.4.4-alpha
+004cfe3b95f3596194276eac8d1644cec56263a0cf0e refs/tags/tor-0.2.4.4-alpha^{}
+00498969df16911297f6cc823128fce579d176d2c281 refs/tags/tor-0.2.4.5-alpha
+004c17a6aa56cefe9d833a14bffd8e972099dadd2c88 refs/tags/tor-0.2.4.5-alpha^{}
+\r
+12a\r
+00499e36d9ba787e21c7d71bea6209553efb49964086 refs/tags/tor-0.2.4.6-alpha
+004cb13c6becc892d9716d8645f16b5d03bdb0b34651 refs/tags/tor-0.2.4.6-alpha^{}
+0049daad79eb8506e7cb945578cf2a70e641fd29a083 refs/tags/tor-0.2.4.7-alpha
+004ce46e1ed1bc50ad24ee8272efc425d4194a750afd refs/tags/tor-0.2.4.7-alpha^{}
+\r
+49\r
+0049e7fb3977cc20063b49c0c8f9780d1cda12971438 refs/tags/tor-0.2.4.8-alpha
+\r
+4c\r
+004c26cffd3b8656bdec13426ac077e6b4f3ecef9d6c refs/tags/tor-0.2.4.8-alpha^{}
+\r
+12a\r
+0049a9f2c984a4b04ed1663f74e8f97b2ca9077b1184 refs/tags/tor-0.2.4.9-alpha
+004c23dd7c901287d7d8282945cb22950a39f5bcdfd2 refs/tags/tor-0.2.4.9-alpha^{}
+004989890782ca3505e22e9e373ce69dad661cf96ab3 refs/tags/tor-0.2.5.1-alpha
+004ce65b54ec75e3c9e9ada33c8f3ee868d1bea167f5 refs/tags/tor-0.2.5.1-alpha^{}
+\r
+116\r
+0044b0736659ec81ed5b1a4a8b76a2712fb1a7d6a918 refs/tags/tor-0.2.5.10
+004742b42605f8d8eac25361be229354f6393967df4f refs/tags/tor-0.2.5.10^{}
+00442716814704cf56953889c904b6ca7df0dd1e5c7e refs/tags/tor-0.2.5.11
+0047cfb61f909a53c4eba54e2a1f37c52103be35f0a1 refs/tags/tor-0.2.5.11^{}
+\r
+8b\r
+0044af8ef8f21e07e9cbd79dede8de6ac4246cd46b54 refs/tags/tor-0.2.5.12
+004799d0579ff5e0349ffbcf072a42a53270ec1c5eda refs/tags/tor-0.2.5.12^{}
+\r
+116\r
+0044c0c0c76fc763c39ce44b43b7715e4cc7c34ab881 refs/tags/tor-0.2.5.13
+004745245fe29e2e5a0e36c6e4a340d44c6d98cbba1d refs/tags/tor-0.2.5.13^{}
+0044907104125c7956b13b7e1ee65f8ddf9fe3316f08 refs/tags/tor-0.2.5.14
+0047e14006a5454f555c1552094a52f8b4120c353ddd refs/tags/tor-0.2.5.14^{}
+\r
+cf\r
+0044f9e3d95596f87e4d65ec7f142ec005819dc93cbd refs/tags/tor-0.2.5.15
+00475a0e73c75b9c8dbad33044c1cdb0662bddb6de22 refs/tags/tor-0.2.5.15^{}
+0044d244a741d55d290b5ed9bc6d498301253c3b57eb refs/tags/tor-0.2.5.16
+\r
+47\r
+0047b97fb313a922f2e9f0247266e516b2b324e3e169 refs/tags/tor-0.2.5.16^{}
+\r
+12a\r
+0049ca2a9d49eb61913686b77b669256ac3571b61ae2 refs/tags/tor-0.2.5.2-alpha
+004c745434d29a92da682f4c8d8fa70a563862e80ae7 refs/tags/tor-0.2.5.2-alpha^{}
+0049e6516aa1976154d579b2257462ba6fec019d3ce3 refs/tags/tor-0.2.5.3-alpha
+004c29a67e73beae804fd9b9347aabb08072c07cbe0d refs/tags/tor-0.2.5.3-alpha^{}
+\r
+12a\r
+0049d9032eab3c2a0d1874508034adce7aad871354de refs/tags/tor-0.2.5.4-alpha
+004cd2147cc7ba5c5d5114bae61000cbf757353c3ed6 refs/tags/tor-0.2.5.4-alpha^{}
+0049333cd2e99bfe561e0574f488a72571bc730c8b46 refs/tags/tor-0.2.5.5-alpha
+004c2a8be08757ca0bbaf67d1c12859e008730bfb13f refs/tags/tor-0.2.5.5-alpha^{}
+\r
+124\r
+0049973826b85460860fd548354e716c2474cbfe2e69 refs/tags/tor-0.2.5.6-alpha
+004c390728d85644a6c062d6807ffc096343d1c1e73e refs/tags/tor-0.2.5.6-alpha^{}
+004697432b85599f954a121517b2f27877a83f7fd854 refs/tags/tor-0.2.5.7-rc
+004940233cadbbbf77214913db818a1458c6ddd14a9f refs/tags/tor-0.2.5.7-rc^{}
+\r
+d5\r
+00465eeb996f6a65e2388026c1243a7c2241a71a49d9 refs/tags/tor-0.2.5.8-rc
+0049a64f3ab3ee5c433cc1f046a7e26df7a49e308e4c refs/tags/tor-0.2.5.8-rc^{}
+0046a90740b4f74f091c9bcb722a27443cbd339d13e1 refs/tags/tor-0.2.5.9-rc
+\r
+49\r
+0049334f4f60e88ae44450983e1d96bb783cd373455e refs/tags/tor-0.2.5.9-rc^{}
+\r
+120\r
+004942679f71161cafaa2651b3f5ba69aba0fff01a7d refs/tags/tor-0.2.6.1-alpha
+004c5a601dd2901644a537621f407f072d634ece2cfe refs/tags/tor-0.2.6.1-alpha^{}
+004423cb0a0d7c5f73f4a7bbebed707d66179180ee0e refs/tags/tor-0.2.6.10
+004758c51dc6087b093690ab15b7cd0ce627a6115e80 refs/tags/tor-0.2.6.10^{}
+\r
+cf\r
+0044495dd306fc07bb09737d886e50b768a184054f4b refs/tags/tor-0.2.6.11
+0047c0c68547ead7e1884c98adf4110a155c88b1f5b5 refs/tags/tor-0.2.6.11^{}
+004460eef1857ef3272eb0de632490d1ad115b374e18 refs/tags/tor-0.2.6.12
+\r
+47\r
+004721a9e5371d39db388a56654afd0b7cd4d6b60182 refs/tags/tor-0.2.6.12^{}
+\r
+49\r
+00497f1a58e0deba1262a8453807984e24c4fcdab777 refs/tags/tor-0.2.6.2-alpha
+\r
+4c\r
+004c6cb1daf062df525224ee7e3f7cd63ee858aacf9f refs/tags/tor-0.2.6.2-alpha^{}
+\r
+124\r
+00491ebace122d2507472f98cb04f821ceeeda6ea4fc refs/tags/tor-0.2.6.3-alpha
+004c7df7e8d71d7afc422ae3ce9514743e96ea0bcf25 refs/tags/tor-0.2.6.3-alpha^{}
+0046c1f1215b2213998a42111c017797448d5947460f refs/tags/tor-0.2.6.4-rc
+00490c2e4aec7b8b2024a93c2ee5a7d97bdc45501f70 refs/tags/tor-0.2.6.4-rc^{}
+\r
+118\r
+004688107dc6853e453c21615be3be0eece41e6b2530 refs/tags/tor-0.2.6.5-rc
+0049e0b77cd3194d705f9bca254f8a95e520070ca365 refs/tags/tor-0.2.6.5-rc^{}
+0043f55e0017333619276fa1da2943c6336599b5657b refs/tags/tor-0.2.6.6
+0046bb8c4e69ca5c8bcad7d66b2ad502ab35b1a5032b refs/tags/tor-0.2.6.6^{}
+\r
+cc\r
+0043a7280f857d97e76b43c8050ba74c36c1dfddb71d refs/tags/tor-0.2.6.7
+00469ccf019b168909ef6674c71aebda9f90516bb6a1 refs/tags/tor-0.2.6.7^{}
+0043d26cc098fee89512f8c58ac59bdd4938fa5a822e refs/tags/tor-0.2.6.8
+\r
+46\r
+00465c8440b13bde6c8847b9a54d12dadde26f6d37ed refs/tags/tor-0.2.6.8^{}
+\r
+43\r
+00437b431fe76638ae3101a046d20f189eb6c4f9729c refs/tags/tor-0.2.6.9
+\r
+46\r
+0046d41ab97294ec69c748566f4cb610f899d9976572 refs/tags/tor-0.2.6.9^{}
+\r
+dc\r
+0048263f5b8918f6ccfc09ee4884cb1f9bb8d287c348 refs/tags/tor-0.2.7.0-root
+004be49d63a7cedf9a71ffc57a81941a5dbd1af227c1 refs/tags/tor-0.2.7.0-root^{}
+004910ece0915b2284d5035cd31ac0dff9d072b8d1ca refs/tags/tor-0.2.7.1-alpha
+\r
+4c\r
+004cdf76da0f3bfd6897362d2a8a92241167b67fd7a3 refs/tags/tor-0.2.7.1-alpha^{}
+\r
+124\r
+00493ee61bfe4d59a6b07aba414eeef2c78023cee94f refs/tags/tor-0.2.7.2-alpha
+004c36c0ae6f7834af16c379ac399edf7af514cafbb5 refs/tags/tor-0.2.7.2-alpha^{}
+00464d55c0e104744681f34287fe8dc7f0d9c69151f2 refs/tags/tor-0.2.7.3-rc
+00499a4cac74fd2f4bb300830e06ff56f74ccf91e373 refs/tags/tor-0.2.7.3-rc^{}
+\r
+46\r
+004643f742e42b7236cfc902c22bccb16718e86a27dc refs/tags/tor-0.2.7.4-rc
+\r
+49\r
+0049f55d23e1e66e9b0f6971016a9c880341e0209db0 refs/tags/tor-0.2.7.4-rc^{}
+\r
+cc\r
+0043bbe3e0ef0571380ded8ab6e572aa8d91b3fc7b93 refs/tags/tor-0.2.7.5
+0046b6024ec1498edbf8a0b89e1575adb932469d4497 refs/tags/tor-0.2.7.5^{}
+00433142eb1ae432e9ca055eb109e46d58d6f4d4a39d refs/tags/tor-0.2.7.6
+\r
+46\r
+00467a489a638911012069981702065b952a5809d249 refs/tags/tor-0.2.7.6^{}
+\r
+cc\r
+004338a6c605a43d4aad064262b2d274fff509acefca refs/tags/tor-0.2.7.7
+0046da819deb56009e91517f793c789308ec26468791 refs/tags/tor-0.2.7.7^{}
+004303cd3c4146d16d424637c82254c728004af6d634 refs/tags/tor-0.2.7.8
+\r
+46\r
+00463db01d3b565032c777e62d7049a29483a41120e3 refs/tags/tor-0.2.7.8^{}
+\r
+49\r
+0049657b754919ce4b4cc10f9734bdcdcb9a317d4813 refs/tags/tor-0.2.8.1-alpha
+\r
+4c\r
+004c9093e3769746742f95a2a11eb9f8dc2f6d8eb4dc refs/tags/tor-0.2.8.1-alpha^{}
+\r
+8b\r
+00446c42ead31168cfa3358ba1257c44bf23d57544d8 refs/tags/tor-0.2.8.10
+004774d091887c5405585e67694cd890c91766e87864 refs/tags/tor-0.2.8.10^{}
+\r
+8b\r
+0044b2afe1ddfc1c3b435cdd22102fa4485f4b1a7e8e refs/tags/tor-0.2.8.11
+004731e7b47fbebe8cafd9dc1c930cc85585116cdc0f refs/tags/tor-0.2.8.11^{}
+\r
+8b\r
+0044f1203f42915dd6d390f356f2a46b5bd1eed1f6bf refs/tags/tor-0.2.8.12
+00479b3b49f83e2f050bc6f7877479fcee7f997694e5 refs/tags/tor-0.2.8.12^{}
+\r
+cf\r
+004414f5d01b2e736872eb7f4d6fbd12457261a36e41 refs/tags/tor-0.2.8.13
+00474e5df7355514377338c3b284950daedd7091edbd refs/tags/tor-0.2.8.13^{}
+0044c7577a00ee799da5f7ac0ae382a1db4bb4d535c7 refs/tags/tor-0.2.8.14
+\r
+47\r
+004764ac28ef5dae7b41d77d64d66f4582ffadbab196 refs/tags/tor-0.2.8.14^{}
+\r
+44\r
+00448f80383d14ae5d237f3e80d05997f17c6d8bc70b refs/tags/tor-0.2.8.15
+\r
+47\r
+0047e25e980285a80231956dba6d3c89a25c27fdf94f refs/tags/tor-0.2.8.15^{}
+\r
+116\r
+0044c905e8fc990ad02397fd57e7b92f7259675e6956 refs/tags/tor-0.2.8.16
+0047cff872f5155bdaf1aee8be48b6e1cb701f736ee7 refs/tags/tor-0.2.8.16^{}
+0044cb5e24aa6598b7392bfbce5143fbde13f5d24784 refs/tags/tor-0.2.8.17
+004793379889003a6d8df14a1e1262c9c8b8b994107a refs/tags/tor-0.2.8.17^{}
+\r
+12a\r
+00492735d26dec3a6c0131945d7c9b1093f8bedc4624 refs/tags/tor-0.2.8.2-alpha
+004c684babee8491c3e98f8b4cce7854127cf4ed3319 refs/tags/tor-0.2.8.2-alpha^{}
+0049f4718111970a7df728f6eca23130825a3b3b9188 refs/tags/tor-0.2.8.3-alpha
+004cc90f808ebc3af50d6408e6c1d8eed819536263e7 refs/tags/tor-0.2.8.3-alpha^{}
+\r
+11e\r
+004648dcea04ff2ba1eae8d5bb611c0b7ea428c708cf refs/tags/tor-0.2.8.4-rc
+0049fa6a228ce86c2737447f32c78eedc00083eb826c refs/tags/tor-0.2.8.4-rc^{}
+0046c6cf315beaaff0fa92fed53fa5187eba745d421e refs/tags/tor-0.2.8.5-rc
+0049a5b953ae2108803833cfd37e25d7a786bfa4538d refs/tags/tor-0.2.8.5-rc^{}
+\r
+112\r
+00435d33ebc916bb37f43aeed89897be01e2cff99643 refs/tags/tor-0.2.8.6
+00464d217548e3f05569da1d3806a0a9b3817ec2fb54 refs/tags/tor-0.2.8.6^{}
+00431960aca6971acd533f83a72ac2e2ec4dcf91bfbb refs/tags/tor-0.2.8.7
+0046263088633a63982a8d6ddffd3ed3e3d85cffd6f1 refs/tags/tor-0.2.8.7^{}
+\r
+112\r
+004325bcf6308a2947e10c967e6d0d26d5a83ba69d5b refs/tags/tor-0.2.8.8
+0046da84aec55c299d8a43566c846bec761c8321a2e3 refs/tags/tor-0.2.8.8^{}
+00439b7a46c3e70142ca851470b14d0410a7f42da3e2 refs/tags/tor-0.2.8.9
+004644c5fc6878d91d6069ed8c58ba6ad3b1f9b2963b refs/tags/tor-0.2.8.9^{}
+\r
+128\r
+0048806ff8ab1e5c047766bf84e691314b1d9df0c24b refs/tags/tor-0.2.9.0-root
+004b447b1c6b1d235e6de6b888e62bce9021895ae4b1 refs/tags/tor-0.2.9.0-root^{}
+0049a6d4ca15104a896d97e75c0a37bb1aaaf332789e refs/tags/tor-0.2.9.1-alpha
+004c8b1ea189610f4a96d1029f7ecc0fa4c321cd71e5 refs/tags/tor-0.2.9.1-alpha^{}
+\r
+cf\r
+004444f7a81b50c19ef542c70a5f5b00c9866d602bdd refs/tags/tor-0.2.9.10
+00471f6c8eda0073f464b7d23323251d72822f0a18bd refs/tags/tor-0.2.9.10^{}
+0044fa5221ab5d60235b1824f861752c0d1fa2e1e676 refs/tags/tor-0.2.9.11
+\r
+47\r
+0047aa8950022562be763eb283d972d9b5351a354773 refs/tags/tor-0.2.9.11^{}
+\r
+cf\r
+0044210882906016d91bbf56512dd2ada0a512feb605 refs/tags/tor-0.2.9.12
+00472e47bfad4f596dc39ab31bc66056a07d05715270 refs/tags/tor-0.2.9.12^{}
+0044360ad2038cbd8e96a1318559a1622cbb4e7c17b4 refs/tags/tor-0.2.9.13
+\r
+47\r
+0047fbe15d1d7a28e480408904347092e107d6de1545 refs/tags/tor-0.2.9.13^{}
+\r
+44\r
+0044275ef6cff3eb7bd5e3c845f6a20216b6c39cac95 refs/tags/tor-0.2.9.14
+\r
+47\r
+00473f9bd01bf5736ff66af34f05b4611f95fcb7ec51 refs/tags/tor-0.2.9.14^{}
+\r
+116\r
+00447b9d88a109d9208ad120488a5efac423298199ee refs/tags/tor-0.2.9.15
+004774b1ed684e30ef68e0eee52550720b8771e5f0a0 refs/tags/tor-0.2.9.15^{}
+004443689bd885f5dfd0ad4d65b9e65f51780c1f1370 refs/tags/tor-0.2.9.16
+0047645ef2e2854b2225f2b05e2cbddc92dc27a78b3c refs/tags/tor-0.2.9.16^{}
+\r
+120\r
+00444b333e6c1946caf68cc2bfdf1a556a370af06057 refs/tags/tor-0.2.9.17
+0047e057a19b74589fcac9c1da9e0f70b70ac4997734 refs/tags/tor-0.2.9.17^{}
+00497f6aaa2f74d13c2486da7c40f0e2ae4cc7435846 refs/tags/tor-0.2.9.2-alpha
+004c00ec701f8343f5523de52d10b19fe637609f735e refs/tags/tor-0.2.9.2-alpha^{}
+\r
+de\r
+0049c48292834d3069e8927848d11796325d9bf03e23 refs/tags/tor-0.2.9.3-alpha
+004c99041ef343eb66c22765ec7d43bbc61304d18955 refs/tags/tor-0.2.9.3-alpha^{}
+0049e8646ec26ba7802f5df95d90f436309a178b182f refs/tags/tor-0.2.9.4-alpha
+\r
+4c\r
+004c8b0755c9bb296ae210e83b88e099d52e40b6f2aa refs/tags/tor-0.2.9.4-alpha^{}
+\r
+49\r
+0049f4fa2728cea3de62384d93b08f725ad7dd6c4ded refs/tags/tor-0.2.9.5-alpha
+\r
+4c\r
+004c330846ac087f7b327d77e118a2bcf96839befc60 refs/tags/tor-0.2.9.5-alpha^{}
+\r
+d5\r
+00465f266efca92a7a153980e982fa96f59de271d9d9 refs/tags/tor-0.2.9.6-rc
+0049a3e07633a45d5c1609a6768347dfc92c06d19bcc refs/tags/tor-0.2.9.6-rc^{}
+0046e7aa6f24e72545d3796626ff843e5678b80b1019 refs/tags/tor-0.2.9.7-rc
+\r
+49\r
+00496b6ad81c2e140d8521307ff838f9068340e244f6 refs/tags/tor-0.2.9.7-rc^{}
+\r
+43\r
+0043fe61adc2e0bc5c66a72091945d39b4992b4c8c85 refs/tags/tor-0.2.9.8
+\r
+46\r
+004601ab67e38b358ae98775d1b30e5f83938af19d21 refs/tags/tor-0.2.9.8^{}
+\r
+d2\r
+00431b977b5c27269a24e5d994161419e9b39dbbb434 refs/tags/tor-0.2.9.9
+004656788a2489127072d513cf4baf35a8ff475f3c7b refs/tags/tor-0.2.9.9^{}
+0049117a829627d12fad51aa4e511051ee9f66b97559 refs/tags/tor-0.3.0.1-alpha
+\r
+4c\r
+004cac04fcd2e758c2258cbde8c8f31586695cb5d666 refs/tags/tor-0.3.0.1-alpha^{}
+\r
+cf\r
+00440c8cca0273a9221c92c842727590279da98aabc0 refs/tags/tor-0.3.0.10
+0047c33db290a9d8d0f921ef8ce0f49803748b5e47e0 refs/tags/tor-0.3.0.10^{}
+0044cf266cdb565173d08f68557dbfedccdb23b30299 refs/tags/tor-0.3.0.11
+\r
+47\r
+00475cb83c942584f86830ef1d13a9cd2501eea367c4 refs/tags/tor-0.3.0.11^{}
+\r
+44\r
+004488220f444421a442b143c012a0272a91d1c7e484 refs/tags/tor-0.3.0.12
+\r
+47\r
+0047700c654d70fa8dda393e471442d14aa8d74844aa refs/tags/tor-0.3.0.12^{}
+\r
+120\r
+00445873d18baafe84dcfc4198ae159c2ab2c4ab9b12 refs/tags/tor-0.3.0.13
+0047b734f871b75b2161c51b23c6fb0c39384d75c93b refs/tags/tor-0.3.0.13^{}
+0049486f9c366df2f8a83cb091ad7975579de662a64e refs/tags/tor-0.3.0.2-alpha
+004c0668d29354a874dc2b7e162f6fd9d34653fdd8ed refs/tags/tor-0.3.0.2-alpha^{}
+\r
+124\r
+0049be5595dfd28d71450de90469e41159f8485735e0 refs/tags/tor-0.3.0.3-alpha
+004cbb2ea3642d54ff03d7d60e593113f4e64e9e07ab refs/tags/tor-0.3.0.3-alpha^{}
+0046666648361882241c2a2b14d906afe4034e8a6cee refs/tags/tor-0.3.0.4-rc
+00494ed142ae9bb42f741b3626f83f89bc3a39af6a33 refs/tags/tor-0.3.0.4-rc^{}
+\r
+118\r
+0046c36117e0f532d4ee54ace037d86e3a0aabe34ead refs/tags/tor-0.3.0.5-rc
+00495eb2786600014d024484aa84d9ee42eed643798f refs/tags/tor-0.3.0.5-rc^{}
+0043ea4836aca2b380670fdb2d99dec77bd16761c0a2 refs/tags/tor-0.3.0.6
+004647d2e4f06ec26a79542865d054f01ea09304f59d refs/tags/tor-0.3.0.6^{}
+\r
+112\r
+00433ce804fb5841222728150913a083e7a04f006c66 refs/tags/tor-0.3.0.7
+0046cfd9c1bdc05826567a91ff89fd59c0cb70a436b2 refs/tags/tor-0.3.0.7^{}
+00435e8b686dfabcac87e7cdfe85cdc85dda1d563912 refs/tags/tor-0.3.0.8
+0046802d30d9b71a6d54ef5fd1278ab4858b2e76e750 refs/tags/tor-0.3.0.8^{}
+\r
+11e\r
+00432b04924993e52e210ef7429ec541bc064e0adc4c refs/tags/tor-0.3.0.9
+004622b3bf094e3270934ae0c66a38a0e656c1fd6d98 refs/tags/tor-0.3.0.9^{}
+0049a11e2547e4ce2467da71b5298ba2db987b846ae1 refs/tags/tor-0.3.1.1-alpha
+004c615dbdb0e094d4ef0b1982d06e62a8058463a28a refs/tags/tor-0.3.1.1-alpha^{}
+\r
+120\r
+00441317fba24cbb28d7609f9aa60f70ecf76d22983c refs/tags/tor-0.3.1.10
+0047e3966d47c72524091fb05faf214074f0a62d34cd refs/tags/tor-0.3.1.10^{}
+00496268b8db8e275804cf802ac59eba10780824f583 refs/tags/tor-0.3.1.2-alpha
+004c61625b8f26384a4a5d407db3f96e343c4dac36f8 refs/tags/tor-0.3.1.2-alpha^{}
+\r
+12a\r
+0049446bd9bea6a81d2539bf9f51be91aa27d85be46b refs/tags/tor-0.3.1.3-alpha
+004cdc47d936d47ffc25dc0b5e59009435cda542d240 refs/tags/tor-0.3.1.3-alpha^{}
+00496529ea60d116fdf454ee97266b33b1006a926270 refs/tags/tor-0.3.1.4-alpha
+004cfab91a290ded3e74e806cf9d05b36b6fcb695785 refs/tags/tor-0.3.1.4-alpha^{}
+\r
+95\r
+0049344a4d79577ff4a493a7a1bd98470b77bc42070f refs/tags/tor-0.3.1.5-alpha
+004c83389502ee6314658bcddd324c3652543b27da6b refs/tags/tor-0.3.1.5-alpha^{}
+\r
+1a1\r
+00461c2bc6befe6e156f4a3dc658380dab5d08659493 refs/tags/tor-0.3.1.6-rc
+0049efc306c59aa9ee1a32d1979df731f25904852709 refs/tags/tor-0.3.1.6-rc^{}
+0043358b2752cddc60fc902a5196f9c8b437493709fd refs/tags/tor-0.3.1.7
+00466babd3d9ba9318b38b5af7278875efe84055a1b0 refs/tags/tor-0.3.1.7^{}
+004378521ffe1304b278e3710d5823e824c1611c9c94 refs/tags/tor-0.3.1.8
+0046ad5027f7dc790624353ecd57796f572d5b55fa4c refs/tags/tor-0.3.1.8^{}
+\r
+89\r
+004350bcb7f32d9caf39799fe95757ed73fb43e27f1c refs/tags/tor-0.3.1.9
+0046727d3f1b5e6eeda721339151e3cd49ffa7efbb29 refs/tags/tor-0.3.1.9^{}
+\r
+95\r
+00496a10633a8fbef51c47cc5b18cd0146e05b8a50e9 refs/tags/tor-0.3.2.1-alpha
+004c290274dbb5428bc5d99926ce5d7f824165be84e8 refs/tags/tor-0.3.2.1-alpha^{}
+\r
+cf\r
+0044c4901d352f57461635d929b6da5c12133d0f4790 refs/tags/tor-0.3.2.10
+004731cc63deb69db819ed55aca406ebaaa52500730e refs/tags/tor-0.3.2.10^{}
+0044b48059c0aeecbb85906c9d49e49de64305d3d72d refs/tags/tor-0.3.2.11
+\r
+47\r
+0047ea3ecb98bd13b9eb4ef7e1ae1b08d7b12d0ffff9 refs/tags/tor-0.3.2.11^{}
+\r
+120\r
+0044fc764b75a962eb78349e68c39654df413d727379 refs/tags/tor-0.3.2.12
+0047a1507572110439604c9fc75168d0d1e585832a65 refs/tags/tor-0.3.2.12^{}
+00494b353217d27d9fc4f5275fc8b4fcc9a9538fa707 refs/tags/tor-0.3.2.2-alpha
+004ce2a2704f17415d8a63eceeaf5508174b1f66d1be refs/tags/tor-0.3.2.2-alpha^{}
+\r
+49\r
+0049642c5839e8552adf6689797fdde6fa59a084e632 refs/tags/tor-0.3.2.3-alpha
+\r
+4c\r
+004c023d756bfc04c244403ca7fb13e3e077dbe16408 refs/tags/tor-0.3.2.3-alpha^{}
+\r
+12a\r
+00491d0c4cd7ac08d35367c3bfc3f7c30d093ecf76af refs/tags/tor-0.3.2.4-alpha
+004c940308f493edd10ff8de2ef743e6872d1f8a4f9d refs/tags/tor-0.3.2.4-alpha^{}
+00496bd36d51e2f34fc69657478d5a10676ed311332f refs/tags/tor-0.3.2.5-alpha
+004cd499a5a708f7298b44dd02389412a0ce3b148f94 refs/tags/tor-0.3.2.5-alpha^{}
+\r
+95\r
+00497ea727bc4a474db39a66f31335fa270dd2312038 refs/tags/tor-0.3.2.6-alpha
+004c87012d076ef58bb9216c7952e0fd536f124aea68 refs/tags/tor-0.3.2.6-alpha^{}
+\r
+8f\r
+0046ff1308a0d348aa6c0549c40b57542e6d973224d2 refs/tags/tor-0.3.2.7-rc
+0049304e2151ac96bad8d5f27c63b070b06683d50665 refs/tags/tor-0.3.2.7-rc^{}
+\r
+d2\r
+004694639eefeb83c34555b47f01284ee3bebda0c0cf refs/tags/tor-0.3.2.8-rc
+004963b84335dc590499e5f22498383d6a3432e91ec4 refs/tags/tor-0.3.2.8-rc^{}
+004376adfe1e2a237a075dec48a22339b039fc5eb504 refs/tags/tor-0.3.2.9
+\r
+46\r
+00469e8b762fcecfece64aae70ae640aaa59fd227ca5 refs/tags/tor-0.3.2.9^{}
+\r
+e6\r
+004ded090af2f9fa8c1d9aa0dcbd6d9bc36f9b9c49f4 refs/tags/tor-0.3.3.0-alpha-dev
+0050e00f12ec6c6fda091bbf09d0bfeab057947d3808 refs/tags/tor-0.3.3.0-alpha-dev^{}
+004982a7c61520aaf80c6c767d6db4aef7da8bfe9d69 refs/tags/tor-0.3.3.1-alpha
+\r
+4c\r
+004cde8bc9eed6eaadfca33381e9b5b6c06fa432e7b5 refs/tags/tor-0.3.3.1-alpha^{}
+\r
+44\r
+00443ecde6e624baaea36dac83a7fb72878327937196 refs/tags/tor-0.3.3.10
+\r
+47\r
+00472e94df92caee0fca5e4f557bbc72b05db3364049 refs/tags/tor-0.3.3.10^{}
+\r
+116\r
+0044d0ccd6e86e73b99097043d5fddcb431cb078c4fc refs/tags/tor-0.3.3.11
+0047801af9a7e3f0f8c68294d8dd212b2eedcb481b72 refs/tags/tor-0.3.3.11^{}
+004448dfab9d646e7e3115552edd591a26c23c2d46ba refs/tags/tor-0.3.3.12
+0047f3e21c27631ee40603c1cab01b8e6b495689b69c refs/tags/tor-0.3.3.12^{}
+\r
+12a\r
+0049253088121f67fdbceac6df1f6a81d1e791234545 refs/tags/tor-0.3.3.2-alpha
+004cefc105716283bbdf44d73422b5036cb3a10c7950 refs/tags/tor-0.3.3.2-alpha^{}
+0049154d028b997301dac71677836b9407750f48bbf9 refs/tags/tor-0.3.3.3-alpha
+004cd15a7a27bb9e49bda7b3ec562e137ef3c50d64f6 refs/tags/tor-0.3.3.3-alpha^{}
+\r
+124\r
+0049c21e252d49e7f4ae7f3e1097a2607a0acda0bf3d refs/tags/tor-0.3.3.4-alpha
+004ca204a919f35441660f7b6f62e63610e75dea1e19 refs/tags/tor-0.3.3.4-alpha^{}
+004644e64d7db7d2185057a2bbf5f6d61eb9ca22a02b refs/tags/tor-0.3.3.5-rc
+004981d71f0d41adf0d8beb0ef1f7f750f20636d5c50 refs/tags/tor-0.3.3.5-rc^{}
+\r
+112\r
+0043b9599c8dbc92eebe4e11a7690211cd95d2c46232 refs/tags/tor-0.3.3.6
+00467dd0813e783ae16e6362e2e3c607476e645e2983 refs/tags/tor-0.3.3.6^{}
+004328f1b5b39048b123555c75ecf6e386c44eb577be refs/tags/tor-0.3.3.7
+0046035a35178c92da94400c13767a265053ff6c8413 refs/tags/tor-0.3.3.7^{}
+\r
+112\r
+0043d60cae78091ee5c404f85a57406006b46ce3397f refs/tags/tor-0.3.3.8
+004699f9816efa08ab83f90a307ea41844d693488fde refs/tags/tor-0.3.3.8^{}
+004390893b36d749eb2146d44278e67c1689246ffa2a refs/tags/tor-0.3.3.9
+004645028085ea188baf011524095e6fa3d55325ff49 refs/tags/tor-0.3.3.9^{}
+\r
+132\r
+004d92f717d9d88775e38c25fe4445658d439f38ec5a refs/tags/tor-0.3.4.0-alpha-dev
+0050cfff582e4d68b4026d19c4cee4c2d893aaab116f refs/tags/tor-0.3.4.0-alpha-dev^{}
+0049a5c317f8223b8b5bb535b8e8a71a1070b1722f36 refs/tags/tor-0.3.4.1-alpha
+004cdeb8970a29ef7427c3d42182d3bacc31ab602c03 refs/tags/tor-0.3.4.1-alpha^{}
+\r
+116\r
+0044a10a003f2ea485c68f0c271538a8765686af1409 refs/tags/tor-0.3.4.10
+00474f5ea89c117c66def603bc6f4d046e2142a76467 refs/tags/tor-0.3.4.10^{}
+0044b555ffe6d7946ed2dedc97465c11d1c444369e1c refs/tags/tor-0.3.4.11
+00474fd31340f3355342deebf49b586ae38bc2e9c8fe refs/tags/tor-0.3.4.11^{}
+\r
+12a\r
+00498af0e8664b30a9203a11deb87f60a4a0dc3c1cb7 refs/tags/tor-0.3.4.2-alpha
+004cbc951e83aac770d123118bf485d14490c2539048 refs/tags/tor-0.3.4.2-alpha^{}
+00499deb32bf8080cec38031a6eb944f10937d58af2b refs/tags/tor-0.3.4.3-alpha
+004ce8c256ca803b09879f52a641d8143543c22ac763 refs/tags/tor-0.3.4.3-alpha^{}
+\r
+11e\r
+00463140f6e65cec7f7d78320c73c8ce8519de6c671c refs/tags/tor-0.3.4.4-rc
+0049ab57cf6493f502abf7cc10bb800c0d01925bc0fc refs/tags/tor-0.3.4.4-rc^{}
+00469c5c315da325ea13bfbbfd47b8c693e036e21083 refs/tags/tor-0.3.4.5-rc
+0049673f3d640ef7fb05adf8533248d1b6bbbf086436 refs/tags/tor-0.3.4.5-rc^{}
+\r
+d5\r
+00462fac1059de5eaaa44a7b10f4cdf24c3c2f5a56cc refs/tags/tor-0.3.4.6-rc
+00496045c26d8442913e936e640fcf165ebfcc9d4bf1 refs/tags/tor-0.3.4.6-rc^{}
+00465a6462c3fe718c53e080a2193cc68808404690a4 refs/tags/tor-0.3.4.7-rc
+\r
+49\r
+00498465a8d84647c349d5995807b93a06f3afdd6185 refs/tags/tor-0.3.4.7-rc^{}
+\r
+43\r
+0043fd83f9f41758c02dcf0fd99d0d1da8c535af21d1 refs/tags/tor-0.3.4.8
+\r
+46\r
+0046da95b91355248ad8f3a6aa6733cc6d24915f59ce refs/tags/tor-0.3.4.8^{}
+\r
+126\r
+0043a2508bc8c163d371233994bfc4ba18a930229368 refs/tags/tor-0.3.4.9
+00464ac3ccf2863b86e79040dcd6c9568f011887c2be refs/tags/tor-0.3.4.9^{}
+004dee240d05bd9f99638b8f44f35d9eafb179758968 refs/tags/tor-0.3.5.0-alpha-dev
+0050e22822e4ae75dc59c7242d84bc306476fbd92a3b refs/tags/tor-0.3.5.0-alpha-dev^{}
+\r
+120\r
+004958eccf144654306e01c0658f4061b40436e70f92 refs/tags/tor-0.3.5.1-alpha
+004c1f9055c8845920e0aad8fc0cf3fd71b19905b2cb refs/tags/tor-0.3.5.1-alpha^{}
+00443d833dcbf1e4caa4a8e825b492b893d0caa65d0f refs/tags/tor-0.3.5.10
+004787fca699578e7190c37e68a290d72b4a77c2be40 refs/tags/tor-0.3.5.10^{}
+\r
+cf\r
+0044a5ef22b9784d4806f5346c2cca793ffbc43b2434 refs/tags/tor-0.3.5.11
+0047fc2d39af700f73859ab3e5fc5e627769867c89e4 refs/tags/tor-0.3.5.11^{}
+00449126a2ff04fa979b66bd6a40c0e1e208c18e021a refs/tags/tor-0.3.5.12
+\r
+47\r
+0047a0b827eb5b50aa818bef3a63644cf8756a53ad3f refs/tags/tor-0.3.5.12^{}
+\r
+44\r
+004432941c9c1dff5ddded6388655a395bd24870b6bc refs/tags/tor-0.3.5.13
+\r
+47\r
+0047fc4d5077482bf4c8ecf0a1aa52cec2baf4d0ca43 refs/tags/tor-0.3.5.13^{}
+\r
+44\r
+00448cc68168e60e6ee0759d172ebcecef8601ae458a refs/tags/tor-0.3.5.14
+\r
+a35\r
+004750d4300e77ea2f8f7d17aade1b9f32f38cffbcde refs/tags/tor-0.3.5.14^{}
+00497d56b346c008fa4e10098d3f3b4f1c7b77e79cc3 refs/tags/tor-0.3.5.2-alpha
+004ce62d92be5a9f1503d67d7d03e10eadcfc6be9b33 refs/tags/tor-0.3.5.2-alpha^{}
+0049dbdd5a8a265cbd1b3776e31d11d18e6636143580 refs/tags/tor-0.3.5.3-alpha
+004c444e9b37c53b0246158a4fca2e4e6e732deb8799 refs/tags/tor-0.3.5.3-alpha^{}
+00498238e34e3f09f0efd6a40c920161541233470b38 refs/tags/tor-0.3.5.4-alpha
+004ceca87ef7660ae0ba96b3f592e698e3f32f0c0357 refs/tags/tor-0.3.5.4-alpha^{}
+0049fe25ffe795c9343fa741f813da8202b474810091 refs/tags/tor-0.3.5.5-alpha
+004ca2ecc19ab923f34cc2363fa6f8c6e8d2bf9d350b refs/tags/tor-0.3.5.5-alpha^{}
+00469abbbf3846a84e647401f5057b0cece7b136d690 refs/tags/tor-0.3.5.6-rc
+0049a06093faaa65b0e0645f29c74abddcb42ac6e975 refs/tags/tor-0.3.5.6-rc^{}
+00437900101b25683548f79406f6c2879cf7f7d42473 refs/tags/tor-0.3.5.7
+00469beb085c10562a257c08abcee43434533d4fa96e refs/tags/tor-0.3.5.7^{}
+00431e3ece02bed4e14227125c087b73477c3c52e681 refs/tags/tor-0.3.5.8
+00465030edfb534245ed3f7e6b476f38a706247f3cb8 refs/tags/tor-0.3.5.8^{}
+004366042017aea0fdd005df5ac0e20ecfe1a839384f refs/tags/tor-0.3.5.9
+004672595eb021048ae9156185c0f75f19d000446f96 refs/tags/tor-0.3.5.9^{}
+00492ff016e0b8415cc2bacb09c865036a82862887b0 refs/tags/tor-0.4.0.1-alpha
+004c81f1b89efc94723f2c13b0b80d311364a2245d85 refs/tags/tor-0.4.0.1-alpha^{}
+0049d8facc02609fac2bc99ac8669d4010e28133f587 refs/tags/tor-0.4.0.2-alpha
+004cfeb744f0d488a0e5768385639311f50aab1f4f5d refs/tags/tor-0.4.0.2-alpha^{}
+0049b5481360a414e3de784001290f71bef8be2add1c refs/tags/tor-0.4.0.3-alpha
+004ceaa34dd6b9cf3ce99e153b175177842f56ef1d1f refs/tags/tor-0.4.0.3-alpha^{}
+00467c686230efa8bd7ceb4ed2a34b5f3049964bc8c4 refs/tags/tor-0.4.0.4-rc
+0049dac18e0b2085814c32070d603c4c94297ee778cc refs/tags/tor-0.4.0.4-rc^{}
+00431019a6b0c9b17e07fc160fa9bb2a5ece88024d94 refs/tags/tor-0.4.0.5
+0046bf071e34aa26e0965910d1adf424e8134b8d45d6 refs/tags/tor-0.4.0.5^{}
+004398cb58b15830539ef8eebd5c9813dabe036350cf refs/tags/tor-0.4.0.6
+004639344e410dca1dd4fda83034e725afa45a0c0bf4 refs/tags/tor-0.4.0.6^{}
+004d8ed8134587c4091280d1d2f5c101e9faa629075c refs/tags/tor-0.4.1.0-alpha-dev
+00509a158a45b1fe9f36cf0d41c5d1dcec7be74f1719 refs/tags/tor-0.4.1.0-alpha-dev^{}
+0049040efa08ecb69714ebc56237a09d3e00fe3346f9 refs/tags/tor-0.4.1.1-alpha
+004cfa410162a3309dba31661f7f22c95bbdc3af66a5 refs/tags/tor-0.4.1.1-alpha^{}
+0049cf62509fe0e28a69b4ff7c25f7b5f22d5cba9b38 refs/tags/tor-0.4.1.2-alpha
+004c3c2b2f072f996ba958ed5b6e07d3bac02291fc4a refs/tags/tor-0.4.1.2-alpha^{}
+004904e042cc926f1d651a32b83c36fb7b5b390ac235 refs/tags/tor-0.4.1.3-alpha
+\r
+41d\r
+004cd2c360c5336b43ba89c077f55461227420d14647 refs/tags/tor-0.4.1.3-alpha^{}
+00467bff1c1a1e0fd570e971df101ba37a208e3bff74 refs/tags/tor-0.4.1.4-rc
+0049716c48c250ed74a1d83e5c1c2d95ddd395c07a7e refs/tags/tor-0.4.1.4-rc^{}
+0043479fc3688b416dc2f7d2729bd2cfc244dc58b521 refs/tags/tor-0.4.1.5
+0046439ca48989ece545c3bb247640ffcde5ea368adf refs/tags/tor-0.4.1.5^{}
+004328fe861a22bd200e0ab7a0d2eea4844720673928 refs/tags/tor-0.4.1.6
+0046d10abc0929f4941d564b72a349aaf421aaa268f3 refs/tags/tor-0.4.1.6^{}
+00436473162d97a7c0c18e04bd41360d94ff6994d044 refs/tags/tor-0.4.1.7
+00460772f901b4b3b74077658c7b9585ee5ab947ad64 refs/tags/tor-0.4.1.7^{}
+0043bd3ccacd21c10c2e711568e7b40e584fe16b7a5d refs/tags/tor-0.4.1.8
+0046de79264c1d697b16ba434d111a39161757d33225 refs/tags/tor-0.4.1.8^{}
+00439fb41b8cb72a00a8be49eb893e42493dfbe53e6b refs/tags/tor-0.4.1.9
+004693ed011a26757b71630e7b61aee947337f6d4b0b refs/tags/tor-0.4.1.9^{}
+0049138e3590a1a613fe5d32b53537d92ee7cd0e5207 refs/tags/tor-0.4.2.1-alpha
+004cb5f39955d1ad14295a9ef415d13a8c6bfd25f8b9 refs/tags/tor-0.4.2.1-alpha^{}
+\r
+95\r
+0049386a0f07fb7def840f8b26859c96b03a4c15f2ec refs/tags/tor-0.4.2.2-alpha
+004caa56465934da31eeab79376a2ab690c5f28b4aa0 refs/tags/tor-0.4.2.2-alpha^{}
+\r
+2bf\r
+004965d75eb6f76a91f663a567775f487d5d87656036 refs/tags/tor-0.4.2.3-alpha
+004c80bfc47198d04c20b853267c3a7b95358ca6478f refs/tags/tor-0.4.2.3-alpha^{}
+00462610120b57238918438ba0f0c59314815df1d1e4 refs/tags/tor-0.4.2.4-rc
+00496a490d3032fa8d368bb54bd479b61c2bcbd45c8f refs/tags/tor-0.4.2.4-rc^{}
+00436c086a90d0f34198f1042cc4ea90064eb550b67a refs/tags/tor-0.4.2.5
+0046bede4ea1008920d8b1b9ea72b0f44cb2ea4dbc6b refs/tags/tor-0.4.2.5^{}
+0043c1ae070a3c2aa5b12d8e411d467f1e216fe700d0 refs/tags/tor-0.4.2.6
+0046971a6beff5a5343415371f7183987e1625bc9565 refs/tags/tor-0.4.2.6^{}
+00433cad484e3b2d481de39d6428b4d91f5d9010b824 refs/tags/tor-0.4.2.7
+004674cad14699087b7ee0b6b17927a3f64683fe31e9 refs/tags/tor-0.4.2.7^{}
+\r
+16f\r
+0043e389ed9a20aebb982e051a421a6293fe8c51c007 refs/tags/tor-0.4.2.8
+0046f945751265a140654fdc1a3e900db9affd60ae69 refs/tags/tor-0.4.2.8^{}
+004d38273e803acb0510190d5154f9133fbea939b74f refs/tags/tor-0.4.3.0-alpha-dev
+005061fe3f448c1c60b6681797feebf2611e458adc47 refs/tags/tor-0.4.3.0-alpha-dev^{}
+004951414ca08cf6502054b5078a88433a35d23a70a7 refs/tags/tor-0.4.3.1-alpha
+\r
+4c\r
+004c6166af5077f5d3a269d9c6c489177e112a206d2d refs/tags/tor-0.4.3.1-alpha^{}
+\r
+49\r
+0049e7f8ccbcaeb17d96f16638bd9d6075071cc28f49 refs/tags/tor-0.4.3.2-alpha
+\r
+4c\r
+004cdcbf6611d998095364f670e26106019fc3e098d2 refs/tags/tor-0.4.3.2-alpha^{}
+\r
+124\r
+0049546b96026cc991b0f70e4b84dfb7af45508581f1 refs/tags/tor-0.4.3.3-alpha
+004c27cc9093af1c7f7862fb242d4de9bd27a046831c refs/tags/tor-0.4.3.3-alpha^{}
+00465c004d327fcd29865fa3909d378d2ae2e4912836 refs/tags/tor-0.4.3.4-rc
+0049251efd11e77df6c27fec9cb75c65fa614a063a74 refs/tags/tor-0.4.3.4-rc^{}
+\r
+112\r
+0043cd2c5416ba9f83b239ae85663aa47d102b3415e1 refs/tags/tor-0.4.3.5
+00465ceb60e5ca61fec9f67c1fcae4d80d0c98e7104c refs/tags/tor-0.4.3.5^{}
+0043a65375c49c43cb374c6eb4b466c22997fd9a5378 refs/tags/tor-0.4.3.6
+004630711296fd5b7f51ef6f4d7b3fbe20f12990c02c refs/tags/tor-0.4.3.6^{}
+\r
+112\r
+00431129919119c028e3b2ad255c73a36fbbd6effe93 refs/tags/tor-0.4.3.7
+004626465179fa13b3127cc127d9a598a4b3da524133 refs/tags/tor-0.4.3.7^{}
+0043c980952a713c290370e9d2572aba4fa2aa1b59fa refs/tags/tor-0.4.3.8
+00465b0fe0ee8aec0d704809a17ba9c64bf94993c668 refs/tags/tor-0.4.3.8^{}
+\r
+132\r
+004d32d0e194fab6b04549b66d684d52ae9d6bbd6beb refs/tags/tor-0.4.4.0-alpha-dev
+005071d96cefc0314bc3ad6cad867586c492a287c6c9 refs/tags/tor-0.4.4.0-alpha-dev^{}
+00498d0faa0b6227243723a2b8aa7f3da51b67f495cb refs/tags/tor-0.4.4.1-alpha
+004c5277f1aad03a2717ee69861a4c4f8e233e815029 refs/tags/tor-0.4.4.1-alpha^{}
+\r
+49\r
+004932351f0e0bc31232bdb7542a1a6df60b1c0d5d56 refs/tags/tor-0.4.4.2-alpha
+\r
+4c\r
+004c50b503a9f90f67e7898efdb560e5fdb577f1a1c6 refs/tags/tor-0.4.4.2-alpha^{}
+\r
+124\r
+004927c66ce30b5d482de6c2c853511d8e4d65bd53b7 refs/tags/tor-0.4.4.3-alpha
+004cc968889a09c453f25ab3b07f1d70e0743eb76b66 refs/tags/tor-0.4.4.3-alpha^{}
+0046389d2afe918a1c0a71f7b2b35c4dfcd0911bec35 refs/tags/tor-0.4.4.4-rc
+00498bd79bd75e760e7493c2fc7dcf5b38d453ea9f13 refs/tags/tor-0.4.4.4-rc^{}
+\r
+112\r
+0043d5e2cac540c142facfe0c0fce49c386df61b33c5 refs/tags/tor-0.4.4.5
+004624e808e946e741d01ed25673fa4d47531858fdb4 refs/tags/tor-0.4.4.5^{}
+00434ffe21f0dea1314c2643f4701b03860a746b26ca refs/tags/tor-0.4.4.6
+00462a8b789ea6f308d081f369d78fa7cfdc9d00bf90 refs/tags/tor-0.4.4.6^{}
+\r
+43\r
+004388b68db04dd09991bf19ab92f6a9f3aad2e5e6ca refs/tags/tor-0.4.4.7
+\r
+46\r
+004637a32b7ee76e5d52439eb840e1087b2fd02dd15a refs/tags/tor-0.4.4.7^{}
+\r
+43\r
+00438408949902514562eecb17d95ecdd2f5957a00f9 refs/tags/tor-0.4.4.8
+\r
+486\r
+0046fecc19529452fcd682272768f17147f4eed360a7 refs/tags/tor-0.4.4.8^{}
+004d397f8b98f79d71ca58eca14d570593ee4d46649d refs/tags/tor-0.4.5.0-alpha-dev
+0050d2f136aab1f7d76a458e834bd791cbb887c96b51 refs/tags/tor-0.4.5.0-alpha-dev^{}
+00499c403ba25916f1fb49727025b37306d48469c56f refs/tags/tor-0.4.5.1-alpha
+004c26679713367b34188e034de1a90a424440294633 refs/tags/tor-0.4.5.1-alpha^{}
+0049e07b657017911805d46889c82cabcb5b6ca0f1a6 refs/tags/tor-0.4.5.2-alpha
+004c135b8eea36edd992d0a0c3e9b6d88c013dc3fe48 refs/tags/tor-0.4.5.2-alpha^{}
+0046bfa68cf08659447a4ec922f981a51323d8ead62f refs/tags/tor-0.4.5.3-rc
+0049e5c47d295bd3dc35f75c7d5c1753c650fd912640 refs/tags/tor-0.4.5.3-rc^{}
+00466508c2bcf9b90cd6a61e7b68a9fedf06e3bf189e refs/tags/tor-0.4.5.4-rc
+00499e26a9399fe2422475406d6ee3cb29b2924f3274 refs/tags/tor-0.4.5.4-rc^{}
+00467ba8d2ba25c5ff39cadddc3ed938e753019d9286 refs/tags/tor-0.4.5.5-rc
+0049b36a00e9a9d3eb4b2949951afaa72e45fb7e68cd refs/tags/tor-0.4.5.5-rc^{}
+0043a1a4c522be022b7080a9a4cc8660e17c15c8def8 refs/tags/tor-0.4.5.6
+0046ae1466e103a5b8bcbf3f561abf0379e535f54cf0 refs/tags/tor-0.4.5.6^{}
+0043d1a799f509629d559e5c257a4aa4c7111f47a903 refs/tags/tor-0.4.5.7
+\r
+e3\r
+004683f895c015de55201e5f226f84a866f30f5ee14b refs/tags/tor-0.4.5.7^{}
+004d824d606db299133aa0efea8d2f067bd20fa249b2 refs/tags/tor-0.4.6.0-alpha-dev
+0050aed2a48c664dad17f58f51c161731a62f876a706 refs/tags/tor-0.4.6.0-alpha-dev^{}
+\r
+49\r
+0049d06d6a532a59320be1fea6f26784515856fa1e17 refs/tags/tor-0.4.6.1-alpha
+\r
+4c\r
+004ccd0e5a942eee0f08f4311899c09c6783b2c8e22c refs/tags/tor-0.4.6.1-alpha^{}
+\r
+4\r
+0000\r
+0\r
+\r
+</data>
+<servercmd>
+writesize: 200
+writedelay: 10
+</servercmd>
+</reply>
+
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Git server response with multiple chunks.
+</name>
+<features>
+proxy
+</features>
+<command>
+--raw http://%HOSTIP:%HTTPPORT/git/tor/info/refs?service=git-upload-pack/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /git/tor/info/refs?service=git-upload-pack/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test35 b/tests/cts/chunked-transfer-encoding/data/test35
new file mode 100644 (file)
index 0000000..fb8ad9b
--- /dev/null
@@ -0,0 +1,83 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+# XXX: Test requires "writesize" support that hasn't been upstreamed yet.
+skip
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: keep-alive\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+\r
+FE\r
+%repeat[253 x A]%
+\r
+XYZ\r
+This chunk is preceded by an invalid chunk-size
+%repeat[1000 x Padding]%
+\r
+0\r
+\r
+</data>
+# We only send parts of the response and then wait longer
+# than Privoxy's socket-timeout to make sure Privoxy always
+# forwards the same data to curl.
+<servercmd>
+writesize: 4000
+writedelay: 4000
+</servercmd>
+</reply>
+
+<proxy-reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: keep-alive\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+\r
+FE\r
+%repeat[253 x A]%
+\r
+XYZ\r
+This chunk is preceded by an invalid chunk-size
+%repeat[507 x Padding]%Paddi
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Invalid chunk-size. Filtering disabled.
+</name>
+<features>
+proxy
+</features>
+<command timeout="20">
+--raw http://%HOSTIP:%HTTPPORT/no-filter/chunked-content/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /no-filter/chunked-content/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+56
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test36 b/tests/cts/chunked-transfer-encoding/data/test36
new file mode 100644 (file)
index 0000000..2971b86
--- /dev/null
@@ -0,0 +1,77 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+# XXX: Test requires "writesize" support that hasn't been upstreamed yet.
+skip
+</keywords>
+</info>
+
+<reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: keep-alive\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+\r
+FE\r
+%repeat[253 x A]%
+\r
+A The previous size could be valid but the line does not end with CRLF %repeat[1000 x Padding]%
+</data>
+# We only send parts of the response and then wait longer
+# than Privoxy's socket-timeout to make sure Privoxy always
+# forwards the same data to curl.
+<servercmd>
+writesize: 4000
+writedelay: 4000
+</servercmd>
+</reply>
+<reply>
+
+<proxy-reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: keep-alive\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+\r
+FE\r
+%repeat[253 x A]%
+\r
+A The previous size could be valid but the line does not end with CRLF %repeat[505 x Padding]%P
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Invalid chunk-size line. Filtering disabled.
+</name>
+<features>
+proxy
+</features>
+<command timeout="20">
+--raw http://%HOSTIP:%HTTPPORT/no-filter/chunked-content/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /no-filter/chunked-content/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+18
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test37 b/tests/cts/chunked-transfer-encoding/data/test37
new file mode 100644 (file)
index 0000000..48817e9
--- /dev/null
@@ -0,0 +1,52 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+\r
+88888888888\r
+The chunk-size for this chunk causes an integer overflow.
+swsclose
+</data>
+</reply>
+<reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Invalid chunk-size that causes integer overflow.
+</name>
+<features>
+proxy
+</features>
+<command>
+--raw http://%HOSTIP:%HTTPPORT/no-filter/chunked-content/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /no-filter/chunked-content/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+18
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test38 b/tests/cts/chunked-transfer-encoding/data/test38
new file mode 100644 (file)
index 0000000..b4305c0
--- /dev/null
@@ -0,0 +1,116 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: keep-alive\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+\r
+12345\r
+%repeat[74564 x A]%
+\r
+67891\r
+%repeat[424080 x B]%
+\r
+31337\r
+%repeat[201526 x C]%
+\r
+31337\r
+%repeat[201526 x D]%
+\r
+31337\r
+%repeat[201526 x E]%
+\r
+0\r
+\r
+</data>
+<data1>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+X-Connection: swsclose\r
+Content-Type: text/html\r
+\r
+Here's your unchunked data.
+</data1>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: keep-alive\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+\r
+12345\r
+%repeat[74564 x A]%
+\r
+67891\r
+%repeat[424080 x B]%
+\r
+31337\r
+%repeat[201526 x C]%
+\r
+31337\r
+%repeat[201526 x D]%
+\r
+31337\r
+%repeat[201526 x E]%
+\r
+0\r
+\r
+</data>
+<data1>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+X-Connection: swsclose\r
+Content-Type: text/html\r
+\r
+Here's your unchunked data.
+</data1>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Multiple largish chunks on connection that is kept alive. Filtering enabled but content too large to buffer.
+</name>
+<features>
+proxy
+</features>
+<command>
+--max-time 20 --raw http://%HOSTIP:%HTTPPORT/chunked-transfer-encoding/%TESTNUMBER0000 --raw http://%HOSTIP:%HTTPPORT/unchunked-content/%TESTNUMBER0001
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER0000 HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+GET /unchunked-content/%TESTNUMBER0001 HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test39 b/tests/cts/chunked-transfer-encoding/data/test39
new file mode 100644 (file)
index 0000000..3c9ada4
--- /dev/null
@@ -0,0 +1,81 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+# XXX: Test requires "writesize" support that hasn't been upstreamed yet.
+skip
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: keep-alive\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+\r
+12345\r
+%repeat[74564 x A]%
+\r
+67891\r
+%repeat[424080 x B]%
+\r
+31337\r
+%repeat[201526 x C]%
+\r
+1d4c0\r
+%repeat[120000 x D]%
+\r
+0\r
+\r
+</data>
+<data1>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+X-Connection: swsclose\r
+Content-Type: text/html\r
+\r
+Here's your unchunked data.
+</data1>
+<servercmd>
+writesize: 5000
+</servercmd>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Multiple largish chunks on connection that is kept alive. Filtering enabled but content too large to buffer. Last-chunk arrives when reaching the buffer limit.
+</name>
+<features>
+proxy
+</features>
+<command>
+--max-time 20 --raw http://%HOSTIP:%HTTPPORT/chunked-transfer-encoding/%TESTNUMBER0000 --raw http://%HOSTIP:%HTTPPORT/unchunked-content/%TESTNUMBER0001
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER0000 HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+GET /unchunked-content/%TESTNUMBER0001 HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test4 b/tests/cts/chunked-transfer-encoding/data/test4
new file mode 100644 (file)
index 0000000..8ed59e4
--- /dev/null
@@ -0,0 +1,70 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+123\r
+This chunk is too small
+0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+123\r
+This chunk is too small
+0\r
+\r
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Single chunk that is too small
+</name>
+<features>
+proxy
+</features>
+<command>
+--raw http://%HOSTIP:%HTTPPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+18
+</errorcode>
+</verify>
+
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test40 b/tests/cts/chunked-transfer-encoding/data/test40
new file mode 100644 (file)
index 0000000..2fff0e7
--- /dev/null
@@ -0,0 +1,57 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: keep-alive\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+\r
+A\r
+%repeat[9 x A]%
+\r
+0\r
+\r
+</data>
+<servercmd>
+writesize: 150
+writedelay: 20
+</servercmd>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Small chunks on connection that is kept alive, last chunk partially received with server headers.
+</name>
+<features>
+proxy
+</features>
+<command>
+--max-time 20 --raw http://%HOSTIP:%HTTPPORT/no-filter/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /no-filter/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test41 b/tests/cts/chunked-transfer-encoding/data/test41
new file mode 100644 (file)
index 0000000..1808f2b
--- /dev/null
@@ -0,0 +1,61 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: keep-alive\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+\r
+0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: keep-alive\r
+Content-Type: text/html\r
+Content-Length: 0\r
+\r
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Only last chunk with connection keep-alive, no actual data.
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test42 b/tests/cts/chunked-transfer-encoding/data/test42
new file mode 100644 (file)
index 0000000..80599e4
--- /dev/null
@@ -0,0 +1,65 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: keep-alive\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+\r
+0\r
+\r
+</data>
+<servercmd>
+writedelay: 20
+writesize: 136
+</servercmd>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: keep-alive\r
+Content-Type: text/html\r
+Content-Length: 0\r
+\r
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Only last chunk that partially arrives with server headers with connection keep-alive, no actual data.
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test43 b/tests/cts/chunked-transfer-encoding/data/test43
new file mode 100644 (file)
index 0000000..d53c8e3
--- /dev/null
@@ -0,0 +1,61 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+# Does not work yet
+skip
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: keep-alive\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+\r
+0\r
+\r
+</data>
+<servercmd>
+writedelay: 20
+writesize: 136
+</servercmd>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Only last chunk that partially arrives with server headers with connection keep-alive, no actual data. Filtering disabled.
+</name>
+<features>
+proxy
+</features>
+<command>
+--raw http://%HOSTIP:%HTTPPORT/no-filter/%TESTNUMBER --max-time 2 --raw http://%HOSTIP:%HTTPPORT/no-filter/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /no-filter/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+GET /no-filter/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test44 b/tests/cts/chunked-transfer-encoding/data/test44
new file mode 100644 (file)
index 0000000..a9a2a03
--- /dev/null
@@ -0,0 +1,64 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+# Does not work yet
+skip
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: keep-alive\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+\r
+FE\r
+%repeat[253 x A]%
+\r
+0\r
+\r
+</data>
+<servercmd>
+writedelay: 20
+writesize: 136
+</servercmd>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Multiple chunks, first chunk partially arrives with server headers with connection keep-alive. Filtering disabled.
+</name>
+<features>
+proxy
+</features>
+<command>
+--raw http://%HOSTIP:%HTTPPORT/no-filter/%TESTNUMBER --max-time 2 --raw http://%HOSTIP:%HTTPPORT/no-filter/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /no-filter/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+GET /no-filter/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test45 b/tests/cts/chunked-transfer-encoding/data/test45
new file mode 100644 (file)
index 0000000..484e820
--- /dev/null
@@ -0,0 +1,2267 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+# Skip the test as it's know to fail
+skip
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Tue, 30 Mar 2021 08:22:13 GMT\r
+Server: Apache\r
+Expires: Fri, 01 Jan 1980 00:00:00 GMT\r
+Pragma: no-cache\r
+Cache-Control: no-cache, max-age=0, must-revalidate\r
+X-Content-Type-Options: nosniff\r
+X-Frame-Options: sameorigin\r
+X-Xss-Protection: 1\r
+Referrer-Policy: no-referrer\r
+Strict-Transport-Security: max-age=15768000; preload\r
+Transfer-Encoding: chunked\r
+Content-Type: application/x-git-upload-pack-advertisement\r
+\r
+22\r
+001e# service=git-upload-pack
+0000\r
+fa\r
+00fa769d54c5d7933ccb4c8638e71ce4b928298ac66a HEAD%hex[%00]hex%multi_ack thin-pack side-band side-band-64k ofs-delta shallow deepen-since deepen-not deepen-relative no-progress include-tag multi_ack_detailed no-done symref=HEAD:refs/heads/master agent=git/2.20.1
+\r
+110\r
+00448608e6823e12856f0c3ca432587c950e0ddb3044 refs/heads/maint-0.1.2
+0044b1859cab2568fa27360a35f2cd906a7dfa4a38c8 refs/heads/maint-0.2.0
+00444180624a7d5a3e528be2cf2fe7f9f673b3964a23 refs/heads/maint-0.2.1
+00443b0265198fc8a55279f2a8501104d2c54900c9d0 refs/heads/maint-0.2.2
+\r
+44\r
+0044e5907e94c225cabec1f5cf94870c424fc1767c7e refs/heads/maint-0.2.3
+\r
+15a\r
+00446199e27a2b4ce4d56a1de9cf35ff09f79c9b6624 refs/heads/maint-0.2.4
+00441fa396b0a49448103ad16cb411163e6f5d741cc0 refs/heads/maint-0.2.5
+00446862eada65a6f41304b32c3d4fca3da9c240d5bd refs/heads/maint-0.2.6
+0044e6376a8004072fde832da77aa6369075dcdcbe8b refs/heads/maint-0.2.7
+004aa48ae2aa67b31cc97942ac2c7fd6f29beba59e3b refs/heads/maint-0.2.7-redux
+\r
+cc\r
+00447d845976e3897fac8e78a4a26688ac57b660151b refs/heads/maint-0.2.8
+004437b04aeed7d6c7acb8b7edf2bcd6ee08f9c3a54c refs/heads/maint-0.2.9
+0044b39c50cde8b1d7e3e27d5a6fc2e58ff208982637 refs/heads/maint-0.3.0
+\r
+44\r
+00442968c716d7689eafcf32a1f5327af7b1ad1582ce refs/heads/maint-0.3.1
+\r
+44\r
+00445b04392c1553e2a3e278a48f8d0e071181c0444f refs/heads/maint-0.3.2
+\r
+44\r
+00440c9cd7c487ac75d9505f46e5ff42087d383eb1b4 refs/heads/maint-0.3.3
+\r
+44\r
+0044a521c427883697fcfa027ffd72bb38f3aee5aceb refs/heads/maint-0.3.4
+\r
+44\r
+00443271c0bde782769ba30685ca8907240328f771c9 refs/heads/maint-0.3.5
+\r
+154\r
+0044f3fa22bf1b52dfce65a37e6a84bac8635916e8c2 refs/heads/maint-0.4.0
+0044768ffb8f43575baac0970659b01e0a484d6bd6de refs/heads/maint-0.4.1
+004445d983049382e09d14d5047f9eef941d089e9fb7 refs/heads/maint-0.4.2
+00448a17999da3626a5f9e8922277151624cd0526fba refs/heads/maint-0.4.3
+00449ca2394d6b51242bb5cf380757be5869d2a44c3c refs/heads/maint-0.4.4
+\r
+c9\r
+0044c359c3056b2dbf17987a8955af30884ee438108e refs/heads/maint-0.4.5
+003f769d54c5d7933ccb4c8638e71ce4b928298ac66a refs/heads/master
+00467da1ae7adf150271a947997a1340f62b990c974d refs/heads/release-0.2.1
+\r
+8c\r
+0046bec76476efb715498b86282d4969c096df336140 refs/heads/release-0.2.2
+004643836f6f0ab7c25b0c8c9fab366ec664ebd0b0ee refs/heads/release-0.2.3
+\r
+118\r
+0046af082895ec3ca700a329d22c46ec454a65b31703 refs/heads/release-0.2.4
+0046279fa65d34bbb41d1428eb62f6172b218598644e refs/heads/release-0.2.5
+00463ae8b32cc97431ff29f1a0dab2b30c7f35038ac9 refs/heads/release-0.2.6
+0046e83affb56fa001d1c27f16e30e6c23c88ff165f5 refs/heads/release-0.2.7
+\r
+4c\r
+004cb05bb04a829250d795e4e81c9228dff57cbad7a5 refs/heads/release-0.2.7-redux
+\r
+8c\r
+004689f40ba97a752f125ef7dbb057d64dd5e06a95db refs/heads/release-0.2.8
+004638cc3a45b655a07f8834ddcd1514f04b09bd80a0 refs/heads/release-0.2.9
+\r
+46\r
+0046d07e069c97ac5f9e0c9a593b7ec84c540b310f0f refs/heads/release-0.3.0
+\r
+46\r
+004601baad0a63780d42e01629777058c3b7f240a9bd refs/heads/release-0.3.1
+\r
+46\r
+0046bf2ffd39781664b6b29a57a1dd1d110368f120ce refs/heads/release-0.3.2
+\r
+8c\r
+00460e74894c5db305a75914bea769d5b1db00d8f792 refs/heads/release-0.3.3
+0046e2dde342b240039c9d4a254a2313fa9ab53d49d7 refs/heads/release-0.3.4
+\r
+46\r
+00461693b6151e1369ce0938761cac95e7a0a524f5f3 refs/heads/release-0.3.5
+\r
+46\r
+0046ed2cbbf71680fd2be67eb7b74c44572e58895d72 refs/heads/release-0.4.0
+\r
+46\r
+0046d97fd7f0762603702179bf2742e0fe5fc66bedbf refs/heads/release-0.4.1
+\r
+46\r
+00465b345c693e73ad636a3dce9ca1e8622e1df8ed26 refs/heads/release-0.4.2
+\r
+46\r
+00461c5dd021a7666806284b851ecb1879704df8020e refs/heads/release-0.4.3
+\r
+46\r
+004644df63e591feec5d5ae5c4a838664997bc64f489 refs/heads/release-0.4.4
+\r
+46\r
+0046c40b729c85ff45501523cbcd37f603aceeea4774 refs/heads/release-0.4.5
+\r
+b5\r
+0059e9313d995ba058b8a1edacbd6b3504f3551d0c76 refs/tags/debian-version-0.0.1+0.0.2pre19-1
+005c9c8876be146a6f8566891fa84e05e1b60238508a refs/tags/debian-version-0.0.1+0.0.2pre19-1^{}
+\r
+b5\r
+0059ff70bb7b40bc104aee55cefa2e298a8e62b2d91e refs/tags/debian-version-0.0.1+0.0.2pre20-1
+005c4e7a2a01741d4ffb4bbe3385e20282a738331aef refs/tags/debian-version-0.0.1+0.0.2pre20-1^{}
+\r
+b5\r
+005905963d37bcbab56bc71448c03b4a347f90676a33 refs/tags/debian-version-0.0.1+0.0.2pre20-2
+005ccb34be367fd9722885d02fcaf65338a270478c08 refs/tags/debian-version-0.0.1+0.0.2pre20-2^{}
+\r
+59\r
+005938270f20bc917516a9ee69be785194a75928b4c6 refs/tags/debian-version-0.0.1+0.0.2pre21-1
+\r
+5c\r
+005ca1b6ce0580ab1330ffd0bdc6ec2f32eabac01057 refs/tags/debian-version-0.0.1+0.0.2pre21-1^{}
+\r
+10e\r
+0059e6c1eb4b697896d21ffb9428986b161d877cfff4 refs/tags/debian-version-0.0.1+0.0.2pre22-1
+005c2849ff13e286b773a483849ad374aaa63d0e5bca refs/tags/debian-version-0.0.1+0.0.2pre22-1^{}
+0059e34683c4b24bf9dec299764d0ed7de9e7c68be57 refs/tags/debian-version-0.0.1+0.0.2pre23-1
+\r
+5c\r
+005c247fe31af2f88ebb687ee08eeb8d7942b52ba853 refs/tags/debian-version-0.0.1+0.0.2pre23-1^{}
+\r
+16a\r
+0059dd3e677ca2d9b40b807d0db68b60a308736267f3 refs/tags/debian-version-0.0.1+0.0.2pre24-1
+005c3e452fed5446f3e744bf7ea321f6b24e01c97578 refs/tags/debian-version-0.0.1+0.0.2pre24-1^{}
+00590ac579c5780021c57e7e15fa59eaea8571093a96 refs/tags/debian-version-0.0.1+0.0.2pre25-1
+005ce0b1aaabe769b8f8c773d964d00936e1c20126d7 refs/tags/debian-version-0.0.1+0.0.2pre25-1^{}
+\r
+10e\r
+00591050e2af36656e480ce429a053ee1451c3fc6268 refs/tags/debian-version-0.0.1+0.0.2pre26-1
+005cea0c5db22892ab11a7a743713438121e295941a1 refs/tags/debian-version-0.0.1+0.0.2pre26-1^{}
+0059c10dbc774a2d017367383a33c1d7ecccb78e9554 refs/tags/debian-version-0.0.1+0.0.2pre27-1
+\r
+5c\r
+005c39835dd9f69c3244f7d2e371196752939f19c638 refs/tags/debian-version-0.0.1+0.0.2pre27-1^{}
+\r
+13e\r
+004e88c086d403ea690346855eca70c8d7a8389608c0 refs/tags/debian-version-0.0.2-1
+005151750ae09a162bd9de70e9163213d3a07788ea9d refs/tags/debian-version-0.0.2-1^{}
+004edc59d84c4cc17cf541fb62bcc96aca693b8507a0 refs/tags/debian-version-0.0.3-1
+0051c940e2644a8629711ba8d33703a40f70b0e76ee2 refs/tags/debian-version-0.0.3-1^{}
+\r
+f6\r
+004e88a02d21ed0463c733cdd1d843ac78fa536f449d refs/tags/debian-version-0.0.4-1
+0051d324e835207432cdfc9ede2d309051d97c57066d refs/tags/debian-version-0.0.4-1^{}
+005739da29283eece63134bc11191b11879dd57bd8b4 refs/tags/debian-version-0.0.5+0.0.6rc2-1
+\r
+5a\r
+005a2b1441e49faf75133fc2a4db900a3f0f01075b65 refs/tags/debian-version-0.0.5+0.0.6rc2-1^{}
+\r
+b1\r
+0057e8df6c4e8dcf298c28bf9eeb3525b0a0e2225510 refs/tags/debian-version-0.0.5+0.0.6rc3-1
+005a3c2659e763d7eed65bd898a868bd7614d4a0d7d9 refs/tags/debian-version-0.0.5+0.0.6rc3-1^{}
+\r
+b1\r
+00574d068d9761666be76d4298db4d22839e13700d2e refs/tags/debian-version-0.0.5+0.0.6rc4-1
+005a334fb4e8f64097417dc31c18cb6d7038ad37f5ce refs/tags/debian-version-0.0.5+0.0.6rc4-1^{}
+\r
+9f\r
+004e358b9a26f4b7cc65d6ea6938d1c5a3baa94fd86d refs/tags/debian-version-0.0.5-1
+0051b1e98321365bd3080f176d38d4e71b6114d6517d refs/tags/debian-version-0.0.5-1^{}
+\r
+142\r
+004e2ff0ef7e1cda1aa77c4fb867f5e0e3a97602e85c refs/tags/debian-version-0.0.6-1
+00516b112c9f2d30b3bbe5b0dd82ff270b885395b215 refs/tags/debian-version-0.0.6-1^{}
+0050e7c66ffc8f80bea640b63587fc9c41328b3354c2 refs/tags/debian-version-0.0.6.1-1
+0053f77be323b12cc765857f5d2a9c324d0f9caf9159 refs/tags/debian-version-0.0.6.1-1^{}
+\r
+a3\r
+00509b1a83af7f5d01413da8415bc68697951149e8ec refs/tags/debian-version-0.0.6.2-1
+0053c2182701de1e34c6109ccbdd79d65df3baa9bb28 refs/tags/debian-version-0.0.6.2-1^{}
+\r
+b1\r
+0057ae3b184def9cbffec7d31b4698e4501cf4209dbd refs/tags/debian-version-0.0.7+0.0.8rc1-1
+005ae5c4c0fbbe4a44cf57345cc35a2b2343ee66a43e refs/tags/debian-version-0.0.7+0.0.8rc1-1^{}
+\r
+9f\r
+004e69576f144f75ee0a8071104a61f5bf0ec44c5504 refs/tags/debian-version-0.0.7-1
+00518b455120b7001443f2c565a03b847ca78dcdf115 refs/tags/debian-version-0.0.7-1^{}
+\r
+a3\r
+005083f4787a0f384bd49bc2a0b039da3a2e656f4151 refs/tags/debian-version-0.0.7.1-1
+0053948a1ad4de18eeb45ed6757bb26a3f0c62dc16ed refs/tags/debian-version-0.0.7.1-1^{}
+\r
+b7\r
+005afea2abbdad4b2c6c8ac3c6b3ae24c77bc1d8a398 refs/tags/debian-version-0.0.7.2+0.0.8pre2-1
+005d6a022bdcdc7416bde405df1cab5cb399d1546227 refs/tags/debian-version-0.0.7.2+0.0.8pre2-1^{}
+\r
+b7\r
+005a9ffe417645e4cdf6c804ebd169acb31b1399e5f3 refs/tags/debian-version-0.0.7.2+0.0.8pre3-1
+005db154f100ff56478dfaf115215c9514c13d5c7638 refs/tags/debian-version-0.0.7.2+0.0.8pre3-1^{}
+\r
+b3\r
+0058bdafa7bc46fd89c1b56cbf87a0dcfeb7d098373c refs/tags/debian-version-0.0.8+0.0.9pre1-1
+005b929475e3b14fddf1efe2f5cbb539ddb9823c0fa2 refs/tags/debian-version-0.0.8+0.0.9pre1-1^{}
+\r
+10b\r
+005895eb0c670492970d415f7fc538cb6a79817e8c20 refs/tags/debian-version-0.0.8+0.0.9pre2-1
+005bfcee963b35c061b4eeb5a7339a1b4b9530ac8089 refs/tags/debian-version-0.0.8+0.0.9pre2-1^{}
+0058a030ca43d9489c033a64c9ebf72f3383b9f5dba4 refs/tags/debian-version-0.0.8+0.0.9pre3-1
+\r
+5b\r
+005b96816bab06f5c17d618b59457468d02fffb28091 refs/tags/debian-version-0.0.8+0.0.9pre3-1^{}
+\r
+b3\r
+005841e86877ae92dbeb50c8e1ab39090b2e6297785c refs/tags/debian-version-0.0.8+0.0.9pre4-1
+005b029a0a4c33b9041366bf167dd0faf9d9e083b183 refs/tags/debian-version-0.0.8+0.0.9pre4-1^{}
+\r
+219\r
+0058e8bc68cf8a18192e231b7abe5476ded232921422 refs/tags/debian-version-0.0.8+0.0.9pre5-1
+005b40f463ec9f0a013ba3bbb43a2904ed70eaba1539 refs/tags/debian-version-0.0.8+0.0.9pre5-1^{}
+0058897348a3bb5986ffa2348f908b65f6ae2b66375a refs/tags/debian-version-0.0.8+0.0.9pre5-2
+005bad8e779db22078ca6b18bd6194bbceee538cb632 refs/tags/debian-version-0.0.8+0.0.9pre5-2^{}
+00587ca7dbd1a6a945068ad3c89b187f439e1c4e56b7 refs/tags/debian-version-0.0.8+0.0.9pre6-1
+005b82185d82839dd7db97b01d6dbd59aa897d757086 refs/tags/debian-version-0.0.8+0.0.9pre6-1^{}
+\r
+1b9\r
+00574abc4016c1be5a7fc791ee43f53a4d7c45f41a2c refs/tags/debian-version-0.0.8+0.0.9rc1-1
+005a0065066dbe8bc79a15f83eb8e3b4f7153001570f refs/tags/debian-version-0.0.8+0.0.9rc1-1^{}
+00571410ed9aac7e0a0f35b540b82bb93a56f486a0d7 refs/tags/debian-version-0.0.8+0.0.9rc2-1
+005acc0fbc0b1341a4de6232f4234ad3b9b9a2afa4cc refs/tags/debian-version-0.0.8+0.0.9rc2-1^{}
+00574e4568bcc20448cc82f32710170339d28d70a921 refs/tags/debian-version-0.0.8+0.0.9rc3-1
+\r
+5a\r
+005af910dc73d3a67ef559de0febb027a2df73eeaca4 refs/tags/debian-version-0.0.8+0.0.9rc3-1^{}
+\r
+b1\r
+0057f05828ae8c3bd94aa9346f2887675e6cdc21dae0 refs/tags/debian-version-0.0.8+0.0.9rc5-1
+005ad10679e2adc79a025fe1c95084bfd31afa159032 refs/tags/debian-version-0.0.8+0.0.9rc5-1^{}
+\r
+b1\r
+00571d4821366fd412bf3d36c1e06807bf8f1cbb8225 refs/tags/debian-version-0.0.8+0.0.9rc6-1
+005a82ed4acd3aa49661b56c4c18d14496df9d8066c1 refs/tags/debian-version-0.0.8+0.0.9rc6-1^{}
+\r
+b1\r
+005712cb8777dee7404ffcb1b66727028db5b027b7bc refs/tags/debian-version-0.0.8+0.0.9rc7-1
+005a90e91a4a4252f52f014673dbbb1b8794285a97e5 refs/tags/debian-version-0.0.8+0.0.9rc7-1^{}
+\r
+9f\r
+004ea2b5d76ebb7a54498c562a0fc372d0ad17d63d69 refs/tags/debian-version-0.0.8-1
+0051dccc4b74158f121d0f25a1328ed3da85203710f5 refs/tags/debian-version-0.0.8-1^{}
+\r
+a3\r
+0050e0c71813f2c9e3301874fc8cc11bfd341a824e7b refs/tags/debian-version-0.0.9.1-1
+0053a3922d0bdcc06a22131d26a4258590338b8cea12 refs/tags/debian-version-0.0.9.1-1^{}
+\r
+a5\r
+0051a2981a73420ab2913d61578f26d865755d943105 refs/tags/debian-version-0.0.9.10-1
+0054ba8690373adffdcac1106bcd298e7deb00329186 refs/tags/debian-version-0.0.9.10-1^{}
+\r
+a3\r
+0050c6ede6de2b946db84a8a858afe7406c2bb5eeadc refs/tags/debian-version-0.0.9.2-1
+0053ba8690373adffdcac1106bcd298e7deb00329186 refs/tags/debian-version-0.0.9.2-1^{}
+\r
+a3\r
+00509781f6b256df4f560e0d9f2e56c88246fce29732 refs/tags/debian-version-0.0.9.3-1
+0053ba8690373adffdcac1106bcd298e7deb00329186 refs/tags/debian-version-0.0.9.3-1^{}
+\r
+50\r
+00507e0fcd4951fb693c38ad419de2a730cde516c6df refs/tags/debian-version-0.0.9.4-1
+\r
+53\r
+0053ba8690373adffdcac1106bcd298e7deb00329186 refs/tags/debian-version-0.0.9.4-1^{}
+\r
+50\r
+0050716cbe4162c13eae22bf0a5141a4b4c126925b23 refs/tags/debian-version-0.0.9.5-1
+\r
+53\r
+0053ba8690373adffdcac1106bcd298e7deb00329186 refs/tags/debian-version-0.0.9.5-1^{}
+\r
+a3\r
+0050481181f4d1ab56f7748711fb728a78a377195f67 refs/tags/debian-version-0.0.9.6-1
+0053ba8690373adffdcac1106bcd298e7deb00329186 refs/tags/debian-version-0.0.9.6-1^{}
+\r
+50\r
+0050795b3a47c7db5f7b6113cd637c5abfbd3f65f603 refs/tags/debian-version-0.0.9.7-1
+\r
+53\r
+0053ba8690373adffdcac1106bcd298e7deb00329186 refs/tags/debian-version-0.0.9.7-1^{}
+\r
+a3\r
+005054ff484e7255de06b73a492308758915e192f8f3 refs/tags/debian-version-0.0.9.8-1
+0053ba8690373adffdcac1106bcd298e7deb00329186 refs/tags/debian-version-0.0.9.8-1^{}
+\r
+a3\r
+00500f59f9f472b9b1155711f7712614394240ccabdf refs/tags/debian-version-0.0.9.9-1
+0053ba8690373adffdcac1106bcd298e7deb00329186 refs/tags/debian-version-0.0.9.9-1^{}
+\r
+64\r
+006436f591b1d6a0f30850e775b8c0357fbb6ad629b9 refs/tags/debian-version-0.1.0.1-rc-cvs-200503310807-1
+\r
+67\r
+0067561cd28f99184a506ce50da157e3c10edcf90889 refs/tags/debian-version-0.1.0.1-rc-cvs-200503310807-1^{}
+\r
+64\r
+0064d567c044afd75a020308509791aadebe0b572b83 refs/tags/debian-version-0.1.0.1-rc-cvs-200504010815-1
+\r
+67\r
+0067b491467912ad9a7485042fbd798d76ce30ac0ce6 refs/tags/debian-version-0.1.0.1-rc-cvs-200504010815-1^{}
+\r
+b1\r
+005707a07226e0a58088a0722722cb5573784fc9a542 refs/tags/debian-version-0.1.0.10-0-pre.1
+005ac8ad2fc0031a3705708a5f1cdf9518f391df4d80 refs/tags/debian-version-0.1.0.10-0-pre.1^{}
+\r
+b1\r
+0057d745412f1acf4b07fd95947551dc9ab0a5cbbf41 refs/tags/debian-version-0.1.0.11-0-pre.1
+005ac8ad2fc0031a3705708a5f1cdf9518f391df4d80 refs/tags/debian-version-0.1.0.11-0-pre.1^{}
+\r
+a5\r
+00515efe9f7863896cdca665f637497e876dd1a46f59 refs/tags/debian-version-0.1.0.11-1
+0054c8ad2fc0031a3705708a5f1cdf9518f391df4d80 refs/tags/debian-version-0.1.0.11-1^{}
+\r
+a5\r
+005192b5bcc76483247225ecb026519ac10f6acc0df0 refs/tags/debian-version-0.1.0.12-1
+0054c8ad2fc0031a3705708a5f1cdf9518f391df4d80 refs/tags/debian-version-0.1.0.12-1^{}
+\r
+51\r
+00511a18bfb9456d03f0e70ea459439e539eecca775f refs/tags/debian-version-0.1.0.13-1
+\r
+54\r
+0054c8ad2fc0031a3705708a5f1cdf9518f391df4d80 refs/tags/debian-version-0.1.0.13-1^{}
+\r
+f6\r
+0051e42cfc72de0ade4e98983c65eff1fff3d969f603 refs/tags/debian-version-0.1.0.14-1
+0054c8ad2fc0031a3705708a5f1cdf9518f391df4d80 refs/tags/debian-version-0.1.0.14-1^{}
+00515ab56a7b330959e72b3b6437c2a0d1fd760dd9a8 refs/tags/debian-version-0.1.0.14-2
+\r
+54\r
+0054c8ad2fc0031a3705708a5f1cdf9518f391df4d80 refs/tags/debian-version-0.1.0.14-2^{}
+\r
+a5\r
+00513e452a736efa4b8d5caf63da30b029073dc600e9 refs/tags/debian-version-0.1.0.15-1
+0054d2795a6ed34b65f84a5b0e70795d4c8b3e55fe43 refs/tags/debian-version-0.1.0.15-1^{}
+\r
+f6\r
+00519858cd959d338d2b97dbab25fdfc9815e560325d refs/tags/debian-version-0.1.0.16-1
+0054d2795a6ed34b65f84a5b0e70795d4c8b3e55fe43 refs/tags/debian-version-0.1.0.16-1^{}
+0051d44c6adb769c11bc502c3e4cad785e022f7af711 refs/tags/debian-version-0.1.0.17-1
+\r
+54\r
+0054d2795a6ed34b65f84a5b0e70795d4c8b3e55fe43 refs/tags/debian-version-0.1.0.17-1^{}
+\r
+c3\r
+0060af13ba9003478d4fc5516b3a1444e6a18c7561b5 refs/tags/debian-version-0.1.0.2-rc-200504011500-1
+00635de85f54ba0c0d21f99cc1e1053da6076eeae4e4 refs/tags/debian-version-0.1.0.2-rc-200504011500-1^{}
+\r
+c3\r
+0060b5a39210925640b7bd24bdb55d273d662df96e8a refs/tags/debian-version-0.1.0.2-rc-200504011640-1
+00637d5411f51aaf35bec79286669ba76a8e4b08a8f1 refs/tags/debian-version-0.1.0.2-rc-200504011640-1^{}
+\r
+196\r
+006443e0acc2f7c7a0489fc97dfecbff3399e7a67aef refs/tags/debian-version-0.1.0.2-rc-cvs-200504031300-1
+0067f89ef9793e5d57a4dfdeb4f6c10e78b7621550f2 refs/tags/debian-version-0.1.0.2-rc-cvs-200504031300-1^{}
+0064be873419cf99306923bd627d596d7f40c5c341fa refs/tags/debian-version-0.1.0.2-rc-cvs-200504061620-1
+0067b16ff67fbf91a31eb530c2a89d03297b3a5dbe23 refs/tags/debian-version-0.1.0.2-rc-cvs-200504061620-1^{}
+\r
+64\r
+006425d228a83903a204e4abd42d10d09e56cee805a3 refs/tags/debian-version-0.1.0.2-rc-cvs-200504062112-1
+\r
+67\r
+0067b5a962bc2e6381ff0c5e5c405e80e172f02d5ce9 refs/tags/debian-version-0.1.0.2-rc-cvs-200504062112-1^{}
+\r
+c3\r
+006049f32646382d62de625179704715c9a4c4158283 refs/tags/debian-version-0.1.0.3-rc-200504080730-1
+00637529186b5adc025381a6e4248a10aaa3989a60d5 refs/tags/debian-version-0.1.0.3-rc-200504080730-1^{}
+\r
+c3\r
+0060dec07a590542399f55c7b3107b7db50edf613ac2 refs/tags/debian-version-0.1.0.3-rc-200504231430-1
+00635827e2e216ad759f240a0c332848cadf65794742 refs/tags/debian-version-0.1.0.3-rc-200504231430-1^{}
+\r
+12b\r
+0064056fdbd9da7b2bfceec196379ec9fa952bf667ab refs/tags/debian-version-0.1.0.3-rc-cvs-200504231630-1
+0067a2129c3a30eb8593ea1e193e8108564f0c9978d4 refs/tags/debian-version-0.1.0.3-rc-cvs-200504231630-1^{}
+00600ea1d05d038027715efaebd5e5d9524cb207c9cc refs/tags/debian-version-0.1.0.4-rc-200504232130-1
+\r
+63\r
+006392b70813ffba87ad63085e10c78cf45354bf2fe8 refs/tags/debian-version-0.1.0.4-rc-200504232130-1^{}
+\r
+60\r
+006074832b1bf93bba56d20e358774a72fb3d73d0f6f refs/tags/debian-version-0.1.0.5-rc-200504272000-1
+\r
+63\r
+006353607d3bb352e93b72360a7772cc60532810566b refs/tags/debian-version-0.1.0.5-rc-200504272000-1^{}
+\r
+16c\r
+00602225b75f9c5a9ef1f7d76dea9fecb9ee2b02e03f refs/tags/debian-version-0.1.0.7-rc-200505171420-1
+006317ba6e76118b11548e623fe22a32f54cba9f6535 refs/tags/debian-version-0.1.0.7-rc-200505171420-1^{}
+00538864cc5c7a5c65980a5ac447363ded6ef1327efd refs/tags/debian-version-0.1.0.8-rc-1
+0056c8ad2fc0031a3705708a5f1cdf9518f391df4d80 refs/tags/debian-version-0.1.0.8-rc-1^{}
+\r
+53\r
+0053339a4540076ba8521598503844170303baebd9a3 refs/tags/debian-version-0.1.0.9-rc-1
+\r
+56\r
+0056c8ad2fc0031a3705708a5f1cdf9518f391df4d80 refs/tags/debian-version-0.1.0.9-rc-1^{}
+\r
+213\r
+00579a0a847629783e5927c57c8f394a61acdd838956 refs/tags/debian-version-0.1.1.10-alpha-1
+005a5331ebd99de37780d4fc4b7272bf8faaae0e3f04 refs/tags/debian-version-0.1.1.10-alpha-1^{}
+005749e8494f56f47d0e430caf2c9360c575147e05b5 refs/tags/debian-version-0.1.1.11-alpha-1
+005a690338d2c4e599900c8623cfcd2c2935943b9561 refs/tags/debian-version-0.1.1.11-alpha-1^{}
+0057cfdf709ac398e2cbb259618fa012d0a871907c02 refs/tags/debian-version-0.1.1.12-alpha-1
+005a20bcce490a77d930228fd36053c2cb9400f348e5 refs/tags/debian-version-0.1.1.12-alpha-1^{}
+\r
+162\r
+0057b8984356c7cc1afd0d9d8b2796236c6f518b339e refs/tags/debian-version-0.1.1.13-alpha-1
+005ac03cf41ca5e2ccfc48ca3f680b6eb2e9a32e997f refs/tags/debian-version-0.1.1.13-alpha-1^{}
+005775cbc7b616490e76cf2f74ef50758777b6d73581 refs/tags/debian-version-0.1.1.14-alpha-1
+005a138676541974dc1188236bb7174b1c31c88fb555 refs/tags/debian-version-0.1.1.14-alpha-1^{}
+\r
+54\r
+00549cc7ea4b30464b1df904c1bb6cd1b4b18c2fc0f7 refs/tags/debian-version-0.1.1.15-rc-1
+\r
+57\r
+0057941fa7b7d979afa638c8552511e05ec350aac0c1 refs/tags/debian-version-0.1.1.15-rc-1^{}
+\r
+ab\r
+0054598259233c8356ba7486b6ce4a327c656669c614 refs/tags/debian-version-0.1.1.16-rc-1
+00575798bf03e0567d255345722841e8723d97b38a33 refs/tags/debian-version-0.1.1.16-rc-1^{}
+\r
+54\r
+00540a69e9b80b8f3006e8ed9adc0c31a29d7d91a097 refs/tags/debian-version-0.1.1.17-rc-1
+\r
+57\r
+00574f0d7b74243644fce7c20b47c3024cf2b622de8f refs/tags/debian-version-0.1.1.17-rc-1^{}
+\r
+ab\r
+0054a9327412b6f9fc57040786d6434477337e3ef464 refs/tags/debian-version-0.1.1.18-rc-1
+0057219dd9b183c138f4a63758251a1841dc94fd9d6c refs/tags/debian-version-0.1.1.18-rc-1^{}
+\r
+54\r
+0054f3f4890f0b54a94017c039f756afaadb2d432f3f refs/tags/debian-version-0.1.1.19-rc-1
+\r
+57\r
+00574f0d7b74243644fce7c20b47c3024cf2b622de8f refs/tags/debian-version-0.1.1.19-rc-1^{}
+\r
+51\r
+00518d775a274df64f3252bfcb2bbe9502334adab6f0 refs/tags/debian-version-0.1.1.20-1
+\r
+54\r
+00544f0d7b74243644fce7c20b47c3024cf2b622de8f refs/tags/debian-version-0.1.1.20-1^{}
+\r
+14a\r
+0051d70f71f58cca087879f4ff3ef93a0eb026efb3d8 refs/tags/debian-version-0.1.1.21-1
+00544f0d7b74243644fce7c20b47c3024cf2b622de8f refs/tags/debian-version-0.1.1.21-1^{}
+00514d94628e783ae082b9ea9e168d33a93187683890 refs/tags/debian-version-0.1.1.22-1
+00544f0d7b74243644fce7c20b47c3024cf2b622de8f refs/tags/debian-version-0.1.1.22-1^{}
+\r
+f4\r
+00504a7f20933dd9e56447ff749e71dd0284e56971d8 refs/tags/debian-version-0.1.1.23-
+0053ac09b3271b8b923df50dc43f67097a2aebade4e6 refs/tags/debian-version-0.1.1.23-^{}
+00519e67777424b6f8d8c92094405625b6d60a0a5976 refs/tags/debian-version-0.1.1.23-1
+\r
+54\r
+005423e2606f1d4484be52774a82660429f03f6d8945 refs/tags/debian-version-0.1.1.23-1^{}
+\r
+105\r
+005608c0218539f48d83371db9e5fe3a894fa597d6a5 refs/tags/debian-version-0.1.1.23-1@6359
+0059958b6e674245a45c00f3db6f07cc851caa34f004 refs/tags/debian-version-0.1.1.23-1@6359^{}
+005620992186b8d780a2af1ba04d2fc02cafc2a93ef1 refs/tags/debian-version-0.1.1.23-1@6967
+\r
+59\r
+00594741cc04b066743aeb3278ea42b9a6a6fb563e75 refs/tags/debian-version-0.1.1.23-1@6967^{}
+\r
+105\r
+00562c55ed425947aa13b1a3105e0766bd5a3e1ef02e refs/tags/debian-version-0.1.1.5-alpha-1
+0059ad1ff57705bf6023be3ad31d990ccc6c423a1ae0 refs/tags/debian-version-0.1.1.5-alpha-1^{}
+00569a50919b4132c868636444029b4634c4103237a0 refs/tags/debian-version-0.1.1.6-alpha-1
+\r
+59\r
+00597a61dbed77765fe6b71c4f1439cf6553b8e887f4 refs/tags/debian-version-0.1.1.6-alpha-1^{}
+\r
+15e\r
+00568149b8917578be2142f15dda372786b9b9901c13 refs/tags/debian-version-0.1.1.6-alpha-2
+0059e4ee8a006949843541ecadcd380d4d7536b0e536 refs/tags/debian-version-0.1.1.6-alpha-2^{}
+00560c040abbd4bfd8f41b625bf0b26b1ff7724a9a0b refs/tags/debian-version-0.1.1.7-alpha-1
+0059db27c322838caa9861b918a64630232bdc5d86e7 refs/tags/debian-version-0.1.1.7-alpha-1^{}
+\r
+af\r
+0056159c14d38f04b2b83c5c804f7a033c62bb572091 refs/tags/debian-version-0.1.1.8-alpha-1
+0059e459f6ee0f71f182718cfbbe6d0a551b1e1886b9 refs/tags/debian-version-0.1.1.8-alpha-1^{}
+\r
+56\r
+00563188b876d3624fa9d45e601fd1448eaec45e8f0e refs/tags/debian-version-0.1.1.9-alpha-1
+\r
+59\r
+0059929dc8dea99ccb8e82671b5b5b601c596765851e refs/tags/debian-version-0.1.1.9-alpha-1^{}
+\r
+49\r
+00493df9883eb290f7e3dcb2339e5d4ae7855f6bc717 refs/tags/imported-from-cvs
+\r
+4c\r
+004c9ee3d81f8bbd6384df71529a9e15f0e74b3a25c7 refs/tags/imported-from-cvs^{}
+\r
+9f\r
+004e89718a4e16b44125603e8fcf526ed6214533ef37 refs/tags/imported-from-cvs@6890
+0051a2d9cbb2e82f568a0d4410d6b93922cded44b689 refs/tags/imported-from-cvs@6890^{}
+\r
+1a3\r
+00412a017f9723be927ade4c3558f06a3483269f05bf refs/tags/tor-0.0.2
+0044161d7d19aeead874831c40c4824551204c6afe21 refs/tags/tor-0.0.2^{}
+00467a72ffda23a0860d6afd986cb82518eea02624d9 refs/tags/tor-0.0.2pre13
+0049b4117d2a37ba646765d85a01348849e614fd2bc2 refs/tags/tor-0.0.2pre13^{}
+0046969b0faf8e86fadc0ef58d21ea6f1ce920c50706 refs/tags/tor-0.0.2pre14
+00493b78f5cb0922a9d9547216f5bbbad1e9f89f6cf4 refs/tags/tor-0.0.2pre14^{}
+\r
+11e\r
+0046eac2fc2bec1a9427d1b015b13e4de3c142012446 refs/tags/tor-0.0.2pre16
+0049a0f16c619cca24d9904b3beb0902fdf7da4927df refs/tags/tor-0.0.2pre16^{}
+0046d62a0bdb2c64a8dacf74d6dfb5a92672ef17c0b7 refs/tags/tor-0.0.2pre17
+0049c2e37901be4187bb209581bab31db0c305bb53cd refs/tags/tor-0.0.2pre17^{}
+\r
+46\r
+0046cb47896649ee02c142bb48b30eab1f86f02eaaf7 refs/tags/tor-0.0.2pre18
+\r
+49\r
+00497622a80904e4b06935d69c38d4a0e9cfc8c8b066 refs/tags/tor-0.0.2pre18^{}
+\r
+d5\r
+00467bd276933b39722c2bc05d75e73a5149460619a1 refs/tags/tor-0.0.2pre19
+0049e47106745e1f987cfb9a06df104334a2ef648d55 refs/tags/tor-0.0.2pre19^{}
+004653cc640c51bb4cb2ae3ab083618bbb394c43ddf1 refs/tags/tor-0.0.2pre20
+\r
+49\r
+0049f00dc6fe1e576a82244b08f488553abfd3bf01a3 refs/tags/tor-0.0.2pre20^{}
+\r
+d5\r
+00462ef6b9a78eed4979f55ee125977706ed59654787 refs/tags/tor-0.0.2pre22
+00491e9a963094c8c83231460ae56bc051cde6937a7d refs/tags/tor-0.0.2pre22^{}
+0046db0f892ac34c4a1639b3791d1e8410c373a6338e refs/tags/tor-0.0.2pre23
+\r
+49\r
+00496ee357e64b45ea6a952743280fa3de2bb16f3896 refs/tags/tor-0.0.2pre23^{}
+\r
+46\r
+0046f856f833eb69020e23eefb82bfe89dac170e1332 refs/tags/tor-0.0.2pre24
+\r
+49\r
+0049476e21aa6ee395910391a1d90f23cb9a1473fe53 refs/tags/tor-0.0.2pre24^{}
+\r
+8f\r
+004651634e5ef96f44365bc54de479ce852ec0cbbbb3 refs/tags/tor-0.0.2pre25
+00499d00c4b81cb29f0c50c534696d7886b2d891805a refs/tags/tor-0.0.2pre25^{}
+\r
+46\r
+0046515bb3b3ee840b31aeee8d6d749bcbf254290178 refs/tags/tor-0.0.2pre27
+\r
+49\r
+00490b9c140102bcafccdd1d1ae080bf396817eb6777 refs/tags/tor-0.0.2pre27^{}
+\r
+112\r
+00451664bd62a972b5c236884f1b45966057467211a4 refs/tags/tor-0.0.2pre8
+00486f46316c319277d68ac44697221f1f9881c1d197 refs/tags/tor-0.0.2pre8^{}
+00412f4c4efc8cf4535ba91a241aabe74e6bdfd413c7 refs/tags/tor-0.0.3
+00444d747cd95492941151bbf6f0dc1c629b553590b5 refs/tags/tor-0.0.3^{}
+\r
+10a\r
+00410e6c6fea42b99dc02e3453cca369166856adf65c refs/tags/tor-0.0.4
+004445699bb5ee379a396cf8709d306a3a2f2e4930a5 refs/tags/tor-0.0.4^{}
+004111517746ee69e59d3944303a67f961f4d44d43b7 refs/tags/tor-0.0.5
+00443dad8557a6622f918f2c7dc68b4f469b0168792b refs/tags/tor-0.0.5^{}
+\r
+10e\r
+0041d7baf800e5242c781a3eb8f85e7a8d757ce10b61 refs/tags/tor-0.0.6
+0044a16ec39800744bab4bf127b5adb86821e2822bb1 refs/tags/tor-0.0.6^{}
+0043272874e41d61cd9c91a909c35b366e990ad91c0e refs/tags/tor-0.0.6.1
+0046a16ec39800744bab4bf127b5adb86821e2822bb1 refs/tags/tor-0.0.6.1^{}
+\r
+12c\r
+0043bf985162bed61bb809eb6d7111df2593ec73c546 refs/tags/tor-0.0.6.2
+0046a16ec39800744bab4bf127b5adb86821e2822bb1 refs/tags/tor-0.0.6.2^{}
+005001c47c7b048e6ab185a1b51e124fbc00c79df766 refs/tags/tor-0.0.6incompat-merged
+0053f36d7b8fea2b6b5dfb94c8d5ca85bccbac09a7a1 refs/tags/tor-0.0.6incompat-merged^{}
+\r
+10e\r
+004175c38e6270fde5c6f9b1779cadc1302e6febe01d refs/tags/tor-0.0.7
+004472ed3c2810e97143f66ac9c8f1771c281366da2a refs/tags/tor-0.0.7^{}
+0043b3f11afb7c78d761a518acd43672bcace79c8f49 refs/tags/tor-0.0.7.1
+0046e4f83de9eba07225abdd03c67bb5a257d6d3b059 refs/tags/tor-0.0.7.1^{}
+\r
+cd\r
+00431a610f3a52a714d05a13a0f215728dd1b30f58e4 refs/tags/tor-0.0.7.2
+0046e4f83de9eba07225abdd03c67bb5a257d6d3b059 refs/tags/tor-0.0.7.2^{}
+00446a44a00b7c93991f9a18324f251cf3be7d39346f refs/tags/tor-0.0.7rc1
+\r
+47\r
+004715f405c062746f44e93dc49063250ca7d583b69c refs/tags/tor-0.0.7rc1^{}
+\r
+c8\r
+0041afda61d54cd01e95ae7a499f4b9153ba1776821b refs/tags/tor-0.0.8
+00446e844ea7431d7cc1d5397cc424e1bd576c94dae0 refs/tags/tor-0.0.8^{}
+00432e35d0235929234bda4138e6a9c8a593b50e8b35 refs/tags/tor-0.0.8.1
+\r
+46\r
+00466e844ea7431d7cc1d5397cc424e1bd576c94dae0 refs/tags/tor-0.0.8.1^{}
+\r
+11a\r
+0045c517f66d40b4cfe9602b2abbb3646039a0ccded0 refs/tags/tor-0.0.8pre1
+0048e4ae4f43dd808b6e2928deb8877fc969986aba2e refs/tags/tor-0.0.8pre1^{}
+004523563f91fba8657df02b13d65eb16a628f186cb5 refs/tags/tor-0.0.8pre2
+0048c577fd497fd27456301d4a80f9f57ce664644ecf refs/tags/tor-0.0.8pre2^{}
+\r
+15c\r
+0045e1f86f1d3bfa3c5446eb47c50bdc58a58b257aea refs/tags/tor-0.0.8pre3
+00481e415817a3b63775a49db5581dd7971e5da659c2 refs/tags/tor-0.0.8pre3^{}
+00441e21132a6b1dc6b3fda515c6ab04fc4a61724339 refs/tags/tor-0.0.8rc1
+004789552dc217fe184faa3ce130d90764db914580c9 refs/tags/tor-0.0.8rc1^{}
+0044323bd57fbc9164d74b3c022e30f77c5e5cbdd3c8 refs/tags/tor-0.0.8rc2
+\r
+47\r
+00471e24d59aef618d859097cd9fe9ec5c3a43cbb9dc refs/tags/tor-0.0.8rc2^{}
+\r
+85\r
+004115dc66870718e22916a80c2b26a05d0e6a13067c refs/tags/tor-0.0.9
+0044c0cb8248579d3b35503412a4f8d835cf5f6f2f95 refs/tags/tor-0.0.9^{}
+\r
+43\r
+0043c0f45c06cecb3fb7b827da22c523d36b473b77bb refs/tags/tor-0.0.9.1
+\r
+46\r
+0046e327b2f3a6f3a9667f42826890d50c354c90fc9e refs/tags/tor-0.0.9.1^{}
+\r
+44\r
+0044f54010204506ee0b2e38294fbb3be6e4b53a3b82 refs/tags/tor-0.0.9.10
+\r
+47\r
+0047afec9f233596807b7464060cecfd256f42700e92 refs/tags/tor-0.0.9.10^{}
+\r
+89\r
+00436a89b2a64ed396584d4d0946ab60bc4907f63362 refs/tags/tor-0.0.9.2
+0046afec9f233596807b7464060cecfd256f42700e92 refs/tags/tor-0.0.9.2^{}
+\r
+224\r
+0043ced9af55adfca9188d1c64a1dc944906979ae116 refs/tags/tor-0.0.9.3
+0046afec9f233596807b7464060cecfd256f42700e92 refs/tags/tor-0.0.9.3^{}
+00435e7f247861bf3730fedd2fa0e7d297fbe73d05ff refs/tags/tor-0.0.9.5
+0046afec9f233596807b7464060cecfd256f42700e92 refs/tags/tor-0.0.9.5^{}
+00438722d0fa5538b268b47885e9904a2e5eae0dd002 refs/tags/tor-0.0.9.6
+0046afec9f233596807b7464060cecfd256f42700e92 refs/tags/tor-0.0.9.6^{}
+004376d9a2a6860788b9d4e92e6970311fab0c295a5a refs/tags/tor-0.0.9.7
+0046afec9f233596807b7464060cecfd256f42700e92 refs/tags/tor-0.0.9.7^{}
+\r
+89\r
+00432817a5c7dbb840ce3ea513ddecf0f73ddfb63b2c refs/tags/tor-0.0.9.9
+0046afec9f233596807b7464060cecfd256f42700e92 refs/tags/tor-0.0.9.9^{}
+\r
+15f\r
+004512153492e4243b6ba6e27fc3df64f5a483ec3489 refs/tags/tor-0.0.9pre1
+0048ce0c7c554da4288666352f2636a817409f7d7a60 refs/tags/tor-0.0.9pre1^{}
+00454a057f01096a915e0e378a1e6dcde7169ede144b refs/tags/tor-0.0.9pre2
+00489e8ae9766e5d4eb94972f2e7118ce8e9c2e09381 refs/tags/tor-0.0.9pre2^{}
+00454faf7e4a8e0431910dade8bbcbb43b658501572d refs/tags/tor-0.0.9pre3
+\r
+48\r
+0048e2dea1dd59064246e217a848808a5837830a066d refs/tags/tor-0.0.9pre3^{}
+\r
+8d\r
+00450f50c3bfdf8c857ba77ebd06f16af53e3b4f2e34 refs/tags/tor-0.0.9pre4
+00484c2595ca66c3dd66086ab1bee0297ca9beb3c556 refs/tags/tor-0.0.9pre4^{}
+\r
+8d\r
+0045d309a2a35a659afc37d4448c80142a0e75d85916 refs/tags/tor-0.0.9pre5
+0048c1bf171ed8c35f59724a18f9ccea8082fd1d7dfc refs/tags/tor-0.0.9pre5^{}
+\r
+8d\r
+00456d040ad2c7dd44962199ccc5bab06cf7ab58a3e3 refs/tags/tor-0.0.9pre6
+00483e4f30fbb99b851c6d3e1a750626c07b22858c43 refs/tags/tor-0.0.9pre6^{}
+\r
+cf\r
+0044db7b66641655f08a1a5b94c9a64f7dfc259f68c6 refs/tags/tor-0.0.9rc1
+0047c893403ed73642acbeea9276733088692718a2bf refs/tags/tor-0.0.9rc1^{}
+00441f05c2b625cd21edd2ad3f1af68d8efaf7b0c6a7 refs/tags/tor-0.0.9rc2
+\r
+47\r
+0047730f4dd52b5c808b06696ea0ec620210cbd15bbd refs/tags/tor-0.0.9rc2^{}
+\r
+cf\r
+0044abcedde859db065263171786390d68fcc316b309 refs/tags/tor-0.0.9rc3
+0047d254aeb09e09a744555b2cf183ab28bc56ee95ca refs/tags/tor-0.0.9rc3^{}
+004412d9506227bc7e3e0d8c75b24513dbeace9c62aa refs/tags/tor-0.0.9rc4
+\r
+47\r
+004767dc7baa59e2b38a6720d843b54257ca0dd9e722 refs/tags/tor-0.0.9rc4^{}
+\r
+cf\r
+00441a569f589746ef006232a7c586220d07f7c50ceb refs/tags/tor-0.0.9rc5
+0047e3f6f92cf7d3a2fedc387ed1084aa82815c911dd refs/tags/tor-0.0.9rc5^{}
+00443ff6eb4f812994bc46d5a59e6e05de69f70a1392 refs/tags/tor-0.0.9rc6
+\r
+47\r
+00474006246b9e38f03e75fdf8b87fd9c52241b5c0bd refs/tags/tor-0.0.9rc6^{}
+\r
+11a\r
+00447430dd6270dde3db44417388fb0412248cedd35b refs/tags/tor-0.0.9rc7
+0047470cdea7f8170738e44566f063426ce419f2e0dc refs/tags/tor-0.0.9rc7^{}
+004623ba8444b54870b28b2624de6c05fd121023dd42 refs/tags/tor-0.1.0.1-rc
+0049fddf560254da197b9e4726b6101f358f4b68e7af refs/tags/tor-0.1.0.1-rc^{}
+\r
+116\r
+00443f8f04c00ce10004f942c48f709fde5e0ea929f3 refs/tags/tor-0.1.0.10
+00474855990d378212d433f65ff960391ae56e5e1365 refs/tags/tor-0.1.0.10^{}
+00442549b54facbc50588926bcdc9317432f07d0eb40 refs/tags/tor-0.1.0.11
+00474855990d378212d433f65ff960391ae56e5e1365 refs/tags/tor-0.1.0.11^{}
+\r
+116\r
+00443d2918543fcd8519e4d65e06afe8f9262e7cedf9 refs/tags/tor-0.1.0.12
+00474855990d378212d433f65ff960391ae56e5e1365 refs/tags/tor-0.1.0.12^{}
+00442fada1bdca5add9df0cd54c99568cb8743260659 refs/tags/tor-0.1.0.13
+00474855990d378212d433f65ff960391ae56e5e1365 refs/tags/tor-0.1.0.13^{}
+\r
+116\r
+004487889f1b96e0b9fb48688f008bc7c5c044d4b7f9 refs/tags/tor-0.1.0.14
+00474855990d378212d433f65ff960391ae56e5e1365 refs/tags/tor-0.1.0.14^{}
+004483b8b9ae0bb0c42abcffd80b8440af11456b4518 refs/tags/tor-0.1.0.15
+0047f4a14410ad0a7941906d983b5134a25089094302 refs/tags/tor-0.1.0.15^{}
+\r
+cf\r
+004463136bfbf8786731fc9f14faf8aa961572310719 refs/tags/tor-0.1.0.16
+0047f4a14410ad0a7941906d983b5134a25089094302 refs/tags/tor-0.1.0.16^{}
+0044a0c517c407bd1545a9cf875cc5ee966e49e8592e refs/tags/tor-0.1.0.17
+\r
+47\r
+0047f4a14410ad0a7941906d983b5134a25089094302 refs/tags/tor-0.1.0.17^{}
+\r
+46\r
+0046d55ab111bf78778747c2d58bf5f53ea9b34026c7 refs/tags/tor-0.1.0.2-rc
+\r
+49\r
+004928fc34b1e21e98ee0deec77e318302a5dbab2909 refs/tags/tor-0.1.0.2-rc^{}
+\r
+164\r
+00460a89a43e8aeff22c59e34581d7a3b1b8245b5ca7 refs/tags/tor-0.1.0.4-rc
+004942d99ed77307243ca7ccd272d5ff1d4fa4f410bc refs/tags/tor-0.1.0.4-rc^{}
+00463bcfe44b232001064f68ba8e13977eee8768416b refs/tags/tor-0.1.0.5-rc
+0049d0a9a8bdd3538f626243daad52c7eb0ba6085507 refs/tags/tor-0.1.0.5-rc^{}
+00460fd0ca62c91ce0db5770f11361b8b3c2ab884db7 refs/tags/tor-0.1.0.6-rc
+\r
+49\r
+00495837711b0abcb43a43fb2573df598f7cbc9b82ba refs/tags/tor-0.1.0.6-rc^{}
+\r
+11e\r
+004645dfa751e07b3ad8b99002ddc5fbe91ad37f8e32 refs/tags/tor-0.1.0.7-rc
+0049356114c28e1170a269ef6a054b78f20f49eba4e4 refs/tags/tor-0.1.0.7-rc^{}
+004681ce93e46f5e6dd957bd1d1f8445b496c8089d8f refs/tags/tor-0.1.0.9-rc
+00494855990d378212d433f65ff960391ae56e5e1365 refs/tags/tor-0.1.0.9-rc^{}
+\r
+12c\r
+0049d8d87e17df319c21ee3af977da857578187540f5 refs/tags/tor-0.1.1.1-alpha
+004cdf56eea8f3f6c67191ecf5832674cb4c65797066 refs/tags/tor-0.1.1.1-alpha^{}
+004a05ab0d3ee49c6ef598f659756a891af5ed6e7ede refs/tags/tor-0.1.1.10-alpha
+004debacd3be0c66367b6a2cd18103b78db608981c4c refs/tags/tor-0.1.1.10-alpha^{}
+\r
+4a\r
+004aca2c2fef0f3128a3b46416c77108aa39b4d01be3 refs/tags/tor-0.1.1.11-alpha
+\r
+4d\r
+004d4f7749dd97a5c433a4f0f486a2e9452ecf9fc64b refs/tags/tor-0.1.1.11-alpha^{}
+\r
+e1\r
+004ae44119faa23ac468d3647d17d7e3b468200b7487 refs/tags/tor-0.1.1.12-alpha
+004d3c894809132137d799fd31c1714e900a2f42d2ab refs/tags/tor-0.1.1.12-alpha^{}
+004ad2652597fce0d66a15ae42073cd4f143fcabbbfa refs/tags/tor-0.1.1.13-alpha
+\r
+4d\r
+004dddb43de2d0bc016f85a56a76bfa1229a95173ea3 refs/tags/tor-0.1.1.13-alpha^{}
+\r
+4a\r
+004aca1f7bc3cd83e438f93cb45224e60b60e6db95d5 refs/tags/tor-0.1.1.14-alpha
+\r
+4d\r
+004df797ce5e597a4b03f725aab1d727a3efb00d1284 refs/tags/tor-0.1.1.14-alpha^{}
+\r
+d8\r
+00476c9ea9d54340d01fbafc66b7cf7f5180be3bf8f9 refs/tags/tor-0.1.1.15-rc
+004a941fa7b7d979afa638c8552511e05ec350aac0c1 refs/tags/tor-0.1.1.15-rc^{}
+00475aa0ac9a6647be3fa9d979f66e77e90f5a8c5d12 refs/tags/tor-0.1.1.16-rc
+\r
+4a\r
+004abcc19b0f837556221336c82c0860236d18448386 refs/tags/tor-0.1.1.16-rc^{}
+\r
+169\r
+00476bfcbe71c56d409866784f11e0ac1309f4bec424 refs/tags/tor-0.1.1.17-rc
+004a26eb815f7388742eab5722f5e2cac9baaae6eacf refs/tags/tor-0.1.1.17-rc^{}
+0047a6cd3dc3da0726ad9a672410483bd9d450f04a9f refs/tags/tor-0.1.1.18-rc
+004ab190c451b8ec438ffe43943f3db03b24a2aa5809 refs/tags/tor-0.1.1.18-rc^{}
+004741ee5235479fc07d1501e9c2328d052b036001d7 refs/tags/tor-0.1.1.19-rc
+\r
+4a\r
+004a53f7a1bb0c84d026cff0478aa8975c202ce84886 refs/tags/tor-0.1.1.19-rc^{}
+\r
+120\r
+00491aa4266193a860568bc48b2dc46f1b493ee543cc refs/tags/tor-0.1.1.2-alpha
+004c452c98058fc214444e726848dafa13447b013721 refs/tags/tor-0.1.1.2-alpha^{}
+00441111d6ecc29fe843eb973a02c3d6b7d8bead747e refs/tags/tor-0.1.1.20
+004753f7a1bb0c84d026cff0478aa8975c202ce84886 refs/tags/tor-0.1.1.20^{}
+\r
+116\r
+0044b9b3bb372883d66531625b5c309678d0c808993b refs/tags/tor-0.1.1.21
+004753f7a1bb0c84d026cff0478aa8975c202ce84886 refs/tags/tor-0.1.1.21^{}
+004451ea194d2d6c31b52204922957ec1624bf0ffd87 refs/tags/tor-0.1.1.22
+004753f7a1bb0c84d026cff0478aa8975c202ce84886 refs/tags/tor-0.1.1.22^{}
+\r
+116\r
+0044bedb349e2f1b21f38d80662b7c07ea99ebf309f0 refs/tags/tor-0.1.1.23
+0047e59976751bd79bba63d8f20dc03ba8b951c60fc8 refs/tags/tor-0.1.1.23^{}
+0044e4a6e5eac6cf0865a4762d12e82d076978a461f2 refs/tags/tor-0.1.1.24
+00471912d1a67c9fe1403d5f300cfbd3009d0476edd9 refs/tags/tor-0.1.1.24^{}
+\r
+44\r
+0044aa0a239041ccc75f9c072f1fb61284aa336a581f refs/tags/tor-0.1.1.25
+\r
+47\r
+004700f78af2d784c0096a1c757d307f7160db811539 refs/tags/tor-0.1.1.25^{}
+\r
+8b\r
+0044fd766e65fb577322f46f7e34f8c21662475545e8 refs/tags/tor-0.1.1.26
+0047fbb0f482637ea8c78729860e24df1f6be94edf6e refs/tags/tor-0.1.1.26^{}
+\r
+de\r
+0049b67d657c97ee61717dc72fe396347f3c51d71a72 refs/tags/tor-0.1.1.4-alpha
+004c3fa821d91127add1d08cba98b3011eed0f4d9be0 refs/tags/tor-0.1.1.4-alpha^{}
+0049ecde2169b900b7ef468029aee46483951500fcd5 refs/tags/tor-0.1.1.5-alpha
+\r
+4c\r
+004c1dd514f244cb1ab3ac44fcc6f6feebf9b1786e95 refs/tags/tor-0.1.1.5-alpha^{}
+\r
+12a\r
+00499ada8f7898267633a4d77b8f8b1d4a08aa86b1ff refs/tags/tor-0.1.1.6-alpha
+004c2ad3e4ff960617808b665d6e0590d31948b82b3b refs/tags/tor-0.1.1.6-alpha^{}
+00499db4cb4e4e4aa1d1ee9017b9b6e59fc08f694ddd refs/tags/tor-0.1.1.7-alpha
+004ce4ee8a006949843541ecadcd380d4d7536b0e536 refs/tags/tor-0.1.1.7-alpha^{}
+\r
+12a\r
+004978e7a370f495214a80065c132ccaaced98cd8877 refs/tags/tor-0.1.1.8-alpha
+004cd7b04a87886c9926b799e263f95b947a237e04cb refs/tags/tor-0.1.1.8-alpha^{}
+0049c188dc6379c8d0dd602bfd9951a2a27d201035db refs/tags/tor-0.1.1.9-alpha
+004cfe7b07754f5c52bc18e648edf32cc8672e1e0aa3 refs/tags/tor-0.1.1.9-alpha^{}
+\r
+126\r
+004972d1991f392d9d82d78e308a6eba88f29467f5a8 refs/tags/tor-0.1.2.1-alpha
+004ce744117d4da1f7cd938480fd9a1541e7377a5204 refs/tags/tor-0.1.2.1-alpha^{}
+0047be5e026cc3282f83b7ebe3d4204f6e7d4c86cd3a refs/tags/tor-0.1.2.10-rc
+004a0066174afa882043a015f75c07b961be6d51b36e refs/tags/tor-0.1.2.10-rc^{}
+\r
+122\r
+0047d2a3acc6647f78745eaa43db046186c591cb50dc refs/tags/tor-0.1.2.11-rc
+004a55aa184ac5da149943e8345e2ac66d2396b409cc refs/tags/tor-0.1.2.11-rc^{}
+004774eddd8c578dd97c8bdd4cfd5193cdd2ac6d5c8e refs/tags/tor-0.1.2.12-rc
+004a378e33a8dad1d2026dafcf9e2e5b1f876ac18911 refs/tags/tor-0.1.2.12-rc^{}
+\r
+cf\r
+0044da0ec14807fa4ae0b0001f06f25bf4f02c4253af refs/tags/tor-0.1.2.13
+0047e35659f66b817c2b7f6400202661687723befb55 refs/tags/tor-0.1.2.13^{}
+004447ad04ea9550fe20e9080e5a8d7fd06be44488e0 refs/tags/tor-0.1.2.14
+\r
+47\r
+0047de4263b450d96c0f29a4fca4f436860a124f4537 refs/tags/tor-0.1.2.14^{}
+\r
+cf\r
+0044043ee25b97f261bc9ae24eae9d225017f403e867 refs/tags/tor-0.1.2.15
+004756b099015ec442cbfa786be3e659980c661daab8 refs/tags/tor-0.1.2.15^{}
+0044ab0e8c911b4894f2e72316499ef88c324fd4d57d refs/tags/tor-0.1.2.16
+\r
+47\r
+00477f193e9edadd8640be8acc94b3000442cf920d90 refs/tags/tor-0.1.2.16^{}
+\r
+122\r
+004aba69074c7cf67c5133e85ca9f5a8aa53b72bfbe7 refs/tags/tor-0.1.2.16@11196
+004d474894b85d13a705c988cf04300f00241f9ed001 refs/tags/tor-0.1.2.16@11196^{}
+00440a25f737653f7969254aeb56f8eaca73c914e67e refs/tags/tor-0.1.2.17
+0047b597d0ee10ba08d01b32f10569285baed1b7fe6e refs/tags/tor-0.1.2.17^{}
+\r
+116\r
+0044be62da760518f7ade8403d8e5eda030e2934e98d refs/tags/tor-0.1.2.18
+0047443bb2c7717ace9497a65d806c2f9ec70ae6d0af refs/tags/tor-0.1.2.18^{}
+0044cfc9fa0dc4b68ad0cb8c46a02c914c4bb14863f7 refs/tags/tor-0.1.2.19
+0047fe4a6cd08e995fff73d36a1073531ef2d826604b refs/tags/tor-0.1.2.19^{}
+\r
+de\r
+0049b2cd414d3edce871c0e25020dbc9f23aae909dc8 refs/tags/tor-0.1.2.2-alpha
+004cf07f7a7a124ade0744afb636a8fd101113a6a7aa refs/tags/tor-0.1.2.2-alpha^{}
+00495bcf45365fa3fdef718cdfd06a206f5101a5df5b refs/tags/tor-0.1.2.3-alpha
+\r
+4c\r
+004cbc6eadd20e502d0fe420749d55f246970ca0e452 refs/tags/tor-0.1.2.3-alpha^{}
+\r
+49\r
+0049e133f8d2ec78d96d393feda0bdf4810602cb9899 refs/tags/tor-0.1.2.4-alpha
+\r
+4c\r
+004c5812a4096bca7015c8a7028a134eb73059c189da refs/tags/tor-0.1.2.4-alpha^{}
+\r
+95\r
+0049240d78ce83b7baa486176f2860fa9c0d8d9b8ccb refs/tags/tor-0.1.2.5-alpha
+004c7cd0495bf6cf6477203d90bed5e680762095dcd3 refs/tags/tor-0.1.2.5-alpha^{}
+\r
+95\r
+00492ed273734af7deb7f4e75ac0ec6ccbf07593a891 refs/tags/tor-0.1.2.6-alpha
+004cca66074106d0841848c51fafba6d6ef48fe6afa3 refs/tags/tor-0.1.2.6-alpha^{}
+\r
+95\r
+00491a4366cd15e920a386099ae51c2b2877c748e585 refs/tags/tor-0.1.2.7-alpha
+004cf1ca295d231f95d0f9d05576238af0e243259147 refs/tags/tor-0.1.2.7-alpha^{}
+\r
+48\r
+00487c90a355da383f5a6b6036224dc659e5cb3a064f refs/tags/tor-0.1.2.8-beta
+\r
+4b\r
+004b38f5fac846ab189f80fe7f10b0a07659f9de130d refs/tags/tor-0.1.2.8-beta^{}
+\r
+46\r
+00464b7df794f565c1cb5d5484cf6b69140ac59773f8 refs/tags/tor-0.1.2.9-rc
+\r
+49\r
+0049c4cf13a5a057b099c407bab4c44d580e06a90606 refs/tags/tor-0.1.2.9-rc^{}
+\r
+95\r
+0049720d70d45804affb62e6c48d046041f8a2a8fbf0 refs/tags/tor-0.2.0.1-alpha
+004c3431377d86e0891a41ce0882069c16f3f87d2142 refs/tags/tor-0.2.0.1-alpha^{}
+\r
+1c5\r
+004a2aedf99cd10114da21c053430ad03999baf481b1 refs/tags/tor-0.2.0.10-alpha
+004d7050df72454ef8f7e49f42d178ac6ef0ba19ec7c refs/tags/tor-0.2.0.10-alpha^{}
+004a17224d68d26ff8020b34ce8b9e24169e2a2eb9fd refs/tags/tor-0.2.0.11-alpha
+004db7024f0f3076c74c44c9422c5dd7e1fe07ed276a refs/tags/tor-0.2.0.11-alpha^{}
+004a0eebbf0da80e419d523112eff59cbb51e1c5b18b refs/tags/tor-0.2.0.12-alpha
+004d6514843026222fe42fa93b01dfb4ed754beeb282 refs/tags/tor-0.2.0.12-alpha^{}
+\r
+4a\r
+004ac5aa54ad438973d7cf03c81cf916fac68fca240c refs/tags/tor-0.2.0.13-alpha
+\r
+4d\r
+004d95daf3382e4f90c2e94ae2d6edc8ee785ddc5b50 refs/tags/tor-0.2.0.13-alpha^{}
+\r
+12e\r
+004a4fb7608c5c1d661de63645ebe3a8f04a1fb863bd refs/tags/tor-0.2.0.14-alpha
+004d2424449947eb06b878dd64bff1cb906f6604989d refs/tags/tor-0.2.0.14-alpha^{}
+004a6d366826b89e710c13631cefdb53e8ef30c35c0a refs/tags/tor-0.2.0.15-alpha
+004d58e429f079a70fe1f019308505bb4743a9fe801f refs/tags/tor-0.2.0.15-alpha^{}
+\r
+97\r
+004aee9e929fd8009abdcf4da39e297e824e881c6ae0 refs/tags/tor-0.2.0.16-alpha
+004d60a3df5a09ec071bc3a7eba1055986a178e46f98 refs/tags/tor-0.2.0.16-alpha^{}
+\r
+12e\r
+004ac1ba2ef6a4e41634e27a832d07fcedece68c50df refs/tags/tor-0.2.0.17-alpha
+004d92e4cfdeb47c0868c5f99caa68d9059d3d068912 refs/tags/tor-0.2.0.17-alpha^{}
+004ab94a19e4ffdadc89f41a99dd418fb3e8932a187e refs/tags/tor-0.2.0.18-alpha
+004d65ecbdad7658ca958fadb2848f4c6d2fa4605253 refs/tags/tor-0.2.0.18-alpha^{}
+\r
+12c\r
+004ac3766e4bceef491ee67faec81e7932d7102da775 refs/tags/tor-0.2.0.19-alpha
+004dd2528e6b48374b31ca07ba85c0caf2dc80fa86bf refs/tags/tor-0.2.0.19-alpha^{}
+0049e5473254ef6299ba03d1457ae4572040b2c22bb2 refs/tags/tor-0.2.0.2-alpha
+004c0b73569dc64d0479d9638ed71da280f752e3637e refs/tags/tor-0.2.0.2-alpha^{}
+\r
+47\r
+00479ac15772ffea5468afcf2bb771fd73cdb3ff39d5 refs/tags/tor-0.2.0.20-rc
+\r
+4a\r
+004a3dd9a3a23a0b8638bcfe0be3036c706e8b6d3eb8 refs/tags/tor-0.2.0.20-rc^{}
+\r
+122\r
+00479ddab1bc02e86009eb6477cb9b04942738307872 refs/tags/tor-0.2.0.21-rc
+004a1ff70f240285669b6072b8e058bd3018f0a5687a refs/tags/tor-0.2.0.21-rc^{}
+0047e9d1b1442416819ce8add75eeb118dcdc1896177 refs/tags/tor-0.2.0.22-rc
+004a77302e3578cb0b22e91b1ef29783d5f6aad7f5a9 refs/tags/tor-0.2.0.22-rc^{}
+\r
+122\r
+0047d6a6bcd2a04044d206b99e78f901c14eced07ecf refs/tags/tor-0.2.0.23-rc
+004a176d5c63b1056b73839ab3ba8bbd66a454dca340 refs/tags/tor-0.2.0.23-rc^{}
+004704bdd3b4b2537938c806d06e09b9dff57c188332 refs/tags/tor-0.2.0.24-rc
+004a94a9eaaf149b1b9fd5c066a3ed56cb0a1f69a16f refs/tags/tor-0.2.0.24-rc^{}
+\r
+d8\r
+0047cb3f34d13ece77af7e3fae45596d4123fffdac93 refs/tags/tor-0.2.0.25-rc
+004a4833d1a30a89efa22199099bd7686a348040d344 refs/tags/tor-0.2.0.25-rc^{}
+00478d04d65d39f2fd3f1488a59c895f93297d49a480 refs/tags/tor-0.2.0.26-rc
+\r
+4a\r
+004a9b87cfbdf8e3eb760d4db80e2edece321a125254 refs/tags/tor-0.2.0.26-rc^{}
+\r
+47\r
+0047a92b99c41a06f9d9a5a61e38f0abd71f5507fe5d refs/tags/tor-0.2.0.27-rc
+\r
+4a\r
+004aee60a8ddff5f5d2d429dd0687c0fafe542694997 refs/tags/tor-0.2.0.27-rc^{}
+\r
+122\r
+00475dcabc0cb419ad7c17732edb07557fabf5770ecc refs/tags/tor-0.2.0.28-rc
+004a3c31afb6c4b131355a75fb62272592af4a5bc40b refs/tags/tor-0.2.0.28-rc^{}
+0047ab7a7fb9c661991c39b4be2425043dc2964535ba refs/tags/tor-0.2.0.29-rc
+004a59b5df9b4e7c16e0a79fdf0c3cd4b6f502490f15 refs/tags/tor-0.2.0.29-rc^{}
+\r
+120\r
+00491a70f68a51aca12961faf86e11b22c639f626897 refs/tags/tor-0.2.0.3-alpha
+004cec1d599302891047d2bd2f722085e187661610f6 refs/tags/tor-0.2.0.3-alpha^{}
+0044323ee2bcd3879826474713e76f6e620ff7ae2a22 refs/tags/tor-0.2.0.30
+004748d9b654bdc9900f4da366213a525a1e6381f584 refs/tags/tor-0.2.0.30^{}
+\r
+116\r
+0044bcf2a83d1b0d92290e81cc8c502c70f9855e755b refs/tags/tor-0.2.0.31
+0047a03e48c541d48bed1ff15616d03880635d2ccb19 refs/tags/tor-0.2.0.31^{}
+00444f578d80c090e0ed9c90ed9f1945dcae47f6e3b3 refs/tags/tor-0.2.0.32
+0047686d30edb695f732d4397e363ed9d6e5163b7ce2 refs/tags/tor-0.2.0.32^{}
+\r
+116\r
+0044b57564db8f93e9006365658dd92aefbe67f4b09d refs/tags/tor-0.2.0.33
+004725290b32a3ecc0bd215ed35bc164f0273ea20a2d refs/tags/tor-0.2.0.33^{}
+0044aa5cff79ebbdae4030653607f1735381ec7c70e3 refs/tags/tor-0.2.0.34
+0047be9efc51c91bc2feb2eaea74d05f3cfccadba36f refs/tags/tor-0.2.0.34^{}
+\r
+8b\r
+00444f19383626d27264daff12943924357867686c1d refs/tags/tor-0.2.0.35
+0047935f457263b88e5d15bc29c84b944c8861d46f90 refs/tags/tor-0.2.0.35^{}
+\r
+49\r
+00497461169f5acd962db5f94a00ecb45a6df2a7f71d refs/tags/tor-0.2.0.4-alpha
+\r
+4c\r
+004ced5acf94d969ac4b0abfb43d76fc715f870d1449 refs/tags/tor-0.2.0.4-alpha^{}
+\r
+ea\r
+004f07a7c04e6f11827653f759039c6158f5b76942ff refs/tags/tor-0.2.0.4-alpha@11197
+005246c4f8ff426c555b05ecbf7cebfdee75dd090278 refs/tags/tor-0.2.0.4-alpha@11197^{}
+0049493fbe1221fca5b734a15bb00b557b963b6536bb refs/tags/tor-0.2.0.5-alpha
+\r
+4c\r
+004c84dddc5df48c5b297ffc4d69214f27d3d26161df refs/tags/tor-0.2.0.5-alpha^{}
+\r
+de\r
+0049d1251ad86f98e1c4ff1bdaffa86616436c5cc1f0 refs/tags/tor-0.2.0.6-alpha
+004cc4ee55ed266cfb8bf8ccd4958536f6eb1e276e5c refs/tags/tor-0.2.0.6-alpha^{}
+004917ea78e9d1694f128514b25784fea27619e496f3 refs/tags/tor-0.2.0.7-alpha
+\r
+4c\r
+004c991ebb42de888661a47512acec02d37f1db12685 refs/tags/tor-0.2.0.7-alpha^{}
+\r
+95\r
+0049570c6f68c70d51755085ff72c5d08f9deb213d4a refs/tags/tor-0.2.0.8-alpha
+004c575487ea9cddd70ea0bba6f0124c38a9830ef670 refs/tags/tor-0.2.0.8-alpha^{}
+\r
+12a\r
+0049b3cff1340528bcf93237c9856ac5a1b12ac32ac4 refs/tags/tor-0.2.0.9-alpha
+004cea4c3d6d1dfe75f14c6c8934c4e6fcfbc5afc204 refs/tags/tor-0.2.0.9-alpha^{}
+00494e182bcc82d449aa0b0513c3875dc5afc8a50961 refs/tags/tor-0.2.1.1-alpha
+004cb2cd61258e52b10d8003c4206f2bf2b56b5bfb38 refs/tags/tor-0.2.1.1-alpha^{}
+\r
+97\r
+004a6f2e1dc93a3aec25f55ccf12570d015f7b03edd9 refs/tags/tor-0.2.1.10-alpha
+004d2d9e8a75b854d10d0943841b0cf27b1cffc28cba refs/tags/tor-0.2.1.10-alpha^{}
+\r
+4a\r
+004aa4776e149d0f28c03b4cf0d5d5be45356098b3a4 refs/tags/tor-0.2.1.11-alpha
+\r
+4d\r
+004d3c668245b7a7e7665679c8fd5461e6efe3a1f166 refs/tags/tor-0.2.1.11-alpha^{}
+\r
+97\r
+004abfd6f7161c056e2967d30434ec516ae19a1821b9 refs/tags/tor-0.2.1.12-alpha
+004d8a555a0d836d27fb14ae22151aa4b10b7bac11e2 refs/tags/tor-0.2.1.12-alpha^{}
+\r
+16f\r
+004a0358f99a0998b2168ad101ccd5912b970f28fe3d refs/tags/tor-0.2.1.13-alpha
+004dd40cbda2cd9e8f41e827d01f99450c760f339dbf refs/tags/tor-0.2.1.13-alpha^{}
+004720fda287b6c9cc7c92d32616014976d3fe2bb396 refs/tags/tor-0.2.1.14-rc
+004a72e4d48c7a8a7722d01c914766a8a663f97c77ec refs/tags/tor-0.2.1.14-rc^{}
+004751ea47275e99022d0210e8ff59ca39ea35844879 refs/tags/tor-0.2.1.15-rc
+\r
+4a\r
+004a2f39eca28b113a18621d3ea3976ab12ceb60c41b refs/tags/tor-0.2.1.15-rc^{}
+\r
+91\r
+00472b14f95551431333d14800f760114de234ee2eb7 refs/tags/tor-0.2.1.16-rc
+004aac3dedacce44b306ec1a9372ee54b0aabaeac8fe refs/tags/tor-0.2.1.16-rc^{}
+\r
+47\r
+00474af8d9328042a9735d3b94ea9f7efc53bbd607d2 refs/tags/tor-0.2.1.17-rc
+\r
+4a\r
+004a32d40607246e357d905bdf17acc20f6c863afd2b refs/tags/tor-0.2.1.17-rc^{}
+\r
+44\r
+0044cef1b0d8e33843f7a025784c314bdd5ab10c23e2 refs/tags/tor-0.2.1.18
+\r
+8b\r
+004752b142219b9ed4b3de8fee4bc09b229cb3f7b410 refs/tags/tor-0.2.1.18^{}
+0044ce6c2ab3161665118ed54d50dc81a4c360196254 refs/tags/tor-0.2.1.19
+\r
+47\r
+004769706f99e80aec9414e6a54e76346d4cf89f1a4c refs/tags/tor-0.2.1.19^{}
+\r
+1ab\r
+0049eed22013dd2e733742e1656ccb6be1979a555847 refs/tags/tor-0.2.1.2-alpha
+004c21cc898a46eec529a74971b10aabf7dd933660dd refs/tags/tor-0.2.1.2-alpha^{}
+004408bb8744ea42d35938135c9636aca6338c70bdbb refs/tags/tor-0.2.1.20
+004716dc543851bb82c481d4319d557ffea5bef6cc50 refs/tags/tor-0.2.1.20^{}
+004479d358e249d2d3154c0077e87a7f96c8ed3cb35b refs/tags/tor-0.2.1.21
+00475201e05fc55d479d95a8b908f6c33d2b88eee26c refs/tags/tor-0.2.1.21^{}
+\r
+116\r
+0044fc9573a1a9bb009eebac943cff77584f7bfdf4a5 refs/tags/tor-0.2.1.22
+0047f43f87db5b945ea86cfb2bce316b46eb6fd9affd refs/tags/tor-0.2.1.22^{}
+0044f1affd4210b91420f2e96a458203781dc60c5bef refs/tags/tor-0.2.1.23
+0047c9a3781580cb0f56ec0b388f0fad41ddef844bb1 refs/tags/tor-0.2.1.23^{}
+\r
+44\r
+00444b5d8333c425dbf0ac8ee706887f45528be0d323 refs/tags/tor-0.2.1.24
+\r
+47\r
+00475e5bc8724edf28491c36fa2e9dd505967f21d45b refs/tags/tor-0.2.1.24^{}
+\r
+116\r
+0044eb4766d6af9a0b1f60d4bb1d4c7f7b86c83bf98c refs/tags/tor-0.2.1.25
+00476b7e5eb5f1ee9d6ef24cbe7d96fa5388f7a54bf0 refs/tags/tor-0.2.1.25^{}
+004464437110963eaf2c2084e20e2930dec1f6f7ada5 refs/tags/tor-0.2.1.26
+004777f30fb55b794b833b104b80504c3a2063e92809 refs/tags/tor-0.2.1.26^{}
+\r
+116\r
+004417d85eae332b54e875ab6bd27f1a5fe95829a857 refs/tags/tor-0.2.1.27
+0047924f7bf9a5c3c960d17c360c9f75a5a43e7b735c refs/tags/tor-0.2.1.27^{}
+0044ed276cafd69a91ff858c6fc62bb301481c2d83e5 refs/tags/tor-0.2.1.28
+00473936267fd9dbc4fed0a29d18c957396b21e10d92 refs/tags/tor-0.2.1.28^{}
+\r
+120\r
+00443c68460c9204de9f702848227ac29280f3ab42ef refs/tags/tor-0.2.1.29
+004741b60af271826162bae94cf6b91adf7f578b380e refs/tags/tor-0.2.1.29^{}
+004980be293f7756cd272d2161b377f72877717ca384 refs/tags/tor-0.2.1.3-alpha
+004cfd4a30d198e2ff166b0fcee9243923eb1b58fcd4 refs/tags/tor-0.2.1.3-alpha^{}
+\r
+116\r
+00447f88ae284afe29b91a22fa57e6c81b21387a4dfc refs/tags/tor-0.2.1.30
+00471855b4ebfdd63c0c3beeeed5eefb9b0c3f50a8bd refs/tags/tor-0.2.1.30^{}
+0044d978be06edad8b31eaade069aa203015c16ce8b3 refs/tags/tor-0.2.1.31
+0047e740ac08c63f68c00f91aeffcd15bef74208fb69 refs/tags/tor-0.2.1.31^{}
+\r
+120\r
+004451e59c71d84d632e84dc2abf2cdbe42075fdb993 refs/tags/tor-0.2.1.32
+0047887bddb7e7323334484c9651ae116e3d28e7b217 refs/tags/tor-0.2.1.32^{}
+00490aabb9e06bd79678c61bb337538510de95b57854 refs/tags/tor-0.2.1.4-alpha
+004cd01813a8ddcfb1db7c833cc42eea1ca98011c599 refs/tags/tor-0.2.1.4-alpha^{}
+\r
+12a\r
+004973a33565696925c8ab5b8e41e0795e2b34adf52d refs/tags/tor-0.2.1.5-alpha
+004ce5576a66dd708be890954a2c01eef5a2764212b1 refs/tags/tor-0.2.1.5-alpha^{}
+0049c7d95faaf2dba3075ae2573b6f2a3dca7ba133a2 refs/tags/tor-0.2.1.6-alpha
+004ca04baf14b6aa0260eb7bcc44e88df09826e3a82b refs/tags/tor-0.2.1.6-alpha^{}
+\r
+12a\r
+0049492958402c4d0787a62dc048043b32a1604dd54d refs/tags/tor-0.2.1.7-alpha
+004c5d19fe51247cab0f4990fe40196d526da1e7a505 refs/tags/tor-0.2.1.7-alpha^{}
+0049cb4cc56962ea87b986fa21ab9522991d4c82d0e6 refs/tags/tor-0.2.1.8-alpha
+004c07c8b2be214cc289f691c6fa5bbb96de7412a3b5 refs/tags/tor-0.2.1.8-alpha^{}
+\r
+49\r
+00496476f56a699ae2a157eb892073970f8c0f1d0d8f refs/tags/tor-0.2.1.9-alpha
+\r
+4c\r
+004c41aef35963efb37b85ac7ea1d24b3bd1dea936cb refs/tags/tor-0.2.1.9-alpha^{}
+\r
+df\r
+004915d2e1911f05c724c9ac6c067f81581498fe3aac refs/tags/tor-0.2.2.1-alpha
+004c1092fdca53ec0110b4e4c0bf51a5881ee68c4ac8 refs/tags/tor-0.2.2.1-alpha^{}
+004af6a31db576b7677ec31bd23e4c42c5ad4c918f3c refs/tags/tor-0.2.2.10-alpha
+\r
+4d\r
+004d81b84c0b017267b4279e18cb5143118efc43ed1c refs/tags/tor-0.2.2.10-alpha^{}
+\r
+12e\r
+004a9bd59f1b009d2cad9ed2cf052897b7a3e8356200 refs/tags/tor-0.2.2.11-alpha
+004d9cde5a4629769d422d28f4b4b71fa87e3d64aa09 refs/tags/tor-0.2.2.11-alpha^{}
+004a414b9ea0ffdd644dd85bebda27f7c66421422724 refs/tags/tor-0.2.2.12-alpha
+004d3d8879a04da79b014700b01f1ed2e8d685040dfb refs/tags/tor-0.2.2.12-alpha^{}
+\r
+12e\r
+004a662522f4390dc986cbe56bc160e250b76946cdf0 refs/tags/tor-0.2.2.13-alpha
+004dfeb8c1b5f67f2c6f4ffe049236e958d26ca5b376 refs/tags/tor-0.2.2.13-alpha^{}
+004a9bd8aace4ad9cfafef973ab9d89de5c674eb37b9 refs/tags/tor-0.2.2.14-alpha
+004d06a79233c57393bc500d27e93a057ebc874bf51d refs/tags/tor-0.2.2.14-alpha^{}
+\r
+12e\r
+004a5797b96f9f6e992ee068d4d854f2c72c14a35607 refs/tags/tor-0.2.2.15-alpha
+004deba3f37f17a2af4ff628dd5cbc653441e6dce6eb refs/tags/tor-0.2.2.15-alpha^{}
+004a17684cd591b8bc7b87caf0302cd85db4e6936cee refs/tags/tor-0.2.2.16-alpha
+004d61e0079ab25db6c31c0b68711e051738a7e5122a refs/tags/tor-0.2.2.16-alpha^{}
+\r
+12e\r
+004ac615c6d2ff1edd7b75a55572a251a06c59db0eab refs/tags/tor-0.2.2.17-alpha
+004ddadd9608d2720368c78e01f485fc2e2783e6a677 refs/tags/tor-0.2.2.17-alpha^{}
+004ab91dc93c1c43f6505cdfe99c6e2ce79e5f16b20e refs/tags/tor-0.2.2.18-alpha
+004d910de7dfac82f3148cff32005de8c0cb4c1042a6 refs/tags/tor-0.2.2.18-alpha^{}
+\r
+e0\r
+004aa2ff4819c3c25a36caef191f29ed4ae8cd8939df refs/tags/tor-0.2.2.19-alpha
+004de57cb6b9762a2f94818738b5790d09c292e1bc24 refs/tags/tor-0.2.2.19-alpha^{}
+0049b8c97b9ab5ec674e1e35daf8e9bb2242faad20de refs/tags/tor-0.2.2.2-alpha
+\r
+4c\r
+004c54ba86d9d0cff2ceef75d564ece3d7d2ea26af26 refs/tags/tor-0.2.2.2-alpha^{}
+\r
+4a\r
+004a3da07914a732f6df129b95ec2efab146a75395c9 refs/tags/tor-0.2.2.20-alpha
+\r
+4d\r
+004daae58deb2cdcaad0ccfbccf26be83a79aad41efa refs/tags/tor-0.2.2.20-alpha^{}
+\r
+12e\r
+004a0761be597f8effc3c707d56ae59c82fb180176fb refs/tags/tor-0.2.2.21-alpha
+004d5f63f0d6312d9f0d66b736f872657fd20f10551c refs/tags/tor-0.2.2.21-alpha^{}
+004aa2c6315e560a15994acb55bfffc7fbf65086a281 refs/tags/tor-0.2.2.22-alpha
+004de5e38e55b33b2cc037c483a38383ab7cfca741fe refs/tags/tor-0.2.2.22-alpha^{}
+\r
+4a\r
+004aa060e931b0655a76174817020a777487153e4c93 refs/tags/tor-0.2.2.23-alpha
+\r
+4d\r
+004db85eb949b528f4d7c6e6a07a550866bb334fd40b refs/tags/tor-0.2.2.23-alpha^{}
+\r
+97\r
+004a77b0a2a1eb310fa642c7b82b274f480738a705c1 refs/tags/tor-0.2.2.24-alpha
+004dc111adb5fe757ea9baf9aaca151af7e8cd5e5808 refs/tags/tor-0.2.2.24-alpha^{}
+\r
+4a\r
+004a2c35a188496d54b1bcc1a17f47ad69465ccd6ad1 refs/tags/tor-0.2.2.25-alpha
+\r
+4d\r
+004d10d45f8d45accdd920918e1980ee45fde1a3d8c4 refs/tags/tor-0.2.2.25-alpha^{}
+\r
+95\r
+004953993ff13eae541c16350dc4b585aa02433e91a2 refs/tags/tor-0.2.2.26-beta
+004cdb3cd62e97294fa14b5b4ecdb3cd1ab7b249b8a5 refs/tags/tor-0.2.2.26-beta^{}
+\r
+12a\r
+0049ee20e4ad993acde3efe6cba02253e8ecb9e2b4f7 refs/tags/tor-0.2.2.27-beta
+004ce3b8457eb38ee76a6912754530a255e4d05b6910 refs/tags/tor-0.2.2.27-beta^{}
+00492218ba7a0857c3a126b21899987fc39b39b59631 refs/tags/tor-0.2.2.28-beta
+004ce084c6fd14caba9567af19cf33f25c4d7a0ac323 refs/tags/tor-0.2.2.28-beta^{}
+\r
+de\r
+0049dfa3c6d03c89028299a737a1219b1f84bfd4dd28 refs/tags/tor-0.2.2.29-beta
+004c2ea53fc0478aaf91c2dd11d520e02da9b2bebd94 refs/tags/tor-0.2.2.29-beta^{}
+00499d213e44e45895f8259d7116f5c3d91d091ce0b3 refs/tags/tor-0.2.2.3-alpha
+\r
+4c\r
+004c0f3417d1dbffdf7a894cb02ac90ecf3de9d2cea7 refs/tags/tor-0.2.2.3-alpha^{}
+\r
+d8\r
+0047f29998d93baa6fa3952d407575def8d0e3cc5722 refs/tags/tor-0.2.2.30-rc
+004a085c9754ccae6caeea2db01e25a749786b6aa84b refs/tags/tor-0.2.2.30-rc^{}
+0047f4a33b9d49581e6e5386d4965350972f08720b3d refs/tags/tor-0.2.2.31-rc
+\r
+4a\r
+004add18fcbbae84a9ac234591ebeb9d88e24abb7158 refs/tags/tor-0.2.2.31-rc^{}
+\r
+cf\r
+0044959ea4eb3db80e2d70cd28cb9b9847b7f6082070 refs/tags/tor-0.2.2.32
+0047877e17749725ab88d7afef5654a3b6d4b668c6bb refs/tags/tor-0.2.2.32^{}
+0044430fd7a34b6f4ca722479a1384224f892b82dac6 refs/tags/tor-0.2.2.33
+\r
+47\r
+00478522652d8e9213d4adf6d1d712c233ad8c9190f7 refs/tags/tor-0.2.2.33^{}
+\r
+44\r
+0044491151cb6e728e47d90771486917d2087685ddeb refs/tags/tor-0.2.2.34
+\r
+47\r
+0047c4eae752f0d157ce1f0f820b4491ca33be86a2ba refs/tags/tor-0.2.2.34^{}
+\r
+cf\r
+004484d6665c4f168d5efcd3eb528b1d0d022754095b refs/tags/tor-0.2.2.35
+0047b04388f9e7546a9f0c77f0d72e41fefb4106d2b5 refs/tags/tor-0.2.2.35^{}
+00446bbdf8cfca2859a8faec46b49656ff52aebb7c07 refs/tags/tor-0.2.2.36
+\r
+47\r
+0047c1414cf70cbfcbb7ad053370f299e7159a85ffc3 refs/tags/tor-0.2.2.36^{}
+\r
+116\r
+0044ae59fc514638b7241891e356929489c516140f76 refs/tags/tor-0.2.2.37
+0047fce6eb1c44e87bc20e1cf62bd46d8fe6e356008e refs/tags/tor-0.2.2.37^{}
+0044b1e604f8394ba9cc867990be3acb2c6ef4746648 refs/tags/tor-0.2.2.38
+004749d150a9fad2cb8d3887af1e112b15365c11f4ba refs/tags/tor-0.2.2.38^{}
+\r
+120\r
+0044b506659865152603faf5fc9e709aa6881bbee19e refs/tags/tor-0.2.2.39
+0047bec76476efb715498b86282d4969c096df336140 refs/tags/tor-0.2.2.39^{}
+004907f9d858aa7bd55e82e60b7d67125b75f5c9618a refs/tags/tor-0.2.2.4-alpha
+004c2f760c54615f9044cad93392c030ef24119026e2 refs/tags/tor-0.2.2.4-alpha^{}
+\r
+12a\r
+0049b8ef9f12e3d7907963cf8d2155768090b3a65033 refs/tags/tor-0.2.2.5-alpha
+004c9d6c79cbbbd21fe685de7cb45f98636dac2f0b36 refs/tags/tor-0.2.2.5-alpha^{}
+00498d844f82849d94cb3ae06c5ea85eb84076ff840e refs/tags/tor-0.2.2.6-alpha
+004c1ee580407ccb91304cf7ae24c0d809f57e6b4ccc refs/tags/tor-0.2.2.6-alpha^{}
+\r
+12a\r
+00497329a658d0c84807adfd32fa06de72a34094d53c refs/tags/tor-0.2.2.7-alpha
+004cc939509051f90d7276355783b255d4a15730efab refs/tags/tor-0.2.2.7-alpha^{}
+00494910cb25694b3b5b6bc2572d790be2ad13a2b32d refs/tags/tor-0.2.2.8-alpha
+004cff88bc7db8edeb290d1905a34442ba7740a90a90 refs/tags/tor-0.2.2.8-alpha^{}
+\r
+de\r
+00499b92daa101835d09817224c94376044a6686c300 refs/tags/tor-0.2.2.9-alpha
+004c2e159967c9871477a20a7caeb6d73c83025ff7c1 refs/tags/tor-0.2.2.9-alpha^{}
+0049a1f41416734c8e4772d4c2037c5732743a1d215b refs/tags/tor-0.2.3.1-alpha
+\r
+4c\r
+004c5cabdc8f679c4124523a1cc02ac1e22ab86b8502 refs/tags/tor-0.2.3.1-alpha^{}
+\r
+4a\r
+004a7590a1315dd97b4b88a735b5b716fcfd61fc7d0c refs/tags/tor-0.2.3.10-alpha
+\r
+4d\r
+004d1fbce83f8c56d9c66eee9ac115c5d7f9211eefb5 refs/tags/tor-0.2.3.10-alpha^{}
+\r
+12e\r
+004a81983ede27cf8ef6a03c5298f73923e5436ec4e2 refs/tags/tor-0.2.3.11-alpha
+004d9ce9836f853d8a31cde1c6ddd7c4e865099a582a refs/tags/tor-0.2.3.11-alpha^{}
+004a61a9179a12ca83893060c07011f0c8bbbef3bd94 refs/tags/tor-0.2.3.12-alpha
+004d800942b4176ca31cbdc03edb6469fd56d2e1acdc refs/tags/tor-0.2.3.12-alpha^{}
+\r
+e1\r
+004aa4397f08bd065fc4bbba14e06242f0a91124252b refs/tags/tor-0.2.3.13-alpha
+004dde73e3692a6d83774027ac9d29e1ec8608076385 refs/tags/tor-0.2.3.13-alpha^{}
+004ade5f9bb4f5a39e5396ffb840f240858b259e5185 refs/tags/tor-0.2.3.14-alpha
+\r
+4d\r
+004d9ebf858824796a3d9cb97580d0970c7881b473e7 refs/tags/tor-0.2.3.14-alpha^{}
+\r
+97\r
+004a7b356a45adbe47f644b1e5af30068ed1b8eba702 refs/tags/tor-0.2.3.15-alpha
+004d2513a3e959b616126f2c0a050e9f8f9593721ef7 refs/tags/tor-0.2.3.15-alpha^{}
+\r
+97\r
+004a8f9966feadb060bcb253bc84066386736f9e4b1d refs/tags/tor-0.2.3.16-alpha
+004de94606a76b98752dac30f366a6eb6877e3438b51 refs/tags/tor-0.2.3.16-alpha^{}
+\r
+49\r
+00495dbef2784f48c34dd90af39e0a4c98e394f8eda0 refs/tags/tor-0.2.3.17-beta
+\r
+4c\r
+004c1e1c7d779eb47fd67e8e01592b434812ffcf134d refs/tags/tor-0.2.3.17-beta^{}
+\r
+d8\r
+0047f249b8e3b8c552e62b166a4e51bf1ee8ed86267e refs/tags/tor-0.2.3.18-rc
+004a64f8e68e65f32c742eab85d993da2a838f90dcf3 refs/tags/tor-0.2.3.18-rc^{}
+0047b9fb482bb2249824ba3fb370cdcb541fdb05d2d1 refs/tags/tor-0.2.3.19-rc
+\r
+4a\r
+004ad8d78f085adef4a3dd9d3c20983daa8571a44097 refs/tags/tor-0.2.3.19-rc^{}
+\r
+126\r
+004993c7136c01f1cc474f84f5908b9bac10dabdf97a refs/tags/tor-0.2.3.2-alpha
+004cbceb136840815bf5014b95adef52eb832fb0b99c refs/tags/tor-0.2.3.2-alpha^{}
+004733b24a09b080446d61e630002335a719f27b93f2 refs/tags/tor-0.2.3.20-rc
+004a24d7a06f04d701c4dd263b911906cb1e97672e99 refs/tags/tor-0.2.3.20-rc^{}
+\r
+47\r
+004769fcb6c76de6b9e66405afe88fdbb18bc86b2de7 refs/tags/tor-0.2.3.21-rc
+\r
+4a\r
+004a139a81c96d4af2f52b1f3d76adc4079403c8d2d7 refs/tags/tor-0.2.3.21-rc^{}
+\r
+d8\r
+0047919ea020348ad0d21c96f4881895079d2fcf93a7 refs/tags/tor-0.2.3.22-rc
+004a213ba1a70b41ea975f2e0119a746aa1bad6f1e22 refs/tags/tor-0.2.3.22-rc^{}
+0047146a84955bd7f9dffe3e509c9e9ee4d03a487be4 refs/tags/tor-0.2.3.23-rc
+\r
+4a\r
+004a3a2b86ef5d576e55defb3a9a1e37bee48b7b3d6a refs/tags/tor-0.2.3.23-rc^{}
+\r
+11c\r
+00478d00658584591cb04c3c4680a9b53dd74ea46ef7 refs/tags/tor-0.2.3.24-rc
+004a4f228f39ec74abfa1a806d944a2d84edb63a5757 refs/tags/tor-0.2.3.24-rc^{}
+0044e361312c50307a2279cda4c4aa884584697646e4 refs/tags/tor-0.2.3.25
+004717c24b3118224d6536c41fa4e1493a831fb29f0a refs/tags/tor-0.2.3.25^{}
+\r
+49\r
+0049f3fec4e995e1b4ea24ca73405972e9795331dcdd refs/tags/tor-0.2.3.3-alpha
+\r
+4c\r
+004c01357d6b163b1823811435871c92d6972b4eb65d refs/tags/tor-0.2.3.3-alpha^{}
+\r
+12a\r
+00496b0fd72197044b242846ee1b099d3e7794d2a16c refs/tags/tor-0.2.3.4-alpha
+004c5f4f727d58daa194656ec43880a6151e88f5c0a2 refs/tags/tor-0.2.3.4-alpha^{}
+004953f8c549015652e8c3444e5b1cb60e42baa9f586 refs/tags/tor-0.2.3.5-alpha
+004c1fac96f4c6c399561f80109e71b2441fa06ac808 refs/tags/tor-0.2.3.5-alpha^{}
+\r
+12a\r
+00490ea474bb10e9986dfcc3bb03a8225639f3ed4c73 refs/tags/tor-0.2.3.6-alpha
+004c47dff61061f4bfc2ad5f1992a11b48e5c7ad94af refs/tags/tor-0.2.3.6-alpha^{}
+0049fbf9b1af0e0cd0d9855b47f024bd7b0b2d3367bd refs/tags/tor-0.2.3.7-alpha
+004cc2d03beb65d0c82035be714666bfd0e9fc7c3060 refs/tags/tor-0.2.3.7-alpha^{}
+\r
+12a\r
+0049c855028e71c1d2a90287fe3e7abed1234d71be80 refs/tags/tor-0.2.3.8-alpha
+004c68475fc5c5a806ebbb5657de1667dab2c3e09b7c refs/tags/tor-0.2.3.8-alpha^{}
+00494bc8751e56a215d6b9dee4a8bccfda53b613791c refs/tags/tor-0.2.3.9-alpha
+004ce44205ee6c3816b8b1f31e62809a8ca053afb033 refs/tags/tor-0.2.3.9-alpha^{}
+\r
+12c\r
+00497f20f3c066b64cd1e58357dbe6318580b15002fd refs/tags/tor-0.2.4.1-alpha
+004c237129847b824925058975f8da665cd8cb1bed13 refs/tags/tor-0.2.4.1-alpha^{}
+004aeabac6f23896c8b25005986e68a2947dc7c9caa5 refs/tags/tor-0.2.4.10-alpha
+004d54f9a402c5f68633cc46c90364741fe1bd28e0da refs/tags/tor-0.2.4.10-alpha^{}
+\r
+12e\r
+004a7784d1d818af9bddeb39266159593b6539d7da59 refs/tags/tor-0.2.4.11-alpha
+004dfcd9248387249d68619734a73860ffaab12b021b refs/tags/tor-0.2.4.11-alpha^{}
+004a7daf1a4bd35cd975c6daa04ee63a439f2e7c33bb refs/tags/tor-0.2.4.12-alpha
+004d91b8bc26f160f172e2d358d20fc8a3bc150e092d refs/tags/tor-0.2.4.12-alpha^{}
+\r
+4a\r
+004a1ae021e420e10138298cf610b63cf536332a1fd8 refs/tags/tor-0.2.4.13-alpha
+\r
+4d\r
+004ddcb4f22506c7763dee9fbf6139df9dc11d41b184 refs/tags/tor-0.2.4.13-alpha^{}
+\r
+128\r
+004a6148d1bb786d249b80c68ffb636904d9893ae290 refs/tags/tor-0.2.4.14-alpha
+004df5729b8c1d45933f57e8df432c63197ecf8f266e refs/tags/tor-0.2.4.14-alpha^{}
+0047c0d6e2656218bdfd130018e149858fd077f13605 refs/tags/tor-0.2.4.15-rc
+004ae7b435872cce464fee8efa75cdb228f07a367c2b refs/tags/tor-0.2.4.15-rc^{}
+\r
+47\r
+0047ba9c51942df3ead71348ba163dff9507a043c4b0 refs/tags/tor-0.2.4.16-rc
+\r
+4a\r
+004a889e9bd5292972842eb6d02dbce2c6589dd3ccfe refs/tags/tor-0.2.4.16-rc^{}
+\r
+122\r
+0047c0b92122f0c0ba494002ca9973cc122a72174c74 refs/tags/tor-0.2.4.17-rc
+004a00fb525b23cf070fb229e1073caae47e6401f1e2 refs/tags/tor-0.2.4.17-rc^{}
+00479e7006bb0133357448a51697de5fa8f0f64c439e refs/tags/tor-0.2.4.18-rc
+004a1cda452bc136de6bad4f203cea8f195599aec242 refs/tags/tor-0.2.4.18-rc^{}
+\r
+8b\r
+0044d25dc5590dbc0f4a8484f4c9c49e8dcbc60c3e0a refs/tags/tor-0.2.4.19
+0047e719d05fd296a9dd59af9becb21ef3ff1c426b3c refs/tags/tor-0.2.4.19^{}
+\r
+49\r
+0049e5d5b8a46d0bd9e289c1ea760c95b380c58c221e refs/tags/tor-0.2.4.2-alpha
+\r
+4c\r
+004c77d17a360767d8a14ce42a1dd91a8c65973bb768 refs/tags/tor-0.2.4.2-alpha^{}
+\r
+cf\r
+00444576ffa537c684e0926bad413ba99b59f7897b57 refs/tags/tor-0.2.4.20
+00473cb5c70beec5bf46b9e70b1fc6287a1c1c7847ee refs/tags/tor-0.2.4.20^{}
+0044b0073f6099bad2d715e2f9a7bc67a637496026e4 refs/tags/tor-0.2.4.21
+\r
+47\r
+0047505962724c05445fa0f0354e990e6cb60ef193e9 refs/tags/tor-0.2.4.21^{}
+\r
+44\r
+004496440f47e07f2a3c7601576bf0630370b3b8ad25 refs/tags/tor-0.2.4.22
+\r
+47\r
+00472ee56e4c2c841a45418cfb826e1ce6689278382d refs/tags/tor-0.2.4.22^{}
+\r
+cf\r
+004492076ef657e2ea655b2f08992256d7a86fbb182f refs/tags/tor-0.2.4.23
+0047598c61362f1b3d3e3a93d15240c7306d955273be refs/tags/tor-0.2.4.23^{}
+004473561cd6745916a22d4eebcb4f5324118470d2d5 refs/tags/tor-0.2.4.24
+\r
+47\r
+0047f48def202c897758e3f1c65ae0773d71e5094158 refs/tags/tor-0.2.4.24^{}
+\r
+44\r
+0044ea7001cc910d4744523c1fe67da119c8cb7e5f84 refs/tags/tor-0.2.4.25
+\r
+47\r
+00476b2ed1a905ce2ca50a480d319368b676de124d6d refs/tags/tor-0.2.4.25^{}
+\r
+116\r
+004456f8b5f6107dfe9e8c8d262a20b7971a4d63a2ca refs/tags/tor-0.2.4.26
+0047d461e7036fe5cddf390be249436c66286ce992c3 refs/tags/tor-0.2.4.26^{}
+0044e497d616fce453059e6799f12c3ce28e8d2764c1 refs/tags/tor-0.2.4.27
+004785169a121e3b59d2032281e72e0e14a53b6085a2 refs/tags/tor-0.2.4.27^{}
+\r
+116\r
+0044f3cd3af5b38b6a0da7922f3da6e20b6c24f438ea refs/tags/tor-0.2.4.28
+004716bbbe82e42d02e2a251535de576c77d60e2a4bb refs/tags/tor-0.2.4.28^{}
+0044fe35d085e5ea98487ef7d0db44eda5ce4a6bb0f3 refs/tags/tor-0.2.4.29
+0047f833164576c3343ab0f20bda903544f7b4dafdfe refs/tags/tor-0.2.4.29^{}
+\r
+95\r
+0049f0cc6f62affc6c376cc2ad6ffc284a4c38684424 refs/tags/tor-0.2.4.3-alpha
+004c3355976bb472c9a5916b20c83ecdf03a9fde20f6 refs/tags/tor-0.2.4.3-alpha^{}
+\r
+12a\r
+0049d85a40e5e2fc0467e7fff55153a1d2b7b11246be refs/tags/tor-0.2.4.4-alpha
+004cfe3b95f3596194276eac8d1644cec56263a0cf0e refs/tags/tor-0.2.4.4-alpha^{}
+00498969df16911297f6cc823128fce579d176d2c281 refs/tags/tor-0.2.4.5-alpha
+004c17a6aa56cefe9d833a14bffd8e972099dadd2c88 refs/tags/tor-0.2.4.5-alpha^{}
+\r
+12a\r
+00499e36d9ba787e21c7d71bea6209553efb49964086 refs/tags/tor-0.2.4.6-alpha
+004cb13c6becc892d9716d8645f16b5d03bdb0b34651 refs/tags/tor-0.2.4.6-alpha^{}
+0049daad79eb8506e7cb945578cf2a70e641fd29a083 refs/tags/tor-0.2.4.7-alpha
+004ce46e1ed1bc50ad24ee8272efc425d4194a750afd refs/tags/tor-0.2.4.7-alpha^{}
+\r
+49\r
+0049e7fb3977cc20063b49c0c8f9780d1cda12971438 refs/tags/tor-0.2.4.8-alpha
+\r
+4c\r
+004c26cffd3b8656bdec13426ac077e6b4f3ecef9d6c refs/tags/tor-0.2.4.8-alpha^{}
+\r
+12a\r
+0049a9f2c984a4b04ed1663f74e8f97b2ca9077b1184 refs/tags/tor-0.2.4.9-alpha
+004c23dd7c901287d7d8282945cb22950a39f5bcdfd2 refs/tags/tor-0.2.4.9-alpha^{}
+004989890782ca3505e22e9e373ce69dad661cf96ab3 refs/tags/tor-0.2.5.1-alpha
+004ce65b54ec75e3c9e9ada33c8f3ee868d1bea167f5 refs/tags/tor-0.2.5.1-alpha^{}
+\r
+116\r
+0044b0736659ec81ed5b1a4a8b76a2712fb1a7d6a918 refs/tags/tor-0.2.5.10
+004742b42605f8d8eac25361be229354f6393967df4f refs/tags/tor-0.2.5.10^{}
+00442716814704cf56953889c904b6ca7df0dd1e5c7e refs/tags/tor-0.2.5.11
+0047cfb61f909a53c4eba54e2a1f37c52103be35f0a1 refs/tags/tor-0.2.5.11^{}
+\r
+8b\r
+0044af8ef8f21e07e9cbd79dede8de6ac4246cd46b54 refs/tags/tor-0.2.5.12
+004799d0579ff5e0349ffbcf072a42a53270ec1c5eda refs/tags/tor-0.2.5.12^{}
+\r
+116\r
+0044c0c0c76fc763c39ce44b43b7715e4cc7c34ab881 refs/tags/tor-0.2.5.13
+004745245fe29e2e5a0e36c6e4a340d44c6d98cbba1d refs/tags/tor-0.2.5.13^{}
+0044907104125c7956b13b7e1ee65f8ddf9fe3316f08 refs/tags/tor-0.2.5.14
+0047e14006a5454f555c1552094a52f8b4120c353ddd refs/tags/tor-0.2.5.14^{}
+\r
+cf\r
+0044f9e3d95596f87e4d65ec7f142ec005819dc93cbd refs/tags/tor-0.2.5.15
+00475a0e73c75b9c8dbad33044c1cdb0662bddb6de22 refs/tags/tor-0.2.5.15^{}
+0044d244a741d55d290b5ed9bc6d498301253c3b57eb refs/tags/tor-0.2.5.16
+\r
+47\r
+0047b97fb313a922f2e9f0247266e516b2b324e3e169 refs/tags/tor-0.2.5.16^{}
+\r
+12a\r
+0049ca2a9d49eb61913686b77b669256ac3571b61ae2 refs/tags/tor-0.2.5.2-alpha
+004c745434d29a92da682f4c8d8fa70a563862e80ae7 refs/tags/tor-0.2.5.2-alpha^{}
+0049e6516aa1976154d579b2257462ba6fec019d3ce3 refs/tags/tor-0.2.5.3-alpha
+004c29a67e73beae804fd9b9347aabb08072c07cbe0d refs/tags/tor-0.2.5.3-alpha^{}
+\r
+12a\r
+0049d9032eab3c2a0d1874508034adce7aad871354de refs/tags/tor-0.2.5.4-alpha
+004cd2147cc7ba5c5d5114bae61000cbf757353c3ed6 refs/tags/tor-0.2.5.4-alpha^{}
+0049333cd2e99bfe561e0574f488a72571bc730c8b46 refs/tags/tor-0.2.5.5-alpha
+004c2a8be08757ca0bbaf67d1c12859e008730bfb13f refs/tags/tor-0.2.5.5-alpha^{}
+\r
+124\r
+0049973826b85460860fd548354e716c2474cbfe2e69 refs/tags/tor-0.2.5.6-alpha
+004c390728d85644a6c062d6807ffc096343d1c1e73e refs/tags/tor-0.2.5.6-alpha^{}
+004697432b85599f954a121517b2f27877a83f7fd854 refs/tags/tor-0.2.5.7-rc
+004940233cadbbbf77214913db818a1458c6ddd14a9f refs/tags/tor-0.2.5.7-rc^{}
+\r
+d5\r
+00465eeb996f6a65e2388026c1243a7c2241a71a49d9 refs/tags/tor-0.2.5.8-rc
+0049a64f3ab3ee5c433cc1f046a7e26df7a49e308e4c refs/tags/tor-0.2.5.8-rc^{}
+0046a90740b4f74f091c9bcb722a27443cbd339d13e1 refs/tags/tor-0.2.5.9-rc
+\r
+49\r
+0049334f4f60e88ae44450983e1d96bb783cd373455e refs/tags/tor-0.2.5.9-rc^{}
+\r
+120\r
+004942679f71161cafaa2651b3f5ba69aba0fff01a7d refs/tags/tor-0.2.6.1-alpha
+004c5a601dd2901644a537621f407f072d634ece2cfe refs/tags/tor-0.2.6.1-alpha^{}
+004423cb0a0d7c5f73f4a7bbebed707d66179180ee0e refs/tags/tor-0.2.6.10
+004758c51dc6087b093690ab15b7cd0ce627a6115e80 refs/tags/tor-0.2.6.10^{}
+\r
+cf\r
+0044495dd306fc07bb09737d886e50b768a184054f4b refs/tags/tor-0.2.6.11
+0047c0c68547ead7e1884c98adf4110a155c88b1f5b5 refs/tags/tor-0.2.6.11^{}
+004460eef1857ef3272eb0de632490d1ad115b374e18 refs/tags/tor-0.2.6.12
+\r
+47\r
+004721a9e5371d39db388a56654afd0b7cd4d6b60182 refs/tags/tor-0.2.6.12^{}
+\r
+49\r
+00497f1a58e0deba1262a8453807984e24c4fcdab777 refs/tags/tor-0.2.6.2-alpha
+\r
+4c\r
+004c6cb1daf062df525224ee7e3f7cd63ee858aacf9f refs/tags/tor-0.2.6.2-alpha^{}
+\r
+124\r
+00491ebace122d2507472f98cb04f821ceeeda6ea4fc refs/tags/tor-0.2.6.3-alpha
+004c7df7e8d71d7afc422ae3ce9514743e96ea0bcf25 refs/tags/tor-0.2.6.3-alpha^{}
+0046c1f1215b2213998a42111c017797448d5947460f refs/tags/tor-0.2.6.4-rc
+00490c2e4aec7b8b2024a93c2ee5a7d97bdc45501f70 refs/tags/tor-0.2.6.4-rc^{}
+\r
+118\r
+004688107dc6853e453c21615be3be0eece41e6b2530 refs/tags/tor-0.2.6.5-rc
+0049e0b77cd3194d705f9bca254f8a95e520070ca365 refs/tags/tor-0.2.6.5-rc^{}
+0043f55e0017333619276fa1da2943c6336599b5657b refs/tags/tor-0.2.6.6
+0046bb8c4e69ca5c8bcad7d66b2ad502ab35b1a5032b refs/tags/tor-0.2.6.6^{}
+\r
+cc\r
+0043a7280f857d97e76b43c8050ba74c36c1dfddb71d refs/tags/tor-0.2.6.7
+00469ccf019b168909ef6674c71aebda9f90516bb6a1 refs/tags/tor-0.2.6.7^{}
+0043d26cc098fee89512f8c58ac59bdd4938fa5a822e refs/tags/tor-0.2.6.8
+\r
+46\r
+00465c8440b13bde6c8847b9a54d12dadde26f6d37ed refs/tags/tor-0.2.6.8^{}
+\r
+43\r
+00437b431fe76638ae3101a046d20f189eb6c4f9729c refs/tags/tor-0.2.6.9
+\r
+46\r
+0046d41ab97294ec69c748566f4cb610f899d9976572 refs/tags/tor-0.2.6.9^{}
+\r
+dc\r
+0048263f5b8918f6ccfc09ee4884cb1f9bb8d287c348 refs/tags/tor-0.2.7.0-root
+004be49d63a7cedf9a71ffc57a81941a5dbd1af227c1 refs/tags/tor-0.2.7.0-root^{}
+004910ece0915b2284d5035cd31ac0dff9d072b8d1ca refs/tags/tor-0.2.7.1-alpha
+\r
+4c\r
+004cdf76da0f3bfd6897362d2a8a92241167b67fd7a3 refs/tags/tor-0.2.7.1-alpha^{}
+\r
+124\r
+00493ee61bfe4d59a6b07aba414eeef2c78023cee94f refs/tags/tor-0.2.7.2-alpha
+004c36c0ae6f7834af16c379ac399edf7af514cafbb5 refs/tags/tor-0.2.7.2-alpha^{}
+00464d55c0e104744681f34287fe8dc7f0d9c69151f2 refs/tags/tor-0.2.7.3-rc
+00499a4cac74fd2f4bb300830e06ff56f74ccf91e373 refs/tags/tor-0.2.7.3-rc^{}
+\r
+46\r
+004643f742e42b7236cfc902c22bccb16718e86a27dc refs/tags/tor-0.2.7.4-rc
+\r
+49\r
+0049f55d23e1e66e9b0f6971016a9c880341e0209db0 refs/tags/tor-0.2.7.4-rc^{}
+\r
+cc\r
+0043bbe3e0ef0571380ded8ab6e572aa8d91b3fc7b93 refs/tags/tor-0.2.7.5
+0046b6024ec1498edbf8a0b89e1575adb932469d4497 refs/tags/tor-0.2.7.5^{}
+00433142eb1ae432e9ca055eb109e46d58d6f4d4a39d refs/tags/tor-0.2.7.6
+\r
+46\r
+00467a489a638911012069981702065b952a5809d249 refs/tags/tor-0.2.7.6^{}
+\r
+cc\r
+004338a6c605a43d4aad064262b2d274fff509acefca refs/tags/tor-0.2.7.7
+0046da819deb56009e91517f793c789308ec26468791 refs/tags/tor-0.2.7.7^{}
+004303cd3c4146d16d424637c82254c728004af6d634 refs/tags/tor-0.2.7.8
+\r
+46\r
+00463db01d3b565032c777e62d7049a29483a41120e3 refs/tags/tor-0.2.7.8^{}
+\r
+49\r
+0049657b754919ce4b4cc10f9734bdcdcb9a317d4813 refs/tags/tor-0.2.8.1-alpha
+\r
+4c\r
+004c9093e3769746742f95a2a11eb9f8dc2f6d8eb4dc refs/tags/tor-0.2.8.1-alpha^{}
+\r
+8b\r
+00446c42ead31168cfa3358ba1257c44bf23d57544d8 refs/tags/tor-0.2.8.10
+004774d091887c5405585e67694cd890c91766e87864 refs/tags/tor-0.2.8.10^{}
+\r
+8b\r
+0044b2afe1ddfc1c3b435cdd22102fa4485f4b1a7e8e refs/tags/tor-0.2.8.11
+004731e7b47fbebe8cafd9dc1c930cc85585116cdc0f refs/tags/tor-0.2.8.11^{}
+\r
+8b\r
+0044f1203f42915dd6d390f356f2a46b5bd1eed1f6bf refs/tags/tor-0.2.8.12
+00479b3b49f83e2f050bc6f7877479fcee7f997694e5 refs/tags/tor-0.2.8.12^{}
+\r
+cf\r
+004414f5d01b2e736872eb7f4d6fbd12457261a36e41 refs/tags/tor-0.2.8.13
+00474e5df7355514377338c3b284950daedd7091edbd refs/tags/tor-0.2.8.13^{}
+0044c7577a00ee799da5f7ac0ae382a1db4bb4d535c7 refs/tags/tor-0.2.8.14
+\r
+47\r
+004764ac28ef5dae7b41d77d64d66f4582ffadbab196 refs/tags/tor-0.2.8.14^{}
+\r
+44\r
+00448f80383d14ae5d237f3e80d05997f17c6d8bc70b refs/tags/tor-0.2.8.15
+\r
+47\r
+0047e25e980285a80231956dba6d3c89a25c27fdf94f refs/tags/tor-0.2.8.15^{}
+\r
+116\r
+0044c905e8fc990ad02397fd57e7b92f7259675e6956 refs/tags/tor-0.2.8.16
+0047cff872f5155bdaf1aee8be48b6e1cb701f736ee7 refs/tags/tor-0.2.8.16^{}
+0044cb5e24aa6598b7392bfbce5143fbde13f5d24784 refs/tags/tor-0.2.8.17
+004793379889003a6d8df14a1e1262c9c8b8b994107a refs/tags/tor-0.2.8.17^{}
+\r
+12a\r
+00492735d26dec3a6c0131945d7c9b1093f8bedc4624 refs/tags/tor-0.2.8.2-alpha
+004c684babee8491c3e98f8b4cce7854127cf4ed3319 refs/tags/tor-0.2.8.2-alpha^{}
+0049f4718111970a7df728f6eca23130825a3b3b9188 refs/tags/tor-0.2.8.3-alpha
+004cc90f808ebc3af50d6408e6c1d8eed819536263e7 refs/tags/tor-0.2.8.3-alpha^{}
+\r
+11e\r
+004648dcea04ff2ba1eae8d5bb611c0b7ea428c708cf refs/tags/tor-0.2.8.4-rc
+0049fa6a228ce86c2737447f32c78eedc00083eb826c refs/tags/tor-0.2.8.4-rc^{}
+0046c6cf315beaaff0fa92fed53fa5187eba745d421e refs/tags/tor-0.2.8.5-rc
+0049a5b953ae2108803833cfd37e25d7a786bfa4538d refs/tags/tor-0.2.8.5-rc^{}
+\r
+112\r
+00435d33ebc916bb37f43aeed89897be01e2cff99643 refs/tags/tor-0.2.8.6
+00464d217548e3f05569da1d3806a0a9b3817ec2fb54 refs/tags/tor-0.2.8.6^{}
+00431960aca6971acd533f83a72ac2e2ec4dcf91bfbb refs/tags/tor-0.2.8.7
+0046263088633a63982a8d6ddffd3ed3e3d85cffd6f1 refs/tags/tor-0.2.8.7^{}
+\r
+112\r
+004325bcf6308a2947e10c967e6d0d26d5a83ba69d5b refs/tags/tor-0.2.8.8
+0046da84aec55c299d8a43566c846bec761c8321a2e3 refs/tags/tor-0.2.8.8^{}
+00439b7a46c3e70142ca851470b14d0410a7f42da3e2 refs/tags/tor-0.2.8.9
+004644c5fc6878d91d6069ed8c58ba6ad3b1f9b2963b refs/tags/tor-0.2.8.9^{}
+\r
+128\r
+0048806ff8ab1e5c047766bf84e691314b1d9df0c24b refs/tags/tor-0.2.9.0-root
+004b447b1c6b1d235e6de6b888e62bce9021895ae4b1 refs/tags/tor-0.2.9.0-root^{}
+0049a6d4ca15104a896d97e75c0a37bb1aaaf332789e refs/tags/tor-0.2.9.1-alpha
+004c8b1ea189610f4a96d1029f7ecc0fa4c321cd71e5 refs/tags/tor-0.2.9.1-alpha^{}
+\r
+cf\r
+004444f7a81b50c19ef542c70a5f5b00c9866d602bdd refs/tags/tor-0.2.9.10
+00471f6c8eda0073f464b7d23323251d72822f0a18bd refs/tags/tor-0.2.9.10^{}
+0044fa5221ab5d60235b1824f861752c0d1fa2e1e676 refs/tags/tor-0.2.9.11
+\r
+47\r
+0047aa8950022562be763eb283d972d9b5351a354773 refs/tags/tor-0.2.9.11^{}
+\r
+cf\r
+0044210882906016d91bbf56512dd2ada0a512feb605 refs/tags/tor-0.2.9.12
+00472e47bfad4f596dc39ab31bc66056a07d05715270 refs/tags/tor-0.2.9.12^{}
+0044360ad2038cbd8e96a1318559a1622cbb4e7c17b4 refs/tags/tor-0.2.9.13
+\r
+47\r
+0047fbe15d1d7a28e480408904347092e107d6de1545 refs/tags/tor-0.2.9.13^{}
+\r
+44\r
+0044275ef6cff3eb7bd5e3c845f6a20216b6c39cac95 refs/tags/tor-0.2.9.14
+\r
+47\r
+00473f9bd01bf5736ff66af34f05b4611f95fcb7ec51 refs/tags/tor-0.2.9.14^{}
+\r
+116\r
+00447b9d88a109d9208ad120488a5efac423298199ee refs/tags/tor-0.2.9.15
+004774b1ed684e30ef68e0eee52550720b8771e5f0a0 refs/tags/tor-0.2.9.15^{}
+004443689bd885f5dfd0ad4d65b9e65f51780c1f1370 refs/tags/tor-0.2.9.16
+0047645ef2e2854b2225f2b05e2cbddc92dc27a78b3c refs/tags/tor-0.2.9.16^{}
+\r
+120\r
+00444b333e6c1946caf68cc2bfdf1a556a370af06057 refs/tags/tor-0.2.9.17
+0047e057a19b74589fcac9c1da9e0f70b70ac4997734 refs/tags/tor-0.2.9.17^{}
+00497f6aaa2f74d13c2486da7c40f0e2ae4cc7435846 refs/tags/tor-0.2.9.2-alpha
+004c00ec701f8343f5523de52d10b19fe637609f735e refs/tags/tor-0.2.9.2-alpha^{}
+\r
+de\r
+0049c48292834d3069e8927848d11796325d9bf03e23 refs/tags/tor-0.2.9.3-alpha
+004c99041ef343eb66c22765ec7d43bbc61304d18955 refs/tags/tor-0.2.9.3-alpha^{}
+0049e8646ec26ba7802f5df95d90f436309a178b182f refs/tags/tor-0.2.9.4-alpha
+\r
+4c\r
+004c8b0755c9bb296ae210e83b88e099d52e40b6f2aa refs/tags/tor-0.2.9.4-alpha^{}
+\r
+49\r
+0049f4fa2728cea3de62384d93b08f725ad7dd6c4ded refs/tags/tor-0.2.9.5-alpha
+\r
+4c\r
+004c330846ac087f7b327d77e118a2bcf96839befc60 refs/tags/tor-0.2.9.5-alpha^{}
+\r
+d5\r
+00465f266efca92a7a153980e982fa96f59de271d9d9 refs/tags/tor-0.2.9.6-rc
+0049a3e07633a45d5c1609a6768347dfc92c06d19bcc refs/tags/tor-0.2.9.6-rc^{}
+0046e7aa6f24e72545d3796626ff843e5678b80b1019 refs/tags/tor-0.2.9.7-rc
+\r
+49\r
+00496b6ad81c2e140d8521307ff838f9068340e244f6 refs/tags/tor-0.2.9.7-rc^{}
+\r
+43\r
+0043fe61adc2e0bc5c66a72091945d39b4992b4c8c85 refs/tags/tor-0.2.9.8
+\r
+46\r
+004601ab67e38b358ae98775d1b30e5f83938af19d21 refs/tags/tor-0.2.9.8^{}
+\r
+d2\r
+00431b977b5c27269a24e5d994161419e9b39dbbb434 refs/tags/tor-0.2.9.9
+004656788a2489127072d513cf4baf35a8ff475f3c7b refs/tags/tor-0.2.9.9^{}
+0049117a829627d12fad51aa4e511051ee9f66b97559 refs/tags/tor-0.3.0.1-alpha
+\r
+4c\r
+004cac04fcd2e758c2258cbde8c8f31586695cb5d666 refs/tags/tor-0.3.0.1-alpha^{}
+\r
+cf\r
+00440c8cca0273a9221c92c842727590279da98aabc0 refs/tags/tor-0.3.0.10
+0047c33db290a9d8d0f921ef8ce0f49803748b5e47e0 refs/tags/tor-0.3.0.10^{}
+0044cf266cdb565173d08f68557dbfedccdb23b30299 refs/tags/tor-0.3.0.11
+\r
+47\r
+00475cb83c942584f86830ef1d13a9cd2501eea367c4 refs/tags/tor-0.3.0.11^{}
+\r
+44\r
+004488220f444421a442b143c012a0272a91d1c7e484 refs/tags/tor-0.3.0.12
+\r
+47\r
+0047700c654d70fa8dda393e471442d14aa8d74844aa refs/tags/tor-0.3.0.12^{}
+\r
+120\r
+00445873d18baafe84dcfc4198ae159c2ab2c4ab9b12 refs/tags/tor-0.3.0.13
+0047b734f871b75b2161c51b23c6fb0c39384d75c93b refs/tags/tor-0.3.0.13^{}
+0049486f9c366df2f8a83cb091ad7975579de662a64e refs/tags/tor-0.3.0.2-alpha
+004c0668d29354a874dc2b7e162f6fd9d34653fdd8ed refs/tags/tor-0.3.0.2-alpha^{}
+\r
+124\r
+0049be5595dfd28d71450de90469e41159f8485735e0 refs/tags/tor-0.3.0.3-alpha
+004cbb2ea3642d54ff03d7d60e593113f4e64e9e07ab refs/tags/tor-0.3.0.3-alpha^{}
+0046666648361882241c2a2b14d906afe4034e8a6cee refs/tags/tor-0.3.0.4-rc
+00494ed142ae9bb42f741b3626f83f89bc3a39af6a33 refs/tags/tor-0.3.0.4-rc^{}
+\r
+118\r
+0046c36117e0f532d4ee54ace037d86e3a0aabe34ead refs/tags/tor-0.3.0.5-rc
+00495eb2786600014d024484aa84d9ee42eed643798f refs/tags/tor-0.3.0.5-rc^{}
+0043ea4836aca2b380670fdb2d99dec77bd16761c0a2 refs/tags/tor-0.3.0.6
+004647d2e4f06ec26a79542865d054f01ea09304f59d refs/tags/tor-0.3.0.6^{}
+\r
+112\r
+00433ce804fb5841222728150913a083e7a04f006c66 refs/tags/tor-0.3.0.7
+0046cfd9c1bdc05826567a91ff89fd59c0cb70a436b2 refs/tags/tor-0.3.0.7^{}
+00435e8b686dfabcac87e7cdfe85cdc85dda1d563912 refs/tags/tor-0.3.0.8
+0046802d30d9b71a6d54ef5fd1278ab4858b2e76e750 refs/tags/tor-0.3.0.8^{}
+\r
+11e\r
+00432b04924993e52e210ef7429ec541bc064e0adc4c refs/tags/tor-0.3.0.9
+004622b3bf094e3270934ae0c66a38a0e656c1fd6d98 refs/tags/tor-0.3.0.9^{}
+0049a11e2547e4ce2467da71b5298ba2db987b846ae1 refs/tags/tor-0.3.1.1-alpha
+004c615dbdb0e094d4ef0b1982d06e62a8058463a28a refs/tags/tor-0.3.1.1-alpha^{}
+\r
+120\r
+00441317fba24cbb28d7609f9aa60f70ecf76d22983c refs/tags/tor-0.3.1.10
+0047e3966d47c72524091fb05faf214074f0a62d34cd refs/tags/tor-0.3.1.10^{}
+00496268b8db8e275804cf802ac59eba10780824f583 refs/tags/tor-0.3.1.2-alpha
+004c61625b8f26384a4a5d407db3f96e343c4dac36f8 refs/tags/tor-0.3.1.2-alpha^{}
+\r
+12a\r
+0049446bd9bea6a81d2539bf9f51be91aa27d85be46b refs/tags/tor-0.3.1.3-alpha
+004cdc47d936d47ffc25dc0b5e59009435cda542d240 refs/tags/tor-0.3.1.3-alpha^{}
+00496529ea60d116fdf454ee97266b33b1006a926270 refs/tags/tor-0.3.1.4-alpha
+004cfab91a290ded3e74e806cf9d05b36b6fcb695785 refs/tags/tor-0.3.1.4-alpha^{}
+\r
+95\r
+0049344a4d79577ff4a493a7a1bd98470b77bc42070f refs/tags/tor-0.3.1.5-alpha
+004c83389502ee6314658bcddd324c3652543b27da6b refs/tags/tor-0.3.1.5-alpha^{}
+\r
+1a1\r
+00461c2bc6befe6e156f4a3dc658380dab5d08659493 refs/tags/tor-0.3.1.6-rc
+0049efc306c59aa9ee1a32d1979df731f25904852709 refs/tags/tor-0.3.1.6-rc^{}
+0043358b2752cddc60fc902a5196f9c8b437493709fd refs/tags/tor-0.3.1.7
+00466babd3d9ba9318b38b5af7278875efe84055a1b0 refs/tags/tor-0.3.1.7^{}
+004378521ffe1304b278e3710d5823e824c1611c9c94 refs/tags/tor-0.3.1.8
+0046ad5027f7dc790624353ecd57796f572d5b55fa4c refs/tags/tor-0.3.1.8^{}
+\r
+89\r
+004350bcb7f32d9caf39799fe95757ed73fb43e27f1c refs/tags/tor-0.3.1.9
+0046727d3f1b5e6eeda721339151e3cd49ffa7efbb29 refs/tags/tor-0.3.1.9^{}
+\r
+95\r
+00496a10633a8fbef51c47cc5b18cd0146e05b8a50e9 refs/tags/tor-0.3.2.1-alpha
+004c290274dbb5428bc5d99926ce5d7f824165be84e8 refs/tags/tor-0.3.2.1-alpha^{}
+\r
+cf\r
+0044c4901d352f57461635d929b6da5c12133d0f4790 refs/tags/tor-0.3.2.10
+004731cc63deb69db819ed55aca406ebaaa52500730e refs/tags/tor-0.3.2.10^{}
+0044b48059c0aeecbb85906c9d49e49de64305d3d72d refs/tags/tor-0.3.2.11
+\r
+47\r
+0047ea3ecb98bd13b9eb4ef7e1ae1b08d7b12d0ffff9 refs/tags/tor-0.3.2.11^{}
+\r
+120\r
+0044fc764b75a962eb78349e68c39654df413d727379 refs/tags/tor-0.3.2.12
+0047a1507572110439604c9fc75168d0d1e585832a65 refs/tags/tor-0.3.2.12^{}
+00494b353217d27d9fc4f5275fc8b4fcc9a9538fa707 refs/tags/tor-0.3.2.2-alpha
+004ce2a2704f17415d8a63eceeaf5508174b1f66d1be refs/tags/tor-0.3.2.2-alpha^{}
+\r
+49\r
+0049642c5839e8552adf6689797fdde6fa59a084e632 refs/tags/tor-0.3.2.3-alpha
+\r
+4c\r
+004c023d756bfc04c244403ca7fb13e3e077dbe16408 refs/tags/tor-0.3.2.3-alpha^{}
+\r
+12a\r
+00491d0c4cd7ac08d35367c3bfc3f7c30d093ecf76af refs/tags/tor-0.3.2.4-alpha
+004c940308f493edd10ff8de2ef743e6872d1f8a4f9d refs/tags/tor-0.3.2.4-alpha^{}
+00496bd36d51e2f34fc69657478d5a10676ed311332f refs/tags/tor-0.3.2.5-alpha
+004cd499a5a708f7298b44dd02389412a0ce3b148f94 refs/tags/tor-0.3.2.5-alpha^{}
+\r
+95\r
+00497ea727bc4a474db39a66f31335fa270dd2312038 refs/tags/tor-0.3.2.6-alpha
+004c87012d076ef58bb9216c7952e0fd536f124aea68 refs/tags/tor-0.3.2.6-alpha^{}
+\r
+8f\r
+0046ff1308a0d348aa6c0549c40b57542e6d973224d2 refs/tags/tor-0.3.2.7-rc
+0049304e2151ac96bad8d5f27c63b070b06683d50665 refs/tags/tor-0.3.2.7-rc^{}
+\r
+d2\r
+004694639eefeb83c34555b47f01284ee3bebda0c0cf refs/tags/tor-0.3.2.8-rc
+004963b84335dc590499e5f22498383d6a3432e91ec4 refs/tags/tor-0.3.2.8-rc^{}
+004376adfe1e2a237a075dec48a22339b039fc5eb504 refs/tags/tor-0.3.2.9
+\r
+46\r
+00469e8b762fcecfece64aae70ae640aaa59fd227ca5 refs/tags/tor-0.3.2.9^{}
+\r
+e6\r
+004ded090af2f9fa8c1d9aa0dcbd6d9bc36f9b9c49f4 refs/tags/tor-0.3.3.0-alpha-dev
+0050e00f12ec6c6fda091bbf09d0bfeab057947d3808 refs/tags/tor-0.3.3.0-alpha-dev^{}
+004982a7c61520aaf80c6c767d6db4aef7da8bfe9d69 refs/tags/tor-0.3.3.1-alpha
+\r
+4c\r
+004cde8bc9eed6eaadfca33381e9b5b6c06fa432e7b5 refs/tags/tor-0.3.3.1-alpha^{}
+\r
+44\r
+00443ecde6e624baaea36dac83a7fb72878327937196 refs/tags/tor-0.3.3.10
+\r
+47\r
+00472e94df92caee0fca5e4f557bbc72b05db3364049 refs/tags/tor-0.3.3.10^{}
+\r
+116\r
+0044d0ccd6e86e73b99097043d5fddcb431cb078c4fc refs/tags/tor-0.3.3.11
+0047801af9a7e3f0f8c68294d8dd212b2eedcb481b72 refs/tags/tor-0.3.3.11^{}
+004448dfab9d646e7e3115552edd591a26c23c2d46ba refs/tags/tor-0.3.3.12
+0047f3e21c27631ee40603c1cab01b8e6b495689b69c refs/tags/tor-0.3.3.12^{}
+\r
+12a\r
+0049253088121f67fdbceac6df1f6a81d1e791234545 refs/tags/tor-0.3.3.2-alpha
+004cefc105716283bbdf44d73422b5036cb3a10c7950 refs/tags/tor-0.3.3.2-alpha^{}
+0049154d028b997301dac71677836b9407750f48bbf9 refs/tags/tor-0.3.3.3-alpha
+004cd15a7a27bb9e49bda7b3ec562e137ef3c50d64f6 refs/tags/tor-0.3.3.3-alpha^{}
+\r
+124\r
+0049c21e252d49e7f4ae7f3e1097a2607a0acda0bf3d refs/tags/tor-0.3.3.4-alpha
+004ca204a919f35441660f7b6f62e63610e75dea1e19 refs/tags/tor-0.3.3.4-alpha^{}
+004644e64d7db7d2185057a2bbf5f6d61eb9ca22a02b refs/tags/tor-0.3.3.5-rc
+004981d71f0d41adf0d8beb0ef1f7f750f20636d5c50 refs/tags/tor-0.3.3.5-rc^{}
+\r
+112\r
+0043b9599c8dbc92eebe4e11a7690211cd95d2c46232 refs/tags/tor-0.3.3.6
+00467dd0813e783ae16e6362e2e3c607476e645e2983 refs/tags/tor-0.3.3.6^{}
+004328f1b5b39048b123555c75ecf6e386c44eb577be refs/tags/tor-0.3.3.7
+0046035a35178c92da94400c13767a265053ff6c8413 refs/tags/tor-0.3.3.7^{}
+\r
+112\r
+0043d60cae78091ee5c404f85a57406006b46ce3397f refs/tags/tor-0.3.3.8
+004699f9816efa08ab83f90a307ea41844d693488fde refs/tags/tor-0.3.3.8^{}
+004390893b36d749eb2146d44278e67c1689246ffa2a refs/tags/tor-0.3.3.9
+004645028085ea188baf011524095e6fa3d55325ff49 refs/tags/tor-0.3.3.9^{}
+\r
+132\r
+004d92f717d9d88775e38c25fe4445658d439f38ec5a refs/tags/tor-0.3.4.0-alpha-dev
+0050cfff582e4d68b4026d19c4cee4c2d893aaab116f refs/tags/tor-0.3.4.0-alpha-dev^{}
+0049a5c317f8223b8b5bb535b8e8a71a1070b1722f36 refs/tags/tor-0.3.4.1-alpha
+004cdeb8970a29ef7427c3d42182d3bacc31ab602c03 refs/tags/tor-0.3.4.1-alpha^{}
+\r
+116\r
+0044a10a003f2ea485c68f0c271538a8765686af1409 refs/tags/tor-0.3.4.10
+00474f5ea89c117c66def603bc6f4d046e2142a76467 refs/tags/tor-0.3.4.10^{}
+0044b555ffe6d7946ed2dedc97465c11d1c444369e1c refs/tags/tor-0.3.4.11
+00474fd31340f3355342deebf49b586ae38bc2e9c8fe refs/tags/tor-0.3.4.11^{}
+\r
+12a\r
+00498af0e8664b30a9203a11deb87f60a4a0dc3c1cb7 refs/tags/tor-0.3.4.2-alpha
+004cbc951e83aac770d123118bf485d14490c2539048 refs/tags/tor-0.3.4.2-alpha^{}
+00499deb32bf8080cec38031a6eb944f10937d58af2b refs/tags/tor-0.3.4.3-alpha
+004ce8c256ca803b09879f52a641d8143543c22ac763 refs/tags/tor-0.3.4.3-alpha^{}
+\r
+11e\r
+00463140f6e65cec7f7d78320c73c8ce8519de6c671c refs/tags/tor-0.3.4.4-rc
+0049ab57cf6493f502abf7cc10bb800c0d01925bc0fc refs/tags/tor-0.3.4.4-rc^{}
+00469c5c315da325ea13bfbbfd47b8c693e036e21083 refs/tags/tor-0.3.4.5-rc
+0049673f3d640ef7fb05adf8533248d1b6bbbf086436 refs/tags/tor-0.3.4.5-rc^{}
+\r
+d5\r
+00462fac1059de5eaaa44a7b10f4cdf24c3c2f5a56cc refs/tags/tor-0.3.4.6-rc
+00496045c26d8442913e936e640fcf165ebfcc9d4bf1 refs/tags/tor-0.3.4.6-rc^{}
+00465a6462c3fe718c53e080a2193cc68808404690a4 refs/tags/tor-0.3.4.7-rc
+\r
+49\r
+00498465a8d84647c349d5995807b93a06f3afdd6185 refs/tags/tor-0.3.4.7-rc^{}
+\r
+43\r
+0043fd83f9f41758c02dcf0fd99d0d1da8c535af21d1 refs/tags/tor-0.3.4.8
+\r
+46\r
+0046da95b91355248ad8f3a6aa6733cc6d24915f59ce refs/tags/tor-0.3.4.8^{}
+\r
+126\r
+0043a2508bc8c163d371233994bfc4ba18a930229368 refs/tags/tor-0.3.4.9
+00464ac3ccf2863b86e79040dcd6c9568f011887c2be refs/tags/tor-0.3.4.9^{}
+004dee240d05bd9f99638b8f44f35d9eafb179758968 refs/tags/tor-0.3.5.0-alpha-dev
+0050e22822e4ae75dc59c7242d84bc306476fbd92a3b refs/tags/tor-0.3.5.0-alpha-dev^{}
+\r
+120\r
+004958eccf144654306e01c0658f4061b40436e70f92 refs/tags/tor-0.3.5.1-alpha
+004c1f9055c8845920e0aad8fc0cf3fd71b19905b2cb refs/tags/tor-0.3.5.1-alpha^{}
+00443d833dcbf1e4caa4a8e825b492b893d0caa65d0f refs/tags/tor-0.3.5.10
+004787fca699578e7190c37e68a290d72b4a77c2be40 refs/tags/tor-0.3.5.10^{}
+\r
+cf\r
+0044a5ef22b9784d4806f5346c2cca793ffbc43b2434 refs/tags/tor-0.3.5.11
+0047fc2d39af700f73859ab3e5fc5e627769867c89e4 refs/tags/tor-0.3.5.11^{}
+00449126a2ff04fa979b66bd6a40c0e1e208c18e021a refs/tags/tor-0.3.5.12
+\r
+47\r
+0047a0b827eb5b50aa818bef3a63644cf8756a53ad3f refs/tags/tor-0.3.5.12^{}
+\r
+44\r
+004432941c9c1dff5ddded6388655a395bd24870b6bc refs/tags/tor-0.3.5.13
+\r
+47\r
+0047fc4d5077482bf4c8ecf0a1aa52cec2baf4d0ca43 refs/tags/tor-0.3.5.13^{}
+\r
+44\r
+00448cc68168e60e6ee0759d172ebcecef8601ae458a refs/tags/tor-0.3.5.14
+\r
+a35\r
+004750d4300e77ea2f8f7d17aade1b9f32f38cffbcde refs/tags/tor-0.3.5.14^{}
+00497d56b346c008fa4e10098d3f3b4f1c7b77e79cc3 refs/tags/tor-0.3.5.2-alpha
+004ce62d92be5a9f1503d67d7d03e10eadcfc6be9b33 refs/tags/tor-0.3.5.2-alpha^{}
+0049dbdd5a8a265cbd1b3776e31d11d18e6636143580 refs/tags/tor-0.3.5.3-alpha
+004c444e9b37c53b0246158a4fca2e4e6e732deb8799 refs/tags/tor-0.3.5.3-alpha^{}
+00498238e34e3f09f0efd6a40c920161541233470b38 refs/tags/tor-0.3.5.4-alpha
+004ceca87ef7660ae0ba96b3f592e698e3f32f0c0357 refs/tags/tor-0.3.5.4-alpha^{}
+0049fe25ffe795c9343fa741f813da8202b474810091 refs/tags/tor-0.3.5.5-alpha
+004ca2ecc19ab923f34cc2363fa6f8c6e8d2bf9d350b refs/tags/tor-0.3.5.5-alpha^{}
+00469abbbf3846a84e647401f5057b0cece7b136d690 refs/tags/tor-0.3.5.6-rc
+0049a06093faaa65b0e0645f29c74abddcb42ac6e975 refs/tags/tor-0.3.5.6-rc^{}
+00437900101b25683548f79406f6c2879cf7f7d42473 refs/tags/tor-0.3.5.7
+00469beb085c10562a257c08abcee43434533d4fa96e refs/tags/tor-0.3.5.7^{}
+00431e3ece02bed4e14227125c087b73477c3c52e681 refs/tags/tor-0.3.5.8
+00465030edfb534245ed3f7e6b476f38a706247f3cb8 refs/tags/tor-0.3.5.8^{}
+004366042017aea0fdd005df5ac0e20ecfe1a839384f refs/tags/tor-0.3.5.9
+004672595eb021048ae9156185c0f75f19d000446f96 refs/tags/tor-0.3.5.9^{}
+00492ff016e0b8415cc2bacb09c865036a82862887b0 refs/tags/tor-0.4.0.1-alpha
+004c81f1b89efc94723f2c13b0b80d311364a2245d85 refs/tags/tor-0.4.0.1-alpha^{}
+0049d8facc02609fac2bc99ac8669d4010e28133f587 refs/tags/tor-0.4.0.2-alpha
+004cfeb744f0d488a0e5768385639311f50aab1f4f5d refs/tags/tor-0.4.0.2-alpha^{}
+0049b5481360a414e3de784001290f71bef8be2add1c refs/tags/tor-0.4.0.3-alpha
+004ceaa34dd6b9cf3ce99e153b175177842f56ef1d1f refs/tags/tor-0.4.0.3-alpha^{}
+00467c686230efa8bd7ceb4ed2a34b5f3049964bc8c4 refs/tags/tor-0.4.0.4-rc
+0049dac18e0b2085814c32070d603c4c94297ee778cc refs/tags/tor-0.4.0.4-rc^{}
+00431019a6b0c9b17e07fc160fa9bb2a5ece88024d94 refs/tags/tor-0.4.0.5
+0046bf071e34aa26e0965910d1adf424e8134b8d45d6 refs/tags/tor-0.4.0.5^{}
+004398cb58b15830539ef8eebd5c9813dabe036350cf refs/tags/tor-0.4.0.6
+004639344e410dca1dd4fda83034e725afa45a0c0bf4 refs/tags/tor-0.4.0.6^{}
+004d8ed8134587c4091280d1d2f5c101e9faa629075c refs/tags/tor-0.4.1.0-alpha-dev
+00509a158a45b1fe9f36cf0d41c5d1dcec7be74f1719 refs/tags/tor-0.4.1.0-alpha-dev^{}
+0049040efa08ecb69714ebc56237a09d3e00fe3346f9 refs/tags/tor-0.4.1.1-alpha
+004cfa410162a3309dba31661f7f22c95bbdc3af66a5 refs/tags/tor-0.4.1.1-alpha^{}
+0049cf62509fe0e28a69b4ff7c25f7b5f22d5cba9b38 refs/tags/tor-0.4.1.2-alpha
+004c3c2b2f072f996ba958ed5b6e07d3bac02291fc4a refs/tags/tor-0.4.1.2-alpha^{}
+004904e042cc926f1d651a32b83c36fb7b5b390ac235 refs/tags/tor-0.4.1.3-alpha
+\r
+41d\r
+004cd2c360c5336b43ba89c077f55461227420d14647 refs/tags/tor-0.4.1.3-alpha^{}
+00467bff1c1a1e0fd570e971df101ba37a208e3bff74 refs/tags/tor-0.4.1.4-rc
+0049716c48c250ed74a1d83e5c1c2d95ddd395c07a7e refs/tags/tor-0.4.1.4-rc^{}
+0043479fc3688b416dc2f7d2729bd2cfc244dc58b521 refs/tags/tor-0.4.1.5
+0046439ca48989ece545c3bb247640ffcde5ea368adf refs/tags/tor-0.4.1.5^{}
+004328fe861a22bd200e0ab7a0d2eea4844720673928 refs/tags/tor-0.4.1.6
+0046d10abc0929f4941d564b72a349aaf421aaa268f3 refs/tags/tor-0.4.1.6^{}
+00436473162d97a7c0c18e04bd41360d94ff6994d044 refs/tags/tor-0.4.1.7
+00460772f901b4b3b74077658c7b9585ee5ab947ad64 refs/tags/tor-0.4.1.7^{}
+0043bd3ccacd21c10c2e711568e7b40e584fe16b7a5d refs/tags/tor-0.4.1.8
+0046de79264c1d697b16ba434d111a39161757d33225 refs/tags/tor-0.4.1.8^{}
+00439fb41b8cb72a00a8be49eb893e42493dfbe53e6b refs/tags/tor-0.4.1.9
+004693ed011a26757b71630e7b61aee947337f6d4b0b refs/tags/tor-0.4.1.9^{}
+0049138e3590a1a613fe5d32b53537d92ee7cd0e5207 refs/tags/tor-0.4.2.1-alpha
+004cb5f39955d1ad14295a9ef415d13a8c6bfd25f8b9 refs/tags/tor-0.4.2.1-alpha^{}
+\r
+95\r
+0049386a0f07fb7def840f8b26859c96b03a4c15f2ec refs/tags/tor-0.4.2.2-alpha
+004caa56465934da31eeab79376a2ab690c5f28b4aa0 refs/tags/tor-0.4.2.2-alpha^{}
+\r
+2bf\r
+004965d75eb6f76a91f663a567775f487d5d87656036 refs/tags/tor-0.4.2.3-alpha
+004c80bfc47198d04c20b853267c3a7b95358ca6478f refs/tags/tor-0.4.2.3-alpha^{}
+00462610120b57238918438ba0f0c59314815df1d1e4 refs/tags/tor-0.4.2.4-rc
+00496a490d3032fa8d368bb54bd479b61c2bcbd45c8f refs/tags/tor-0.4.2.4-rc^{}
+00436c086a90d0f34198f1042cc4ea90064eb550b67a refs/tags/tor-0.4.2.5
+0046bede4ea1008920d8b1b9ea72b0f44cb2ea4dbc6b refs/tags/tor-0.4.2.5^{}
+0043c1ae070a3c2aa5b12d8e411d467f1e216fe700d0 refs/tags/tor-0.4.2.6
+0046971a6beff5a5343415371f7183987e1625bc9565 refs/tags/tor-0.4.2.6^{}
+00433cad484e3b2d481de39d6428b4d91f5d9010b824 refs/tags/tor-0.4.2.7
+004674cad14699087b7ee0b6b17927a3f64683fe31e9 refs/tags/tor-0.4.2.7^{}
+\r
+16f\r
+0043e389ed9a20aebb982e051a421a6293fe8c51c007 refs/tags/tor-0.4.2.8
+0046f945751265a140654fdc1a3e900db9affd60ae69 refs/tags/tor-0.4.2.8^{}
+004d38273e803acb0510190d5154f9133fbea939b74f refs/tags/tor-0.4.3.0-alpha-dev
+005061fe3f448c1c60b6681797feebf2611e458adc47 refs/tags/tor-0.4.3.0-alpha-dev^{}
+004951414ca08cf6502054b5078a88433a35d23a70a7 refs/tags/tor-0.4.3.1-alpha
+\r
+4c\r
+004c6166af5077f5d3a269d9c6c489177e112a206d2d refs/tags/tor-0.4.3.1-alpha^{}
+\r
+49\r
+0049e7f8ccbcaeb17d96f16638bd9d6075071cc28f49 refs/tags/tor-0.4.3.2-alpha
+\r
+4c\r
+004cdcbf6611d998095364f670e26106019fc3e098d2 refs/tags/tor-0.4.3.2-alpha^{}
+\r
+124\r
+0049546b96026cc991b0f70e4b84dfb7af45508581f1 refs/tags/tor-0.4.3.3-alpha
+004c27cc9093af1c7f7862fb242d4de9bd27a046831c refs/tags/tor-0.4.3.3-alpha^{}
+00465c004d327fcd29865fa3909d378d2ae2e4912836 refs/tags/tor-0.4.3.4-rc
+0049251efd11e77df6c27fec9cb75c65fa614a063a74 refs/tags/tor-0.4.3.4-rc^{}
+\r
+112\r
+0043cd2c5416ba9f83b239ae85663aa47d102b3415e1 refs/tags/tor-0.4.3.5
+00465ceb60e5ca61fec9f67c1fcae4d80d0c98e7104c refs/tags/tor-0.4.3.5^{}
+0043a65375c49c43cb374c6eb4b466c22997fd9a5378 refs/tags/tor-0.4.3.6
+004630711296fd5b7f51ef6f4d7b3fbe20f12990c02c refs/tags/tor-0.4.3.6^{}
+\r
+112\r
+00431129919119c028e3b2ad255c73a36fbbd6effe93 refs/tags/tor-0.4.3.7
+004626465179fa13b3127cc127d9a598a4b3da524133 refs/tags/tor-0.4.3.7^{}
+0043c980952a713c290370e9d2572aba4fa2aa1b59fa refs/tags/tor-0.4.3.8
+00465b0fe0ee8aec0d704809a17ba9c64bf94993c668 refs/tags/tor-0.4.3.8^{}
+\r
+132\r
+004d32d0e194fab6b04549b66d684d52ae9d6bbd6beb refs/tags/tor-0.4.4.0-alpha-dev
+005071d96cefc0314bc3ad6cad867586c492a287c6c9 refs/tags/tor-0.4.4.0-alpha-dev^{}
+00498d0faa0b6227243723a2b8aa7f3da51b67f495cb refs/tags/tor-0.4.4.1-alpha
+004c5277f1aad03a2717ee69861a4c4f8e233e815029 refs/tags/tor-0.4.4.1-alpha^{}
+\r
+49\r
+004932351f0e0bc31232bdb7542a1a6df60b1c0d5d56 refs/tags/tor-0.4.4.2-alpha
+\r
+4c\r
+004c50b503a9f90f67e7898efdb560e5fdb577f1a1c6 refs/tags/tor-0.4.4.2-alpha^{}
+\r
+124\r
+004927c66ce30b5d482de6c2c853511d8e4d65bd53b7 refs/tags/tor-0.4.4.3-alpha
+004cc968889a09c453f25ab3b07f1d70e0743eb76b66 refs/tags/tor-0.4.4.3-alpha^{}
+0046389d2afe918a1c0a71f7b2b35c4dfcd0911bec35 refs/tags/tor-0.4.4.4-rc
+00498bd79bd75e760e7493c2fc7dcf5b38d453ea9f13 refs/tags/tor-0.4.4.4-rc^{}
+\r
+112\r
+0043d5e2cac540c142facfe0c0fce49c386df61b33c5 refs/tags/tor-0.4.4.5
+004624e808e946e741d01ed25673fa4d47531858fdb4 refs/tags/tor-0.4.4.5^{}
+00434ffe21f0dea1314c2643f4701b03860a746b26ca refs/tags/tor-0.4.4.6
+00462a8b789ea6f308d081f369d78fa7cfdc9d00bf90 refs/tags/tor-0.4.4.6^{}
+\r
+43\r
+004388b68db04dd09991bf19ab92f6a9f3aad2e5e6ca refs/tags/tor-0.4.4.7
+\r
+46\r
+004637a32b7ee76e5d52439eb840e1087b2fd02dd15a refs/tags/tor-0.4.4.7^{}
+\r
+43\r
+00438408949902514562eecb17d95ecdd2f5957a00f9 refs/tags/tor-0.4.4.8
+\r
+486\r
+0046fecc19529452fcd682272768f17147f4eed360a7 refs/tags/tor-0.4.4.8^{}
+004d397f8b98f79d71ca58eca14d570593ee4d46649d refs/tags/tor-0.4.5.0-alpha-dev
+0050d2f136aab1f7d76a458e834bd791cbb887c96b51 refs/tags/tor-0.4.5.0-alpha-dev^{}
+00499c403ba25916f1fb49727025b37306d48469c56f refs/tags/tor-0.4.5.1-alpha
+004c26679713367b34188e034de1a90a424440294633 refs/tags/tor-0.4.5.1-alpha^{}
+0049e07b657017911805d46889c82cabcb5b6ca0f1a6 refs/tags/tor-0.4.5.2-alpha
+004c135b8eea36edd992d0a0c3e9b6d88c013dc3fe48 refs/tags/tor-0.4.5.2-alpha^{}
+0046bfa68cf08659447a4ec922f981a51323d8ead62f refs/tags/tor-0.4.5.3-rc
+0049e5c47d295bd3dc35f75c7d5c1753c650fd912640 refs/tags/tor-0.4.5.3-rc^{}
+00466508c2bcf9b90cd6a61e7b68a9fedf06e3bf189e refs/tags/tor-0.4.5.4-rc
+00499e26a9399fe2422475406d6ee3cb29b2924f3274 refs/tags/tor-0.4.5.4-rc^{}
+00467ba8d2ba25c5ff39cadddc3ed938e753019d9286 refs/tags/tor-0.4.5.5-rc
+0049b36a00e9a9d3eb4b2949951afaa72e45fb7e68cd refs/tags/tor-0.4.5.5-rc^{}
+0043a1a4c522be022b7080a9a4cc8660e17c15c8def8 refs/tags/tor-0.4.5.6
+0046ae1466e103a5b8bcbf3f561abf0379e535f54cf0 refs/tags/tor-0.4.5.6^{}
+0043d1a799f509629d559e5c257a4aa4c7111f47a903 refs/tags/tor-0.4.5.7
+\r
+e3\r
+004683f895c015de55201e5f226f84a866f30f5ee14b refs/tags/tor-0.4.5.7^{}
+004d824d606db299133aa0efea8d2f067bd20fa249b2 refs/tags/tor-0.4.6.0-alpha-dev
+0050aed2a48c664dad17f58f51c161731a62f876a706 refs/tags/tor-0.4.6.0-alpha-dev^{}
+\r
+49\r
+0049d06d6a532a59320be1fea6f26784515856fa1e17 refs/tags/tor-0.4.6.1-alpha
+\r
+4c\r
+004ccd0e5a942eee0f08f4311899c09c6783b2c8e22c refs/tags/tor-0.4.6.1-alpha^{}
+\r
+4\r
+0000\r
+0\r
+\r
+</data>
+<data1>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+X-Connection: swsclose\r
+Content-Type: text/html\r
+\r
+Here's your unchunked data.
+</data1>
+<servercmd>
+writesize: 440
+writedelay: 10
+</servercmd>
+</reply>
+
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Git server response with multiple chunks. First chunks partially arrives with server headers.
+</name>
+<features>
+proxy
+</features>
+<command>
+--raw http://%HOSTIP:%HTTPPORT/git/tor/info/refs?service=git-upload-pack/%TESTNUMBER --next --max-time 2 http://%HOSTIP:%HTTPPORT/unchunked-content/%TESTNUMBER0001
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /git/tor/info/refs?service=git-upload-pack/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+GET /unchunked-content/%TESTNUMBER0001 HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test5 b/tests/cts/chunked-transfer-encoding/data/test5
new file mode 100644 (file)
index 0000000..fbbbbb6
--- /dev/null
@@ -0,0 +1,60 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+3\r
+AA
+\r
+4\r
+BBB
+\r
+123\r
+This chunk is too small
+0\r
+\r
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Multiple small chunks, last one too small.
+</name>
+<features>
+proxy
+</features>
+<command>
+--raw http://%HOSTIP:%HTTPPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+18
+</errorcode>
+</verify>
+
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test6 b/tests/cts/chunked-transfer-encoding/data/test6
new file mode 100644 (file)
index 0000000..7de6678
--- /dev/null
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+3\r
+AA
+\r
+4\r
+BBB
+\r
+123\r
+This chunk is too small
+4\r
+DDD
+0\r
+\r
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Multiple small chunks, chunk in the middle too small.
+</name>
+<features>
+proxy
+</features>
+<command>
+--raw http://%HOSTIP:%HTTPPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+18
+</errorcode>
+</verify>
+
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test7 b/tests/cts/chunked-transfer-encoding/data/test7
new file mode 100644 (file)
index 0000000..00fc6a6
--- /dev/null
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+100\r
+%repeat[255 x A]%
+\r
+1000\r
+%repeat[4095 x B]%
+\r
+10000\r
+%repeat[65535 x C]%
+123\r
+This chunk is too small
+0\r
+\r
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Multiple chunks, some of them large, last chunk too small.
+</name>
+<features>
+proxy
+</features>
+<command>
+--raw http://%HOSTIP:%HTTPPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+56
+</errorcode>
+</verify>
+
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test8 b/tests/cts/chunked-transfer-encoding/data/test8
new file mode 100644 (file)
index 0000000..d991f51
--- /dev/null
@@ -0,0 +1,53 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+100\r
+%repeat[255 x A]%
+\r
+\r
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - One data chunk, last chunk missing
+</name>
+<features>
+proxy
+</features>
+<command>
+--raw http://%HOSTIP:%HTTPPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+56
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/data/test9 b/tests/cts/chunked-transfer-encoding/data/test9
new file mode 100644 (file)
index 0000000..ba0cb01
--- /dev/null
@@ -0,0 +1,58 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+chunked transfer encoding
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Transfer-Encoding: chunked\r
+X-Control: swsclose\r
+\r
+100\r
+%repeat[255 x A]%
+\r
+100\r
+%repeat[255 x B]%
+\r
+100\r
+%repeat[255 x C]%
+\r
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Chunked transfer encoding - Multiple chunks, last chunk missing - XXX: Further corrupted data forwarded
+</name>
+<features>
+proxy
+</features>
+<command>
+--raw http://%HOSTIP:%HTTPPORT/chunked-transfer-encoding/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /chunked-transfer-encoding/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+18
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/chunked-transfer-encoding/privoxy.conf b/tests/cts/chunked-transfer-encoding/privoxy.conf
new file mode 100644 (file)
index 0000000..337f716
--- /dev/null
@@ -0,0 +1,26 @@
+listen-address 127.0.0.1:9119
+
+debug     1 # Log the destination for each request Privoxy let through. See also debug 1024.
+debug     2 # show each connection status
+debug     4 # show tagging-related messages
+debug     8 # show header parsing
+debug    32 # debug force feature
+debug    64 # debug regular expression filters
+debug   128 # debug redirects
+debug   256 # debug GIF de-animation
+debug   512 # Common Log Format
+debug  1024 # Log the destination for requests Privoxy didn't let through, and the reason why.
+debug  4096 # Startup banner and warnings.
+debug  8192 # Non-fatal errors
+
+#debug   16 # log all data written to the network into the logfile
+#debug 32768 # log all data read from the network
+
+filterfile ../../../default.filter
+actionsfile ./chunked-transfer-encoding.action
+
+buffer-limit 800
+
+keep-alive-timeout 10
+default-server-timeout 10
+socket-timeout 3
diff --git a/tests/cts/client-body-filter-https/client-body-filter.action b/tests/cts/client-body-filter-https/client-body-filter.action
new file mode 100644 (file)
index 0000000..40cf782
--- /dev/null
@@ -0,0 +1,8 @@
+{+client-body-filter{blafasel-to-bumfidel}}
+/
+
+{+client-body-filter{bumfidel-to-tralala}}
+/bumfidel-to-tralala
+
+{+client-body-filter{empty-body}}
+/.*/empty-body/
diff --git a/tests/cts/client-body-filter-https/client-body-filter.filter b/tests/cts/client-body-filter-https/client-body-filter.filter
new file mode 100644 (file)
index 0000000..ecc3798
--- /dev/null
@@ -0,0 +1,8 @@
+CLIENT-BODY-FILTER: blafasel-to-bumfidel Changes "blafasel" to "bumfidel"
+s@blafasel@bumfidel@
+
+CLIENT-BODY-FILTER: bumfidel-to-tralala Changes "bumfidel" to "tralala"
+s@bumfidel@tralala@
+
+CLIENT-BODY-FILTER: empty-body Only applies to empty content bodies
+s@^$@empty-body detected that there was no data@
diff --git a/tests/cts/client-body-filter-https/data/test1 b/tests/cts/client-body-filter-https/data/test1
new file mode 100644 (file)
index 0000000..b2ddb31
--- /dev/null
@@ -0,0 +1,61 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP POST
+client-body-filter
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Connection: close\r
+Content-Type: text/html\r
+X-Connection: swsclose\r
+\r
+Received your input.
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Replace whole https request body with client-body-filter{blafasel-to-bumfidel}
+</name>
+<features>
+proxy
+</features>
+<command>
+-d blafasel --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+POST /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Length: 8\r
+Content-Type: application/x-www-form-urlencoded\r
+\r
+bumfidel
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-filter-https/data/test10 b/tests/cts/client-body-filter-https/data/test10
new file mode 100644 (file)
index 0000000..f7c32a3
--- /dev/null
@@ -0,0 +1,57 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP POST
+client-body-filter
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Connection: close\r
+Content-Type: text/html\r
+X-Connection: swsclose\r
+\r
+Received your input.
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Attempt to apply client-body-filter{blafasel-to-bumfidel} to client request that does not completely arrive in time. (XXX: Privoxy send a "Connection failed" message instead of a timeout message which would be more appropriate)
+</name>
+<features>
+proxy
+</features>
+# Sending the first request to appease the test framework.
+# We mainly care about the second request where we overwrite the Content-Length
+# header so curl sends less data than Privoxy expects.
+<command>
+-s --insecure https://%HOSTIP:%HTTPSPORT/first-request/%TESTNUMBER --next -s --write-out '%{stderr}%{response_code}\n' --limit-rate 5000 -d "blafasel%repeat[100 x padding]%" -H "Content-Length: 8000" --insecure https://%HOSTIP:%HTTPSPORT/second-request/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<stderr>
+400
+</stderr>
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-filter-https/data/test12 b/tests/cts/client-body-filter-https/data/test12
new file mode 100644 (file)
index 0000000..3cb2046
--- /dev/null
@@ -0,0 +1,87 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP POST
+client-body-filter
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your first request.
+</data>
+<data1>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your second request.
+</data1>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Connection: close\r
+Content-Type: text/html\r
+X-Connection: swsclose\r
+\r
+Received your first request.
+</data>
+<data1>
+HTTP/1.1 200 OK\r
+Connection: close\r
+Content-Type: text/html\r
+X-Connection: swsclose\r
+\r
+Received your second request.
+</data1>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Attempt to apply client-body-filter{blafasel-to-bumfidel} to client request that is too large to buffer.
+</name>
+<features>
+proxy
+</features>
+# Sending the first request to appease the test framework.
+# We mainly care about the second request which is too large for Privoxy to buffer it.
+<command>
+--insecure https://%HOSTIP:%HTTPSPORT/first-request/%TESTNUMBER --next -d @log/post-data-%TESTNUMBER --insecure https://%HOSTIP:%HTTPSPORT/second-request/%TESTNUMBER
+</command>
+<file name="log/post-data-%TESTNUMBER">
+blafasel%repeat[20000 x padding]%
+</file>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+GET /first-request/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+POST /second-request/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Length: 140008\r
+Content-Type: application/x-www-form-urlencoded\r
+\r
+blafasel%repeat[20000 x padding]%
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-filter-https/data/test13 b/tests/cts/client-body-filter-https/data/test13
new file mode 100644 (file)
index 0000000..995c1ee
--- /dev/null
@@ -0,0 +1,82 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP POST
+client-body-filter
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: keep-alive
+Content-Type: text/html
+Content-Length: 21
+
+Received your input.
+</data>
+<data1>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data1>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Connection: keep-alive\r
+Content-Type: text/html\r
+Content-Length: 21\r
+\r
+Received your input.
+</data>
+<data1>
+HTTP/1.1 200 OK\r
+Connection: close\r
+Content-Type: text/html\r
+X-Connection: swsclose\r
+\r
+Received your input.
+</data1>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Modify parts of the client body of a request on a reused connection with client-body-filter{blafasel-to-bumfidel} (based on test 2)
+</name>
+<features>
+proxy
+</features>
+<command>
+--insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER --next -d "foo blafasel bar" --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+POST /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Length: 16\r
+Content-Type: application/x-www-form-urlencoded\r
+\r
+foo bumfidel bar
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-filter-https/data/test14 b/tests/cts/client-body-filter-https/data/test14
new file mode 100644 (file)
index 0000000..517fb71
--- /dev/null
@@ -0,0 +1,80 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP POST
+client-body-filter
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Content-Length: 21
+Content-Type: text/html
+
+Received your input.
+</data>
+<data1>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data1>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Content-Length: 21\r
+Content-Type: text/html\r
+\r
+Received your input.
+</data>
+<data1>
+HTTP/1.1 200 OK\r
+Connection: close\r
+Content-Type: text/html\r
+X-Connection: swsclose\r
+\r
+Received your input.
+</data1>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Applying client-body-filter{blafasel-to-bumfidel} to client request on a reused connection that is too large to read at once (based on test 5)
+</name>
+<features>
+proxy
+</features>
+<command>
+--insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER --next -d "blafasel%repeat[5000 x padding]%" --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+POST /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Length: 35008\r
+Content-Type: application/x-www-form-urlencoded\r
+\r
+bumfidel%repeat[5000 x padding]%
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-filter-https/data/test15 b/tests/cts/client-body-filter-https/data/test15
new file mode 100644 (file)
index 0000000..b36e828
--- /dev/null
@@ -0,0 +1,72 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP POST
+client-body-filter
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Content-Length: 21
+Content-Type: text/html
+
+Received your input.
+</data>
+<data1>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data1>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Content-Length: 21\r
+Content-Type: text/html\r
+\r
+Received your input.
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Two filters applied to client request on a reused connection reusing the already filtered content (based on test 7)
+</name>
+<features>
+proxy
+</features>
+<command>
+--insecure https://%HOSTIP:%HTTPSPORT/bumfidel-to-tralala/%TESTNUMBER --next -d "blafasel" --insecure https://%HOSTIP:%HTTPSPORT/bumfidel-to-tralala/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+GET /bumfidel-to-tralala/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+POST /bumfidel-to-tralala/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Length: 7\r
+Content-Type: application/x-www-form-urlencoded\r
+\r
+tralala
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-filter-https/data/test16 b/tests/cts/client-body-filter-https/data/test16
new file mode 100644 (file)
index 0000000..4e828be
--- /dev/null
@@ -0,0 +1,71 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP POST
+client-body-filter
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Content-Length: 21
+Content-Type: text/html
+
+Received your input.
+</data>
+<data1>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data1>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Content-Length: 21\r
+Content-Type: text/html\r
+\r
+Received your input.
+</data>
+<data1>
+HTTP/1.1 200 OK\r
+Connection: close\r
+Content-Type: text/html\r
+X-Connection: swsclose\r
+\r
+Received your input.
+</data1>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Attempt to apply client-body-filter{blafasel-to-bumfidel} to client request that does not completely arrive in time on a reused connection. (based on test 10)
+</name>
+<features>
+proxy
+</features>
+# Sending the first request to appease the test framework.
+# We mainly care about the second request where we overwrite the Content-Length
+# header so curl sends less data than Privoxy expects.
+<command>
+-s --insecure https://%HOSTIP:%HTTPSPORT/first-request/%TESTNUMBER --next -s --write-out '%{stderr}%{response_code}\n' --limit-rate 5000 -d "blafasel%repeat[100 x padding]%" -H "Content-Length: 8000" --insecure https://%HOSTIP:%HTTPSPORT/second-request/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<stderr>
+400
+</stderr>
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-filter-https/data/test17 b/tests/cts/client-body-filter-https/data/test17
new file mode 100644 (file)
index 0000000..8c87f0f
--- /dev/null
@@ -0,0 +1,84 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP POST
+client-body-filter
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Content-Length: 29\r
+Content-Type: text/html
+
+Received your first request.
+</data>
+<data1>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your second request.
+</data1>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Content-Length: 29\r
+Content-Type: text/html\r
+\r
+Received your first request.
+</data>
+<data1>
+HTTP/1.1 200 OK\r
+Connection: close\r
+Content-Type: text/html\r
+X-Connection: swsclose\r
+\r
+Received your second request.
+</data1>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Attempt to apply client-body-filter{blafasel-to-bumfidel} to client request on reused connection that is too large to buffer. (based on test12)
+</name>
+<features>
+proxy
+</features>
+# We mainly care about the second request which is too large for Privoxy to buffer it.
+<command>
+--insecure https://%HOSTIP:%HTTPSPORT/first-request/%TESTNUMBER --next -d @log/post-data-%TESTNUMBER --insecure https://%HOSTIP:%HTTPSPORT/second-request/%TESTNUMBER
+</command>
+<file name="log/post-data-%TESTNUMBER">
+blafasel%repeat[20000 x padding]%
+</file>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+GET /first-request/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+POST /second-request/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Length: 140008\r
+Content-Type: application/x-www-form-urlencoded\r
+\r
+blafasel%repeat[20000 x padding]%
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-filter-https/data/test2 b/tests/cts/client-body-filter-https/data/test2
new file mode 100644 (file)
index 0000000..2a2bd3e
--- /dev/null
@@ -0,0 +1,61 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP POST
+client-body-filter
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Connection: close\r
+Content-Type: text/html\r
+X-Connection: swsclose\r
+\r
+Received your input.
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Modify parts of the client body with client-body-filter{blafasel-to-bumfidel}
+</name>
+<features>
+proxy
+</features>
+<command>
+-d "foo blafasel bar" --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+POST /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Length: 16\r
+Content-Type: application/x-www-form-urlencoded\r
+\r
+foo bumfidel bar
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-filter-https/data/test3 b/tests/cts/client-body-filter-https/data/test3
new file mode 100644 (file)
index 0000000..429127c
--- /dev/null
@@ -0,0 +1,61 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP POST
+client-body-filter
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Connection: close\r
+Content-Type: text/html\r
+X-Connection: swsclose\r
+\r
+Received your input.
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Apply client-body-filter{blafasel-to-bumfidel} to request that does not contain blafasel
+</name>
+<features>
+proxy
+</features>
+<command>
+-d "foo bar" --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+POST /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Length: 7\r
+Content-Type: application/x-www-form-urlencoded\r
+\r
+foo bar
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-filter-https/data/test4 b/tests/cts/client-body-filter-https/data/test4
new file mode 100644 (file)
index 0000000..4816554
--- /dev/null
@@ -0,0 +1,63 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP POST
+client-body-filter
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+
+Received your input.
+
+Will keep the connection open despite the "Connection: Close" header.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Connection: close\r
+Content-Type: text/html\r
+\r
+Received your input.
+
+Will keep the connection open despite the "Connection: Close" header.
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Using client-body-filter{blafasel-to-bumfidel} with server connection that times out after delivering the response
+</name>
+<features>
+proxy
+</features>
+<command>
+-d "blafasel" --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+POST /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Length: 8\r
+Content-Type: application/x-www-form-urlencoded\r
+\r
+bumfidel
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-filter-https/data/test5 b/tests/cts/client-body-filter-https/data/test5
new file mode 100644 (file)
index 0000000..6a253fe
--- /dev/null
@@ -0,0 +1,61 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP POST
+client-body-filter
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Connection: close\r
+Content-Type: text/html\r
+X-Connection: swsclose\r
+\r
+Received your input.
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Applying client-body-filter{blafasel-to-bumfidel} to client request that is too large to read at once
+</name>
+<features>
+proxy
+</features>
+<command>
+-d "blafasel%repeat[5000 x padding]%" --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+POST /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Length: 35008\r
+Content-Type: application/x-www-form-urlencoded\r
+\r
+bumfidel%repeat[5000 x padding]%
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-filter-https/data/test6 b/tests/cts/client-body-filter-https/data/test6
new file mode 100644 (file)
index 0000000..305d298
--- /dev/null
@@ -0,0 +1,61 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP POST
+client-body-filter
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Connection: close\r
+Content-Type: text/html\r
+X-Connection: swsclose\r
+\r
+Received your input.
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Applying client-body-filter{blafasel-to-bumfidel} to client request that is too large to be read at once and arrives slowly
+</name>
+<features>
+proxy
+</features>
+<command>
+--limit-rate 4k -d "blafasel%repeat[5000 x padding]%" --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+POST /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Length: 35008\r
+Content-Type: application/x-www-form-urlencoded\r
+\r
+bumfidel%repeat[5000 x padding]%
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-filter-https/data/test7 b/tests/cts/client-body-filter-https/data/test7
new file mode 100644 (file)
index 0000000..2ce0924
--- /dev/null
@@ -0,0 +1,61 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP POST
+client-body-filter
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Connection: close\r
+Content-Type: text/html\r
+X-Connection: swsclose\r
+\r
+Received your input.
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Two filters applied to client request reusing the already filtered content
+</name>
+<features>
+proxy
+</features>
+<command>
+-d "blafasel" --insecure https://%HOSTIP:%HTTPSPORT/bumfidel-to-tralala/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+POST /bumfidel-to-tralala/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Length: 7\r
+Content-Type: application/x-www-form-urlencoded\r
+\r
+tralala
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-filter-https/data/test8 b/tests/cts/client-body-filter-https/data/test8
new file mode 100644 (file)
index 0000000..2a12987
--- /dev/null
@@ -0,0 +1,61 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP POST
+client-body-filter
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Connection: close\r
+Content-Type: text/html\r
+X-Connection: swsclose\r
+\r
+Received your input.
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Three filters applied to client request reusing the already filtered content. Last filter does not modify content.
+</name>
+<features>
+proxy
+</features>
+<command>
+-d "blafasel" --insecure https://%HOSTIP:%HTTPSPORT/bumfidel-to-tralala/empty-body/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+POST /bumfidel-to-tralala/empty-body/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Length: 7\r
+Content-Type: application/x-www-form-urlencoded\r
+\r
+tralala
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-filter-https/data/test9 b/tests/cts/client-body-filter-https/data/test9
new file mode 100644 (file)
index 0000000..80ea75e
--- /dev/null
@@ -0,0 +1,63 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP POST
+client-body-filter
+# This test currently doesn't work as Privoxy truncates the request.
+# Sending no Content-Length header is an error but truncating the
+# request still doesn't seem ideal. Probably Privoxy should reject
+# the request instead of forwarding it.
+skip
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+
+Received your input.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Connection: close\r
+Content-Type: text/html\r
+\r
+Received your input.
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Attempt to apply client-body-filter{blafasel-to-bumfidel} to client request without Content-Length header
+</name>
+<features>
+proxy
+</features>
+<command>
+--limit-rate 1000 -d "blafasel%repeat[5000 x padding]%" -H "Content-Length:" --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+POST /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Type: application/x-www-form-urlencoded\r
+\r
+bumfidel%repeat[5000 x padding]%
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-filter-https/privoxy.conf b/tests/cts/client-body-filter-https/privoxy.conf
new file mode 100644 (file)
index 0000000..3a6eecf
--- /dev/null
@@ -0,0 +1,37 @@
+listen-address 127.0.0.1:9119
+
+ca-directory          ../ca-directory
+ca-cert-file          privoxy-test-cacert.crt
+ca-key-file           privoxy-test-cakey.pem
+ca-password           blafasel
+# We don't check certificate anyway
+trusted-cas-file      privoxy-test-cacert.crt
+
+certificate-directory ../certs
+
+debug     1 # Log the destination for each request Privoxy let through. See also debug 1024.
+debug     2 # show each connection status
+debug     4 # show tagging-related messages
+debug     8 # show header parsing
+debug    32 # debug force feature
+debug    64 # debug regular expression filters
+debug   128 # debug redirects
+debug   256 # debug GIF de-animation
+debug   512 # Common Log Format
+debug  1024 # Log the destination for requests Privoxy didn't let through, and the reason why.
+debug  4096 # Startup banner and warnings.
+debug  8192 # Non-fatal errors
+
+actionsfile ../blocked-https-requests/https-inspection.action
+actionsfile ../client-body-filter/client-body-filter.action
+filterfile ../client-body-filter/client-body-filter.filter
+
+socket-timeout 3
+
+templdir ../../../templates/
+
+# Reduce buffer limit so tests can reach it sooner.
+buffer-limit 100
+
+keep-alive-timeout 10
+default-server-timeout 10
diff --git a/tests/cts/client-body-filter/client-body-filter.action b/tests/cts/client-body-filter/client-body-filter.action
new file mode 100644 (file)
index 0000000..40cf782
--- /dev/null
@@ -0,0 +1,8 @@
+{+client-body-filter{blafasel-to-bumfidel}}
+/
+
+{+client-body-filter{bumfidel-to-tralala}}
+/bumfidel-to-tralala
+
+{+client-body-filter{empty-body}}
+/.*/empty-body/
diff --git a/tests/cts/client-body-filter/client-body-filter.filter b/tests/cts/client-body-filter/client-body-filter.filter
new file mode 100644 (file)
index 0000000..ecc3798
--- /dev/null
@@ -0,0 +1,8 @@
+CLIENT-BODY-FILTER: blafasel-to-bumfidel Changes "blafasel" to "bumfidel"
+s@blafasel@bumfidel@
+
+CLIENT-BODY-FILTER: bumfidel-to-tralala Changes "bumfidel" to "tralala"
+s@bumfidel@tralala@
+
+CLIENT-BODY-FILTER: empty-body Only applies to empty content bodies
+s@^$@empty-body detected that there was no data@
diff --git a/tests/cts/client-body-filter/data/test1 b/tests/cts/client-body-filter/data/test1
new file mode 100644 (file)
index 0000000..cfb7b26
--- /dev/null
@@ -0,0 +1,49 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP POST
+client-body-filter
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Replace whole request body with client-body-filter{blafasel-to-bumfidel}
+</name>
+<features>
+proxy
+</features>
+<command>
+-d blafasel http://%HOSTIP:%HTTPPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+POST /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Length: 8\r
+Content-Type: application/x-www-form-urlencoded\r
+Connection: close\r
+\r
+bumfidel
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-filter/data/test10 b/tests/cts/client-body-filter/data/test10
new file mode 100644 (file)
index 0000000..d09d568
--- /dev/null
@@ -0,0 +1,44 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP POST
+client-body-filter
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Attempt to apply client-body-filter{blafasel-to-bumfidel} to client request that does not completely arrive in time. (XXX: Privoxy sends a "Connection failed" message instead of a timeout message which would be more appropriate)
+</name>
+<features>
+proxy
+</features>
+# Sending the first request to appease the test framework.
+# We mainly care about the second request where we overwrite the Content-Length
+# header with an incorrect value so curl sends less data than Privoxy expects.
+<command>
+-s http://%HOSTIP:%HTTPPORT/first-request/%TESTNUMBER --next -s --write-out '%{stderr}%{response_code}\n' --limit-rate 5000 -d "blafasel%repeat[100 x padding]%" -H "Content-Length: 10000" http://%HOSTIP:%HTTPPORT/second-request/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<stderr>
+400
+</stderr>
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-filter/data/test11 b/tests/cts/client-body-filter/data/test11
new file mode 100644 (file)
index 0000000..8cc8b61
--- /dev/null
@@ -0,0 +1,49 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP POST
+client-body-filter
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Applying client-body-filter{blafasel-to-bumfidel} to large client request slowly while the server times out quickly (XXX: not properly implemented)
+</name>
+<features>
+proxy
+</features>
+<command>
+--limit-rate 1000 -d "blafasel%repeat[5000 x padding]%" http://%HOSTIP:%HTTPPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+POST /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Length: 35008\r
+Content-Type: application/x-www-form-urlencoded\r
+Connection: close\r
+\r
+bumfidel%repeat[5000 x padding]%
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-filter/data/test12 b/tests/cts/client-body-filter/data/test12
new file mode 100644 (file)
index 0000000..b2d3ad6
--- /dev/null
@@ -0,0 +1,68 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP POST
+client-body-filter
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your first request.
+</data>
+<data1>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your second request.
+</data1>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Attempt to apply client-body-filter{blafasel-to-bumfidel} to client request that is too large to buffer.
+</name>
+<features>
+proxy
+</features>
+# Sending the first request to appease the test framework.
+# We mainly care about the second request which is too large for Privoxy to buffer it.
+<command>
+http://%HOSTIP:%HTTPPORT/first-request/%TESTNUMBER --next -d @log/post-data-%TESTNUMBER http://%HOSTIP:%HTTPPORT/second-request/%TESTNUMBER
+</command>
+<file name="log/post-data-%TESTNUMBER">
+blafasel%repeat[20000 x padding]%
+</file>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+GET /first-request/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+POST /second-request/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Length: 140008\r
+Content-Type: application/x-www-form-urlencoded\r
+Connection: close\r
+\r
+blafasel%repeat[20000 x padding]%
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-filter/data/test2 b/tests/cts/client-body-filter/data/test2
new file mode 100644 (file)
index 0000000..830424a
--- /dev/null
@@ -0,0 +1,49 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP POST
+client-body-filter
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Modify parts of the client body with client-body-filter{blafasel-to-bumfidel}
+</name>
+<features>
+proxy
+</features>
+<command>
+-d "foo blafasel bar" http://%HOSTIP:%HTTPPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+POST /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Length: 16\r
+Content-Type: application/x-www-form-urlencoded\r
+Connection: close\r
+\r
+foo bumfidel bar
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-filter/data/test3 b/tests/cts/client-body-filter/data/test3
new file mode 100644 (file)
index 0000000..606cdc5
--- /dev/null
@@ -0,0 +1,49 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP POST
+client-body-filter
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Apply client-body-filter{blafasel-to-bumfidel} to request that does not contain blafasel
+</name>
+<features>
+proxy
+</features>
+<command>
+-d "foo bar" http://%HOSTIP:%HTTPPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+POST /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Length: 7\r
+Content-Type: application/x-www-form-urlencoded\r
+Connection: close\r
+\r
+foo bar
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-filter/data/test4 b/tests/cts/client-body-filter/data/test4
new file mode 100644 (file)
index 0000000..47249c0
--- /dev/null
@@ -0,0 +1,50 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP POST
+client-body-filter
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+
+Received your input.
+
+Will keep the connection open despite the "Connection: Close" header.
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Using client-body-filter{blafasel-to-bumfidel} with server connection that times out after delivering the response
+</name>
+<features>
+proxy
+</features>
+<command>
+-d "blafasel" http://%HOSTIP:%HTTPPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+POST /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Length: 8\r
+Content-Type: application/x-www-form-urlencoded\r
+Connection: close\r
+\r
+bumfidel
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-filter/data/test5 b/tests/cts/client-body-filter/data/test5
new file mode 100644 (file)
index 0000000..3a75016
--- /dev/null
@@ -0,0 +1,49 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP POST
+client-body-filter
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Applying client-body-filter{blafasel-to-bumfidel} to client request that is too large to read at once
+</name>
+<features>
+proxy
+</features>
+<command>
+-d "blafasel%repeat[5000 x padding]%" http://%HOSTIP:%HTTPPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+POST /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Length: 35008\r
+Content-Type: application/x-www-form-urlencoded\r
+Connection: close\r
+\r
+bumfidel%repeat[5000 x padding]%
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-filter/data/test6 b/tests/cts/client-body-filter/data/test6
new file mode 100644 (file)
index 0000000..cae9dd1
--- /dev/null
@@ -0,0 +1,49 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP POST
+client-body-filter
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Applying client-body-filter{blafasel-to-bumfidel} to client request that is too large to read at once and arrives slowly
+</name>
+<features>
+proxy
+</features>
+<command>
+--limit-rate 4k -d "blafasel%repeat[5000 x padding]%" http://%HOSTIP:%HTTPPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+POST /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Length: 35008\r
+Content-Type: application/x-www-form-urlencoded\r
+Connection: close\r
+\r
+bumfidel%repeat[5000 x padding]%
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-filter/data/test7 b/tests/cts/client-body-filter/data/test7
new file mode 100644 (file)
index 0000000..7402be5
--- /dev/null
@@ -0,0 +1,49 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP POST
+client-body-filter
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Two filters applied to client request reusing the already filtered content
+</name>
+<features>
+proxy
+</features>
+<command>
+-d "blafasel" http://%HOSTIP:%HTTPPORT/bumfidel-to-tralala/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+POST /bumfidel-to-tralala/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Length: 7\r
+Content-Type: application/x-www-form-urlencoded\r
+Connection: close\r
+\r
+tralala
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-filter/data/test8 b/tests/cts/client-body-filter/data/test8
new file mode 100644 (file)
index 0000000..76acb0f
--- /dev/null
@@ -0,0 +1,49 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP POST
+client-body-filter
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Three filters applied to client request reusing the already filtered content. Last filter does not modify content.
+</name>
+<features>
+proxy
+</features>
+<command>
+-d "blafasel" http://%HOSTIP:%HTTPPORT/bumfidel-to-tralala/empty-body/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+POST /bumfidel-to-tralala/empty-body/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Length: 7\r
+Content-Type: application/x-www-form-urlencoded\r
+Connection: close\r
+\r
+tralala
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-filter/data/test9 b/tests/cts/client-body-filter/data/test9
new file mode 100644 (file)
index 0000000..a837102
--- /dev/null
@@ -0,0 +1,64 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP POST
+client-body-filter
+# This test currently doesn't work. Privoxy shuffles the data
+# to the server and once that's done the connection times out.
+# Sending no Content-Length header is an error but truncating the
+# request still doesn't seem ideal. Probably Privoxy should reject
+# the request instead of forwarding it.
+skip
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+
+Received your input.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Connection: close\r
+Content-Type: text/html\r
+\r
+Received your input.
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Attempt to apply client-body-filter{blafasel-to-bumfidel} to client request without Content-Length header
+</name>
+<features>
+proxy
+</features>
+<command>
+--limit-rate 1000 -d "blafasel%repeat[5000 x padding]%" -H "Content-Length:" http://%HOSTIP:%HTTPPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+POST /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Type: application/x-www-form-urlencoded\r
+\r
+bumfidel%repeat[5000 x padding]%
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-filter/privoxy.conf b/tests/cts/client-body-filter/privoxy.conf
new file mode 100644 (file)
index 0000000..fcab848
--- /dev/null
@@ -0,0 +1,24 @@
+listen-address 127.0.0.1:9119
+
+debug     1 # Log the destination for each request Privoxy let through. See also debug 1024.
+debug     2 # show each connection status
+debug     4 # show tagging-related messages
+debug     8 # show header parsing
+debug    32 # debug force feature
+debug    64 # debug regular expression filters
+debug   128 # debug redirects
+debug   256 # debug GIF de-animation
+debug   512 # Common Log Format
+debug  1024 # Log the destination for requests Privoxy didn't let through, and the reason why.
+debug  4096 # Startup banner and warnings.
+debug  8192 # Non-fatal errors
+
+actionsfile client-body-filter.action
+filterfile client-body-filter.filter
+
+socket-timeout 3
+
+templdir ../../../templates/
+
+# Reduce buffer limit so tests can reach it sooner.
+buffer-limit 100
diff --git a/tests/cts/client-body-tagger-https/client-body-tagger.action b/tests/cts/client-body-tagger-https/client-body-tagger.action
new file mode 100644 (file)
index 0000000..2bc5848
--- /dev/null
@@ -0,0 +1,11 @@
+{+client-body-tagger{blafasel}}
+/
+
+{+block{Request body contains blafasel}}
+TAG:^content contains blafasel$
+
+{+client-body-tagger{bumfidel}}
+/tag-bumfidel-requests/
+
+{+client-body-filter{bumfidel-to-tralala}}
+TAG:^content contains bumfidel$
diff --git a/tests/cts/client-body-tagger-https/client-body-tagger.filter b/tests/cts/client-body-tagger-https/client-body-tagger.filter
new file mode 100644 (file)
index 0000000..dc3ebae
--- /dev/null
@@ -0,0 +1,5 @@
+CLIENT-BODY-TAGGER: blafasel Tags requests with "content contains blafasel" if the client body contains the word "blafasel"
+s@.*blafasel.*@content contains blafasel@s
+
+CLIENT-BODY-TAGGER: bumfidel Tags requests with "content contains bumfidel" if the client body contains the word "bumfidel"
+s@.*bumfidel.*@content contains bumfidel@s
diff --git a/tests/cts/client-body-tagger-https/data/test1 b/tests/cts/client-body-tagger-https/data/test1
new file mode 100644 (file)
index 0000000..6d43cc7
--- /dev/null
@@ -0,0 +1,63 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP POST
+client-body-tagger
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Connection: close\r
+Content-Type: text/html\r
+X-Connection: swsclose\r
+\r
+Received your input.
+</data>
+</proxyreply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Two requests to the same URL. The second one is blocked based on a tag applied with client-body-tagger{blafasel}.
+</name>
+<features>
+proxy
+</features>
+<command>
+-s --write-out '%{stderr}%{response_code}\n' --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER --next -d blafasel -s --write-out '%{stderr}%{response_code}\n' --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<stderr>
+200
+403
+</stderr>
+
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-tagger-https/data/test10 b/tests/cts/client-body-tagger-https/data/test10
new file mode 100644 (file)
index 0000000..cbba8d2
--- /dev/null
@@ -0,0 +1,61 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP POST
+client-body-tagger
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Content-Length: 21
+Content-Type: text/html
+
+Received your input.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Content-Length: 21\r
+Content-Type: text/html\r
+\r
+Received your input.
+</data>
+</proxyreply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Two requests to the same URL on a reused connection. The second one is large and blocked based on a tag applied with the client-body-tagger{blafasel}. (based on test 2)
+</name>
+<features>
+proxy
+</features>
+<command>
+-s --write-out '%{stderr}%{response_code}\n' --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER --next -d "blafasel%repeat[5000 x padding]%" -s --write-out '%{stderr}%{response_code}\n' --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<stderr>
+200
+403
+</stderr>
+
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-tagger-https/data/test11 b/tests/cts/client-body-tagger-https/data/test11
new file mode 100644 (file)
index 0000000..29521bc
--- /dev/null
@@ -0,0 +1,61 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP POST
+client-body-tagger
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Content-Length: 21
+Content-Type: text/html
+
+Received your input.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Content-Length: 21\r
+Content-Type: text/html\r
+\r
+Received your input.
+</data>
+</proxyreply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Two requests to the same URL on a reused connection. The second one is large and blocked based on a tag. Offending phrase at end of content. (based on test 3)
+</name>
+<features>
+proxy
+</features>
+<command>
+-s --write-out '%{stderr}%{response_code}\n' --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER --next -d "%repeat[5000 x padding]%blafasel" -s --write-out '%{stderr}%{response_code}\n' --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<stderr>
+200
+403
+</stderr>
+
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-tagger-https/data/test12 b/tests/cts/client-body-tagger-https/data/test12
new file mode 100644 (file)
index 0000000..896b0a2
--- /dev/null
@@ -0,0 +1,61 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP POST
+client-body-tagger
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Content-Length: 21
+Content-Type: text/html
+
+Received your input.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Content-Length: 21\r
+Content-Type: text/html\r
+\r
+Received your input.
+</data>
+</proxyreply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Two requests to the same URL on a reused connection. The second one is large and blocked based on a tag. Offending phrase in the middle of the content. (based on test 4)
+</name>
+<features>
+proxy
+</features>
+<command>
+-s --write-out '%{stderr}%{response_code}\n' --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER --next -d "%repeat[5000 x padding]% blafasel tralala" -s --write-out '%{stderr}%{response_code}\n' --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<stderr>
+200
+403
+</stderr>
+
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-tagger-https/data/test13 b/tests/cts/client-body-tagger-https/data/test13
new file mode 100644 (file)
index 0000000..b0d227e
--- /dev/null
@@ -0,0 +1,69 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP POST
+client-body-tagger
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Content-Length: 21
+Content-Type: text/html
+
+Received your input.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Content-Length: 21\r
+Content-Type: text/html\r
+\r
+Received your input.
+</data>
+</proxyreply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Two requests to the same URL on a reused connection. The second one is a POST request but it's not expected to be blocked due to a tag. (based on test 5)
+</name>
+<features>
+proxy
+</features>
+<command>
+-s --write-out '%{stderr}%{response_code}\n' --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER --next -d "%repeat[5000 x padding]%bumfidel" -s --write-out '%{stderr}%{response_code}\n' --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+POST /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Length: 35008\r
+Content-Type: application/x-www-form-urlencoded\r
+\r
+%repeat[5000 x padding]%bumfidel
+</protocol>
+<stderr>
+200
+200
+</stderr>
+
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-tagger-https/data/test14 b/tests/cts/client-body-tagger-https/data/test14
new file mode 100644 (file)
index 0000000..5f22e50
--- /dev/null
@@ -0,0 +1,69 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP POST
+client-body-tagger
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Content-Length: 21
+Content-Type: text/html
+
+Received your input.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Content-Length: 21\r
+Content-Type: text/html\r
+\r
+Received your input.
+</data>
+</proxyreply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Two requests to the same URL on a reused connection. The second one is a POST request and a client-body-filter is enabled based on a tag. (based on test 6)
+</name>
+<features>
+proxy
+</features>
+<command>
+-s --write-out '%{stderr}%{response_code}\n' --insecure https://%HOSTIP:%HTTPSPORT/tag-bumfidel-requests/%TESTNUMBER --next -d "%repeat[5000 x padding]%bumfidel" -s --write-out '%{stderr}%{response_code}\n' --insecure https://%HOSTIP:%HTTPSPORT/tag-bumfidel-requests/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+GET /tag-bumfidel-requests/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+POST /tag-bumfidel-requests/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Length: 35007\r
+Content-Type: application/x-www-form-urlencoded\r
+\r
+%repeat[5000 x padding]%tralala
+</protocol>
+<stderr>
+200
+200
+</stderr>
+
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-tagger-https/data/test15 b/tests/cts/client-body-tagger-https/data/test15
new file mode 100644 (file)
index 0000000..ece0648
--- /dev/null
@@ -0,0 +1,72 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP POST
+client-body-tagger
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Content-Length: 21
+Content-Type: text/html
+
+Received your input.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Content-Length: 21\r
+Content-Type: text/html\r
+\r
+Received your input.
+</data>
+</proxyreply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Two requests to the same URL. The second one is a POST request with an offending word but it's too large to buffer and tag so it gets to pass. (XXX: Privoxy could execute the tagger based on the data that fits into the buffer) (based on test 7)
+</name>
+<features>
+proxy
+</features>
+<command>
+-s --write-out '%{stderr}%{response_code}\n' --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER --next -d @log/post-data-%TESTNUMBER -s --write-out '%{stderr}%{response_code}\n' --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER
+</command>
+<file name="log/post-data-%TESTNUMBER">
+blafasel%repeat[20000 x padding]%
+</file>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+POST /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Length: 140008\r
+Content-Type: application/x-www-form-urlencoded\r
+\r
+blafasel%repeat[20000 x padding]%
+</protocol>
+<stderr>
+200
+200
+</stderr>
+
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-tagger-https/data/test16 b/tests/cts/client-body-tagger-https/data/test16
new file mode 100644 (file)
index 0000000..94311c4
--- /dev/null
@@ -0,0 +1,72 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP POST
+client-body-tagger
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Content-Length: 21
+Content-Type: text/html
+
+Received your input.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Content-Length: 21\r
+Content-Type: text/html\r
+\r
+Received your input.
+</data>
+</proxyreply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Two requests to the same URL on a reused connection. The second one is a POST request with an offending word but it's chunk-encoded so it gets to pass. (based on test 8)
+</name>
+<features>
+proxy
+</features>
+<command>
+-s --write-out '%{stderr}%{response_code}\n' --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER --next -H "Transfer-Encoding: chunked" -d "blafasel" -s --write-out '%{stderr}%{response_code}\n' --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+POST /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Transfer-Encoding: chunked\r
+Content-Type: application/x-www-form-urlencoded\r
+\r
+8\r
+blafasel\r
+0\r
+\r
+</protocol>
+<stderr>
+200
+200
+</stderr>
+
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-tagger-https/data/test2 b/tests/cts/client-body-tagger-https/data/test2
new file mode 100644 (file)
index 0000000..028d05f
--- /dev/null
@@ -0,0 +1,63 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP POST
+client-body-tagger
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Connection: close\r
+Content-Type: text/html\r
+X-Connection: swsclose\r
+\r
+Received your input.
+</data>
+</proxyreply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Two requests to the same URL. The second one is large and blocked based on a tag applied with the client-body-tagger{blafasel}.
+</name>
+<features>
+proxy
+</features>
+<command>
+-s --write-out '%{stderr}%{response_code}\n' --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER --next -d "blafasel%repeat[5000 x padding]%" -s --write-out '%{stderr}%{response_code}\n' --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<stderr>
+200
+403
+</stderr>
+
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-tagger-https/data/test3 b/tests/cts/client-body-tagger-https/data/test3
new file mode 100644 (file)
index 0000000..9a1fbec
--- /dev/null
@@ -0,0 +1,63 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP POST
+client-body-tagger
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Connection: close\r
+Content-Type: text/html\r
+X-Connection: swsclose\r
+\r
+Received your input.
+</data>
+</proxyreply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Two requests to the same URL. The second one is large and blocked based on a tag. Offending phrase at end of content.
+</name>
+<features>
+proxy
+</features>
+<command>
+-s --write-out '%{stderr}%{response_code}\n' --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER --next -d "%repeat[5000 x padding]%blafasel" -s --write-out '%{stderr}%{response_code}\n' --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<stderr>
+200
+403
+</stderr>
+
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-tagger-https/data/test4 b/tests/cts/client-body-tagger-https/data/test4
new file mode 100644 (file)
index 0000000..96bcf20
--- /dev/null
@@ -0,0 +1,63 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP POST
+client-body-tagger
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Connection: close\r
+Content-Type: text/html\r
+X-Connection: swsclose\r
+\r
+Received your input.
+</data>
+</proxyreply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Two requests to the same URL. The second one is large and blocked based on a tag. Offending phrase in the middle of the content.
+</name>
+<features>
+proxy
+</features>
+<command>
+-s --write-out '%{stderr}%{response_code}\n' --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER --next -d "%repeat[5000 x padding]% blafasel tralala" -s --write-out '%{stderr}%{response_code}\n' --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<stderr>
+200
+403
+</stderr>
+
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-tagger-https/data/test5 b/tests/cts/client-body-tagger-https/data/test5
new file mode 100644 (file)
index 0000000..b7afdfa
--- /dev/null
@@ -0,0 +1,71 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP POST
+client-body-tagger
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Connection: close\r
+Content-Type: text/html\r
+X-Connection: swsclose\r
+\r
+Received your input.
+</data>
+</proxyreply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Two requests to the same URL. The second one is a POST request but it's not expected to be blocked due to a tag.
+</name>
+<features>
+proxy
+</features>
+<command>
+-s --write-out '%{stderr}%{response_code}\n' --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER --next -d "%repeat[5000 x padding]%bumfidel" -s --write-out '%{stderr}%{response_code}\n' --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+POST /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Length: 35008\r
+Content-Type: application/x-www-form-urlencoded\r
+\r
+%repeat[5000 x padding]%bumfidel
+</protocol>
+<stderr>
+200
+200
+</stderr>
+
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-tagger-https/data/test6 b/tests/cts/client-body-tagger-https/data/test6
new file mode 100644 (file)
index 0000000..76dd32d
--- /dev/null
@@ -0,0 +1,71 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP POST
+client-body-tagger
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Connection: close\r
+Content-Type: text/html\r
+X-Connection: swsclose\r
+\r
+Received your input.
+</data>
+</proxyreply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Two requests to the same URL. The second one is a POST request and a client-body-filter is enabled based on a tag.
+</name>
+<features>
+proxy
+</features>
+<command>
+-s --write-out '%{stderr}%{response_code}\n' --insecure https://%HOSTIP:%HTTPSPORT/tag-bumfidel-requests/%TESTNUMBER --next -d "%repeat[5000 x padding]%bumfidel" -s --write-out '%{stderr}%{response_code}\n' --insecure https://%HOSTIP:%HTTPSPORT/tag-bumfidel-requests/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+GET /tag-bumfidel-requests/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+POST /tag-bumfidel-requests/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Length: 35007\r
+Content-Type: application/x-www-form-urlencoded\r
+\r
+%repeat[5000 x padding]%tralala
+</protocol>
+<stderr>
+200
+200
+</stderr>
+
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-tagger-https/data/test7 b/tests/cts/client-body-tagger-https/data/test7
new file mode 100644 (file)
index 0000000..445148d
--- /dev/null
@@ -0,0 +1,74 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP POST
+client-body-tagger
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Connection: close\r
+Content-Type: text/html\r
+X-Connection: swsclose\r
+\r
+Received your input.
+</data>
+</proxyreply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Two requests to the same URL. The second one is a POST request with an offending word but it's too large to buffer and tag so it gets to pass. (XXX: Privoxy could execute the tagger based on the data that fits into the buffer)
+</name>
+<features>
+proxy
+</features>
+<command>
+-s --write-out '%{stderr}%{response_code}\n' --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER --next -d @log/post-data-%TESTNUMBER -s --write-out '%{stderr}%{response_code}\n' --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER
+</command>
+<file name="log/post-data-%TESTNUMBER">
+blafasel%repeat[20000 x padding]%
+</file>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+POST /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Length: 140008\r
+Content-Type: application/x-www-form-urlencoded\r
+\r
+blafasel%repeat[20000 x padding]%
+</protocol>
+<stderr>
+200
+200
+</stderr>
+
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-tagger-https/data/test8 b/tests/cts/client-body-tagger-https/data/test8
new file mode 100644 (file)
index 0000000..3809140
--- /dev/null
@@ -0,0 +1,74 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP POST
+client-body-tagger
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Connection: close\r
+Content-Type: text/html\r
+X-Connection: swsclose\r
+\r
+Received your input.
+</data>
+</proxyreply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Two requests to the same URL. The second one is a POST request with an offending word but it's chunk-encoded so it gets to pass.
+</name>
+<features>
+proxy
+</features>
+<command>
+-s --write-out '%{stderr}%{response_code}\n' --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER --next -H "Transfer-Encoding: chunked" -d "blafasel" -s --write-out '%{stderr}%{response_code}\n' --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+POST /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Transfer-Encoding: chunked\r
+Content-Type: application/x-www-form-urlencoded\r
+\r
+8\r
+blafasel\r
+0\r
+\r
+</protocol>
+<stderr>
+200
+200
+</stderr>
+
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-tagger-https/data/test9 b/tests/cts/client-body-tagger-https/data/test9
new file mode 100644 (file)
index 0000000..f829288
--- /dev/null
@@ -0,0 +1,61 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP POST
+client-body-tagger
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Content-Length: 21
+Content-Type: text/html
+
+Received your input.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established\r
+\r
+HTTP/1.1 200 OK\r
+Content-Length: 21\r
+Content-Type: text/html\r
+\r
+Received your input.
+</data>
+</proxyreply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Two requests to the same URL on a reused connection. The second one is blocked based on a tag applied with client-body-tagger{blafasel}. (based on test 1)
+</name>
+<features>
+proxy
+</features>
+<command>
+-s --write-out '%{stderr}%{response_code}\n' --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER --next -d blafasel -s --write-out '%{stderr}%{response_code}\n' --insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<stderr>
+200
+403
+</stderr>
+
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-tagger-https/privoxy.conf b/tests/cts/client-body-tagger-https/privoxy.conf
new file mode 100644 (file)
index 0000000..09b4f68
--- /dev/null
@@ -0,0 +1,38 @@
+listen-address 127.0.0.1:9119
+
+ca-directory          ../ca-directory
+ca-cert-file          privoxy-test-cacert.crt
+ca-key-file           privoxy-test-cakey.pem
+ca-password           blafasel
+# We don't check certificate anyway
+trusted-cas-file      privoxy-test-cacert.crt
+
+certificate-directory ../certs
+
+debug     1 # Log the destination for each request Privoxy let through. See also debug 1024.
+debug     2 # show each connection status
+debug     4 # show tagging-related messages
+debug     8 # show header parsing
+debug    32 # debug force feature
+debug    64 # debug regular expression filters
+debug   128 # debug redirects
+debug   256 # debug GIF de-animation
+debug   512 # Common Log Format
+debug  1024 # Log the destination for requests Privoxy didn't let through, and the reason why.
+debug  4096 # Startup banner and warnings.
+debug  8192 # Non-fatal errors
+
+actionsfile ../blocked-https-requests/https-inspection.action
+actionsfile ../client-body-tagger/client-body-tagger.action
+filterfile ../client-body-tagger/client-body-tagger.filter
+filterfile ../client-body-filter/client-body-filter.filter
+
+socket-timeout 3
+
+templdir ../../../templates/
+
+# Reduce buffer limit so tests can reach it sooner.
+buffer-limit 100
+
+keep-alive-timeout 10
+default-server-timeout 10
diff --git a/tests/cts/client-body-tagger/client-body-tagger.action b/tests/cts/client-body-tagger/client-body-tagger.action
new file mode 100644 (file)
index 0000000..2bc5848
--- /dev/null
@@ -0,0 +1,11 @@
+{+client-body-tagger{blafasel}}
+/
+
+{+block{Request body contains blafasel}}
+TAG:^content contains blafasel$
+
+{+client-body-tagger{bumfidel}}
+/tag-bumfidel-requests/
+
+{+client-body-filter{bumfidel-to-tralala}}
+TAG:^content contains bumfidel$
diff --git a/tests/cts/client-body-tagger/client-body-tagger.filter b/tests/cts/client-body-tagger/client-body-tagger.filter
new file mode 100644 (file)
index 0000000..dc3ebae
--- /dev/null
@@ -0,0 +1,5 @@
+CLIENT-BODY-TAGGER: blafasel Tags requests with "content contains blafasel" if the client body contains the word "blafasel"
+s@.*blafasel.*@content contains blafasel@s
+
+CLIENT-BODY-TAGGER: bumfidel Tags requests with "content contains bumfidel" if the client body contains the word "bumfidel"
+s@.*bumfidel.*@content contains bumfidel@s
diff --git a/tests/cts/client-body-tagger/data/test1 b/tests/cts/client-body-tagger/data/test1
new file mode 100644 (file)
index 0000000..77814a1
--- /dev/null
@@ -0,0 +1,51 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP POST
+client-body-tagger
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Two requests to the same URL. The second one is blocked based on a tag applied with client-body-tagger{blafasel}.
+</name>
+<features>
+proxy
+</features>
+<command>
+-s --write-out '%{stderr}%{response_code}\n' http://%HOSTIP:%HTTPPORT/%TESTNUMBER --next -d blafasel -s --write-out '%{stderr}%{response_code}\n' http://%HOSTIP:%HTTPPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+<stderr>
+200
+403
+</stderr>
+
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-tagger/data/test2 b/tests/cts/client-body-tagger/data/test2
new file mode 100644 (file)
index 0000000..0931e57
--- /dev/null
@@ -0,0 +1,51 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP POST
+client-body-tagger
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Two requests to the same URL. The second one is large and blocked based on a tag applied with the client-body-tagger{blafasel}.
+</name>
+<features>
+proxy
+</features>
+<command>
+-s --write-out '%{stderr}%{response_code}\n' http://%HOSTIP:%HTTPPORT/%TESTNUMBER --next -d "blafasel%repeat[5000 x padding]%" -s --write-out '%{stderr}%{response_code}\n' http://%HOSTIP:%HTTPPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+<stderr>
+200
+403
+</stderr>
+
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-tagger/data/test3 b/tests/cts/client-body-tagger/data/test3
new file mode 100644 (file)
index 0000000..1968b47
--- /dev/null
@@ -0,0 +1,51 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP POST
+client-body-tagger
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Two requests to the same URL. The second one is large and blocked based on a tag. Offending phrase at end of content.
+</name>
+<features>
+proxy
+</features>
+<command>
+-s --write-out '%{stderr}%{response_code}\n' http://%HOSTIP:%HTTPPORT/%TESTNUMBER --next -d "%repeat[5000 x padding]%blafasel" -s --write-out '%{stderr}%{response_code}\n' http://%HOSTIP:%HTTPPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+<stderr>
+200
+403
+</stderr>
+
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-tagger/data/test4 b/tests/cts/client-body-tagger/data/test4
new file mode 100644 (file)
index 0000000..b342917
--- /dev/null
@@ -0,0 +1,51 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP POST
+client-body-tagger
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Two requests to the same URL. The second one is large and blocked based on a tag. Offending phrase in the middle of the content.
+</name>
+<features>
+proxy
+</features>
+<command>
+-s --write-out '%{stderr}%{response_code}\n' http://%HOSTIP:%HTTPPORT/%TESTNUMBER --next -d "%repeat[5000 x padding]% blafasel tralala" -s --write-out '%{stderr}%{response_code}\n' http://%HOSTIP:%HTTPPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+<stderr>
+200
+403
+</stderr>
+
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-tagger/data/test5 b/tests/cts/client-body-tagger/data/test5
new file mode 100644 (file)
index 0000000..092af03
--- /dev/null
@@ -0,0 +1,60 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP POST
+client-body-tagger
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Two requests to the same URL. The second one is a POST request but it's not expected to be blocked due to a tag.
+</name>
+<features>
+proxy
+</features>
+<command>
+-s --write-out '%{stderr}%{response_code}\n' http://%HOSTIP:%HTTPPORT/%TESTNUMBER --next -d "%repeat[5000 x padding]%bumfidel" -s --write-out '%{stderr}%{response_code}\n' http://%HOSTIP:%HTTPPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+POST /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Length: 35008\r
+Content-Type: application/x-www-form-urlencoded\r
+Connection: close\r
+\r
+%repeat[5000 x padding]%bumfidel
+</protocol>
+<stderr>
+200
+200
+</stderr>
+
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-tagger/data/test6 b/tests/cts/client-body-tagger/data/test6
new file mode 100644 (file)
index 0000000..cbb0065
--- /dev/null
@@ -0,0 +1,60 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP POST
+client-body-tagger
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Two requests to the same URL. The second one is a POST request and a client-body-filter is enabled based on a tag.
+</name>
+<features>
+proxy
+</features>
+<command>
+-s --write-out '%{stderr}%{response_code}\n' http://%HOSTIP:%HTTPPORT/tag-bumfidel-requests/%TESTNUMBER --next -d "%repeat[5000 x padding]%bumfidel" -s --write-out '%{stderr}%{response_code}\n' http://%HOSTIP:%HTTPPORT/tag-bumfidel-requests/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+GET /tag-bumfidel-requests/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+POST /tag-bumfidel-requests/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Length: 35007\r
+Content-Type: application/x-www-form-urlencoded\r
+Connection: close\r
+\r
+%repeat[5000 x padding]%tralala
+</protocol>
+<stderr>
+200
+200
+</stderr>
+
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-tagger/data/test7 b/tests/cts/client-body-tagger/data/test7
new file mode 100644 (file)
index 0000000..753d89f
--- /dev/null
@@ -0,0 +1,63 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP POST
+client-body-tagger
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Two requests to the same URL. The second one is a POST request with an offending word but it's too large to buffer and tag so it gets to pass. (XXX: Privoxy could execute the tagger based on the data that fits into the buffer)
+</name>
+<features>
+proxy
+</features>
+<command>
+-s --write-out '%{stderr}%{response_code}\n' http://%HOSTIP:%HTTPPORT/%TESTNUMBER --next -d @log/post-data-%TESTNUMBER -s --write-out '%{stderr}%{response_code}\n' http://%HOSTIP:%HTTPPORT/%TESTNUMBER
+</command>
+<file name="log/post-data-%TESTNUMBER">
+blafasel%repeat[20000 x padding]%
+</file>
+</client>
+
+<verify>
+<protocol nonewline="yes">
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+POST /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Content-Length: 140008\r
+Content-Type: application/x-www-form-urlencoded\r
+Connection: close\r
+\r
+blafasel%repeat[20000 x padding]%
+</protocol>
+<stderr>
+200
+200
+</stderr>
+
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-tagger/data/test8 b/tests/cts/client-body-tagger/data/test8
new file mode 100644 (file)
index 0000000..c669915
--- /dev/null
@@ -0,0 +1,63 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP POST
+client-body-tagger
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Two requests to the same URL. The second one is a POST request with an offending word but it's chunk-encoded so it gets to pass.
+</name>
+<features>
+proxy
+</features>
+<command>
+-s --write-out '%{stderr}%{response_code}\n' http://%HOSTIP:%HTTPPORT/%TESTNUMBER --next -H "Transfer-Encoding: chunked" -d "blafasel" -s --write-out '%{stderr}%{response_code}\n' http://%HOSTIP:%HTTPPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+POST /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Transfer-Encoding: chunked\r
+Content-Type: application/x-www-form-urlencoded\r
+Connection: close\r
+\r
+8\r
+blafasel\r
+0\r
+\r
+</protocol>
+<stderr>
+200
+200
+</stderr>
+
+</verify>
+</testcase>
diff --git a/tests/cts/client-body-tagger/privoxy.conf b/tests/cts/client-body-tagger/privoxy.conf
new file mode 100644 (file)
index 0000000..9628703
--- /dev/null
@@ -0,0 +1,25 @@
+listen-address 127.0.0.1:9119
+
+debug     1 # Log the destination for each request Privoxy let through. See also debug 1024.
+debug     2 # show each connection status
+debug     4 # show tagging-related messages
+debug     8 # show header parsing
+debug    32 # debug force feature
+debug    64 # debug regular expression filters
+debug   128 # debug redirects
+debug   256 # debug GIF de-animation
+debug   512 # Common Log Format
+debug  1024 # Log the destination for requests Privoxy didn't let through, and the reason why.
+debug  4096 # Startup banner and warnings.
+debug  8192 # Non-fatal errors
+
+actionsfile client-body-tagger.action
+filterfile client-body-tagger.filter
+filterfile ../client-body-filter/client-body-filter.filter
+
+socket-timeout 3
+
+templdir ../../../templates/
+
+# Reduce buffer limit so tests can reach it sooner.
+buffer-limit 100
diff --git a/tests/cts/client-header-order-https/data/test332 b/tests/cts/client-header-order-https/data/test332
new file mode 100644 (file)
index 0000000..2e0287f
--- /dev/null
@@ -0,0 +1,66 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Content-Length: 9
+Connection: close
+
+Blafasel
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established
+
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Content-Length: 9
+Connection: close
+
+Blafasel
+</data>
+</proxy-reply>
+
+
+<client>
+<server>
+https
+</server>
+
+<name>
+HTTP client header order through https
+</name>
+<command>
+--insecure -H "Origin: https://www.privoxy.org/" -H "Cache-Control: max-age=315576000" -H "If-Modified-Since: Thu, 07 Jan 2021 22:05:31 GMT" -H "Upgrade-Insecure-Requests: 1" -H "Pragma: no-cache" -H "DNT: 1" -H "Cookie: yolo=123" -H "Referer: https://www.example.org/" -H "Proxy-Connection: keep-alive" -H "Accept-Encoding: gzip" -H "Accept: */*" -H "Host: %HOSTIP:%HTTPSPORT" -H "Accept-Language: en-CA" --user-agent "Client with unsorted headers" https://%HOSTIP:%HTTPSPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: Client with unsorted headers\r
+Accept: */*\r
+Accept-Language: en-CA\r
+Accept-Encoding: gzip\r
+Referer: https://www.example.org/\r
+Cookie: yolo=123\r
+DNT: 1\r
+Pragma: no-cache\r
+Upgrade-Insecure-Requests: 1\r
+If-Modified-Since: Thu, 07 Jan 2021 22:05:31 GMT\r
+Cache-Control: max-age=315576000\r
+Origin: https://www.privoxy.org/\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/client-header-order-https/data/test333 b/tests/cts/client-header-order-https/data/test333
new file mode 100644 (file)
index 0000000..38d4ea8
--- /dev/null
@@ -0,0 +1,64 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Content-Length: 9
+
+Blafasel
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established
+
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Content-Length: 9
+Connection: close
+
+Blafasel
+</data>
+</proxy-reply>
+
+
+<client>
+<server>
+https
+</server>
+<name>
+HTTP client header order through https 2
+</name>
+<command>
+--insecure -H "Origin: https://www.privoxy.org/" -H "Cache-Control: max-age=315576000" -H "If-Modified-Since: Thu, 07 Jan 2021 22:05:31 GMT" -H "Upgrade-Insecure-Requests: 1" -H "DNT: 1" -H "Pragma: no-cache" -H "Cookie: yolo=123" -H "Referer: https://www.example.org/" -H "Accept-Encoding: gzip" -H "Proxy-Connection: keep-alive" -H "Accept: */*" -H "Accept-Language: en-CA" -H "Host: %HOSTIP:%HTTPSPORT" --user-agent "Client with unsorted headers" https://%HOSTIP:%HTTPSPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: Client with unsorted headers\r
+Accept: */*\r
+Accept-Language: en-CA\r
+Accept-Encoding: gzip\r
+Referer: https://www.example.org/\r
+Cookie: yolo=123\r
+DNT: 1\r
+Pragma: no-cache\r
+Upgrade-Insecure-Requests: 1\r
+If-Modified-Since: Thu, 07 Jan 2021 22:05:31 GMT\r
+Cache-Control: max-age=315576000\r
+Origin: https://www.privoxy.org/\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/client-header-order-https/data/test334 b/tests/cts/client-header-order-https/data/test334
new file mode 100644 (file)
index 0000000..21e9fde
--- /dev/null
@@ -0,0 +1,56 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Content-Length: 9
+
+Blafasel
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established
+
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Content-Length: 9
+Connection: close
+
+Blafasel
+</data>
+</proxy-reply>
+
+<client>
+<features>
+SSL
+</features>
+<server>
+https
+</server>
+<name>
+HTTP client header order 3 through https. Only a few headers to sort.
+</name>
+<command>
+--insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/client-header-order-https/data/test335 b/tests/cts/client-header-order-https/data/test335
new file mode 100644 (file)
index 0000000..03315aa
--- /dev/null
@@ -0,0 +1,66 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Content-Length: 9
+
+Blafasel
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established
+
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Content-Length: 9
+Connection: close
+
+Blafasel
+</data>
+</proxy-reply>
+
+
+<client>
+<server>
+https
+</server>
+<name>
+HTTP client header order 4. Left over headers.
+</name>
+<command>
+--insecure -H "Bum: Tschaka" -H "Blafasel: Die da" -H "Origin: https://www.privoxy.org/" -H "Cache-Control: max-age=315576000" -H "If-Modified-Since: Thu, 07 Jan 2021 22:05:31 GMT" -H "Upgrade-Insecure-Requests: 1" -H "DNT: 1" -H "Pragma: no-cache" -H "Cookie: yolo=123" -H "Referer: https://www.example.org/" -H "Accept-Encoding: gzip" -H "Proxy-Connection: keep-alive" -H "Accept: */*" -H "Accept-Language: en-CA" -H "Host: %HOSTIP:%HTTPSPORT" --user-agent "Client with unsorted headers" https://%HOSTIP:%HTTPSPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: Client with unsorted headers\r
+Accept: */*\r
+Accept-Language: en-CA\r
+Accept-Encoding: gzip\r
+Referer: https://www.example.org/\r
+Cookie: yolo=123\r
+DNT: 1\r
+Pragma: no-cache\r
+Upgrade-Insecure-Requests: 1\r
+If-Modified-Since: Thu, 07 Jan 2021 22:05:31 GMT\r
+Cache-Control: max-age=315576000\r
+Origin: https://www.privoxy.org/\r
+Bum: Tschaka\r
+Blafasel: Die da\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/client-header-order-https/https-inspection.action b/tests/cts/client-header-order-https/https-inspection.action
new file mode 100644 (file)
index 0000000..01b2181
--- /dev/null
@@ -0,0 +1,2 @@
+{+https-inspection +ignore-certificate-errors}
+/
diff --git a/tests/cts/client-header-order-https/privoxy.conf b/tests/cts/client-header-order-https/privoxy.conf
new file mode 100644 (file)
index 0000000..2df6cce
--- /dev/null
@@ -0,0 +1,31 @@
+listen-address 127.0.0.1:9119
+
+ca-directory          ../ca-directory
+ca-cert-file          privoxy-test-cacert.crt
+ca-key-file           privoxy-test-cakey.pem
+ca-password           blafasel
+# We don't check certificate anyway
+trusted-cas-file      privoxy-test-cacert.crt
+
+certificate-directory ../certs
+
+client-header-order Host User-Agent Accept Accept-Language Accept-Encoding \
+                    Proxy-Connection Referer Cookie DNT Connection \
+                    Pragma Upgrade-Insecure-Requests If-Modified-Since \
+                    Cache-Control Content-Length Origin Content-Type
+
+actionsfile ./https-inspection.action
+
+debug     1 # Log the destination for each request Privoxy let through. See also debug 1024.
+debug     2 # show each connection status
+debug     4 # show tagging-related messages
+debug     8 # show header parsing
+debug    32 # debug force feature
+debug    64 # debug regular expression filters
+debug   128 # debug redirects
+debug   256 # debug GIF de-animation
+debug   512 # Common Log Format
+debug  1024 # Log the destination for requests Privoxy didn't let through, and the reason why.
+debug  4096 # Startup banner and warnings.
+debug  8192 # Non-fatal errors
+
diff --git a/tests/cts/client-header-order/data/test332 b/tests/cts/client-header-order/data/test332
new file mode 100644 (file)
index 0000000..0cf8407
--- /dev/null
@@ -0,0 +1,52 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Content-Length: 9
+
+Blafasel
+</data>
+</reply>
+
+
+<client>
+<server>
+http
+</server>
+<name>
+HTTP client header order
+</name>
+<command>
+-H "Origin: https://www.privoxy.org/" -H "Cache-Control: max-age=315576000" -H "If-Modified-Since: Thu, 07 Jan 2021 22:05:31 GMT" -H "Upgrade-Insecure-Requests: 1" -H "Pragma: no-cache" -H "DNT: 1" -H "Cookie: yolo=123" -H "Referer: https://www.example.org/" -H "Proxy-Connection: keep-alive" -H "Accept-Encoding: gzip" -H "Accept: */*" -H "Host: %HOSTIP:%HTTPPORT" -H "Accept-Language: en-CA" --user-agent "Client with unsorted headers" http://%HOSTIP:%HTTPPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: Client with unsorted headers\r
+Accept: */*\r
+Accept-Language: en-CA\r
+Accept-Encoding: gzip\r
+Referer: https://www.example.org/\r
+Cookie: yolo=123\r
+DNT: 1\r
+Connection: close\r
+Pragma: no-cache\r
+Upgrade-Insecure-Requests: 1\r
+If-Modified-Since: Thu, 07 Jan 2021 22:05:31 GMT\r
+Cache-Control: max-age=315576000\r
+Origin: https://www.privoxy.org/\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/client-header-order/data/test333 b/tests/cts/client-header-order/data/test333
new file mode 100644 (file)
index 0000000..a67eb4f
--- /dev/null
@@ -0,0 +1,52 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Content-Length: 9
+
+Blafasel
+</data>
+</reply>
+
+
+<client>
+<server>
+http
+</server>
+<name>
+HTTP client header order 2
+</name>
+<command>
+-H "Origin: https://www.privoxy.org/" -H "Cache-Control: max-age=315576000" -H "If-Modified-Since: Thu, 07 Jan 2021 22:05:31 GMT" -H "Upgrade-Insecure-Requests: 1" -H "DNT: 1" -H "Pragma: no-cache" -H "Cookie: yolo=123" -H "Referer: https://www.example.org/" -H "Accept-Encoding: gzip" -H "Proxy-Connection: keep-alive" -H "Accept: */*" -H "Accept-Language: en-CA" -H "Host: %HOSTIP:%HTTPPORT" --user-agent "Client with unsorted headers" http://%HOSTIP:%HTTPPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: Client with unsorted headers\r
+Accept: */*\r
+Accept-Language: en-CA\r
+Accept-Encoding: gzip\r
+Referer: https://www.example.org/\r
+Cookie: yolo=123\r
+DNT: 1\r
+Connection: close\r
+Pragma: no-cache\r
+Upgrade-Insecure-Requests: 1\r
+If-Modified-Since: Thu, 07 Jan 2021 22:05:31 GMT\r
+Cache-Control: max-age=315576000\r
+Origin: https://www.privoxy.org/\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/client-header-order/data/test334 b/tests/cts/client-header-order/data/test334
new file mode 100644 (file)
index 0000000..2c7ed0f
--- /dev/null
@@ -0,0 +1,42 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Content-Length: 9
+
+Blafasel
+</data>
+</reply>
+
+
+<client>
+<server>
+http
+</server>
+<name>
+HTTP client header order 3. Only a few headers to sort.
+</name>
+<command>
+http://%HOSTIP:%HTTPPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/client-header-order/data/test335 b/tests/cts/client-header-order/data/test335
new file mode 100644 (file)
index 0000000..7c89c6b
--- /dev/null
@@ -0,0 +1,54 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Content-Length: 9
+
+Blafasel
+</data>
+</reply>
+
+
+<client>
+<server>
+http
+</server>
+<name>
+HTTP client header order 4. Left over headers.
+</name>
+<command>
+-H "Bum: Tschaka" -H "Blafasel: Die da" -H "Origin: https://www.privoxy.org/" -H "Cache-Control: max-age=315576000" -H "If-Modified-Since: Thu, 07 Jan 2021 22:05:31 GMT" -H "Upgrade-Insecure-Requests: 1" -H "DNT: 1" -H "Pragma: no-cache" -H "Cookie: yolo=123" -H "Referer: https://www.example.org/" -H "Accept-Encoding: gzip" -H "Proxy-Connection: keep-alive" -H "Accept: */*" -H "Accept-Language: en-CA" -H "Host: %HOSTIP:%HTTPPORT" --user-agent "Client with unsorted headers" http://%HOSTIP:%HTTPPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: Client with unsorted headers\r
+Accept: */*\r
+Accept-Language: en-CA\r
+Accept-Encoding: gzip\r
+Referer: https://www.example.org/\r
+Cookie: yolo=123\r
+DNT: 1\r
+Connection: close\r
+Pragma: no-cache\r
+Upgrade-Insecure-Requests: 1\r
+If-Modified-Since: Thu, 07 Jan 2021 22:05:31 GMT\r
+Cache-Control: max-age=315576000\r
+Origin: https://www.privoxy.org/\r
+Bum: Tschaka\r
+Blafasel: Die da\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/client-header-order/privoxy.conf b/tests/cts/client-header-order/privoxy.conf
new file mode 100644 (file)
index 0000000..fb15ffd
--- /dev/null
@@ -0,0 +1,20 @@
+listen-address 127.0.0.1:9119
+
+client-header-order Host User-Agent Accept Accept-Language Accept-Encoding \
+                    Proxy-Connection Referer Cookie DNT Connection \
+                    Pragma Upgrade-Insecure-Requests If-Modified-Since \
+                    Cache-Control Content-Length Origin Content-Type
+
+debug     1 # Log the destination for each request Privoxy let through. See also debug 1024.
+debug     2 # show each connection status
+debug     4 # show tagging-related messages
+debug     8 # show header parsing
+debug    32 # debug force feature
+debug    64 # debug regular expression filters
+debug   128 # debug redirects
+debug   256 # debug GIF de-animation
+debug   512 # Common Log Format
+debug  1024 # Log the destination for requests Privoxy didn't let through, and the reason why.
+debug  4096 # Startup banner and warnings.
+debug  8192 # Non-fatal errors
+
diff --git a/tests/cts/client-tags/client-tags.action b/tests/cts/client-tags/client-tags.action
new file mode 100644 (file)
index 0000000..6fb6b3b
--- /dev/null
@@ -0,0 +1,8 @@
+{+block{Blocked based on the path}}
+/block-request/
+
+{-block}
+CLIENT-TAG:^overrule-blocks$
+
+{-filter}
+CLIENT-TAG:^overrule-filters$
diff --git a/tests/cts/client-tags/data/test1 b/tests/cts/client-tags/data/test1
new file mode 100644 (file)
index 0000000..1c6ea1a
--- /dev/null
@@ -0,0 +1,26 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<client>
+<server>
+none
+</server>
+<name>
+Request to blocked URL with now client-tags active
+</name>
+<command>
+-s --write-out '%{stderr}%{response_code}\n' http://www.electrobsd.org/block-request/
+</command>
+</client>
+
+<verify>
+<stderr>
+403
+</stderr>
+</verify>
+</testcase>
diff --git a/tests/cts/client-tags/data/test2 b/tests/cts/client-tags/data/test2
new file mode 100644 (file)
index 0000000..59f8b12
--- /dev/null
@@ -0,0 +1,27 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<client>
+<server>
+http
+</server>
+<name>
+Attempt to enable client-tag to disable block action for follow-up request without trusted Referer
+</name>
+<command>
+-s --write-out '%{stderr}%{response_code}\n' 'http://p.p/toggle-client-tag?tag=overrule-blocks&toggle-state=1&expires=1' --next -s --write-out '%{stderr}%{response_code}\n' http://%HOSTIP:%HTTPPORT/block-request/
+</command>
+</client>
+
+<verify>
+<stderr>
+403
+403
+</stderr>
+</verify>
+</testcase>
diff --git a/tests/cts/client-tags/data/test3 b/tests/cts/client-tags/data/test3
new file mode 100644 (file)
index 0000000..8b0d6ac
--- /dev/null
@@ -0,0 +1,39 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Enabling client-tag to disable block action for follow-up request with trusted Referer
+</name>
+# Limit the transfer rate for the second request so tag timed out by the time the next test is executed.
+<command option="no-include">
+-s --write-out '%{stderr}%{response_code}\n' --referer "http://p.p/client-tags" 'http://p.p/toggle-client-tag?tag=overrule-blocks&toggle-state=1&expires=1' --next -s --include --output log/curl%TESTNUMBER.out --write-out '%{stderr}%{response_code}\n' --limit-rate 10 http://%HOSTIP:%HTTPPORT/block-request/
+</command>
+</client>
+
+<verify>
+<stderr>
+302
+200
+</stderr>
+</verify>
+</testcase>
diff --git a/tests/cts/client-tags/data/test4 b/tests/cts/client-tags/data/test4
new file mode 100644 (file)
index 0000000..6a2240b
--- /dev/null
@@ -0,0 +1,40 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+X-Connection: swsclose
+
+Received your input.
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Enabling client-tag to disable block action for follow-up request with trusted Referer and disabling it again
+</name>
+<command option="no-include">
+-s --write-out '%{stderr}%{response_code}\n' --referer "http://p.p/client-tags" 'http://p.p/toggle-client-tag?tag=overrule-blocks&toggle-state=1&expires=1' --next -s --include --output log/curl%TESTNUMBER.out --write-out '%{stderr}%{response_code}\n' http://%HOSTIP:%HTTPPORT/block-request/ --next -s --write-out '%{stderr}%{response_code}\n' --referer "http://p.p/client-tags" 'http://p.p/toggle-client-tag?tag=overrule-blocks&toggle-state=0&expires=1' --next --write-out '%{stderr}%{response_code}\n' http://%HOSTIP:%HTTPPORT/block-request/
+</command>
+</client>
+
+<verify>
+<stderr>
+302
+200
+302
+403
+</stderr>
+</verify>
+</testcase>
diff --git a/tests/cts/client-tags/data/test5 b/tests/cts/client-tags/data/test5
new file mode 100644 (file)
index 0000000..4eddbc5
--- /dev/null
@@ -0,0 +1,39 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Content-Length: 21
+Content-Type: text/html
+
+Received your input.
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Enabling client-tag to disable block action for follow-up request with trusted Referer and disabling it again reusing the connection (based on test 4)
+</name>
+<command option="no-include">
+-s --write-out '%{stderr}%{response_code}\n' --referer "http://p.p/client-tags" 'http://p.p/toggle-client-tag?tag=overrule-blocks&toggle-state=1&expires=1' --next -s --include --output log/curl%TESTNUMBER.out --write-out '%{stderr}%{response_code}\n' http://%HOSTIP:%HTTPPORT/block-request/ --next -s --write-out '%{stderr}%{response_code}\n' --referer "http://p.p/client-tags" 'http://p.p/toggle-client-tag?tag=overrule-blocks&toggle-state=0&expires=1' --next --write-out '%{stderr}%{response_code}\n' http://%HOSTIP:%HTTPPORT/block-request/
+</command>
+</client>
+
+<verify>
+<stderr>
+302
+200
+302
+403
+</stderr>
+</verify>
+</testcase>
diff --git a/tests/cts/client-tags/data/test6 b/tests/cts/client-tags/data/test6
new file mode 100644 (file)
index 0000000..c11365a
--- /dev/null
@@ -0,0 +1,39 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Content-Length: 21
+Content-Type: text/html
+
+Received your input.
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Enabling client-tag to disable block action for follow-up request with Referer specified with trusted-cgi-referer and disabling the tag again reusing the connection (based on test 5)
+</name>
+<command option="no-include">
+-s --write-out '%{stderr}%{response_code}\n' --referer "http://www.electrobsd.org/" 'http://p.p/toggle-client-tag?tag=overrule-blocks&toggle-state=1&expires=1' --next -s --include --output log/curl%TESTNUMBER.out --write-out '%{stderr}%{response_code}\n' http://%HOSTIP:%HTTPPORT/block-request/ --next -s --write-out '%{stderr}%{response_code}\n' --referer "http://www.electrobsd.org/" 'http://p.p/toggle-client-tag?tag=overrule-blocks&toggle-state=0&expires=1' --next --write-out '%{stderr}%{response_code}\n' http://%HOSTIP:%HTTPPORT/block-request/
+</command>
+</client>
+
+<verify>
+<stderr>
+302
+200
+302
+403
+</stderr>
+</verify>
+</testcase>
diff --git a/tests/cts/client-tags/data/test7 b/tests/cts/client-tags/data/test7
new file mode 100644 (file)
index 0000000..905cab5
--- /dev/null
@@ -0,0 +1,38 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<proxy-reply>
+<data>
+HTTP/1.1 302 Done dealing with toggle request
+Location: //config.privoxy.org/client-tags
+Access-Control-Allow-Origin: http://www.electrobsd.org/
+Access-Control-Allow-Methods: GET,POST
+Access-Control-Allow-Headers: X-Requested-With
+Access-Control-Max-Age: 86400
+Content-Length: 0
+X-Ignore-Header: Date
+Date: Sun, 28 Mar 2021 09:35:05 GMT
+
+</data>
+</proxy-reply>
+
+<client>
+<server>
+none
+</server>
+<name>
+Confirm that the cors-allowed-origin directives results in headers being are added to CGI responses.
+</name>
+<command>
+--head --referer http://www.electrobsd.org/ 'http://p.p/toggle-client-tag'
+</command>
+</client>
+
+<verify>
+</verify>
+</testcase>
diff --git a/tests/cts/client-tags/privoxy.conf b/tests/cts/client-tags/privoxy.conf
new file mode 100644 (file)
index 0000000..443b78a
--- /dev/null
@@ -0,0 +1,36 @@
+listen-address 127.0.0.1:9119
+
+debug     1 # Log the destination for each request Privoxy let through. See also debug 1024.
+debug     2 # show each connection status
+debug     4 # show tagging-related messages
+debug     8 # show header parsing
+debug    32 # debug force feature
+debug    64 # debug regular expression filters
+debug   128 # debug redirects
+debug   256 # debug GIF de-animation
+debug   512 # Common Log Format
+debug  1024 # Log the destination for requests Privoxy didn't let through, and the reason why.
+debug  4096 # Startup banner and warnings.
+debug  8192 # Non-fatal errors
+debug 65536 # log applying actions
+#debug    16 # log all data written to the network into the logfile
+#debug 32768 # log all data read from the network
+
+actionsfile client-tags.action
+filterfile ../../../default.filter
+
+socket-timeout 3
+
+templdir ../../../templates/
+
+client-specific-tag overrule-blocks Overrule block sections.
+client-specific-tag overrule-filters Overrule filter sections.
+
+# Try to let tags timeout between tests. This is racy but works for me.
+client-tag-lifetime 1
+
+trusted-cgi-referer http://www.electrobsd.org/
+cors-allowed-origin http://www.electrobsd.org/
+
+keep-alive-timeout 10
+default-server-timeout 10
diff --git a/tests/cts/content-filters/content-filters.action b/tests/cts/content-filters/content-filters.action
new file mode 100644 (file)
index 0000000..25de253
--- /dev/null
@@ -0,0 +1,95 @@
+{+filter{js-annoyances}}
+/js-annoyances/
+
+{+filter{js-events}}
+/js-events/
+
+{+filter{html-annoyances}}
+/html-annoyances/
+
+{+filter{content-cookies}}
+/content-cookies/
+
+{+filter{refresh-tags}}
+/refresh-tags/
+
+{+filter{unsolicited-popups}}
+/unsolicited-popups/
+
+{+filter{all-popups}}
+/all-popups/
+
+{+filter{img-reorder}}
+/img-reorder/
+
+{+filter{banners-by-size}}
+/banners-by-size/
+
+{+filter{banners-by-link}}
+/banners-by-link/
+
+{+filter{webbugs}}
+/webbugs/
+
+{+filter{tiny-textforms}}
+/tiny-textforms/
+
+{+filter{jumping-windows}}
+/jumping-windows/
+
+{+filter{frameset-borders}}
+/frameset-borders/
+
+{+filter{iframes}}
+/iframes/
+
+{+filter{demoronizer}}
+/demoronizer/
+
+{+filter{shockwave-flash}}
+/shockwave-flash/
+
+{+filter{quicktime-kioskmode}}
+/quicktime-kioskmode/
+
+{+filter{fun}}
+/fun/
+
+{+filter{crude-parental}}
+/crude-parental/
+
+{+filter{ie-exploits}}
+/ie-exploits/
+
+{+filter{site-specifics}}
+/site-specifics/
+
+{+filter{no-ping}}
+/no-ping/
+
+{+filter{allow-autocompletion}}
+/allow-autocompletion/
+
+{+filter{github}}
+/github/
+
+{+filter{imdb}}
+/imdb/
+
+{+filter{google}}
+/google/
+
+{+filter{google}}
+/google/
+
+{+filter{yahoo}}
+/yahoo/
+
+{+filter{msn}}
+/msn/
+
+{+filter{blogspot}}
+/blogspot/
+
+{+filter{sourceforge}}
+/sourceforge/
diff --git a/tests/cts/content-filters/data/test1 b/tests/cts/content-filters/data/test1
new file mode 100644 (file)
index 0000000..e971307
--- /dev/null
@@ -0,0 +1,229 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter js-annoyances
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: close
+Content-Type: text/html
+X-Control: swsclose
+
+# Here are some strings the js-annoyances filter should modify:
+
+# pcrs command 1:
+
+blafasel.referrer
+
+# pcrs command 2:
+
+bla bla bla this.defaultstatus = "hoho" x y z
+bla bla bla window.status = "whatever" x y z
+
+# pcrs command 3:
+
+this.status = blafasel;
+window.defaultstatus= dieda;
+
+# pcrs command 4:
+
+<body onunload="box('query').focus();">
+
+# pcrs command 5:
+
+<script
+     window.onunload="do.something()"
+</script>
+
+# pcrs command 6:
+
+open (blafasel resizable="no");
+open(blafasel resizable='0');
+
+# pcrs command 7:
+
+open(blafasel location="no")
+open(blafasel location='0')
+
+# pcrs command 8:
+
+open(blafasel status="no")
+open(blafasel   status='0')
+
+# pcrs command 9:
+
+open(blafasel scrolling="no")
+open(blafasel   scrollbars='0')
+
+# pcrs command 10:
+
+open(blafasel menubar="no")
+open(blafasel   menubar='0')
+
+# pcrs command 11:
+
+open(blafasel toolbar="no")
+open(blafasel   toolbar='0')
+
+# pcrs command 12:
+
+open(blafasel directories="no")
+open(blafasel   directories='0')
+
+# pcrs command 13:
+
+open(blafasel fullscreen="no")
+open(blafasel   fullscreen='0')
+
+# pcrs command 14:
+
+open(blafasel alwaysraised="yes")
+open(blafasel alwayslowered='yes')
+
+# pcrs command 15:
+
+open(blafasel z-lock="yes")
+open(blafasel zlock='yes')
+
+# pcrs command 16:
+
+open(blafasel hotkeys="yes")
+open(blafasel   hotkeys='1')
+
+# pcrs command 17:
+
+open(blafasel titlebar="no")
+open(blafasel   titlebar='0')
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: close
+Content-Type: text/html
+X-Control: swsclose
+Content-Length: 1503
+
+# Here are some strings the js-annoyances filter should modify:
+
+# pcrs command 1:
+
+false.toString()
+
+# pcrs command 2:
+
+bla bla bla this.defaultstatus = (typeof(this.href) != 'undefined')?("hoho" + ' URL: ' + this.href):(this.defaultstatus) x y z
+bla bla bla window.status = (typeof(this.href) != 'undefined')?("whatever" + ' URL: ' + this.href):(window.status) x y z
+
+# pcrs command 3:
+
+
+
+
+# pcrs command 4:
+
+<body never="box('query').focus();">
+
+# pcrs command 5:
+
+<script
+     never="do.something()"
+</script>
+
+# pcrs command 6:
+
+open (blafasel resizable="yes");
+open(blafasel resizable='yes');
+
+# pcrs command 7:
+
+open(blafasel location="yes")
+open(blafasel location='yes')
+
+# pcrs command 8:
+
+open(blafasel status="yes")
+open(blafasel   status='yes')
+
+# pcrs command 9:
+
+open(blafasel scrolling="auto")
+open(blafasel   scrollbars='auto')
+
+# pcrs command 10:
+
+open(blafasel menubar="yes")
+open(blafasel   menubar='yes')
+
+# pcrs command 11:
+
+open(blafasel toolbar="yes")
+open(blafasel   toolbar='yes')
+
+# pcrs command 12:
+
+open(blafasel directories="yes")
+open(blafasel   directories='yes')
+
+# pcrs command 13:
+
+open(blafasel fullscreen="no")
+open(blafasel   fullscreen='0')
+
+# pcrs command 14:
+
+open(blafasel alwaysraised="no")
+open(blafasel alwayslowered='no')
+
+# pcrs command 15:
+
+open(blafasel z-lock="no")
+open(blafasel zlock='no')
+
+# pcrs command 16:
+
+open(blafasel hotkeys="no")
+open(blafasel   hotkeys='no')
+
+# pcrs command 17:
+
+open(blafasel titlebar="yes")
+open(blafasel   titlebar='yes')
+</data>
+</proxy-reply>
+
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{js-annoyances}
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/js-annoyances/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /js-annoyances/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test10 b/tests/cts/content-filters/data/test10
new file mode 100644 (file)
index 0000000..e5c3564
--- /dev/null
@@ -0,0 +1,108 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter banners-by-link
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# Here is some HTML that the banners-by-link filter should modify:
+
+# pcrs command 1:
+
+<a href="http://www.example.org/adclick/blafasel"><img src="https://www.example.org/img-link-target" width="123" height="345">
+<a href="http://www.example.org/advert/blafasel"><img src="https://www.example.org/img-link-target" width="123" height="345">
+<a href="http://atwola.com/link"><img src="https://www.example.org/img-link-target" width="123" height="345">
+<a href="http://atwola.com/redir"><img src="https://www.example.org/img-link-target" width="123" height="345">
+<a href="http://doubleclick.net/jump/"><img src="https://www.example.org/img-link-target" width="123" height="345">
+<a href="http://www.example.org/blafasel/counter"><img src="https://www.example.org/img-link-target" width="123" height="345">
+<a href="http://www.example.org/blafasel/tracker"><img src="https://www.example.org/img-link-target" width="123" height="345">
+<a href="http://www.example.org/blafasel/keep-me&type=tracker"><img src="https://www.example.org/img-link-target" width="123" height="345">
+<a href="http://adlog.pl"><img src="https://www.example.org/img-link-target" width="123" height="345">
+
+# pcrs command 2:
+
+<a href="http://www.example.org/adclick/blafasel"><img src="https://www.example.org/img-link-target">
+<a href="http://www.example.org/advert/blafasel"><img src="https://www.example.org/img-link-target">
+<a href="http://atwola.com/link"><img src="https://www.example.org/img-link-target">
+<a href="http://atwola.com/redir"><img src="https://www.example.org/img-link-target">
+<a href="http://doubleclick.net/jump/"><img src="https://www.example.org/img-link-target">
+<a href="http://www.example.org/blafasel/counter"><img src="https://www.example.org/img-link-target">
+<a href="http://www.example.org/blafasel/tracker"><img src="https://www.example.org/img-link-target">
+<a href="http://www.example.org/blafasel/keep-me&type=tracker"><img src="https://www.example.org/img-link-target">
+<a href="http://adlog.pl"><img src="https://www.example.org/img-link-target">
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 3256\r
+\r
+# Here is some HTML that the banners-by-link filter should modify:
+
+# pcrs command 1:
+
+<img width="123" height="345" src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed https://www.example.org/img-link-target by link to http://www.example.org/adclick/blafasel">
+<img width="123" height="345" src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed https://www.example.org/img-link-target by link to http://www.example.org/advert/blafasel">
+<img width="123" height="345" src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed https://www.example.org/img-link-target by link to http://atwola.com/link">
+<img width="123" height="345" src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed https://www.example.org/img-link-target by link to http://atwola.com/redir">
+<img width="123" height="345" src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed https://www.example.org/img-link-target by link to http://doubleclick.net/jump/">
+<img width="123" height="345" src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed https://www.example.org/img-link-target by link to http://www.example.org/blafasel/counter">
+<img width="123" height="345" src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed https://www.example.org/img-link-target by link to http://www.example.org/blafasel/tracker">
+<a href="http://www.example.org/blafasel/keep-me&type=tracker"><img src="https://www.example.org/img-link-target" width="123" height="345">
+<img width="123" height="345" src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed https://www.example.org/img-link-target by link to http://adlog.pl">
+
+# pcrs command 2:
+
+<img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed https://www.example.org/img-link-target by link to http://www.example.org/adclick/blafasel">
+<img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed https://www.example.org/img-link-target by link to http://www.example.org/advert/blafasel">
+<img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed https://www.example.org/img-link-target by link to http://atwola.com/link">
+<img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed https://www.example.org/img-link-target by link to http://atwola.com/redir">
+<img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed https://www.example.org/img-link-target by link to http://doubleclick.net/jump/">
+<img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed https://www.example.org/img-link-target by link to http://www.example.org/blafasel/counter">
+<img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed https://www.example.org/img-link-target by link to http://www.example.org/blafasel/tracker">
+<a href="http://www.example.org/blafasel/keep-me&type=tracker"><img src="https://www.example.org/img-link-target">
+<img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed https://www.example.org/img-link-target by link to http://adlog.pl">
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{banners-by-link}
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/banners-by-link/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /banners-by-link/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test11 b/tests/cts/content-filters/data/test11
new file mode 100644 (file)
index 0000000..277ea88
--- /dev/null
@@ -0,0 +1,102 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter webbugs
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# Here is some HTML that the webbugs filter should squash:
+
+<img width="0" height="0" src="http://www.example.org/tracker.cgi">
+<img width='0' height='0' src="http://www.example.org/tracker.cgi">
+<img height="0" width="0" src="http://www.example.org/tracker.cgi">
+<img height='0' width='0'  src="http://www.example.org/tracker.cgi">
+
+<img width="0" height="1" src="http://www.example.org/tracker.cgi">
+<img width='0' height='1' src="http://www.example.org/tracker.cgi">
+<img height="0" width="1" src="http://www.example.org/tracker.cgi">
+<img height='0' width='1'  src="http://www.example.org/tracker.cgi">
+
+<img width="1" height="0" src="http://www.example.org/tracker.cgi">
+<img width='1' height='0' src="http://www.example.org/tracker.cgi">
+<img height="1" width="0" src="http://www.example.org/tracker.cgi">
+<img height='1' width='0'  src="http://www.example.org/tracker.cgi">
+
+<img width="1" height="1" src="http://www.example.org/tracker.cgi">
+<img width='1' height='1' src="http://www.example.org/tracker.cgi">
+<img height="1" width="1" src="http://www.example.org/tracker.cgi">
+<img height='1' width='1'  src="http://www.example.org/tracker.cgi">
+
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 80\r
+\r
+# Here is some HTML that the webbugs filter should squash:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{webbugs}
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/webbugs/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /webbugs/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test12 b/tests/cts/content-filters/data/test12
new file mode 100644 (file)
index 0000000..a7a7fd6
--- /dev/null
@@ -0,0 +1,92 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter tiny-textforms
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# Here are some tiny textforms the tiny-textforms filter should filter:
+
+# pcrs command 1:
+
+<textarea rows="10" cols="10">
+<textarea cols="10" rows="10">
+<textarea rows='5' cols="5">
+<textarea cols='7' rows='7'>
+
+<!-- The filter actual makes large forms tynier ... -->
+<textarea rows="100" cols="100">
+<textarea cols="1000" rows="1000">
+
+# pcrs command 2:
+
+<textarea wrap="hard">
+<textarea wrap='hard'>
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 379\r
+\r
+# Here are some tiny textforms the tiny-textforms filter should filter:
+
+# pcrs command 1:
+
+<textarea rows="40" cols="80">
+<textarea rows="40" cols="80">
+<textarea rows="40" cols="80">
+<textarea rows='40' cols='80'>
+
+<!-- The filter actual makes large forms tynier ... -->
+<textarea rows="40" cols="80">
+<textarea rows="40" cols="80">
+
+# pcrs command 2:
+
+<textarea >
+<textarea >
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{tiny-textforms}
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/tiny-textforms/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /tiny-textforms/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test13 b/tests/cts/content-filters/data/test13
new file mode 100644 (file)
index 0000000..3f4c027
--- /dev/null
@@ -0,0 +1,84 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter jumping-windows
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# Here are some strings the jumping-windows filter should filter:
+
++window.moveto(
++this.moveto(
++self.moveto(
+
++window.moveby(
++this.moveby(
++self.moveby(
+
++window.resizeto(
++this.resizeto(
++self.resizeto(
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 177\r
+\r
+# Here are some strings the jumping-windows filter should filter:
+
++''.concat(
++''.concat(
++''.concat(
+
++''.concat(
++''.concat(
++''.concat(
+
++''.concat(
++''.concat(
++''.concat(
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{jumping-windows}
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/jumping-windows/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /jumping-windows/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test14 b/tests/cts/content-filters/data/test14
new file mode 100644 (file)
index 0000000..18563bf
--- /dev/null
@@ -0,0 +1,118 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter frameset-borders
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# Here are some strings the frameset-borders filter should filter:
+
+# pcrs command 1:
+
+<frameset framespacing="no"
+<frameset framespacing='0'
+
+# pcrs command 2:
+
+<frameset frameborder="no"
+<frameset frameborder='0'
+
+# pcrs command 3:
+
+<frameset border="no"
+<frameset border='0'
+
+# pcrs command 4:
+
+<frameset noresize
+
+# pcrs command 5:
+
+<frame frameborder="no"
+<frame frameborder='0'
+
+# pcrs command 6:
+
+<frame scrolling="no"
+<frame scrolling='0'
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 309\r
+\r
+# Here are some strings the frameset-borders filter should filter:
+
+# pcrs command 1:
+
+<frameset 
+<frameset 
+
+# pcrs command 2:
+
+<frameset 
+<frameset 
+
+# pcrs command 3:
+
+<frameset 
+<frameset 
+
+# pcrs command 4:
+
+<frameset noresize
+
+# pcrs command 5:
+
+<frame 
+<frame frame
+
+# pcrs command 6:
+
+<frame 
+<frame 
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{frameset-borders}
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/frameset-borders/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /frameset-borders/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test15 b/tests/cts/content-filters/data/test15
new file mode 100644 (file)
index 0000000..6043a3e
--- /dev/null
@@ -0,0 +1,80 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter iframes
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# Here are some iframes the iframes filter should filter:
+
+<iframe src="https://www.example.org/ads" title="Some ads for you"></iframe>
+
+<iframe
+   src="https://www.example.org/ads"
+        title="Some ads for you"></iframe>
+
+<iframe src="https://www.example.org/ads">
+</iframe>
+
+<iframe src="https://www.example.org/ads">
+</iframe>
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 266\r
+\r
+# Here are some iframes the iframes filter should filter:
+
+<!-- iframe removed by Privoxy's iframe filter -->
+
+<!-- iframe removed by Privoxy's iframe filter -->
+
+<!-- iframe removed by Privoxy's iframe filter -->
+
+<!-- iframe removed by Privoxy's iframe filter -->
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{iframes}
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/iframes/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /iframes/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test16 b/tests/cts/content-filters/data/test16
new file mode 100644 (file)
index 0000000..251a31b
--- /dev/null
@@ -0,0 +1,216 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter demoronizer
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# Here are some supposedly moronic byte sequences the demoronizer filter should filter:
+
+# pcrs command 1:
+
+&#012 
+&#123 
+&#255 
+
+# pcrs command 2:
+
+%hex[ %E2%80%94 ]hex%
+
+# pcrs command 3:
+
+%hex[ %82 ]hex%
+
+# pcrs command 4 (commented out, no change expected):
+
+%hex[ %83 ]hex%
+
+# pcrs command 5:
+
+%hex[ %84 ]hex%
+
+# pcrs command 6:
+
+%hex[ %85 ]hex%
+
+# pcrs command 7 (commented out, no change expected):
+
+%hex[ %88 ]hex%
+
+# pcrs command 8 (commented out, no change expected):
+
+%hex[ %89 ]hex%
+
+# pcrs command 9:
+
+%hex[ %8B ]hex%
+
+# pcrs command 10:
+
+%hex[ %8C ]hex%
+
+# pcrs command 11:
+
+%hex[ %91 ]hex%
+
+# pcrs command 12:
+
+%hex[ %92 ]hex%
+
+# pcrs command 13:
+
+%hex[ %92%94 ]hex%
+
+# pcrs command 14:
+
+%hex[ %95 ]hex%
+
+# pcrs command 15:
+
+%hex[ %96 ]hex%
+
+# pcrs command 16:
+
+%hex[ %97 ]hex%
+
+# pcrs command 17 (commented out, no change expected):
+
+%hex[ %98 ]hex%
+
+# pcrs command 18 (commented out, no change expected):
+
+%hex[ %99 ]hex%
+
+# pcrs command 19
+
+%hex[ %9B ]hex%/>
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 771\r
+\r
+# Here are some supposedly moronic byte sequences the demoronizer filter should filter:
+
+# pcrs command 1:
+
+&#012; 
+&#123; 
+&#255; 
+
+# pcrs command 2:
+
+  --  
+
+# pcrs command 3:
+
+ , 
+
+# pcrs command 4 (commented out, no change expected):
+
+%hex[ %83 ]hex%
+
+# pcrs command 5:
+
+ ,, 
+
+# pcrs command 6:
+
+ ... 
+
+# pcrs command 7 (commented out, no change expected):
+
+%hex[ %88 ]hex%
+
+# pcrs command 8 (commented out, no change expected):
+
+%hex[ %89 ]hex%
+
+# pcrs command 9:
+
+ < 
+
+# pcrs command 10:
+
+ Oe 
+
+# pcrs command 11:
+
+ ` 
+
+# pcrs command 12:
+
+ ' 
+
+# pcrs command 13:
+
+ '" 
+
+# pcrs command 14:
+
+ &middot; 
+
+# pcrs command 15:
+
+ - 
+
+# pcrs command 16:
+
+ -- 
+
+# pcrs command 17 (commented out, no change expected):
+
+%hex[ %98 ]hex%
+
+# pcrs command 18 (commented out, no change expected):
+
+%hex[ %99 ]hex%
+
+# pcrs command 19
+
+ > />
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{demoronizer}
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/demoronizer/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /demoronizer/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test17 b/tests/cts/content-filters/data/test17
new file mode 100644 (file)
index 0000000..da38889
--- /dev/null
@@ -0,0 +1,138 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter shockwave-flash
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# Here are some strings the shockwave-flash filter should filter:
+
+# pcrs command 1:
+
+<object blafasel macromedia tralala>bla bla bla</object>
+
+<object
+blafasel
+macromedia
+tralala
+>bla bla bla</object>
+
+<Object
+        blafasel
+                macromedia
+                        tralala
+                                >       bla     bla     bla
+</Object>
+
+# pcrs command 2:
+
+<embed blafasel application/x-shockwave-flash bumfidel>xyz</embed>
+
+<embed blafasel
+application/x-shockwave-flash
+bumfidel>xyz</embed>
+
+<embed blafasel
+       application/x-shockwave-flash
+       bumfidel>
+
+<embed blafasel src="https://example.org/flash-me.swf">
+
+XXX: The following strings don't get filter but probably should be:
+
+<embed
+blafasel
+        src="https://example.org/flash-me.swf">
+
+<EMBED
+blafasel
+        src="https://example.org/flash-me.swf">
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 739\r
+\r
+# Here are some strings the shockwave-flash filter should filter:
+
+# pcrs command 1:
+
+<!-- Squished Shockwave Object -->
+
+<object
+blafasel
+macromedia
+tralala
+>bla bla bla</object>
+
+<Object
+        blafasel
+                macromedia
+                        tralala
+                                >       bla     bla     bla
+</Object>
+
+# pcrs command 2:
+
+<!-- Squished Shockwave Flash Embed -->xyz</embed>
+
+<!-- Squished Shockwave Flash Embed -->xyz</embed>
+
+<!-- Squished Shockwave Flash Embed -->
+
+<!-- Squished Shockwave Flash Embed -->
+
+XXX: The following strings don't get filter but probably should be:
+
+<embed
+blafasel
+        src="https://example.org/flash-me.swf">
+
+<EMBED
+blafasel
+        src="https://example.org/flash-me.swf">
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{shockwave-flash}
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/shockwave-flash/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /shockwave-flash/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test18 b/tests/cts/content-filters/data/test18
new file mode 100644 (file)
index 0000000..9d57c16
--- /dev/null
@@ -0,0 +1,76 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter quicktime-kioskmode
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# Here are some strings the quicktime-kioskmode filter should filter:
+
+s/(<embed\s+[^>]*)kioskmode\s*=\s*(["']?)true\2/$1/ig
+
+<embed blafasel kioskmode="true">
+
+<embed blafasel kioskmode='true'>
+
+<embed blafasel kioskmode='true' tralala>
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 190\r
+\r
+# Here are some strings the quicktime-kioskmode filter should filter:
+
+s/(<embed\s+[^>]*)kioskmode\s*=\s*(["']?)true\2/$1/ig
+
+<embed blafasel >
+
+<embed blafasel >
+
+<embed blafasel  tralala>
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{quicktime-kioskmode}
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/quicktime-kioskmode/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /quicktime-kioskmode/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test19 b/tests/cts/content-filters/data/test19
new file mode 100644 (file)
index 0000000..623c505
--- /dev/null
@@ -0,0 +1,116 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter fun
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# Here are some strings the fun filter should filter:
+
+# pcrs command 1:
+
+Microsoft
+
+# pcrs command 1 should not break URLs:
+
+https://www.microsoft.com/
+
+# pcrs command 2:
+
+Our great product is
+    industry leading
+             world-leading
+                        cutting edge
+                                customer-focused
+                                        market driven
+                                               award winning
+                                                     high performance
+                                                          solutions-based
+                                                                unmatched
+                                                                        unparalleled
+                                                                                and unrivalled.
+
+# pcrs command 3:
+
+Medieninformatik
+        medien
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 1456\r
+\r
+# Here are some strings the fun filter should filter:
+
+# pcrs command 1:
+
+MicroSuck
+
+# pcrs command 1 should not break URLs:
+
+https://www.microsoft.com/
+
+# pcrs command 2:
+
+Our great product is
+    industry leading<sup><font color="red"><b>Bingo!</b></font></sup> 
+             world-leading<sup><font color="red"><b>Bingo!</b></font></sup> 
+                        cutting edge<sup><font color="red"><b>Bingo!</b></font></sup> 
+                                customer-focused<sup><font color="red"><b>Bingo!</b></font></sup> 
+                                        market driven<sup><font color="red"><b>Bingo!</b></font></sup> 
+                                               award winning<sup><font color="red"><b>Bingo!</b></font></sup> 
+                                                     high performance<sup><font color="red"><b>Bingo!</b></font></sup> 
+                                                          solutions-based<sup><font color="red"><b>Bingo!</b></font></sup> 
+                                                                unmatched<sup><font color="red"><b>Bingo!</b></font></sup> 
+                                                                        unparalleled<sup><font color="red"><b>Bingo!</b></font></sup> 
+                                                                                and unrivalled<sup><font color="red"><b>Bingo!</b></font></sup> .
+
+# pcrs command 3:
+
+M&auml;dcheninformatik
+        m&auml;dchen
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{fun}
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/fun/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /fun/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test2 b/tests/cts/content-filters/data/test2
new file mode 100644 (file)
index 0000000..30be85f
--- /dev/null
@@ -0,0 +1,129 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter js-annoyances
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: close
+Content-Type: text/html
+X-Control: swsclose
+
+# Here are some strings the js-events filter should modify:
+
+# pcrs command 1:
+
+onmouseover
+onmouseout
+onmousedown
+onmouseup
+onmousemove
+
+event.mouseover
+event.mouseout
+event.mousedown
+event.mouseup
+event.mousemove
+
+onload
+onunload
+oncontextmenu
+onselectstart
+
+event.load
+event.unload
+event.contextmenu
+event.selectstart
+
+# pcrs command 2:
+
+alert (
+confirm (
+
+# pcrs command 3:
+
+settimeout(
+setinterval(
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: close
+Content-Type: text/html
+X-Control: swsclose
+Content-Length: 263
+
+# Here are some strings the js-events filter should modify:
+
+# pcrs command 1:
+
+never
+never
+never
+never
+never
+
+never
+never
+never
+never
+never
+
+never
+never
+never
+never
+
+never
+never
+never
+never
+
+# pcrs command 2:
+
+concat(
+concat(
+
+# pcrs command 3:
+
+concat(
+concat(
+</data>
+</proxy-reply>
+
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{js-events}
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/js-events/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /js-events/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test200 b/tests/cts/content-filters/data/test200
new file mode 100644 (file)
index 0000000..39792a1
--- /dev/null
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter crude-parental
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# This is a site which contains the word sex which should trigger the crude-parental filter:
+
+Here it comes again: SEX!!!!
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 170\r
+\r
+<html><head><title>Blocked</title></head><body><h3>Blocked by <a href="http://p.p/">Privoxy's</a> crude-parental filter due to possible adult content.</h3></body></html>
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{crude-parental} with page containing "sex"
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/crude-parental/pornsite-1/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /crude-parental/pornsite-1/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test201 b/tests/cts/content-filters/data/test201
new file mode 100644 (file)
index 0000000..063817f
--- /dev/null
@@ -0,0 +1,65 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter crude-parental
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# This is a fairly inoffensive info page which does
+# not get blocked by the crude-parental filter:
+
+Middlesex, Sussex and Essex are counties in the UK.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# This is a fairly inoffensive info page which does
+# not get blocked by the crude-parental filter:
+
+Middlesex, Sussex and Essex are counties in the UK.
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{crude-parental} with page containing Middlesex, Sussex and Essex
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/crude-parental/harmless-info-page/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /crude-parental/harmless-info-page/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test202 b/tests/cts/content-filters/data/test202
new file mode 100644 (file)
index 0000000..28dd503
--- /dev/null
@@ -0,0 +1,61 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter crude-parental
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# This is a fake porn side the crude-parental filter should filter:
+Come and see wet cunts waiting to get licked!!!!
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 122\r
+\r
+This page has been blocked by <a href="http://p.p/">Privoxy's</a> crude-parental content filter based on the description.
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{crude-parental} pcrs command 3 with porn description A
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/crude-parental/p0rnpage/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /crude-parental/p0rnpage/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test203 b/tests/cts/content-filters/data/test203
new file mode 100644 (file)
index 0000000..f9c12e0
--- /dev/null
@@ -0,0 +1,61 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter crude-parental
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# This is a fake porn side the crude-parental filter should filter:
+You can rub my balls here!!!
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 122\r
+\r
+This page has been blocked by <a href="http://p.p/">Privoxy's</a> crude-parental content filter based on the description.
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{crude-parental} pcrs command 3 with porn description B
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/crude-parental/porn-description-b/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /crude-parental/porn-description-b/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test204 b/tests/cts/content-filters/data/test204
new file mode 100644 (file)
index 0000000..e93f79a
--- /dev/null
@@ -0,0 +1,61 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter crude-parental
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# This is a fake porn side the crude-parental filter should filter:
+Suck her dick here!!!
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 122\r
+\r
+This page has been blocked by <a href="http://p.p/">Privoxy's</a> crude-parental content filter based on the description.
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{crude-parental} pcrs command 3 with porn description C
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/crude-parental/porn-description-c/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /crude-parental/porn-description-c/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test21 b/tests/cts/content-filters/data/test21
new file mode 100644 (file)
index 0000000..29bc79e
--- /dev/null
@@ -0,0 +1,60 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter crude-parental
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+Here are some Warez. Download them now!
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 120\r
+\r
+<html><head><title>No Warez</title></head><body><h3>You're not searching for illegal stuff, are you?</h3></body></html>
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{crude-parental} with warez page
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/crude-parental/warez-page-1/%TESTNUMBER 
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /crude-parental/warez-page-1/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test22 b/tests/cts/content-filters/data/test22
new file mode 100644 (file)
index 0000000..34dbf1f
--- /dev/null
@@ -0,0 +1,88 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter yahoo
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# Here are some strings the yahoo filter should filter:
+
+# pcrs command 1:
+
+</head>
+
+# pcrs command 2:
+
+<textarea id="composeArea" blafasel width:545px;
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 904\r
+\r
+# Here are some strings the yahoo filter should filter:
+
+# pcrs command 1:
+
+
+<style type="text/css">
+ /* Style sheet inserted by Privoxy's yahoo filter. */
+ #symadbn, #ymadbn, .yschbox, .yschhd, .bbox, #yschsec, #sec, #yschanswr, .yschftad, .yschspn, .yschspns, #ygrp-sponsored-links, #nwad, #MWA2, #MSCM, #yregad, #sponsored-links, #ks-ypn-ads, .ad, #east, #ygrp-vital, .ads {display: none !important;}
+ #yschpri, #yschweb, #pri, #web, #main, .yschttl, .abstr, .res 
+ {width: 99% !important; max-width: 100% !important;}
+ .yschttl, .res, .res.indent, #web {padding: 0px; margin: 0px !important;}
+ #web {padding-left: 0.5em}
+ #yschqcon, #yschtg {width: auto !important; /* No useless horizontal scrollbar please */}
+ #composebox #compose_editorArea {width: 70% !important; /* reasonably sized reply textarea please */
+ </style>
+</head>
+
+
+# pcrs command 2:
+
+<textarea id="composeArea" blafasel width:70%;
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{yahoo}
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/yahoo/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /yahoo/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test23 b/tests/cts/content-filters/data/test23
new file mode 100644 (file)
index 0000000..175a64e
--- /dev/null
@@ -0,0 +1,124 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter msn
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# Here are some strings the msn filter should filter:
+
+# pcrs command 1:
+
+</head>
+
+# pcrs command 2:
+
+<div id="ads_blafasel">
+<div id='ads_foo'>
+
+# pcrs command 3:
+
+<div blafasel class="sb_ads_blafasel">
+<div blafasel class='sb_ads_foo'>
+
+# pcrs command 4:
+
+<a href="http://g.msn.com/blafasel\?http://www.example.org/&amp;&amp;DI=tralala"
+
+# pcrs command 5:
+
+<a href="http://www.example.org" gping="http://www.example/ping.cgi"
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 1488\r
+\r
+# Here are some strings the msn filter should filter:
+
+# pcrs command 1:
+
+<style type="text/css">
+ /* Style sheet inserted by Privoxy's msn filter. */
+ .msn_ads, #at, #ar, .mktmsg {display: none !important;}
+ #results, #b_results, .flank, .results_area_flank, .results_area_stroke,
+ #results_area, #content, .sb_tlst, .sa_cc, .sb_ph, #sw_main,
+ .content, .b_content, #sw_foot, #bf, #sw_content, #sidebar, #pag
+ {width: 99% !important; min-width: 99% !important;
+ max-width: 100% !important; /* width:100% sometimes causes horizontal scrollbars */}
+ /* Remove 'related' ads */
+ .b_ad, .b_adlabel {clear: both; display:none;}
+ /* Remove "suggestions". They are next to worthless but partly overlap with the search results */
+ .suggestion, #nys_right, #nys {clear: both; display:none;}
+ /* Remove "Related searches" at the left side of the main results.
+    They are next to worthless, too, and also are still present below the main search results */
+ #b_results > .b_ans {clear: both; display:none;}
+ #s_notf_div,
+  /* Overlay ads to enable Facebook 'likes' in search results. */
+ .sn_container {display:none !important;}
+ #content, #b_content {padding: 0px 0px 0px 0px}
+ </style>
+</head>
+
+# pcrs command 2:
+
+<div class="msn_ads">
+<div class="msn_ads">
+
+# pcrs command 3:
+
+<div blafasel class="msn_ads">
+<div blafasel class="msn_ads">
+
+# pcrs command 4:
+
+<a href="http://www.example.org/"
+
+# pcrs command 5:
+
+<a href="http://www.example.org"  title="URL cleaned up by Privoxy's msn filter"
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{msn}
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/msn/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /msn/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test24 b/tests/cts/content-filters/data/test24
new file mode 100644 (file)
index 0000000..34bcb33
--- /dev/null
@@ -0,0 +1,132 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter blogspot
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# Here are some strings the blogspot filter should filter:
+
+# pcrs command 1:
+
+</head>
+
+# pcrs command 2:
+
+<body blafasel>
+   <div id="space-for-ie"></div>
+
+# pcrs command 2 does not filter these because it only hits once:
+
+   <div id="content"
+   <div id="wrap4"
+   <div id="wrapper"
+
+# pcrs command 3:
+
+<div style="blafasel width:30em
+
+# pcrs command 4:
+
+background:url("http://www.blogblog.com/roundersblafasel") tralala;
+
+# pcrs command 5:
+
+background:#abc url("http://www.blogblog.com/roundersblafasel") tralala;@
+
+# pcrs command 6:
+
+XXX: TODO
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 946\r
+\r
+# Here are some strings the blogspot filter should filter:
+
+# pcrs command 1:
+
+<style type="text/css">
+ /* Style sheet inserted by Privoxy's blogspot filter. */
+ #powered-by {display: none !important;}
+ #wrap4, #wrapper {margin-top: 0px }
+ #blogheader, #header {margin-top: 0.5em !important}
+ #content {width: 98% }
+ #main {width: 70% }
+ #sidebar {width: 29% }
+ .post-body {overflow: auto;}
+ .blogComments {width: 100%; overflow: auto;}
+</style>
+</head>
+
+# pcrs command 2:
+
+<body> <!-- Privoxy's blogspot filter ditched some garbage here -->
+
+# pcrs command 2 does not filter these because it only hits once:
+
+   <div id="content"
+   <div id="wrap4"
+   <div id="wrapper"
+
+# pcrs command 3:
+
+<div style="blafasel width: 100%
+
+# pcrs command 4:
+
+/*background:url("http://www.blogblog.com/roundersblafasel") tralala;*/
+
+# pcrs command 5:
+
+background:#abc ;/* url("http://www.blogblog.com/roundersblafasel") tralala;*/@
+
+# pcrs command 6:
+
+XXX: TODO
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{blogspot} XXX: incomplete test coverage
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/blogspot/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /blogspot/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test25 b/tests/cts/content-filters/data/test25
new file mode 100644 (file)
index 0000000..fbd51cf
--- /dev/null
@@ -0,0 +1,100 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter sourceforge
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# Here are some strings the sourceforge filter should filter:
+
+# pcrs command 1:
+
+<div id="banner-sterling" blafasel
+
+# pcrs command 2:
+
+<section id="nels" blafasel
+
+# pcrs command 3:
+
+<aside class="m-wide-widget m-wide-projects-widget " blafasel
+
+# pcrs command 4:
+
+<div id="newsletter-floating" blafasel
+
+# pcrs command 5:
+
+<div class="sterling" id="banner-sterling" blafasel
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 488\r
+\r
+# Here are some strings the sourceforge filter should filter:
+
+# pcrs command 1:
+
+<div id="banner-sterling" style="display:none;" blafasel
+
+# pcrs command 2:
+
+<section id="nels" style="display:none;" blafasel
+
+# pcrs command 3:
+
+<aside class="m-wide-widget m-wide-projects-widget " style="display:none;" blafasel
+
+# pcrs command 4:
+
+<div id="newsletter-floating" style="display:none;" blafasel
+
+# pcrs command 5:
+
+<div class="sterling" id="banner-sterling" style="display:none;" blafasel
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{sourceforge}
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/sourceforge/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /sourceforge/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test3 b/tests/cts/content-filters/data/test3
new file mode 100644 (file)
index 0000000..a40485c
--- /dev/null
@@ -0,0 +1,121 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter js-annoyances
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# Here are some strings the html-annoyances filter should modify:
+
+# pcrs command 1:
+
+<a href="http://www.example.org/" resizable="no">click here!</a>
+<a href="http://www.example.org/" resizable='0'>click here!</a>
+
+# pcrs command 2:
+
+<a href="http://www.example.org/" location="no">click here!</a>
+<a href="http://www.example.org/" location='0'>click here!</a>
+
+# pcrs command 3:
+
+<a href="http://www.example.org/" status="no">click here!</a>
+<a href="http://www.example.org/" status='0'>click here!</a>
+
+# pcrs command 4:
+
+<a href="http://www.example.org/" scrolling="no">click here!</a>
+<a href="http://www.example.org/" scrolling='0'>click here!</a>
+
+# pcrs command 5:
+
+<a href="http://www.example.org/" menubar="no">click here!</a>
+<a href="http://www.example.org/" menubar='0'>click here!</a>
+
+# pcrs command 6:
+
+<blink>Blink! Blink! Blink!</blink>
+<marquee>Annoying marquee text!</marquee>
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 880\r
+\r
+# Here are some strings the html-annoyances filter should modify:
+
+# pcrs command 1:
+
+<a href="http://www.example.org/" resizable="yes">click here!</a>
+<a href="http://www.example.org/" resizable='yes'>click here!</a>
+
+# pcrs command 2:
+
+<a href="http://www.example.org/" location="yes">click here!</a>
+<a href="http://www.example.org/" location='yes'>click here!</a>
+
+# pcrs command 3:
+
+<a href="http://www.example.org/" status="yes">click here!</a>
+<a href="http://www.example.org/" status='yes'>click here!</a>
+
+# pcrs command 4:
+
+<a href="http://www.example.org/" scrolling="auto">click here!</a>
+<a href="http://www.example.org/" scrolling='auto'>click here!</a>
+
+# pcrs command 5:
+
+<a href="http://www.example.org/" menubar="yes">click here!</a>
+<a href="http://www.example.org/" menubar='yes'>click here!</a>
+
+# pcrs command 6:
+
+Blink! Blink! Blink!
+Annoying marquee text!
+</data>
+</proxy-reply>
+
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{html-annoyances}
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/html-annoyances/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /html-annoyances/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test300 b/tests/cts/content-filters/data/test300
new file mode 100644 (file)
index 0000000..76ebe2d
--- /dev/null
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter crude-parental
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# This is a fake "porn" page that triggers pcrs command 4 of the crude-parental filter:
+
+Download hot asian movies!
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 116\r
+\r
+This page has been blocked by <a href="http://p.p/">Privoxy's</a> crude-parental content filter based on link text.
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{crude-parental} with "offensive" "link text" A
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/crude-parental/link-text-a/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /crude-parental/link-text-a/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test301 b/tests/cts/content-filters/data/test301
new file mode 100644 (file)
index 0000000..0468052
--- /dev/null
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter crude-parental
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# This is a fake "porn" page that triggers pcrs command 4 of the crude-parental filter:
+
+View cumshot movies now!
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 116\r
+\r
+This page has been blocked by <a href="http://p.p/">Privoxy's</a> crude-parental content filter based on link text.
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{crude-parental} with "offensive" "link text" B
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/crude-parental/link-text-b/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /crude-parental/link-text-b/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test302 b/tests/cts/content-filters/data/test302
new file mode 100644 (file)
index 0000000..913291c
--- /dev/null
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter crude-parental
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# This is a fake "porn" page that triggers pcrs command 4 of the crude-parental filter:
+
+Get fucking DVDs of naked ladies here!
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 116\r
+\r
+This page has been blocked by <a href="http://p.p/">Privoxy's</a> crude-parental content filter based on link text.
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{crude-parental} with "offensive" "link text" C
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/crude-parental/link-text-c/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /crude-parental/link-text-c/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test310 b/tests/cts/content-filters/data/test310
new file mode 100644 (file)
index 0000000..fdccb3a
--- /dev/null
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter crude-parental
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# This is a age disclaimer that triggers pcrs command 5 of the crude-parental filter:
+
+The models are over 16 years old!
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 126\r
+\r
+This page has been blocked by <a href="http://p.p/">Privoxy's</a> crude-parental content filter because of an age disclaimer.
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{crude-parental} with suspicious age disclaimer A
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/crude-parental/age-disclaimer-a/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /crude-parental/age-disclaimer-a/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test311 b/tests/cts/content-filters/data/test311
new file mode 100644 (file)
index 0000000..90fb507
--- /dev/null
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter crude-parental
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# This is a age disclaimer that triggers pcrs command 5 of the crude-parental filter:
+
+The chicks are at least 18 years of age or so we claim!
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 126\r
+\r
+This page has been blocked by <a href="http://p.p/">Privoxy's</a> crude-parental content filter because of an age disclaimer.
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{crude-parental} with suspicious age disclaimer B
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/crude-parental/age-disclaimer-b/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /crude-parental/age-disclaimer-b/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test312 b/tests/cts/content-filters/data/test312
new file mode 100644 (file)
index 0000000..e6fdd5a
--- /dev/null
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter crude-parental
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# This is a age disclaimer that triggers pcrs command 5 of the crude-parental filter:
+
+The persons were over 21 years old last we checked!
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 126\r
+\r
+This page has been blocked by <a href="http://p.p/">Privoxy's</a> crude-parental content filter because of an age disclaimer.
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{crude-parental} with suspicious age disclaimer C
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/crude-parental/age-disclaimer-c/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /crude-parental/age-disclaimer-c/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test320 b/tests/cts/content-filters/data/test320
new file mode 100644 (file)
index 0000000..5a2a9ad
--- /dev/null
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter crude-parental
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# This regulation text triggers pcrs command 6 of the crude-parental filter:
+
+We comply with section 2257 of whatever!
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 128\r
+\r
+This page has been blocked by <a href="http://p.p/">Privoxy's</a> crude-parental content filter because of an regulations text.
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{crude-parental} with suspicious regulation text A
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/crude-parental/regulation-text-a/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /crude-parental/regulation-text-a/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test321 b/tests/cts/content-filters/data/test321
new file mode 100644 (file)
index 0000000..7fe8089
--- /dev/null
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter crude-parental
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# This regulation text triggers pcrs command 6 of the crude-parental filter:
+
+We comply with code 18 U.S.C. 2257 of whatever!
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 128\r
+\r
+This page has been blocked by <a href="http://p.p/">Privoxy's</a> crude-parental content filter because of an regulations text.
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{crude-parental} with suspicious regulation text B
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/crude-parental/regulation-text-b/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /crude-parental/regulation-text-b/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test322 b/tests/cts/content-filters/data/test322
new file mode 100644 (file)
index 0000000..330e9c1
--- /dev/null
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter crude-parental
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# This regulation text triggers pcrs command 6 of the crude-parental filter:
+
+We comply with code 18 USC 2257 of whatever!
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 128\r
+\r
+This page has been blocked by <a href="http://p.p/">Privoxy's</a> crude-parental content filter because of an regulations text.
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{crude-parental} with suspicious regulation text C
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/crude-parental/regulation-text-c/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /crude-parental/regulation-text-c/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test33 b/tests/cts/content-filters/data/test33
new file mode 100644 (file)
index 0000000..f1dc0db
--- /dev/null
@@ -0,0 +1,99 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter ie-exploits
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# Here are some strings the ie-exploits filter should filter:
+
+# pcrs command 1:
+
+f("javascript:location.replace('mk:@MSITStore:C:')");
+
+# pcrs command 2:
+
+<a href="http://www.example.org/%hex[%01]hex%@blafasel">
+<a href="http://www.example.org/%hex[%02]hex%@blafasel">
+<a href="http://www.example.org/%hex[%03]hex%@blafasel">
+
+<a href="http://www.example.org/%00@blafasel">
+<a href="http://www.example.org/%01@blafasel">
+<a href="http://www.example.org/%02@blafasel">
+
+# pcrs command 3:
+
+<script language="JavaScript">window.open("readme.eml", null, "resizable=no,top=6000,left=6000")</script>
+<script language="JavaScript">1;''.concat("readme.eml", null, "resizable=no,top=6000,left=6000")</script>
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 890\r
+\r
+# Here are some strings the ie-exploits filter should filter:
+
+# pcrs command 1:
+
+alert("This page looks like it tries to use a vulnerability described here:
+ http://online.securityfocus.com/archive/1/298748/2002-11-02/2002-11-08/2");
+
+# pcrs command 2:
+
+<a href="http://www.example.org/MALICIOUS-LINK@blafasel">
+<a href="http://www.example.org/MALICIOUS-LINK@blafasel">
+<a href="http://www.example.org/MALICIOUS-LINK@blafasel">
+
+<a href="http://www.example.org/MALICIOUS-LINK@blafasel">
+<a href="http://www.example.org/MALICIOUS-LINK@blafasel">
+<a href="http://www.example.org/MALICIOUS-LINK@blafasel">
+
+# pcrs command 3:
+
+<br><font size="7"> WARNING: This Server is infected with <a href="http://www.cert.org/advisories/CA-2001-26.html">Nimda</a>!</font>
+<br><font size="7"> WARNING: This Server is infected with <a href="http://www.cert.org/advisories/CA-2001-26.html">Nimda</a>!</font>
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{ie-exploits}
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/ie-exploits/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /ie-exploits/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test34 b/tests/cts/content-filters/data/test34
new file mode 100644 (file)
index 0000000..0322698
--- /dev/null
@@ -0,0 +1,134 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter site-specifics
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# Here are some strings the site-specifics filter should filter:
+
+# pcrs command 1:
+
+indexOf("x11")
+
+# pcrs command 2 (XXX: should probably kill the parens as well):
+
+mylogfunc()
+
+# pcrs command 3:
+
+<a href="http://www.example.org/">Continue to message</a>
+<a href="http://www.example.org/">Weiter zu Nachricht</a>
+
+# pcrs command 4:
+
+<input type="hidden" name="REDIRECT" value="http://www.example.org/">
+
+# pcrs command 5:
+
+<IMG SRC="http://media.monster.com/mm/usen/my/no_thanks_211x40.gif" blafasel>
+
+# pcrs command 6:
+
+<img blafasel onload="alert('blafasel')"
+
+# pcrs command 7:
+
+<INPUT name="1234" type="RADIO" value="0" CHECKED 
+<INPUT name="123" type="RADIO" value="0" CHECKED 
+<INPUT name="12" type="RADIO" value="0" CHECKED 
+
+# pcrs command 8:
+
+<INPUT name="12" type="RADIO" value="3" 
+<INPUT name="123" type="RADIO" value="3" 
+<INPUT name="1233" type="RADIO" value="3" 
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 888\r
+\r
+# Here are some strings the site-specifics filter should filter:
+
+# pcrs command 1:
+
+indexOf("x13")
+
+# pcrs command 2 (XXX: should probably kill the parens as well):
+
+()
+
+# pcrs command 3:
+
+<meta http-equiv="refresh" content="0; URL=http://www.example.org/">
+<meta http-equiv="refresh" content="0; URL=http://www.example.org/">
+
+# pcrs command 4:
+
+<meta http-equiv="refresh" content="0; URL=http://www.example.org/">
+
+# pcrs command 5:
+
+<meta http-equiv="refresh" content="0; URL=http://my.monster.com/resume.asp">
+
+# pcrs command 6:
+
+<img blafasel never="alert('blafasel')"
+
+# pcrs command 7:
+
+<INPUT name="1234" type="RADIO" value="0"
+<INPUT name="123" type="RADIO" value="0"
+<INPUT name="12" type="RADIO" value="0"
+
+# pcrs command 8:
+
+<INPUT name="12" type="RADIO" value="3"  checked
+<INPUT name="123" type="RADIO" value="3"  checked
+<INPUT name="1233" type="RADIO" value="3"  checked
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{site-specifics}
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/site-specifics/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /site-specifics/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test35 b/tests/cts/content-filters/data/test35
new file mode 100644 (file)
index 0000000..e5c8326
--- /dev/null
@@ -0,0 +1,80 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter no-ping
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# Here are some strings the no-ping filter should filter:
+
+<a ping="http://www.example.org/ping-target" href="http://www.example.org/link-target">click here</a>
+
+<a ping='http://www.example.org/ping-target' href="http://www.example.org/link-target">click here</a>
+
+<area ping="http://www.example.org/ping-target" href="http://www.example.org/link-target">
+
+<area ping='http://www.example.org/ping-target' href="http://www.example.org/link-target">
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 836\r
+\r
+# Here are some strings the no-ping filter should filter:
+
+<strong style="color:white; background-color:red;" title="Privoxy removed ping target 'http://www.example.org/ping-target'">PING!</strong>
+<a href="http://www.example.org/link-target">click here</a>
+
+<strong style="color:white; background-color:red;" title="Privoxy removed ping target 'http://www.example.org/ping-target'">PING!</strong>
+<a href="http://www.example.org/link-target">click here</a>
+
+<strong style="color:white; background-color:red;" title="Privoxy removed ping target 'http://www.example.org/ping-target'">PING!</strong>
+<area href="http://www.example.org/link-target">
+
+<strong style="color:white; background-color:red;" title="Privoxy removed ping target 'http://www.example.org/ping-target'">PING!</strong>
+<area href="http://www.example.org/link-target">
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{no-ping}
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/no-ping/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /no-ping/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test36 b/tests/cts/content-filters/data/test36
new file mode 100644 (file)
index 0000000..e121709
--- /dev/null
@@ -0,0 +1,84 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter allow-autocompletion
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# Here are some strings the allow-autocompletion filter should filter:
+
+<input blafasel autocomplete="off"
+<input blafasel autocomplete='0'
+
+<form blafasel autocomplete="off"
+<form blafasel autocomplete='0'
+
+<select blafasel autocomplete="off"
+<select blafasel autocomplete='0'
+
+<textarea blafasel autocomplete="off"
+<textarea blafasel autocomplete='0'
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 353\r
+\r
+# Here are some strings the allow-autocompletion filter should filter:
+
+<input blafasel autocomplete="on"
+<input blafasel autocomplete='on'
+
+<form blafasel autocomplete="on"
+<form blafasel autocomplete='on'
+
+<select blafasel autocomplete="on"
+<select blafasel autocomplete='on'
+
+<textarea blafasel autocomplete="on"
+<textarea blafasel autocomplete='on'
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{allow-autocompletion}
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/allow-autocompletion/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /allow-autocompletion/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test37 b/tests/cts/content-filters/data/test37
new file mode 100644 (file)
index 0000000..39c1555
--- /dev/null
@@ -0,0 +1,74 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter github
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# Here are some strings the github filter should filter:
+
+<signup-prompt blafasel>
+Come join our proprietary platform!!!
+</signup-prompt>
+
+<div class="hx_cookie-banner>
+By the way, we are using cookies to track you.
+</div>
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 166\r
+\r
+# Here are some strings the github filter should filter:
+
+
+
+<div style="display:none;" class="hx_cookie-banner>
+By the way, we are using cookies to track you.
+</div>
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{github}
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/github/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /github/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test38 b/tests/cts/content-filters/data/test38
new file mode 100644 (file)
index 0000000..9b9f6b4
--- /dev/null
@@ -0,0 +1,84 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter imdb
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# Here are some strings the imdb filter should filter:
+
+# pcrs command 1:
+
+<div id="top_ad_wrapper"
+
+# pcrs command 2:
+
+<iframe blafasel id="top_ad" tralala></iframe>
+
+# pcrs command 3:
+
+<iframe blafasel onload="doWithAds.call bumfidel></iframe>
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 259\r
+\r
+# Here are some strings the imdb filter should filter:
+
+# pcrs command 1:
+
+<div id="top_ad_wrapper" style="display:none"
+
+# pcrs command 2:
+
+<!-- Iframe removed by Privoxy's imdb filter -->
+
+# pcrs command 3:
+
+<!-- Iframe removed by Privoxy's imdb filter -->
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{imdb}
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/imdb/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /imdb/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test390 b/tests/cts/content-filters/data/test390
new file mode 100644 (file)
index 0000000..dc77146
--- /dev/null
@@ -0,0 +1,115 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter google
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# Here are some strings the google filter should filter:
+
+# pcrs command 1:
+
+</head>
+
+# pcrs command 2:
+
+<div style="padding-top:11px;min-width:500px">
+
+# pcrs command 3:
+
+<table cellspacing=0 cellpadding=0 width=25% align=right bgcolor=#ffffff border=0
+
+# pcrs command 3 does not filter these because it only hits one pattern:
+
+</font></td></tr></tbody></table><table align="right" bgcolor="#ffffff"
+
+<table cellspacing=0 cellpadding=0 align=right bgcolor=#ffffff border=0
+
+<table style="clear:both" align=right width=25% cellspacing="0" cellpadding="0" border="0" bgcolor="#ffffff"
+
+# pcrs command 4:
+
+<br clear=all><table border=0 cellpadding=9><tr><td
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 1023\r
+\r
+# Here are some strings the google filter should filter:
+
+# pcrs command 1:
+
+<style type="text/css">
+ /* Style sheet inserted by Privoxy's google filter. */
+ #fbc, #fbl, #ra, .rhh {visibility: hidden !important;}
+ #tpa1,#tpa2,#tpa3,#tpa4,#tpa5,#tpa5, #spl, .ch, #ads, #toolbar, #google_ads_frame, #mbEnd {display: none !important;}
+ .main_body, .j, #res, .med, .hd, .g, .s
+ {width: 99%; max-width: 100%; margin-left: 0; margin-right: 0;}
+ </style>
+</head>
+
+# pcrs command 2:
+
+<div id="main_body">
+
+# pcrs command 3:
+
+<table cellspacing=0 cellpadding=0 width=25% align=right bgcolor=#ffffff border=0 id="ads"
+
+# pcrs command 3 does not filter these because it only hits one pattern:
+
+</font></td></tr></tbody></table><table align="right" bgcolor="#ffffff"
+
+<table cellspacing=0 cellpadding=0 align=right bgcolor=#ffffff border=0
+
+<table style="clear:both" align=right width=25% cellspacing="0" cellpadding="0" border="0" bgcolor="#ffffff"
+
+# pcrs command 4:
+
+<br clear=all><table id="toolbar" border=0 cellpadding=9><tr><td
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{google} - multiple pcrs commands triggered
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/google/multiple-pcrs-commands/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /google/multiple-pcrs-commands/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test391 b/tests/cts/content-filters/data/test391
new file mode 100644 (file)
index 0000000..fa41d0a
--- /dev/null
@@ -0,0 +1,63 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter google
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# Here is a string the google filter's pcrs command 3 should filter:
+
+</font></td></tr></tbody></table><table align="right" bgcolor="#ffffff"
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Content-Type: text/html
+X-Control: swsclose
+Content-Length: 151
+
+# Here is a string the google filter's pcrs command 3 should filter:
+
+</font></td></tr></tbody></table><table align="right" bgcolor="#ffffff" id="ads"
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{google} - pcrs command 3 - pattern B
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/google/pcrs-command-3b/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /google/pcrs-command-3b/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test392 b/tests/cts/content-filters/data/test392
new file mode 100644 (file)
index 0000000..c93f99b
--- /dev/null
@@ -0,0 +1,64 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter google
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# Here is a string the google filter's pcrs command 3 should filter:
+
+<table cellspacing=0 cellpadding=0 align=right bgcolor=#ffffff border=0
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 151\r
+\r
+# Here is a string the google filter's pcrs command 3 should filter:
+
+<table cellspacing=0 cellpadding=0 align=right bgcolor=#ffffff border=0 id="ads"
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{google} - pcrs command 3 - pattern C
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/google/pcrs-command-3c/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /google/pcrs-command-3c/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test393 b/tests/cts/content-filters/data/test393
new file mode 100644 (file)
index 0000000..2f19c09
--- /dev/null
@@ -0,0 +1,63 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter google
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# Here is a string the google filter's pcrs command 3 should filter:
+
+<table style="clear:both" align=right width=25% cellspacing="0" cellpadding="0" border="0" bgcolor="#ffffff"
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 188\r
+\r
+# Here is a string the google filter's pcrs command 3 should filter:
+
+<table style="clear:both" align=right width=25% cellspacing="0" cellpadding="0" border="0" bgcolor="#ffffff" id="ads"
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{google} - pcrs command 3 - pattern D
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/google/pcrs-command-3d/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /google/pcrs-command-3d/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test4 b/tests/cts/content-filters/data/test4
new file mode 100644 (file)
index 0000000..f1eb3e3
--- /dev/null
@@ -0,0 +1,81 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter content-cookies
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# Here are some strings the content-cookies filter should modify:
+
+# pcrs command 1:
+
+blafasel.cookie=tralala=12
+blafasel.cookie='aab=keep-me-unmodified'
+
+# pcrs command 2:
+
+<meta http-equiv="set-cookie" content="blafasel=123">
+<meta http-equiv='set-cookie' content="blafasel=123">
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 215\r
+\r
+# Here are some strings the content-cookies filter should modify:
+
+# pcrs command 1:
+
+ZappedCookie=tralala=12
+blafasel.cookie='aab=keep-me-unmodified'
+
+# pcrs command 2:
+
+<!-- ZappedCookie -->
+<!-- ZappedCookie -->
+</data>
+</proxy-reply>
+
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{content-cookies}
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/content-cookies/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /content-cookies/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test5 b/tests/cts/content-filters/data/test5
new file mode 100644 (file)
index 0000000..c345b84
--- /dev/null
@@ -0,0 +1,89 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter refresh-tags
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# Here are some strings the refresh-tags filter should modify:
+
+<meta http-equiv="refresh" content="15; url=https://www.privoxy.org/">
+<meta http-equiv='refresh' content='20; url=https://www.privoxy.org/'>
+
+# Here are some strings the refresh-tags filter should not modify:
+
+<meta http-equiv="refresh" content="1; url=https://www.privoxy.org/">
+<meta http-equiv='refresh' content='2; url=https://www.privoxy.org/'>
+<meta http-equiv='refresh' content='3; url=https://www.privoxy.org/'>
+<meta http-equiv='refresh' content='4; url=https://www.privoxy.org/'>
+<meta http-equiv='refresh' content='5; url=https://www.privoxy.org/'>
+<meta http-equiv='refresh' content='6; url=https://www.privoxy.org/'>
+<meta http-equiv='refresh' content='7; url=https://www.privoxy.org/'>
+<meta http-equiv='refresh' content='8; url=https://www.privoxy.org/'>
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 803\r
+\r
+# Here are some strings the refresh-tags filter should modify:
+
+<link rev="x-refresh" href="https://www.privoxy.org/">
+<link rev="x-refresh" href="https://www.privoxy.org/">
+
+# Here are some strings the refresh-tags filter should not modify:
+
+<meta http-equiv="refresh" content="1; url=https://www.privoxy.org/">
+<meta http-equiv='refresh' content='2; url=https://www.privoxy.org/'>
+<meta http-equiv='refresh' content='3; url=https://www.privoxy.org/'>
+<meta http-equiv='refresh' content='4; url=https://www.privoxy.org/'>
+<meta http-equiv='refresh' content='5; url=https://www.privoxy.org/'>
+<meta http-equiv='refresh' content='6; url=https://www.privoxy.org/'>
+<meta http-equiv='refresh' content='7; url=https://www.privoxy.org/'>
+<meta http-equiv='refresh' content='8; url=https://www.privoxy.org/'>
+</data>
+</proxy-reply>
+
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{refresh-tags}
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/refresh-tags/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /refresh-tags/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test6 b/tests/cts/content-filters/data/test6
new file mode 100644 (file)
index 0000000..f4d88f4
--- /dev/null
@@ -0,0 +1,97 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter unsolicited-popups
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# Here are some strings the unsolicited-popups filter should modify:
+
+# pcrs command 1:
+
+<head blafasel>
+
+# pcrs command 2:
+
+blafasel + window.open(
+blafasel - mapwindow.open(
+blafasel + mapthis.open(
+blafasel - mapparent.open(
+blafasel + window.open(
+blafasel = this.open(
+blafasel = parent.open(
+
+# pcrs command 3:
+
+aslkdfalksjfd </html>
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 520\r
+\r
+# Here are some strings the unsolicited-popups filter should modify:
+
+# pcrs command 1:
+
+<head blafasel><script>function PrivoxyWindowOpen(){return(null);}</script>
+
+# pcrs command 2:
+
+blafasel + PrivoxyWindowOpen(
+blafasel - PrivoxyWindowOpen(
+blafasel + PrivoxyWindowOpen(
+blafasel - PrivoxyWindowOpen(
+blafasel + PrivoxyWindowOpen(
+blafasel = PrivoxyWindowOpen(
+blafasel = PrivoxyWindowOpen(
+
+# pcrs command 3:
+
+aslkdfalksjfd </html><script>function PrivoxyWindowOpen(a, b, c){return(window.open(a, b, c));}</script>
+</data>
+</proxy-reply>
+
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{unsolicited-popups}
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/unsolicited-popups/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /unsolicited-popups/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test7 b/tests/cts/content-filters/data/test7
new file mode 100644 (file)
index 0000000..6393fab
--- /dev/null
@@ -0,0 +1,89 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter all-popups
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# Here are some strings the all-popups filter should modify:
+
+# pcrs command 1:
+
++ mapwindow.open(
++ window.open(
++ this.open(
++ parent.open(
+
+# pcrs command 2:
+
+ target  = "blank"
+ target  =   'blank'
+ target  =   "new"
+ target  =   'new'
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 178\r
+\r
+# Here are some strings the all-popups filter should modify:
+
+# pcrs command 1:
+
++ mapwindow.concat(
++ window.concat(
++ this.concat(
++ parent.concat(
+
+# pcrs command 2:
+
+</data>
+</proxy-reply>
+
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{all-popups}
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/all-popups/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /all-popups/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test8 b/tests/cts/content-filters/data/test8
new file mode 100644 (file)
index 0000000..75f49ae
--- /dev/null
@@ -0,0 +1,105 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter img-reorder
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# Here are some strings the img-reorder filter should modify:
+
+<img alt="blafasel" src="http://example.org/">
+<img alt="blafasel" title="blafasel" src="http://example.org/">
+<img alt='blafasel' title='blafasel' src="http://example.org/">
+<img width="100" height="100" src="http://example.org/">
+<img width=100 height=100 src="http://example.org/">
+<img width=100 height='100' src="http://example.org/">
+<img width="100" height=100 src="http://example.org/">
+<img width="100" height=100 src="http://example.org/">
+<img width=100 src="http://example.org/" height='100'>
+<img  src="http://example.org/" width="100" height=100>
+<img width="100" height=100 src="http://example.org/">
+
+<img src="http://example.org/" alt="blafasel">
+
+<img data-index="0" class="lazy" src="" data-original="blafasel.jpg" title="">
+<img data-index="0" class="lazy" src='' data-original='blafasel.jpg' title="">
+
+<img data-index="0" class="lazy" src="a" data-original="blafasel.jpg" title="">
+<img data-index="0" class="lazy" src='b' data-original='blafasel.jpg' title="">
+
+<img width=888 height=573 src=socket.png>
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 1089\r
+\r
+# Here are some strings the img-reorder filter should modify:
+
+<img src="http://example.org/" alt="blafasel">
+<img src="http://example.org/" alt="blafasel" title="blafasel">
+<img src="http://example.org/" alt='blafasel' title='blafasel'>
+<img src="http://example.org/" width="100" height="100">
+<img src="http://example.org/" width=100 height=100>
+<img src="http://example.org/" width=100 height='100'>
+<img src="http://example.org/" width="100" height=100>
+<img src="http://example.org/" width="100" height=100>
+<img src="http://example.org/" width=100 height='100'>
+<img src="http://example.org/" width="100" height=100>
+<img src="http://example.org/" width="100" height=100>
+
+<img src="http://example.org/" alt="blafasel">
+
+<img data-index="0" class="lazy" src="" data-original="blafasel.jpg" title="">
+<img data-index="0" class="lazy" src='' data-original='blafasel.jpg' title="">
+
+<img src="a" data-index="0" class="lazy" data-original="blafasel.jpg" title="">
+<img src='b' data-index="0" class="lazy" data-original='blafasel.jpg' title="">
+
+<img src=socket.png width=888 height=573>
+</data>
+</proxy-reply>
+
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{img-reorder}
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/img-reorder/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /img-reorder/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/data/test9 b/tests/cts/content-filters/data/test9
new file mode 100644 (file)
index 0000000..7695fac
--- /dev/null
@@ -0,0 +1,236 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+filter banners-by-size
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+\r
+# Here is some HTML that the banners-by-size filter should modify:
+
+# pcrs command 1 (88*31):
+
+<img src="http://www.privoxy.org/images/privoxy.png" width="88" height="31">
+<img src="https://www.privoxy.org/images/privoxy.png" width="88" height="31">
+<img src='http://www.privoxy.org/images/privoxy.png' width='88' height='31'>
+<img src="http://www.privoxy.org/images/privoxy.png" width="88" height="31">
+
+# pcrs command 2 (120*60, 120*90, 120*240, 120*600):
+
+<img src="http://www.privoxy.org/images/privoxy.png" width="120" height="60">
+<img src="https://www.privoxy.org/images/privoxy.png" width="120" height="60">
+<img src='http://www.privoxy.org/images/privoxy.png' width='120' height='60'>
+<img src="http://www.privoxy.org/images/privoxy.png" width="120" height="60">
+
+<img src="http://www.privoxy.org/images/privoxy.png" width="120" height="90">
+<img src="https://www.privoxy.org/images/privoxy.png" width="120" height="90">
+<img src='http://www.privoxy.org/images/privoxy.png' width='120' height='90'>
+<img src="http://www.privoxy.org/images/privoxy.png" width="120" height="90">
+
+<img src="http://www.privoxy.org/images/privoxy.png" width="120" height="240">
+<img src="https://www.privoxy.org/images/privoxy.png" width="120" height="240">
+<img src='http://www.privoxy.org/images/privoxy.png' width='120' height='240'>
+<img src="http://www.privoxy.org/images/privoxy.png" width="120" height="240">
+
+<img src="http://www.privoxy.org/images/privoxy.png" width="120" height="600">
+<img src="https://www.privoxy.org/images/privoxy.png" width="120" height="600">
+<img src='http://www.privoxy.org/images/privoxy.png' width='120' height='600'>
+<img src="http://www.privoxy.org/images/privoxy.png" width="120" height="600">
+
+# pcrs command 3 (125*125):
+
+<img src="http://www.privoxy.org/images/privoxy.png" width="125" height="125">
+<img src="https://www.privoxy.org/images/privoxy.png" width="125" height="125">
+<img src='http://www.privoxy.org/images/privoxy.png' width='125' height='125'>
+<img src="http://www.privoxy.org/images/privoxy.png" width="125" height="125">
+
+# pcrs command 4 (160*600):
+
+<img src="http://www.privoxy.org/images/privoxy.png" width="160" height="600">
+<img src="https://www.privoxy.org/images/privoxy.png" width="160" height="600">
+<img src='http://www.privoxy.org/images/privoxy.png' width='160' height='600'>
+<img src="http://www.privoxy.org/images/privoxy.png" width="160" height="600">
+
+# pcrs command 5 (180*150):
+
+<img src="http://www.privoxy.org/images/privoxy.png" width="180" height="150">
+<img src="https://www.privoxy.org/images/privoxy.png" width="180" height="150">
+<img src='http://www.privoxy.org/images/privoxy.png' width='180' height='150'>
+<img src="http://www.privoxy.org/images/privoxy.png" width="180" height="150">
+
+# pcrs command 6 (234*60, 468*60):
+
+<img src="http://www.privoxy.org/images/privoxy.png" width="234" height="60">
+<img src="https://www.privoxy.org/images/privoxy.png" width="234" height="60">
+<img src='http://www.privoxy.org/images/privoxy.png' width='234' height='60'>
+<img src="http://www.privoxy.org/images/privoxy.png" width="234" height="60">
+
+<img src="http://www.privoxy.org/images/privoxy.png" width="468" height="60">
+<img src="https://www.privoxy.org/images/privoxy.png" width="468" height="60">
+<img src='http://www.privoxy.org/images/privoxy.png' width='468' height='60'>
+<img src="http://www.privoxy.org/images/privoxy.png" width="468" height="60">
+
+# pcrs command 7 (240*400):
+
+<img src="http://www.privoxy.org/images/privoxy.png" width="240" height="400">
+<img src="https://www.privoxy.org/images/privoxy.png" width="240" height="400">
+<img src='http://www.privoxy.org/images/privoxy.png' width='240' height='400'>
+<img src="http://www.privoxy.org/images/privoxy.png" width="240" height="400">
+
+# pcrs command 8 (250*250, 300*250):
+
+<img src="http://www.privoxy.org/images/privoxy.png" width="250" height="250">
+<img src="https://www.privoxy.org/images/privoxy.png" width="250" height="250">
+<img src='http://www.privoxy.org/images/privoxy.png' width='250' height='250'>
+<img src="http://www.privoxy.org/images/privoxy.png" width="250" height="250">
+
+<img src="http://www.privoxy.org/images/privoxy.png" width="300" height="250">
+<img src="https://www.privoxy.org/images/privoxy.png" width="300" height="250">
+<img src='http://www.privoxy.org/images/privoxy.png' width='300' height='250'>
+<img src="http://www.privoxy.org/images/privoxy.png" width="300" height="250">
+
+# pcrs command 8 (336*280):
+
+<img src="http://www.privoxy.org/images/privoxy.png" width="336" height="280">
+<img src="https://www.privoxy.org/images/privoxy.png" width="336" height="280">
+<img src='http://www.privoxy.org/images/privoxy.png' width='336' height='280'>
+<img src="http://www.privoxy.org/images/privoxy.png" width="336" height="280">
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 9499\r
+\r
+# Here is some HTML that the banners-by-size filter should modify:
+
+# pcrs command 1 (88*31):
+
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width="88" height="31">
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-https://www.privoxy.org/images/privoxy.png-by-size" width="88" height="31">
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width='88' height='31'>
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width="88" height="31">
+
+# pcrs command 2 (120*60, 120*90, 120*240, 120*600):
+
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width="120" height="60">
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-https://www.privoxy.org/images/privoxy.png-by-size" width="120" height="60">
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width='120' height='60'>
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width="120" height="60">
+
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width="120" height="90">
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-https://www.privoxy.org/images/privoxy.png-by-size" width="120" height="90">
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width='120' height='90'>
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width="120" height="90">
+
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width="120" height="240">
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-https://www.privoxy.org/images/privoxy.png-by-size" width="120" height="240">
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width='120' height='240'>
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width="120" height="240">
+
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width="120" height="600">
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-https://www.privoxy.org/images/privoxy.png-by-size" width="120" height="600">
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width='120' height='600'>
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width="120" height="600">
+
+# pcrs command 3 (125*125):
+
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width="125" height="125">
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-https://www.privoxy.org/images/privoxy.png-by-size" width="125" height="125">
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width='125' height='125'>
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width="125" height="125">
+
+# pcrs command 4 (160*600):
+
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width="160" height="600">
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-https://www.privoxy.org/images/privoxy.png-by-size" width="160" height="600">
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width='160' height='600'>
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width="160" height="600">
+
+# pcrs command 5 (180*150):
+
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width="180" height="150">
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-https://www.privoxy.org/images/privoxy.png-by-size" width="180" height="150">
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width='180' height='150'>
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width="180" height="150">
+
+# pcrs command 6 (234*60, 468*60):
+
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width="234" height="60">
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-https://www.privoxy.org/images/privoxy.png-by-size" width="234" height="60">
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width='234' height='60'>
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width="234" height="60">
+
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width="468" height="60">
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-https://www.privoxy.org/images/privoxy.png-by-size" width="468" height="60">
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width='468' height='60'>
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width="468" height="60">
+
+# pcrs command 7 (240*400):
+
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width="240" height="400">
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-https://www.privoxy.org/images/privoxy.png-by-size" width="240" height="400">
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width='240' height='400'>
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width="240" height="400">
+
+# pcrs command 8 (250*250, 300*250):
+
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width="250" height="250">
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-https://www.privoxy.org/images/privoxy.png-by-size" width="250" height="250">
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width='250' height='250'>
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width="250" height="250">
+
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width="300" height="250">
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-https://www.privoxy.org/images/privoxy.png-by-size" width="300" height="250">
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width='300' height='250'>
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width="300" height="250">
+
+# pcrs command 8 (336*280):
+
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width="336" height="280">
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-https://www.privoxy.org/images/privoxy.png-by-size" width="336" height="280">
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width='336' height='280'>
+  <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width="336" height="280">
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++filter{banners-by-size}
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/banners-by-size/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /banners-by-size/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/content-filters/privoxy.conf b/tests/cts/content-filters/privoxy.conf
new file mode 100644 (file)
index 0000000..2b67300
--- /dev/null
@@ -0,0 +1,17 @@
+listen-address 127.0.0.1:9119
+
+debug     1 # Log the destination for each request Privoxy let through. See also debug 1024.
+debug     2 # show each connection status
+debug     4 # show tagging-related messages
+debug     8 # show header parsing
+debug    32 # debug force feature
+debug    64 # debug regular expression filters
+debug   128 # debug redirects
+debug   256 # debug GIF de-animation
+debug   512 # Common Log Format
+debug  1024 # Log the destination for requests Privoxy didn't let through, and the reason why.
+debug  4096 # Startup banner and warnings.
+debug  8192 # Non-fatal errors
+
+filterfile ../../../default.filter
+actionsfile ./content-filters.action
diff --git a/tests/cts/curl-test-manifest-for-privoxy b/tests/cts/curl-test-manifest-for-privoxy
new file mode 100644 (file)
index 0000000..3cd1c83
--- /dev/null
@@ -0,0 +1,85 @@
+keyword:--libcurl: Tests with keyword '--libcurl' currently don't work with Privoxy as they need additional runtests.pl changes.
+keyword:--request-target: Tests with keyword '--request-target' don't work with Privoxy as they use the OPTIONS method which is currently not properly supported (TODO #186).
+keyword:--resolve: Tests with keyword '--resolve' currently don't work with Privoxy as they need additional runtests.pl changes.
+keyword:curl-config: Tests with keyword 'curl-config' do not reach the proxy. Or do they?
+keyword:CURLOPT_RESOLVE: Tests with keyword 'CURLOPT_RESOLVE' currently don't work with Privoxy as they need additional runtests.pl changes.
+keyword:FAILURE: Tests with keyword 'FAILURE' do not reach the proxy. Or do they?
+keyword:FILE: Protocol FILE is not supported by Privoxy.
+keyword:FTP: Protocol FTP is not supported by Privoxy.
+keyword:GOPHER: Protocol GOPHER is not supported by Privoxy.
+keyword:IMAP: Protocol IMAP is not supported by Privoxy.
+keyword:IPv6: Tests with keyword 'IPv6' aren't expected to work with Privoxy running in a jail without IPv6 connectivity.
+keyword:POP3: Protocol POP3 is not supported by Privoxy.
+keyword:proxy: Tests with keyword 'proxy' currently don't work with Privoxy as they need additional runtests.pl changes.
+keyword:RTSP: Protocol RTSP is not supported by Privoxy.
+keyword:skip: Tests with keyword 'skip' obviously should be skipped. Check the full keyword for details.
+keyword:SMTP: Protocol SMTP is not supported by Privoxy.
+keyword:SOCKS4: Protocol SOCKS4 is supported by Privoxy but the tests need additional magic before they can be used.
+keyword:SOCKS5: Protocol SOCKS5 is supported by Privoxy but the tests need additional magic before they can be used.
+keyword:TELNET: Protocol TELNET is not supported by Privoxy.
+keyword:unsupported: Tests with keyword 'unsupported' do not reach the proxy. Or do they?
+test:1052: Expected to fail. Connection header expected in one response but not in the other. Not yet covered by runtests.pl's proxy mode.
+test:1074: Expected to fail. Privoxy doesn't downgrade the forwarded request and doesn't have to as long as the client is treated like a HTTP/1.0 client. Needs double-checking.
+test:1118: Expected to fail. Looks like a curl bug although Privoxy's behaviour seems subobtimal as well.
+test:1144: Expected to fail. Server response is invalid and results in 502 message from Privoxy
+test:1147: Expected to fail. Privoxy merges a two-line cookie into a one line cookie.
+test:1151: Expected to fail. Large cookies that don't make it to the cookie file. Needs investigating.
+test:1156: Expected to fail as it relies on Range requests making it to the server.
+test:1164, 1172, 1174: Expected to fail as Privoxy does not support HTTP/0.9.
+test:1188: Expected to fail. Relies on a connection failure which results in a Privoxy error message the test does not expect
+test:1223: Expected to fail. Tests remote address which doesn't work with proxies.
+test:1274: Expected to fail. Privoxy unfolds the folded headers which the test does not expect.
+test:129: Invalid HTTP version. Privoxy downgrades it to 1.1.
+test:1292: Expected to fail as Privoxy replaces the empty Host header.
+test:1310: Known to fail. NTLM-related. Cause not properly diagnosed yet. Privoxy's behaviour seems reasonable.
+test:1433: Expected to fail. Privoxy will enforce a valid HTTP version number
+test:1506, 1510: Expected to fail when using a proxy. Hardcoded addresses in expected output.
+test:1533: Sends an invalid method. Needs investigating.
+test:1543: Expected to fail as the URL contains spaces. XXX: investigate
+test:155: Known to fail. Not yet analyzed.
+test:1556: Known to fail. Body value changes from 100008 to 100009. Needs investigating.
+test:158, 246, 565, 579: Known to fail. Not properly analyzed. Looks like Privoxy's continue hack is insufficient.
+test:16, 45, 63: Not supposed to work with Privoxy. Expected forwarding failure. Workaround probably possible.
+test:1671: Known to fail as curl adds a Proxy-Connection header to the JSON output which the test doesn't expect.
+test:17: Not supposed to work with Privoxy. Invalid METHODs get rejected.
+test:187: Expected to fail. Test doesn't deal with Privoxy's error message in case of invalid URLs.
+test:19, 20: Not supposed to work with Privoxy. Tests behaviour with non-existing server and doesn't deal with error messages coming from a proxy.
+test:1901, 1902, 1903: Known to fail due to different response orders.
+test:1915: Known to fail. Uses tool that doesn't expect a proxy.
+test:1933: Known to fail. Modified signature in Authorization header. Needs investigating
+test:2032, 2033: Known to fail due to a limitation of the test which doesn't properly deal with interleaved output from two parallel connections
+test:2049, 2052, 2053, 2054: Uses --connect-to. Need investigating.
+test:207: Expected to fail. Test doesn't handle Privoxy's error message. Privoxy doesn't behave correctly, though.
+test:2082, 2084, 2085: Known to fail. Uses %HTTPPORT and does not expect Privoxy's port but the remote one.
+test:2100: Known to fail. Use DNS-over-HTTP.
+test:260: Known to fail. Looks like a curl bug. The URL passed to Privoxy is invalid but the test expect a valid one when not using a proxy
+test:262: Not supposed to work with Privoxy. Privoxy doesn't support nul bytes in headers and neither does the spec.
+test:266, 1116, 1540: Known to fail. Uses chunk trailers which Privoxy currently doesn't support.
+test:30, 37, 66, 1079: Expected to fail with Privoxy. In case of missing server headers Privoxy generates an error message the test doesn't expect.
+test:3014, 3015: Known to fail. Curl adds a Proxy-Connection header while test expect a certain number of headers.
+test:309: Known to fail. Uses https and test does not expect the 'Connection established' response from Privoxy
+test:31, 1105, 1160: Expected to fail. Privoxy normalizes white-space in a cookie.
+test:339, 347, 1591: Chunked transfer with trailers which Privoxy does not understand. Needs investigating.
+test:412, 413: Known to fail as curl is tunneling the request even though it's vanilla HTTP.
+test:415: Known to fail. Control code in Content-Length header.
+test:435: Expected to fail. Uses %{remote_port} and expects the port of the server and not the one from Privoxy.
+test:46: Invalid URL and use of --resolv.
+test:501: Not relevant for a proxy.
+test:507: Expected to fail. DNS failures cause a Privoxy error message the test doesn't handle.
+test:530, 584: Known to fail. Test server expects pipelined requests and doesn't respond otherwise.
+test:556: Expected to fail. Uses HTTP/1.2 which Privoxy rejects as invalid.
+test:581: Expected to fail. Privoxy removes second Content-Type header.
+test:587, 644: Expected to fail. POST request doesn't make it to the server. Needs investigating.
+test:59: Invalid URL gets rejected by Privoxy which the test can't handle.
+test:655: Expected to fail. Uses tool. Failure reason not yet analyzed
+test:8: Expected to fail. Tab in cookie that Privoxy converts to a space which the test does not expect.
+test:96: Test 96 is incomplete
+test:970, 972: Expected to fail. Privoxy adds a Proxy-Connection header which results in a modified num_headers value in the JSON output
+tool:--help: Tests with tool '--help' are not relevant for proxies.
+tool:--manual: Tests with tool '--manual' are not relevant for proxies.
+tool:lib517: Tests with tool 'lib517' are not relevant for proxies.
+tool:lib543: Tests with tool 'lib543' are not relevant for proxies.
+tool:lib543: Tests with tool 'lib543' are not relevant for proxies.
+tool:memory-includes: Tests with tool 'memory-includes' are not relevant for proxies.
+tool:symbols-in-versions: Tests with tool 'symbols-in-versions' are not relevant for proxies.
+tool:unittest: Tests with tool 'unittest' are not relevant for proxies.
diff --git a/tests/cts/forward-to-http-proxy/data/test1 b/tests/cts/forward-to-http-proxy/data/test1
new file mode 100644 (file)
index 0000000..5c1c833
--- /dev/null
@@ -0,0 +1,59 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+HTTP proxy
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: close
+Content-Type: text/html
+X-Control: swsclose
+
+Blafasel
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: close
+Content-Type: text/html
+X-Control: swsclose
+
+Blafasel
+</data>
+</proxy-reply>
+
+
+<client>
+<server>
+http
+</server>
+<name>
+Request forwarded through an HTTP proxy
+</name>
+<features>
+proxy
+</features>
+<command>
+http://www.example.org/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET http://www.example.org/%TESTNUMBER HTTP/1.1\r
+Host: www.example.org\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/forward-to-http-proxy/data/test2 b/tests/cts/forward-to-http-proxy/data/test2
new file mode 100644 (file)
index 0000000..af117b5
--- /dev/null
@@ -0,0 +1,83 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+HTTP proxy
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: keep-alive
+Content-Type: text/html
+Content-Length: 11
+
+Blafasel 1
+</data>
+<data1>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: close
+Content-Type: text/html
+X-Control: swsclose
+Content-Length: 11
+
+Blafasel 2
+</data1>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: keep-alive
+Content-Type: text/html
+Content-Length: 11
+
+Blafasel 1
+</data>
+<data1>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: close
+Content-Type: text/html
+X-Control: swsclose
+Content-Length: 11
+
+Blafasel 2
+</data1>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Two requests forwarded through an HTTP proxy on a reused connection
+</name>
+<features>
+proxy
+</features>
+<command>
+http://www.example.org/%TESTNUMBER0000 http://www.example.org/%TESTNUMBER0001
+</command>
+</client>
+
+<verify>
+<protocol>
+GET http://www.example.org/%TESTNUMBER0000 HTTP/1.1\r
+Host: www.example.org\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+GET http://www.example.org/%TESTNUMBER0001 HTTP/1.1\r
+Host: www.example.org\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/forward-to-http-proxy/data/test3 b/tests/cts/forward-to-http-proxy/data/test3
new file mode 100644 (file)
index 0000000..27810b8
--- /dev/null
@@ -0,0 +1,105 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+HTTP proxy
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: keep-alive
+Content-Type: text/html
+Content-Length: 11
+
+Blafasel 1
+</data>
+<data1>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: keep-alive
+Content-Type: text/html
+Content-Length: 11
+
+Blafasel 2
+</data1>
+<data2>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: close
+Content-Type: text/html
+X-Control: swsclose
+Content-Length: 11
+
+Blafasel 3
+</data2>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: keep-alive
+Content-Type: text/html
+Content-Length: 11
+
+Blafasel 1
+</data>
+<data1>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: keep-alive
+Content-Type: text/html
+Content-Length: 11
+
+Blafasel 2
+</data1>
+<data2>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: keep-alive
+Content-Type: text/html
+Content-Length: 11
+
+Blafasel 3
+</data2>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Two requests forwarded through an HTTP proxy on a reused connection followed by request that needs a new connection
+</name>
+<features>
+proxy
+</features>
+<command>
+http://www.example.org/%TESTNUMBER0000 http://www.example.org/%TESTNUMBER0001 http://www.example.org/%TESTNUMBER0002
+</command>
+</client>
+
+<verify>
+<protocol>
+GET http://www.example.org/%TESTNUMBER0000 HTTP/1.1\r
+Host: www.example.org\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+GET http://www.example.org/%TESTNUMBER0001 HTTP/1.1\r
+Host: www.example.org\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+GET /%TESTNUMBER0002 HTTP/1.1\r
+Host: www.example.org\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/forward-to-http-proxy/data/test4 b/tests/cts/forward-to-http-proxy/data/test4
new file mode 100644 (file)
index 0000000..7fe4d12
--- /dev/null
@@ -0,0 +1,105 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+HTTP proxy
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: keep-alive
+Content-Type: text/html
+Content-Length: 11
+
+Blafasel 1
+</data>
+<data1>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: keep-alive
+Content-Type: text/html
+Content-Length: 11
+
+Blafasel 2
+</data1>
+<data2>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: close
+Content-Type: text/html
+X-Control: swsclose
+Content-Length: 11
+
+Blafasel 3
+</data2>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: keep-alive
+Content-Type: text/html
+Content-Length: 11
+
+Blafasel 1
+</data>
+<data1>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: keep-alive
+Content-Type: text/html
+Content-Length: 11
+
+Blafasel 2
+</data1>
+<data2>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: keep-alive
+Content-Type: text/html
+Content-Length: 11
+
+Blafasel 3
+</data2>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Two requests forwarded through an HTTP proxy on a reused connection followed by request that does not use a forwarder
+</name>
+<features>
+proxy
+</features>
+<command>
+http://www.example.org/%TESTNUMBER0000 http://www.example.org/%TESTNUMBER0001 http://%HOSTIP:%HTTPPORT/%TESTNUMBER0002
+</command>
+</client>
+
+<verify>
+<protocol>
+GET http://www.example.org/%TESTNUMBER0000 HTTP/1.1\r
+Host: www.example.org\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+GET http://www.example.org/%TESTNUMBER0001 HTTP/1.1\r
+Host: www.example.org\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+GET /%TESTNUMBER0002 HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/forward-to-http-proxy/forward-to-http-proxy.action b/tests/cts/forward-to-http-proxy/forward-to-http-proxy.action
new file mode 100644 (file)
index 0000000..94791c8
--- /dev/null
@@ -0,0 +1,5 @@
+{+forward-override{forward-webserver 127.0.0.1:20000}}
+www.example.org/30002
+
+{+forward-override{forward .}}
+/40002
diff --git a/tests/cts/forward-to-http-proxy/privoxy.conf b/tests/cts/forward-to-http-proxy/privoxy.conf
new file mode 100644 (file)
index 0000000..2a72042
--- /dev/null
@@ -0,0 +1,23 @@
+listen-address 127.0.0.1:9119
+
+debug     1 # Log the destination for each request Privoxy let through. See also debug 1024.
+debug     2 # show each connection status
+debug     4 # show tagging-related messages
+debug     8 # show header parsing
+debug    32 # debug force feature
+debug    64 # debug regular expression filters
+debug   128 # debug redirects
+debug   256 # debug GIF de-animation
+debug   512 # Common Log Format
+debug  1024 # Log the destination for requests Privoxy didn't let through, and the reason why.
+debug  4096 # Startup banner and warnings.
+debug  8192 # Non-fatal errors
+
+templdir ../../../templates
+
+keep-alive-timeout 5
+default-server-timeout 5
+
+forward / 127.0.0.1:20000
+
+actionsfile forward-to-http-proxy.action
diff --git a/tests/cts/forward-to-socks-proxy/data/test1 b/tests/cts/forward-to-socks-proxy/data/test1
new file mode 100644 (file)
index 0000000..39120f5
--- /dev/null
@@ -0,0 +1,59 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: close
+Content-Type: text/html
+X-Control: swsclose
+
+Blafasel
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: close
+Content-Type: text/html
+X-Control: swsclose
+
+Blafasel
+</data>
+</proxy-reply>
+
+
+<client>
+<server>
+http
+socks4
+</server>
+<name>
+Request forwarded through a SOCKS4 proxy
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/socks4/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /socks4/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/forward-to-socks-proxy/data/test2 b/tests/cts/forward-to-socks-proxy/data/test2
new file mode 100644 (file)
index 0000000..2f23b1f
--- /dev/null
@@ -0,0 +1,59 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: close
+Content-Type: text/html
+X-Control: swsclose
+
+Blafasel
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: close
+Content-Type: text/html
+X-Control: swsclose
+
+Blafasel
+</data>
+</proxy-reply>
+
+
+<client>
+<server>
+http
+socks4
+</server>
+<name>
+Request forwarded through a SOCKS4A proxy
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/socks4a/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /socks4a/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/forward-to-socks-proxy/data/test3 b/tests/cts/forward-to-socks-proxy/data/test3
new file mode 100644 (file)
index 0000000..08172ca
--- /dev/null
@@ -0,0 +1,59 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: close
+Content-Type: text/html
+X-Control: swsclose
+
+Blafasel
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: close
+Content-Type: text/html
+X-Control: swsclose
+
+Blafasel
+</data>
+</proxy-reply>
+
+
+<client>
+<server>
+http
+socks4
+</server>
+<name>
+Request forwarded through a SOCKS5 proxy. Destination host specified by IPv4 address.
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/socks5/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /socks5/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/forward-to-socks-proxy/data/test4 b/tests/cts/forward-to-socks-proxy/data/test4
new file mode 100644 (file)
index 0000000..d4ad737
--- /dev/null
@@ -0,0 +1,63 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: close
+Content-Type: text/html
+X-Control: swsclose
+
+Blafasel
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: close
+Content-Type: text/html
+X-Control: swsclose
+
+Blafasel
+</data>
+</proxy-reply>
+
+
+<client>
+<server>
+http
+socks4
+</server>
+<precheck>
+# XXX: The test also requires that localhost resolves to 127.0.0.1 ...
+perl -e "print 'Test requires %HOSTIP 127.0.0.1' if ('%HOSTIP' ne '127.0.0.1');"
+</precheck>
+<name>
+Request forwarded through a SOCKS5 proxy. Destination host specified by domain name.
+</name>
+<features>
+proxy
+</features>
+<command>
+http://localhost:%HTTPPORT/socks5/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /socks5/%TESTNUMBER HTTP/1.1\r
+Host: localhost:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/forward-to-socks-proxy/data/test5 b/tests/cts/forward-to-socks-proxy/data/test5
new file mode 100644 (file)
index 0000000..ad416af
--- /dev/null
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+# Skip for now as the Socks server from curl's test suite does
+# not seem to deal properly deal with optimistically sent data
+skip
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: close
+Content-Type: text/html
+X-Control: swsclose
+
+Blafasel
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Connection: close
+Content-Type: text/html
+X-Control: swsclose
+
+Blafasel
+</data>
+</proxy-reply>
+
+
+<client>
+<server>
+http
+socks4
+</server>
+<name>
+Request forwarded through a SOCKS5t proxy. Destination host specified by IPv4 address.
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/socks5t/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /socks5t/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/forward-to-socks-proxy/data/test6 b/tests/cts/forward-to-socks-proxy/data/test6
new file mode 100644 (file)
index 0000000..1d03754
--- /dev/null
@@ -0,0 +1,30 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<client>
+<server>
+http
+socks4
+</server>
+<name>
+Request forwarded through a SOCKS5 proxy. Destination host specified by invalid IPv4 address.
+</name>
+<features>
+proxy
+</features>
+<command>
+-s --write-out '%{stderr}%{response_code}\n' http://127.1234.0.1:%HTTPPORT/socks5/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<stderr>
+503
+</stderr>
+</verify>
+</testcase>
diff --git a/tests/cts/forward-to-socks-proxy/privoxy.conf b/tests/cts/forward-to-socks-proxy/privoxy.conf
new file mode 100644 (file)
index 0000000..8079715
--- /dev/null
@@ -0,0 +1,25 @@
+listen-address 127.0.0.1:9119
+
+debug     1 # Log the destination for each request Privoxy let through. See also debug 1024.
+debug     2 # show each connection status
+debug     4 # show tagging-related messages
+debug     8 # show header parsing
+debug    32 # debug force feature
+debug    64 # debug regular expression filters
+debug   128 # debug redirects
+debug   256 # debug GIF de-animation
+debug   512 # Common Log Format
+debug  1024 # Log the destination for requests Privoxy didn't let through, and the reason why.
+debug  4096 # Startup banner and warnings.
+debug  8192 # Non-fatal errors
+
+templdir ../../../templates
+
+keep-alive-timeout 5
+default-server-timeout 5
+
+forward-socks4 /socks4/ 127.0.0.1:20001 .
+forward-socks4a /socks4a/ 127.0.0.1:20001 .
+forward-socks5 /socks5/ 127.0.0.1:20001 .
+forward-socks5t /socks5t/ 127.0.0.1:20001 .
+forward /verifiedserver .
diff --git a/tests/cts/gen-skip-reasons.pl b/tests/cts/gen-skip-reasons.pl
new file mode 100755 (executable)
index 0000000..c46b6c6
--- /dev/null
@@ -0,0 +1,199 @@
+#!/usr/bin/perl
+
+################################################################################
+#
+# gen-skip-reasons.pl
+#
+# Generates an exclude file that can be passed to runtests.pl to skip certain
+# tests that aren't expected to work when run through Privoxy.
+#
+# Copyright (c) 2012-2022 Fabian Keil <fk@fabiankeil.de>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+################################################################################
+
+use warnings;
+use strict;
+
+sub main() {
+    my %related_tests;
+
+    for my $testnum (1..3500) {
+        my $why;
+        if ($testnum eq 8) {
+            $why = "Expected to fail. Tab in cookie that Privoxy converts to a space which the test does not expect.";
+        } elsif ($testnum eq 16 or
+            $testnum eq 45 or
+            $testnum eq 63) {
+            $why = "Not supposed to work with Privoxy. Expected forwarding failure. Workaround probably possible.";
+        } elsif ($testnum eq 17) {
+            $why = "Not supposed to work with Privoxy. Invalid METHODs get rejected.";
+        } elsif ($testnum eq 19 or
+                 $testnum eq 20) {
+            $why = "Not supposed to work with Privoxy. Tests behaviour with non-existing server and doesn't deal with error messages coming from a proxy.";
+        } elsif ($testnum eq 30 or
+                 $testnum eq 37 or
+                 $testnum eq 66 or
+                 $testnum eq 1079) {
+            $why = "Expected to fail with Privoxy. In case of missing server headers Privoxy generates an error message the test doesn't expect.";
+        } elsif ($testnum eq 31 or $testnum eq 1105 or $testnum eq 1160) {
+            $why = "Expected to fail. Privoxy normalizes white-space in a cookie.";
+        } elsif ($testnum eq 46) {
+            $why = "Invalid URL and use of --resolv.";
+        } elsif ($testnum eq 59) {
+            $why = "Invalid URL gets rejected by Privoxy which the test can't handle.";
+        } elsif ($testnum eq 129) {
+            $why = "Invalid HTTP version. Privoxy downgrades it to 1.1.";
+        } elsif ($testnum eq 187) {
+            $why = "Expected to fail. Test doesn't deal with Privoxy's error message in case of invalid URLs.";
+        } elsif ($testnum eq 207) {
+             $why = "Expected to fail. Test doesn't handle Privoxy's error message. Privoxy doesn't behave correctly, though.";
+        } elsif ($testnum eq 260) {
+            $why = "Known to fail. Looks like a curl bug. The URL passed to Privoxy is invalid but the test expect a valid one when not using a proxy";
+        } elsif ($testnum eq 262) {
+            $why = "Not supposed to work with Privoxy. Privoxy doesn't support nul bytes in headers and neither does the spec.";
+        } elsif ($testnum eq 266 or $testnum eq 1116 or $testnum eq 1540) {
+            $why = "Known to fail. Uses chunk trailers which Privoxy currently doesn't support.";
+        } elsif ($testnum eq 309) {
+            $why = "Known to fail. Uses https and test does not expect the 'Connection established' response from Privoxy";
+        } elsif ($testnum eq 339 or $testnum eq 347 or $testnum eq 1591) {
+            $why = "Chunked transfer with trailers which Privoxy does not understand. Needs investigating.";
+        } elsif ($testnum eq 1052) {
+            $why = "Expected to fail. Connection header expected in one response but not in the other. Not yet covered by runtests.pl's proxy mode.";
+        } elsif ($testnum eq 1118) {
+            $why = "Expected to fail. Looks like a curl bug although Privoxy's behaviour seems subobtimal as well.";
+        } elsif ($testnum eq 1310) {
+            $why = "Known to fail. NTLM-related. Cause not properly diagnosed yet. Privoxy's behaviour seems reasonable.";
+        } elsif ($testnum eq 155) {
+            $why = "Known to fail. Not yet analyzed.";
+        } elsif ($testnum eq 158 or $testnum eq 246 or $testnum eq 565 or $testnum eq 579) {
+            $why = "Known to fail. Not properly analyzed. Looks like Privoxy's continue hack is insufficient.";
+        } elsif ($testnum eq 412 or $testnum eq 413) {
+            $why = "Known to fail as curl is tunneling the request even though it's vanilla HTTP.";
+        } elsif ($testnum eq 415) {
+            $why = "Known to fail. Control code in Content-Length header.";
+        } elsif ($testnum eq 435) {
+            $why = "Expected to fail. Uses %{remote_port} and expects the port of the server and not the one from Privoxy.";
+        } elsif ($testnum eq 507) {
+            $why = "Expected to fail. DNS failures cause a Privoxy error message the test doesn't handle.";
+        } elsif ($testnum eq 501) {
+            $why = "Not relevant for a proxy.";
+        } elsif ($testnum eq 530 or
+                 $testnum eq 584) {
+            $why = "Known to fail. Test server expects pipelined requests and doesn't respond otherwise.";
+        } elsif ($testnum eq 556) {
+            $why = "Expected to fail. Uses HTTP/1.2 which Privoxy rejects as invalid.";
+        } elsif ($testnum eq 581) {
+            $why = "Expected to fail. Privoxy removes second Content-Type header.";
+        } elsif ($testnum eq 587 or $testnum eq 644) {
+            $why = "Expected to fail. POST request doesn't make it to the server. Needs investigating.";
+        } elsif ($testnum eq 655) {
+            $why = "Expected to fail. Uses tool. Failure reason not yet analyzed";
+        } elsif ($testnum eq 970 or $testnum eq 972) {
+            $why = "Expected to fail. Privoxy adds a Proxy-Connection header which results in a modified num_headers value in the JSON output";
+        } elsif ($testnum eq 1074) {
+            $why = "Expected to fail. Privoxy doesn't downgrade the forwarded request and doesn't have ".
+                   "to as long as the client is treated like a HTTP/1.0 client. Needs double-checking.";
+        } elsif ($testnum eq 1144) {
+            $why = "Expected to fail. Server response is invalid and results in 502 message from Privoxy";
+        } elsif ($testnum eq 1147) {
+            $why = "Expected to fail. Privoxy merges a two-line cookie into a one line cookie.";
+        } elsif ($testnum eq 1151) {
+            $why = "Expected to fail. Large cookies that don't make it to the cookie file. Needs investigating.";
+        } elsif ($testnum eq 1188) {
+            $why = "Expected to fail. Relies on a connection failure which results in a Privoxy error message the test does not expect";
+        } elsif ($testnum eq 1223) {
+            $why = "Expected to fail. Tests remote address which doesn't work with proxies.";
+        } elsif ($testnum eq 1274) {
+            $why = "Expected to fail. Privoxy unfolds the folded headers which the test does not expect.";
+        } elsif ($testnum eq 1433) {
+            $why = "Expected to fail. Privoxy will enforce a valid HTTP version number";
+        } elsif ($testnum eq 1506 or $testnum eq 1510) {
+            $why = "Expected to fail when using a proxy. Hardcoded addresses in expected output.";
+        } elsif ($testnum eq 1156) {
+            $why = "Expected to fail as it relies on Range requests making it to the server.";
+        } elsif ($testnum eq 1164 or $testnum eq 1172 or $testnum eq 1174) {
+            $why = "Expected to fail as Privoxy does not support HTTP/0.9.";
+        } elsif ($testnum eq 1292) {
+            $why = "Expected to fail as Privoxy replaces the empty Host header.";
+        } elsif ($testnum eq 1533) {
+            $why = "Sends an invalid method. Needs investigating.";
+        } elsif ($testnum eq 1543) {
+            $why = "Expected to fail as the URL contains spaces. XXX: Looks like a curl bug that should be investigated.";
+        } elsif ($testnum eq 1556) {
+            $why = "Known to fail. Body value changes from 100008 to 100009. Needs investigating.";
+        } elsif ($testnum eq 1671) {
+            $why = "Known to fail as curl adds a Proxy-Connection header to the JSON output which the test doesn't expect.";
+        } elsif ($testnum eq 1915) {
+            $why = "Known to fail. Uses tool that doesn't expect a proxy.";
+        } elsif ($testnum eq 1933) {
+            $why = "Known to fail. Modified signature in Authorization header. Needs investigating";
+        } elsif ($testnum eq 2032 or $testnum eq 2033) {
+            $why = "Known to fail due to a limitation of the test which doesn't properly deal with interleaved output from two parallel connections";
+        } elsif ($testnum eq 2049 or $testnum eq 2052 or $testnum eq 2053 or $testnum eq 2054) {
+            $why = "Uses --connect-to. Need investigating.";
+        } elsif ($testnum eq 2082 or $testnum eq 2084 or $testnum eq 2085) {
+            $why = "Known to fail. Uses %HTTPPORT and does not expect Privoxy's port but the remote one.";
+        } elsif ($testnum eq 96) {
+            $why = "Test 96 is incomplete";
+        } elsif ($testnum eq 1901 or $testnum eq 1902 or $testnum eq 1903) {
+            $why = "Known to fail due to different response orders.";
+        } elsif ($testnum eq 2100) {
+            $why = "Known to fail. Use DNS-over-HTTP.";
+        } elsif ($testnum eq 3014 or $testnum eq 3015) {
+            $why = "Known to fail. Curl adds a Proxy-Connection header while test expect a certain number of headers.";
+        }
+
+        next unless defined $why;
+
+        if (exists $related_tests{$why}) {
+            $related_tests{$why} = $related_tests{$why} . ", $testnum";
+        } else {
+            $related_tests{$why} = "$testnum";
+        }
+    }
+
+    foreach my $why (keys %related_tests) {
+        printf("test:%s: %s\n", $related_tests{$why}, $why);
+    }
+
+    foreach my $protocol ('FTP', 'POP3', 'IMAP', 'SMTP', 'GOPHER', 'TELNET', 'FILE', 'RTSP') {
+        # Curl's behaviour when combining --proxy, -H and telnet:// seems strange and may be a bug."
+        printf("keyword:%s: Protocol %s is not supported by Privoxy.\n", $protocol, $protocol);
+    }
+
+    foreach my $protocol ('SOCKS4', 'SOCKS5') {
+        # Curl's behaviour when combining --proxy, -H and telnet:// seems strange and may be a bug."
+        printf("keyword:%s: Protocol %s is supported by Privoxy but the tests need additional magic before they can be used.\n", $protocol, $protocol);
+    }
+
+    foreach my $misc ('proxy', '--resolve', '--libcurl', 'CURLOPT_RESOLVE') {
+        printf("keyword:%s: Tests with keyword '%s' currently don't work with Privoxy as they need additional runtests.pl changes.\n", $misc, $misc);
+    }
+    printf("keyword:%s: Tests with keyword '%s' aren't expected to work with Privoxy running in a jail without IPv6 connectivity.\n", 'IPv6', 'IPv6');
+
+    printf("keyword:%s: Tests with keyword '%s' don't work with Privoxy as they use the OPTIONS method which is currently not properly supported (TODO #186).\n", '--request-target', '--request-target');
+
+    printf("keyword:%s: Tests with keyword '%s' obviously should be skipped. Check the full keyword for details.\n", 'skip', 'skip');
+
+    foreach my $keyword ('FAILURE', 'unsupported', 'curl-config') {
+        printf("keyword:%s: Tests with keyword '%s' do not reach the proxy. Or do they?\n", $keyword, $keyword);
+    }
+
+    foreach my $tool ('lib517', 'lib543', 'lib543', '--manual', '--help', 'symbols-in-versions', 'memory-includes', 'unittest') {
+        printf("tool:%s: Tests with tool '%s' are not relevant for proxies.\n", $tool, $tool);
+    }
+
+}
+
+main();
diff --git a/tests/cts/gif-deanimation/data/test1 b/tests/cts/gif-deanimation/data/test1
new file mode 100644 (file)
index 0000000..e96bc1a
--- /dev/null
@@ -0,0 +1,61 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gzip compression
+</keywords>
+</info>
+
+<reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+\r
+GIF89a000000000000000000;
+</data>
+</reply>
+
+<proxy-reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+\r
+GIF89a000000000000000000;
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Invalid gif.
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/deanimate-gif/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /deanimate-gif/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gif-deanimation/data/test10 b/tests/cts/gif-deanimation/data/test10
new file mode 100644 (file)
index 0000000..3e8e049
--- /dev/null
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gif deanimation
+</keywords>
+</info>
+
+<reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+\r
+%hex[%47%49%46%38%39%61%14%00%14%00%f0%00%00%fe%00%00%00%00%00%21%f9%04%00%c8%00%00%00%21%ff%0b%4e%45%54%53%43%41%50%45%32%2e%30%03%01%00%00%00%2c%00%00%00%00%14%00%14%00%00%02%11%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%af%15%00%21%f9%04%00%c8%00%00%00%2c%00%00%00%00%14%00%14%00%80%1e%42%ee%00%00%00%02%11%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%af%15%00%3b]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+Content-Length: 58\r
+\r
+%hex[%47%49%46%38%39%61%14%00%14%00%f0%00%00%fe%00%00%00%00%00%21%f9%04%00%c8%00%00%00%2c%00%00%00%00%14%00%14%00%00%02%11%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%af%15%00%3b]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Valid gif. Two frames. No comment. Using first frame.
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/deanimate-gif/first-frame/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /deanimate-gif/first-frame/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gif-deanimation/data/test11 b/tests/cts/gif-deanimation/data/test11
new file mode 100644 (file)
index 0000000..5e5ec57
--- /dev/null
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gif deanimation
+</keywords>
+</info>
+
+<reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+\r
+%hex[%47%49%46%38%39%61%14%00%14%00%f0%00%00%fe%00%00%00%00%00%21%f9%04%00%c8%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%ff%0b%4e%45%54%53%43%41%50%45%32%2e%30%03%01%00%00%00%21%ff%0b%49%43%43%52%47%42%47%31%30%31%32%ff%00%00%02%a0%6c%63%6d%73%04%30%00%00%6d%6e%74%72%52%47%42%20%58%59%5a%20%07%e5%00%02%00%09%00%10%00%2f%00%33%61%63%73%70%41%50%50%4c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%6c%63%6d%73%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0d%64%65%73%63%00%00%01%20%00%00%00%40%63%70%72%74%00%00%01%60%00%00%00%36%77%74%70%74%00%00%01%98%00%00%00%14%63%68%61%64%00%00%01%ac%00%00%00%2c%72%58%59%5a%00%00%01%d8%00%00%00%14%62%58%59%5a%00%00%01%ec%00%00%00%14%67%58%59%5a%00%00%02%00%00%00%00%14%72%54%52%43%00%00%02%14%00%00%00%20%67%54%52%43%00%00%02%14%00%00%00%20%62%54%52%43%00%00%02%14%00%00%00%20%63%68%72%ff%6d%00%00%02%34%00%00%00%24%64%6d%6e%64%00%00%02%58%00%00%00%24%64%6d%64%64%00%00%02%7c%00%00%00%24%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%24%00%00%00%1c%00%47%00%49%00%4d%00%50%00%20%00%62%00%75%00%69%00%6c%00%74%00%2d%00%69%00%6e%00%20%00%73%00%52%00%47%00%42%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%1a%00%00%00%1c%00%50%00%75%00%62%00%6c%00%69%00%63%00%20%00%44%00%6f%00%6d%00%61%00%69%00%6e%00%00%58%59%5a%20%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%73%66%33%32%00%00%00%00%00%01%0c%42%00%00%05%de%ff%ff%f3%25%00%00%07%93%00%00%fd%90%ff%ff%fb%a1%ff%ff%fd%a2%00%00%03%dc%00%00%c0%6e%58%59%5a%20%00%00%00%00%00%00%6f%a0%00%00%38%f5%00%00%03%90%58%59%5a%20%00%00%00%00%00%00%24%9f%00%00%0f%84%00%00%a2%b6%c4%58%59%5a%20%00%00%00%00%00%00%62%97%00%00%b7%87%00%00%18%d9%70%61%72%61%00%00%00%00%00%03%00%00%00%02%66%66%00%00%f2%a7%00%00%0d%59%00%00%13%d0%00%00%0a%5b%63%68%72%6d%00%00%00%00%00%03%00%00%00%00%a3%d7%00%00%54%7c%00%00%4c%cd%00%00%99%9a%00%00%26%67%00%00%0f%5c%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%47%00%49%00%4d%00%50%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%73%00%52%00%47%00%42%00%2c%00%00%00%00%14%00%14%00%00%02%11%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%af%15%00%21%f9%04%00%c8%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%ff%0b%49%43%43%52%47%42%47%31%30%31%32%ff%00%00%02%a0%6c%63%6d%73%04%30%00%00%6d%6e%74%72%52%47%42%20%58%59%5a%20%07%e5%00%02%00%09%00%10%00%2f%00%33%61%63%73%70%41%50%50%4c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%6c%63%6d%73%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0d%64%65%73%63%00%00%01%20%00%00%00%40%63%70%72%74%00%00%01%60%00%00%00%36%77%74%70%74%00%00%01%98%00%00%00%14%63%68%61%64%00%00%01%ac%00%00%00%2c%72%58%59%5a%00%00%01%d8%00%00%00%14%62%58%59%5a%00%00%01%ec%00%00%00%14%67%58%59%5a%00%00%02%00%00%00%00%14%72%54%52%43%00%00%02%14%00%00%00%20%67%54%52%43%00%00%02%14%00%00%00%20%62%54%52%43%00%00%02%14%00%00%00%20%63%68%72%ff%6d%00%00%02%34%00%00%00%24%64%6d%6e%64%00%00%02%58%00%00%00%24%64%6d%64%64%00%00%02%7c%00%00%00%24%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%24%00%00%00%1c%00%47%00%49%00%4d%00%50%00%20%00%62%00%75%00%69%00%6c%00%74%00%2d%00%69%00%6e%00%20%00%73%00%52%00%47%00%42%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%1a%00%00%00%1c%00%50%00%75%00%62%00%6c%00%69%00%63%00%20%00%44%00%6f%00%6d%00%61%00%69%00%6e%00%00%58%59%5a%20%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%73%66%33%32%00%00%00%00%00%01%0c%42%00%00%05%de%ff%ff%f3%25%00%00%07%93%00%00%fd%90%ff%ff%fb%a1%ff%ff%fd%a2%00%00%03%dc%00%00%c0%6e%58%59%5a%20%00%00%00%00%00%00%6f%a0%00%00%38%f5%00%00%03%90%58%59%5a%20%00%00%00%00%00%00%24%9f%00%00%0f%84%00%00%a2%b6%c4%58%59%5a%20%00%00%00%00%00%00%62%97%00%00%b7%87%00%00%18%d9%70%61%72%61%00%00%00%00%00%03%00%00%00%02%66%66%00%00%f2%a7%00%00%0d%59%00%00%13%d0%00%00%0a%5b%63%68%72%6d%00%00%00%00%00%03%00%00%00%00%a3%d7%00%00%54%7c%00%00%4c%cd%00%00%99%9a%00%00%26%67%00%00%0f%5c%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%47%00%49%00%4d%00%50%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%73%00%52%00%47%00%42%00%2c%00%00%00%00%14%00%14%00%80%1e%42%ee%00%00%00%02%11%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%af%15%00%3b]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+Content-Length: 58\r
+\r
+%hex[%47%49%46%38%39%61%14%00%14%00%f0%00%00%fe%00%00%00%00%00%21%f9%04%00%c8%00%00%00%2c%00%00%00%00%14%00%14%00%00%02%11%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%af%15%00%3b]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Valid gif. Two frames. Lots of meta data. Using first frame.
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/deanimate-gif/first-frame/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /deanimate-gif/first-frame/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gif-deanimation/data/test12 b/tests/cts/gif-deanimation/data/test12
new file mode 100644 (file)
index 0000000..40ca32d
--- /dev/null
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gif deanimation
+</keywords>
+</info>
+
+<reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+\r
+%hex[%47%49%46%38%39%61%14%00%14%00%80%01%00%1e%42%ee%ff%ff%ff%21%f9%04%01%0a%00%01%00%2c%00%00%00%00%14%00%14%00%00%02%11%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%af%15%00%3b]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+Content-Length: 58\r
+\r
+%hex[%47%49%46%38%39%61%14%00%14%00%80%01%00%1e%42%ee%ff%ff%ff%21%f9%04%01%0a%00%01%00%2c%00%00%00%00%14%00%14%00%00%02%11%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%af%15%00%3b]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Valid gif created with gimp. Gif not changed.
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/deanimate-gif/first-frame/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /deanimate-gif/first-frame/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gif-deanimation/data/test13 b/tests/cts/gif-deanimation/data/test13
new file mode 100644 (file)
index 0000000..644d434
--- /dev/null
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gif deanimation
+</keywords>
+</info>
+
+<reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+\r
+%hex[%47%49%46%38%39%61%14%00%14%00%80%02%00%fe%00%00%1e%42%ee%21%ff%0b%4e%45%54%53%43%41%50%45%32%2e%30%03%01%00%00%00%21%f9%04%00%0a%00%ff%00%2c%00%00%00%00%14%00%14%00%00%02%11%8c%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%af%15%00%21%f9%04%00%0a%00%ff%00%2c%00%00%00%00%14%00%14%00%00%02%11%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%af%15%00%3b]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+Content-Length: 58\r
+\r
+%hex[%47%49%46%38%39%61%14%00%14%00%80%02%00%fe%00%00%1e%42%ee%21%f9%04%00%0a%00%ff%00%2c%00%00%00%00%14%00%14%00%00%02%11%8c%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%af%15%00%3b]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Valid gif. No comment. Two frames. Using the first one.
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/deanimate-gif/first-frame/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /deanimate-gif/first-frame/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gif-deanimation/data/test14 b/tests/cts/gif-deanimation/data/test14
new file mode 100644 (file)
index 0000000..04a40c8
--- /dev/null
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gif deanimation
+</keywords>
+</info>
+
+<reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+\r
+%hex[%47%49%46%38%39%61%14%00%14%00%80%02%00%fe%00%00%1e%42%ee%21%ff%0b%4e%45%54%53%43%41%50%45%32%2e%30%03%01%00%00%00%21%f9%04%00%0a%00%ff%00%2c%00%00%00%00%14%00%14%00%00%02%11%8c%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%af%15%00%21%f9%04%00%0a%00%ff%00%2c%00%00%00%00%14%00%14%00%00%02%11%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%af%15%00%3b]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+Content-Length: 58\r
+\r
+%hex[%47%49%46%38%39%61%14%00%14%00%80%02%00%fe%00%00%1e%42%ee%21%f9%04%00%0a%00%ff%00%2c%00%00%00%00%14%00%14%00%00%02%11%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%af%15%00%3b]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Valid gif. No comment. Two frames. Using the last one.
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/deanimate-gif/last-frame/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /deanimate-gif/last-frame/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gif-deanimation/data/test15 b/tests/cts/gif-deanimation/data/test15
new file mode 100644 (file)
index 0000000..9b947da
--- /dev/null
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gif deanimation
+</keywords>
+</info>
+
+<reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+\r
+%hex[%47%49%46%38%39%61%14%00%14%00%f0%00%00%fe%00%00%00%00%00%21%f9%04%00%c8%00%00%00%21%ff%0b%4e%45%54%53%43%41%50%45%32%2e%30%03%01%00%00%00%2c%00%00%00%00%14%00%14%00%00%02%11%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%af%15%00%21%f9%04%00%c8%00%00%00%2c%00%00%00%00%14%00%14%00%80%1e%42%ee%00%00%00%02%11%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%af%15%00%3b]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+Content-Length: 58\r
+\r
+%hex[%47%49%46%38%39%61%14%00%14%00%f0%00%00%fe%00%00%00%00%00%21%f9%04%00%c8%00%00%00%2c%00%00%00%00%14%00%14%00%00%02%11%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%af%15%00%3b]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Valid gif. No comment. Two frames. Multiple extension blocks in a row. Using first frame
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/deanimate-gif/first-frame/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /deanimate-gif/first-frame/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gif-deanimation/data/test16 b/tests/cts/gif-deanimation/data/test16
new file mode 100644 (file)
index 0000000..16bcb06
--- /dev/null
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gif deanimation
+</keywords>
+</info>
+
+<reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+\r
+%hex[%47%49%46%38%39%61%14%00%14%00%f0%00%00%fe%00%00%00%00%00%21%f9%04%00%c8%00%00%00%21%ff%0b%4e%45%54%53%43%41%50%45%32%2e%30%03%01%00%00%00%2c%00%00%00%00%14%00%14%00%00%02%11%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%af%15%00%21%f9%04%00%c8%00%00%00%2c%00%00%00%00%14%00%14%00%80%1e%42%ee%00%00%00%02%11%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%af%15%00%3b]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+Content-Length: 64\r
+\r
+%hex[%47%49%46%38%39%61%14%00%14%00%f0%00%00%fe%00%00%00%00%00%21%f9%04%00%c8%00%00%00%2c%00%00%00%00%14%00%14%00%80%1e%42%ee%00%00%00%02%11%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%af%15%00%3b]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Valid gif. No comment. Two frames. Multiple extension blocks in a row. Using last frame
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/deanimate-gif/last-frame/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /deanimate-gif/last-frame/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gif-deanimation/data/test17 b/tests/cts/gif-deanimation/data/test17
new file mode 100644 (file)
index 0000000..075e504
--- /dev/null
@@ -0,0 +1,63 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gif deanimation
+</keywords>
+</info>
+
+<reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+Content-Encoding: gzip\r
+\r
+%hex[%1f%8b%08%00%00%00%00%00%00%03%03%00%00%00%00%00%00%00%00%00]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+Content-Length: 0\r
+\r
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Supposedly compressed gif. No actual data after compression.
+</name>
+<features>
+proxy
+</features>
+<command>
+-H "Accept-Encoding: gzip" http://%HOSTIP:%HTTPPORT/deanimate-gif/last-frame/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /deanimate-gif/last-frame/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Accept-Encoding: gzip\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gif-deanimation/data/test18 b/tests/cts/gif-deanimation/data/test18
new file mode 100644 (file)
index 0000000..adb2483
--- /dev/null
@@ -0,0 +1,64 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gif deanimation
+</keywords>
+</info>
+
+<reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+Content-Encoding: gzip\r
+\r
+%hex[%1f%8b%08%08%35%d6%22%60%00%03%61%6e%69%6d%61%74%69%6f%6e%2d%77%69%74%68%6f%75%74%2d%63%6f%6d%6d%65%6e%74%2e%67%69%66%00%73%f7%74%b3%b0%4c%14%61%10%61%68%60%62%f8%c7%c0%20%e7%f4%4e%f1%3f%b7%9f%6b%48%b0%b3%63%80%ab%91%9e%01%33%23%03%03%83%e2%4f%16%06%2e%86%ff%0c%3a%40%36%03%48%31%03%93%60%4f%ff%ca%d3%6f%f9%17%cf%d9%72%ab%7b%f3%bd%3d%bf%d7%8b%62%55%d5%82%a1%ca%1a%00%1f%8e%7e%77%73%00%00%00]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+Content-Length: 58\r
+\r
+%hex[%47%49%46%38%39%61%14%00%14%00%80%02%00%fe%00%00%1e%42%ee%21%f9%04%00%0a%00%ff%00%2c%00%00%00%00%14%00%14%00%00%02%11%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%af%15%00%3b]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Compressed gif. Valid data.
+</name>
+<features>
+proxy
+</features>
+<command>
+-H "Accept-Encoding: gzip" http://%HOSTIP:%HTTPPORT/deanimate-gif/last-frame/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /deanimate-gif/last-frame/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Accept-Encoding: gzip\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gif-deanimation/data/test19 b/tests/cts/gif-deanimation/data/test19
new file mode 100644 (file)
index 0000000..245bd5d
--- /dev/null
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gif deanimation
+</keywords>
+</info>
+
+<reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+\r
+%hex[%47%49%46%38%39%61%ea%00%3c%00%f0%00%00%00%2c%ff%00%00%00%21%f9%04%00%64%00%00%00%21%ff%0b%4e%45%54%53%43%41%50%45%32%2e%30%03%01%ff%00%00%2c%00%00%00%00%ea%00%3c%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%2c%00%00%00%00%ea%00%3c%00%80%00%00%00%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%2c%00%00%00%00%ea%00%3c%00%80%ff%00%50%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%2c%00%00%00%00%ea%00%3c%00%80%00%f0%ff%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%2c%00%00%00%00%ea%00%3c%00%80%66%ff%00%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%2c%00%00%00%00%ea%00%3c%00%80%ff%a8%00%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%2c%00%00%00%00%ea%00%3c%00%80%ff%24%00%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%2c%00%00%00%00%ea%00%3c%00%80%49%00%ff%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%2c%00%00%00%00%ea%00%3c%00%80%00%ff%f8%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%2c%00%00%00%00%ea%00%3c%00%80%00%ff%66%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%3b]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+Content-Length: 189\r
+\r
+%hex[%47%49%46%38%39%61%ea%00%3c%00%f0%00%00%00%2c%ff%00%00%00%21%f9%04%00%64%00%00%00%2c%00%00%00%00%ea%00%3c%00%80%00%ff%66%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%3b]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Valid gif. Multiple frames. Choosing the last one.
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/deanimate-gif/last-frame/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /deanimate-gif/last-frame/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gif-deanimation/data/test2 b/tests/cts/gif-deanimation/data/test2
new file mode 100644 (file)
index 0000000..66d6b87
--- /dev/null
@@ -0,0 +1,58 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gif deanimation
+</keywords>
+</info>
+
+<reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 502 Server or forwarder response invalid\r
+Content-Type: text/plain\r
+Connection: close\r
+\r
+Bad response. The server or forwarder response doesn't look like HTTP.
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+No actual content sent by the server.
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/deanimate-gif/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /deanimate-gif/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gif-deanimation/data/test20 b/tests/cts/gif-deanimation/data/test20
new file mode 100644 (file)
index 0000000..6a4278b
--- /dev/null
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gif deanimation
+</keywords>
+</info>
+
+<reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+\r
+%hex[%47%49%46%38%39%61%ea%00%3c%00%f0%00%00%00%2c%ff%00%00%00%21%f9%04%00%64%00%00%00%21%ff%0b%4e%45%54%53%43%41%50%45%32%2e%30%03%01%ff%00%00%2c%00%00%00%00%ea%00%3c%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%2c%00%00%00%00%ea%00%3c%00%80%00%00%00%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%2c%00%00%00%00%ea%00%3c%00%80%ff%00%50%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%2c%00%00%00%00%ea%00%3c%00%80%00%f0%ff%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%2c%00%00%00%00%ea%00%3c%00%80%66%ff%00%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%2c%00%00%00%00%ea%00%3c%00%80%ff%a8%00%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%2c%00%00%00%00%ea%00%3c%00%80%ff%24%00%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%2c%00%00%00%00%ea%00%3c%00%80%49%00%ff%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%2c%00%00%00%00%ea%00%3c%00%80%00%ff%f8%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%2c%00%00%00%00%ea%00%3c%00%80%00%ff%66%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%3b]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+Content-Length: 183\r
+\r
+%hex[%47%49%46%38%39%61%ea%00%3c%00%f0%00%00%00%2c%ff%00%00%00%21%f9%04%00%64%00%00%00%2c%00%00%00%00%ea%00%3c%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%3b]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Valid gif. Multiple frames. Choosing the first one.
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/deanimate-gif/first-frame/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /deanimate-gif/first-frame/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gif-deanimation/data/test21 b/tests/cts/gif-deanimation/data/test21
new file mode 100644 (file)
index 0000000..5050bf4
--- /dev/null
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gif deanimation
+</keywords>
+</info>
+
+<reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+\r
+%hex[%47%49%46%38%39%61%ea%00%3c%00%f0%00%00%00%2c%ff%00%00%00%21%f9%04%00%64%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%ff%0b%4e%45%54%53%43%41%50%45%32%2e%30%03%01%ff%00%00%21%ff%0b%49%43%43%52%47%42%47%31%30%31%32%ff%00%00%02%a0%6c%63%6d%73%04%30%00%00%6d%6e%74%72%52%47%42%20%58%59%5a%20%07%e5%00%02%00%0a%00%0a%00%0c%00%34%61%63%73%70%41%50%50%4c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%6c%63%6d%73%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0d%64%65%73%63%00%00%01%20%00%00%00%40%63%70%72%74%00%00%01%60%00%00%00%36%77%74%70%74%00%00%01%98%00%00%00%14%63%68%61%64%00%00%01%ac%00%00%00%2c%72%58%59%5a%00%00%01%d8%00%00%00%14%62%58%59%5a%00%00%01%ec%00%00%00%14%67%58%59%5a%00%00%02%00%00%00%00%14%72%54%52%43%00%00%02%14%00%00%00%20%67%54%52%43%00%00%02%14%00%00%00%20%62%54%52%43%00%00%02%14%00%00%00%20%63%68%72%ff%6d%00%00%02%34%00%00%00%24%64%6d%6e%64%00%00%02%58%00%00%00%24%64%6d%64%64%00%00%02%7c%00%00%00%24%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%24%00%00%00%1c%00%47%00%49%00%4d%00%50%00%20%00%62%00%75%00%69%00%6c%00%74%00%2d%00%69%00%6e%00%20%00%73%00%52%00%47%00%42%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%1a%00%00%00%1c%00%50%00%75%00%62%00%6c%00%69%00%63%00%20%00%44%00%6f%00%6d%00%61%00%69%00%6e%00%00%58%59%5a%20%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%73%66%33%32%00%00%00%00%00%01%0c%42%00%00%05%de%ff%ff%f3%25%00%00%07%93%00%00%fd%90%ff%ff%fb%a1%ff%ff%fd%a2%00%00%03%dc%00%00%c0%6e%58%59%5a%20%00%00%00%00%00%00%6f%a0%00%00%38%f5%00%00%03%90%58%59%5a%20%00%00%00%00%00%00%24%9f%00%00%0f%84%00%00%a2%b6%c4%58%59%5a%20%00%00%00%00%00%00%62%97%00%00%b7%87%00%00%18%d9%70%61%72%61%00%00%00%00%00%03%00%00%00%02%66%66%00%00%f2%a7%00%00%0d%59%00%00%13%d0%00%00%0a%5b%63%68%72%6d%00%00%00%00%00%03%00%00%00%00%a3%d7%00%00%54%7c%00%00%4c%cd%00%00%99%9a%00%00%26%67%00%00%0f%5c%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%47%00%49%00%4d%00%50%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%73%00%52%00%47%00%42%00%2c%00%00%00%00%ea%00%3c%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%ff%0b%49%43%43%52%47%42%47%31%30%31%32%ff%00%00%02%a0%6c%63%6d%73%04%30%00%00%6d%6e%74%72%52%47%42%20%58%59%5a%20%07%e5%00%02%00%0a%00%0a%00%0c%00%34%61%63%73%70%41%50%50%4c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%6c%63%6d%73%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0d%64%65%73%63%00%00%01%20%00%00%00%40%63%70%72%74%00%00%01%60%00%00%00%36%77%74%70%74%00%00%01%98%00%00%00%14%63%68%61%64%00%00%01%ac%00%00%00%2c%72%58%59%5a%00%00%01%d8%00%00%00%14%62%58%59%5a%00%00%01%ec%00%00%00%14%67%58%59%5a%00%00%02%00%00%00%00%14%72%54%52%43%00%00%02%14%00%00%00%20%67%54%52%43%00%00%02%14%00%00%00%20%62%54%52%43%00%00%02%14%00%00%00%20%63%68%72%ff%6d%00%00%02%34%00%00%00%24%64%6d%6e%64%00%00%02%58%00%00%00%24%64%6d%64%64%00%00%02%7c%00%00%00%24%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%24%00%00%00%1c%00%47%00%49%00%4d%00%50%00%20%00%62%00%75%00%69%00%6c%00%74%00%2d%00%69%00%6e%00%20%00%73%00%52%00%47%00%42%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%1a%00%00%00%1c%00%50%00%75%00%62%00%6c%00%69%00%63%00%20%00%44%00%6f%00%6d%00%61%00%69%00%6e%00%00%58%59%5a%20%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%73%66%33%32%00%00%00%00%00%01%0c%42%00%00%05%de%ff%ff%f3%25%00%00%07%93%00%00%fd%90%ff%ff%fb%a1%ff%ff%fd%a2%00%00%03%dc%00%00%c0%6e%58%59%5a%20%00%00%00%00%00%00%6f%a0%00%00%38%f5%00%00%03%90%58%59%5a%20%00%00%00%00%00%00%24%9f%00%00%0f%84%00%00%a2%b6%c4%58%59%5a%20%00%00%00%00%00%00%62%97%00%00%b7%87%00%00%18%d9%70%61%72%61%00%00%00%00%00%03%00%00%00%02%66%66%00%00%f2%a7%00%00%0d%59%00%00%13%d0%00%00%0a%5b%63%68%72%6d%00%00%00%00%00%03%00%00%00%00%a3%d7%00%00%54%7c%00%00%4c%cd%00%00%99%9a%00%00%26%67%00%00%0f%5c%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%47%00%49%00%4d%00%50%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%73%00%52%00%47%00%42%00%2c%00%00%00%00%ea%00%3c%00%80%00%00%00%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%ff%0b%49%43%43%52%47%42%47%31%30%31%32%ff%00%00%02%a0%6c%63%6d%73%04%30%00%00%6d%6e%74%72%52%47%42%20%58%59%5a%20%07%e5%00%02%00%0a%00%0a%00%0c%00%34%61%63%73%70%41%50%50%4c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%6c%63%6d%73%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0d%64%65%73%63%00%00%01%20%00%00%00%40%63%70%72%74%00%00%01%60%00%00%00%36%77%74%70%74%00%00%01%98%00%00%00%14%63%68%61%64%00%00%01%ac%00%00%00%2c%72%58%59%5a%00%00%01%d8%00%00%00%14%62%58%59%5a%00%00%01%ec%00%00%00%14%67%58%59%5a%00%00%02%00%00%00%00%14%72%54%52%43%00%00%02%14%00%00%00%20%67%54%52%43%00%00%02%14%00%00%00%20%62%54%52%43%00%00%02%14%00%00%00%20%63%68%72%ff%6d%00%00%02%34%00%00%00%24%64%6d%6e%64%00%00%02%58%00%00%00%24%64%6d%64%64%00%00%02%7c%00%00%00%24%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%24%00%00%00%1c%00%47%00%49%00%4d%00%50%00%20%00%62%00%75%00%69%00%6c%00%74%00%2d%00%69%00%6e%00%20%00%73%00%52%00%47%00%42%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%1a%00%00%00%1c%00%50%00%75%00%62%00%6c%00%69%00%63%00%20%00%44%00%6f%00%6d%00%61%00%69%00%6e%00%00%58%59%5a%20%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%73%66%33%32%00%00%00%00%00%01%0c%42%00%00%05%de%ff%ff%f3%25%00%00%07%93%00%00%fd%90%ff%ff%fb%a1%ff%ff%fd%a2%00%00%03%dc%00%00%c0%6e%58%59%5a%20%00%00%00%00%00%00%6f%a0%00%00%38%f5%00%00%03%90%58%59%5a%20%00%00%00%00%00%00%24%9f%00%00%0f%84%00%00%a2%b6%c4%58%59%5a%20%00%00%00%00%00%00%62%97%00%00%b7%87%00%00%18%d9%70%61%72%61%00%00%00%00%00%03%00%00%00%02%66%66%00%00%f2%a7%00%00%0d%59%00%00%13%d0%00%00%0a%5b%63%68%72%6d%00%00%00%00%00%03%00%00%00%00%a3%d7%00%00%54%7c%00%00%4c%cd%00%00%99%9a%00%00%26%67%00%00%0f%5c%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%47%00%49%00%4d%00%50%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%73%00%52%00%47%00%42%00%2c%00%00%00%00%ea%00%3c%00%80%ff%00%50%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%ff%0b%49%43%43%52%47%42%47%31%30%31%32%ff%00%00%02%a0%6c%63%6d%73%04%30%00%00%6d%6e%74%72%52%47%42%20%58%59%5a%20%07%e5%00%02%00%0a%00%0a%00%0c%00%34%61%63%73%70%41%50%50%4c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%6c%63%6d%73%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0d%64%65%73%63%00%00%01%20%00%00%00%40%63%70%72%74%00%00%01%60%00%00%00%36%77%74%70%74%00%00%01%98%00%00%00%14%63%68%61%64%00%00%01%ac%00%00%00%2c%72%58%59%5a%00%00%01%d8%00%00%00%14%62%58%59%5a%00%00%01%ec%00%00%00%14%67%58%59%5a%00%00%02%00%00%00%00%14%72%54%52%43%00%00%02%14%00%00%00%20%67%54%52%43%00%00%02%14%00%00%00%20%62%54%52%43%00%00%02%14%00%00%00%20%63%68%72%ff%6d%00%00%02%34%00%00%00%24%64%6d%6e%64%00%00%02%58%00%00%00%24%64%6d%64%64%00%00%02%7c%00%00%00%24%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%24%00%00%00%1c%00%47%00%49%00%4d%00%50%00%20%00%62%00%75%00%69%00%6c%00%74%00%2d%00%69%00%6e%00%20%00%73%00%52%00%47%00%42%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%1a%00%00%00%1c%00%50%00%75%00%62%00%6c%00%69%00%63%00%20%00%44%00%6f%00%6d%00%61%00%69%00%6e%00%00%58%59%5a%20%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%73%66%33%32%00%00%00%00%00%01%0c%42%00%00%05%de%ff%ff%f3%25%00%00%07%93%00%00%fd%90%ff%ff%fb%a1%ff%ff%fd%a2%00%00%03%dc%00%00%c0%6e%58%59%5a%20%00%00%00%00%00%00%6f%a0%00%00%38%f5%00%00%03%90%58%59%5a%20%00%00%00%00%00%00%24%9f%00%00%0f%84%00%00%a2%b6%c4%58%59%5a%20%00%00%00%00%00%00%62%97%00%00%b7%87%00%00%18%d9%70%61%72%61%00%00%00%00%00%03%00%00%00%02%66%66%00%00%f2%a7%00%00%0d%59%00%00%13%d0%00%00%0a%5b%63%68%72%6d%00%00%00%00%00%03%00%00%00%00%a3%d7%00%00%54%7c%00%00%4c%cd%00%00%99%9a%00%00%26%67%00%00%0f%5c%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%47%00%49%00%4d%00%50%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%73%00%52%00%47%00%42%00%2c%00%00%00%00%ea%00%3c%00%80%00%f0%ff%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%ff%0b%49%43%43%52%47%42%47%31%30%31%32%ff%00%00%02%a0%6c%63%6d%73%04%30%00%00%6d%6e%74%72%52%47%42%20%58%59%5a%20%07%e5%00%02%00%0a%00%0a%00%0c%00%34%61%63%73%70%41%50%50%4c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%6c%63%6d%73%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0d%64%65%73%63%00%00%01%20%00%00%00%40%63%70%72%74%00%00%01%60%00%00%00%36%77%74%70%74%00%00%01%98%00%00%00%14%63%68%61%64%00%00%01%ac%00%00%00%2c%72%58%59%5a%00%00%01%d8%00%00%00%14%62%58%59%5a%00%00%01%ec%00%00%00%14%67%58%59%5a%00%00%02%00%00%00%00%14%72%54%52%43%00%00%02%14%00%00%00%20%67%54%52%43%00%00%02%14%00%00%00%20%62%54%52%43%00%00%02%14%00%00%00%20%63%68%72%ff%6d%00%00%02%34%00%00%00%24%64%6d%6e%64%00%00%02%58%00%00%00%24%64%6d%64%64%00%00%02%7c%00%00%00%24%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%24%00%00%00%1c%00%47%00%49%00%4d%00%50%00%20%00%62%00%75%00%69%00%6c%00%74%00%2d%00%69%00%6e%00%20%00%73%00%52%00%47%00%42%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%1a%00%00%00%1c%00%50%00%75%00%62%00%6c%00%69%00%63%00%20%00%44%00%6f%00%6d%00%61%00%69%00%6e%00%00%58%59%5a%20%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%73%66%33%32%00%00%00%00%00%01%0c%42%00%00%05%de%ff%ff%f3%25%00%00%07%93%00%00%fd%90%ff%ff%fb%a1%ff%ff%fd%a2%00%00%03%dc%00%00%c0%6e%58%59%5a%20%00%00%00%00%00%00%6f%a0%00%00%38%f5%00%00%03%90%58%59%5a%20%00%00%00%00%00%00%24%9f%00%00%0f%84%00%00%a2%b6%c4%58%59%5a%20%00%00%00%00%00%00%62%97%00%00%b7%87%00%00%18%d9%70%61%72%61%00%00%00%00%00%03%00%00%00%02%66%66%00%00%f2%a7%00%00%0d%59%00%00%13%d0%00%00%0a%5b%63%68%72%6d%00%00%00%00%00%03%00%00%00%00%a3%d7%00%00%54%7c%00%00%4c%cd%00%00%99%9a%00%00%26%67%00%00%0f%5c%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%47%00%49%00%4d%00%50%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%73%00%52%00%47%00%42%00%2c%00%00%00%00%ea%00%3c%00%80%66%ff%00%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%ff%0b%49%43%43%52%47%42%47%31%30%31%32%ff%00%00%02%a0%6c%63%6d%73%04%30%00%00%6d%6e%74%72%52%47%42%20%58%59%5a%20%07%e5%00%02%00%0a%00%0a%00%0c%00%34%61%63%73%70%41%50%50%4c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%6c%63%6d%73%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0d%64%65%73%63%00%00%01%20%00%00%00%40%63%70%72%74%00%00%01%60%00%00%00%36%77%74%70%74%00%00%01%98%00%00%00%14%63%68%61%64%00%00%01%ac%00%00%00%2c%72%58%59%5a%00%00%01%d8%00%00%00%14%62%58%59%5a%00%00%01%ec%00%00%00%14%67%58%59%5a%00%00%02%00%00%00%00%14%72%54%52%43%00%00%02%14%00%00%00%20%67%54%52%43%00%00%02%14%00%00%00%20%62%54%52%43%00%00%02%14%00%00%00%20%63%68%72%ff%6d%00%00%02%34%00%00%00%24%64%6d%6e%64%00%00%02%58%00%00%00%24%64%6d%64%64%00%00%02%7c%00%00%00%24%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%24%00%00%00%1c%00%47%00%49%00%4d%00%50%00%20%00%62%00%75%00%69%00%6c%00%74%00%2d%00%69%00%6e%00%20%00%73%00%52%00%47%00%42%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%1a%00%00%00%1c%00%50%00%75%00%62%00%6c%00%69%00%63%00%20%00%44%00%6f%00%6d%00%61%00%69%00%6e%00%00%58%59%5a%20%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%73%66%33%32%00%00%00%00%00%01%0c%42%00%00%05%de%ff%ff%f3%25%00%00%07%93%00%00%fd%90%ff%ff%fb%a1%ff%ff%fd%a2%00%00%03%dc%00%00%c0%6e%58%59%5a%20%00%00%00%00%00%00%6f%a0%00%00%38%f5%00%00%03%90%58%59%5a%20%00%00%00%00%00%00%24%9f%00%00%0f%84%00%00%a2%b6%c4%58%59%5a%20%00%00%00%00%00%00%62%97%00%00%b7%87%00%00%18%d9%70%61%72%61%00%00%00%00%00%03%00%00%00%02%66%66%00%00%f2%a7%00%00%0d%59%00%00%13%d0%00%00%0a%5b%63%68%72%6d%00%00%00%00%00%03%00%00%00%00%a3%d7%00%00%54%7c%00%00%4c%cd%00%00%99%9a%00%00%26%67%00%00%0f%5c%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%47%00%49%00%4d%00%50%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%73%00%52%00%47%00%42%00%2c%00%00%00%00%ea%00%3c%00%80%ff%a8%00%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%ff%0b%49%43%43%52%47%42%47%31%30%31%32%ff%00%00%02%a0%6c%63%6d%73%04%30%00%00%6d%6e%74%72%52%47%42%20%58%59%5a%20%07%e5%00%02%00%0a%00%0a%00%0c%00%34%61%63%73%70%41%50%50%4c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%6c%63%6d%73%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0d%64%65%73%63%00%00%01%20%00%00%00%40%63%70%72%74%00%00%01%60%00%00%00%36%77%74%70%74%00%00%01%98%00%00%00%14%63%68%61%64%00%00%01%ac%00%00%00%2c%72%58%59%5a%00%00%01%d8%00%00%00%14%62%58%59%5a%00%00%01%ec%00%00%00%14%67%58%59%5a%00%00%02%00%00%00%00%14%72%54%52%43%00%00%02%14%00%00%00%20%67%54%52%43%00%00%02%14%00%00%00%20%62%54%52%43%00%00%02%14%00%00%00%20%63%68%72%ff%6d%00%00%02%34%00%00%00%24%64%6d%6e%64%00%00%02%58%00%00%00%24%64%6d%64%64%00%00%02%7c%00%00%00%24%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%24%00%00%00%1c%00%47%00%49%00%4d%00%50%00%20%00%62%00%75%00%69%00%6c%00%74%00%2d%00%69%00%6e%00%20%00%73%00%52%00%47%00%42%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%1a%00%00%00%1c%00%50%00%75%00%62%00%6c%00%69%00%63%00%20%00%44%00%6f%00%6d%00%61%00%69%00%6e%00%00%58%59%5a%20%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%73%66%33%32%00%00%00%00%00%01%0c%42%00%00%05%de%ff%ff%f3%25%00%00%07%93%00%00%fd%90%ff%ff%fb%a1%ff%ff%fd%a2%00%00%03%dc%00%00%c0%6e%58%59%5a%20%00%00%00%00%00%00%6f%a0%00%00%38%f5%00%00%03%90%58%59%5a%20%00%00%00%00%00%00%24%9f%00%00%0f%84%00%00%a2%b6%c4%58%59%5a%20%00%00%00%00%00%00%62%97%00%00%b7%87%00%00%18%d9%70%61%72%61%00%00%00%00%00%03%00%00%00%02%66%66%00%00%f2%a7%00%00%0d%59%00%00%13%d0%00%00%0a%5b%63%68%72%6d%00%00%00%00%00%03%00%00%00%00%a3%d7%00%00%54%7c%00%00%4c%cd%00%00%99%9a%00%00%26%67%00%00%0f%5c%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%47%00%49%00%4d%00%50%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%73%00%52%00%47%00%42%00%2c%00%00%00%00%ea%00%3c%00%80%ff%24%00%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%ff%0b%49%43%43%52%47%42%47%31%30%31%32%ff%00%00%02%a0%6c%63%6d%73%04%30%00%00%6d%6e%74%72%52%47%42%20%58%59%5a%20%07%e5%00%02%00%0a%00%0a%00%0c%00%34%61%63%73%70%41%50%50%4c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%6c%63%6d%73%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0d%64%65%73%63%00%00%01%20%00%00%00%40%63%70%72%74%00%00%01%60%00%00%00%36%77%74%70%74%00%00%01%98%00%00%00%14%63%68%61%64%00%00%01%ac%00%00%00%2c%72%58%59%5a%00%00%01%d8%00%00%00%14%62%58%59%5a%00%00%01%ec%00%00%00%14%67%58%59%5a%00%00%02%00%00%00%00%14%72%54%52%43%00%00%02%14%00%00%00%20%67%54%52%43%00%00%02%14%00%00%00%20%62%54%52%43%00%00%02%14%00%00%00%20%63%68%72%ff%6d%00%00%02%34%00%00%00%24%64%6d%6e%64%00%00%02%58%00%00%00%24%64%6d%64%64%00%00%02%7c%00%00%00%24%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%24%00%00%00%1c%00%47%00%49%00%4d%00%50%00%20%00%62%00%75%00%69%00%6c%00%74%00%2d%00%69%00%6e%00%20%00%73%00%52%00%47%00%42%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%1a%00%00%00%1c%00%50%00%75%00%62%00%6c%00%69%00%63%00%20%00%44%00%6f%00%6d%00%61%00%69%00%6e%00%00%58%59%5a%20%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%73%66%33%32%00%00%00%00%00%01%0c%42%00%00%05%de%ff%ff%f3%25%00%00%07%93%00%00%fd%90%ff%ff%fb%a1%ff%ff%fd%a2%00%00%03%dc%00%00%c0%6e%58%59%5a%20%00%00%00%00%00%00%6f%a0%00%00%38%f5%00%00%03%90%58%59%5a%20%00%00%00%00%00%00%24%9f%00%00%0f%84%00%00%a2%b6%c4%58%59%5a%20%00%00%00%00%00%00%62%97%00%00%b7%87%00%00%18%d9%70%61%72%61%00%00%00%00%00%03%00%00%00%02%66%66%00%00%f2%a7%00%00%0d%59%00%00%13%d0%00%00%0a%5b%63%68%72%6d%00%00%00%00%00%03%00%00%00%00%a3%d7%00%00%54%7c%00%00%4c%cd%00%00%99%9a%00%00%26%67%00%00%0f%5c%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%47%00%49%00%4d%00%50%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%73%00%52%00%47%00%42%00%2c%00%00%00%00%ea%00%3c%00%80%49%00%ff%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%ff%0b%49%43%43%52%47%42%47%31%30%31%32%ff%00%00%02%a0%6c%63%6d%73%04%30%00%00%6d%6e%74%72%52%47%42%20%58%59%5a%20%07%e5%00%02%00%0a%00%0a%00%0c%00%34%61%63%73%70%41%50%50%4c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%6c%63%6d%73%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0d%64%65%73%63%00%00%01%20%00%00%00%40%63%70%72%74%00%00%01%60%00%00%00%36%77%74%70%74%00%00%01%98%00%00%00%14%63%68%61%64%00%00%01%ac%00%00%00%2c%72%58%59%5a%00%00%01%d8%00%00%00%14%62%58%59%5a%00%00%01%ec%00%00%00%14%67%58%59%5a%00%00%02%00%00%00%00%14%72%54%52%43%00%00%02%14%00%00%00%20%67%54%52%43%00%00%02%14%00%00%00%20%62%54%52%43%00%00%02%14%00%00%00%20%63%68%72%ff%6d%00%00%02%34%00%00%00%24%64%6d%6e%64%00%00%02%58%00%00%00%24%64%6d%64%64%00%00%02%7c%00%00%00%24%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%24%00%00%00%1c%00%47%00%49%00%4d%00%50%00%20%00%62%00%75%00%69%00%6c%00%74%00%2d%00%69%00%6e%00%20%00%73%00%52%00%47%00%42%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%1a%00%00%00%1c%00%50%00%75%00%62%00%6c%00%69%00%63%00%20%00%44%00%6f%00%6d%00%61%00%69%00%6e%00%00%58%59%5a%20%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%73%66%33%32%00%00%00%00%00%01%0c%42%00%00%05%de%ff%ff%f3%25%00%00%07%93%00%00%fd%90%ff%ff%fb%a1%ff%ff%fd%a2%00%00%03%dc%00%00%c0%6e%58%59%5a%20%00%00%00%00%00%00%6f%a0%00%00%38%f5%00%00%03%90%58%59%5a%20%00%00%00%00%00%00%24%9f%00%00%0f%84%00%00%a2%b6%c4%58%59%5a%20%00%00%00%00%00%00%62%97%00%00%b7%87%00%00%18%d9%70%61%72%61%00%00%00%00%00%03%00%00%00%02%66%66%00%00%f2%a7%00%00%0d%59%00%00%13%d0%00%00%0a%5b%63%68%72%6d%00%00%00%00%00%03%00%00%00%00%a3%d7%00%00%54%7c%00%00%4c%cd%00%00%99%9a%00%00%26%67%00%00%0f%5c%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%47%00%49%00%4d%00%50%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%73%00%52%00%47%00%42%00%2c%00%00%00%00%ea%00%3c%00%80%00%ff%f8%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%ff%0b%49%43%43%52%47%42%47%31%30%31%32%ff%00%00%02%a0%6c%63%6d%73%04%30%00%00%6d%6e%74%72%52%47%42%20%58%59%5a%20%07%e5%00%02%00%0a%00%0a%00%0c%00%34%61%63%73%70%41%50%50%4c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%6c%63%6d%73%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0d%64%65%73%63%00%00%01%20%00%00%00%40%63%70%72%74%00%00%01%60%00%00%00%36%77%74%70%74%00%00%01%98%00%00%00%14%63%68%61%64%00%00%01%ac%00%00%00%2c%72%58%59%5a%00%00%01%d8%00%00%00%14%62%58%59%5a%00%00%01%ec%00%00%00%14%67%58%59%5a%00%00%02%00%00%00%00%14%72%54%52%43%00%00%02%14%00%00%00%20%67%54%52%43%00%00%02%14%00%00%00%20%62%54%52%43%00%00%02%14%00%00%00%20%63%68%72%ff%6d%00%00%02%34%00%00%00%24%64%6d%6e%64%00%00%02%58%00%00%00%24%64%6d%64%64%00%00%02%7c%00%00%00%24%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%24%00%00%00%1c%00%47%00%49%00%4d%00%50%00%20%00%62%00%75%00%69%00%6c%00%74%00%2d%00%69%00%6e%00%20%00%73%00%52%00%47%00%42%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%1a%00%00%00%1c%00%50%00%75%00%62%00%6c%00%69%00%63%00%20%00%44%00%6f%00%6d%00%61%00%69%00%6e%00%00%58%59%5a%20%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%73%66%33%32%00%00%00%00%00%01%0c%42%00%00%05%de%ff%ff%f3%25%00%00%07%93%00%00%fd%90%ff%ff%fb%a1%ff%ff%fd%a2%00%00%03%dc%00%00%c0%6e%58%59%5a%20%00%00%00%00%00%00%6f%a0%00%00%38%f5%00%00%03%90%58%59%5a%20%00%00%00%00%00%00%24%9f%00%00%0f%84%00%00%a2%b6%c4%58%59%5a%20%00%00%00%00%00%00%62%97%00%00%b7%87%00%00%18%d9%70%61%72%61%00%00%00%00%00%03%00%00%00%02%66%66%00%00%f2%a7%00%00%0d%59%00%00%13%d0%00%00%0a%5b%63%68%72%6d%00%00%00%00%00%03%00%00%00%00%a3%d7%00%00%54%7c%00%00%4c%cd%00%00%99%9a%00%00%26%67%00%00%0f%5c%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%47%00%49%00%4d%00%50%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%73%00%52%00%47%00%42%00%2c%00%00%00%00%ea%00%3c%00%80%00%ff%66%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%3b]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+Content-Length: 189\r
+\r
+%hex[%47%49%46%38%39%61%ea%00%3c%00%f0%00%00%00%2c%ff%00%00%00%21%f9%04%00%64%00%00%00%2c%00%00%00%00%ea%00%3c%00%80%00%ff%66%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%3b]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Valid gif. Multiple frames. Lots of meta data. Choosing the last frame.
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/deanimate-gif/last-frame/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /deanimate-gif/last-frame/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gif-deanimation/data/test22 b/tests/cts/gif-deanimation/data/test22
new file mode 100644 (file)
index 0000000..80a7404
--- /dev/null
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gif deanimation
+</keywords>
+</info>
+
+<reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+\r
+%hex[%47%49%46%38%39%61%ea%00%3c%00%f0%00%00%00%2c%ff%00%00%00%21%f9%04%00%64%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%ff%0b%4e%45%54%53%43%41%50%45%32%2e%30%03%01%ff%00%00%21%ff%0b%49%43%43%52%47%42%47%31%30%31%32%ff%00%00%02%a0%6c%63%6d%73%04%30%00%00%6d%6e%74%72%52%47%42%20%58%59%5a%20%07%e5%00%02%00%0a%00%0a%00%0c%00%34%61%63%73%70%41%50%50%4c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%6c%63%6d%73%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0d%64%65%73%63%00%00%01%20%00%00%00%40%63%70%72%74%00%00%01%60%00%00%00%36%77%74%70%74%00%00%01%98%00%00%00%14%63%68%61%64%00%00%01%ac%00%00%00%2c%72%58%59%5a%00%00%01%d8%00%00%00%14%62%58%59%5a%00%00%01%ec%00%00%00%14%67%58%59%5a%00%00%02%00%00%00%00%14%72%54%52%43%00%00%02%14%00%00%00%20%67%54%52%43%00%00%02%14%00%00%00%20%62%54%52%43%00%00%02%14%00%00%00%20%63%68%72%ff%6d%00%00%02%34%00%00%00%24%64%6d%6e%64%00%00%02%58%00%00%00%24%64%6d%64%64%00%00%02%7c%00%00%00%24%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%24%00%00%00%1c%00%47%00%49%00%4d%00%50%00%20%00%62%00%75%00%69%00%6c%00%74%00%2d%00%69%00%6e%00%20%00%73%00%52%00%47%00%42%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%1a%00%00%00%1c%00%50%00%75%00%62%00%6c%00%69%00%63%00%20%00%44%00%6f%00%6d%00%61%00%69%00%6e%00%00%58%59%5a%20%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%73%66%33%32%00%00%00%00%00%01%0c%42%00%00%05%de%ff%ff%f3%25%00%00%07%93%00%00%fd%90%ff%ff%fb%a1%ff%ff%fd%a2%00%00%03%dc%00%00%c0%6e%58%59%5a%20%00%00%00%00%00%00%6f%a0%00%00%38%f5%00%00%03%90%58%59%5a%20%00%00%00%00%00%00%24%9f%00%00%0f%84%00%00%a2%b6%c4%58%59%5a%20%00%00%00%00%00%00%62%97%00%00%b7%87%00%00%18%d9%70%61%72%61%00%00%00%00%00%03%00%00%00%02%66%66%00%00%f2%a7%00%00%0d%59%00%00%13%d0%00%00%0a%5b%63%68%72%6d%00%00%00%00%00%03%00%00%00%00%a3%d7%00%00%54%7c%00%00%4c%cd%00%00%99%9a%00%00%26%67%00%00%0f%5c%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%47%00%49%00%4d%00%50%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%73%00%52%00%47%00%42%00%2c%00%00%00%00%ea%00%3c%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%ff%0b%49%43%43%52%47%42%47%31%30%31%32%ff%00%00%02%a0%6c%63%6d%73%04%30%00%00%6d%6e%74%72%52%47%42%20%58%59%5a%20%07%e5%00%02%00%0a%00%0a%00%0c%00%34%61%63%73%70%41%50%50%4c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%6c%63%6d%73%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0d%64%65%73%63%00%00%01%20%00%00%00%40%63%70%72%74%00%00%01%60%00%00%00%36%77%74%70%74%00%00%01%98%00%00%00%14%63%68%61%64%00%00%01%ac%00%00%00%2c%72%58%59%5a%00%00%01%d8%00%00%00%14%62%58%59%5a%00%00%01%ec%00%00%00%14%67%58%59%5a%00%00%02%00%00%00%00%14%72%54%52%43%00%00%02%14%00%00%00%20%67%54%52%43%00%00%02%14%00%00%00%20%62%54%52%43%00%00%02%14%00%00%00%20%63%68%72%ff%6d%00%00%02%34%00%00%00%24%64%6d%6e%64%00%00%02%58%00%00%00%24%64%6d%64%64%00%00%02%7c%00%00%00%24%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%24%00%00%00%1c%00%47%00%49%00%4d%00%50%00%20%00%62%00%75%00%69%00%6c%00%74%00%2d%00%69%00%6e%00%20%00%73%00%52%00%47%00%42%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%1a%00%00%00%1c%00%50%00%75%00%62%00%6c%00%69%00%63%00%20%00%44%00%6f%00%6d%00%61%00%69%00%6e%00%00%58%59%5a%20%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%73%66%33%32%00%00%00%00%00%01%0c%42%00%00%05%de%ff%ff%f3%25%00%00%07%93%00%00%fd%90%ff%ff%fb%a1%ff%ff%fd%a2%00%00%03%dc%00%00%c0%6e%58%59%5a%20%00%00%00%00%00%00%6f%a0%00%00%38%f5%00%00%03%90%58%59%5a%20%00%00%00%00%00%00%24%9f%00%00%0f%84%00%00%a2%b6%c4%58%59%5a%20%00%00%00%00%00%00%62%97%00%00%b7%87%00%00%18%d9%70%61%72%61%00%00%00%00%00%03%00%00%00%02%66%66%00%00%f2%a7%00%00%0d%59%00%00%13%d0%00%00%0a%5b%63%68%72%6d%00%00%00%00%00%03%00%00%00%00%a3%d7%00%00%54%7c%00%00%4c%cd%00%00%99%9a%00%00%26%67%00%00%0f%5c%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%47%00%49%00%4d%00%50%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%73%00%52%00%47%00%42%00%2c%00%00%00%00%ea%00%3c%00%80%00%00%00%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%ff%0b%49%43%43%52%47%42%47%31%30%31%32%ff%00%00%02%a0%6c%63%6d%73%04%30%00%00%6d%6e%74%72%52%47%42%20%58%59%5a%20%07%e5%00%02%00%0a%00%0a%00%0c%00%34%61%63%73%70%41%50%50%4c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%6c%63%6d%73%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0d%64%65%73%63%00%00%01%20%00%00%00%40%63%70%72%74%00%00%01%60%00%00%00%36%77%74%70%74%00%00%01%98%00%00%00%14%63%68%61%64%00%00%01%ac%00%00%00%2c%72%58%59%5a%00%00%01%d8%00%00%00%14%62%58%59%5a%00%00%01%ec%00%00%00%14%67%58%59%5a%00%00%02%00%00%00%00%14%72%54%52%43%00%00%02%14%00%00%00%20%67%54%52%43%00%00%02%14%00%00%00%20%62%54%52%43%00%00%02%14%00%00%00%20%63%68%72%ff%6d%00%00%02%34%00%00%00%24%64%6d%6e%64%00%00%02%58%00%00%00%24%64%6d%64%64%00%00%02%7c%00%00%00%24%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%24%00%00%00%1c%00%47%00%49%00%4d%00%50%00%20%00%62%00%75%00%69%00%6c%00%74%00%2d%00%69%00%6e%00%20%00%73%00%52%00%47%00%42%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%1a%00%00%00%1c%00%50%00%75%00%62%00%6c%00%69%00%63%00%20%00%44%00%6f%00%6d%00%61%00%69%00%6e%00%00%58%59%5a%20%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%73%66%33%32%00%00%00%00%00%01%0c%42%00%00%05%de%ff%ff%f3%25%00%00%07%93%00%00%fd%90%ff%ff%fb%a1%ff%ff%fd%a2%00%00%03%dc%00%00%c0%6e%58%59%5a%20%00%00%00%00%00%00%6f%a0%00%00%38%f5%00%00%03%90%58%59%5a%20%00%00%00%00%00%00%24%9f%00%00%0f%84%00%00%a2%b6%c4%58%59%5a%20%00%00%00%00%00%00%62%97%00%00%b7%87%00%00%18%d9%70%61%72%61%00%00%00%00%00%03%00%00%00%02%66%66%00%00%f2%a7%00%00%0d%59%00%00%13%d0%00%00%0a%5b%63%68%72%6d%00%00%00%00%00%03%00%00%00%00%a3%d7%00%00%54%7c%00%00%4c%cd%00%00%99%9a%00%00%26%67%00%00%0f%5c%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%47%00%49%00%4d%00%50%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%73%00%52%00%47%00%42%00%2c%00%00%00%00%ea%00%3c%00%80%ff%00%50%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%ff%0b%49%43%43%52%47%42%47%31%30%31%32%ff%00%00%02%a0%6c%63%6d%73%04%30%00%00%6d%6e%74%72%52%47%42%20%58%59%5a%20%07%e5%00%02%00%0a%00%0a%00%0c%00%34%61%63%73%70%41%50%50%4c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%6c%63%6d%73%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0d%64%65%73%63%00%00%01%20%00%00%00%40%63%70%72%74%00%00%01%60%00%00%00%36%77%74%70%74%00%00%01%98%00%00%00%14%63%68%61%64%00%00%01%ac%00%00%00%2c%72%58%59%5a%00%00%01%d8%00%00%00%14%62%58%59%5a%00%00%01%ec%00%00%00%14%67%58%59%5a%00%00%02%00%00%00%00%14%72%54%52%43%00%00%02%14%00%00%00%20%67%54%52%43%00%00%02%14%00%00%00%20%62%54%52%43%00%00%02%14%00%00%00%20%63%68%72%ff%6d%00%00%02%34%00%00%00%24%64%6d%6e%64%00%00%02%58%00%00%00%24%64%6d%64%64%00%00%02%7c%00%00%00%24%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%24%00%00%00%1c%00%47%00%49%00%4d%00%50%00%20%00%62%00%75%00%69%00%6c%00%74%00%2d%00%69%00%6e%00%20%00%73%00%52%00%47%00%42%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%1a%00%00%00%1c%00%50%00%75%00%62%00%6c%00%69%00%63%00%20%00%44%00%6f%00%6d%00%61%00%69%00%6e%00%00%58%59%5a%20%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%73%66%33%32%00%00%00%00%00%01%0c%42%00%00%05%de%ff%ff%f3%25%00%00%07%93%00%00%fd%90%ff%ff%fb%a1%ff%ff%fd%a2%00%00%03%dc%00%00%c0%6e%58%59%5a%20%00%00%00%00%00%00%6f%a0%00%00%38%f5%00%00%03%90%58%59%5a%20%00%00%00%00%00%00%24%9f%00%00%0f%84%00%00%a2%b6%c4%58%59%5a%20%00%00%00%00%00%00%62%97%00%00%b7%87%00%00%18%d9%70%61%72%61%00%00%00%00%00%03%00%00%00%02%66%66%00%00%f2%a7%00%00%0d%59%00%00%13%d0%00%00%0a%5b%63%68%72%6d%00%00%00%00%00%03%00%00%00%00%a3%d7%00%00%54%7c%00%00%4c%cd%00%00%99%9a%00%00%26%67%00%00%0f%5c%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%47%00%49%00%4d%00%50%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%73%00%52%00%47%00%42%00%2c%00%00%00%00%ea%00%3c%00%80%00%f0%ff%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%ff%0b%49%43%43%52%47%42%47%31%30%31%32%ff%00%00%02%a0%6c%63%6d%73%04%30%00%00%6d%6e%74%72%52%47%42%20%58%59%5a%20%07%e5%00%02%00%0a%00%0a%00%0c%00%34%61%63%73%70%41%50%50%4c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%6c%63%6d%73%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0d%64%65%73%63%00%00%01%20%00%00%00%40%63%70%72%74%00%00%01%60%00%00%00%36%77%74%70%74%00%00%01%98%00%00%00%14%63%68%61%64%00%00%01%ac%00%00%00%2c%72%58%59%5a%00%00%01%d8%00%00%00%14%62%58%59%5a%00%00%01%ec%00%00%00%14%67%58%59%5a%00%00%02%00%00%00%00%14%72%54%52%43%00%00%02%14%00%00%00%20%67%54%52%43%00%00%02%14%00%00%00%20%62%54%52%43%00%00%02%14%00%00%00%20%63%68%72%ff%6d%00%00%02%34%00%00%00%24%64%6d%6e%64%00%00%02%58%00%00%00%24%64%6d%64%64%00%00%02%7c%00%00%00%24%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%24%00%00%00%1c%00%47%00%49%00%4d%00%50%00%20%00%62%00%75%00%69%00%6c%00%74%00%2d%00%69%00%6e%00%20%00%73%00%52%00%47%00%42%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%1a%00%00%00%1c%00%50%00%75%00%62%00%6c%00%69%00%63%00%20%00%44%00%6f%00%6d%00%61%00%69%00%6e%00%00%58%59%5a%20%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%73%66%33%32%00%00%00%00%00%01%0c%42%00%00%05%de%ff%ff%f3%25%00%00%07%93%00%00%fd%90%ff%ff%fb%a1%ff%ff%fd%a2%00%00%03%dc%00%00%c0%6e%58%59%5a%20%00%00%00%00%00%00%6f%a0%00%00%38%f5%00%00%03%90%58%59%5a%20%00%00%00%00%00%00%24%9f%00%00%0f%84%00%00%a2%b6%c4%58%59%5a%20%00%00%00%00%00%00%62%97%00%00%b7%87%00%00%18%d9%70%61%72%61%00%00%00%00%00%03%00%00%00%02%66%66%00%00%f2%a7%00%00%0d%59%00%00%13%d0%00%00%0a%5b%63%68%72%6d%00%00%00%00%00%03%00%00%00%00%a3%d7%00%00%54%7c%00%00%4c%cd%00%00%99%9a%00%00%26%67%00%00%0f%5c%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%47%00%49%00%4d%00%50%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%73%00%52%00%47%00%42%00%2c%00%00%00%00%ea%00%3c%00%80%66%ff%00%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%ff%0b%49%43%43%52%47%42%47%31%30%31%32%ff%00%00%02%a0%6c%63%6d%73%04%30%00%00%6d%6e%74%72%52%47%42%20%58%59%5a%20%07%e5%00%02%00%0a%00%0a%00%0c%00%34%61%63%73%70%41%50%50%4c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%6c%63%6d%73%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0d%64%65%73%63%00%00%01%20%00%00%00%40%63%70%72%74%00%00%01%60%00%00%00%36%77%74%70%74%00%00%01%98%00%00%00%14%63%68%61%64%00%00%01%ac%00%00%00%2c%72%58%59%5a%00%00%01%d8%00%00%00%14%62%58%59%5a%00%00%01%ec%00%00%00%14%67%58%59%5a%00%00%02%00%00%00%00%14%72%54%52%43%00%00%02%14%00%00%00%20%67%54%52%43%00%00%02%14%00%00%00%20%62%54%52%43%00%00%02%14%00%00%00%20%63%68%72%ff%6d%00%00%02%34%00%00%00%24%64%6d%6e%64%00%00%02%58%00%00%00%24%64%6d%64%64%00%00%02%7c%00%00%00%24%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%24%00%00%00%1c%00%47%00%49%00%4d%00%50%00%20%00%62%00%75%00%69%00%6c%00%74%00%2d%00%69%00%6e%00%20%00%73%00%52%00%47%00%42%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%1a%00%00%00%1c%00%50%00%75%00%62%00%6c%00%69%00%63%00%20%00%44%00%6f%00%6d%00%61%00%69%00%6e%00%00%58%59%5a%20%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%73%66%33%32%00%00%00%00%00%01%0c%42%00%00%05%de%ff%ff%f3%25%00%00%07%93%00%00%fd%90%ff%ff%fb%a1%ff%ff%fd%a2%00%00%03%dc%00%00%c0%6e%58%59%5a%20%00%00%00%00%00%00%6f%a0%00%00%38%f5%00%00%03%90%58%59%5a%20%00%00%00%00%00%00%24%9f%00%00%0f%84%00%00%a2%b6%c4%58%59%5a%20%00%00%00%00%00%00%62%97%00%00%b7%87%00%00%18%d9%70%61%72%61%00%00%00%00%00%03%00%00%00%02%66%66%00%00%f2%a7%00%00%0d%59%00%00%13%d0%00%00%0a%5b%63%68%72%6d%00%00%00%00%00%03%00%00%00%00%a3%d7%00%00%54%7c%00%00%4c%cd%00%00%99%9a%00%00%26%67%00%00%0f%5c%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%47%00%49%00%4d%00%50%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%73%00%52%00%47%00%42%00%2c%00%00%00%00%ea%00%3c%00%80%ff%a8%00%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%ff%0b%49%43%43%52%47%42%47%31%30%31%32%ff%00%00%02%a0%6c%63%6d%73%04%30%00%00%6d%6e%74%72%52%47%42%20%58%59%5a%20%07%e5%00%02%00%0a%00%0a%00%0c%00%34%61%63%73%70%41%50%50%4c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%6c%63%6d%73%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0d%64%65%73%63%00%00%01%20%00%00%00%40%63%70%72%74%00%00%01%60%00%00%00%36%77%74%70%74%00%00%01%98%00%00%00%14%63%68%61%64%00%00%01%ac%00%00%00%2c%72%58%59%5a%00%00%01%d8%00%00%00%14%62%58%59%5a%00%00%01%ec%00%00%00%14%67%58%59%5a%00%00%02%00%00%00%00%14%72%54%52%43%00%00%02%14%00%00%00%20%67%54%52%43%00%00%02%14%00%00%00%20%62%54%52%43%00%00%02%14%00%00%00%20%63%68%72%ff%6d%00%00%02%34%00%00%00%24%64%6d%6e%64%00%00%02%58%00%00%00%24%64%6d%64%64%00%00%02%7c%00%00%00%24%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%24%00%00%00%1c%00%47%00%49%00%4d%00%50%00%20%00%62%00%75%00%69%00%6c%00%74%00%2d%00%69%00%6e%00%20%00%73%00%52%00%47%00%42%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%1a%00%00%00%1c%00%50%00%75%00%62%00%6c%00%69%00%63%00%20%00%44%00%6f%00%6d%00%61%00%69%00%6e%00%00%58%59%5a%20%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%73%66%33%32%00%00%00%00%00%01%0c%42%00%00%05%de%ff%ff%f3%25%00%00%07%93%00%00%fd%90%ff%ff%fb%a1%ff%ff%fd%a2%00%00%03%dc%00%00%c0%6e%58%59%5a%20%00%00%00%00%00%00%6f%a0%00%00%38%f5%00%00%03%90%58%59%5a%20%00%00%00%00%00%00%24%9f%00%00%0f%84%00%00%a2%b6%c4%58%59%5a%20%00%00%00%00%00%00%62%97%00%00%b7%87%00%00%18%d9%70%61%72%61%00%00%00%00%00%03%00%00%00%02%66%66%00%00%f2%a7%00%00%0d%59%00%00%13%d0%00%00%0a%5b%63%68%72%6d%00%00%00%00%00%03%00%00%00%00%a3%d7%00%00%54%7c%00%00%4c%cd%00%00%99%9a%00%00%26%67%00%00%0f%5c%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%47%00%49%00%4d%00%50%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%73%00%52%00%47%00%42%00%2c%00%00%00%00%ea%00%3c%00%80%ff%24%00%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%ff%0b%49%43%43%52%47%42%47%31%30%31%32%ff%00%00%02%a0%6c%63%6d%73%04%30%00%00%6d%6e%74%72%52%47%42%20%58%59%5a%20%07%e5%00%02%00%0a%00%0a%00%0c%00%34%61%63%73%70%41%50%50%4c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%6c%63%6d%73%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0d%64%65%73%63%00%00%01%20%00%00%00%40%63%70%72%74%00%00%01%60%00%00%00%36%77%74%70%74%00%00%01%98%00%00%00%14%63%68%61%64%00%00%01%ac%00%00%00%2c%72%58%59%5a%00%00%01%d8%00%00%00%14%62%58%59%5a%00%00%01%ec%00%00%00%14%67%58%59%5a%00%00%02%00%00%00%00%14%72%54%52%43%00%00%02%14%00%00%00%20%67%54%52%43%00%00%02%14%00%00%00%20%62%54%52%43%00%00%02%14%00%00%00%20%63%68%72%ff%6d%00%00%02%34%00%00%00%24%64%6d%6e%64%00%00%02%58%00%00%00%24%64%6d%64%64%00%00%02%7c%00%00%00%24%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%24%00%00%00%1c%00%47%00%49%00%4d%00%50%00%20%00%62%00%75%00%69%00%6c%00%74%00%2d%00%69%00%6e%00%20%00%73%00%52%00%47%00%42%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%1a%00%00%00%1c%00%50%00%75%00%62%00%6c%00%69%00%63%00%20%00%44%00%6f%00%6d%00%61%00%69%00%6e%00%00%58%59%5a%20%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%73%66%33%32%00%00%00%00%00%01%0c%42%00%00%05%de%ff%ff%f3%25%00%00%07%93%00%00%fd%90%ff%ff%fb%a1%ff%ff%fd%a2%00%00%03%dc%00%00%c0%6e%58%59%5a%20%00%00%00%00%00%00%6f%a0%00%00%38%f5%00%00%03%90%58%59%5a%20%00%00%00%00%00%00%24%9f%00%00%0f%84%00%00%a2%b6%c4%58%59%5a%20%00%00%00%00%00%00%62%97%00%00%b7%87%00%00%18%d9%70%61%72%61%00%00%00%00%00%03%00%00%00%02%66%66%00%00%f2%a7%00%00%0d%59%00%00%13%d0%00%00%0a%5b%63%68%72%6d%00%00%00%00%00%03%00%00%00%00%a3%d7%00%00%54%7c%00%00%4c%cd%00%00%99%9a%00%00%26%67%00%00%0f%5c%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%47%00%49%00%4d%00%50%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%73%00%52%00%47%00%42%00%2c%00%00%00%00%ea%00%3c%00%80%49%00%ff%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%ff%0b%49%43%43%52%47%42%47%31%30%31%32%ff%00%00%02%a0%6c%63%6d%73%04%30%00%00%6d%6e%74%72%52%47%42%20%58%59%5a%20%07%e5%00%02%00%0a%00%0a%00%0c%00%34%61%63%73%70%41%50%50%4c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%6c%63%6d%73%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0d%64%65%73%63%00%00%01%20%00%00%00%40%63%70%72%74%00%00%01%60%00%00%00%36%77%74%70%74%00%00%01%98%00%00%00%14%63%68%61%64%00%00%01%ac%00%00%00%2c%72%58%59%5a%00%00%01%d8%00%00%00%14%62%58%59%5a%00%00%01%ec%00%00%00%14%67%58%59%5a%00%00%02%00%00%00%00%14%72%54%52%43%00%00%02%14%00%00%00%20%67%54%52%43%00%00%02%14%00%00%00%20%62%54%52%43%00%00%02%14%00%00%00%20%63%68%72%ff%6d%00%00%02%34%00%00%00%24%64%6d%6e%64%00%00%02%58%00%00%00%24%64%6d%64%64%00%00%02%7c%00%00%00%24%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%24%00%00%00%1c%00%47%00%49%00%4d%00%50%00%20%00%62%00%75%00%69%00%6c%00%74%00%2d%00%69%00%6e%00%20%00%73%00%52%00%47%00%42%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%1a%00%00%00%1c%00%50%00%75%00%62%00%6c%00%69%00%63%00%20%00%44%00%6f%00%6d%00%61%00%69%00%6e%00%00%58%59%5a%20%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%73%66%33%32%00%00%00%00%00%01%0c%42%00%00%05%de%ff%ff%f3%25%00%00%07%93%00%00%fd%90%ff%ff%fb%a1%ff%ff%fd%a2%00%00%03%dc%00%00%c0%6e%58%59%5a%20%00%00%00%00%00%00%6f%a0%00%00%38%f5%00%00%03%90%58%59%5a%20%00%00%00%00%00%00%24%9f%00%00%0f%84%00%00%a2%b6%c4%58%59%5a%20%00%00%00%00%00%00%62%97%00%00%b7%87%00%00%18%d9%70%61%72%61%00%00%00%00%00%03%00%00%00%02%66%66%00%00%f2%a7%00%00%0d%59%00%00%13%d0%00%00%0a%5b%63%68%72%6d%00%00%00%00%00%03%00%00%00%00%a3%d7%00%00%54%7c%00%00%4c%cd%00%00%99%9a%00%00%26%67%00%00%0f%5c%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%47%00%49%00%4d%00%50%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%73%00%52%00%47%00%42%00%2c%00%00%00%00%ea%00%3c%00%80%00%ff%f8%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%ff%0b%49%43%43%52%47%42%47%31%30%31%32%ff%00%00%02%a0%6c%63%6d%73%04%30%00%00%6d%6e%74%72%52%47%42%20%58%59%5a%20%07%e5%00%02%00%0a%00%0a%00%0c%00%34%61%63%73%70%41%50%50%4c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%6c%63%6d%73%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0d%64%65%73%63%00%00%01%20%00%00%00%40%63%70%72%74%00%00%01%60%00%00%00%36%77%74%70%74%00%00%01%98%00%00%00%14%63%68%61%64%00%00%01%ac%00%00%00%2c%72%58%59%5a%00%00%01%d8%00%00%00%14%62%58%59%5a%00%00%01%ec%00%00%00%14%67%58%59%5a%00%00%02%00%00%00%00%14%72%54%52%43%00%00%02%14%00%00%00%20%67%54%52%43%00%00%02%14%00%00%00%20%62%54%52%43%00%00%02%14%00%00%00%20%63%68%72%ff%6d%00%00%02%34%00%00%00%24%64%6d%6e%64%00%00%02%58%00%00%00%24%64%6d%64%64%00%00%02%7c%00%00%00%24%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%24%00%00%00%1c%00%47%00%49%00%4d%00%50%00%20%00%62%00%75%00%69%00%6c%00%74%00%2d%00%69%00%6e%00%20%00%73%00%52%00%47%00%42%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%1a%00%00%00%1c%00%50%00%75%00%62%00%6c%00%69%00%63%00%20%00%44%00%6f%00%6d%00%61%00%69%00%6e%00%00%58%59%5a%20%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%73%66%33%32%00%00%00%00%00%01%0c%42%00%00%05%de%ff%ff%f3%25%00%00%07%93%00%00%fd%90%ff%ff%fb%a1%ff%ff%fd%a2%00%00%03%dc%00%00%c0%6e%58%59%5a%20%00%00%00%00%00%00%6f%a0%00%00%38%f5%00%00%03%90%58%59%5a%20%00%00%00%00%00%00%24%9f%00%00%0f%84%00%00%a2%b6%c4%58%59%5a%20%00%00%00%00%00%00%62%97%00%00%b7%87%00%00%18%d9%70%61%72%61%00%00%00%00%00%03%00%00%00%02%66%66%00%00%f2%a7%00%00%0d%59%00%00%13%d0%00%00%0a%5b%63%68%72%6d%00%00%00%00%00%03%00%00%00%00%a3%d7%00%00%54%7c%00%00%4c%cd%00%00%99%9a%00%00%26%67%00%00%0f%5c%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%47%00%49%00%4d%00%50%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%73%00%52%00%47%00%42%00%2c%00%00%00%00%ea%00%3c%00%80%00%ff%66%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%3b]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+Content-Length: 183\r
+\r
+%hex[%47%49%46%38%39%61%ea%00%3c%00%f0%00%00%00%2c%ff%00%00%00%21%f9%04%00%64%00%00%00%2c%00%00%00%00%ea%00%3c%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%3b]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Valid gif. Multiple frames. Lots of meta data. Choosing the first frame.
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/deanimate-gif/first-frame/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /deanimate-gif/first-frame/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gif-deanimation/data/test23 b/tests/cts/gif-deanimation/data/test23
new file mode 100644 (file)
index 0000000..9e117c9
--- /dev/null
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gif deanimation
+</keywords>
+</info>
+
+<reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+\r
+%hex[%47%49%46%38%39%61%ea%00%3c%00%f0%00%00%00%2c%ff%00%00%00%21%f9%04%00%64%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%ff%0b%4e%45%54%53%43%41%50%45%32%2e%30%03%01%ff%00%00%21%ff%0b%49%43%43%52%47%42%47%31%30%31%32%ff%00%00%02%a0%6c%63%6d%73%04%30%00%00%6d%6e%74%72%52%47%42%20%58%59%5a%20%07%e5%00%02%00%0a%00%0a%00%0c%00%34%61%63%73%70%41%50%50%4c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%6c%63%6d%73%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0d%64%65%73%63%00%00%01%20%00%00%00%40%63%70%72%74%00%00%01%60%00%00%00%36%77%74%70%74%00%00%01%98%00%00%00%14%63%68%61%64%00%00%01%ac%00%00%00%2c%72%58%59%5a%00%00%01%d8%00%00%00%14%62%58%59%5a%00%00%01%ec%00%00%00%14%67%58%59%5a%00%00%02%00%00%00%00%14%72%54%52%43%00%00%02%14%00%00%00%20%67%54%52%43%00%00%02%14%00%00%00%20%62%54%52%43%00%00%02%14%00%00%00%20%63%68%72%ff%6d%00%00%02%34%00%00%00%24%64%6d%6e%64%00%00%02%58%00%00%00%24%64%6d%64%64%00%00%02%7c%00%00%00%24%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%24%00%00%00%1c%00%47%00%49%00%4d%00%50%00%20%00%62%00%75%00%69%00%6c%00%74%00%2d%00%69%00%6e%00%20%00%73%00%52%00%47%00%42%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%1a%00%00%00%1c%00%50%00%75%00%62%00%6c%00%69%00%63%00%20%00%44%00%6f%00%6d%00%61%00%69%00%6e%00%00%58%59%5a%20%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%73%66%33%32%00%00%00%00%00%01%0c%42%00%00%05%de%ff%ff%f3%25%00%00%07%93%00%00%fd%90%ff%ff%fb%a1%ff%ff%fd%a2%00%00%03%dc%00%00%c0%6e%58%59%5a%20%00%00%00%00%00%00%6f%a0%00%00%38%f5%00%00%03%90%58%59%5a%20%00%00%00%00%00%00%24%9f%00%00%0f%84%00%00%a2%b6%c4%58%59%5a%20%00%00%00%00%00%00%62%97%00%00%b7%87%00%00%18%d9%70%61%72%61%00%00%00%00%00%03%00%00%00%02%66%66%00%00%f2%a7%00%00%0d%59%00%00%13%d0%00%00%0a%5b%63%68%72%6d%00%00%00%00%00%03%00%00%00%00%a3%d7%00%00%54%7c%00%00%4c%cd%00%00%99%9a%00%00%26%67%00%00%0f%5c%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%47%00%49%00%4d%00%50%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%73%00%52%00%47%00%42%00%2c%00%00%00%00%ea%00%3c%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%ff%0b%49%43%43%52%47%42%47%31%30%31%32%ff%00%00%02%a0%6c%63%6d%73%04%30%00%00%6d%6e%74%72%52%47%42%20%58%59%5a%20%07%e5%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%00%02%00%0a%00%0a%00%0c%00%34%61%63%73%70%41%50%50%4c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%6c%63%6d%73%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0d%64%65%73%63%00%00%01%20%00%00%00%40%63%70%72%74%00%00%01%60%00%00%00%36%77%74%70%74%00%00%01%98%00%00%00%14%63%68%61%64%00%00%01%ac%00%00%00%2c%72%58%59%5a%00%00%01%d8%00%00%00%14%62%58%59%5a%00%00%01%ec%00%00%00%14%67%58%59%5a%00%00%02%00%00%00%00%14%72%54%52%43%00%00%02%14%00%00%00%20%67%54%52%43%00%00%02%14%00%00%00%20%62%54%52%43%00%00%02%14%00%00%00%20%63%68%72%ff%6d%00%00%02%34%00%00%00%24%64%6d%6e%64%00%00%02%58%00%00%00%24%64%6d%64%64%00%00%02%7c%00%00%00%24%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%24%00%00%00%1c%00%47%00%49%00%4d%00%50%00%20%00%62%00%75%00%69%00%6c%00%74%00%2d%00%69%00%6e%00%20%00%73%00%52%00%47%00%42%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%1a%00%00%00%1c%00%50%00%75%00%62%00%6c%00%69%00%63%00%20%00%44%00%6f%00%6d%00%61%00%69%00%6e%00%00%58%59%5a%20%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%73%66%33%32%00%00%00%00%00%01%0c%42%00%00%05%de%ff%ff%f3%25%00%00%07%93%00%00%fd%90%ff%ff%fb%a1%ff%ff%fd%a2%00%00%03%dc%00%00%c0%6e%58%59%5a%20%00%00%00%00%00%00%6f%a0%00%00%38%f5%00%00%03%90%58%59%5a%20%00%00%00%00%00%00%24%9f%00%00%0f%84%00%00%a2%b6%c4%58%59%5a%20%00%00%00%00%00%00%62%97%00%00%b7%87%00%00%18%d9%70%61%72%61%00%00%00%00%00%03%00%00%00%02%66%66%00%00%f2%a7%00%00%0d%59%00%00%13%d0%00%00%0a%5b%63%68%72%6d%00%00%00%00%00%03%00%00%00%00%a3%d7%00%00%54%7c%00%00%4c%cd%00%00%99%9a%00%00%26%67%00%00%0f%5c%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%47%00%49%00%4d%00%50%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%73%00%52%00%47%00%42%00%2c%00%00%00%00%ea%00%3c%00%80%00%00%00%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%ff%0b%49%43%43%52%47%42%47%31%30%31%32%ff%00%00%02%a0%6c%63%6d%73%04%30%00%00%6d%6e%74%72%52%47%42%20%58%59%5a%20%07%e5%00%02%00%0a%00%0a%00%0c%00%34%61%63%73%70%41%50%50%4c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%6c%63%6d%73%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0d%64%65%73%63%00%00%01%20%00%00%00%40%63%70%72%74%00%00%01%60%00%00%00%36%77%74%70%74%00%00%01%98%00%00%00%14%63%68%61%64%00%00%01%ac%00%00%00%2c%72%58%59%5a%00%00%01%d8%00%00%00%14%62%58%59%5a%00%00%01%ec%00%00%00%14%67%58%59%5a%00%00%02%00%00%00%00%14%72%54%52%43%00%00%02%14%00%00%00%20%67%54%52%43%00%00%02%14%00%00%00%20%62%54%52%43%00%00%02%14%00%00%00%20%63%68%72%ff%6d%00%00%02%34%00%00%00%24%64%6d%6e%64%00%00%02%58%00%00%00%24%64%6d%64%64%00%00%02%7c%00%00%00%24%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%24%00%00%00%1c%00%47%00%49%00%4d%00%50%00%20%00%62%00%75%00%69%00%6c%00%74%00%2d%00%69%00%6e%00%20%00%73%00%52%00%47%00%42%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%1a%00%00%00%1c%00%50%00%75%00%62%00%6c%00%69%00%63%00%20%00%44%00%6f%00%6d%00%61%00%69%00%6e%00%00%58%59%5a%20%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%73%66%33%32%00%00%00%00%00%01%0c%42%00%00%05%de%ff%ff%f3%25%00%00%07%93%00%00%fd%90%ff%ff%fb%a1%ff%ff%fd%a2%00%00%03%dc%00%00%c0%6e%58%59%5a%20%00%00%00%00%00%00%6f%a0%00%00%38%f5%00%00%03%90%58%59%5a%20%00%00%00%00%00%00%24%9f%00%00%0f%84%00%00%a2%b6%c4%58%59%5a%20%00%00%00%00%00%00%62%97%00%00%b7%87%00%00%18%d9%70%61%72%61%00%00%00%00%00%03%00%00%00%02%66%66%00%00%f2%a7%00%00%0d%59%00%00%13%d0%00%00%0a%5b%63%68%72%6d%00%00%00%00%00%03%00%00%00%00%a3%d7%00%00%54%7c%00%00%4c%cd%00%00%99%9a%00%00%26%67%00%00%0f%5c%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%47%00%49%00%4d%00%50%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%73%00%52%00%47%00%42%00%2c%00%00%00%00%ea%00%3c%00%80%ff%00%50%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%ff%0b%49%43%43%52%47%42%47%31%30%31%32%ff%00%00%02%a0%6c%63%6d%73%04%30%00%00%6d%6e%74%72%52%47%42%20%58%59%5a%20%07%e5%00%02%00%0a%00%0a%00%0c%00%34%61%63%73%70%41%50%50%4c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%6c%63%6d%73%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0d%64%65%73%63%00%00%01%20%00%00%00%40%63%70%72%74%00%00%01%60%00%00%00%36%77%74%70%74%00%00%01%98%00%00%00%14%63%68%61%64%00%00%01%ac%00%00%00%2c%72%58%59%5a%00%00%01%d8%00%00%00%14%62%58%59%5a%00%00%01%ec%00%00%00%14%67%58%59%5a%00%00%02%00%00%00%00%14%72%54%52%43%00%00%02%14%00%00%00%20%67%54%52%43%00%00%02%14%00%00%00%20%62%54%52%43%00%00%02%14%00%00%00%20%63%68%72%ff%6d%00%00%02%34%00%00%00%24%64%6d%6e%64%00%00%02%58%00%00%00%24%64%6d%64%64%00%00%02%7c%00%00%00%24%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%24%00%00%00%1c%00%47%00%49%00%4d%00%50%00%20%00%62%00%75%00%69%00%6c%00%74%00%2d%00%69%00%6e%00%20%00%73%00%52%00%47%00%42%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%1a%00%00%00%1c%00%50%00%75%00%62%00%6c%00%69%00%63%00%20%00%44%00%6f%00%6d%00%61%00%69%00%6e%00%00%58%59%5a%20%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%73%66%33%32%00%00%00%00%00%01%0c%42%00%00%05%de%ff%ff%f3%25%00%00%07%93%00%00%fd%90%ff%ff%fb%a1%ff%ff%fd%a2%00%00%03%dc%00%00%c0%6e%58%59%5a%20%00%00%00%00%00%00%6f%a0%00%00%38%f5%00%00%03%90%58%59%5a%20%00%00%00%00%00%00%24%9f%00%00%0f%84%00%00%a2%b6%c4%58%59%5a%20%00%00%00%00%00%00%62%97%00%00%b7%87%00%00%18%d9%70%61%72%61%00%00%00%00%00%03%00%00%00%02%66%66%00%00%f2%a7%00%00%0d%59%00%00%13%d0%00%00%0a%5b%63%68%72%6d%00%00%00%00%00%03%00%00%00%00%a3%d7%00%00%54%7c%00%00%4c%cd%00%00%99%9a%00%00%26%67%00%00%0f%5c%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%47%00%49%00%4d%00%50%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%73%00%52%00%47%00%42%00%2c%00%00%00%00%ea%00%3c%00%80%00%f0%ff%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%ff%0b%49%43%43%52%47%42%47%31%30%31%32%ff%00%00%02%a0%6c%63%6d%73%04%30%00%00%6d%6e%74%72%52%47%42%20%58%59%5a%20%07%e5%00%02%00%0a%00%0a%00%0c%00%34%61%63%73%70%41%50%50%4c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%6c%63%6d%73%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0d%64%65%73%63%00%00%01%20%00%00%00%40%63%70%72%74%00%00%01%60%00%00%00%36%77%74%70%74%00%00%01%98%00%00%00%14%63%68%61%64%00%00%01%ac%00%00%00%2c%72%58%59%5a%00%00%01%d8%00%00%00%14%62%58%59%5a%00%00%01%ec%00%00%00%14%67%58%59%5a%00%00%02%00%00%00%00%14%72%54%52%43%00%00%02%14%00%00%00%20%67%54%52%43%00%00%02%14%00%00%00%20%62%54%52%43%00%00%02%14%00%00%00%20%63%68%72%ff%6d%00%00%02%34%00%00%00%24%64%6d%6e%64%00%00%02%58%00%00%00%24%64%6d%64%64%00%00%02%7c%00%00%00%24%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%24%00%00%00%1c%00%47%00%49%00%4d%00%50%00%20%00%62%00%75%00%69%00%6c%00%74%00%2d%00%69%00%6e%00%20%00%73%00%52%00%47%00%42%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%1a%00%00%00%1c%00%50%00%75%00%62%00%6c%00%69%00%63%00%20%00%44%00%6f%00%6d%00%61%00%69%00%6e%00%00%58%59%5a%20%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%73%66%33%32%00%00%00%00%00%01%0c%42%00%00%05%de%ff%ff%f3%25%00%00%07%93%00%00%fd%90%ff%ff%fb%a1%ff%ff%fd%a2%00%00%03%dc%00%00%c0%6e%58%59%5a%20%00%00%00%00%00%00%6f%a0%00%00%38%f5%00%00%03%90%58%59%5a%20%00%00%00%00%00%00%24%9f%00%00%0f%84%00%00%a2%b6%c4%58%59%5a%20%00%00%00%00%00%00%62%97%00%00%b7%87%00%00%18%d9%70%61%72%61%00%00%00%00%00%03%00%00%00%02%66%66%00%00%f2%a7%00%00%0d%59%00%00%13%d0%00%00%0a%5b%63%68%72%6d%00%00%00%00%00%03%00%00%00%00%a3%d7%00%00%54%7c%00%00%4c%cd%00%00%99%9a%00%00%26%67%00%00%0f%5c%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%47%00%49%00%4d%00%50%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%73%00%52%00%47%00%42%00%2c%00%00%00%00%ea%00%3c%00%80%66%ff%00%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%ff%0b%49%43%43%52%47%42%47%31%30%31%32%ff%00%00%02%a0%6c%63%6d%73%04%30%00%00%6d%6e%74%72%52%47%42%20%58%59%5a%20%07%e5%00%02%00%0a%00%0a%00%0c%00%34%61%63%73%70%41%50%50%4c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%6c%63%6d%73%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0d%64%65%73%63%00%00%01%20%00%00%00%40%63%70%72%74%00%00%01%60%00%00%00%36%77%74%70%74%00%00%01%98%00%00%00%14%63%68%61%64%00%00%01%ac%00%00%00%2c%72%58%59%5a%00%00%01%d8%00%00%00%14%62%58%59%5a%00%00%01%ec%00%00%00%14%67%58%59%5a%00%00%02%00%00%00%00%14%72%54%52%43%00%00%02%14%00%00%00%20%67%54%52%43%00%00%02%14%00%00%00%20%62%54%52%43%00%00%02%14%00%00%00%20%63%68%72%ff%6d%00%00%02%34%00%00%00%24%64%6d%6e%64%00%00%02%58%00%00%00%24%64%6d%64%64%00%00%02%7c%00%00%00%24%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%24%00%00%00%1c%00%47%00%49%00%4d%00%50%00%20%00%62%00%75%00%69%00%6c%00%74%00%2d%00%69%00%6e%00%20%00%73%00%52%00%47%00%42%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%1a%00%00%00%1c%00%50%00%75%00%62%00%6c%00%69%00%63%00%20%00%44%00%6f%00%6d%00%61%00%69%00%6e%00%00%58%59%5a%20%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%73%66%33%32%00%00%00%00%00%01%0c%42%00%00%05%de%ff%ff%f3%25%00%00%07%93%00%00%fd%90%ff%ff%fb%a1%ff%ff%fd%a2%00%00%03%dc%00%00%c0%6e%58%59%5a%20%00%00%00%00%00%00%6f%a0%00%00%38%f5%00%00%03%90%58%59%5a%20%00%00%00%00%00%00%24%9f%00%00%0f%84%00%00%a2%b6%c4%58%59%5a%20%00%00%00%00%00%00%62%97%00%00%b7%87%00%00%18%d9%70%61%72%61%00%00%00%00%00%03%00%00%00%02%66%66%00%00%f2%a7%00%00%0d%59%00%00%13%d0%00%00%0a%5b%63%68%72%6d%00%00%00%00%00%03%00%00%00%00%a3%d7%00%00%54%7c%00%00%4c%cd%00%00%99%9a%00%00%26%67%00%00%0f%5c%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%47%00%49%00%4d%00%50%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%73%00%52%00%47%00%42%00%2c%00%00%00%00%ea%00%3c%00%80%ff%a8%00%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%ff%0b%49%43%43%52%47%42%47%31%30%31%32%ff%00%00%02%a0%6c%63%6d%73%04%30%00%00%6d%6e%74%72%52%47%42%20%58%59%5a%20%07%e5%00%02%00%0a%00%0a%00%0c%00%34%61%63%73%70%41%50%50%4c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%6c%63%6d%73%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0d%64%65%73%63%00%00%01%20%00%00%00%40%63%70%72%74%00%00%01%60%00%00%00%36%77%74%70%74%00%00%01%98%00%00%00%14%63%68%61%64%00%00%01%ac%00%00%00%2c%72%58%59%5a%00%00%01%d8%00%00%00%14%62%58%59%5a%00%00%01%ec%00%00%00%14%67%58%59%5a%00%00%02%00%00%00%00%14%72%54%52%43%00%00%02%14%00%00%00%20%67%54%52%43%00%00%02%14%00%00%00%20%62%54%52%43%00%00%02%14%00%00%00%20%63%68%72%ff%6d%00%00%02%34%00%00%00%24%64%6d%6e%64%00%00%02%58%00%00%00%24%64%6d%64%64%00%00%02%7c%00%00%00%24%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%24%00%00%00%1c%00%47%00%49%00%4d%00%50%00%20%00%62%00%75%00%69%00%6c%00%74%00%2d%00%69%00%6e%00%20%00%73%00%52%00%47%00%42%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%1a%00%00%00%1c%00%50%00%75%00%62%00%6c%00%69%00%63%00%20%00%44%00%6f%00%6d%00%61%00%69%00%6e%00%00%58%59%5a%20%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%73%66%33%32%00%00%00%00%00%01%0c%42%00%00%05%de%ff%ff%f3%25%00%00%07%93%00%00%fd%90%ff%ff%fb%a1%ff%ff%fd%a2%00%00%03%dc%00%00%c0%6e%58%59%5a%20%00%00%00%00%00%00%6f%a0%00%00%38%f5%00%00%03%90%58%59%5a%20%00%00%00%00%00%00%24%9f%00%00%0f%84%00%00%a2%b6%c4%58%59%5a%20%00%00%00%00%00%00%62%97%00%00%b7%87%00%00%18%d9%70%61%72%61%00%00%00%00%00%03%00%00%00%02%66%66%00%00%f2%a7%00%00%0d%59%00%00%13%d0%00%00%0a%5b%63%68%72%6d%00%00%00%00%00%03%00%00%00%00%a3%d7%00%00%54%7c%00%00%4c%cd%00%00%99%9a%00%00%26%67%00%00%0f%5c%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%47%00%49%00%4d%00%50%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%73%00%52%00%47%00%42%00%2c%00%00%00%00%ea%00%3c%00%80%ff%24%00%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%ff%0b%49%43%43%52%47%42%47%31%30%31%32%ff%00%00%02%a0%6c%63%6d%73%04%30%00%00%6d%6e%74%72%52%47%42%20%58%59%5a%20%07%e5%00%02%00%0a%00%0a%00%0c%00%34%61%63%73%70%41%50%50%4c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%6c%63%6d%73%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0d%64%65%73%63%00%00%01%20%00%00%00%40%63%70%72%74%00%00%01%60%00%00%00%36%77%74%70%74%00%00%01%98%00%00%00%14%63%68%61%64%00%00%01%ac%00%00%00%2c%72%58%59%5a%00%00%01%d8%00%00%00%14%62%58%59%5a%00%00%01%ec%00%00%00%14%67%58%59%5a%00%00%02%00%00%00%00%14%72%54%52%43%00%00%02%14%00%00%00%20%67%54%52%43%00%00%02%14%00%00%00%20%62%54%52%43%00%00%02%14%00%00%00%20%63%68%72%ff%6d%00%00%02%34%00%00%00%24%64%6d%6e%64%00%00%02%58%00%00%00%24%64%6d%64%64%00%00%02%7c%00%00%00%24%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%24%00%00%00%1c%00%47%00%49%00%4d%00%50%00%20%00%62%00%75%00%69%00%6c%00%74%00%2d%00%69%00%6e%00%20%00%73%00%52%00%47%00%42%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%1a%00%00%00%1c%00%50%00%75%00%62%00%6c%00%69%00%63%00%20%00%44%00%6f%00%6d%00%61%00%69%00%6e%00%00%58%59%5a%20%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%73%66%33%32%00%00%00%00%00%01%0c%42%00%00%05%de%ff%ff%f3%25%00%00%07%93%00%00%fd%90%ff%ff%fb%a1%ff%ff%fd%a2%00%00%03%dc%00%00%c0%6e%58%59%5a%20%00%00%00%00%00%00%6f%a0%00%00%38%f5%00%00%03%90%58%59%5a%20%00%00%00%00%00%00%24%9f%00%00%0f%84%00%00%a2%b6%c4%58%59%5a%20%00%00%00%00%00%00%62%97%00%00%b7%87%00%00%18%d9%70%61%72%61%00%00%00%00%00%03%00%00%00%02%66%66%00%00%f2%a7%00%00%0d%59%00%00%13%d0%00%00%0a%5b%63%68%72%6d%00%00%00%00%00%03%00%00%00%00%a3%d7%00%00%54%7c%00%00%4c%cd%00%00%99%9a%00%00%26%67%00%00%0f%5c%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%47%00%49%00%4d%00%50%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%73%00%52%00%47%00%42%00%2c%00%00%00%00%ea%00%3c%00%80%49%00%ff%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%ff%0b%49%43%43%52%47%42%47%31%30%31%32%ff%00%00%02%a0%6c%63%6d%73%04%30%00%00%6d%6e%74%72%52%47%42%20%58%59%5a%20%07%e5%00%02%00%0a%00%0a%00%0c%00%34%61%63%73%70%41%50%50%4c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%6c%63%6d%73%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0d%64%65%73%63%00%00%01%20%00%00%00%40%63%70%72%74%00%00%01%60%00%00%00%36%77%74%70%74%00%00%01%98%00%00%00%14%63%68%61%64%00%00%01%ac%00%00%00%2c%72%58%59%5a%00%00%01%d8%00%00%00%14%62%58%59%5a%00%00%01%ec%00%00%00%14%67%58%59%5a%00%00%02%00%00%00%00%14%72%54%52%43%00%00%02%14%00%00%00%20%67%54%52%43%00%00%02%14%00%00%00%20%62%54%52%43%00%00%02%14%00%00%00%20%63%68%72%ff%6d%00%00%02%34%00%00%00%24%64%6d%6e%64%00%00%02%58%00%00%00%24%64%6d%64%64%00%00%02%7c%00%00%00%24%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%24%00%00%00%1c%00%47%00%49%00%4d%00%50%00%20%00%62%00%75%00%69%00%6c%00%74%00%2d%00%69%00%6e%00%20%00%73%00%52%00%47%00%42%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%1a%00%00%00%1c%00%50%00%75%00%62%00%6c%00%69%00%63%00%20%00%44%00%6f%00%6d%00%61%00%69%00%6e%00%00%58%59%5a%20%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%73%66%33%32%00%00%00%00%00%01%0c%42%00%00%05%de%ff%ff%f3%25%00%00%07%93%00%00%fd%90%ff%ff%fb%a1%ff%ff%fd%a2%00%00%03%dc%00%00%c0%6e%58%59%5a%20%00%00%00%00%00%00%6f%a0%00%00%38%f5%00%00%03%90%58%59%5a%20%00%00%00%00%00%00%24%9f%00%00%0f%84%00%00%a2%b6%c4%58%59%5a%20%00%00%00%00%00%00%62%97%00%00%b7%87%00%00%18%d9%70%61%72%61%00%00%00%00%00%03%00%00%00%02%66%66%00%00%f2%a7%00%00%0d%59%00%00%13%d0%00%00%0a%5b%63%68%72%6d%00%00%00%00%00%03%00%00%00%00%a3%d7%00%00%54%7c%00%00%4c%cd%00%00%99%9a%00%00%26%67%00%00%0f%5c%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%47%00%49%00%4d%00%50%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%73%00%52%00%47%00%42%00%2c%00%00%00%00%ea%00%3c%00%80%00%ff%f8%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%21%f9%04%00%64%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%ff%0b%49%43%43%52%47%42%47%31%30%31%32%ff%00%00%02%a0%6c%63%6d%73%04%30%00%00%6d%6e%74%72%52%47%42%20%58%59%5a%20%07%e5%00%02%00%0a%00%0a%00%0c%00%34%61%63%73%70%41%50%50%4c%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%6c%63%6d%73%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%0d%64%65%73%63%00%00%01%20%00%00%00%40%63%70%72%74%00%00%01%60%00%00%00%36%77%74%70%74%00%00%01%98%00%00%00%14%63%68%61%64%00%00%01%ac%00%00%00%2c%72%58%59%5a%00%00%01%d8%00%00%00%14%62%58%59%5a%00%00%01%ec%00%00%00%14%67%58%59%5a%00%00%02%00%00%00%00%14%72%54%52%43%00%00%02%14%00%00%00%20%67%54%52%43%00%00%02%14%00%00%00%20%62%54%52%43%00%00%02%14%00%00%00%20%63%68%72%ff%6d%00%00%02%34%00%00%00%24%64%6d%6e%64%00%00%02%58%00%00%00%24%64%6d%64%64%00%00%02%7c%00%00%00%24%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%24%00%00%00%1c%00%47%00%49%00%4d%00%50%00%20%00%62%00%75%00%69%00%6c%00%74%00%2d%00%69%00%6e%00%20%00%73%00%52%00%47%00%42%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%1a%00%00%00%1c%00%50%00%75%00%62%00%6c%00%69%00%63%00%20%00%44%00%6f%00%6d%00%61%00%69%00%6e%00%00%58%59%5a%20%00%00%00%00%00%00%f6%d6%00%01%00%00%00%00%d3%2d%73%66%33%32%00%00%00%00%00%01%0c%42%00%00%05%de%ff%ff%f3%25%00%00%07%93%00%00%fd%90%ff%ff%fb%a1%ff%ff%fd%a2%00%00%03%dc%00%00%c0%6e%58%59%5a%20%00%00%00%00%00%00%6f%a0%00%00%38%f5%00%00%03%90%58%59%5a%20%00%00%00%00%00%00%24%9f%00%00%0f%84%00%00%a2%b6%c4%58%59%5a%20%00%00%00%00%00%00%62%97%00%00%b7%87%00%00%18%d9%70%61%72%61%00%00%00%00%00%03%00%00%00%02%66%66%00%00%f2%a7%00%00%0d%59%00%00%13%d0%00%00%0a%5b%63%68%72%6d%00%00%00%00%00%03%00%00%00%00%a3%d7%00%00%54%7c%00%00%4c%cd%00%00%99%9a%00%00%26%67%00%00%0f%5c%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%47%00%49%00%4d%00%50%6d%6c%75%63%00%00%00%00%00%00%00%01%00%00%00%0c%65%6e%55%53%00%00%00%08%00%00%00%1c%00%73%00%52%00%47%00%42%00%2c%00%00%00%00%ea%00%3c%00%80%00%ff%66%00%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%3b]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+Content-Length: 183\r
+\r
+%hex[%47%49%46%38%39%61%ea%00%3c%00%f0%00%00%00%2c%ff%00%00%00%21%f9%04%00%64%00%00%00%2c%00%00%00%00%ea%00%3c%00%00%02%8e%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%0f%86%e2%48%96%e6%89%a6%ea%ca%b6%ee%0b%c7%f2%4c%d7%f6%8d%e7%fa%ce%f7%fe%0f%0c%0a%87%c4%a2%f1%88%4c%2a%97%cc%a6%f3%09%8d%4a%a7%d4%aa%f5%8a%cd%6a%b7%dc%ae%f7%0b%0e%8b%c7%e4%b2%f9%8c%4e%ab%d7%ec%b6%fb%0d%8f%cb%e7%f4%ba%fd%8e%cf%eb%f7%fc%be%ff%0f%18%28%38%48%58%68%78%88%98%a8%b8%c8%d8%e8%f8%08%19%29%39%49%59%69%79%89%99%a9%b9%c9%d9%e9%f9%09%1a%2a%3a%4a%5a%6a%7a%8a%9a%aa%ba%0a%51%00%00%3b]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Corrupted gif. Multiple frames. Lots of meta data. Choosing the first frame without parsing the corrupted parts.
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/deanimate-gif/first-frame/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /deanimate-gif/first-frame/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gif-deanimation/data/test3 b/tests/cts/gif-deanimation/data/test3
new file mode 100644 (file)
index 0000000..b583c51
--- /dev/null
@@ -0,0 +1,61 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gif deanimation
+</keywords>
+</info>
+
+<reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+\r
+G
+</data>
+</reply>
+
+<proxy-reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+\r
+G
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Invalid gif. Only a single byte of data.
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/deanimate-gif/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /deanimate-gif/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gif-deanimation/data/test4 b/tests/cts/gif-deanimation/data/test4
new file mode 100644 (file)
index 0000000..03d6428
--- /dev/null
@@ -0,0 +1,61 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gif deanimation
+</keywords>
+</info>
+
+<reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+\r
+GIF89a
+</data>
+</reply>
+
+<proxy-reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+\r
+GIF89a
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Invalid gif. Only a gif header.
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/deanimate-gif/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /deanimate-gif/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gif-deanimation/data/test5 b/tests/cts/gif-deanimation/data/test5
new file mode 100644 (file)
index 0000000..9055a9f
--- /dev/null
@@ -0,0 +1,61 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gif deanimation
+</keywords>
+</info>
+
+<reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+\r
+GIF89aABCDEFG
+</data>
+</reply>
+
+<proxy-reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+\r
+GIF89aABCDEFG
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Invalid gif. Insufficient data.
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/deanimate-gif/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /deanimate-gif/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gif-deanimation/data/test6 b/tests/cts/gif-deanimation/data/test6
new file mode 100644 (file)
index 0000000..4213929
--- /dev/null
@@ -0,0 +1,59 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gif deanimation
+</keywords>
+</info>
+
+<reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+Content-Length: 0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 502 Server or forwarder response invalid\r
+Content-Type: text/plain\r
+Connection: close\r
+\r
+Bad response. The server or forwarder response doesn't look like HTTP.
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Content-Length 0 and no body sent.
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/deanimate-gif/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /deanimate-gif/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gif-deanimation/data/test7 b/tests/cts/gif-deanimation/data/test7
new file mode 100644 (file)
index 0000000..26d90c8
--- /dev/null
@@ -0,0 +1,61 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gif deanimation
+</keywords>
+</info>
+
+<reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+\r
+GIF89a%hex[%00%00%00%00%80]hex%%repeat[100 x %FF]%
+</data>
+</reply>
+
+<proxy-reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+\r
+GIF89a%hex[%00%00%00%00%80]hex%%repeat[100 x %FF]%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Invalid gif. Negative colour map.
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/deanimate-gif/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /deanimate-gif/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gif-deanimation/data/test8 b/tests/cts/gif-deanimation/data/test8
new file mode 100644 (file)
index 0000000..037d6de
--- /dev/null
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gif deanimation
+</keywords>
+</info>
+
+<reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+\r
+%hex[%47%49%46%38%39%61%14%00%14%00%a1%04%00%fe%00%00%ff%00%00%1e%42%ee%1f%42%ef%21%ff%0b%4e%45%54%53%43%41%50%45%32%2e%30%03%01%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%f9%04%00%0a%00%ff%00%2c%00%00%00%00%14%00%14%00%00%02%11%8c%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%af%15%00%21%f9%04%01%0a%00%02%00%2c%00%00%00%00%14%00%14%00%00%02%11%9c%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%af%15%00%21%f9%04%00%0a%00%ff%00%2c%00%00%00%00%14%00%14%00%00%02%11%94%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%af%15%00%21%f9%04%00%0a%00%ff%00%2c%00%00%00%00%14%00%14%00%00%02%11%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%af%15%00%3b]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+Content-Length: 64\r
+\r
+%hex[%47%49%46%38%39%61%14%00%14%00%a1%04%00%fe%00%00%ff%00%00%1e%42%ee%1f%42%ef%21%f9%04%00%0a%00%ff%00%2c%00%00%00%00%14%00%14%00%00%02%11%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%af%15%00%3b]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Valid gif. Two frames.
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/deanimate-gif/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /deanimate-gif/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gif-deanimation/data/test9 b/tests/cts/gif-deanimation/data/test9
new file mode 100644 (file)
index 0000000..85c6e5e
--- /dev/null
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gif deanimation
+</keywords>
+</info>
+
+<reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+\r
+%hex[%47%49%46%38%39%61%14%00%14%00%a1%04%00%fe%00%00%ff%00%00%1e%42%ee%1f%42%ef%21%ff%0b%4e%45%54%53%43%41%50%45%32%2e%30%03%01%00%00%00%21%fe%24%43%72%65%61%74%65%64%20%62%79%20%46%61%62%69%61%6e%20%4b%65%69%6c%20%77%69%74%68%20%54%68%65%20%47%49%4d%50%00%21%f9%04%00%0a%00%ff%00%2c%00%00%00%00%14%00%14%00%00%02%11%8c%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%af%15%00%21%f9%04%01%0a%00%02%00%2c%00%00%00%00%14%00%14%00%00%02%11%9c%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%af%15%00%21%f9%04%00%0a%00%ff%00%2c%00%00%00%00%14%00%14%00%00%02%11%94%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%af%15%00%21%f9%04%00%0a%00%ff%00%2c%00%00%00%00%14%00%14%00%00%02%11%84%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%af%15%00%3b]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data nonewline="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: image/gif\r
+X-Control: swsclose\r
+Content-Length: 64\r
+\r
+%hex[%47%49%46%38%39%61%14%00%14%00%a1%04%00%fe%00%00%ff%00%00%1e%42%ee%1f%42%ef%21%f9%04%00%0a%00%ff%00%2c%00%00%00%00%14%00%14%00%00%02%11%8c%8f%a9%cb%ed%0f%a3%9c%b4%da%8b%b3%de%bc%fb%af%15%00%3b]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+Valid gif. Two frames. Using the first one.
+</name>
+<features>
+proxy
+</features>
+<command>
+http://%HOSTIP:%HTTPPORT/deanimate-gif/first-frame/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /deanimate-gif/first-frame/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gif-deanimation/deanimate-gifs.action b/tests/cts/gif-deanimation/deanimate-gifs.action
new file mode 100644 (file)
index 0000000..011a18f
--- /dev/null
@@ -0,0 +1,8 @@
+{+deanimate-gifs{last}}
+/
+
+{+deanimate-gifs{first}}
+/deanimate-gif/first-frame/
+
+{+deanimate-gifs{last}}
+/deanimate-gif/last-frame/
diff --git a/tests/cts/gif-deanimation/privoxy.conf b/tests/cts/gif-deanimation/privoxy.conf
new file mode 100644 (file)
index 0000000..288209e
--- /dev/null
@@ -0,0 +1,16 @@
+listen-address 127.0.0.1:9119
+
+debug     1 # Log the destination for each request Privoxy let through. See also debug 1024.
+debug     2 # show each connection status
+debug     4 # show tagging-related messages
+debug     8 # show header parsing
+debug    32 # debug force feature
+debug    64 # debug regular expression filters
+debug   128 # debug redirects
+debug   256 # debug GIF de-animation
+debug   512 # Common Log Format
+debug  1024 # Log the destination for requests Privoxy didn't let through, and the reason why.
+debug  4096 # Startup banner and warnings.
+debug  8192 # Non-fatal errors
+
+actionsfile ./deanimate-gifs.action
diff --git a/tests/cts/gzip-compression/data/test1 b/tests/cts/gzip-compression/data/test1
new file mode 100644 (file)
index 0000000..52325df
--- /dev/null
@@ -0,0 +1,65 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gzip compression
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%08%a2%c1%12%60%00%03%62%6c%61%66%61%73%65%6c%00%73%ca%49%4c%4b%2c%4e%cd%51%48%c9%4c%55%48%49%e4%0a%ce%cf%4d%55%c8%cd%2f%02%71%4a%12%15%32%52%8b%52%b9%00%62%37%9b%0c%24%00%00%00%0a]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 36\r
+\r
+Blafasel die da
+Some more data here
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+gzip-encoded content. Valid gzip data.
+</name>
+<features>
+proxy
+</features>
+<command>
+-H "Accept-Encoding: gzip" http://%HOSTIP:%HTTPPORT/gzip-compressed-data/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /gzip-compressed-data/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Accept-Encoding: gzip\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gzip-compression/data/test10 b/tests/cts/gzip-compression/data/test10
new file mode 100644 (file)
index 0000000..2fefead
--- /dev/null
@@ -0,0 +1,65 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gzip compression
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%0C%a2%c1%12%60%00%00%01%00%00%0A%61%66%61%73%65%6c%00%73%ca%49%4c%4b%2c%4e%cd%51%48%c9%4c%55%48%49%e4%0a%ce%cf%4d%55%c8%cd%2f%02%71%4a%12%15%32%52%8b%52%b9%00%62%37%9b%0c%24%00%00%00%0a]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 36\r
+\r
+Blafasel die da
+Some more data here
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+gzip-encoded content. gzip extra fields. Skipping 1 bytes for gzip compression. Does this sound right?
+</name>
+<features>
+proxy
+</features>
+<command>
+-H "Accept-Encoding: gzip" http://%HOSTIP:%HTTPPORT/gzip-compressed-data/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /gzip-compressed-data/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Accept-Encoding: gzip\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gzip-compression/data/test11 b/tests/cts/gzip-compression/data/test11
new file mode 100644 (file)
index 0000000..a956474
--- /dev/null
@@ -0,0 +1,64 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gzip compression
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%0C%a2%c1%12%60%00%00%FF%00%00%0A%61%66%61%73%65%6c%00%73%ca%49%4c%4b%2c%4e%cd%51%48%c9%4c%55%48%49%e4%0a%ce%cf%4d%55%c8%cd%2f%02%71%4a%12%15%32%52%8b%52%b9%00%62%37%9b%0c%24%00%00%00%0a]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%0C%a2%c1%12%60%00%00%FF%00%00%0A%61%66%61%73%65%6c%00%73%ca%49%4c%4b%2c%4e%cd%51%48%c9%4c%55%48%49%e4%0a%ce%cf%4d%55%c8%cd%2f%02%71%4a%12%15%32%52%8b%52%b9%00%62%37%9b%0c%24%00%00%00%0a]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+gzip-encoded content. gzip extra fields. Unreasonable amount of bytes to skip (-1). Stopping decompression
+</name>
+<features>
+proxy
+</features>
+<command>
+-H "Accept-Encoding: gzip" http://%HOSTIP:%HTTPPORT/gzip-compressed-data/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /gzip-compressed-data/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Accept-Encoding: gzip\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gzip-compression/data/test12 b/tests/cts/gzip-compression/data/test12
new file mode 100644 (file)
index 0000000..d621a11
--- /dev/null
@@ -0,0 +1,64 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gzip compression
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%0C%a2%c1%12%60%00%00%00%01]hex%%repeat[256 x A]%hex[%00%0A%61%66%61%73%65%6c%00%73%ca%49%4c%4b%2c%4e%cd%51%48%c9%4c%55%48%49%e4%0a%ce%cf%4d%55%c8%cd%2f%02%71%4a%12%15%32%52%8b%52%b9%00%62%37%9b%0c%24%00%00%00%0a]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%0C%a2%c1%12%60%00%00%00%01]hex%%repeat[256 x A]%hex[%00%0A%61%66%61%73%65%6c%00%73%ca%49%4c%4b%2c%4e%cd%51%48%c9%4c%55%48%49%e4%0a%ce%cf%4d%55%c8%cd%2f%02%71%4a%12%15%32%52%8b%52%b9%00%62%37%9b%0c%24%00%00%00%0a]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+gzip-encoded content. gzip extra fields. Unexpected error while decompressing to the buffer (iob): invalid distance too far back
+</name>
+<features>
+proxy
+</features>
+<command>
+-H "Accept-Encoding: gzip" http://%HOSTIP:%HTTPPORT/gzip-compressed-data/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /gzip-compressed-data/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Accept-Encoding: gzip\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gzip-compression/data/test13 b/tests/cts/gzip-compression/data/test13
new file mode 100644 (file)
index 0000000..87f5a0a
--- /dev/null
@@ -0,0 +1,65 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gzip compression
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%0C%a2%c1%12%60%00%00%00%01]hex%%repeat[256 x A]%hex[%0A%61%66%61%73%65%6c%00%73%ca%49%4c%4b%2c%4e%cd%51%48%c9%4c%55%48%49%e4%0a%ce%cf%4d%55%c8%cd%2f%02%71%4a%12%15%32%52%8b%52%b9%00%62%37%9b%0c%24%00%00%00%0a]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 36\r
+\r
+Blafasel die da
+Some more data here
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+gzip-encoded content. gzip extra fields. Skipping 256 bytes for gzip compression. Does this sound right?
+</name>
+<features>
+proxy
+</features>
+<command>
+-H "Accept-Encoding: gzip" http://%HOSTIP:%HTTPPORT/gzip-compressed-data/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /gzip-compressed-data/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Accept-Encoding: gzip\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gzip-compression/data/test14 b/tests/cts/gzip-compression/data/test14
new file mode 100644 (file)
index 0000000..1080abd
--- /dev/null
@@ -0,0 +1,65 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gzip compression
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%0C%a2%c1%12%60%00%00%00%00%0A%61%66%61%73%65%6c%00%73%ca%49%4c%4b%2c%4e%cd%51%48%c9%4c%55%48%49%e4%0a%ce%cf%4d%55%c8%cd%2f%02%71%4a%12%15%32%52%8b%52%b9%00%62%37%9b%0c%24%00%00%00%0a]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 36\r
+\r
+Blafasel die da
+Some more data here
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+gzip-encoded content. gzip extra fields. Skipping 0 bytes for gzip compression. Does this sound right?
+</name>
+<features>
+proxy
+</features>
+<command>
+-H "Accept-Encoding: gzip" http://%HOSTIP:%HTTPPORT/gzip-compressed-data/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /gzip-compressed-data/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Accept-Encoding: gzip\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gzip-compression/data/test15 b/tests/cts/gzip-compression/data/test15
new file mode 100644 (file)
index 0000000..12d3042
--- /dev/null
@@ -0,0 +1,65 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gzip compression
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%18%a2%c1%12%60%00%03%62%6c%61%66%61%73%65%6c%00]hex%This is a comment to skip%hex[%00%73%ca%49%4c%4b%2c%4e%cd%51%48%c9%4c%55%48%49%e4%0a%ce%cf%4d%55%c8%cd%2f%02%71%4a%12%15%32%52%8b%52%b9%00%62%37%9b%0c%24%00%00%00%0a]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 36\r
+\r
+Blafasel die da
+Some more data here
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+gzip-encoded content. gzip extra fields. Comment to skip.
+</name>
+<features>
+proxy
+</features>
+<command>
+-H "Accept-Encoding: gzip" http://%HOSTIP:%HTTPPORT/gzip-compressed-data/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /gzip-compressed-data/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Accept-Encoding: gzip\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gzip-compression/data/test16 b/tests/cts/gzip-compression/data/test16
new file mode 100644 (file)
index 0000000..25a4a03
--- /dev/null
@@ -0,0 +1,65 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gzip compression
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%18%a2%c1%12%60%00%03%62%6c%61%66%61%73%65%6c%00]hex%%repeat[1000 x This is a long comment to skip]%hex[%00%73%ca%49%4c%4b%2c%4e%cd%51%48%c9%4c%55%48%49%e4%0a%ce%cf%4d%55%c8%cd%2f%02%71%4a%12%15%32%52%8b%52%b9%00%62%37%9b%0c%24%00%00%00%0a]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 36\r
+\r
+Blafasel die da
+Some more data here
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+gzip-encoded content. gzip extra fields. Long comment to skip.
+</name>
+<features>
+proxy
+</features>
+<command>
+-H "Accept-Encoding: gzip" http://%HOSTIP:%HTTPPORT/gzip-compressed-data/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /gzip-compressed-data/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Accept-Encoding: gzip\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gzip-compression/data/test17 b/tests/cts/gzip-compression/data/test17
new file mode 100644 (file)
index 0000000..b25b44b
--- /dev/null
@@ -0,0 +1,65 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gzip compression
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%00%a2%c1%12%60%00%03%73%ca%49%4c%4b%2c%4e%cd%51%48%c9%4c%55%48%49%e4%0a%ce%cf%4d%55%c8%cd%2f%02%71%4a%12%15%32%52%8b%52%b9%00%62%37%9b%0c%24%00%00%00%0a]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 36\r
+\r
+Blafasel die da
+Some more data here
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+gzip-encoded content. gzip extra fields. No filename to skip.
+</name>
+<features>
+proxy
+</features>
+<command>
+-H "Accept-Encoding: gzip" http://%HOSTIP:%HTTPPORT/gzip-compressed-data/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /gzip-compressed-data/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Accept-Encoding: gzip\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gzip-compression/data/test18 b/tests/cts/gzip-compression/data/test18
new file mode 100644 (file)
index 0000000..5968359
--- /dev/null
@@ -0,0 +1,65 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gzip compression
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%02%a2%c1%12%60%00%FF%FF%03%73%ca%49%4c%4b%2c%4e%cd%51%48%c9%4c%55%48%49%e4%0a%ce%cf%4d%55%c8%cd%2f%02%71%4a%12%15%32%52%8b%52%b9%00%62%37%9b%0c%24%00%00%00%0a]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 36\r
+\r
+Blafasel die da
+Some more data here
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+gzip-encoded content. gzip extra fields. Checksum to skip.
+</name>
+<features>
+proxy
+</features>
+<command>
+-H "Accept-Encoding: gzip" http://%HOSTIP:%HTTPPORT/gzip-compressed-data/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /gzip-compressed-data/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Accept-Encoding: gzip\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gzip-compression/data/test19 b/tests/cts/gzip-compression/data/test19
new file mode 100644 (file)
index 0000000..0a8c8ab
--- /dev/null
@@ -0,0 +1,64 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gzip compression
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%02%a2%c1%12%60%00%FF]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%02%a2%c1%12%60%00%FF]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+gzip-encoded content. gzip extra fields. Checksum to skip. Insufficient data left.
+</name>
+<features>
+proxy
+</features>
+<command>
+-H "Accept-Encoding: gzip" http://%HOSTIP:%HTTPPORT/gzip-compressed-data/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /gzip-compressed-data/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Accept-Encoding: gzip\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gzip-compression/data/test2 b/tests/cts/gzip-compression/data/test2
new file mode 100644 (file)
index 0000000..8ebb10e
--- /dev/null
@@ -0,0 +1,64 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gzip compression
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%08%a2%c1%12%60%00]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%08%a2%c1%12%60%00]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+gzip-encoded content. Malformed gzip header.
+</name>
+<features>
+proxy
+</features>
+<command>
+-H "Accept-Encoding: gzip" http://%HOSTIP:%HTTPPORT/gzip-compressed-data/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /gzip-compressed-data/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Accept-Encoding: gzip\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gzip-compression/data/test20 b/tests/cts/gzip-compression/data/test20
new file mode 100644 (file)
index 0000000..7fcd00a
--- /dev/null
@@ -0,0 +1,64 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gzip compression
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%00%00%00%00%00%02%03%ed%c4%31%0d%00%00%08%03%b0%1f%97%4b%26%01%ff%c1%05%57%7b%b4%d9%4c%25%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%a4%9f%0e%80%af%70%a8%40%ec%00%00]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%00%00%00%00%00%02%03%ed%c4%31%0d%00%00%08%03%b0%1f%97%4b%26%01%ff%c1%05%57%7b%b4%d9%4c%25%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%a4%9f%0e%80%af%70%a8%40%ec%00%00]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+gzip-encoded content. Buffer limit reached while decompressing iob.
+</name>
+<features>
+proxy
+</features>
+<command>
+-H "Accept-Encoding: gzip" http://%HOSTIP:%HTTPPORT/gzip-compressed-data/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /gzip-compressed-data/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Accept-Encoding: gzip\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gzip-compression/data/test21 b/tests/cts/gzip-compression/data/test21
new file mode 100644 (file)
index 0000000..255d54e
--- /dev/null
@@ -0,0 +1,64 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gzip compression
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%00%00%00%00%00%02%03%ed%c4%31%0d%00%00%08%03%b0%1f%97%4b%26%01%ff%c1%05%57%7b%b4%d9%4c%25%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%a4%9f%0e%80%af%70%a8%40%ec%00%00]hex%%repeat[10000 x padding data]%
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%00%00%00%00%00%02%03%ed%c4%31%0d%00%00%08%03%b0%1f%97%4b%26%01%ff%c1%05%57%7b%b4%d9%4c%25%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%24%49%92%a4%9f%0e%80%af%70%a8%40%ec%00%00]hex%%repeat[10000 x padding data]%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+gzip-encoded content. Buffer limit reached while extending the buffer (iob).
+</name>
+<features>
+proxy
+</features>
+<command>
+-H "Accept-Encoding: gzip" http://%HOSTIP:%HTTPPORT/gzip-compressed-data/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /gzip-compressed-data/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Accept-Encoding: gzip\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gzip-compression/data/test22 b/tests/cts/gzip-compression/data/test22
new file mode 100644 (file)
index 0000000..d3c41bc
--- /dev/null
@@ -0,0 +1,65 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+deflate compression
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: deflate\r
+X-Control: swsclose\r
+\r
+%hex[%0b%ce%cf%4d%55%48%49%4d%cb%49%2c%49%55%48%cd%4b%ce%4f%49%4d%51%48%49%2c%49%d4%e3%f2%4b%2d%57%c8%c9%cc%4b%55%c8%48%2d%4a%d5%e3%02%00]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 42\r
+\r
+Some deflate encoded data.
+New line here.
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+deflate-encoded content. Valid.
+</name>
+<features>
+proxy
+</features>
+<command>
+-H "Accept-Encoding: deflate" http://%HOSTIP:%HTTPPORT/deflate-compressed-data/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /deflate-compressed-data/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Accept-Encoding: deflate\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gzip-compression/data/test23 b/tests/cts/gzip-compression/data/test23
new file mode 100644 (file)
index 0000000..07b5bf2
--- /dev/null
@@ -0,0 +1,71 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+deflate compression
+skip
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: deflate\r
+X-Control: swsclose\r
+\r
+%hex[%0b%ce%cf%4d%55%48%49%4d%cb%49%2c%49%55%48%cd%4b%ce%4f%49%4d%]hex%
+Bogus data blafasel
+</data>
+</reply>
+
+# The actual reply does not contain a line break after the trailing NUL byte
+# but we can't currently express this as the </data> tag has to be on its
+# own line.
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: deflate\r
+X-Control: swsclose\r
+\r
+%hex[%0b%ce%cf%4d%55%48%49%4d%cb%49%2c%49%55%48%cd%4b%ce%4f%49%4d%]hex%
+Bogus data blafasel
+%hex[%00]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+deflate-encoded content. Corrupted data.
+</name>
+<features>
+proxy
+</features>
+<command>
+-H "Accept-Encoding: deflate" http://%HOSTIP:%HTTPPORT/deflate-compressed-data/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /deflate-compressed-data/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Accept-Encoding: deflate\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gzip-compression/data/test24 b/tests/cts/gzip-compression/data/test24
new file mode 100644 (file)
index 0000000..94eae47
--- /dev/null
@@ -0,0 +1,64 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gzip compression
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%0C%a2%c1%12%60%00%00%00%FF%00%0A%61%66%61%73%65%6c%00%73%ca%49%4c%4b%2c%4e%cd%51%48%c9%4c%55%48%49%e4%0a%ce%cf%4d%55%c8%cd%2f%02%71%4a%12%15%32%52%8b%52%b9%00%62%37%9b%0c%24%00%00%00]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%0C%a2%c1%12%60%00%00%00%FF%00%0A%61%66%61%73%65%6c%00%73%ca%49%4c%4b%2c%4e%cd%51%48%c9%4c%55%48%49%e4%0a%ce%cf%4d%55%c8%cd%2f%02%71%4a%12%15%32%52%8b%52%b9%00%62%37%9b%0c%24%00%00%00]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+gzip-encoded content. gzip extra fields with skip bytes that would be negative when not being casted.
+</name>
+<features>
+proxy
+</features>
+<command>
+-H "Accept-Encoding: gzip" http://%HOSTIP:%HTTPPORT/gzip-compressed-data/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /gzip-compressed-data/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Accept-Encoding: gzip\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gzip-compression/data/test25 b/tests/cts/gzip-compression/data/test25
new file mode 100644 (file)
index 0000000..520d69e
--- /dev/null
@@ -0,0 +1,64 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gzip compression
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%0C%a2%c1%12%60%00]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%0C%a2%c1%12%60%00]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+gzip-encoded content. gzip extra fields with not enough data.
+</name>
+<features>
+proxy
+</features>
+<command>
+-H "Accept-Encoding: gzip" http://%HOSTIP:%HTTPPORT/gzip-compressed-data/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /gzip-compressed-data/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Accept-Encoding: gzip\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gzip-compression/data/test26 b/tests/cts/gzip-compression/data/test26
new file mode 100644 (file)
index 0000000..62621cc
--- /dev/null
@@ -0,0 +1,64 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gzip compression
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%1A%a2%c1%12%60%FF%03%62%6c%61%66%61%73%65%6c%FF%73%ca%49%4c%4b%2c%4e%cd%51%48%c9%4c%55%48%49%e4%0a%ce%cf%4d%55%c8%cd%2f%02%71%4a%12%15%32%52%8b%52%b9%FF%62%37%9b%0c%24%FF%FF%FF%FF]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%1A%a2%c1%12%60%FF%03%62%6c%61%66%61%73%65%6c%FF%73%ca%49%4c%4b%2c%4e%cd%51%48%c9%4c%55%48%49%e4%0a%ce%cf%4d%55%c8%cd%2f%02%71%4a%12%15%32%52%8b%52%b9%FF%62%37%9b%0c%24%FF%FF%FF%FF]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+gzip-encoded content. Unterminated file name and comment.
+</name>
+<features>
+proxy
+</features>
+<command>
+-H "Accept-Encoding: gzip" http://%HOSTIP:%HTTPPORT/gzip-compressed-data/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /gzip-compressed-data/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Accept-Encoding: gzip\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gzip-compression/data/test27 b/tests/cts/gzip-compression/data/test27
new file mode 100644 (file)
index 0000000..52e22f5
--- /dev/null
@@ -0,0 +1,64 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gzip compression
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%1A%a2%c1%12%60%FF%03%62%6c%61%66%61%73%65%6c%FF%73%ca%49%4c%4b%2c%4e%cd%51%48%c9%4c%55%48%49%e4%0a%ce%cf%4d%55%c8%cd%2f%02%71%4a%12%15%32%52%8b%52%b9%FF%62%37%9b%0c%24%FF%FF%FF%FF]hex%%repeat[302 x A]%
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%1A%a2%c1%12%60%FF%03%62%6c%61%66%61%73%65%6c%FF%73%ca%49%4c%4b%2c%4e%cd%51%48%c9%4c%55%48%49%e4%0a%ce%cf%4d%55%c8%cd%2f%02%71%4a%12%15%32%52%8b%52%b9%FF%62%37%9b%0c%24%FF%FF%FF%FF]hex%%repeat[302 x A]%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+gzip-encoded content. Unterminated file name and comment, padding data to fill iob.
+</name>
+<features>
+proxy
+</features>
+<command>
+-H "Accept-Encoding: gzip" http://%HOSTIP:%HTTPPORT/gzip-compressed-data/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /gzip-compressed-data/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Accept-Encoding: gzip\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gzip-compression/data/test28 b/tests/cts/gzip-compression/data/test28
new file mode 100644 (file)
index 0000000..106b0e2
--- /dev/null
@@ -0,0 +1,63 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gzip compression
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%00%00%00%00%00%00%03%03%00%00%00%00%00%00%00%00%00]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 0\r
+\r
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+gzip-encoded content. Valid gzip data, no compressed content
+</name>
+<features>
+proxy
+</features>
+<command>
+-H "Accept-Encoding: gzip" http://%HOSTIP:%HTTPPORT/gzip-compressed-data/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /gzip-compressed-data/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Accept-Encoding: gzip\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gzip-compression/data/test3 b/tests/cts/gzip-compression/data/test3
new file mode 100644 (file)
index 0000000..020fa63
--- /dev/null
@@ -0,0 +1,64 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gzip compression
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%08%a2%c1%12%60]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%08%a2%c1%12%60]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+gzip-encoded content. Insufficient data to start decompression.
+</name>
+<features>
+proxy
+</features>
+<command>
+-H "Accept-Encoding: gzip" http://%HOSTIP:%HTTPPORT/gzip-compressed-data/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /gzip-compressed-data/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Accept-Encoding: gzip\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gzip-compression/data/test4 b/tests/cts/gzip-compression/data/test4
new file mode 100644 (file)
index 0000000..fab585f
--- /dev/null
@@ -0,0 +1,65 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gzip compression
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%00%00%00%00%00%00%03%73%ca%49%4c%4b%2c%4e%cd%51%48%c9%4c%55%48%49%e4%0a%ce%cf%4d%55%c8%cd%2f%02%71%4a%12%15%32%52%8b%52%b9%00%62%37%9b%0c%24%00%00%00]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 36\r
+\r
+Blafasel die da
+Some more data here
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+gzip-encoded content. Valid gzip data. No embedded file name.
+</name>
+<features>
+proxy
+</features>
+<command>
+-H "Accept-Encoding: gzip" http://%HOSTIP:%HTTPPORT/gzip-compressed-data/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /gzip-compressed-data/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Accept-Encoding: gzip\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gzip-compression/data/test5 b/tests/cts/gzip-compression/data/test5
new file mode 100644 (file)
index 0000000..c5e9944
--- /dev/null
@@ -0,0 +1,64 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gzip compression
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1G%8b%08%08%a2%c1%12%60%00%03%62%6c%61%66%61%73%65%6c%00%73%ca%49%4c%4b%2c%4e%cd%51%48%c9%4c%55%48%49%e4%0a%ce%cf%4d%55%c8%cd%2f%02%71%4a%12%15%32%52%8b%52%b9%00%62%37%9b%0c%24%00%00%00%0a]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1G%8b%08%08%a2%c1%12%60%00%03%62%6c%61%66%61%73%65%6c%00%73%ca%49%4c%4b%2c%4e%cd%51%48%c9%4c%55%48%49%e4%0a%ce%cf%4d%55%c8%cd%2f%02%71%4a%12%15%32%52%8b%52%b9%00%62%37%9b%0c%24%00%00%00%0a]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+gzip-encoded content. Invalid gzip header when decompressing 1.
+</name>
+<features>
+proxy
+</features>
+<command>
+-H "Accept-Encoding: gzip" http://%HOSTIP:%HTTPPORT/gzip-compressed-data/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /gzip-compressed-data/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Accept-Encoding: gzip\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gzip-compression/data/test6 b/tests/cts/gzip-compression/data/test6
new file mode 100644 (file)
index 0000000..45a80c4
--- /dev/null
@@ -0,0 +1,64 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gzip compression
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8c%08%08%a2%c1%12%60%00%03%62%6c%61%66%61%73%65%6c%00%73%ca%49%4c%4b%2c%4e%cd%51%48%c9%4c%55%48%49%e4%0a%ce%cf%4d%55%c8%cd%2f%02%71%4a%12%15%32%52%8b%52%b9%00%62%37%9b%0c%24%00%00%00%0a]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8c%08%08%a2%c1%12%60%00%03%62%6c%61%66%61%73%65%6c%00%73%ca%49%4c%4b%2c%4e%cd%51%48%c9%4c%55%48%49%e4%0a%ce%cf%4d%55%c8%cd%2f%02%71%4a%12%15%32%52%8b%52%b9%00%62%37%9b%0c%24%00%00%00%0a]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+gzip-encoded content. Invalid gzip header when decompressing 2.
+</name>
+<features>
+proxy
+</features>
+<command>
+-H "Accept-Encoding: gzip" http://%HOSTIP:%HTTPPORT/gzip-compressed-data/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /gzip-compressed-data/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Accept-Encoding: gzip\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gzip-compression/data/test7 b/tests/cts/gzip-compression/data/test7
new file mode 100644 (file)
index 0000000..b548809
--- /dev/null
@@ -0,0 +1,64 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gzip compression
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%FF%08%a2%c1%12%60%00%03%62%6c%61%66%61%73%65%6c%00%73%ca%49%4c%4b%2c%4e%cd%51%48%c9%4c%55%48%49%e4%0a%ce%cf%4d%55%c8%cd%2f%02%71%4a%12%15%32%52%8b%52%b9%00%62%37%9b%0c%24%00%00%00%0a]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%FF%08%a2%c1%12%60%00%03%62%6c%61%66%61%73%65%6c%00%73%ca%49%4c%4b%2c%4e%cd%51%48%c9%4c%55%48%49%e4%0a%ce%cf%4d%55%c8%cd%2f%02%71%4a%12%15%32%52%8b%52%b9%00%62%37%9b%0c%24%00%00%00%0a]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+gzip-encoded content. Invalid gzip header when decompressing 3.
+</name>
+<features>
+proxy
+</features>
+<command>
+-H "Accept-Encoding: gzip" http://%HOSTIP:%HTTPPORT/gzip-compressed-data/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /gzip-compressed-data/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Accept-Encoding: gzip\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gzip-compression/data/test8 b/tests/cts/gzip-compression/data/test8
new file mode 100644 (file)
index 0000000..568dc75
--- /dev/null
@@ -0,0 +1,64 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gzip compression
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%e8%a2%c1%12%60%00%03%62%6c%61%66%61%73%65%6c%00%73%ca%49%4c%4b%2c%4e%cd%51%48%c9%4c%55%48%49%e4%0a%ce%cf%4d%55%c8%cd%2f%02%71%4a%12%15%32%52%8b%52%b9%00%62%37%9b%0c%24%00%00%00%0a]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%e8%a2%c1%12%60%00%03%62%6c%61%66%61%73%65%6c%00%73%ca%49%4c%4b%2c%4e%cd%51%48%c9%4c%55%48%49%e4%0a%ce%cf%4d%55%c8%cd%2f%02%71%4a%12%15%32%52%8b%52%b9%00%62%37%9b%0c%24%00%00%00%0a]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+gzip-encoded content. Invalid gzip header flags.
+</name>
+<features>
+proxy
+</features>
+<command>
+-H "Accept-Encoding: gzip" http://%HOSTIP:%HTTPPORT/gzip-compressed-data/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /gzip-compressed-data/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Accept-Encoding: gzip\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gzip-compression/data/test9 b/tests/cts/gzip-compression/data/test9
new file mode 100644 (file)
index 0000000..31f35b0
--- /dev/null
@@ -0,0 +1,64 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+gzip compression
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%0C%a2%c1%12%60%00%03%62%6c%61%66%61%73%65%6c%00%73%ca%49%4c%4b%2c%4e%cd%51%48%c9%4c%55%48%49%e4%0a%ce%cf%4d%55%c8%cd%2f%02%71%4a%12%15%32%52%8b%52%b9%00%62%37%9b%0c%24%00%00%00%0a]hex%
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Encoding: gzip\r
+X-Control: swsclose\r
+\r
+%hex[%1f%8b%08%0C%a2%c1%12%60%00%03%62%6c%61%66%61%73%65%6c%00%73%ca%49%4c%4b%2c%4e%cd%51%48%c9%4c%55%48%49%e4%0a%ce%cf%4d%55%c8%cd%2f%02%71%4a%12%15%32%52%8b%52%b9%00%62%37%9b%0c%24%00%00%00%0a]hex%
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
+gzip-encoded content. gzip extra fields. Unreasonable amount of bytes to skip.
+</name>
+<features>
+proxy
+</features>
+<command>
+-H "Accept-Encoding: gzip" http://%HOSTIP:%HTTPPORT/gzip-compressed-data/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /gzip-compressed-data/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Accept-Encoding: gzip\r
+\r
+</protocol>
+<errorcode>
+0
+</errorcode>
+</verify>
+</testcase>
diff --git a/tests/cts/gzip-compression/gzip-compression.action b/tests/cts/gzip-compression/gzip-compression.action
new file mode 100644 (file)
index 0000000..0928e19
--- /dev/null
@@ -0,0 +1,3 @@
+# Enable a filter so Privoxy decompresses the content
+{+filter{img-reorder}}
+/
diff --git a/tests/cts/gzip-compression/privoxy.conf b/tests/cts/gzip-compression/privoxy.conf
new file mode 100644 (file)
index 0000000..ba95f95
--- /dev/null
@@ -0,0 +1,20 @@
+listen-address 127.0.0.1:9119
+
+debug     1 # Log the destination for each request Privoxy let through. See also debug 1024.
+debug     2 # show each connection status
+debug     4 # show tagging-related messages
+debug     8 # show header parsing
+debug    32 # debug force feature
+debug    64 # debug regular expression filters
+debug   128 # debug redirects
+debug   256 # debug GIF de-animation
+debug   512 # Common Log Format
+debug  1024 # Log the destination for requests Privoxy didn't let through, and the reason why.
+debug  4096 # Startup banner and warnings.
+debug  8192 # Non-fatal errors
+
+filterfile ../../../default.filter
+actionsfile ./gzip-compression.action
+
+# Reduce buffer limit so we reach it sooner
+buffer-limit 30
diff --git a/tests/cts/header-filters/data/test1 b/tests/cts/header-filters/data/test1
new file mode 100644 (file)
index 0000000..763ea61
--- /dev/null
@@ -0,0 +1,59 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+server-header-filter x-httpd-php-to-html
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: application/x-httpd-php\r
+X-Control: swsclose\r
+Content-Length: 0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 0\r
+\r
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++server-header-filter{x-httpd-php-to-html}
+</name>
+<features>
+proxy
+</features>
+<command>
+--head http://%HOSTIP:%HTTPPORT/x-httpd-php-to-html/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+HEAD /x-httpd-php-to-html/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/header-filters/data/test2 b/tests/cts/header-filters/data/test2
new file mode 100644 (file)
index 0000000..77bcc76
--- /dev/null
@@ -0,0 +1,61 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+server-header-filter html-to-xml
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+Content-Type: text/html; blafasel\r
+X-Control: swsclose\r
+Content-Length: 0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: application/xhtml+xml\r
+Content-Type: application/xhtml+xml; blafasel\r
+X-Control: swsclose\r
+Content-Length: 0\r
+\r
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++server-header-filter{html-to-xml}
+</name>
+<features>
+proxy
+</features>
+<command>
+--head http://%HOSTIP:%HTTPPORT/html-to-xml/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+HEAD /html-to-xml/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/header-filters/data/test3 b/tests/cts/header-filters/data/test3
new file mode 100644 (file)
index 0000000..776fab8
--- /dev/null
@@ -0,0 +1,67 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+server-header-filter xml-to-html
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: application/xhtml+xml; blafasel\r
+Content-Type: application/xml; blafasel\r
+Content-Type: application/xml\r
+Content-Type: text/xml; blafasel\r
+Content-Type: text/xml\r
+X-Control: swsclose\r
+Content-Length: 0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html; blafasel\r
+Content-Type: text/html; blafasel\r
+Content-Type: text/html\r
+Content-Type: text/html; blafasel\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 0\r
+\r
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++server-header-filter{xml-to-html}
+</name>
+<features>
+proxy
+</features>
+<command>
+--head http://%HOSTIP:%HTTPPORT/xml-to-html/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+HEAD /xml-to-html/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/header-filters/data/test4 b/tests/cts/header-filters/data/test4
new file mode 100644 (file)
index 0000000..37ebfd4
--- /dev/null
@@ -0,0 +1,60 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+client-header-filter hide-tor-exit-notation
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 0\r
+\r
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++client-header-filter{hide-tor-exit-notation} with http:// Referer:
+</name>
+<features>
+proxy
+</features>
+<command>
+--head -H "Referer: http://www.example.org.blafasel.exit/" -H "Host: www.example.org.blafasel.exit" http://%HOSTIP:%HTTPPORT/hide-tor-exit-notation/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+HEAD /hide-tor-exit-notation/%TESTNUMBER HTTP/1.1\r
+Host: www.example.org\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Referer: http://www.example.org/\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/header-filters/data/test5 b/tests/cts/header-filters/data/test5
new file mode 100644 (file)
index 0000000..f614a55
--- /dev/null
@@ -0,0 +1,60 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+client-header-filter hide-tor-exit-notation
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 0\r
+\r
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++client-header-filter{hide-tor-exit-notation} with https:// Referer:
+</name>
+<features>
+proxy
+</features>
+<command>
+--head -H "Referer: https://www.example.org.blafasel.exit/secure/" -H "Host: www.example.org.blafasel.exit" http://%HOSTIP:%HTTPPORT/hide-tor-exit-notation/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+HEAD /hide-tor-exit-notation/%TESTNUMBER HTTP/1.1\r
+Host: www.example.org\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Referer: https://www.example.org/secure/\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/header-filters/data/test6 b/tests/cts/header-filters/data/test6
new file mode 100644 (file)
index 0000000..802d9f5
--- /dev/null
@@ -0,0 +1,62 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+client-header-filter no-brotli-accepted
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/html\r
+X-Control: swsclose\r
+Content-Length: 0\r
+\r
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++client-header-filter{no-brotli-accepted}
+</name>
+<features>
+proxy
+</features>
+<command>
+--head -H "Accept-Encoding: br" -H "Accept-Encoding: gzip, br" -H "Accept-Encoding: br, gzip" http://%HOSTIP:%HTTPPORT/no-brotli-accepted/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+HEAD /no-brotli-accepted/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Accept-Encoding: \r
+Accept-Encoding: gzip\r
+Accept-Encoding: gzip\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/header-filters/data/test7 b/tests/cts/header-filters/data/test7
new file mode 100644 (file)
index 0000000..6706141
--- /dev/null
@@ -0,0 +1,78 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+server-header-filter less-download-windows
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Disposition: blafasel filename="foo.png" tralala\r
+Content-Disposition: blafasel filename="foo.gif" tralala\r
+Content-Disposition: blafasel filename="foo.jpeg" tralala\r
+Content-Disposition: blafasel filename="foo.jpg" tralala\r
+Content-Disposition: blafasel filename="foo.diff" tralala\r
+Content-Disposition: blafasel filename="foo.patch" tralala\r
+Content-Disposition: blafasel filename="foo.dpatch" tralala\r
+Content-Disposition: blafasel filename='foo.c' tralala\r
+Content-Disposition: blafasel filename="foo.h" tralala\r
+Content-Disposition: blafasel filename=foo.pl tralala\r
+Content-Disposition: blafasel filename="foo.shar" tralala\r
+Content-Type: message/news\r
+Content-Type: message/rfc822\r
+Content-Type: message/text-blafasel\r
+Content-Type: application/x-sh\r
+Content-Type: application/x-sh \r
+X-Control: swsclose\r
+Content-Length: 0\r
+\r
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 OK\r
+Date: Thu, 22 Jul 2010 11:22:33 GMT\r
+Connection: close\r
+Content-Type: text/plain\r
+Content-Type: text/plain\r
+Content-Type: message/text-blafasel\r
+Content-Type: text/plain\r
+Content-Type: text/plain\r
+X-Control: swsclose\r
+Content-Length: 0\r
+\r
+</data>
+</proxy-reply>
+
+<client>
+<server>
+http
+</server>
+<name>
++server-header-filter{less-download-windows}
+</name>
+<features>
+proxy
+</features>
+<command>
+--head http://%HOSTIP:%HTTPPORT/less-download-windows/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+HEAD /less-download-windows/%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/header-filters/header-filters.action b/tests/cts/header-filters/header-filters.action
new file mode 100644 (file)
index 0000000..bcb6095
--- /dev/null
@@ -0,0 +1,17 @@
+{+server-header-filter{x-httpd-php-to-html}}
+/x-httpd-php-to-html/
+
+{+server-header-filter{html-to-xml}}
+/html-to-xml/
+
+{+server-header-filter{xml-to-html}}
+/xml-to-html/
+
+{+client-header-filter{hide-tor-exit-notation}}
+/hide-tor-exit-notation/
+
+{+client-header-filter{no-brotli-accepted}}
+/no-brotli-accepted/
+
+{+server-header-filter{less-download-windows}}
+/less-download-windows/
diff --git a/tests/cts/header-filters/privoxy.conf b/tests/cts/header-filters/privoxy.conf
new file mode 100644 (file)
index 0000000..7ffc629
--- /dev/null
@@ -0,0 +1,17 @@
+listen-address 127.0.0.1:9119
+
+debug     1 # Log the destination for each request Privoxy let through. See also debug 1024.
+debug     2 # show each connection status
+debug     4 # show tagging-related messages
+debug     8 # show header parsing
+debug    32 # debug force feature
+debug    64 # debug regular expression filters
+debug   128 # debug redirects
+debug   256 # debug GIF de-animation
+debug   512 # Common Log Format
+debug  1024 # Log the destination for requests Privoxy didn't let through, and the reason why.
+debug  4096 # Startup banner and warnings.
+debug  8192 # Non-fatal errors
+
+filterfile ../../../default.filter
+actionsfile ./header-filters.action
diff --git a/tests/cts/logs/.gitignore b/tests/cts/logs/.gitignore
new file mode 100644 (file)
index 0000000..bc74a1e
--- /dev/null
@@ -0,0 +1,2 @@
+# Ignore the logs in this directory
+*.log
diff --git a/tests/cts/pac-file-delivery/data/test1 b/tests/cts/pac-file-delivery/data/test1
new file mode 100644 (file)
index 0000000..1967870
--- /dev/null
@@ -0,0 +1,50 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+Content-Length: 18
+
+Here's your data.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+function FindProxyForURL(url, host) {
+    var proxy = "PROXY 127.0.0.1:9119; DIRECT";
+    var direct = "DIRECT";
+    if (isPlainHostName(host)) {
+        return direct;
+    }
+    if (url.substring(0, 4) == "ftp:" || url.substring(0, 6) == "rsync:") {
+        return direct;
+    }
+    return proxy;
+}
+</data>
+</proxy-reply>
+
+<client>
+<server>
+none
+</server>
+<name>
+CGI request for PAC file
+</name>
+<command option="no-include">
+http://config.privoxy.org/wpad.dat
+</command>
+</client>
+
+<verify>
+</verify>
+</testcase>
diff --git a/tests/cts/pac-file-delivery/privoxy.conf b/tests/cts/pac-file-delivery/privoxy.conf
new file mode 100644 (file)
index 0000000..0039865
--- /dev/null
@@ -0,0 +1,18 @@
+listen-address 127.0.0.1:9119
+
+debug     1 # Log the destination for each request Privoxy let through. See also debug 1024.
+debug     2 # show each connection status
+debug     4 # show tagging-related messages
+debug     8 # show header parsing
+debug    32 # debug force feature
+debug    64 # debug regular expression filters
+debug   128 # debug redirects
+debug   256 # debug GIF de-animation
+debug   512 # Common Log Format
+debug  1024 # Log the destination for requests Privoxy didn't let through, and the reason why.
+debug  4096 # Startup banner and warnings.
+debug  8192 # Non-fatal errors
+
+templdir ../../../templates
+
+keep-alive-timeout 15
diff --git a/tests/cts/privoxy-runtests.pm b/tests/cts/privoxy-runtests.pm
new file mode 100644 (file)
index 0000000..b04b027
--- /dev/null
@@ -0,0 +1,223 @@
+################################################################################
+# privoxy-runtests.pm
+#
+# Code that has to be loaded by curl's runtests.pl with the -L option
+# to deal with modifications required when using the tests with Privoxy.
+#
+# Copyright (c) 2014-2022 Fabian Keil <fk@fabiankeil.de>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+################################################################################
+
+use strict;
+use warnings;
+no warnings "redefine";
+
+my $verbose = 0;
+my $use_external_proxy = 0;
+
+BEGIN {
+    # Keep a couple of functions from getpart.pm accessible so
+    # our redefinitions don't have to reimplement them.
+    our $real_showdiff = \&showdiff;
+    our $real_getpart = \&getpart;
+    our $real_getpartattr = \&getpartattr;
+    our $real_compareparts = \&compareparts;
+    our $real_startnew = \&startnew;
+}
+
+sub print_skipped_header($) {
+    my $skipped_header = shift;
+    $skipped_header =~ s@\r?\n$@@;
+    print "Skipping '$skipped_header'\n";
+}
+
+# Process headers to ignore differences that are to be expected
+# when Privoxy is being used.
+#
+# - Filter out "Proxy-Connection:" headers when checking for
+#   test success.
+# - Filter out a header that is specified with a "X-Ignore-Header" header.
+# - Deal with tests that don't expect CRLF header endings as
+#   long as the test uses it consistently.
+# - Reduce spaces in server headers with a too-simplistic heuristic
+#   that happens to work for the existing tests.
+sub process_headers($$) {
+    my ($head1_ref, $head2_ref) = @_;
+    my @head1;
+    my @head2;
+    my $crlf_expected = 0;
+    my $connection_header_expected = 0;
+    my $proxy_connection_header_expected = 0;
+    my $parsing_server_headers = 0;
+    my $ignore_header;
+    my $ignored_header;
+
+    foreach (@$head2_ref) {
+        if (/^HTTP/) {
+            # If it starts like a response line, assume we are
+            # looking at server headers.
+            $parsing_server_headers = 1;
+        }
+        if (/^\r?\n$/) {
+            $parsing_server_headers = 0;
+        }
+        if (/\r\n$/) {
+            $crlf_expected = 1; # XXX: assume the expectancy is consistent.
+        }
+
+        if (/^Connection:/) {
+            $connection_header_expected = 1;
+        }
+        if (/^Proxy-Connection:/) {
+            $proxy_connection_header_expected = 1;
+        }
+        if (/^X-Ignore-Header: (.*)/) {
+            $ignore_header = $1;
+            print "Ignoring header '$ignore_header'\n" if $verbose;
+        }
+        if (defined $ignore_header and /^$ignore_header: .*/) {
+            $ignored_header = $_;
+        }
+
+        if ($parsing_server_headers and not /"/) {
+            # Normalize spaces in server headers similar to the way Privoxy
+            # does. This is required for curl tests 29, 40, 42 and 54.
+            s@  +@ @g;
+        }
+    }
+
+    if ($verbose) {
+        print "Expecting " . ($crlf_expected ? "" : "no ") . "crlf\n";
+        print "Expecting " . ($connection_header_expected ? "a" : "no") . " Connection: header\n";
+        print "Expecting " . ($proxy_connection_header_expected ? "a" : "no") . " Proxy-Connection: header\n";
+    }
+
+    foreach (@$head1_ref) {
+
+        s@\r\n$@\n@ unless ($crlf_expected);
+
+        if ((m/^Connection:/ and not $connection_header_expected) or
+            (m/^Proxy-Connection:/ and not $proxy_connection_header_expected)) {
+            print_skipped_header($_) if ($verbose);
+            next;
+        }
+        if (defined $ignore_header) {
+            if (m/^$ignore_header:/) {
+                push @head1, "X-Ignore-Header: $ignore_header\n";
+                $_ = $ignored_header;
+            }
+        }
+        push @head1, $_;
+    }
+    $head1_ref = \@head1;
+
+    return ($head1_ref, $head2_ref);
+}
+
+# Behaves like the real compareparts(), but if a proxy is being used,
+# headers are run through process_headers() before checking them for
+# differences.
+sub compareparts {
+    my ($head1_ref, $head2_ref) = @_;
+    our $real_compareparts;
+
+    if ($use_external_proxy) {
+        ($head1_ref, $head2_ref) = process_headers($head1_ref, $head2_ref);
+    }
+
+    return &$real_compareparts($head1_ref, $head2_ref);
+}
+
+# Behaves like the real getpart() but if a proxy is being used
+# and a proxy-reply section exists, it is returned instead of
+# a common reply section.
+sub getpart {
+    my ($section, $part) = @_;
+    our $real_getpart;
+
+    if ($use_external_proxy and
+        $section eq 'reply' and
+        partexists("proxy-reply", $part)) {
+        $section = "proxy-reply";
+    }
+
+    return &$real_getpart($section, $part);
+}
+
+# Behaves like the real getpartattr() but if a proxy is being used
+# and a proxy-reply section exists, it is being used instead of
+# a common reply section.
+sub getpartattr {
+    my ($section, $part)=@_;
+    our $real_getpartattr;
+
+    if ($use_external_proxy and
+        $section eq 'reply' and
+        partexists("proxy-reply", $part)) {
+        $section = "proxy-reply";
+    }
+
+    return &$real_getpartattr($section, $part);
+}
+
+# Behaves like the real logmsg but suppresses warnings
+# about unknown tests
+sub logmsg {
+    for (@_) {
+        next if /^Warning: test\d+ not present in/;
+        print "$_";
+    }
+}
+
+# Behaves like the real showdiff() but diffs twice,
+# the second time after processing the headers.
+sub showdiff {
+    my ($logdir, $head1_ref, $head2_ref) = @_;
+    our $real_showdiff;
+
+    print "Unprocessed headers:\n";
+    print &$real_showdiff($logdir, $head1_ref, $head2_ref);
+
+    print "Processed headers:\n";
+    ($head1_ref, $head2_ref) = process_headers($head1_ref, $head2_ref);
+    return &$real_showdiff($logdir, $head1_ref, $head2_ref);
+}
+
+# Behaves like the real startnew() but sets a static port if
+# the started server is httpserver.pl.
+sub startnew {
+    my ($cmd, $pidfile, $timeout, $fake) = @_;
+    our $real_startnew;
+
+    if ($cmd =~ /httpserver\.pl/) {
+        $cmd =~ s@--port 0@--port 20000@;
+    } elsif ($cmd =~ m@server/socksd@) {
+        $cmd =~ s@--port 0@--port 20001@;
+    }
+
+    return &$real_startnew($cmd, $pidfile, $timeout, $fake);
+}
+
+sub main() {
+
+    # Look but don't touch, @ARGV is still needed elsewhere
+    foreach my $arg (@ARGV) {
+        $use_external_proxy = 1 if ($arg eq "-P");
+        $verbose = 1 if ($arg eq "-v");
+    }
+
+    return 1;
+}
+
+main();
diff --git a/tests/cts/redirects-https/data/test1 b/tests/cts/redirects-https/data/test1
new file mode 100644 (file)
index 0000000..a1a69ad
--- /dev/null
@@ -0,0 +1,47 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+Content-Length: 29
+
+Not actually used.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established
+
+HTTP/1.1 302 Local Redirect from Privoxy
+Location: http://www.privoxy.org/
+Content-Length: 0
+X-Ignore-Header: Date
+Date: Sun, 10 Jan 2021 08:13:02 GMT
+
+</data>
+</proxy-reply>
+
+<client>
+<server>
+none
+</server>
+<name>
+Redirect to http://www.privoxy.org
+</name>
+<command>
+--insecure https://%HOSTIP/%TESTNUMBER-redirect-me-to-www.privoxy.org
+</command>
+</client>
+
+<verify>
+</verify>
+</testcase>
diff --git a/tests/cts/redirects-https/data/test2 b/tests/cts/redirects-https/data/test2
new file mode 100644 (file)
index 0000000..60e815f
--- /dev/null
@@ -0,0 +1,47 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+Content-Length: 29
+
+Not actually used.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established
+
+HTTP/1.1 302 Local Redirect from Privoxy
+Location: https://www.privoxy.org/
+Content-Length: 0
+X-Ignore-Header: Date
+Date: Sun, 10 Jan 2021 08:13:02 GMT
+
+</data>
+</proxy-reply>
+
+<client>
+<server>
+none
+</server>
+<name>
+Redirect to https://www.privoxy.org
+</name>
+<command>
+--insecure https://%HOSTIP/%TESTNUMBER-redirect-me-to-www.privoxy.org
+</command>
+</client>
+
+<verify>
+</verify>
+</testcase>
diff --git a/tests/cts/redirects-https/data/test3 b/tests/cts/redirects-https/data/test3
new file mode 100644 (file)
index 0000000..3e7368b
--- /dev/null
@@ -0,0 +1,47 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+Content-Length: 29
+
+Not actually used.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established
+
+HTTP/1.1 302 Local Redirect from Privoxy
+Location: http://www.privoxy.org/
+Content-Length: 0
+X-Ignore-Header: Date
+Date: Sun, 10 Jan 2021 08:13:02 GMT
+
+</data>
+</proxy-reply>
+
+<client>
+<server>
+none
+</server>
+<name>
+Redirect to http://www.privoxy.org/ using a pcrs command
+</name>
+<command>
+--insecure https://www.example.org/%TESTNUMBER-redirect-me-to-www.privoxy.org
+</command>
+</client>
+
+<verify>
+</verify>
+</testcase>
diff --git a/tests/cts/redirects-https/data/test4 b/tests/cts/redirects-https/data/test4
new file mode 100644 (file)
index 0000000..47491e6
--- /dev/null
@@ -0,0 +1,47 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+Content-Length: 29
+
+Not actually used.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established
+
+HTTP/1.1 302 Local Redirect from Privoxy
+Location: https://www.privoxy.org/
+Content-Length: 0
+X-Ignore-Header: Date
+Date: Sun, 10 Jan 2021 08:13:02 GMT
+
+</data>
+</proxy-reply>
+
+<client>
+<server>
+none
+</server>
+<name>
+Redirect to https://www.privoxy.org/ using a pcrs command
+</name>
+<command>
+--insecure https://www.example.org/%TESTNUMBER-redirect-me-to-www.privoxy.org
+</command>
+</client>
+
+<verify>
+</verify>
+</testcase>
diff --git a/tests/cts/redirects-https/data/test5 b/tests/cts/redirects-https/data/test5
new file mode 100644 (file)
index 0000000..9bcc1bf
--- /dev/null
@@ -0,0 +1,47 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+Content-Length: 29
+
+Not actually used.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established
+
+HTTP/1.1 302 Local Redirect from Privoxy
+Location: https://www.privoxy.org/path-replaced
+Content-Length: 0
+X-Ignore-Header: Date
+Date: Sun, 10 Jan 2021 08:13:02 GMT
+
+</data>
+</proxy-reply>
+
+<client>
+<server>
+none
+</server>
+<name>
+Redirect to https://www.privoxy.org/path-replaced using a pcrs command
+</name>
+<command>
+--insecure https://www.privoxy.org/%TESTNUMBER-replace-me
+</command>
+</client>
+
+<verify>
+</verify>
+</testcase>
diff --git a/tests/cts/redirects-https/privoxy.conf b/tests/cts/redirects-https/privoxy.conf
new file mode 100644 (file)
index 0000000..5bc00da
--- /dev/null
@@ -0,0 +1,25 @@
+listen-address 127.0.0.1:9119
+
+ca-directory          ../ca-directory
+ca-cert-file          privoxy-test-cacert.crt
+ca-key-file           privoxy-test-cakey.pem
+ca-password           blafasel
+# We don't check certificate anyway
+trusted-cas-file      privoxy-test-cacert.crt
+
+certificate-directory ../certs
+
+debug     1 # Log the destination for each request Privoxy let through. See also debug 1024.
+debug     2 # show each connection status
+debug     4 # show tagging-related messages
+debug     8 # show header parsing
+debug    32 # debug force feature
+debug    64 # debug regular expression filters
+debug   128 # debug redirects
+debug   256 # debug GIF de-animation
+debug   512 # Common Log Format
+debug  1024 # Log the destination for requests Privoxy didn't let through, and the reason why.
+debug  4096 # Startup banner and warnings.
+debug  8192 # Non-fatal errors
+
+actionsfile redirects.action
diff --git a/tests/cts/redirects-https/redirects.action b/tests/cts/redirects-https/redirects.action
new file mode 100644 (file)
index 0000000..4c5017d
--- /dev/null
@@ -0,0 +1,17 @@
+{+https-inspection +ignore-certificate-errors}
+/
+
+{+redirect{http://www.privoxy.org/}}
+/1-redirect-me-to-www.privoxy.org
+
+{+redirect{https://www.privoxy.org/}}
+/2-redirect-me-to-www.privoxy.org
+
+{+redirect{s@https://www.example.org/.*@http://www.privoxy.org/@}}
+/3-redirect-me-to-www.privoxy.org
+
+{+redirect{s@https://www.example.org/.*@https://www.privoxy.org/@}}
+/4-redirect-me-to-www.privoxy.org
+
+{+redirect{s@https://www.privoxy.org/\d-replace-me@https://www.privoxy.org/path-replaced@}}
+/5-replace-me
diff --git a/tests/cts/redirects/data/test1 b/tests/cts/redirects/data/test1
new file mode 100644 (file)
index 0000000..3bcd690
--- /dev/null
@@ -0,0 +1,45 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+Content-Length: 29
+
+Not actually used.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 302 Local Redirect from Privoxy
+Location: http://www.privoxy.org
+Content-Length: 0
+X-Ignore-Header: Date
+Date: Sun, 10 Jan 2021 08:13:02 GMT
+
+</data>
+</proxy-reply>
+
+<client>
+<server>
+none
+</server>
+<name>
+Redirect to http://www.privoxy.org
+</name>
+<command>
+http://%HOSTIP/%TESTNUMBER-redirect-me-to-www.privoxy.org
+</command>
+</client>
+
+<verify>
+</verify>
+</testcase>
diff --git a/tests/cts/redirects/data/test2 b/tests/cts/redirects/data/test2
new file mode 100644 (file)
index 0000000..245b5bc
--- /dev/null
@@ -0,0 +1,45 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+Content-Length: 29
+
+Not actually used.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 302 Local Redirect from Privoxy
+Location: https://www.privoxy.org
+Content-Length: 0
+X-Ignore-Header: Date
+Date: Sun, 10 Jan 2021 08:13:02 GMT
+
+</data>
+</proxy-reply>
+
+<client>
+<server>
+none
+</server>
+<name>
+Redirect to https://www.privoxy.org
+</name>
+<command>
+http://%HOSTIP/%TESTNUMBER-redirect-me-to-www.privoxy.org
+</command>
+</client>
+
+<verify>
+</verify>
+</testcase>
diff --git a/tests/cts/redirects/data/test3 b/tests/cts/redirects/data/test3
new file mode 100644 (file)
index 0000000..625131b
--- /dev/null
@@ -0,0 +1,45 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+Content-Length: 29
+
+Not actually used.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 302 Local Redirect from Privoxy
+Location: http://www.privoxy.org/
+Content-Length: 0
+X-Ignore-Header: Date
+Date: Sun, 10 Jan 2021 08:13:02 GMT
+
+</data>
+</proxy-reply>
+
+<client>
+<server>
+none
+</server>
+<name>
+Redirect to http://www.privoxy.org using a pcrs command
+</name>
+<command>
+http://www.example.org/%TESTNUMBER-redirect-me-to-www.privoxy.org
+</command>
+</client>
+
+<verify>
+</verify>
+</testcase>
diff --git a/tests/cts/redirects/data/test4 b/tests/cts/redirects/data/test4
new file mode 100644 (file)
index 0000000..f9c632b
--- /dev/null
@@ -0,0 +1,45 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+Content-Length: 29
+
+Not actually used.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 302 Local Redirect from Privoxy
+Location: http://www.privoxy.org/path-replaced
+Content-Length: 0
+X-Ignore-Header: Date
+Date: Sun, 10 Jan 2021 08:13:02 GMT
+
+</data>
+</proxy-reply>
+
+<client>
+<server>
+none
+</server>
+<name>
+Redirect to http://www.privoxy.org/path-replaced using a pcrs command
+</name>
+<command>
+http://www.privoxy.org/%TESTNUMBER-replace-me
+</command>
+</client>
+
+<verify>
+</verify>
+</testcase>
diff --git a/tests/cts/redirects/privoxy.conf b/tests/cts/redirects/privoxy.conf
new file mode 100644 (file)
index 0000000..777fb32
--- /dev/null
@@ -0,0 +1,16 @@
+listen-address 127.0.0.1:9119
+
+debug     1 # Log the destination for each request Privoxy let through. See also debug 1024.
+debug     2 # show each connection status
+debug     4 # show tagging-related messages
+debug     8 # show header parsing
+debug    32 # debug force feature
+debug    64 # debug regular expression filters
+debug   128 # debug redirects
+debug   256 # debug GIF de-animation
+debug   512 # Common Log Format
+debug  1024 # Log the destination for requests Privoxy didn't let through, and the reason why.
+debug  4096 # Startup banner and warnings.
+debug  8192 # Non-fatal errors
+
+actionsfile redirects.action
diff --git a/tests/cts/redirects/redirects.action b/tests/cts/redirects/redirects.action
new file mode 100644 (file)
index 0000000..b95ea2e
--- /dev/null
@@ -0,0 +1,11 @@
+{+redirect{http://www.privoxy.org}}
+/1-redirect-me-to-www.privoxy.org
+
+{+redirect{https://www.privoxy.org}}
+/2-redirect-me-to-www.privoxy.org
+
+{+redirect{s@http://www.example.org/.*@http://www.privoxy.org/@}}
+/3-redirect-me-to-www.privoxy.org
+
+{+redirect{s@http://www.privoxy.org/\d-replace-me@http://www.privoxy.org/path-replaced@}}
+/4-replace-me
diff --git a/tests/cts/rewrite-behind-client-back-https/data/test1 b/tests/cts/rewrite-behind-client-back-https/data/test1
new file mode 100644 (file)
index 0000000..53ee678
--- /dev/null
@@ -0,0 +1,48 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+Content-Length: 18
+
+Here's your data.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established
+
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+Content-Length: 18
+
+Here's your data.
+</data>
+</proxy-reply>
+
+
+<client>
+<server>
+http
+</server>
+<name>
+Rewrite behind the client's back: Downgrade from https to http
+</name>
+<command>
+--insecure https://%HOSTIP/%TESTNUMBER-downgrade-to-http-%HOSTIP:%HTTPPORT
+</command>
+</client>
+
+<verify>
+</verify>
+</testcase>
diff --git a/tests/cts/rewrite-behind-client-back-https/data/test2 b/tests/cts/rewrite-behind-client-back-https/data/test2
new file mode 100644 (file)
index 0000000..a8f1094
--- /dev/null
@@ -0,0 +1,54 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+Content-Length: 18
+
+Here's your data.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established
+
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+Content-Length: 18
+
+Here's your data.
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Rewrite path behind the client's back
+</name>
+<command>
+--insecure https://%HOSTIP:%HTTPSPORT/%TESTNUMBER-remove-this
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/rewrite-behind-client-back-https/data/test3 b/tests/cts/rewrite-behind-client-back-https/data/test3
new file mode 100644 (file)
index 0000000..6c49f64
--- /dev/null
@@ -0,0 +1,55 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+Content-Length: 18
+
+Here's your data.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established
+
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+Content-Length: 18
+
+Here's your data.
+</data>
+</proxy-reply>
+
+
+<client>
+<server>
+https
+</server>
+<name>
+Rewrite host behind the client's back
+</name>
+<command>
+--insecure https://www.example.org/%TESTNUMBER-%HOSTIP:%HTTPSPORT
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1\r
+Host: www.example.org\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/rewrite-behind-client-back-https/data/test4 b/tests/cts/rewrite-behind-client-back-https/data/test4
new file mode 100644 (file)
index 0000000..2375271
--- /dev/null
@@ -0,0 +1,54 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+Content-Length: 18
+
+Here's your data.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established
+
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+Content-Length: 18
+
+Here's your data.
+</data>
+</proxy-reply>
+
+<client>
+<server>
+https
+</server>
+<name>
+Client header filter that doesn't match anything. According to Valgrind it triggers a "Conditional jump or move depends on uninitialised value(s)"
+</name>
+<command>
+--insecure https:///%HOSTIP:%HTTPSPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPSPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/rewrite-behind-client-back-https/data/test5 b/tests/cts/rewrite-behind-client-back-https/data/test5
new file mode 100644 (file)
index 0000000..2e6bd11
--- /dev/null
@@ -0,0 +1,47 @@
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+Content-Length: 18
+
+Here's your data.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 200 Connection established
+
+HTTP/1.1 400 Malformed request after rewriting
+Content-Type: text/plain
+Connection: close
+
+Bad request. Messed up with header filters.
+</data>
+</proxy-reply>
+
+
+<client>
+<server>
+none
+</server>
+<name>
+Rewrite behind the client's back: unsupporte http version
+</name>
+<command>
+--insecure https://%HOSTIP/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+</verify>
+</testcase>
diff --git a/tests/cts/rewrite-behind-client-back-https/privoxy.conf b/tests/cts/rewrite-behind-client-back-https/privoxy.conf
new file mode 100644 (file)
index 0000000..8fb261e
--- /dev/null
@@ -0,0 +1,26 @@
+listen-address 127.0.0.1:9119
+
+ca-directory          ../ca-directory
+ca-cert-file          privoxy-test-cacert.crt
+ca-key-file           privoxy-test-cakey.pem
+ca-password           blafasel
+# We don't check certificate anyway
+trusted-cas-file      privoxy-test-cacert.crt
+
+certificate-directory ../certs
+
+debug     1 # Log the destination for each request Privoxy let through. See also debug 1024.
+debug     2 # show each connection status
+debug     4 # show tagging-related messages
+debug     8 # show header parsing
+debug    32 # debug force feature
+debug    64 # debug regular expression filters
+debug   128 # debug redirects
+debug   256 # debug GIF de-animation
+debug   512 # Common Log Format
+debug  1024 # Log the destination for requests Privoxy didn't let through, and the reason why.
+debug  4096 # Startup banner and warnings.
+debug  8192 # Non-fatal errors
+
+actionsfile rewrites.action
+filterfile rewrites.filter
diff --git a/tests/cts/rewrite-behind-client-back-https/rewrites.action b/tests/cts/rewrite-behind-client-back-https/rewrites.action
new file mode 100644 (file)
index 0000000..2623552
--- /dev/null
@@ -0,0 +1,17 @@
+{+https-inspection +ignore-certificate-errors}
+/
+
+{+client-header-filter{https-to-http}}
+/1-downgrade-to-http
+
+{+client-header-filter{truncate-path}}
+/2-remove-this
+
+{+client-header-filter{rewrite-host}}
+/3
+
+{+client-header-filter{non-matching-rewriter}}
+/4
+
+{+client-header-filter{invalid-http-version}}
+/5
diff --git a/tests/cts/rewrite-behind-client-back-https/rewrites.filter b/tests/cts/rewrite-behind-client-back-https/rewrites.filter
new file mode 100644 (file)
index 0000000..a644255
--- /dev/null
@@ -0,0 +1,16 @@
+CLIENT-HEADER-FILTER: https-to-http Downgrade protocol to http
+s@^(\w+) (/\d-downgrade-to-http)-(\d+\.\d+\.\d+\.\d+\:\d+)@$1 http://$3$2@i
+
+CLIENT-HEADER-FILTER: truncate-path Removes '-remove-this' from the path
+s@(/\d)-remove-this (HTTP/1.1)@$1 $2@i
+
+CLIENT-HEADER-FILTER: rewrite-host Replaces the host with the one specified in the path
+s@GET /(\d)-(\d+\.\d+\.\d+\.\d+\:\d+) (HTTP/1.1)@GET https://$2/$1 $3@i
+
+# Results in Conditional jump or move depends on uninitialised value(s)?
+CLIENT-HEADER-FILTER: non-matching-rewriter Does not actually match
+s@/-@@
+
+CLIENT-HEADER-FILTER: invalid-http-version Rewrites the request line with an invalid HTTP version
+s@HTTP/1.1@HTTP/9000@
+
diff --git a/tests/cts/rewrite-behind-client-back/data/test1 b/tests/cts/rewrite-behind-client-back/data/test1
new file mode 100644 (file)
index 0000000..dd0175b
--- /dev/null
@@ -0,0 +1,45 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+Content-Length: 29
+
+Not actually used.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 400 Malformed request after rewriting
+Content-Type: text/plain
+Connection: close
+
+Bad request. Messed up with header filters.
+</data>
+</proxy-reply>
+
+
+<client>
+<server>
+none
+</server>
+<name>
+Rewrite behind the client's back: invalid upgrade to https
+</name>
+<command>
+http://%HOSTIP/%TESTNUMBER-upgrade-to-https
+</command>
+</client>
+
+<verify>
+</verify>
+</testcase>
diff --git a/tests/cts/rewrite-behind-client-back/data/test2 b/tests/cts/rewrite-behind-client-back/data/test2
new file mode 100644 (file)
index 0000000..b145d73
--- /dev/null
@@ -0,0 +1,41 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Content-Length: 9
+
+Blafasel
+</data>
+</reply>
+
+
+<client>
+<server>
+http
+</server>
+<name>
+Rewrite path behind the client's back
+</name>
+<command>
+http://%HOSTIP:%HTTPPORT/%TESTNUMBER-remove-this
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/rewrite-behind-client-back/data/test3 b/tests/cts/rewrite-behind-client-back/data/test3
new file mode 100644 (file)
index 0000000..61e3557
--- /dev/null
@@ -0,0 +1,42 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Content-Length: 9
+
+Blafasel
+</data>
+</reply>
+
+
+<client>
+<server>
+http
+</server>
+<name>
+Rewrite host behind the client's back
+</name>
+<command>
+http://www.example.org/%TESTNUMBER-%HOSTIP:%HTTPPORT
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1\r
+Host: www.example.org\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/rewrite-behind-client-back/data/test4 b/tests/cts/rewrite-behind-client-back/data/test4
new file mode 100644 (file)
index 0000000..d7c10f8
--- /dev/null
@@ -0,0 +1,42 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 22 Jul 2010 11:22:33 GMT
+Content-Length: 9
+
+Blafasel
+</data>
+</reply>
+
+
+<client>
+<server>
+http
+</server>
+<name>
+Client header filter that doesn't match anything. According to Valgrind it triggers a "Conditional jump or move depends on uninitialised value(s)"
+</name>
+<command>
+http:///%HOSTIP:%HTTPPORT/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1\r
+Host: %HOSTIP:%HTTPPORT\r
+User-Agent: curl/%VERSION\r
+Accept: */*\r
+Connection: close\r
+\r
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/cts/rewrite-behind-client-back/data/test5 b/tests/cts/rewrite-behind-client-back/data/test5
new file mode 100644 (file)
index 0000000..82da79d
--- /dev/null
@@ -0,0 +1,44 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<reply>
+<data>
+HTTP/1.1 200 OK
+Connection: close
+Content-Type: text/html
+Content-Length: 29
+
+Not actually used.
+</data>
+</reply>
+
+<proxy-reply>
+<data>
+HTTP/1.1 400 Malformed request after rewriting
+Content-Type: text/plain
+Connection: close
+
+Bad request. Messed up with header filters.
+</data>
+</proxy-reply>
+
+<client>
+<server>
+none
+</server>
+<name>
+Rewrite behind the client's back: unsupported http version
+</name>
+<command>
+http://%HOSTIP/%TESTNUMBER
+</command>
+</client>
+
+<verify>
+</verify>
+</testcase>
diff --git a/tests/cts/rewrite-behind-client-back/privoxy.conf b/tests/cts/rewrite-behind-client-back/privoxy.conf
new file mode 100644 (file)
index 0000000..0630430
--- /dev/null
@@ -0,0 +1,17 @@
+listen-address 127.0.0.1:9119
+
+debug     1 # Log the destination for each request Privoxy let through. See also debug 1024.
+debug     2 # show each connection status
+debug     4 # show tagging-related messages
+debug     8 # show header parsing
+debug    32 # debug force feature
+debug    64 # debug regular expression filters
+debug   128 # debug redirects
+debug   256 # debug GIF de-animation
+debug   512 # Common Log Format
+debug  1024 # Log the destination for requests Privoxy didn't let through, and the reason why.
+debug  4096 # Startup banner and warnings.
+debug  8192 # Non-fatal errors
+
+actionsfile rewrites.action
+filterfile rewrites.filter
diff --git a/tests/cts/rewrite-behind-client-back/rewrites.action b/tests/cts/rewrite-behind-client-back/rewrites.action
new file mode 100644 (file)
index 0000000..78d3b5f
--- /dev/null
@@ -0,0 +1,14 @@
+{+client-header-filter{http-to-https}}
+/1-upgrade-to-https
+
+{+client-header-filter{truncate-path}}
+/2-remove-this
+
+{+client-header-filter{rewrite-host}}
+/3
+
+{+client-header-filter{non-matching-rewriter}}
+/4
+
+{+client-header-filter{invalid-http-version}}
+/5
diff --git a/tests/cts/rewrite-behind-client-back/rewrites.filter b/tests/cts/rewrite-behind-client-back/rewrites.filter
new file mode 100644 (file)
index 0000000..30f59de
--- /dev/null
@@ -0,0 +1,16 @@
+CLIENT-HEADER-FILTER: http-to-https Upgrade http requests to https behind the client's back. Not actually supported.
+s@^(\w+)\s+http://@$1 https://@i
+
+CLIENT-HEADER-FILTER: truncate-path Removes '-remove-this' from the path
+s@(/\d)-remove-this (HTTP/1.1)@$1 $2@i
+
+CLIENT-HEADER-FILTER: rewrite-host Replaces the host with the one specified in the path
+s@GET .*/(\d)-(\d+\.\d+\.\d+\.\d+\:\d+) (HTTP/1.1)@GET http://$2/$1 $3@i
+
+# Results in Conditional jump or move depends on uninitialised value(s)?
+CLIENT-HEADER-FILTER: non-matching-rewriter Does not actually match
+s@/-@@
+
+CLIENT-HEADER-FILTER: invalid-http-version Rewrites the request line with an invalid HTTP version
+s@HTTP/1.1@HTTP/9000@
+
diff --git a/tests/cts/run-privoxy-tests.sh b/tests/cts/run-privoxy-tests.sh
new file mode 100755 (executable)
index 0000000..1b3e469
--- /dev/null
@@ -0,0 +1,158 @@
+#!/bin/sh
+################################################################################
+#
+# run-privoxy-tests.sh
+#
+# Runs the Privoxy tests based on curl's runtests.pl framework.
+#
+# Copyright (c) 2021 Fabian Keil <fk@fabiankeil.de>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+################################################################################
+
+UPSTREAM_TEST_SCENARIO=upstream-tests
+
+# Delaying the test run by a whole second is annoying on fast systems
+# and may not be long enough on slow systems. There must be a more
+# elegant method to verify that Privoxy is running or failed to start.
+SECONDS_TO_WAIT_FOR_PRIVOXY_TO_START=1
+
+start_privoxy() {
+    local test_dir test_scenario
+    local privoxy_config privoxy_binary pid_file
+    test_dir="${1}"
+    test_scenario="${2}"
+
+    privoxy_config_dir="${test_dir}/${test_scenario}"
+    privoxy_binary="$(realpath "${test_dir}/../../privoxy")"
+    pid_file="${test_dir}/${test_scenario}/../privoxy.pid"
+    log_file="${test_dir}/logs/${test_scenario}.log"
+
+    (
+        cd "${privoxy_config_dir}" || exit 1
+        "${privoxy_binary}" --no-daemon \
+                            --pidfile "${pid_file}" \
+                            privoxy.conf > "${log_file}" 2>&1 || exit 1 &
+    )
+
+    sleep "${SECONDS_TO_WAIT_FOR_PRIVOXY_TO_START}"
+
+    if [ ! -f "${pid_file}" ]; then
+        echo "Privoxy failed to start or did not start in time"
+        if [ -f "${log_file}" ]; then
+            tail -n 1 "${log_file}"
+        fi
+        exit 1
+    fi
+}
+
+stop_privoxy() {
+    local test_dir test_scenario
+    local pid_file
+    test_dir="${1}"
+    test_scenario="${2}"
+    pid_file="${test_dir}/${test_scenario}/../privoxy.pid"
+    if [ -f "${pid_file}" ]; then
+        kill "$(cat "${pid_file}")"
+    fi
+}
+
+run_privoxy_tests() {
+    local start_privoxy="$1"
+    local test_scenario="$2"
+    local directory_name="$(dirname "$0")"
+    local test_dir="$(realpath "${directory_name}")"
+    local ret
+
+    echo "Test scenario: ${test_scenario}"
+    $start_privoxy && start_privoxy "${test_dir}" "${test_scenario}"
+
+    "${test_dir}/runtests-wrapper.sh" -A -E -t "${test_dir}/${test_scenario}/data" HTTP HTTPS
+    ret=$?
+
+    $start_privoxy && stop_privoxy "${test_dir}" "${test_scenario}"
+
+    return $ret
+}
+
+run_upstream_tests() {
+    local start_privoxy="$1"
+    local directory_name="$(dirname "$0")"
+    local test_dir="$(realpath "${directory_name}")"
+    local ret
+
+    echo "Test scenario: ${UPSTREAM_TEST_SCENARIO}"
+    $start_privoxy && start_privoxy "${test_dir}" "${UPSTREAM_TEST_SCENARIO}"
+
+    "${test_dir}/runtests-wrapper.sh" -A -T HTTP
+    ret=$?
+
+    $start_privoxy && stop_privoxy "${test_dir}" "${UPSTREAM_TEST_SCENARIO}"
+
+    return $ret
+}
+
+get_test_scenarios() {
+    local directory_name="$(dirname "$0")"
+    local test_dir="$(realpath "${directory_name}")"
+    local test_scenario
+    local privoxy_config
+
+    for privoxy_config in "${test_dir}"/*/privoxy.conf; do
+        test_scenario="${privoxy_config%%/privoxy.conf}"
+        test_scenario="${test_scenario##$test_dir/}"
+        echo "${test_scenario}"
+    done
+}
+
+main() {
+    local test_scenario=""
+    local test_scenarios=""
+    local start_privoxy=true
+
+    while [ -n "$1" ];
+    do
+        case "$1" in
+            "-r")
+                echo "Not starting privoxy."
+                start_privoxy=false
+                shift
+                ;;
+            "-t")
+                shift
+                test_scenarios="$1"
+                shift
+                ;;
+            *)
+                echo "Invalid parameter: $1"
+                exit 1
+                ;;
+        esac
+    done
+
+    if [ -z "${test_scenarios}" ]; then
+        test_scenarios="$(get_test_scenarios)"
+    fi
+
+    for test_scenario in ${test_scenarios}; do
+        if [ "${test_scenario}" = "${UPSTREAM_TEST_SCENARIO}" ]; then
+            run_upstream_tests ${start_privoxy} || exit 1
+        else
+            run_privoxy_tests ${start_privoxy} "${test_scenario}" || exit 1
+        fi
+    done
+
+    exit 0
+}
+
+main "$@"
diff --git a/tests/cts/runtests-wrapper.sh b/tests/cts/runtests-wrapper.sh
new file mode 100755 (executable)
index 0000000..e56a408
--- /dev/null
@@ -0,0 +1,128 @@
+#!/bin/sh
+################################################################################
+#
+# runtests-wrapper.sh
+#
+# Wrapper around curl's runtests.pl that sets a couple of options
+# so Privoxy is being used.
+#
+# Copyright (c) 2013-2021 Fabian Keil <fk@fabiankeil.de>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+################################################################################
+
+curl_setup_is_sane() {
+    local curl_source_directory="${1}"
+    local curl_binary="${curl_source_directory}/src/curl"
+    local runtests_pl="${curl_source_directory}/tests/runtests.pl"
+
+    if [ ! -d "${curl_source_directory}" ]; then
+        echo "Missing curl source directory at ${curl_source_directory}"
+        return 1
+    fi
+    if [ ! -f "${curl_binary}" ]; then
+        echo "Missing curl binary at ${curl_binary}. Did you compile curl?"
+        return 1
+    fi
+    if [ ! -f "${runtests_pl}" ]; then
+        echo "Did not find runtests.pl at ${runtests_pl}"
+        return 1
+    fi
+
+    return 0
+}
+
+runtests_wrapper() {
+    local extra_args \
+        a_flag proxy_args exclude_file_args testdir_args \
+        privoxy_lib privoxy_ip privoxy_source_directory curl_source_directory \
+        keyword directory_name test_dir
+
+    directory_name="$(dirname "$0")"
+    test_dir="$(realpath "${directory_name}")"
+    privoxy_source_directory="$(realpath "${test_dir}"/../..)"
+    privoxy_lib="${privoxy_source_directory}/tests/cts/privoxy-runtests.pm"
+    curl_source_directory="$(realpath "${privoxy_source_directory}"/../curl)"
+
+    curl_setup_is_sane "${curl_source_directory}" || exit 1
+
+    # Defaults that can be changed through arguments
+    privoxy_ip=127.0.0.1
+    privoxy_port=9119
+    a_flag="-a"
+    proxy_args="-P http://${privoxy_ip}:${privoxy_port}/ -o HOSTIP=${privoxy_ip}"
+    exclude_file_args="-E ${privoxy_source_directory}/tests/cts/curl-test-manifest-for-privoxy"
+    testdir_args="-o TESTDIR=${privoxy_source_directory}/tests/cts/data"
+    keyword=HTTP
+
+    while [ -n "$1" ];
+    do
+        case "$1" in
+            "-A")
+                a_flag=""
+                shift
+                ;;
+            "-E")
+                exclude_file_args=""
+                shift
+                ;;
+            "-k")
+                shift
+                keyword="$1"
+                shift
+                ;;
+            "-i")
+                shift
+                privoxy_ip="$1"
+                shift
+                proxy_args="-P http://${privoxy_ip}:${privoxy_port}/ -o HOSTIP=${privoxy_ip}"
+                ;;
+            "-T")
+                echo "Not setting TESTDIR"
+                testdir_args=""
+                shift
+                ;;
+            "-t")
+                shift
+                echo "Overwriting default TESTDIR with $1"
+                testdir_args="-o TESTDIR=$1"
+                shift
+                ;;
+            "-p")
+                shift
+                privoxy_port="$1"
+                shift
+                proxy_args="-P http://${privoxy_ip}:${privoxy_port}/ -o HOSTIP=${privoxy_ip}"
+                ;;
+            "-P")
+                # "Obviously" -P means not setting -P
+                echo "Not setting '$proxy_args'"
+                proxy_args=""
+                shift
+                ;;
+            *)
+                break;;
+        esac
+    done
+
+    extra_args="$*"
+    
+    cd "${curl_source_directory}/tests" || exit 1
+    ./runtests.pl -L "${privoxy_lib}" $proxy_args $exclude_file_args $testdir_args $a_flag -n $keyword !skip $extra_args
+}
+
+main() {
+    runtests_wrapper "$@"
+}
+
+main "$@"
diff --git a/tests/cts/upstream-tests/privoxy.conf b/tests/cts/upstream-tests/privoxy.conf
new file mode 100644 (file)
index 0000000..2bbef63
--- /dev/null
@@ -0,0 +1,25 @@
+listen-address 127.0.0.1:9119
+
+debug     1 # Log the destination for each request Privoxy let through. See also debug 1024.
+debug     2 # show each connection status
+debug     4 # show tagging-related messages
+debug     8 # show header parsing
+debug    32 # debug force feature
+debug    64 # debug regular expression filters
+debug   128 # debug redirects
+debug   256 # debug GIF de-animation
+debug   512 # Common Log Format
+debug  1024 # Log the destination for requests Privoxy didn't let through, and the reason why.
+debug  4096 # Startup banner and warnings.
+debug  8192 # Non-fatal errors
+
+#debug    16 # log all data written to the network
+#debug 32768 # log all data read from the network
+
+actionsfile ../../../default.action.master
+filterfile ../../../default.filter
+templdir ../../../templates
+
+keep-alive-timeout 5
+socket-timeout 5
+default-server-timeout 5
diff --git a/tests/cts/user-manual-http/data/test1 b/tests/cts/user-manual-http/data/test1
new file mode 100644 (file)
index 0000000..ee986ba
--- /dev/null
@@ -0,0 +1,27 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<client>
+<server>
+none
+</server>
+<name>
+CGI request for the user manual while delivery has been disabled by specifying a http:// URL
+</name>
+<command>
+-s --write-out '%{stderr}%{response_code}\n' --head http://config.privoxy.org/user-manual/
+</command>
+</client>
+
+# It would be better to test more than just the status code
+<verify>
+<stderr>
+404
+</stderr>
+</verify>
+</testcase>
diff --git a/tests/cts/user-manual-http/privoxy.conf b/tests/cts/user-manual-http/privoxy.conf
new file mode 100644 (file)
index 0000000..e2d74e7
--- /dev/null
@@ -0,0 +1,18 @@
+listen-address 127.0.0.1:9119
+
+debug     1 # Log the destination for each request Privoxy let through. See also debug 1024.
+debug     2 # show each connection status
+debug     4 # show tagging-related messages
+debug     8 # show header parsing
+debug    32 # debug force feature
+debug    64 # debug regular expression filters
+debug   128 # debug redirects
+debug   256 # debug GIF de-animation
+debug   512 # Common Log Format
+debug  1024 # Log the destination for requests Privoxy didn't let through, and the reason why.
+debug  4096 # Startup banner and warnings.
+debug  8192 # Non-fatal errors
+
+templdir ../../../templates
+user-manual http://www.privoxy.org/user-manual/
+
diff --git a/tests/cts/user-manual-https/data/test1 b/tests/cts/user-manual-https/data/test1
new file mode 100644 (file)
index 0000000..e9d6acb
--- /dev/null
@@ -0,0 +1,27 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+</keywords>
+</info>
+
+<client>
+<server>
+none
+</server>
+<name>
+CGI request for the user manual while delivery has been disabled by specifying a https:// URL
+</name>
+<command>
+-s --write-out '%{stderr}%{response_code}\n' --head http://config.privoxy.org/user-manual/
+</command>
+</client>
+
+# It would be better to test more than just the status code
+<verify>
+<stderr>
+404
+</stderr>
+</verify>
+</testcase>
diff --git a/tests/cts/user-manual-https/privoxy.conf b/tests/cts/user-manual-https/privoxy.conf
new file mode 100644 (file)
index 0000000..644195c
--- /dev/null
@@ -0,0 +1,18 @@
+listen-address 127.0.0.1:9119
+
+debug     1 # Log the destination for each request Privoxy let through. See also debug 1024.
+debug     2 # show each connection status
+debug     4 # show tagging-related messages
+debug     8 # show header parsing
+debug    32 # debug force feature
+debug    64 # debug regular expression filters
+debug   128 # debug redirects
+debug   256 # debug GIF de-animation
+debug   512 # Common Log Format
+debug  1024 # Log the destination for requests Privoxy didn't let through, and the reason why.
+debug  4096 # Startup banner and warnings.
+debug  8192 # Non-fatal errors
+
+templdir ../../../templates
+user-manual https://www.privoxy.org/user-manual/
+
index 2f28d31..ae18c57 100755 (executable)
@@ -23,7 +23,7 @@
 #         hash key as input.
 #       - Add --compress and --decompress options.
 #
-# Copyright (c) 2007-2021 Fabian Keil <fk@fabiankeil.de>
+# Copyright (c) 2007-2024 Fabian Keil <fk@fabiankeil.de>
 #
 # Permission to use, copy, modify, and distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
@@ -43,7 +43,7 @@ use warnings;
 use Getopt::Long;
 
 use constant {
-    PRIVOXY_LOG_PARSER_VERSION => '0.9.4',
+    PRIVOXY_LOG_PARSER_VERSION => '0.9.5',
     # Feel free to mess with these ...
     DEFAULT_BACKGROUND => 'black',  # Choose registered colour (like 'black')
     DEFAULT_TEXT_COLOUR => 'white', # Choose registered colour (like 'black')
@@ -186,6 +186,8 @@ sub prepare_our_stuff() {
         'configuration-line' => 'red',
         'content-type'       => 'yellow',
         'HOST'               => HEADER_DEFAULT_COLOUR,
+        'tls-version'        => 'pink',
+        'cipher-suite'       => 'light_cyan',
     );
 
     %h_colours = %h;
@@ -1458,7 +1460,8 @@ sub handle_loglevel_crunch($) {
 
     # Highlight crunch reason
     foreach my $reason (keys %reason_colours) {
-        $content =~ s@($reason)@$reason_colours{$reason}$1$h{'Standard'}@g;
+        # Crunch: Blocked: https://capture.condenastdigital.com/track?_o=cne&[...]&dim2=%7B%22adBlocked%[...]
+        $content =~ s@($reason)@$reason_colours{$reason}$1$h{'Standard'}@;
     }
 
     if ($content =~ m/\[too long, truncated\]$/) {
@@ -1571,6 +1574,11 @@ sub handle_loglevel_connect($) {
 
         $c =~ s@(?<=accept failed: )(.*)@$h{'Error'}$1$h{'Standard'}@;
 
+    } elsif ($c =~ m/^Failed to accept\(\) incoming connection:/) {
+
+        # Failed to accept() incoming connection: Software caused connection abort
+        $c =~ s@(?<=connection: )(.*)@$h{'Error'}$1$h{'Standard'}@;
+
     } elsif ($c =~ m/^Overriding forwarding settings/) {
 
         # Overriding forwarding settings based on 'forward 10.0.0.1:8123'
@@ -1645,7 +1653,7 @@ sub handle_loglevel_connect($) {
         $c =~ s@(?<=Assumed latency: )(\d+)@$h{'Number'}$1$h{'Standard'}@;
 
     } elsif ($c =~ m/^Stopped waiting for the request line/ or
-             $c =~ m/^No request line on socket \d received in time/ or
+             $c =~ m/^No request line on socket \d+ received in time/ or
              $c =~ m/^The client side of the connection on socket \d/) {
 
         # Stopped waiting for the request line. Timeout: 121.
@@ -1802,8 +1810,13 @@ sub handle_loglevel_connect($) {
     } elsif ($c =~ m/^Optimistically sending /) {
 
         # Optimistically sending 318 bytes of client headers intended for www.privoxy.org
+        # Optimistically sending 318 bytes of client headers intended for www.privoxy.org.
         $c =~ s@(?<=sending )(\d+)@$h{'Number'}$1$h{'Standard'}@;
-        $c = highlight_matched_host($c, '(?<=for )[^\s]+');
+        if ($c =~ /\.$/) {
+            $c = highlight_matched_host($c, '[^\s]+(?=\.)');
+        } else {
+            $c = highlight_matched_host($c, '(?<=for )[^\s]+');
+        }
 
     } elsif ($c =~ m/^Stopping to watch the client socket/) {
 
@@ -1910,6 +1923,64 @@ sub handle_loglevel_connect($) {
         $c =~ s@(?<=timeout )(\d+)@$h{'Number'}$1$h{'Standard'}@;
         $c = highlight_matched_url($c, "(?<=reached: ).*")
 
+    } elsif ($c =~ m/^Prepared to read up to /) {
+
+        # Prepared to read up to 157 bytes of encrypted request body from the client.
+        $c =~ s@(?<=up to )(\d+)@$h{'Number'}$1$h{'Standard'}@;
+
+    } elsif ($c =~ m/^Forwarding \d+ bytes /) {
+
+        # Forwarding 157 bytes of encrypted request body.
+        $c =~ s@(?<=Forwarding )(\d+)@$h{'Number'}$1$h{'Standard'}@;
+
+    } elsif ($c =~ m/^Buffering encrypted client body/) {
+
+        # Buffering encrypted client body. Prepared to read up to 2236 bytes.
+        $c =~ s@(?<=up to )(\d+)@$h{'Number'}$1$h{'Standard'}@;
+
+    } elsif ($c =~ m/^The last \d+ bytes of the encrypted request body have been read/) {
+
+        # The last 6945 bytes of the encrypted request body have been read.
+        $c =~ s@(?<=The last )(\d+)@$h{'Number'}$1$h{'Standard'}@;
+
+    } elsif ($c =~ m/^Reducing the chunk offset from/) {
+
+        # Reducing the chunk offset from 1096654 to 32704 after discarding 1063950 bytes to make room in the buffer.
+        # Reducing the chunk offset from 16219 to 128 after flushing 16091 bytes.
+        $c =~ s@(?<=\d to )(\d+)@$h{'Number'}$1$h{'Standard'}@;
+        $c =~ s@(?<=offset from )(\d+)@$h{'Number'}$1$h{'Standard'}@;
+        $c =~ s@(?<=after discarding )(\d+)@$h{'Number'}$1$h{'Standard'}@;
+        $c =~ s@(?<=after flushing )(\d+)@$h{'Number'}$1$h{'Standard'}@;
+
+    } elsif ($c =~ m/^Client socket \d+ is no longer usable/) {
+
+        # Client socket 21 is no longer usable. The server socket has been closed.
+        $c =~ s@(?<=Client socket )(\d+)@$h{'Number'}$1$h{'Standard'}@;
+
+    } elsif ($c =~ m/^(Client|Server) successfully connected over/) {
+
+        # Server successfully connected over TLSv1.3 (TLS_AES_256_GCM_SHA384).
+        # Client successfully connected over TLSv1.3 (TLS_AES_128_GCM_SHA256).
+        $c =~ s@(?<=connected over )(TLSv\d\.\d)@$h{'tls-version'}$1$h{'Standard'}@;
+        $c =~ s@(?<=\()([^)]+)@$h{'cipher-suite'}$1$h{'Standard'}@;
+
+    } elsif ($c =~ m/^Couldn't deliver the error message for/) {
+
+        # Couldn't deliver the error message for https://m.media-amazon.com/[...] through client socket 18 using TLS/SSL
+        $c = highlight_matched_url($c, "(?<=error message for )[^ ]*");
+        $c =~ s@(?<=client socket )(\d+)@$h{'Number'}$1$h{'Standard'}@;
+
+    } elsif ($c =~ m/^Keeping chunk offset at/) {
+
+        # Keeping chunk offset at 0 despite flushing 31 bytes.
+        $c =~ s@(?<=offset at )(\d+)@$h{'Number'}$1$h{'Standard'}@;
+        $c =~ s@(?<=flushing )(\d+)@$h{'Number'}$1$h{'Standard'}@;
+
+    } elsif ($c =~ m/^Not shutting down client connection on/) {
+
+        # Not shutting down client connection on socket 8. The socket is no longer alive.
+        $c =~ s@(?<=socket )(\d+)@$h{'Number'}$1$h{'Standard'}@;
+
     } elsif ($c =~ m/^Looks like we / or
              $c =~ m/^Unsetting keep-alive flag/ or
              $c =~ m/^No connections to wait/ or
@@ -2156,6 +2227,10 @@ sub handle_loglevel_error($) {
         $c =~ s@(?<=digested )(\d+)@$h{'Number'}$1$h{'Standard'}@;
         $c =~ s@(?<=of )(\d+)@$h{'Number'}$1$h{'Standard'}@;
 
+    } elsif ($c =~ m/^The socks connection timed out after/) {
+
+        # The socks connection timed out after 60 seconds.
+        $c =~ s@(?<=after )(\d+)@$h{'Number'}$1$h{'Standard'}@;
     }
 
     # XXX: There are probably more messages that deserve highlighting.
@@ -2163,6 +2238,41 @@ sub handle_loglevel_error($) {
     return $c;
 }
 
+sub handle_loglevel_received($) {
+
+    my $c = shift;
+
+    if ($c =~ m/^TLS from socket/) {
+        # TLS from socket 3: \x16\xda\xe2\xa2;\x0d\x0a
+
+        $c =~ s@(?<=TLS from socket )(\d+)@$h{'Number'}$1$h{'Standard'}@;
+
+    } elsif ($c =~ m/^from socket/) {
+        # from socket 3: HEAD http://p.p/ HTTP/1.1\x0d\x0aHost: p.p\x0d\x0aUser-Agent: curl/7.85.0\x0d\x0aAccept: */*\x0d\x0aProxy-Connection: Keep-Alive\x0d\x0a\x0d\x0a
+
+        $c =~ s@(?<=from socket )(\d+)@$h{'Number'}$1$h{'Standard'}@;
+    }
+
+    return $c;
+}
+
+sub handle_loglevel_writing($) {
+
+    my $c = shift;
+
+    if ($c =~ m/^to socket/) {
+        # to socket 11: HTTP/1.1 200 Connection established\x0d\x0a\x0d\x0a
+
+        $c =~ s@(?<=to socket )(\d+)@$h{'Number'}$1$h{'Standard'}@;
+
+    } elsif ($c =~ m/^TLS on socket /) {
+        # TLS on socket 9: o~\xfcS[\xfa\x8f\xd6\x96\xe6_\xc7$\x1b[...]
+
+        $c =~ s@(?<=TLS on socket )(\d+)@$h{'Number'}$1$h{'Standard'}@;
+    }
+
+    return $c;
+}
 
 sub handle_loglevel_ignore($) {
     return shift;
@@ -2621,8 +2731,8 @@ sub parse_loop() {
         'Force'             => \&handle_loglevel_force,
         'Error'             => \&handle_loglevel_error,
         'Fatal error'       => \&handle_loglevel_ignore,
-        'Writing'           => \&handle_loglevel_ignore,
-        'Received'          => \&handle_loglevel_ignore,
+        'Writing'           => \&handle_loglevel_writing,
+        'Received'          => \&handle_loglevel_received,
         'Tagging'           => \&handle_loglevel_tagging,
         'Actions'           => \&handle_loglevel_ignore,
         'Unknown log level' => \&handle_loglevel_ignore,
index 29eb9c1..d9ca098 100755 (executable)
@@ -17,7 +17,7 @@
 # - Document magic Expect Header values
 # - Internal fuzz support?
 #
-# Copyright (c) 2007-2021 Fabian Keil <fk@fabiankeil.de>
+# Copyright (c) 2007-2023 Fabian Keil <fk@fabiankeil.de>
 #
 # Permission to use, copy, modify, and distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
@@ -38,7 +38,7 @@ use strict;
 use Getopt::Long;
 
 use constant {
-    PRT_VERSION => 'Privoxy-Regression-Test 0.7.3',
+    PRT_VERSION => 'Privoxy-Regression-Test 0.7.4',
  
     CURL => 'curl',
 
@@ -1779,6 +1779,11 @@ sub parse_cli_options() {
         'version'            => sub {print_version && exit(0)}
     ) or exit(1);
     $log_level |= $cli_options{'debug'};
+
+    if ($cli_options{'min-level'} > $cli_options{'max-level'}) {
+        log_message("Increasing --max-level to --min-level " . $cli_options{'min-level'});
+        $cli_options{'max-level'} = $cli_options{'min-level'};
+    }
 }
 
 sub cli_option_is_set($) {
@@ -2097,6 +2102,8 @@ a fuzzer.
 
 B<--min-level min-level> Only execute tests with a B<level>
 above or equal to the numerical B<min-level>.
+If the B<min-level> is larger than the B<max-level>,
+the B<max-level> is set to the B<min-level>.
 
 B<--privoxy-address proxy-address> Privoxy's listening address.
 If it's not set, the value of the environment variable http_proxy
index 61e90f6..47dcdc9 100755 (executable)
@@ -17,7 +17,7 @@
 # Mozilla/5.0 (X11; ElectroBSD amd64; rv:78.0) Gecko/20100101 Firefox/78.0
 # Mozilla/5.0 (X11; FreeBSD i386; rv:78.0) Gecko/20100101 Firefox/78.0
 #
-# Copyright (c) 2006-2021 Fabian Keil <fk@fabiankeil.de>
+# Copyright (c) 2006-2023 Fabian Keil <fk@fabiankeil.de>
 #
 # Permission to use, copy, modify, and distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
@@ -39,7 +39,7 @@ use Getopt::Long;
 
 use constant {
 
-   UAGEN_VERSION       => 'uagen 1.2.3',
+   UAGEN_VERSION       => 'uagen 1.2.5',
 
    UAGEN_LOGFILE       => '/var/log/uagen.log',
    ACTION_FILE         => '/etc/privoxy/user-agent.action',
@@ -59,8 +59,8 @@ use constant {
    # are too lazy to check, but want to change them anyway, take the values you
    # see in the "Help/About Mozilla Firefox" menu.
 
-   BROWSER_VERSION                   => "91.0",
-   BROWSER_REVISION                  => '91.0',
+   BROWSER_VERSION                   => "115.0",
+   BROWSER_REVISION                  => '109.0',
    BROWSER_RELEASE_DATE              => '20100101',
 };
 
@@ -138,13 +138,13 @@ sub generate_platform_and_os() {
         FreeBSD => {
             karma             => 1,
             platform          => 'X11',
-            architectures     => [ 'i386', 'amd64', 'sparc64' ],
+            architectures     => [ 'i386', 'amd64' ],
             order_is_inversed => 0,
         },
         OpenBSD => {
             karma             => 1,
             platform          => 'X11',
-            architectures     => [ 'i386', 'amd64', 'sparc64', 'alpha' ],
+            architectures     => [ 'arm64', 'i386', 'amd64', 'sparc64', 'alpha' ],
             order_is_inversed => 0,
         },
         NetBSD => {
@@ -156,7 +156,7 @@ sub generate_platform_and_os() {
         Linux => {
             karma             => 1,
             platform          => 'X11',
-            architectures     => [ 'i586', 'i686', 'x86_64' ],
+            architectures     => [ 'aarch64', 'i586', 'i686', 'x86_64' ],
             order_is_inversed => 0,
         },
         SunOS => {
@@ -324,7 +324,7 @@ sub write_prefs_file() {
 }
 
 sub VersionMessage() {
-    printf UAGEN_VERSION . "\n" . 'Copyright (C) 2006-2020 Fabian Keil <fk@fabiankeil.de> ' .
+    printf UAGEN_VERSION . "\n" . 'Copyright (c) 2006-2022 Fabian Keil <fk@fabiankeil.de> ' .
         "\nhttps://www.fabiankeil.de/sourcecode/uagen/\n";
 }
 
@@ -487,7 +487,9 @@ nor cares if all actions are present. Garbage in, garbage out.
 
 B<--browser-release-date> I<browser_release_date> Date to use.
 The format is YYYYMMDD. Some sanity checks are done, but you
-shouldn't rely on them.
+shouldn't rely on them. Note that the Mozilla project has frozen
+the "Gecko token" starting with Firefox 4 so using a different
+one than the default is somewhat suspicious.
 
 B<--browser-revision> I<browser_revision> Use a custom revision.
 B<uagen> will use it without any sanity checks.
diff --git a/trust b/trust
index d1f58de..e08c47a 100644 (file)
--- a/trust
+++ b/trust
@@ -1,12 +1,11 @@
 ######################################################################
-# 
+#
 #  File        :  trust
-# 
-#  Purpose     :  Trustfiles are an experimental feature and can be used
-#                 to build "whitelists" (versus the usual "blacklists"
-#                 techniques).
-# 
-#  Copyright   :  Written by and Copyright
+#
+#  Purpose     :  Trustfiles can be used to build "allowlists"
+#                 (versus the usual "blocklists" techniques).
+#
+#  Copyright   :  Written by and Copyright (C) 2001-2023 the
 #                 Privoxy team. https://www.privoxy.org/
 #
 #                 Based on the Internet Junkbuster originally written
@@ -15,7 +14,7 @@
 #
 # We value your feedback. However, to provide you with the best support,
 # please note:
-#  
+#
 #  * Use the support forum to get help:
 #    https://sourceforge.net/p/ijbswa/support-requests/
 #  * Submit bugs only thru our bug forum:
 #    please try the latest one. Or even better, git sources.
 #  * Submit feature requests only thru our feature request tracker:
 #    https://sourceforge.net/p/ijbswa/feature-requests/
-#      
+#
 # For any other issues, feel free to use the mailing lists.
 # Anyone interested in actively participating in development and related
 # discussions can join the appropriate mailing list here:
 # https://lists.privoxy.org/mailman/listinfo. Archives are available
 # here too.
-# 
+#
 ######################################################################
 #
 #                      Sample Trustfile for Privoxy
@@ -43,8 +42,8 @@
 # with "trustfile" must be uncommented, with the name of this file following the
 # word "trustfile".
 
-# Trustfiles are an experimental feature used for building "whitelists"
-# of "trusted" sites (versus the usual "blacklists" technique). For more
+# Trustfiles are an experimental feature used for building "allowlists"
+# of "trusted" sites (versus the usual "blocklists" technique). For more
 # detail, see https://www.privoxy.org/user-manual/config.html#TRUSTFILE.
 
 # List trusted domains here. The default is to block any URL that is NOT
 
 # Preceding the domain with '~' character allows access to that domain only
 # (including all paths within that domain), but does not allow access to links
-# to other, outside domains. Sites that are added dynamically by trusted 
+# to other, outside domains. Sites that are added dynamically by trusted
 # referrers will include the '~' character, and thus do not become trusted
 # referrers themselves.
 
 # Example: to allow example.com and to white-list domains that appear to
 # be reached through links from example.com, uncomment this line:
 
-# +example.com 
+# +example.com
 
 # The next two lines make sure that the user can access Privoxy's
 # CGI pages, without automatically trusting their links.
index 750cd24..494a69a 100644 (file)
@@ -105,7 +105,7 @@ void free_http_request(struct http_request *http)
  * Description :  Splits the domain name so we can compare it
  *                against wildcards. It used to be part of
  *                parse_http_url, but was separated because the
- *                same code is required in chat in case of
+ *                same code is required in chat() in case of
  *                intercepted requests.
  *
  * Parameters  :
@@ -245,7 +245,7 @@ jb_err parse_http_url(const char *url, struct http_request *http, int require_pr
 
 
    /*
-    * Split URL into protocol,hostport,path.
+    * Split URL into protocol, hostport, path.
     */
    {
       char *buf;
@@ -604,6 +604,100 @@ jb_err parse_http_request(const char *req, struct http_request *http)
 }
 
 
+#ifdef HAVE_PCRE2
+/*********************************************************************
+ *
+ * Function    :  compile_pattern
+ *
+ * Description :  Compiles a host, domain or TAG pattern.
+ *
+ * Parameters  :
+ *          1  :  pattern = The pattern to compile.
+ *          2  :  anchoring = How the regex should be modified
+ *                            before compilation. Can be either
+ *                            one of NO_ANCHORING, LEFT_ANCHORED,
+ *                            RIGHT_ANCHORED or RIGHT_ANCHORED_HOST.
+ *          3  :  url     = In case of failures, the spec member is
+ *                          logged and the structure freed.
+ *          4  :  regex   = Where the compiled regex should be stored.
+ *
+ * Returns     :  JB_ERR_OK - Success
+ *                JB_ERR_PARSE - Cannot parse regex
+ *
+ *********************************************************************/
+static jb_err compile_pattern(const char *pattern, enum regex_anchoring anchoring,
+                              struct pattern_spec *url, pcre2_code **regex)
+{
+   int errcode;
+   const char *fmt = NULL;
+   char *rebuf;
+   size_t rebuf_size;
+   PCRE2_SIZE error_offset;
+   int ret;
+
+   assert(pattern);
+
+   if (pattern[0] == '\0')
+   {
+      *regex = NULL;
+      return JB_ERR_OK;
+   }
+
+   switch (anchoring)
+   {
+      case NO_ANCHORING:
+         fmt = "%s";
+         break;
+      case RIGHT_ANCHORED:
+         fmt = "%s$";
+         break;
+      case RIGHT_ANCHORED_HOST:
+         fmt = "%s\\.?$";
+         break;
+      case LEFT_ANCHORED:
+         fmt = "^%s";
+         break;
+      default:
+         log_error(LOG_LEVEL_FATAL,
+            "Invalid anchoring in compile_pattern %d", anchoring);
+   }
+   rebuf_size = strlen(pattern) + strlen(fmt);
+   rebuf = malloc_or_die(rebuf_size);
+
+   snprintf(rebuf, rebuf_size, fmt, pattern);
+
+   *regex = pcre2_compile((const unsigned char *)rebuf,
+      PCRE2_ZERO_TERMINATED, PCRE2_CASELESS, &errcode,
+      &error_offset, NULL);
+   if (*regex == NULL)
+   {
+      log_error(LOG_LEVEL_ERROR, "error compiling %s from %s: %s",
+         pattern, url->spec, rebuf);
+      freez(rebuf);
+
+      return JB_ERR_PARSE;
+   }
+
+#ifndef DISABLE_PCRE_JIT_COMPILATION
+   /* Try to enable JIT compilation but continue if it's unsupported. */
+   if ((ret = pcre2_jit_compile(*regex, PCRE2_JIT_COMPLETE)) &&
+       (ret != PCRE2_ERROR_JIT_BADOPTION))
+   {
+      log_error(LOG_LEVEL_ERROR,
+         "Unexpected error enabling JIT compilation for %s from %s: %s",
+         pattern, url->spec, rebuf);
+      freez(rebuf);
+
+      return JB_ERR_PARSE;
+   }
+#endif
+
+   freez(rebuf);
+
+   return JB_ERR_OK;
+
+}
+#else
 /*********************************************************************
  *
  * Function    :  compile_pattern
@@ -686,6 +780,7 @@ static jb_err compile_pattern(const char *pattern, enum regex_anchoring anchorin
    return JB_ERR_OK;
 
 }
+#endif
 
 
 /*********************************************************************
@@ -1051,6 +1146,72 @@ static int simplematch(const char *pattern, const char *text)
 }
 
 
+#ifdef HAVE_PCRE2
+/*********************************************************************
+ *
+ * Function    :  pcre2_pattern_matches
+ *
+ * Description :  Checks if a compiled pcre2 pattern matches a string.
+ *
+ * Parameters  :
+ *          1  :  pattern = The compiled pattern
+ *          2  :  string = The string to check
+ *
+ * Returns     :  TRUE for yes, FALSE otherwise.
+ *
+ *********************************************************************/
+static int pcre2_pattern_matches(const pcre2_code *pattern, const char *string)
+{
+   PCRE2_SIZE offset;
+   int ret;
+   pcre2_match_data *pcre2_matches;
+
+   assert(pattern != NULL);
+   assert(string != NULL);
+
+   offset = 0;
+
+   pcre2_matches = pcre2_match_data_create_from_pattern(pattern, NULL);
+   if (NULL == pcre2_matches)
+   {
+      log_error(LOG_LEVEL_ERROR,
+         "Out of memory while matching pattern against %s", string);
+      return FALSE;
+   }
+
+   ret = pcre2_match(pattern, (const unsigned char *)string, strlen(string),
+      offset, 0, pcre2_matches, NULL);
+
+   pcre2_match_data_free(pcre2_matches);
+
+   return (ret >= 0);
+}
+#endif
+
+
+/*********************************************************************
+ *
+ * Function    :  regex_matches
+ *
+ * Description :  Checks if a compiled regex pattern matches a string
+ *                using either pcre2 or pcre1 code.
+ *
+ * Parameters  :
+ *          1  :  pattern = The compiled pattern
+ *          2  :  string = The string to check
+ *
+ * Returns     :  TRUE for yes, FALSE otherwise.
+ *
+ *********************************************************************/
+int regex_matches(const REGEX_TYPE *pattern, const char *string)
+{
+#ifdef HAVE_PCRE2
+   return pcre2_pattern_matches(pattern, string);
+#else
+   return (0 == regexec(pattern, string, 0, NULL, 0));
+#endif
+}
+
 /*********************************************************************
  *
  * Function    :  simple_domaincmp
@@ -1268,8 +1429,12 @@ void free_pattern_spec(struct pattern_spec *pattern)
    {
       if (pattern->pattern.tag_regex)
       {
+#ifdef HAVE_PCRE2
+         pcre2_code_free(pattern->pattern.tag_regex);
+#else
          regfree(pattern->pattern.tag_regex);
          freez(pattern->pattern.tag_regex);
+#endif
       }
       return;
    }
@@ -1277,8 +1442,12 @@ void free_pattern_spec(struct pattern_spec *pattern)
 #ifdef FEATURE_PCRE_HOST_PATTERNS
    if (pattern->pattern.url_spec.host_regex)
    {
+#ifdef HAVE_PCRE2
+      pcre2_code_free(pattern->pattern.url_spec.host_regex);
+#else
       regfree(pattern->pattern.url_spec.host_regex);
       freez(pattern->pattern.url_spec.host_regex);
+#endif
    }
 #endif /* def FEATURE_PCRE_HOST_PATTERNS */
    freez(pattern->pattern.url_spec.dbuffer);
@@ -1287,8 +1456,12 @@ void free_pattern_spec(struct pattern_spec *pattern)
    freez(pattern->pattern.url_spec.port_list);
    if (pattern->pattern.url_spec.preg)
    {
+#ifdef HAVE_PCRE2
+      pcre2_code_free(pattern->pattern.url_spec.preg);
+#else
       regfree(pattern->pattern.url_spec.preg);
       freez(pattern->pattern.url_spec.preg);
+#endif
    }
 }
 
@@ -1333,8 +1506,7 @@ static int host_matches(const struct http_request *http,
    if (pattern->pattern.url_spec.host_regex_type == PCRE_HOST_PATTERN)
    {
       return ((NULL == pattern->pattern.url_spec.host_regex)
-         || (0 == regexec(pattern->pattern.url_spec.host_regex,
-               http->host, 0, NULL, 0)));
+         || regex_matches(pattern->pattern.url_spec.host_regex, http->host));
    }
 #endif
    return ((NULL == pattern->pattern.url_spec.dbuffer) || (0 == domain_match(pattern, http)));
@@ -1357,7 +1529,7 @@ static int host_matches(const struct http_request *http,
 static int path_matches(const char *path, const struct pattern_spec *pattern)
 {
    return ((NULL == pattern->pattern.url_spec.preg)
-      || (0 == regexec(pattern->pattern.url_spec.preg, path, 0, NULL, 0)));
+      || regex_matches(pattern->pattern.url_spec.preg, path));
 }
 
 
index 315e8b2..543f2b8 100644 (file)
@@ -50,6 +50,8 @@ extern int url_requires_percent_encoding(const char *url);
 extern int url_match(const struct pattern_spec *pattern,
                      const struct http_request *http);
 
+int regex_matches(const REGEX_TYPE *pattern, const char *string);
+
 extern jb_err create_pattern_spec(struct pattern_spec *url, char *buf);
 extern void free_pattern_spec(struct pattern_spec *url);
 extern int match_portlist(const char *portlist, int port);
index 4d93a80..7523cdb 100644 (file)
@@ -5,6 +5,9 @@
 #  Purpose     :  User-maintained actions file, see
 #                 https://www.privoxy.org/user-manual/actions-file.html
 #
+#  Copyright   :  Written by and Copyright (C) 2002-2022 the
+#                 Privoxy team. https://www.privoxy.org/
+#
 ######################################################################
 
 # This is the place to add your personal exceptions and additions to
@@ -194,6 +197,11 @@ www.example.com/nasty-ads/sponsor.gif
 #{+block{Facebook "like" and similar tracking URLs.}}
 #www.facebook.com/(extern|plugins)/(login_status|like(box)?|activity|fan)\.php
 
+# Hide cookie and privacy information banner on the Bundeswehr website.
+# The relevant parts seem to work without accepting cookies.
+# {+filter{bundeswehr.de}}
+# .bundeswehr.de/
+
 ######### Examples for SSL actions #########
 # Following section enables TLS/SSL filtering for all sites defined by pattern and requested by HTTPS.
 # {+https-inspection}
diff --git a/win32.c b/win32.c
index 39a4819..c9d5c4e 100644 (file)
--- a/win32.c
+++ b/win32.c
@@ -65,7 +65,7 @@
  */
 const char win32_blurb[] =
 "Privoxy version " VERSION " for Windows\n"
-"Copyright (C) 2000-2021 the Privoxy Team (" HOME_PAGE_URL ")\n"
+"Copyright (C) 2000-2023 the Privoxy Team (" HOME_PAGE_URL ")\n"
 "Based on the Internet Junkbuster by Junkbusters Corp.\n"
 "This is free software; it may be used and copied under the\n"
 "GNU General Public License, version 2: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html\n"
index 4d0f2ae..fa063ff 100755 (executable)
@@ -20,6 +20,7 @@ fi
 # --enable-mingw32                Use mingw32 for a Windows GUI
 # --enable-static-linking         Use static linking instead of dynamic linking (and not have
 #                                 to put all the .DLLs in the path or the same dir as Privoxy)
+# --disable-pcre2                 Don't try to use the pcre2 library even if it's available
 # --disable-pthread               Use native threads instead of POSIX pthreads library
 # --disable-dynamic-pcre          Use the built-in, static pcre, even if libpcre is available
 # --with-docbook=yes              Enable docbook documentation creation
@@ -38,6 +39,11 @@ export LDFLAGS=""
 # start with initially empty flags
 
 
+CFLAGS="${CFLAGS} -fdiagnostics-color=always"
+# Have gcc diagnostics be in color even if stderr is not going to a terminal.
+# It's nice having warnings in color even if I run a script that does
+#   'make 2>&1 | tee log.make'
+
 CFLAGS="${CFLAGS} -fstack-protector-strong -D_FORTIFY_SOURCE=2"
 LDFLAGS="${LDFLAGS} -fstack-protector-strong"
 # -fstack-protector-strong:  enable stack checking.
@@ -52,7 +58,7 @@ LDFLAGS="${LDFLAGS} -fstack-protector-strong"
 # -D_FORTIFY_SOURCE:  detect some buffer overflow errors
 #     ***>> requires compiler optimization level 1 or above <<***
 # see : https://gcc.gnu.org/legacy-ml/gcc-patches/2004-09/msg02055.html
-#   The diffence between -D_FORTIFY_SOURCE=1 and -D_FORTIFY_SOURCE=2 is e.g. for
+#   The difference between -D_FORTIFY_SOURCE=1 and -D_FORTIFY_SOURCE=2 is e.g. for
 #     struct S { struct T { char buf[5]; int x; } t; char buf[20]; } var;
 #   With -D_FORTIFY_SOURCE=1,
 #     strcpy (&var.t.buf[1], "abcdefg");
@@ -80,7 +86,6 @@ LDFLAGS="${LDFLAGS} -Wl,--nxcompat"
 #   $ peflags -v privoxy.exe
 #   privoxy.exe: coff(0x0106[+executable_image,+line_nums_stripped,+32bit_machine]) pe(0x0140[+dynamicbase,+nxcompat])
 
-
 LDFLAGS="${LDFLAGS} -Wl,--dynamicbase,--export-all-symbols"
 # https://en.wikipedia.org/wiki/Address_space_layout_randomization
 # https://stackoverflow.com/questions/24283918/how-can-i-enable-aslr-dep-and-safeseh-on-an-exe-in-codeblocks-using-mingw
@@ -92,8 +97,6 @@ CFLAGS="${CFLAGS} -Wall"
 # see: http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
 # -Wall   doesn't actually turn on all warnings, so add  -Wextra
 #    but then plenty too many complaints by
-#      -Wimplicit-fallthrough=3
-#         too many warnings in pcre/study.c & pcre.c
 #      -Wmissing-field-initializers
 #      -Wsign-compare
 #      -Wtype-limits
@@ -105,6 +108,9 @@ CFLAGS="${CFLAGS} -Wno-unused-parameter -Wno-unused-but-set-variable"
 #-no-# CFLAGS="${CFLAGS} -Wconversion"
 #   way too many warnings for things that don't look like a problem
 
+CFLAGS="${CFLAGS} -Wno-deprecated-declarations"
+#   way too many warnings in openssl.c about RSA deprecated-declarations
+
 #-no-# CFLAGS="${CFLAGS} -Werror"
 # Turn all warnings into errors.
 #   Privoxy still has a few warnings that are not a problem
@@ -129,19 +135,45 @@ CFLAGS="${CFLAGS} -Wshadow"
 
 # why does the mingw library _not_ include .a files for libpcre?
 # *sigh* build my own pcre so I can do static linking
-# Get the 8.x PCRE library from  https://ftp.pcre.org/pub/pcre/
-inc="/source/pcre-8.45/"
-lib="/source/pcre-8.45/.libs"
+# Get the 8.x PCRE library from
+#   https://sourceforge.net/projects/pcre/files/pcre/
+# Get the 10.x PCRE2 library from
+#   https://github.com/PCRE2Project/pcre2/releases
+#
+#
+usepcre2=yes
+#
+#
+if [ "$usepcre2" = "yes" ]; then
+    PCREOPT=""
+    inc="/source/pcre2-10.42/src/"
+      # need pcre2.h
+    lib="/source/pcre2-10.42/.libs"
+      # need libpcre2-8.a & libpcre2-posix.a
+else
+    PCREOPT="--disable-pcre2"
+    inc="/source/pcre-8.45/"
+    lib="/source/pcre-8.45/.libs"
+fi
 CPPFLAGS="${CPPFLAGS} -I${inc}"
 LDFLAGS="${LDFLAGS} -L${lib}"
 
 # mbedtls
-# Get the 2.16.x mbedtls library from  https://github.com/ARMmbed/mbedtls/tags
-inc="/source/mbedtls-2.16.11/include"
-lib="/source/mbedtls-2.16.11/library"
-MITMOPT="--with-mbedtls"
-CPPFLAGS="${CPPFLAGS} -I${inc}"
-LDFLAGS="${LDFLAGS} -L${lib}"
+## https://github.com/Mbed-TLS/mbedtls/releases/tag/v2.16.12
+##   This is the last release of the 2.16 long-time support branch.
+##   Users who want a long-time branch should move to mbedtls-2.28,
+##   which is backward-compatible and will be supported for at least
+##   3 years.
+# Get the 2.28.x mbedtls library from  https://github.com/Mbed-TLS/mbedtls/tags
+# Release Notes: https://github.com/Mbed-TLS/mbedtls/releases/tag/v2.28.4
+
+##MITMOPT="--with-mbedtls"
+##inc="/source/mbedtls-2.28.4/include"
+##lib="/source/mbedtls-2.28.4/library"
+##CPPFLAGS="${CPPFLAGS} -I${inc}"
+##LDFLAGS="${LDFLAGS} -L${lib}"
+
+MITMOPT="--with-openssl"
 
 # brotli
 # Get the brotli library from  https://github.com/google/brotli/releases
@@ -163,12 +195,13 @@ echo "LDFLAGS=${LDFLAGS}"
 
 ./configure  --host=i686-w64-mingw32  --enable-mingw32  --enable-zlib \
              --enable-extended-statistics \
+             ${PCREOPT} \
              --enable-pcre-host-patterns \
              --enable-static-linking \
              --enable-strptime-sanity-checks \
              --disable-pthread  \
              --with-brotli  \
-             --with-mbedtls \
+             ${MITMOPT} \
              --with-docbook=yes
 
 #  -- done --
index b18f27d..45b7193 100755 (executable)
@@ -243,7 +243,7 @@ UDM     Up-down control
 !define WM_CLEAR                        0x0303\r
 !define WM_CLOSE                        0x0010\r
 !define WM_COMMAND                      0x0111\r
-!define WM_COMMNOTIFY                   0x0044  # no longer suported\r
+!define WM_COMMNOTIFY                   0x0044  # no longer supported\r
 !define WM_COMPACTING                   0x0041\r
 !define WM_COMPAREITEM                  0x0039\r
 !define WM_CONTEXTMENU                  0x007B\r
@@ -573,4 +573,4 @@ UDM     Up-down control
 !define TCM_FIRST                   0x1300\r
 \r
 !verbose pop\r
-!endif
\ No newline at end of file
+!endif\r
index 89bb625..376cba9 100755 (executable)
@@ -111,7 +111,7 @@ SetDatablockOptimize on
 CRCCheck on
 AutoCloseWindow true ; (can be true for the window go away automatically at end)
 ShowInstDetails nevershow ; (can be show to have them shown, or nevershow to disable)
-SetDateSave on ; (can be on to have files restored to their orginal date)
+SetDateSave on ; (can be on to have files restored to their original date)
 ; SetOverwrite ifnewer ; (files are only overwritten if the existing file is older than the new file)
 SetOverwrite on  ; install package files over-write existing files regardless of date
 
diff --git a/wolfssl.c b/wolfssl.c
new file mode 100644 (file)
index 0000000..7f6c964
--- /dev/null
+++ b/wolfssl.c
@@ -0,0 +1,2001 @@
+/*********************************************************************
+ *
+ * File        :  $Source: /cvsroot/ijbswa/current/wolfssl.c,v $
+ *
+ * Purpose     :  File with TLS/SSL extension. Contains methods for
+ *                creating, using and closing TLS/SSL connections
+ *                using wolfSSL.
+ *
+ * Copyright   :  Copyright (C) 2018-2024 by Fabian Keil <fk@fabiankeil.de>
+ *                Copyright (C) 2020 Maxim Antonov <mantonov@gmail.com>
+ *                Copyright (C) 2017 Vaclav Svec. FIT CVUT.
+ *
+ *                This program is free software; you can redistribute it
+ *                and/or modify it under the terms of the GNU General
+ *                Public License as published by the Free Software
+ *                Foundation; either version 2 of the License, or (at
+ *                your option) any later version.
+ *
+ *                This program is distributed in the hope that it will
+ *                be useful, but WITHOUT ANY WARRANTY; without even the
+ *                implied warranty of MERCHANTABILITY or FITNESS FOR A
+ *                PARTICULAR PURPOSE.  See the GNU General Public
+ *                License for more details.
+ *
+ *                The GNU General Public License should be included with
+ *                this file.  If not, you can view it at
+ *                http://www.gnu.org/copyleft/gpl.html
+ *                or write to the Free Software Foundation, Inc., 59
+ *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ *********************************************************************/
+
+#include <string.h>
+#include <unistd.h>
+#include <assert.h>
+#include "config.h"
+
+#include <wolfssl/options.h>
+#include <wolfssl/openssl/x509v3.h>
+#include <wolfssl/openssl/pem.h>
+#include <wolfssl/ssl.h>
+#include <wolfssl/wolfcrypt/coding.h>
+#include <wolfssl/wolfcrypt/rsa.h>
+
+#include "project.h"
+#include "miscutil.h"
+#include "errlog.h"
+#include "encode.h"
+#include "jcc.h"
+#include "jbsockets.h"
+#include "ssl.h"
+#include "ssl_common.h"
+
+static int ssl_certificate_is_invalid(const char *cert_file);
+static int generate_host_certificate(struct client_state *csp,
+   const char *certificate_path, const char *key_path);
+static void free_client_ssl_structures(struct client_state *csp);
+static void free_server_ssl_structures(struct client_state *csp);
+static int ssl_store_cert(struct client_state *csp, X509 *crt);
+static void log_ssl_errors(int debuglevel, const char* fmt, ...) __attribute__((format(printf, 2, 3)));
+
+static int wolfssl_initialized = 0;
+
+/*
+ * Whether or not sharing the RNG is thread-safe
+ * doesn't matter because we only use it with
+ * the certificate_mutex locked.
+ */
+static WC_RNG wolfssl_rng;
+
+#ifndef WOLFSSL_ALT_CERT_CHAINS
+/*
+ * Without WOLFSSL_ALT_CERT_CHAINS wolfSSL will reject valid
+ * certificates if the certificate chain contains CA certificates
+ * that are "only" signed by trusted CA certificates but aren't
+ * trusted CAs themselves.
+ */
+#warning wolfSSL has been compiled without WOLFSSL_ALT_CERT_CHAINS
+#endif
+
+/*********************************************************************
+ *
+ * Function    :  wolfssl_init
+ *
+ * Description :  Initializes wolfSSL library once
+ *
+ * Parameters  :  N/A
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+static void wolfssl_init(void)
+{
+   if (wolfssl_initialized == 0)
+   {
+      privoxy_mutex_lock(&ssl_init_mutex);
+      if (wolfssl_initialized == 0)
+      {
+         if (wolfSSL_Init() != WOLFSSL_SUCCESS)
+         {
+            log_error(LOG_LEVEL_FATAL, "Failed to initialize wolfSSL");
+         }
+         wc_InitRng(&wolfssl_rng);
+         wolfssl_initialized = 1;
+      }
+      privoxy_mutex_unlock(&ssl_init_mutex);
+   }
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  is_ssl_pending
+ *
+ * Description :  Tests if there are some waiting data on ssl connection.
+ *                Only considers data that has actually been received
+ *                locally and ignores data that is still on the fly
+ *                or has not yet been sent by the remote end.
+ *
+ * Parameters  :
+ *          1  :  ssl_attr = SSL context to test
+ *
+ * Returns     :   0 => No data are pending
+ *                >0 => Pending data length. XXX: really?
+ *
+ *********************************************************************/
+extern size_t is_ssl_pending(struct ssl_attr *ssl_attr)
+{
+   return (size_t)wolfSSL_pending(ssl_attr->wolfssl_attr.ssl);
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  ssl_send_data
+ *
+ * Description :  Sends the content of buf (for n bytes) to given SSL
+ *                connection context.
+ *
+ * Parameters  :
+ *          1  :  ssl_attr = SSL context to send data to
+ *          2  :  buf = Pointer to data to be sent
+ *          3  :  len = Length of data to be sent to the SSL context
+ *
+ * Returns     :  Length of sent data or negative value on error.
+ *
+ *********************************************************************/
+extern int ssl_send_data(struct ssl_attr *ssl_attr, const unsigned char *buf, size_t len)
+{
+   WOLFSSL *ssl;
+   int ret = 0;
+   int pos = 0; /* Position of unsent part in buffer */
+   int fd = -1;
+
+   if (len == 0)
+   {
+      return 0;
+   }
+
+   ssl = ssl_attr->wolfssl_attr.ssl;
+   fd = wolfSSL_get_fd(ssl);
+
+   while (pos < len)
+   {
+      int send_len = (int)len - pos;
+
+      log_error(LOG_LEVEL_WRITING, "TLS on socket %d: %N",
+         fd, send_len, buf+pos);
+
+      ret = wolfSSL_write(ssl, buf+pos, send_len);
+      if (ret <= 0)
+      {
+         log_ssl_errors(LOG_LEVEL_ERROR,
+            "Sending data on socket %d over TLS failed", fd);
+         return -1;
+      }
+
+      /* Adding count of sent bytes to position in buffer */
+      pos = pos + ret;
+   }
+
+   return (int)len;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  ssl_recv_data
+ *
+ * Description :  Receives data from given SSL context and puts
+ *                it into buffer.
+ *
+ * Parameters  :
+ *          1  :  ssl_attr = SSL context to receive data from
+ *          2  :  buf = Pointer to buffer where data will be written
+ *          3  :  max_length = Maximum number of bytes to read
+ *
+ * Returns     :  Number of bytes read, 0 for EOF, or -1
+ *                on error.
+ *
+ *********************************************************************/
+extern int ssl_recv_data(struct ssl_attr *ssl_attr, unsigned char *buf, size_t max_length)
+{
+   WOLFSSL *ssl;
+   int ret = 0;
+   int fd = -1;
+
+   memset(buf, 0, max_length);
+
+   /*
+    * Receiving data from SSL context into buffer
+    */
+   ssl = ssl_attr->wolfssl_attr.ssl;
+   ret = wolfSSL_read(ssl, buf, (int)max_length);
+   fd = wolfSSL_get_fd(ssl);
+
+   if (ret < 0)
+   {
+      log_ssl_errors(LOG_LEVEL_ERROR,
+         "Receiving data on socket %d over TLS failed", fd);
+
+      return -1;
+   }
+
+   log_error(LOG_LEVEL_RECEIVED, "TLS from socket %d: %N",
+      fd, ret, buf);
+
+   return ret;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  get_public_key_size_string
+ *
+ * Description : Translates a public key type to a string.
+ *
+ * Parameters  :
+ *          1  :  key_type = The public key type.
+ *
+ * Returns     :  String containing the translated key size.
+ *
+ *********************************************************************/
+static const char *get_public_key_size_string(int key_type)
+{
+   switch (key_type)
+   {
+      case EVP_PKEY_RSA:
+         return "RSA key size";
+      case EVP_PKEY_DSA:
+         return "DSA key size";
+      case EVP_PKEY_EC:
+         return "EC key size";
+      default:
+         return "non-RSA/DSA/EC key size";
+   }
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  ssl_store_cert
+ *
+ * Description : This function is called once for each certificate in the
+ *               server's certificate trusted chain and prepares
+ *               information about the certificate. The information can
+ *               be used to inform the user about invalid certificates.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  cert = certificate from trusted chain
+ *
+ * Returns     :  0 on success and negative value on error
+ *
+ *********************************************************************/
+static int ssl_store_cert(struct client_state *csp, X509 *cert)
+{
+   long len;
+   struct certs_chain *last = &(csp->server_certs_chain);
+   int ret = 0;
+   WOLFSSL_BIO *bio = BIO_new(BIO_s_mem());
+   WOLFSSL_EVP_PKEY *pkey = NULL;
+   char *bio_mem_data = NULL;
+   char *encoded_text;
+   long l;
+   unsigned char serial_number[32];
+   int  serial_number_size = sizeof(serial_number);
+   WOLFSSL_X509_NAME *issuer_name;
+   WOLFSSL_X509_NAME *subject_name;
+   char *subject_alternative_name;
+   int loc;
+   int san_prefix_printed = 0;
+
+   if (!bio)
+   {
+      log_ssl_errors(LOG_LEVEL_ERROR, "BIO_new() failed");
+      return -1;
+   }
+
+   /*
+    * Searching for last item in certificates linked list
+    */
+   while (last->next != NULL)
+   {
+      last = last->next;
+   }
+
+   /*
+    * Preparing next item in linked list for next certificate
+    */
+   last->next = zalloc_or_die(sizeof(struct certs_chain));
+
+   /*
+    * Saving certificate file into buffer
+    */
+   if (wolfSSL_PEM_write_bio_X509(bio, cert) != WOLFSSL_SUCCESS)
+   {
+      log_ssl_errors(LOG_LEVEL_ERROR, "wolfSSL_PEM_write_bio_X509() failed");
+      ret = -1;
+      goto exit;
+   }
+
+   len = wolfSSL_BIO_get_mem_data(bio, &bio_mem_data);
+   last->file_buf = malloc((size_t)len + 1);
+   if (last->file_buf == NULL)
+   {
+      log_error(LOG_LEVEL_ERROR,
+         "Failed to allocate %lu bytes to store the X509 PEM certificate",
+         len + 1);
+      ret = -1;
+      goto exit;
+   }
+
+   strncpy(last->file_buf, bio_mem_data, (size_t)len);
+   last->file_buf[len] = '\0';
+   wolfSSL_BIO_free(bio);
+   bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
+   if (!bio)
+   {
+      log_ssl_errors(LOG_LEVEL_ERROR, "wolfSSL_BIO_new() failed");
+      ret = -1;
+      goto exit;
+   }
+
+   /*
+    * Saving certificate information into buffer
+    */
+   l = wolfSSL_X509_get_version(cert);
+   if (l >= 0 && l <= 2)
+   {
+      if (wolfSSL_BIO_printf(bio, "cert. version     : %ld\n", l + 1) <= 0)
+      {
+         log_ssl_errors(LOG_LEVEL_ERROR,
+            "wolfSSL_BIO_printf() for version failed");
+         ret = -1;
+         goto exit;
+      }
+   }
+   else
+   {
+      if (wolfSSL_BIO_printf(bio, "cert. version     : Unknown (%ld)\n", l) <= 0)
+      {
+         log_ssl_errors(LOG_LEVEL_ERROR,
+            "wolfSSL_BIO_printf() for version failed");
+         ret = -1;
+         goto exit;
+      }
+   }
+
+   if (wolfSSL_BIO_puts(bio, "serial number     : ") <= 0)
+   {
+      log_ssl_errors(LOG_LEVEL_ERROR,
+         "wolfSSL_BIO_puts() for serial number failed");
+      ret = -1;
+      goto exit;
+   }
+   if (wolfSSL_X509_get_serial_number(cert, serial_number, &serial_number_size)
+      != WOLFSSL_SUCCESS)
+   {
+      log_error(LOG_LEVEL_ERROR, "wolfSSL_X509_get_serial_number() failed");
+      ret = -1;
+      goto exit;
+   }
+
+   if (serial_number_size <= (int)sizeof(char))
+   {
+      if (wolfSSL_BIO_printf(bio, "%lu (0x%lx)\n", serial_number[0],
+            serial_number[0]) <= 0)
+      {
+         log_ssl_errors(LOG_LEVEL_ERROR,
+            "wolfSSL_BIO_printf() for serial number as single byte failed");
+         ret = -1;
+         goto exit;
+      }
+   }
+   else
+   {
+      int i;
+      for (i = 0; i < serial_number_size; i++)
+      {
+         if (wolfSSL_BIO_printf(bio, "%02x%c", serial_number[i],
+               ((i + 1 == serial_number_size) ? '\n' : ':')) <= 0)
+         {
+            log_ssl_errors(LOG_LEVEL_ERROR,
+               "wolfSSL_BIO_printf() for serial number bytes failed");
+            ret = -1;
+            goto exit;
+         }
+      }
+   }
+
+   if (wolfSSL_BIO_puts(bio, "issuer name       : ") <= 0)
+   {
+      log_ssl_errors(LOG_LEVEL_ERROR, "wolfSSL_BIO_puts() for issuer failed");
+      ret = -1;
+      goto exit;
+   }
+   issuer_name = wolfSSL_X509_get_issuer_name(cert);
+   if (wolfSSL_X509_NAME_get_sz(issuer_name) <= 0)
+   {
+      if (wolfSSL_BIO_puts(bio, "none") <= 0)
+      {
+         log_ssl_errors(LOG_LEVEL_ERROR,
+            "wolfSSL_BIO_puts() for issuer name failed");
+         ret = -1;
+         goto exit;
+      }
+   }
+   else if (wolfSSL_X509_NAME_print_ex(bio, issuer_name, 0, 0) < 0)
+   {
+      log_ssl_errors(LOG_LEVEL_ERROR,
+         "wolfSSL_X509_NAME_print_ex() for issuer failed");
+      ret = -1;
+      goto exit;
+   }
+
+   if (wolfSSL_BIO_puts(bio, "\nsubject name      : ") <= 0)
+   {
+      log_ssl_errors(LOG_LEVEL_ERROR,
+         "wolfSSL_BIO_puts() for subject name failed");
+      ret = -1;
+      goto exit;
+   }
+   subject_name = wolfSSL_X509_get_subject_name(cert);
+   if (wolfSSL_X509_NAME_get_sz(subject_name) <= 0)
+   {
+      if (wolfSSL_BIO_puts(bio, "none") <= 0)
+      {
+         log_ssl_errors(LOG_LEVEL_ERROR,
+            "wolfSSL_BIO_puts() for subject name failed");
+         ret = -1;
+         goto exit;
+      }
+   }
+   else if (wolfSSL_X509_NAME_print_ex(bio, subject_name, 0, 0) < 0)
+   {
+      log_ssl_errors(LOG_LEVEL_ERROR,
+         "wolfSSL_X509_NAME_print_ex() for subject name failed");
+      ret = -1;
+      goto exit;
+   }
+
+   if (wolfSSL_BIO_puts(bio, "\nissued  on        : ") <= 0)
+   {
+      log_ssl_errors(LOG_LEVEL_ERROR,
+         "wolfSSL_BIO_puts() for issued on failed");
+      ret = -1;
+      goto exit;
+   }
+   if (!wolfSSL_ASN1_TIME_print(bio, wolfSSL_X509_get_notBefore(cert)))
+   {
+      log_ssl_errors(LOG_LEVEL_ERROR,
+         "wolfSSL_ASN1_TIME_print() for issued on failed");
+      ret = -1;
+      goto exit;
+   }
+
+   if (wolfSSL_BIO_puts(bio, "\nexpires on        : ") <= 0)
+   {
+      log_ssl_errors(LOG_LEVEL_ERROR,
+         "wolfSSL_BIO_puts() for expires on failed");
+      ret = -1;
+      goto exit;
+   }
+   if (!wolfSSL_ASN1_TIME_print(bio, wolfSSL_X509_get_notAfter(cert)))
+   {
+      log_ssl_errors(LOG_LEVEL_ERROR,
+         "wolfSSL_ASN1_TIME_print() for expires on failed");
+      ret = -1;
+      goto exit;
+   }
+
+   /* XXX: Show signature algorithm */
+
+   pkey = wolfSSL_X509_get_pubkey(cert);
+   if (!pkey)
+   {
+      log_ssl_errors(LOG_LEVEL_ERROR, "wolfSSL_X509_get_pubkey() failed");
+      ret = -1;
+      goto exit;
+   }
+   ret = wolfSSL_BIO_printf(bio, "\n%-18s: %d bits",
+      get_public_key_size_string(wolfSSL_EVP_PKEY_base_id(pkey)),
+      wolfSSL_EVP_PKEY_bits(pkey));
+   if (ret <= 0)
+   {
+      log_ssl_errors(LOG_LEVEL_ERROR,
+         "wolfSSL_BIO_printf() for key size failed");
+      ret = -1;
+      goto exit;
+   }
+
+   /*
+    * XXX: Show cert usage, etc.
+    */
+   loc = wolfSSL_X509_get_ext_by_NID(cert, NID_basic_constraints, -1);
+   if (loc != -1)
+   {
+      WOLFSSL_X509_EXTENSION *ex = wolfSSL_X509_get_ext(cert, loc);
+      if (BIO_puts(bio, "\nbasic constraints : ") <= 0)
+      {
+         log_ssl_errors(LOG_LEVEL_ERROR,
+            "BIO_printf() for basic constraints failed");
+         ret = -1;
+         goto exit;
+      }
+      if (!wolfSSL_X509V3_EXT_print(bio, ex, 0, 0))
+      {
+         if (!wolfSSL_ASN1_STRING_print_ex(bio,
+               wolfSSL_X509_EXTENSION_get_data(ex),
+               ASN1_STRFLGS_RFC2253))
+         {
+            log_ssl_errors(LOG_LEVEL_ERROR,
+               "wolfSSL_ASN1_STRING_print_ex() for basic constraints failed");
+            ret = -1;
+            goto exit;
+         }
+      }
+   }
+
+   while ((subject_alternative_name = wolfSSL_X509_get_next_altname(cert))
+      != NULL)
+   {
+      if (san_prefix_printed == 0)
+      {
+         ret = wolfSSL_BIO_printf(bio, "\nsubject alt name  : ");
+         san_prefix_printed = 1;
+      }
+      if (ret > 0)
+      {
+         ret = wolfSSL_BIO_printf(bio, "%s ", subject_alternative_name);
+      }
+      if (ret <= 0)
+      {
+         log_ssl_errors(LOG_LEVEL_ERROR,
+            "wolfSSL_BIO_printf() for Subject Alternative Name failed");
+         ret = -1;
+         goto exit;
+      }
+   }
+
+#if 0
+   /*
+    * This code compiles but does not work because wolfSSL
+    * sets NID_netscape_cert_type to NID_undef.
+    */
+   loc = wolfSSL_X509_get_ext_by_NID(cert, NID_netscape_cert_type, -1);
+   if (loc != -1)
+   {
+      WOLFSSL_X509_EXTENSION *ex = wolfSSL_X509_get_ext(cert, loc);
+      if (wolfSSL_BIO_puts(bio, "\ncert. type        : ") <= 0)
+      {
+         log_ssl_errors(LOG_LEVEL_ERROR,
+            "wolfSSL_BIO_printf() for cert type failed");
+         ret = -1;
+         goto exit;
+      }
+      if (!wolfSSL_X509V3_EXT_print(bio, ex, 0, 0))
+      {
+         if (!wolfSSL_ASN1_STRING_print_ex(bio,
+               wolfSSL_X509_EXTENSION_get_data(ex),
+               ASN1_STRFLGS_RFC2253))
+         {
+            log_ssl_errors(LOG_LEVEL_ERROR,
+               "wolfSSL_ASN1_STRING_print_ex() for cert type failed");
+            ret = -1;
+            goto exit;
+         }
+      }
+   }
+#endif
+
+#if 0
+   /*
+    * This code compiles but does not work. wolfSSL_OBJ_obj2nid()
+    * triggers a 'X509V3_EXT_print not yet implemented for ext type' message.
+     */
+   loc = wolfSSL_X509_get_ext_by_NID(cert, NID_key_usage, -1);
+   if (loc != -1)
+   {
+      WOLFSSL_X509_EXTENSION *extension = wolfSSL_X509_get_ext(cert, loc);
+      if (BIO_puts(bio, "\nkey usage         : ") <= 0)
+      {
+         log_ssl_errors(LOG_LEVEL_ERROR,
+            "wolfSSL_BIO_printf() for key usage failed");
+         ret = -1;
+         goto exit;
+      }
+      if (!wolfSSL_X509V3_EXT_print(bio, extension, 0, 0))
+      {
+         if (!wolfSSL_ASN1_STRING_print_ex(bio,
+               wolfSSL_X509_EXTENSION_get_data(extension),
+               ASN1_STRFLGS_RFC2253))
+         {
+            log_ssl_errors(LOG_LEVEL_ERROR,
+               "wolfSSL_ASN1_STRING_print_ex() for key usage failed");
+            ret = -1;
+            goto exit;
+         }
+      }
+   }
+#endif
+
+#if 0
+   /*
+    * This compiles but doesn't work. wolfSSL_X509_ext_isSet_by_NID()
+    * complains about "NID not in table".
+    */
+   loc = wolfSSL_X509_get_ext_by_NID(cert, NID_ext_key_usage, -1);
+   if (loc != -1) {
+      WOLFSSL_X509_EXTENSION *ex = wolfSSL_X509_get_ext(cert, loc);
+      if (wolfSSL_BIO_puts(bio, "\next key usage     : ") <= 0)
+      {
+         log_ssl_errors(LOG_LEVEL_ERROR,
+            "wolfSSL_BIO_printf() for ext key usage failed");
+         ret = -1;
+         goto exit;
+      }
+      if (!wolfSSL_X509V3_EXT_print(bio, ex, 0, 0))
+      {
+         if (!wolfSSL_ASN1_STRING_print_ex(bio,
+               wolfSSL_X509_EXTENSION_get_data(ex),
+               ASN1_STRFLGS_RFC2253))
+         {
+            log_ssl_errors(LOG_LEVEL_ERROR,
+               "wolfSSL_ASN1_STRING_print_ex() for ext key usage failed");
+            ret = -1;
+            goto exit;
+         }
+      }
+   }
+#endif
+
+#if 0
+   /*
+    * This compiles but doesn't work. wolfSSL_X509_ext_isSet_by_NID()
+    * complains about "NID not in table". XXX: again?
+    */
+   loc = wolfSSL_X509_get_ext_by_NID(cert, NID_certificate_policies, -1);
+   if (loc != -1)
+   {
+      WOLFSSL_X509_EXTENSION *ex = wolfSSL_X509_get_ext(cert, loc);
+      if (wolfSSL_BIO_puts(bio, "\ncertificate policies : ") <= 0)
+      {
+         log_ssl_errors(LOG_LEVEL_ERROR,
+            "wolfSSL_BIO_printf() for certificate policies failed");
+         ret = -1;
+         goto exit;
+      }
+      if (!wolfSSL_X509V3_EXT_print(bio, ex, 0, 0))
+      {
+         if (!wolfSSL_ASN1_STRING_print_ex(bio,
+               wolfSSL_X509_EXTENSION_get_data(ex),
+               ASN1_STRFLGS_RFC2253))
+         {
+            log_ssl_errors(LOG_LEVEL_ERROR,
+               "wolfSSL_ASN1_STRING_print_ex() for certificate policies failed");
+            ret = -1;
+            goto exit;
+         }
+      }
+   }
+#endif
+
+   /* make valgrind happy */
+   static const char zero = 0;
+   wolfSSL_BIO_write(bio, &zero, 1);
+
+   len = wolfSSL_BIO_get_mem_data(bio, &bio_mem_data);
+   if (len <= 0)
+   {
+      log_error(LOG_LEVEL_ERROR, "BIO_get_mem_data() returned %ld "
+         "while gathering certificate information", len);
+      ret = -1;
+      goto exit;
+   }
+   encoded_text = html_encode(bio_mem_data);
+   if (encoded_text == NULL)
+   {
+      log_error(LOG_LEVEL_ERROR,
+         "Failed to HTML-encode the certificate information");
+      ret = -1;
+      goto exit;
+   }
+
+   strlcpy(last->info_buf, encoded_text, sizeof(last->info_buf));
+   freez(encoded_text);
+   ret = 0;
+
+exit:
+   if (bio)
+   {
+      wolfSSL_BIO_free(bio);
+   }
+   if (pkey)
+   {
+      wolfSSL_EVP_PKEY_free(pkey);
+   }
+   return ret;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  host_to_hash
+ *
+ * Description :  Creates MD5 hash from host name. Host name is loaded
+ *                from structure csp and saved again into it.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *
+ * Returns     : -1 => Error while creating hash
+ *                0 => Hash created successfully
+ *
+ *********************************************************************/
+static int host_to_hash(struct client_state *csp)
+{
+   wc_Md5 md5;
+   int ret;
+   size_t i;
+
+   ret = wc_InitMd5(&md5);
+   if (ret != 0)
+   {
+      return -1;
+   }
+
+   ret = wc_Md5Update(&md5, (const byte *)csp->http->host,
+      (word32)strlen(csp->http->host));
+   if (ret != 0)
+   {
+      return -1;
+   }
+
+   ret = wc_Md5Final(&md5, csp->http->hash_of_host);
+   if (ret != 0)
+   {
+      return -1;
+   }
+
+   wc_Md5Free(&md5);
+
+   /* Converting hash into string with hex */
+   for (i = 0; i < 16; i++)
+   {
+      ret = snprintf((char *)csp->http->hash_of_host_hex + 2 * i,
+         sizeof(csp->http->hash_of_host_hex) - 2 * i,
+         "%02x", csp->http->hash_of_host[i]);
+      if (ret < 0)
+      {
+         log_error(LOG_LEVEL_ERROR, "sprintf() failed. Return value: %d", ret);
+         return -1;
+      }
+   }
+
+   return 0;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  create_client_ssl_connection
+ *
+ * Description :  Creates a TLS-secured connection with the client.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *
+ * Returns     :  0 on success, negative value if connection wasn't created
+ *                successfully.
+ *
+ *********************************************************************/
+extern int create_client_ssl_connection(struct client_state *csp)
+{
+   struct ssl_attr *ssl_attr = &csp->ssl_client_attr;
+   /* Paths to certificates file and key file */
+   char *key_file  = NULL;
+   char *cert_file = NULL;
+   int ret = 0;
+   WOLFSSL *ssl;
+
+   /* Should probably be called from somewhere else. */
+   wolfssl_init();
+
+   /*
+    * Preparing hash of host for creating certificates
+    */
+   ret = host_to_hash(csp);
+   if (ret != 0)
+   {
+      log_error(LOG_LEVEL_ERROR, "Generating hash of host failed: %d", ret);
+      ret = -1;
+      goto exit;
+   }
+
+   /*
+    * Preparing paths to certificates files and key file
+    */
+   cert_file = make_certs_path(csp->config->certificate_directory,
+      (const char *)csp->http->hash_of_host_hex, CERT_FILE_TYPE);
+   key_file  = make_certs_path(csp->config->certificate_directory,
+      (const char *)csp->http->hash_of_host_hex, KEY_FILE_TYPE);
+
+   if (cert_file == NULL || key_file == NULL)
+   {
+      ret = -1;
+      goto exit;
+   }
+
+   /* Do we need to generate a new host certificate and key? */
+   if (!file_exists(cert_file) || !file_exists(key_file) ||
+       ssl_certificate_is_invalid(cert_file))
+   {
+      /*
+       * Yes we do. Lock mutex to prevent certificate and
+       * key inconsistencies.
+       */
+      privoxy_mutex_lock(&certificate_mutex);
+      ret = generate_host_certificate(csp, cert_file, key_file);
+      privoxy_mutex_unlock(&certificate_mutex);
+      if (ret < 0)
+      {
+         /*
+          * No need to log something, generate_host_certificate()
+          * took care of it.
+          */
+         ret = -1;
+         goto exit;
+      }
+   }
+   ssl_attr->wolfssl_attr.ctx = wolfSSL_CTX_new(wolfSSLv23_method());
+   if (ssl_attr->wolfssl_attr.ctx == NULL)
+   {
+      log_ssl_errors(LOG_LEVEL_ERROR, "Unable to create TLS context");
+      ret = -1;
+      goto exit;
+   }
+
+   /* Set the key and cert */
+   if (wolfSSL_CTX_use_certificate_file(ssl_attr->wolfssl_attr.ctx,
+         cert_file, SSL_FILETYPE_PEM) != WOLFSSL_SUCCESS)
+   {
+      log_ssl_errors(LOG_LEVEL_ERROR,
+         "Loading host certificate %s failed", cert_file);
+      ret = -1;
+      goto exit;
+   }
+
+   if (wolfSSL_CTX_use_PrivateKey_file(ssl_attr->wolfssl_attr.ctx,
+         key_file, SSL_FILETYPE_PEM) != WOLFSSL_SUCCESS)
+   {
+      log_ssl_errors(LOG_LEVEL_ERROR,
+         "Loading host certificate private key %s failed", key_file);
+      ret = -1;
+      goto exit;
+   }
+
+   wolfSSL_CTX_set_options(ssl_attr->wolfssl_attr.ctx, WOLFSSL_OP_NO_SSLv3);
+
+   ssl = ssl_attr->wolfssl_attr.ssl = wolfSSL_new(ssl_attr->wolfssl_attr.ctx);
+
+   if (wolfSSL_set_fd(ssl, csp->cfd) != WOLFSSL_SUCCESS)
+   {
+      log_ssl_errors(LOG_LEVEL_ERROR,
+         "wolfSSL_set_fd() failed to set the client socket");
+      ret = -1;
+      goto exit;
+   }
+
+   if (csp->config->cipher_list != NULL)
+   {
+      if (!wolfSSL_set_cipher_list(ssl, csp->config->cipher_list))
+      {
+         log_ssl_errors(LOG_LEVEL_ERROR,
+            "Setting the cipher list '%s' for the client connection failed",
+            csp->config->cipher_list);
+         ret = -1;
+         goto exit;
+      }
+   }
+
+   /*
+    *  Handshake with client
+    */
+   log_error(LOG_LEVEL_CONNECT,
+      "Performing the TLS/SSL handshake with client. Hash of host: %s",
+      csp->http->hash_of_host_hex);
+
+   ret = wolfSSL_accept(ssl);
+   if (ret == WOLFSSL_SUCCESS)
+   {
+      log_error(LOG_LEVEL_CONNECT,
+         "Client successfully connected over %s (%s).",
+         wolfSSL_get_version(ssl), wolfSSL_get_cipher_name(ssl));
+      csp->ssl_with_client_is_opened = 1;
+      ret = 0;
+   }
+   else
+   {
+      char buffer[80];
+      int error = wolfSSL_get_error(ssl, ret);
+      log_error(LOG_LEVEL_ERROR,
+         "The TLS handshake with the client failed. error = %d, %s",
+         error, wolfSSL_ERR_error_string((unsigned long)error, buffer));
+      ret = -1;
+   }
+
+exit:
+   /*
+    * Freeing allocated paths to files
+    */
+   freez(cert_file);
+   freez(key_file);
+
+   /* Freeing structures if connection wasn't created successfully */
+   if (ret < 0)
+   {
+      free_client_ssl_structures(csp);
+   }
+   return ret;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  shutdown_connection
+ *
+ * Description :  Shuts down a TLS connection if the socket is still
+ *                alive.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+static void shutdown_connection(WOLFSSL *ssl, const char *type)
+{
+   int shutdown_attempts = 0;
+   int ret;
+   int fd;
+   enum { MAX_SHUTDOWN_ATTEMPTS = 5 };
+
+   fd = wolfSSL_get_fd(ssl);
+
+   do
+   {
+      if (!socket_is_still_alive(fd))
+      {
+         log_error(LOG_LEVEL_CONNECT, "Not shutting down %s connection "
+            "on socket %d. The socket is no longer alive.", type, fd);
+         return;
+      }
+      ret = wolfSSL_shutdown(ssl);
+      shutdown_attempts++;
+      if (WOLFSSL_SUCCESS != ret)
+      {
+         log_error(LOG_LEVEL_CONNECT, "Failed to shutdown %s connection "
+            "on socket %d. Attempts so far: %d, ret: %d", type, fd,
+            shutdown_attempts, ret);
+      }
+   } while (ret == WOLFSSL_SHUTDOWN_NOT_DONE &&
+      shutdown_attempts < MAX_SHUTDOWN_ATTEMPTS);
+   if (WOLFSSL_SUCCESS != ret)
+   {
+      char buffer[80];
+      int error = wolfSSL_get_error(ssl, ret);
+      log_error(LOG_LEVEL_ERROR, "Failed to shutdown %s connection "
+         "on socket %d after %d attempts. ret: %d, error: %d, %s",
+         type, fd, shutdown_attempts, ret, error,
+         wolfSSL_ERR_error_string((unsigned long)error, buffer));
+   }
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  close_client_ssl_connection
+ *
+ * Description :  Closes TLS connection with client. This function
+ *                checks if this connection is already created.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+extern void close_client_ssl_connection(struct client_state *csp)
+{
+   struct ssl_attr *ssl_attr = &csp->ssl_client_attr;
+
+   if (csp->ssl_with_client_is_opened == 0)
+   {
+      return;
+   }
+
+   /*
+    * Notify the peer that the connection is being closed.
+    */
+   shutdown_connection(ssl_attr->wolfssl_attr.ssl, "client");
+
+   free_client_ssl_structures(csp);
+   csp->ssl_with_client_is_opened = 0;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  free_client_ssl_structures
+ *
+ * Description :  Frees structures used for SSL communication with
+ *                client.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+static void free_client_ssl_structures(struct client_state *csp)
+{
+   struct ssl_attr *ssl_attr = &csp->ssl_client_attr;
+
+   if (ssl_attr->wolfssl_attr.ssl)
+   {
+      wolfSSL_free(ssl_attr->wolfssl_attr.ssl);
+   }
+   if (ssl_attr->wolfssl_attr.ctx)
+   {
+      wolfSSL_CTX_free(ssl_attr->wolfssl_attr.ctx);
+   }
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  close_server_ssl_connection
+ *
+ * Description :  Closes TLS connection with server. This function
+ *                checks if this connection is already opened.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+extern void close_server_ssl_connection(struct client_state *csp)
+{
+   struct ssl_attr *ssl_attr = &csp->ssl_server_attr;
+
+   if (csp->ssl_with_server_is_opened == 0)
+   {
+      return;
+   }
+
+   /*
+   * Notify the peer that the connection is being closed.
+   */
+   shutdown_connection(ssl_attr->wolfssl_attr.ssl, "server");
+
+   free_server_ssl_structures(csp);
+   csp->ssl_with_server_is_opened = 0;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  create_server_ssl_connection
+ *
+ * Description :  Creates TLS-secured connection with the server.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *
+ * Returns     :  0 on success, negative value if connection wasn't created
+ *                successfully.
+ *
+ *********************************************************************/
+extern int create_server_ssl_connection(struct client_state *csp)
+{
+   wolfssl_connection_attr *ssl_attrs = &csp->ssl_server_attr.wolfssl_attr;
+   int ret = 0;
+   WOLFSSL *ssl;
+   int connect_ret = 0;
+
+   csp->server_cert_verification_result = SSL_CERT_NOT_VERIFIED;
+   csp->server_certs_chain.next = NULL;
+
+   ssl_attrs->ctx = wolfSSL_CTX_new(wolfSSLv23_method());
+   if (ssl_attrs->ctx == NULL)
+   {
+      log_ssl_errors(LOG_LEVEL_ERROR, "TLS context creation failed");
+      ret = -1;
+      goto exit;
+   }
+
+   if (csp->dont_verify_certificate)
+   {
+      wolfSSL_CTX_set_verify(ssl_attrs->ctx, WOLFSSL_VERIFY_NONE, NULL);
+   }
+   else if (wolfSSL_CTX_load_verify_locations(ssl_attrs->ctx,
+      csp->config->trusted_cas_file, NULL) != WOLFSSL_SUCCESS)
+   {
+      log_ssl_errors(LOG_LEVEL_ERROR, "Loading trusted CAs file %s failed",
+         csp->config->trusted_cas_file);
+      ret = -1;
+      goto exit;
+   }
+
+   wolfSSL_CTX_set_options(ssl_attrs->ctx, WOLFSSL_OP_NO_SSLv3);
+
+   ssl = ssl_attrs->ssl = wolfSSL_new(ssl_attrs->ctx);
+
+   if (wolfSSL_set_fd(ssl, csp->server_connection.sfd) != WOLFSSL_SUCCESS)
+   {
+      log_ssl_errors(LOG_LEVEL_ERROR,
+         "wolfSSL_set_fd() failed to set the server socket");
+      ret = -1;
+      goto exit;
+   }
+
+   if (csp->config->cipher_list != NULL)
+   {
+      if (wolfSSL_set_cipher_list(ssl, csp->config->cipher_list) != WOLFSSL_SUCCESS)
+      {
+         log_ssl_errors(LOG_LEVEL_ERROR,
+            "Setting the cipher list '%s' for the server connection failed",
+            csp->config->cipher_list);
+         ret = -1;
+         goto exit;
+      }
+   }
+
+   ret = wolfSSL_UseSNI(ssl, WOLFSSL_SNI_HOST_NAME,
+      csp->http->host, (unsigned short)strlen(csp->http->host));
+   if (ret != WOLFSSL_SUCCESS)
+   {
+      log_ssl_errors(LOG_LEVEL_ERROR, "Failed to set use of SNI");
+      ret = -1;
+      goto exit;
+   }
+
+   ret = wolfSSL_check_domain_name(ssl, csp->http->host);
+   if (ret != WOLFSSL_SUCCESS)
+   {
+      char buffer[80];
+      int error = wolfSSL_get_error(ssl, ret);
+      log_error(LOG_LEVEL_FATAL,
+         "Failed to set check domain name. error = %d, %s",
+         error, wolfSSL_ERR_error_string((unsigned long)error, buffer));
+      ret = -1;
+      goto exit;
+   }
+
+#ifdef HAVE_SECURE_RENEGOTIATION
+#warning wolfssl has been compiled with HAVE_SECURE_RENEGOTIATION while you probably want HAVE_RENEGOTIATION_INDICATION
+   if(wolfSSL_UseSecureRenegotiation(ssl) != WOLFSSL_SUCCESS)
+   {
+      log_ssl_errors(LOG_LEVEL_ERROR,
+         "Failed to enable 'Secure' Renegotiation. Continuing anyway.");
+   }
+#endif
+#ifndef HAVE_RENEGOTIATION_INDICATION
+#warning Looks like wolfssl has been compiled without HAVE_RENEGOTIATION_INDICATION
+#endif
+
+   log_error(LOG_LEVEL_CONNECT,
+      "Performing the TLS/SSL handshake with the server");
+
+   /* wolfSSL_Debugging_ON(); */
+   connect_ret = wolfSSL_connect(ssl);
+   /* wolfSSL_Debugging_OFF(); */
+
+   /*
+   wolfSSL_Debugging_ON();
+   */
+   if (!csp->dont_verify_certificate)
+   {
+      long verify_result = wolfSSL_get_error(ssl, connect_ret);
+
+#if LIBWOLFSSL_VERSION_HEX > 0x05005004
+      if (verify_result == WOLFSSL_X509_V_OK)
+#else
+      if (verify_result == X509_V_OK)
+#endif
+      {
+         ret = 0;
+         csp->server_cert_verification_result = SSL_CERT_VALID;
+      }
+      else
+      {
+         WOLF_STACK_OF(WOLFSSL_X509) *chain;
+
+         csp->server_cert_verification_result = verify_result;
+         log_error(LOG_LEVEL_ERROR,
+            "X509 certificate verification for %s failed with error %ld: %s",
+            csp->http->hostport, verify_result,
+            wolfSSL_X509_verify_cert_error_string(verify_result));
+
+         chain = wolfSSL_get_peer_cert_chain(ssl);
+         if (chain != NULL)
+         {
+            int i;
+            for (i = 0; i < wolfSSL_sk_X509_num(chain); i++)
+            {
+               if (ssl_store_cert(csp, wolfSSL_sk_X509_value(chain, i)) != 0)
+               {
+                  log_error(LOG_LEVEL_ERROR,
+                     "ssl_store_cert() failed for cert %d", i);
+                  /*
+                   * ssl_send_certificate_error() wil not be able to show
+                   * the certificate but the user will stil get the error
+                   * description.
+                   */
+               }
+            }
+         }
+
+         ret = -1;
+         goto exit;
+      }
+   }
+   /*
+   wolfSSL_Debugging_OFF();
+   */
+   if (connect_ret == WOLFSSL_SUCCESS)
+   {
+      log_error(LOG_LEVEL_CONNECT,
+         "Server successfully connected over %s (%s).",
+         wolfSSL_get_version(ssl), wolfSSL_get_cipher_name(ssl));
+      csp->ssl_with_server_is_opened = 1;
+      ret = 0;
+   }
+   else
+   {
+      char buffer[80];
+      int error = wolfSSL_get_error(ssl, ret);
+      log_error(LOG_LEVEL_ERROR,
+         "The TLS handshake with the server %s failed. error = %d, %s",
+         csp->http->hostport,
+         error, wolfSSL_ERR_error_string((unsigned long)error, buffer));
+      ret = -1;
+   }
+
+exit:
+   /* Freeing structures if connection wasn't created successfully */
+   if (ret < 0)
+   {
+      free_server_ssl_structures(csp);
+   }
+
+   return ret;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  free_server_ssl_structures
+ *
+ * Description :  Frees structures used for SSL communication with server
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+static void free_server_ssl_structures(struct client_state *csp)
+{
+   struct ssl_attr *ssl_attr = &csp->ssl_server_attr;
+
+   if (ssl_attr->wolfssl_attr.ssl)
+   {
+      wolfSSL_free(ssl_attr->wolfssl_attr.ssl);
+   }
+   if (ssl_attr->wolfssl_attr.ctx)
+   {
+      wolfSSL_CTX_free(ssl_attr->wolfssl_attr.ctx);
+   }
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  log_ssl_errors
+ *
+ * Description :  Log SSL errors
+ *
+ * Parameters  :
+ *          1  :  debuglevel = Debug level
+ *          2  :  desc = Error description
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+static void log_ssl_errors(int debuglevel, const char* fmt, ...)
+{
+   unsigned long err_code;
+   char prefix[ERROR_BUF_SIZE];
+   va_list args;
+   va_start(args, fmt);
+   vsnprintf(prefix, sizeof(prefix), fmt, args);
+   int reported = 0;
+
+   while ((err_code = wolfSSL_ERR_get_error()))
+   {
+      char err_buf[ERROR_BUF_SIZE];
+      reported = 1;
+      wolfSSL_ERR_error_string_n(err_code, err_buf, sizeof(err_buf));
+      log_error(debuglevel, "%s: %s", prefix, err_buf);
+   }
+   va_end(args);
+   /*
+    * In case if called by mistake and there were
+    * no TLS errors let's report it to the log.
+    */
+   if (!reported)
+   {
+      log_error(debuglevel, "%s: no TLS errors detected", prefix);
+   }
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  ssl_base64_encode
+ *
+ * Description :  Encode a buffer into base64 format.
+ *
+ * Parameters  :
+ *          1  :  dst = Destination buffer
+ *          2  :  dlen = Destination buffer length
+ *          3  :  olen = Number of bytes written
+ *          4  :  src = Source buffer
+ *          5  :  slen = Amount of data to be encoded
+ *
+ * Returns     :  0 on success, error code othervise
+ *
+ *********************************************************************/
+extern int ssl_base64_encode(unsigned char *dst, size_t dlen, size_t *olen,
+                             const unsigned char *src, size_t slen)
+{
+   word32 output_length;
+   int ret;
+
+   *olen = 4 * ((slen/3) + ((slen%3) ? 1 : 0)) + 1;
+   if (*olen > dlen)
+   {
+      return ENOBUFS;
+   }
+
+   output_length = (word32)dlen;
+   ret = Base64_Encode_NoNl(src, (word32)slen, dst, &output_length);
+   if (ret != 0)
+   {
+      log_error(LOG_LEVEL_ERROR, "base64 encoding failed with %d", ret);
+      return ret;
+   }
+   *olen = output_length;
+
+   return 0;
+
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  close_file_stream
+ *
+ * Description :  Close file stream, report error on close error
+ *
+ * Parameters  :
+ *          1  :  f = file stream to close
+ *          2  :  path = path for error report
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+static void close_file_stream(FILE *f, const char *path)
+{
+   if (fclose(f) != 0)
+   {
+      log_error(LOG_LEVEL_ERROR,
+         "Error closing file %s: %s", path, strerror(errno));
+   }
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  write_certificate
+ *
+ * Description :  Writes a PEM-encoded certificate to a file.
+ *
+ * Parameters  :
+ *          1  :  certificate_path = Path to the file to create
+ *          2  :  certificate = PEM-encoded certificate to write.
+ *
+ * Returns     :  NULL => Error. Otherwise a key;
+ *
+ *********************************************************************/
+static int write_certificate(const char *certificate_path, const char *certificate)
+{
+   FILE *fp;
+
+   assert(certificate_path != NULL);
+   assert(certificate != NULL);
+
+   fp = fopen(certificate_path, "wb");
+   if (NULL == fp)
+   {
+      log_error(LOG_LEVEL_ERROR,
+         "Failed to open %s to write the certificate: %E",
+         certificate_path);
+      return -1;
+   }
+   if (fputs(certificate, fp) < 0)
+   {
+      log_error(LOG_LEVEL_ERROR, "Failed to write certificate to %s: %E",
+         certificate_path);
+      fclose(fp);
+      return -1;
+   }
+   fclose(fp);
+
+   return 0;
+
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  generate_rsa_key
+ *
+ * Description : Generates a new RSA key and saves it in a file.
+ *
+ * Parameters  :
+ *          1  :  rsa_key_path = Path to the key that should be written.
+ *
+ * Returns     :  -1 => Error while generating private key
+ *                 0 => Success.
+ *
+ *********************************************************************/
+static int generate_rsa_key(const char *rsa_key_path)
+{
+   RsaKey rsa_key;
+   byte rsa_key_der[4096];
+   int ret;
+   byte key_pem[4096];
+   int der_key_size;
+   int pem_key_size;
+   FILE *f = NULL;
+
+   assert(file_exists(rsa_key_path) != 1);
+
+   wc_InitRsaKey(&rsa_key, NULL);
+
+   log_error(LOG_LEVEL_CONNECT, "Making RSA key %s ...", rsa_key_path);
+   ret = wc_MakeRsaKey(&rsa_key, RSA_KEYSIZE, RSA_KEY_PUBLIC_EXPONENT,
+      &wolfssl_rng);
+   if (ret != 0)
+   {
+      log_error(LOG_LEVEL_ERROR, "RSA key generation failed");
+      ret = -1;
+      goto exit;
+   }
+   log_error(LOG_LEVEL_CONNECT, "Done making RSA key %s", rsa_key_path);
+
+   der_key_size = wc_RsaKeyToDer(&rsa_key, rsa_key_der, sizeof(rsa_key_der));
+   wc_FreeRsaKey(&rsa_key);
+   if (der_key_size < 0)
+   {
+      log_error(LOG_LEVEL_ERROR, "RSA key conversion to DER format failed");
+      ret = -1;
+      goto exit;
+   }
+   pem_key_size = wc_DerToPem(rsa_key_der, (word32)der_key_size,
+      key_pem, sizeof(key_pem), PRIVATEKEY_TYPE);
+   if (pem_key_size < 0)
+   {
+      log_error(LOG_LEVEL_ERROR, "RSA key conversion to PEM format failed");
+      ret = -1;
+      goto exit;
+   }
+
+   /*
+    * Saving key into file
+    */
+   if ((f = fopen(rsa_key_path, "wb")) == NULL)
+   {
+      log_error(LOG_LEVEL_ERROR,
+         "Opening file %s to save private key failed: %E",
+         rsa_key_path);
+      ret = -1;
+      goto exit;
+   }
+
+   if (fwrite(key_pem, 1, (size_t)pem_key_size, f) != pem_key_size)
+   {
+      log_error(LOG_LEVEL_ERROR,
+         "Writing private key into file %s failed",
+         rsa_key_path);
+      close_file_stream(f, rsa_key_path);
+      ret = -1;
+      goto exit;
+   }
+
+   close_file_stream(f, rsa_key_path);
+
+exit:
+
+   return ret;
+
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  ssl_certificate_load
+ *
+ * Description :  Loads certificate from file.
+ *
+ * Parameters  :
+ *          1  :  cert_path = The certificate path to load
+ *
+ * Returns     :   NULL => error loading certificate,
+ *                   pointer to certificate instance otherwise
+ *
+ *********************************************************************/
+static X509 *ssl_certificate_load(const char *cert_path)
+{
+   X509 *cert = NULL;
+   FILE *cert_f = NULL;
+
+   if (!(cert_f = fopen(cert_path, "r")))
+   {
+      log_error(LOG_LEVEL_ERROR,
+         "Error opening certificate file %s: %s", cert_path, strerror(errno));
+      return NULL;
+   }
+
+   if (!(cert = PEM_read_X509(cert_f, NULL, NULL, NULL)))
+   {
+      log_ssl_errors(LOG_LEVEL_ERROR,
+         "Error reading certificate file %s", cert_path);
+   }
+
+   close_file_stream(cert_f, cert_path);
+   return cert;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  ssl_certificate_is_invalid
+ *
+ * Description :  Checks whether or not a certificate is valid.
+ *                Currently only checks that the certificate can be
+ *                parsed and that the "valid to" date is in the future.
+ *
+ * Parameters  :
+ *          1  :  cert_file = The certificate to check
+ *
+ * Returns     :   0 => The certificate is valid.
+ *                 1 => The certificate is invalid
+ *
+ *********************************************************************/
+static int ssl_certificate_is_invalid(const char *cert_file)
+{
+   int ret;
+
+   X509 *cert = NULL;
+
+   if (!(cert = ssl_certificate_load(cert_file)))
+   {
+      return 1;
+   }
+
+   ret = wolfSSL_X509_cmp_current_time(wolfSSL_X509_get_notAfter(cert));
+   if (ret == 0)
+   {
+      log_ssl_errors(LOG_LEVEL_ERROR,
+         "Error checking certificate %s validity", cert_file);
+      ret = -1;
+   }
+
+   wolfSSL_X509_free(cert);
+
+   return ret == -1 ? 1 : 0;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  load_rsa_key
+ *
+ * Description :  Load a PEM-encoded RSA file into memory.
+ *
+ * Parameters  :
+ *          1  :  rsa_key_path = Path to the file that holds the key.
+ *          2  :  password = Password to unlock the key. NULL if no
+ *                           password is required.
+ *          3  :  rsa_key = Initialized RSA key storage.
+ *
+ * Returns     :   0 => Error while creating the key.
+ *                 1 => It worked
+ *
+ *********************************************************************/
+static int load_rsa_key(const char *rsa_key_path, const char *password, RsaKey *rsa_key)
+{
+   FILE *fp;
+   size_t length;
+   long ret;
+   unsigned char *key_pem;
+   DerBuffer *der_buffer;
+   word32 der_index = 0;
+   DerBuffer decrypted_der_buffer;
+   unsigned char der_data[4096];
+
+   fp = fopen(rsa_key_path, "rb");
+   if (NULL == fp)
+   {
+      log_error(LOG_LEVEL_ERROR, "Failed to open %s: %E", rsa_key_path);
+      return 0;
+   }
+
+   /* Get file length */
+   if (fseek(fp, 0, SEEK_END))
+   {
+      log_error(LOG_LEVEL_ERROR,
+         "Unexpected error while fseek()ing to the end of %s: %E",
+         rsa_key_path);
+      fclose(fp);
+      return 0;
+   }
+   ret = ftell(fp);
+   if (-1 == ret)
+   {
+      log_error(LOG_LEVEL_ERROR,
+         "Unexpected ftell() error while loading %s: %E",
+         rsa_key_path);
+      fclose(fp);
+      return 0;
+   }
+   length = (size_t)ret;
+
+   /* Go back to the beginning. */
+   if (fseek(fp, 0, SEEK_SET))
+   {
+      log_error(LOG_LEVEL_ERROR,
+         "Unexpected error while fseek()ing to the beginning of %s: %E",
+         rsa_key_path);
+      fclose(fp);
+      return 0;
+   }
+
+   key_pem = malloc_or_die(length);
+
+   if (1 != fread(key_pem, length, 1, fp))
+   {
+      log_error(LOG_LEVEL_ERROR,
+         "Couldn't completely read file %s.", rsa_key_path);
+      fclose(fp);
+      freez(key_pem);
+      return 0;
+   }
+
+   fclose(fp);
+
+   if (password == NULL)
+   {
+      ret = wc_PemToDer(key_pem, (long)length, PRIVATEKEY_TYPE,
+         &der_buffer, NULL, NULL, NULL);
+   }
+   else
+   {
+      der_buffer = &decrypted_der_buffer;
+      der_buffer->buffer = der_data;
+      ret = wc_KeyPemToDer(key_pem, (int)length, der_buffer->buffer,
+         sizeof(der_data), password);
+      if (ret < 0)
+      {
+         log_error(LOG_LEVEL_ERROR,
+            "Failed to convert PEM key %s into DER format. Error: %ld",
+            rsa_key_path, ret);
+         freez(key_pem);
+         return 0;
+      }
+      der_buffer->length = (word32)ret;
+   }
+
+   freez(key_pem);
+
+   if (ret < 0)
+   {
+      log_error(LOG_LEVEL_ERROR,
+         "Failed to convert buffer into DER format for file %s. Error = %ld",
+         rsa_key_path, ret);
+      return 0;
+   }
+
+   ret = wc_RsaPrivateKeyDecode(der_buffer->buffer, &der_index, rsa_key,
+      der_buffer->length);
+   if (password == NULL)
+   {
+      freez(der_buffer);
+   }
+   if (ret < 0)
+   {
+      log_error(LOG_LEVEL_ERROR,
+         "Failed to decode DER buffer into RSA key structure for %s",
+         rsa_key_path);
+      return 0;
+   }
+
+   return 1;
+}
+
+#ifndef WOLFSSL_ALT_NAMES
+#error wolfSSL lacks Subject Alternative Name support (WOLFSSL_ALT_NAMES) which is mandatory
+#endif
+/*********************************************************************
+ *
+ * Function    :  set_subject_alternative_name
+ *
+ * Description :  Sets the Subject Alternative Name extension to
+ *                a cert using the awesome "API" provided by wolfSSL.
+ *
+ * Parameters  :
+ *          1  :  cert = The certificate to modify
+ *          2  :  hostname = The hostname to add
+ *
+ * Returns     :  <0 => Error.
+ *                 0 => It worked
+ *
+ *********************************************************************/
+static int set_subject_alternative_name(struct Cert *certificate, const char *hostname)
+{
+   const size_t hostname_length = strlen(hostname);
+
+   if (hostname_length >= 253)
+   {
+      /*
+       * We apparently only have a byte to represent the length
+       * of the sequence.
+       */
+      log_error(LOG_LEVEL_ERROR,
+         "Hostname '%s' is too long to set Subject Alternative Name",
+         hostname);
+      return -1;
+   }
+   certificate->altNames[0] = 0x30; /* Sequence */
+   certificate->altNames[1] = (unsigned char)hostname_length + 2;
+
+   certificate->altNames[2] = 0x82; /* DNS name */
+   certificate->altNames[3] = (unsigned char)hostname_length;
+   memcpy(&certificate->altNames[4], hostname, hostname_length);
+
+   certificate->altNamesSz = (int)hostname_length + 4;
+
+   return 0;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  generate_host_certificate
+ *
+ * Description :  Creates certificate file in presetted directory.
+ *                If certificate already exists, no other certificate
+ *                will be created. Subject of certificate is named
+ *                by csp->http->host from parameter. This function also
+ *                triggers generating of private key for new certificate.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *          2  :  certificate_path = Path to the certficate to generate.
+ *          3  :  rsa_key_path = Path to the key to generate for the
+ *                               certificate.
+ *
+ * Returns     :  -1 => Error while creating certificate.
+ *                 0 => Certificate already exists.
+ *                 1 => Certificate created
+ *
+ *********************************************************************/
+static int generate_host_certificate(struct client_state *csp,
+   const char *certificate_path, const char *rsa_key_path)
+{
+   struct Cert certificate;
+   RsaKey ca_key;
+   RsaKey rsa_key;
+   int ret;
+   byte certificate_der[4096];
+   int der_certificate_length;
+   byte certificate_pem[4096];
+   int pem_certificate_length;
+
+   if (file_exists(certificate_path) == 1)
+   {
+      /* The file exists, but is it valid? */
+      if (ssl_certificate_is_invalid(certificate_path))
+      {
+         log_error(LOG_LEVEL_CONNECT,
+            "Certificate %s is no longer valid. Removing it.",
+            certificate_path);
+         if (unlink(certificate_path))
+         {
+            log_error(LOG_LEVEL_ERROR, "Failed to unlink %s: %E",
+               certificate_path);
+            return -1;
+         }
+         if (unlink(rsa_key_path))
+         {
+            log_error(LOG_LEVEL_ERROR, "Failed to unlink %s: %E",
+               rsa_key_path);
+            return -1;
+         }
+      }
+      else
+      {
+         return 0;
+      }
+   }
+   else
+   {
+      log_error(LOG_LEVEL_CONNECT, "Creating new certificate %s",
+         certificate_path);
+   }
+   if (enforce_sane_certificate_state(certificate_path, rsa_key_path))
+   {
+      return -1;
+   }
+
+   wc_InitRsaKey(&rsa_key, NULL);
+   wc_InitRsaKey(&ca_key, NULL);
+
+   if (generate_rsa_key(rsa_key_path) == -1)
+   {
+      return -1;
+   }
+
+   wc_InitCert(&certificate);
+
+   strncpy(certificate.subject.country, CERT_PARAM_COUNTRY_CODE, CTC_NAME_SIZE);
+   strncpy(certificate.subject.org, "Privoxy", CTC_NAME_SIZE);
+   strncpy(certificate.subject.unit, "Development", CTC_NAME_SIZE);
+   strncpy(certificate.subject.commonName, csp->http->host, CTC_NAME_SIZE);
+   certificate.daysValid = 90;
+   certificate.selfSigned = 0;
+   certificate.sigType = CTC_SHA256wRSA;
+   if (!host_is_ip_address(csp->http->host) &&
+       set_subject_alternative_name(&certificate, csp->http->host))
+   {
+      ret = -1;
+      goto exit;
+   }
+
+   ret = wc_SetIssuer(&certificate, csp->config->ca_cert_file);
+   if (ret < 0)
+   {
+      log_error(LOG_LEVEL_ERROR,
+         "Failed to set Issuer file %s", csp->config->ca_cert_file);
+      ret = -1;
+      goto exit;
+   }
+
+   if (load_rsa_key(rsa_key_path, NULL, &rsa_key) != 1)
+   {
+      log_error(LOG_LEVEL_ERROR,
+         "Failed to load RSA key %s", rsa_key_path);
+      ret = -1;
+      goto exit;
+   }
+
+   /* wolfSSL_Debugging_ON(); */
+   der_certificate_length = wc_MakeCert(&certificate, certificate_der,
+      sizeof(certificate_der), &rsa_key, NULL, &wolfssl_rng);
+   /* wolfSSL_Debugging_OFF(); */
+
+   if (der_certificate_length < 0)
+   {
+      log_error(LOG_LEVEL_ERROR, "Failed to make certificate");
+      ret = -1;
+      goto exit;
+   }
+
+   if (load_rsa_key(csp->config->ca_key_file, csp->config->ca_password,
+      &ca_key) != 1)
+   {
+      log_error(LOG_LEVEL_ERROR,
+         "Failed to load CA key %s", csp->config->ca_key_file);
+      ret = -1;
+      goto exit;
+   }
+
+   der_certificate_length = wc_SignCert(certificate.bodySz, certificate.sigType,
+      certificate_der, sizeof(certificate_der), &ca_key, NULL, &wolfssl_rng);
+   wc_FreeRsaKey(&ca_key);
+   if (der_certificate_length < 0)
+   {
+      log_error(LOG_LEVEL_ERROR, "Failed to sign certificate");
+      ret = -1;
+      goto exit;
+   }
+
+   pem_certificate_length = wc_DerToPem(certificate_der,
+      (word32)der_certificate_length, certificate_pem,
+      sizeof(certificate_pem), CERT_TYPE);
+   if (pem_certificate_length < 0)
+   {
+      log_error(LOG_LEVEL_ERROR,
+         "Failed to convert certificate from DER to PEM");
+      ret = -1;
+      goto exit;
+   }
+   certificate_pem[pem_certificate_length] = '\0';
+
+   if (write_certificate(certificate_path, (const char*)certificate_pem))
+   {
+      ret = -1;
+      goto exit;
+   }
+
+   ret = 1;
+
+exit:
+   wc_FreeRsaKey(&rsa_key);
+   wc_FreeRsaKey(&ca_key);
+
+   return 1;
+
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  ssl_crt_verify_info
+ *
+ * Description :  Returns an informational string about the verification
+ *                status of a certificate.
+ *
+ * Parameters  :
+ *          1  :  buf = Buffer to write to
+ *          2  :  size = Maximum size of buffer
+ *          3  :  csp = client state
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+extern void ssl_crt_verify_info(char *buf, size_t size, struct client_state *csp)
+{
+   strncpy(buf, wolfSSL_X509_verify_cert_error_string(
+      csp->server_cert_verification_result), size);
+   buf[size - 1] = 0;
+}
+
+
+#ifdef FEATURE_GRACEFUL_TERMINATION
+/*********************************************************************
+ *
+ * Function    :  ssl_release
+ *
+ * Description :  Release all SSL resources
+ *
+ * Parameters  :
+ *
+ * Returns     :  N/A
+ *
+ *********************************************************************/
+extern void ssl_release(void)
+{
+   if (wolfssl_initialized == 1)
+   {
+      wc_FreeRng(&wolfssl_rng);
+      wolfSSL_Cleanup();
+   }
+}
+#endif /* def FEATURE_GRACEFUL_TERMINATION */