| 1 | patplex(1) |
| 2 | ========== |
| 3 | |
| 4 | NAME |
| 5 | ---- |
| 6 | patplex - Request pattern matcher for ashd(7) |
| 7 | |
| 8 | SYNOPSIS |
| 9 | -------- |
| 10 | *patplex* [*-hN*] 'CONFIGFILE' |
| 11 | |
| 12 | DESCRIPTION |
| 13 | ----------- |
| 14 | |
| 15 | The *patplex* handler matches requests against the rules specified in |
| 16 | 'CONFIGFILE', and dispatches them to the specified handlers |
| 17 | accordingly. See CONFIGURATION below for a description of how requests |
| 18 | are matched. |
| 19 | |
| 20 | *patplex* is a persistent handler, as defined in *ashd*(7). |
| 21 | |
| 22 | OPTIONS |
| 23 | ------- |
| 24 | |
| 25 | *-h*:: |
| 26 | |
| 27 | Print a brief help message to standard output and exit. |
| 28 | |
| 29 | *-N*:: |
| 30 | |
| 31 | Do not read the global configuration file `patplex.rc`. |
| 32 | |
| 33 | CONFIGURATION |
| 34 | ------------- |
| 35 | |
| 36 | In addition to the 'CONFIGFILE' specified on the command-line, |
| 37 | *patplex* also attempts to find and read a global configuration file |
| 38 | called `patplex.rc`, unless the *-N* option is given. It looks in all |
| 39 | directories named by the *PATH* environment variable, appended with |
| 40 | `../etc`. For example, then, if *PATH* is |
| 41 | `/usr/local/bin:/bin:/usr/bin`, the directories `/usr/local/etc`, |
| 42 | `/etc` and `/usr/etc` are searched for `patplex.rc`, in that |
| 43 | order. Only the first file found is used, should there exist several. |
| 44 | |
| 45 | Should the global and the given configuration files conflict, the |
| 46 | directives from the given file take precedence. |
| 47 | |
| 48 | The configuration files follow the same general format as for |
| 49 | *dirplex*(1), though the recognized stanzas differ. The *child*, |
| 50 | *fchild* and *include* stanzas are also shared with *dirplex*(1), so |
| 51 | see its manpage for a description thereof. |
| 52 | |
| 53 | *patplex* recognizes the *match* stanza, which takes no arguments, but |
| 54 | must contain at least one follow-up line to specify match rules. All |
| 55 | rules must match for the stanza as a whole to match. The following |
| 56 | rules are recognized: |
| 57 | |
| 58 | *point* 'REGEX' 'FLAGS':: |
| 59 | |
| 60 | 'REGEX' must be an extended regular expression. The rule is |
| 61 | considered to match if 'REGEX' matches the rest string of the |
| 62 | request. If 'FLAGS' contain the character `i`, 'REGEX' is |
| 63 | matched case-independently. If the *match* stanza as a whole |
| 64 | matches and contains no *restpat* line (as described below), |
| 65 | the rest string of the request is replaced by the remainder of |
| 66 | the rest string after the portion that was matched by 'REGEX'. |
| 67 | |
| 68 | *url* 'REGEX' 'FLAGS':: |
| 69 | |
| 70 | 'REGEX' must be an extended regular expression. The rule is |
| 71 | considered to match if 'REGEX' matches the raw URL of the |
| 72 | request. If 'FLAGS' contain the character `i`, 'REGEX' is |
| 73 | matched case-independently. |
| 74 | |
| 75 | *method* 'REGEX' 'FLAGS':: |
| 76 | |
| 77 | 'REGEX' must be an extended regular expression. The rule is |
| 78 | considered to match if 'REGEX' matches the HTTP method of the |
| 79 | request. If 'FLAGS' contain the character `i`, 'REGEX' is |
| 80 | matched case-independently. |
| 81 | |
| 82 | *header* 'HEADER' 'REGEX' 'FLAGS':: |
| 83 | |
| 84 | 'REGEX' must be an extended regular expression. The rule is |
| 85 | considered to match if 'REGEX' matches the named 'HEADER' in |
| 86 | the request. If the request does not contain the named |
| 87 | 'HEADER', the rule never matches. If 'FLAGS' contain the |
| 88 | character `i`, 'REGEX' is matched case-independently. |
| 89 | |
| 90 | *default*:: |
| 91 | |
| 92 | Matches if and only if no *match* stanza without a *default* |
| 93 | rule has matched. |
| 94 | |
| 95 | In addition to the rules, a *match* stanza must contain exactly one |
| 96 | follow-up line specifying the action to take if it mathces. Currently, |
| 97 | only the *handler* action is recognized: |
| 98 | |
| 99 | *handler* 'HANDLER':: |
| 100 | |
| 101 | 'HANDLER' must be a named handler as declared by a *child* or |
| 102 | *fchild* stanza, to which the request is passed. |
| 103 | |
| 104 | Additionally, a *match* stanza may contain a *restpat* line: |
| 105 | |
| 106 | *restpat* 'TEMPLATE':: |
| 107 | |
| 108 | If the *match* stanza as a whole matches, 'TEMPLATE' is |
| 109 | expanded and installed as the rest string of the request |
| 110 | before it is passed to the specified handler. In 'TEMPLATE', |
| 111 | the following parameters are recognized and expanded. |
| 112 | |
| 113 | *$0* ... *$9*:: |
| 114 | |
| 115 | Exactly one of the *point*, *url*, *method* or *header* rules |
| 116 | specified in the *match* stanza must have the `s` character |
| 117 | among its 'FLAGS'. *$0* is replaced by the whole text that was |
| 118 | matched by the rule's 'REGEX', and any of *$1* to *$9* is |
| 119 | replaced by the corresponding parenthesized subgroup of |
| 120 | 'REGEX'. |
| 121 | |
| 122 | *$_*:: |
| 123 | |
| 124 | Replaced by the entire rest string, as it was originally. |
| 125 | |
| 126 | *$$*:: |
| 127 | |
| 128 | Replaced by a single *$*. |
| 129 | |
| 130 | *${*'HEADER'*}*:: |
| 131 | |
| 132 | Replaced by the value of the named 'HEADER' in the request, or |
| 133 | the empty string if the request contained no such header. |
| 134 | |
| 135 | If no *match* stanza matches, a 404 response is returned to the |
| 136 | client. |
| 137 | |
| 138 | SIGNALS |
| 139 | ------- |
| 140 | |
| 141 | SIGHUP:: |
| 142 | |
| 143 | Reread the given configuration file (but not the global |
| 144 | file). If any named handlers, as specified by *child* stanzas, |
| 145 | are currently running and have stanzas with matching names in |
| 146 | the new file, they are left running for those stanzas (even if |
| 147 | the *exec* line has changed). |
| 148 | |
| 149 | EXAMPLES |
| 150 | -------- |
| 151 | |
| 152 | The following configuration file serves files from the `/srv/www` |
| 153 | directory by default, and in addition recognizes standard `/~user/` |
| 154 | URLs as user directories and calls the *userplex*(1) program to serve |
| 155 | them. |
| 156 | |
| 157 | -------- |
| 158 | child root |
| 159 | exec sudo -u www-data dirplex /srv/www |
| 160 | child userdir |
| 161 | exec userplex -g users |
| 162 | match |
| 163 | default |
| 164 | handler root |
| 165 | match |
| 166 | point ^~ |
| 167 | handler userdir |
| 168 | -------- |
| 169 | |
| 170 | The following rules can be used to implement virtual hosts. The actual |
| 171 | handlers are left out of the example. Note that the dots in the |
| 172 | regular expressions need to be escaped with double backslashes, since |
| 173 | the configuration file reader consumes one level of quoting. |
| 174 | |
| 175 | -------- |
| 176 | # Match one exact domain name only. |
| 177 | match |
| 178 | header host ^www\\.foo\\.net$ i |
| 179 | handler site-foo |
| 180 | # Match any sub-domain of bar.com. |
| 181 | match |
| 182 | header host (^|\\.)bar\\.com$ i |
| 183 | handler site-bar |
| 184 | # Use the last level of the domain name to enter a subdirectory. |
| 185 | match |
| 186 | header host ^([^.]*)\\.multi\\.org$ is |
| 187 | restpat $1/$_ |
| 188 | handler site-multi |
| 189 | -------- |
| 190 | |
| 191 | AUTHOR |
| 192 | ------ |
| 193 | Fredrik Tolf <fredrik@dolda2000.com> |
| 194 | |
| 195 | SEE ALSO |
| 196 | -------- |
| 197 | *dirplex*(1), *ashd*(7), *regex*(7) |