aboutsummaryrefslogtreecommitdiff
path: root/src/hydrilla/proxy/self_doc/en_US
diff options
context:
space:
mode:
Diffstat (limited to 'src/hydrilla/proxy/self_doc/en_US')
-rw-r--r--src/hydrilla/proxy/self_doc/en_US/advanced_ui_features.html.jinja70
-rw-r--r--src/hydrilla/proxy/self_doc/en_US/doc_index.html.jinja59
-rw-r--r--src/hydrilla/proxy/self_doc/en_US/packages.html.jinja218
-rw-r--r--src/hydrilla/proxy/self_doc/en_US/policy_selection.html.jinja109
-rw-r--r--src/hydrilla/proxy/self_doc/en_US/popup.html.jinja157
-rw-r--r--src/hydrilla/proxy/self_doc/en_US/repositories.html.jinja128
-rw-r--r--src/hydrilla/proxy/self_doc/en_US/script_blocking.html.jinja125
-rw-r--r--src/hydrilla/proxy/self_doc/en_US/url_patterns.html.jinja409
8 files changed, 1275 insertions, 0 deletions
diff --git a/src/hydrilla/proxy/self_doc/en_US/advanced_ui_features.html.jinja b/src/hydrilla/proxy/self_doc/en_US/advanced_ui_features.html.jinja
new file mode 100644
index 0000000..045309b
--- /dev/null
+++ b/src/hydrilla/proxy/self_doc/en_US/advanced_ui_features.html.jinja
@@ -0,0 +1,70 @@
+{#
+SPDX-License-Identifier: GPL-3.0-or-later OR CC-BY-SA-4.0
+
+Documentation page explaining what Haketilo's advanced UI features are.
+
+This file is part of Hydrilla&Haketilo.
+
+Copyright (C) 2022 Wojtek Kosior
+
+Dual licensed under
+* GNU General Public License v3.0 or later and
+* Creative Commons Attribution Share Alike 4.0 International.
+
+You can choose to use either of these licenses or both.
+
+
+I, Wojtek Kosior, thereby promise not to sue for violation of this
+file's licenses. Although I request that you do not make use of this
+code in a proprietary work, I am not going to enforce this in court.
+#}
+{% extends "doc_base.html.jinja" %}
+
+{% block title %} Advanced UI features {% endblock %}
+
+{% block main %}
+ {{ big_heading('Haketilo user interface features for advanced users') }}
+
+ {% call section() %}
+ {% call paragraph() %}
+ Certain options that may cause a lot of unnecessary confusion to casual
+ Haketilo users have been hidden by default. They can be accessed after
+ enabling advanced UI features on the
+ {{ hkt_link('settings page', 'home.home') }}.
+ {% endcall %}
+ {% endcall %}
+
+ {% call section() %}
+ {{ medium_heading('Concept of libraries') }}
+
+ {% call paragraph() %}
+ Haketilo has a concept of 2 types of entities -
+ <span class="bold">packages</span> and
+ <span class="bold">libraries</span>.
+ As explained on the {{ doc_page_link('packages', 'packages') }} page, it's
+ ultimately a package that provides concrete functionality and a casual
+ user does not need to be aware of the existence of libraries.
+ Consequently, with advanced features off the UI does not contain any
+ notion of libraries and even the
+ {{ hkt_link('libraries listing page', 'items.libraries') }} link is
+ removed from the navigation bar.
+ {% endcall %}
+ {% endcall %}
+
+ {% call section() %}
+ {{ medium_heading('Selective installation/uninstallation of packages') }}
+
+ {% call paragraph() %}
+ A packages is automatically installed together with all its dependencies
+ when the user enables it.
+ Additionally, whenever some installed Haketilo packages or libraries are
+ found not to be needed anymore, they can be pruned from the
+ {{ hkt_link('settings page', 'home.home') }}.
+ This functionality was deemed sufficient for most users' needs.
+ With advanced features enabled the UI also allows any single package or
+ library not in use to be uninstalled manually and any package or library
+ available from a {{ doc_page_link('repository', 'repositories') }} to be
+ installed without prior enabling.
+ {% endcall %}
+ {% endcall %}
+{% endblock main %}
diff --git a/src/hydrilla/proxy/self_doc/en_US/doc_index.html.jinja b/src/hydrilla/proxy/self_doc/en_US/doc_index.html.jinja
new file mode 100644
index 0000000..03f2231
--- /dev/null
+++ b/src/hydrilla/proxy/self_doc/en_US/doc_index.html.jinja
@@ -0,0 +1,59 @@
+{#
+SPDX-License-Identifier: GPL-3.0-or-later OR CC-BY-SA-4.0
+
+Documentation pages index.
+
+This file is part of Hydrilla&Haketilo.
+
+Copyright (C) 2022 Wojtek Kosior
+
+Dual licensed under
+* GNU General Public License v3.0 or later and
+* Creative Commons Attribution Share Alike 4.0 International.
+
+You can choose to use either of these licenses or both.
+
+
+I, Wojtek Kosior, thereby promise not to sue for violation of this
+file's licenses. Although I request that you do not make use of this
+code in a proprietary work, I am not going to enforce this in court.
+#}
+{% extends "doc_base.html.jinja" %}
+
+{% block title %} Documentation index {% endblock %}
+
+{% block main %}
+ {{ big_heading('Haketilo embedded documentation') }}
+
+ {% call section() %}
+ {% call paragraph() %}
+ This is the embedded documentation of Haketilo proxy.
+ It contains some basic information aimed to help new users understand how
+ the tool works.
+ {% endcall %}
+
+ {% call unordered_list() %}
+ {% call list_entry() %}
+ {{ doc_page_link('Advanced UI features', 'advanced_ui_features') }}
+ {% endcall %}
+ {% call list_entry() %}
+ {{ doc_page_link('Packages', 'packages') }}
+ {% endcall %}
+ {% call list_entry() %}
+ {{ doc_page_link('Policy selection', 'policy_selection') }}
+ {% endcall %}
+ {% call list_entry() %}
+ {{ doc_page_link('Popup', 'popup') }}
+ {% endcall %}
+ {% call list_entry() %}
+ {{ doc_page_link('Repositories', 'repositories') }}
+ {% endcall %}
+ {% call list_entry() %}
+ {{ doc_page_link('Script blocking', 'script_blocking') }}
+ {% endcall %}
+ {% call list_entry() %}
+ {{ doc_page_link('URL patterns', 'url_patterns') }}
+ {% endcall %}
+ {% endcall %}
+ {% endcall %}
+{% endblock main %}
diff --git a/src/hydrilla/proxy/self_doc/en_US/packages.html.jinja b/src/hydrilla/proxy/self_doc/en_US/packages.html.jinja
new file mode 100644
index 0000000..23e6f45
--- /dev/null
+++ b/src/hydrilla/proxy/self_doc/en_US/packages.html.jinja
@@ -0,0 +1,218 @@
+{#
+SPDX-License-Identifier: GPL-3.0-or-later OR CC-BY-SA-4.0
+
+Documentation page describing the concept of packages in Haketilo.
+
+This file is part of Hydrilla&Haketilo.
+
+Copyright (C) 2022 Wojtek Kosior
+
+Dual licensed under
+* GNU General Public License v3.0 or later and
+* Creative Commons Attribution Share Alike 4.0 International.
+
+You can choose to use either of these licenses or both.
+
+
+I, Wojtek Kosior, thereby promise not to sue for violation of this
+file's licenses. Although I request that you do not make use of this
+code in a proprietary work, I am not going to enforce this in court.
+#}
+{% extends "doc_base.html.jinja" %}
+
+{% block title %} Packages {% endblock %}
+
+{% block main %}
+ {{ big_heading('Packages in Haketilo') }}
+
+ {% call section() %}
+ {% call paragraph() %}
+ Users can modify web pages by creating, installing and enabling
+ <span class="bold">packages</span>.
+ A package associates {{ doc_page_link('URL patterns', 'url_patterns') }}
+ with payloads (i.e. sets of scripts) that can be injected to pages.
+ For instance, if an enabled package associates pattern
+ <code>https://example.com/***</code> with a script that adds a big
+ "Hello world!" text to the page, this package shall cause "Hello world!"
+ to appear on pages under <code>example.com</code>.
+ {% endcall %}
+ {% endcall %}
+
+ {% call section() %}
+ {{ medium_heading('Packages and libraries') }}
+
+ {% call paragraph() %}
+ To make mapping custom JavaScript applications and their dependencies to
+ web pages more manageable, Haketilo defines its own concept of "packages"
+ and "libraries".
+ {% endcall %}
+
+ {% call unordered_list() %}
+ {% call list_entry() %}
+ package - Also called <span class="bold">mapping</span>.
+ It associates URL patterns with libraries.
+ {% endcall %}
+ {% call list_entry() %}
+ library - Sometimes also referred to as
+ <span class="bold">resource</span>.
+ Defines a set of scripts that can be injected together into a page.
+ It can also name other libraries as its dependencies.
+ When injecting scripts of a given library into some page, Haketilo will
+ first inject scripts of all libraries depended on.
+ {% endcall %}
+ {% endcall %}
+
+ {% call paragraph() %}
+ It's ultimately a package that provides concrete functionality to the end
+ user and that can be enabled or disabled.
+ For this reason, a casual user does not even need to be aware of the
+ existence of libraries.
+ Haketilo UI advanced interface features need to be enabled on the
+ {{ hkt_link('settings page', 'home.home') }} for installed libraries to be
+ viewable.
+ {% endcall %}
+ {% endcall %}
+
+ {% call section() %}
+ {{ medium_heading('Installing') }}
+
+ {% call paragraph() %}
+ Useful packages prepared by others can be installed from Hydrilla
+ repositories. The repositories can be configured
+ {{ hkt_link('through Haketilo user interface', 'repos.repos') }} as
+ described on
+ {{ doc_page_link('the relevant documentation page', 'repositories') }}.
+ As of Haketilo 3.0-beta1 they need to be manually "refreshed" for new
+ packages from them to be shown in Haketilo.
+ Available packages viewable on the
+ {{ hkt_link('packages listing page', 'items.packages') }} are not
+ immediately installed.
+ This only happens after they are explicitly enabled or automatically
+ enabled (if the user configured Haketilo to do this).
+ {% endcall %}
+
+ {% call paragraph() %}
+ For convenience, users can also create simple packages
+ {{ hkt_link('directly in Haketilo UI', 'import.items_import') }}.
+ A simple form can be used to quickly define a standalone script payload
+ for a set of URL patterns. As of Haketilo 3.0 only simple (i.e.
+ single-library) payloads can be created this way.
+ {% endcall %}
+
+ {% call paragraph() %}
+ It is also possible to import packages from files.
+ For this, a directory of serveable mappings and reasources - as produced
+ by Hydrilla builder and used by Hydrilla server - has to be put into a ZIP
+ archive.
+ It can then be uploaded to Haketilo via its
+ {{ hkt_link('import page', 'import.items_import') }}.
+ {% endcall %}
+ {% endcall %}
+
+ {% call section() %}
+ {{ medium_heading('Uninstalling') }}
+
+ {% call paragraph() %}
+ Haketilo tracks dependencies between packages and libraries and
+ automatically determines which of them are no longer needed.
+ These are called <span class="bold">orphans</span> and if present, can be
+ removed from the {{ hkt_link('settings page', 'home.home') }}.
+ A version of package or library that is not being used but is still
+ available from an active repository is not considered an orphan. It
+ automatically becomes one when the repository either stops advertising it
+ as available or gets removed by the user from
+ {{ hkt_link('the repositories list', 'repos.repos') }}.
+ {% endcall %}
+
+ {% call paragraph() %}
+ When advanced UI features are enabled, it is additionally possible to
+ manually uninstall any single package that is not in use at a given
+ moment.
+ {% endcall %}
+ {% endcall %}
+
+ {% call section() %}
+ {{ medium_heading('Package contents') }}
+
+ {% call paragraph() %}
+ Each package has an <span class="bold">identifier</span> (built from a
+ restricted set of characters), a <span class="bold">long name</span>, a
+ <span class="bold">description</span>, a <span class="bold">version</span>
+ and almost always a list of <span class="bold">license files</span> and a
+ set of <span class="bold">URL patterns mapped to libraries</span>.
+ In addition there might also be other pieces of information such as
+ required permissions.
+ {% endcall %}
+ {% endcall %}
+
+ {% call section() %}
+ {{ medium_heading('Enabling/disabling') }}
+
+ {% call paragraph() %}
+ The user can put package in any of 3 possible states.
+ It can be either <span class="bold">enabled</span>,
+ <span class="bold">disabled</span> or
+ <span class="bold">not configured</span>.
+ {% endcall %}
+
+ {% call paragraph() %}
+ An enabled package always has its payloads injected on pages matched by
+ their patterns (unless some more specific pattern takes precedence on the
+ given page as described on the
+ {{ doc_page_link('policy selection page', 'policy_selection') }}).
+ {% endcall %}
+
+ {% call paragraph() %}
+ A disabled package is always ignored.
+ It has to be manually re-enabled for Haketilo to take it into account
+ again.
+ {% endcall %}
+
+ {% call paragraph() %}
+ Finally, a package that is neither explicitly enabled nor disabled can be
+ treated differently depending on user's choice on the
+ {{ hkt_link('settings page', 'home.home') }}.
+ It is possible to have Haketilo
+ {% endcall %}
+
+ {% call unordered_list() %}
+ {% call list_entry() %}
+ automatically inject such packages' payloads on mathing pages,
+ {% endcall %}
+ {% call list_entry() %}
+ prompt the user on matching pages asking whether the package should be
+ enabled or
+ {% endcall %}
+ {% call list_entry() %}
+ completely ignore non-configured packages.
+ {% endcall %}
+ {% endcall %}
+ {% endcall %}
+
+ {% call section() %}
+ {{ medium_heading('Handling multiple versions') }}
+
+ {% call paragraph() %}
+ It is possible to have many versions of the same package or library
+ installed.
+ When this is the case, Haketilo by default uses the newest versions it
+ can.
+ Additionally, if certain package is enabled, its page also allows the user
+ to configure its <span class="bold">pinning</span>.
+ A package can be
+ {% endcall %}
+
+ {% call unordered_list() %}
+ {% call list_entry() %}
+ pinned to use a particular version,
+ {% endcall %}
+ {% call list_entry() %}
+ pinned to use the best version from a particular
+ {{ doc_page_link('repository', 'repositories') }} or
+ {% endcall %}
+ {% call list_entry() %}
+ not pinned at all (best version overall is used).
+ {% endcall %}
+ {% endcall %}
+ {% endcall %}
+{% endblock main %}
diff --git a/src/hydrilla/proxy/self_doc/en_US/policy_selection.html.jinja b/src/hydrilla/proxy/self_doc/en_US/policy_selection.html.jinja
new file mode 100644
index 0000000..687d2bd
--- /dev/null
+++ b/src/hydrilla/proxy/self_doc/en_US/policy_selection.html.jinja
@@ -0,0 +1,109 @@
+{#
+SPDX-License-Identifier: GPL-3.0-or-later OR CC-BY-SA-4.0
+
+Documentation page describing how Haketilo selects policy to apply to a page.
+
+This file is part of Hydrilla&Haketilo.
+
+Copyright (C) 2022 Wojtek Kosior
+
+Dual licensed under
+* GNU General Public License v3.0 or later and
+* Creative Commons Attribution Share Alike 4.0 International.
+
+You can choose to use either of these licenses or both.
+
+
+I, Wojtek Kosior, thereby promise not to sue for violation of this
+file's licenses. Although I request that you do not make use of this
+code in a proprietary work, I am not going to enforce this in court.
+#}
+{% extends "doc_base.html.jinja" %}
+
+{% block title %} Policy selection {% endblock %}
+
+{% block main %}
+ {{ big_heading('Page policy selection') }}
+
+ {% call section() %}
+ {% call paragraph() %}
+ When a web page is opened, Haketilo is capable of either
+ {% call unordered_list() %}
+ {% call list_entry() %}
+ blocking page's own scripts and
+ {{ doc_page_link('injecting payload', 'packages') }}
+ configured by the user,
+ {% endcall %}
+ {% call list_entry() %}
+ blocking page's own scripts and injecting an automatically-chosen
+ payload that is usable with the page,
+ {% endcall %}
+ {% call list_entry() %}
+ presenting a dialog asking whether to enable an automatically-chosen
+ payload that is usable with the page,
+ {% endcall %}
+ {% call list_entry() %}
+ {{ doc_page_link('blocking', 'script_blocking') }} page's own scripts
+ or
+ {% endcall %}
+ {% call list_entry() %}
+ allowing page's own scripts to execute normally (i.e. not modifying
+ the page in any meaningful way).
+ {% endcall %}
+ {% endcall %}
+ {% endcall %}
+ {% endcall %}
+
+ {% call section() %}
+ {{ medium_heading('Policy precedence') }}
+
+ {% call paragraph() %}
+ User configures Haketilo's behavior by defining script-blocking and
+ -allowing rules and by adding and enabling packages. Each rule and each
+ package payload has a {{ doc_page_link('URL pattern', 'url_patterns') }}.
+ This pattern determines which pages the policy is compatible with.
+ Patterns also have well-defined specificity. When multiple rules and
+ packages are combatible with given page's URL, the one with the most
+ specific pattern "wins". In case of a tie, payload injection is assumed to
+ take precedence over rule application.
+ {% endcall %}
+
+ {% call paragraph() %}
+ In the absence of suitable rules and enabled packages, Haketilo may
+ consider non-enabled packages that are suitable for use on the
+ currently-visited site. It will either inject package payload
+ automatically, ask the user whether to enable the package or ignore it
+ completely. The user can switch between these 3 behaviors on the Haketilo
+ {{ hkt_link('settings page', 'home.home') }}. Packages that were
+ explicitly marked as disabled will always be ignored. Pattern specificity
+ is also taken into account in case of multiple packages.
+ {% endcall %}
+
+ {% call paragraph() %}
+ When absolutely no explicit policy appears suitable for given page,
+ Haketilo will apply its default script handling behavrior. Whether
+ JavaScript is blocked or allowed by default is also determined by user's
+ choice on the {{ hkt_link('settings page', 'home.home') }}.
+ {% endcall %}
+ {% endcall %}
+
+ {% call section() %}
+ {{ medium_heading('Special cases') }}
+
+ {% call paragraph() %}
+ The sites served by Haketilo itself are exempt from all policies. These
+ are <code>http://hkt.mitm.it</code>, <code>https://hkt.mitm.it</code>
+ and <code>http://mitm.it</code>. Additionally, if Haketilo experiences an
+ internal error (e.g. because it could not parse current URL as sent in by
+ the browser), it will try to block page's JavaScript as a security
+ measure.
+ {% endcall %}
+
+ {% call paragraph() %}
+ Internally, Haketilo also has a special high-priority policy for serving
+ files used by payloads and for making its APIs accessible to payload
+ scripts. This is, however, an implementation detail and casual users need
+ not care about it nor understand these nuances.
+ {% endcall %}
+ {% endcall %}
+{% endblock main %}
diff --git a/src/hydrilla/proxy/self_doc/en_US/popup.html.jinja b/src/hydrilla/proxy/self_doc/en_US/popup.html.jinja
new file mode 100644
index 0000000..a5ad909
--- /dev/null
+++ b/src/hydrilla/proxy/self_doc/en_US/popup.html.jinja
@@ -0,0 +1,157 @@
+{#
+SPDX-License-Identifier: GPL-3.0-or-later OR CC-BY-SA-4.0
+
+Documentation page describing Haketilo popup.
+
+This file is part of Hydrilla&Haketilo.
+
+Copyright (C) 2022 Wojtek Kosior
+
+Dual licensed under
+* GNU General Public License v3.0 or later and
+* Creative Commons Attribution Share Alike 4.0 International.
+
+You can choose to use either of these licenses or both.
+
+
+I, Wojtek Kosior, thereby promise not to sue for violation of this
+file's licenses. Although I request that you do not make use of this
+code in a proprietary work, I am not going to enforce this in court.
+#}
+{% extends "doc_base.html.jinja" %}
+
+{% block title %} Popup {% endblock %}
+
+{% block main %}
+ {{ big_heading('Haketilo popup') }}
+
+ {% call section() %}
+ {% call paragraph() %}
+ Taking inspiration from user interface features of browser extensions,
+ Haketilo also offers a popup window for quick interaction with the
+ user. For technical reasons, the popup is presented as part of the web
+ page and behaves slightly differently from those some users might have
+ found in similar tools.
+ {% endcall %}
+ {% endcall %}
+
+ {% call section() %}
+ {{ medium_heading('Operating') }}
+
+ {% call paragraph() %}
+ The popup dialog can be opened by typing big letters "HKT" anywhere on the
+ page. It then presents some basic information about the handling of
+ current URL. It also allows the user quickly define new
+ {{ doc_page_link('rules', 'script_blocking') }} or
+ {{ doc_page_link('payloads', 'packages') }} for it. As of Haketilo 3.0,
+ however, the actual configuration is not performed from the popup itself
+ but rather a relevant Haketilo rule/payload definition page is opened in a
+ new tab.
+ {% endcall %}
+
+ {% call paragraph() %}
+ The dialog can be closed by clicking anywhere on the darker area around
+ it. It can then be reopened by typing "HKT" again.
+ {% endcall %}
+ {% endcall %}
+
+ {% call section() %}
+ {{ medium_heading('Enabling/disabling') }}
+
+ {% call paragraph() %}
+ Popup is unavailable by default on Haketilo special sites including
+ <code>https://hkt.mitm.it</code>. It can also be disabled independently on
+ {% endcall %}
+
+ {% call unordered_list() %}
+ {% call list_entry() %}
+ pages with JS allowed,
+ {% endcall %}
+ {% call list_entry() %}
+ pages with JS blocked and
+ {% endcall %}
+ {% call list_entry() %}
+ pages with script payload injected.
+ {% endcall %}
+ {% endcall %}
+
+ {% call paragraph() %}
+ This can be configured on the {{ hkt_link('setings page', 'home.home') }}
+ and might be useful to users who are careful about fingerprinting.
+ {% endcall %}
+ {% endcall %}
+
+ {% call section() %}
+ {{ medium_heading('Fingerprinting considerations') }}
+
+ {% call paragraph() %}
+ To make the popup available, Haketilo has to inject an additional script
+ to all pages. That makes it easy for pages to determine with certainty
+ that given user is running Haketilo. This has implications for privacy and
+ may also be used by a hostile site to selectively cause annoyance to
+ Haketilo users.
+ {% endcall %}
+
+ {% call paragraph() %}
+ The above problems would be present regardless on pages with
+ Haketilo-injected payloads. I.e. in many cases a site could theoretically
+ find out the user is not accessing it in a normal way. However, the popup
+ also increases fingerprintability when no payload is in use and especially
+ on pages with JavaScript allowed. For this reason, the presence of popup
+ on pages has been made configurable.
+ {% endcall %}
+
+ {% call paragraph() %}
+ It is also worth noting that as of version 3.0 Haketilo does not make
+ guarantees about the browser fingerprint. Despite best efforts, there are
+ still other aspects that might make a Haketilo user distinguishable to a
+ website even when popup is disabled.
+ {% endcall %}
+ {% endcall %}
+
+ {% call section() %}
+ {{ medium_heading('Other caveats') }}
+
+ {% call paragraph() %}
+ Some other potential issues related to the popup are described below.
+ {% endcall %}
+ {% endcall %}
+
+ {% call section() %}
+ {{ small_heading('Interference with the site') }}
+
+ {% call paragraph() %}
+ The popup gets injected by Haketilo into the actual web page. Although
+ care was taken to make accidental breakage unlikely, it might still happen
+ under some specific conditions.
+ {% endcall %}
+ {% endcall %}
+
+ {% call section() %}
+ {{ small_heading('Interference with other script-blocking tools') }}
+
+ {% call paragraph() %}
+ The popup is driven by a piece of JavaScript code injected by Haketilo to
+ pages. Haketilo by itself makes sure neither the policies specified by the
+ page nor its own script-blocking mechanisms interfere with this particular
+ piece. In spite of that, a browser extension or web browser's own settings
+ might prevent the popup script from executing, making the dialog
+ unavailable.
+ {% endcall %}
+ {% endcall %}
+
+ {% call section() %}
+ {{ small_heading('URL mismatch') }}
+
+ {% call paragraph() %}
+ Sometimes a page might change parts of its address visible in browser's
+ URL bar. E.g. after opening <code>https://entraide.chatons.org/</code> in
+ the browser we might see <code>https://entraide.chatons.org/en/</code> as
+ the current address even though no reload happened. In addition, some
+ browsers hide URL's traling dash ("/") from the user. Regardless of that,
+ Haketilo's popup always presents the original URL under which the current
+ page was served. Although this the intended behavior, it might cause
+ confusion and therefore has been documented here.
+ {% endcall %}
+ {% endcall %}
+{% endblock main %}
diff --git a/src/hydrilla/proxy/self_doc/en_US/repositories.html.jinja b/src/hydrilla/proxy/self_doc/en_US/repositories.html.jinja
new file mode 100644
index 0000000..4cf6d2c
--- /dev/null
+++ b/src/hydrilla/proxy/self_doc/en_US/repositories.html.jinja
@@ -0,0 +1,128 @@
+{#
+SPDX-License-Identifier: GPL-3.0-or-later OR CC-BY-SA-4.0
+
+Documentation page describing the concept of repositories in Haketilo.
+
+This file is part of Hydrilla&Haketilo.
+
+Copyright (C) 2022 Wojtek Kosior
+
+Dual licensed under
+* GNU General Public License v3.0 or later and
+* Creative Commons Attribution Share Alike 4.0 International.
+
+You can choose to use either of these licenses or both.
+
+
+I, Wojtek Kosior, thereby promise not to sue for violation of this
+file's licenses. Although I request that you do not make use of this
+code in a proprietary work, I am not going to enforce this in court.
+#}
+{% extends "doc_base.html.jinja" %}
+
+{% block title %} Repositories {% endblock %}
+
+{% block main %}
+ {{ big_heading('Repositories in Haketilo') }}
+
+ {% call section() %}
+ {% call paragraph() %}
+ {{ doc_page_link('Packages', 'packages') }} used to alter sites' behavior
+ can be obtained by users from Hydrilla repositories. The repositories to
+ use can be configured from the
+ {{ hkt_link('relevant Haketilo UI page', 'repos.repos') }}. When Haketilo
+ is first run, it only has one entry on that page - the official Hydrilla
+ repository with fixes for sites that normally rely on (often proprietary)
+ JavaScript.
+ {% endcall %}
+ {% endcall %}
+
+ {% call section() %}
+ {{ medium_heading('Adding') }}
+
+ {% call paragraph() %}
+ Before experimenting with third-party repositories please bear in mind
+ that a hostile Haketilo package can cause real harm.
+ Scripts injected by Haketilo have access to data on the page, including
+ cookies and passwords you may enter.
+ Do make sure the repositories you are using are trustworthy.
+ {% endcall %}
+
+ {% call paragraph() %}
+ On the {{ hkt_link('repository addition page', 'repos.add_repo') }} the
+ user is expected to supply 2 pieces of information.
+ The <span class="bold">URL</span> of the repository and its
+ <span class="bold">name</span>.
+ The URL is supposed to be provided by repository owner.
+ Then name is only used locally and can be chosen by the user.
+ Allowed are most visible ASCII characters, with possible spaces in-betwen.
+ No 2 repositories can use the same name.
+ {% endcall %}
+
+ {% call paragraph() %}
+ As of Haketilo version 3.0 the user does not need to provide any
+ authentication data (e.g. private keys) because cryptographic signing of
+ packages is not yet supported. This may change in the future.
+ {% endcall %}
+ {% endcall %}
+
+ {% call section() %}
+ {{ medium_heading('Removing') }}
+
+ {% call paragraph() %}
+ A repository can be deleted at any time. When this happens,
+ {% endcall %}
+
+ {% call unordered_list() %}
+ {% call list_entry() %}
+ its packages that were in use (e.g. were enabled) retain their state,
+ {% endcall %}
+ {% call list_entry() %}
+ its packages that were installed but not in use become
+ <span class="bold">orphans</span> and can be removed from the
+ {{ hkt_link('settings page', 'home.home') }} and
+ {% endcall %}
+ {% call list_entry() %}
+ its packages that were not installed are forgotten.
+ {% endcall %}
+ {% endcall %}
+
+ {% call paragraph() %}
+ A deleted repository remains viewable from the
+ {{ hkt_link('repositories management page', 'repos.repos') }} for as long
+ as some of its packages remain installed.
+ {% endcall %}
+ {% endcall %}
+
+ {% call section() %}
+ {{ medium_heading('Operating') }}
+
+ {% call paragraph() %}
+ Before repository's contents become viewable on the
+ {{ hkt_link('packages listing page', 'items.packages') }}, it needs to be
+ <span class="bold">refreshed</span>.
+ As of Haketilo 3.0-beta1, this action needs to be triggered manually by
+ the user from the configuration page of that repository.
+ Subsequent refreshals are needed every time the user wants to pull package
+ updates.
+ {% endcall %}
+
+ {% call paragraph() %}
+ Repository's name and URL can also be changed from its configuration page.
+ The same requirements for their format hold as when adding a new
+ repository.
+ {% endcall %}
+ {% endcall %}
+
+ {% call section() %}
+ {{ medium_heading('Local items') }}
+
+ {% call paragraph() %}
+ When the users installs some additional packages without using a
+ repository, these are considered <span class="bold">local packages</span>.
+ A special "Local items" entry then appears on the
+ {{ hkt_link('repositories management page', 'repos.repos') }}. Local
+ packages that are not in use are automatically considered orhpans.
+ {% endcall %}
+ {% endcall %}
+{% endblock %}
diff --git a/src/hydrilla/proxy/self_doc/en_US/script_blocking.html.jinja b/src/hydrilla/proxy/self_doc/en_US/script_blocking.html.jinja
new file mode 100644
index 0000000..c0a5275
--- /dev/null
+++ b/src/hydrilla/proxy/self_doc/en_US/script_blocking.html.jinja
@@ -0,0 +1,125 @@
+{#
+SPDX-License-Identifier: GPL-3.0-or-later OR CC-BY-SA-4.0
+
+Documentation page describing how Haketilo blocks scripts.
+
+This file is part of Hydrilla&Haketilo.
+
+Copyright (C) 2022 Wojtek Kosior
+
+Dual licensed under
+* GNU General Public License v3.0 or later and
+* Creative Commons Attribution Share Alike 4.0 International.
+
+You can choose to use either of these licenses or both.
+
+
+I, Wojtek Kosior, thereby promise not to sue for violation of this
+file's licenses. Although I request that you do not make use of this
+code in a proprietary work, I am not going to enforce this in court.
+#}
+{% extends "doc_base.html.jinja" %}
+
+{% block title %} Script blocking {% endblock %}
+
+{% block main %}
+ {{ big_heading('Script blocking in Haketilo') }}
+
+ {% call section() %}
+ {% call paragraph() %}
+ Modern web browsers allow sites to execute software on users'
+ devices. This software is usually written in a language called JavaScript
+ and abbreviated as JS. It can serve various purposes - from small
+ enhancements to deployment of heavy applications inside the
+ browser. Because Haketilo aims to give users control over their web
+ browsing, one of its supported features is blocking of JavaScript
+ execution on per-page and per-site basis.
+ {% endcall %}
+
+ {% call paragraph() %}
+ Besides the casual script-blocking discussed here, Haketilo also blocks
+ page's JavaScript when injecting the user-specified
+ {{ doc_page_link('script payloads', 'packages') }}. That functionality is
+ described on its own documentation page.
+ {% endcall %}
+ {% endcall %}
+
+ {% call section() %}
+ {{ medium_heading('Configuring script blocking') }}
+
+ {% call paragraph() %}
+ User can
+ {{
+ hkt_link('define script-blocking and -allowing rules', 'rules.rules')
+ }}
+ using {{ doc_page_link('URL patterns', 'url_patterns') }}. Each such rule
+ tells Haketilo to either block or allow scripts on pages matched by its
+ pattern. Rules with more specific patterns can override those with less
+ specific ones as described on the
+ {{ doc_page_link('policy selection page', 'policy_selection') }}.
+ {% endcall %}
+
+ {% call paragraph() %}
+ As an example, if we want all scripts on english Wikipedia pages to be
+ blocked, we can add a blocking rule with
+ pattern <code>https://en.wikipedia.org/***</code>. If we then wanted to
+ make an exception just for the "List of emoticons" page, we could create
+ an additional allowing rule with
+ <code>https://en.wikipedia.org/wiki/List_of_emoticons</code> as its
+ pattern. It would take effect on that page while all the other english
+ Wikipedia pages would still have their scripts blocked.
+ {% endcall %}
+
+ {% call paragraph() %}
+ It is also possible to configure whether scripts should be blocked by
+ dafault on pages where no explicit rule and no payload is used. The
+ relevant option can be found on Haketilo
+ {{ hkt_link('settings page', 'home.home') }}.
+ {% endcall %}
+ {% endcall %}
+
+ {% call section() %}
+ {{ medium_heading('Use with other script-blocking tools') }}
+
+ {% call paragraph() %}
+ Various browsers and browser extension can also be configured to block
+ JavaScript. Haketilo works independently of those tools. If the user
+ desires to have scripts on certain page to execute normally, both Haketilo
+ and other tools must be configured to allow that.
+ {% endcall %}
+
+ {% call paragraph() %}
+ Unlike most similar tools, Haketilo operates outside the web browser. As a
+ result, it is relatively unlikely for Haketilo to cause these to
+ malfunction. At the same time, it is relatively easy to have another
+ script blocker break some Haketilo functionality (e.g. its
+ {{ doc_page_link('popup', 'popup') }}).
+ {% endcall %}
+ {% endcall %}
+
+ {% call section() %}
+ {{ medium_heading('Technical details') }}
+
+ {% call paragraph() %}
+ From technical point of view, Haketilo, as of version 3.0, blocks
+ JavaScript by altering the Content-Security-Policy (abbreviated CSP)
+ headers in HTTP responses. The original CSP directives sent by site are
+ retained, with exception of those which would result in CSP violation
+ reports being sent. Haketilo's own script-blocking directives are then
+ added to produce the final CSP which user's web browser eventually sees.
+ {% endcall %}
+
+ {% call paragraph() %}
+ The above means that neither the scripts that would be blocked by page's
+ own rules nor those that are blocked by Haketilo are going to cause CSP
+ reports to be sent.
+ {% endcall %}
+
+ {% call paragraph() %}
+ In addition, even when a page has JavaScript nominally blocked, Haketilo
+ 3.0 may nevertheless inject into it its own script responsible for making
+ the popup available. The CSP is then modified appropriately to allow only
+ that script to run.
+ {% endcall %}
+ {% endcall %}
+{% endblock main %}
diff --git a/src/hydrilla/proxy/self_doc/en_US/url_patterns.html.jinja b/src/hydrilla/proxy/self_doc/en_US/url_patterns.html.jinja
new file mode 100644
index 0000000..f3415c5
--- /dev/null
+++ b/src/hydrilla/proxy/self_doc/en_US/url_patterns.html.jinja
@@ -0,0 +1,409 @@
+{#
+SPDX-License-Identifier: GPL-3.0-or-later OR CC-BY-SA-4.0
+
+Documentation page describing URL patterns understood by Haketilo.
+
+This file is part of Hydrilla&Haketilo.
+
+Copyright (C) 2022 Wojtek Kosior
+
+Dual licensed under
+* GNU General Public License v3.0 or later and
+* Creative Commons Attribution Share Alike 4.0 International.
+
+You can choose to use either of these licenses or both.
+
+
+I, Wojtek Kosior, thereby promise not to sue for violation of this
+file's licenses. Although I request that you do not make use of this
+code in a proprietary work, I am not going to enforce this in court.
+#}
+{% extends "doc_base.html.jinja" %}
+
+{% block title %} URL patterns {% endblock %}
+
+{% block main %}
+ {{ big_heading('Haketio URL patterns') }}
+
+ {% call section() %}
+ {% call paragraph() %}
+ We want to be able to apply different rules and custom scripts for
+ different websites. However, merely specifying "do this for all documents
+ under <code>https://example.com</code>" is not enough. Single site's pages
+ might differ strongly and require different custom scripts to be
+ loaded. Always matching against a full URL like
+ <code>https://example.com/something/somethingelse</code> is also not
+ a good option. It doesn't allow us to properly handle a site that serves
+ similar pages for multiple values substituted for
+ <code>somethingelse</code>.
+ {% endcall %}
+ {% endcall %}
+
+ {% call section() %}
+ {{ medium_heading('Employed solution') }}
+
+ {% call paragraph() %}
+ Wildcards are being used to address the problem. Each payload and rule in
+ Haketilo has a URL pattern that specifies to which internet pages it
+ applies. A URL pattern can be as as simple as literal URL in which case it
+ only matches itself. It can also contain wildcards in the form of one or
+ more asterisks (<code>*</code>) that correspond to multiple possible
+ strings occurring in that place.
+ {% endcall %}
+
+ {% call paragraph() %}
+ Wildcards can appear in URL's domain and path that follows it. These 2
+ types of wildcards are handled separately.
+ {% endcall %}
+ {% endcall %}
+
+ {% call section() %}
+ {{ small_heading('Domain wildcards') }}
+
+ {% call paragraph() %}
+ A domain wildcard takes the form of one, two or three asterisks occurring
+ in place of a single domain name segment at the beginning
+ (left). Depending on the number of asterisks, the meaning is as follows
+ {% endcall %}
+
+ {% call unordered_list() %}
+ {% call list_entry() %}
+ no asterisks (e.g. <code>example.com</code>) - match domain name exactly
+ (e.g. <code>example.com</code>)
+ {% endcall %}
+ {% call list_entry() %}
+ one asterisk (e.g. <code>*.example.com</code>) - match all domains
+ resulting from substituting <code>*</code> with a
+ <span class="bold">single</span> segment (e.g.
+ <code>banana.example.com</code> or <code>pineapple.example.com</code>
+ but <span class="bold">not</span> <code>pineapple.pen.example.com</code>
+ nor <code>example.com</code>)
+ {% endcall %}
+ {% call list_entry() %}
+ two asterisks (e.g. <code>**.example.com</code>) - match all domains
+ resulting from substituting <code>**</code> with
+ <span class="bold">two or more</span> segments (e.g.
+ <code>monad.breakfast.example.com</code> or
+ <code>pure.monad.breakfast.example.com</code> but
+ <span class="bold">not</span> <code>cabalhell.example.com</code> nor
+ <code>example.com</code>)
+ {% endcall %}
+ {% call list_entry() %}
+ three asterisks (e.g. <code>***.example.com</code>) - match all domains
+ resulting from substituting <code>***</code> with
+ <span class="bold">zero or more</span> segments (e.g.
+ <code>hello.parkmeter.example.com</code> or
+ <code>iliketrains.example.com</code> or <code>example.com</code>)
+ {% endcall %}
+ {% endcall %}
+ {% endcall %}
+
+ {% call section() %}
+ {{ small_heading('Path wildcards') }}
+
+ {% call paragraph() %}
+ A path wildcard takes the form of one, two or three asterisks occurring in
+ place of a single path segment at the end of path (right). Depending on
+ the number of asterisks, the meaning is as follows
+ {% endcall %}
+
+ {% call unordered_list() %}
+ {% call list_entry() %}
+ no asterisks (e.g. <code>/joke/clowns</code>) - match path exactly (e.g.
+ <code>/joke/clowns</code>)
+ {% endcall %}
+ {% call list_entry() %}
+ one asterisk (e.g. <code>/itscalled/*</code>) - match all paths
+ resulting from substituting <code>*</code> with a
+ <span class="bold">single</span> segment (e.g.
+ <code>/itscalled/gnulinux</code> or <code>/itscalled/glamp</code> but
+ <span class="bold">not</span> <code>/itscalled/</code> nor
+ <code>/itscalled/gnu/linux</code>)
+ {% endcall %}
+ {% call list_entry() %}
+ two asterisks (e.g. <code>/another/**</code>) - match all paths
+ resulting from substituting <code>**</code> with
+ <span class="bold">two or more</span> segments (e.g.
+ <code>/another/nsa/backdoor</code> or
+ <code>/another/best/programming/language</code> but
+ <span class="bold">not</span> <code>/another/apibreak</code> nor
+ <code>/another</code>)
+ {% endcall %}
+ {% call list_entry() %}
+ three asterisks (e.g. <code>/mail/dmarc/***</code>) - match all paths
+ resulting from substituting <code>***</code> with
+ <span class="bold">zero or more</span> segments (e.g.
+ <code>/mail/dmarc/spf</code>, <code>/mail/dmarc</code> or
+ <code>/mail/dmarc/dkim/failure</code> but
+ <span class="bold">not</span> <code>/mail/</code>)
+ {% endcall %}
+ {% endcall %}
+
+ {% call paragraph() %}
+ If pattern ends <span class="bold">without</span> a trailing slash, it
+ mathes paths with any number of trailing slashes, including zero. If
+ pattern ends <span class="bold">with</span> a trailing slash, it only
+ mathes paths with one or more trailing slashes. For example,
+ <code>/itscalled/*</code> matches <code>/itscalled/gnulinux</code>,
+ <code>/itscalled/gnulinux/</code> and <code>/itscalled/gnulinux//</code>
+ while <code>/itscalled/*/</code> only matches
+ <code>/itscalled/gnulinux/</code> and <code>/itscalled/gnulinux//</code>
+ out of those three.
+ {% endcall %}
+
+ {% call paragraph() %}
+ If two patterns only differ by the presence of a trailing slash,
+ pattern <span class="bold">with</span> a trailing slash is considered
+ <span class="bold">more specific</span>.
+ {% endcall %}
+
+ {% call paragraph() %}
+ Additionally, any path with literal trailing asterisks is matched by
+ itself, even if such pattern would otherwise be treated as wildcard
+ (e.g. <code>/gobacktoxul/**</code> matches <code>/gobacktoxul/**</code>).
+ This is likely to change in the future and would best not be relied upon.
+ Appending three additional asterisks to path pattern to represent literal
+ asterisks is being considered.
+ {% endcall %}
+ {% endcall %}
+
+ {% call section() %}
+ {{ small_heading('URL scheme wildcard') }}
+
+ {% call paragraph() %}
+ <code>http://</code> and <code>https://</code> shemes in the URL are
+ matched exactly. However, starting with Haketilo 3.0, it is also possible
+ for scheme pseudo-wildcard of <code>http*://</code> to be used. Use of URL
+ pattern with this scheme is equivalent to the use of 2 separate patterns
+ starting with <code>http://</code> and <code>https://</code>,
+ respectively. For example, pattern <code>http*://example.com</code> shall
+ match both <code>https://example.com</code> and
+ <code>http://example.com</code>.
+ {% endcall %}
+
+ {% call paragraph() %}
+ <code>http*://</code> may be considered not to be a true wildcard but
+ rather an alias for either of the other 2 values. As of Haketilo 3.0, the
+ speicificity of a URL pattern starting with <code>http*://</code> is
+ considered to be the same as that of the corresponding URL pattern
+ starting with <code>http://</code> or <code>https://</code>. In case of a
+ conflict, the order of precedence of such patterns is unspecified. This
+ behavior is likely to change in the future versions of Haketilo.
+ {% endcall %}
+ {% endcall %}
+
+ {% call section() %}
+ {{ small_heading('Wildcard pattern priorities and querying') }}
+
+ {% call paragraph() %}
+ In case multiple patterns match some URL, the more specific one is
+ preferred. Specificity is considered as follows
+ {% endcall %}
+
+ {% call unordered_list() %}
+ {% call list_entry() %}
+ If patterns only differ in the final path segment, the one with least
+ wildcard asterisks in that segment if preferred.
+ {% endcall %}
+ {% call list_entry() %}
+ If patterns, besides the above, only differ in path length, one with
+ longer path is preferred. Neither final wildcard segment nor trailing
+ dashes account for path length.
+ {% endcall %}
+ {% call list_entry() %}
+ If patterns, besides the above, only differ in the initial domain
+ segment, one with least wildcard asterisks in that segment is preferred.
+ {% endcall %}
+ {% call list_entry() %}
+ If patterns differ in domain length, one with longer domain is
+ preferred. Initial wildcard segment does not account for domain length.
+ {% endcall %}
+ {% endcall %}
+
+ {% call paragraph() %}
+ As an example, consider the URL
+ <code>http://settings.query.example.com/google/tries/destroy/adblockers//</code>.
+ Patterns matching it are, in the following order
+ {% endcall %}
+
+ {% call verbatim() %}
+http://settings.query.example.com/google/tries/destroy/adblockers/
+http://settings.query.example.com/google/tries/destroy/adblockers
+http://settings.query.example.com/google/tries/destroy/adblockers/***/
+http://settings.query.example.com/google/tries/destroy/adblockers/***
+http://settings.query.example.com/google/tries/destroy/*/
+http://settings.query.example.com/google/tries/destroy/*
+http://settings.query.example.com/google/tries/destroy/***/
+http://settings.query.example.com/google/tries/destroy/***
+http://settings.query.example.com/google/tries/**/
+http://settings.query.example.com/google/tries/**
+http://settings.query.example.com/google/tries/***/
+http://settings.query.example.com/google/tries/***
+http://settings.query.example.com/google/**/
+http://settings.query.example.com/google/**
+http://settings.query.example.com/google/***/
+http://settings.query.example.com/google/***
+http://settings.query.example.com/**/
+http://settings.query.example.com/**
+http://settings.query.example.com/***/
+http://settings.query.example.com/***
+http://***.settings.query.example.com/google/tries/destroy/adblockers/
+http://***.settings.query.example.com/google/tries/destroy/adblockers
+http://***.settings.query.example.com/google/tries/destroy/adblockers/***/
+http://***.settings.query.example.com/google/tries/destroy/adblockers/***
+http://***.settings.query.example.com/google/tries/destroy/*/
+http://***.settings.query.example.com/google/tries/destroy/*
+http://***.settings.query.example.com/google/tries/destroy/***/
+http://***.settings.query.example.com/google/tries/destroy/***
+http://***.settings.query.example.com/google/tries/**/
+http://***.settings.query.example.com/google/tries/**
+http://***.settings.query.example.com/google/tries/***/
+http://***.settings.query.example.com/google/tries/***
+http://***.settings.query.example.com/google/**/
+http://***.settings.query.example.com/google/**
+http://***.settings.query.example.com/google/***/
+http://***.settings.query.example.com/google/***
+http://***.settings.query.example.com/**/
+http://***.settings.query.example.com/**
+http://***.settings.query.example.com/***/
+http://***.settings.query.example.com/***
+http://*.query.example.com/google/tries/destroy/adblockers/
+http://*.query.example.com/google/tries/destroy/adblockers
+http://*.query.example.com/google/tries/destroy/adblockers/***/
+http://*.query.example.com/google/tries/destroy/adblockers/***
+http://*.query.example.com/google/tries/destroy/*/
+http://*.query.example.com/google/tries/destroy/*
+http://*.query.example.com/google/tries/destroy/***/
+http://*.query.example.com/google/tries/destroy/***
+http://*.query.example.com/google/tries/**/
+http://*.query.example.com/google/tries/**
+http://*.query.example.com/google/tries/***/
+http://*.query.example.com/google/tries/***
+http://*.query.example.com/google/**/
+http://*.query.example.com/google/**
+http://*.query.example.com/google/***/
+http://*.query.example.com/google/***
+http://*.query.example.com/**/
+http://*.query.example.com/**
+http://*.query.example.com/***/
+http://*.query.example.com/***
+http://***.query.example.com/google/tries/destroy/adblockers/
+http://***.query.example.com/google/tries/destroy/adblockers
+http://***.query.example.com/google/tries/destroy/adblockers/***/
+http://***.query.example.com/google/tries/destroy/adblockers/***
+http://***.query.example.com/google/tries/destroy/*/
+http://***.query.example.com/google/tries/destroy/*
+http://***.query.example.com/google/tries/destroy/***/
+http://***.query.example.com/google/tries/destroy/***
+http://***.query.example.com/google/tries/**/
+http://***.query.example.com/google/tries/**
+http://***.query.example.com/google/tries/***/
+http://***.query.example.com/google/tries/***
+http://***.query.example.com/google/**/
+http://***.query.example.com/google/**
+http://***.query.example.com/google/***/
+http://***.query.example.com/google/***
+http://***.query.example.com/**/
+http://***.query.example.com/**
+http://***.query.example.com/***/
+http://***.query.example.com/***
+http://**.example.com/google/tries/destroy/adblockers/
+http://**.example.com/google/tries/destroy/adblockers
+http://**.example.com/google/tries/destroy/adblockers/***/
+http://**.example.com/google/tries/destroy/adblockers/***
+http://**.example.com/google/tries/destroy/*/
+http://**.example.com/google/tries/destroy/*
+http://**.example.com/google/tries/destroy/***/
+http://**.example.com/google/tries/destroy/***
+http://**.example.com/google/tries/**/
+http://**.example.com/google/tries/**
+http://**.example.com/google/tries/***/
+http://**.example.com/google/tries/***
+http://**.example.com/google/**/
+http://**.example.com/google/**
+http://**.example.com/google/***/
+http://**.example.com/google/***
+http://**.example.com/**/
+http://**.example.com/**
+http://**.example.com/***/
+http://**.example.com/***
+http://***.example.com/google/tries/destroy/adblockers/
+http://***.example.com/google/tries/destroy/adblockers
+http://***.example.com/google/tries/destroy/adblockers/***/
+http://***.example.com/google/tries/destroy/adblockers/***
+http://***.example.com/google/tries/destroy/*/
+http://***.example.com/google/tries/destroy/*
+http://***.example.com/google/tries/destroy/***/
+http://***.example.com/google/tries/destroy/***
+http://***.example.com/google/tries/**/
+http://***.example.com/google/tries/**
+http://***.example.com/google/tries/***/
+http://***.example.com/google/tries/***
+http://***.example.com/google/**/
+http://***.example.com/google/**
+http://***.example.com/google/***/
+http://***.example.com/google/***
+http://***.example.com/**/
+http://***.example.com/**
+http://***.example.com/***/
+http://***.example.com/***
+ {% endcall %}
+
+ {% call paragraph() %}
+ Variants of those patterns starting with <code>http*://</code> would of
+ course match as well. They have been omitted for simplicity.
+ {% endcall %}
+
+ {% call paragraph() %}
+ For a simpler URL like <code>https://example.com</code> the patterns would
+ be
+ {% endcall %}
+
+ {% call verbatim() %}
+https://example.com
+https://example.com/***
+https://***.example.com
+https://***.example.com/***
+ {% endcall %}
+
+ {% call paragraph() %}
+ Variants of those patterns with a trailing dash added
+ would <span class="bold">not</span> match the URL. Also, the pattern
+ variants starting with <code>http*://</code> have been once again omitted.
+ {% endcall %}
+ {% endcall %}
+
+ {% call section() %}
+ {{ small_heading('Limits') }}
+
+ {% call paragraph() %}
+ In order to prevent some easy-to-conduct DoS attacks, older versions of
+ Haketilo and Hydrilla limited the lengths of domain and path parts of
+ processed URLs. This is no longer the case.
+ {% endcall %}
+ {% endcall %}
+
+ {% call section() %}
+ {{ medium_heading('Alternative solution idea: mimicking web server mechanics') }}
+
+ {% call paragraph() %}
+ While wildcard patterns as presented give a lot of flexibility, they are
+ not the only viable approach to specifying what URLs to apply
+ rules/payloads to. In fact, wildcards are different from how the server
+ side of a typical website decides what to return for a given URL request.
+ {% endcall %}
+
+ {% call paragraph() %}
+ In a typical scenario, an HTTP server like Apache reads configuration
+ files provided by its administrator and uses various (virtual host,
+ redirect, request rewrite, CGI, etc.) instructions to decide how to handle
+ given URL. Perhps using a scheme that mimics the configuration options
+ typically used with web servers would give more efficiency in specifying
+ what page settings to apply when.
+ {% endcall %}
+
+ {% call paragraph() %}
+ This approach may be considered in the future.
+ {% endcall %}
+ {% endcall %}
+{% endblock main %}