diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2021-03-19 12:05:54 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2021-03-19 12:05:54 +0200 |
commit | 3dfea6ae6a2c5a664093f959258378f0c23eb836 (patch) | |
tree | 0f380ec2d87d54dcfb236be5a753980580a3b6ac | |
download | web-master.tar.gz web-master.tar.bz2 |
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | Makefile | 20 | ||||
-rw-r--r-- | index.org | 244 | ||||
-rw-r--r-- | org2html.el | 7 | ||||
-rw-r--r-- | style.css | 85 |
5 files changed, 360 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2f784f5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*~ +.emacs* +/tmp +*.html diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a4457cd --- /dev/null +++ b/Makefile @@ -0,0 +1,20 @@ +CVSREPO=:ext:gray@puszcza.gnu.org.ua:/webcvs/haproxy-bulkredirect +SOURCES=index.html style.css + +index.html: index.org + emacs --batch -l org2html.el index.org + +clean: index.html + +.PHONY: .cache +.cache: + @if test -d .cache ; then \ + cd .cache && cvs update ; \ + else \ + mkdir .cache && \ + cvs -z3 -d $(CVSREPO) co -d .cache haproxy-bulkredirect; \ + fi + +update: .cache index.html + rsync -az $(SOURCES) .cache + cd .cache && cvs commit -m 'Update' diff --git a/index.org b/index.org new file mode 100644 index 0000000..df590a7 --- /dev/null +++ b/index.org @@ -0,0 +1,244 @@ +* Overview + +Lua library for handling big amounts of redirect rules in HAProxy. + +* Introduction + +The traditional way of implementing redirects in HAProxy configuration +file is by using the *http-request redirect* statement. It is quite +OK for a couple of redirect rules. Sometimes, however, you need to +install thousands of redirects. This may be necessary, for instance, +when switching to a new version of a site, in order to preserve old +references. Keeping such a big number of redirect statements in the +configuration file is impractical, and maintaining such a +configuration is tedious and error-prone task. + +The *haproxy-bulkredirect* library is designed for such cases. It +reads redirection rules from a plain text file, which is easy to +maintain. Internally, the rules are stored in an associative array, +which provides for fast lookups. + +* Dependencies + +[[http://www.haproxy.org/][HAProxy]] version 2.3.6 or newer, compiled with [[https://www.lua.org][Lua]] support. + +* Installation + +Copy the file *bulkredirect.lua* to a directory on the server where +the *haproxy* server runs. Load it in the *global* section of your +configuration file: + +#+BEGIN_SRC conf + global + lua-load /DIR/bulkredirect.lua +#+END_SRC + +(replace _DIR_ with the actual location on the filesystem). + +In your *frontend* section, add the following statement: + +#+BEGIN_SRC conf + http-request lua.bulkredirect +#+END_SRC + +Write down your redirection rules to the file +*/etc/haproxy/bulkredirect.rt* (see below for detailed instructions). +If you prefer another file name, make it known to the library using +the *HAPROXY_BULKREDIRECT* environment variable. When done, restart +haproxy. + +* Redirection table + +By default, the library reads redirection table from the file +*/etc/haproxy/bulkredirect.rt*. Another file name can be supplied via +the *HAPROXY_BULKREDIRECT* environment variable. + +Each line in a redirection table file is either a comment or a +statement. A comment begins with a *#* character as first +non-whitespace character in the line and extends to the end of the +line. Comments serve as human-readable annotations and are otherwise +ignored. Empty lines are ignored as well. + +There are three kinds of statements: option definition, domain +declaration, and redirection rule. + +** Option definition + +Option definition begins with the word *option* followed by one or +more option names, delimited with commas. Valid option names are: + +- *www* + + Declares that rules for each domain name declared below apply also for + that domain name, prefixed with *www.* + + Similarly, if a domain name already begins with *www.*, all rules + defined for it apply also for a domain name with the *www.* prefix + removed. + +- *exact* + + By default, all redirects imply prefix search. That is, if you + declare redirect rule from */foo* to */bar*, it would also apply to + */foo/bay*, which would be redirected to */bar/bay*, etc. + + If the *exact* option is set, no path prefix search is done: the + redirection is triggered only when the pathname part of the URL + matches exactly the left-hand side of a redirection rule. + +- *strippath* + + When set, removes from the final URL the pathname components + stripped off during prefix search. For example, given a redirect rule + from */foo* to */bar*, the URL */foo/bay/qux* will be redirected to + */bar* as well. + +- *stripquery* + + Discard any query string attached to the incoming URI. + +- *temporary* + + Creates a temporary redirect (HTTP response code 302). By default, + permanent redirects (301) are created. + +- *urlencode* + + Encode special characters in path parts of both source and destination + URLs as specified in RFC 3986 ("percent encoding"). By default, + bulkencode assumes all URLs are already properly encoded. + +Each of these option names can be prefixed with *no* to revert its +meaning. + +By default all options are unset. + +The options defined in this statement remain in effect until changed +by another *option* statement below. They also can be overridden for +each redirect individually. See the discussion of redirection rules +below. + +Here is an example of the *option* statement: + +#+BEGIN_SRC conf + option www,stripquery +#+END_SRC + +** Domain declaration + +This statement declares a domain for which the redirection rules below +apply. Syntactically, it is: + +#+BEGIN_SRC conf + [DOMAIN] +#+END_SRC + +where *DOMAIN* is the domain name. No whitespace is allowed between the +name and square brackets. + +If the [[https://puszcza.gnu.org.ua/projects/lua-idna][lua-idna]] library is available, the *DOMAIN* can be a UTF-8 +string. It will be converted to the appropriate ASCII form automatically. + +Each domain declaration remains in effect until another domain +declaration is encountered in the redirection table. + +Special name "*" means "any domain name". + +** Redirection rule + +A redirection rule consists of two parts separated by arbitrary +amount of whitespace. The left-hand side of the rule supplies the URI +in the current domain and the right-hand side gives the URL to +redirect it to. Examples + +#+BEGIN_SRC + /about /info + /pager?q=10&confirm=true https://example.com/pages +#+END_SRC + +Left-hand side may contain query part, as shown in the last example. +Notice, that the query part is matched verbatim, which means that, e.g. +*/pager?confirm=true&q=10* won't be redirected. + +If the query part is present in the right-hand side, it will replace +the actual query (i.e. the *stripquery* option is enabled +automatically). It will also enable the *strippath* option for this +redirect. + +A question mark without query part in the destination silently enables +both *stripquery* and *strippath* options for this redirect. + +To override options for a single redirect, supply them after the +destination using the same syntax as in *option* statement. For +example: + +#+BEGIN_SRC + /about /info exact,www +#+END_SRC + +* Test suite + +A test suite is included in the distribution. The following utilities +are needed for testing: *curl*, *egrep*, and *nc*. To run the test, change +to the directory *t/* and run: + +#+BEGIN_SRC + ./testsuite +#+END_SRC + +By default this will start a copy of *haproxy* listening on localhost +port 8080, if this port is available. If not, you will need to select +an unused TCP port and supply its number with the *-p* option, e.g.: + +#+BEGIN_SRC + ./testsuite -p 8081 +#+END_SRC + +Upon termination the *testsuite* tool prints total number of tests run and +number of failed tests. In case of failure, the information about +each failed test is preserved in the directory *testsuite.dir/N*, +where *N* is the test number. If you encounter any failures, please +create a tar archive of the testsuite.dir directory and send it to +the author. + +* Bug reports + +Please, send bug reports and suggestions to [[mailto:gray@gnu.org][Sergey Poznyakoff]]. + +* Copyright + +Copyright (C) 2021 Sergey Poznyakoff + +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 3, 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. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. + +* Document settings :noexport: + +Please ignore this section. It supplies the variables necessary for +proper rendering of this document. + +:PROPERTIES: +:VISIBILITY: folded +:END: + +#+TITLE: HAProxy bulk redirects +#+STARTUP: showall +#+EXCLUDE_TAGS: noexport +#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="style.css" /> +#+OPTIONS: ^:nil + +# Local Variables: +# mode: org +# paragraph-separate: "[ ^L]*$" +# version-control: never +# End: diff --git a/org2html.el b/org2html.el new file mode 100644 index 0000000..8556e3f --- /dev/null +++ b/org2html.el @@ -0,0 +1,7 @@ +(let ((bufname (car command-line-args-left)) + (target (car (cdr command-line-args-left)))) + (set-buffer (find-file bufname)) + (let ((name (org-html-export-to-html))) + (if target + (rename-file name target t)) + (kill-buffer (current-buffer)))) diff --git a/style.css b/style.css new file mode 100644 index 0000000..2304fb5 --- /dev/null +++ b/style.css @@ -0,0 +1,85 @@ +/* Basic settings */ +body { + margin-left: auto; + margin-right: auto; + max-width: 80em; + background-color: silver; + padding: 4px; +} +html {} +div { + background-color: white; +} + +div#content { + margin-top: 2em; + margin-left: 5%; + margin-right: 5%; + padding: 1em; + border: 1px solid black; +} + +div#postamble { + margin-bottom: 2em; + margin-left: 5%; + margin-right: 5%; + border: 1px solid black; + font-size: 80%; + padding: 4px; +} + +.title { text-align: center; } +.todo { color: red; } +.done { color: green; } +.tag { background-color: #add8e6; font-weight:normal } +.target { } +.timestamp { color: #bebebe; } +.timestamp-kwd { color: #5f9ea0; } +.right {margin-left:auto; margin-right:0px; text-align:right;} +.left {margin-left:0px; margin-right:auto; text-align:left;} +.center {margin-left:auto; margin-right:auto; text-align:center;} +p.verse { margin-left: 3% } +pre { + border: 1pt solid #AEBDCC; + background-color: #F3F5F7; + padding: 5pt; + font-family: courier, monospace; + font-size: 90%; + overflow:auto; +} +table { border-collapse: collapse; } +td, th { vertical-align: top; } +th.right { text-align:center; } +th.left { text-align:center; } +th.center { text-align:center; } +td.right { text-align:right; } +td.left { text-align:left; } +td.center { text-align:center; } +dt { font-weight: bold; } +div.figure { padding: 0.5em; } +div.figure p { text-align: center; } +div.inlinetask { + padding:10px; + border:2px solid gray; + margin:10px; + background: #ffffcc; +} +textarea { overflow-x: auto; } +.linenr { font-size:smaller } +.code-highlighted { + background-color:#ffff00; +} +.org-info-js_info-navigation { + border-style:none; +} +#org-info-js_console-label { + font-size:10px; + font-weight:bold; + white-space:nowrap; +} +.org-info-js_search-highlight { + background-color:#ffff00; + color:#000000; + font-weight:bold; +} + |