Docs: updated header_rewrite plugin documentation
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/65f4e69c Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/65f4e69c Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/65f4e69c Branch: refs/heads/master Commit: 65f4e69c64916e8fd2a161ea4d9b8ec65db0d33f Parents: b30cc31 Author: Jon Sime <[email protected]> Authored: Tue Feb 16 00:51:29 2016 +0000 Committer: Jon Sime <[email protected]> Committed: Tue Feb 16 00:51:29 2016 +0000 ---------------------------------------------------------------------- doc/admin-guide/plugins/header_rewrite.en.rst | 1053 ++++++++++++++++---- 1 file changed, 866 insertions(+), 187 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/trafficserver/blob/65f4e69c/doc/admin-guide/plugins/header_rewrite.en.rst ---------------------------------------------------------------------- diff --git a/doc/admin-guide/plugins/header_rewrite.en.rst b/doc/admin-guide/plugins/header_rewrite.en.rst index 427b442..4e2f18e 100644 --- a/doc/admin-guide/plugins/header_rewrite.en.rst +++ b/doc/admin-guide/plugins/header_rewrite.en.rst @@ -1,246 +1,925 @@ -.. _header-rewrite-plugin: +.. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + +.. include:: ../../common.defs + +.. _admin-plugins-header-rewrite: Header Rewrite Plugin ********************* -.. Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at +This plugin allows you to modify arbitrary headers based on defined rules, for +both requests and responses. - http://www.apache.org/licenses/LICENSE-2.0 +Purpose +======= - Unless required by applicable law or agreed to in writing, - software distributed under the License is distributed on an - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - KIND, either express or implied. See the License for the - specific language governing permissions and limitations - under the License. +Remapping an incoming client request to an origin server is at the heart of +what we use |TS| for, but often we need to do more to requests than just change +their destination according to simple rewriting rules against the URL. +We may need to direct requests to different origins based on a client cookie. -This is a plugin for Apache Traffic Server that allows you to -modify various headers based on defined rules (operations) on a request or -response. +Our origins might return error response codes which are a little too customized +and we want to condense the possible values to just the official codes. -Using the plugin ----------------- +We might want to strip a set of internal-use or debugging related HTTP headers +from responses before sending them to clients, unless the original request had +its own special header indicating that they should be retained. + +Or perhaps we want to redirect certain requests differently when they come from +a known group of IP addresses (say, our developers' office network) and we have +a file on our proxy caching servers called ``/var/developertesting``. (Stranger +QA methods exist.) + +Maybe we want to deny access to a resource with an HTTP 403 if the client +connected to |TS| over a particular port, used ``HEAD`` instead of ``GET``, +doesn't list Spanish (Paraguay dialect) in their ``Accept-Language`` header, +and either the origin server replied with 304 or we randomly generate an +integer between 0 and 500 and get back anything greater than 290. + +These more complicated transformations of requests and responses (even that +last one) are made possible by this plugin. + +Installation +============ + +This plugin is considered stable and is included with |TS| by default. There +are no special steps necessary for its installation. + +Configuration +============= -This plugin can be used as both a global plugin, enabled in plugin.config:: +Header rewrite configurations, the actual conditions and operations that make +up the activity performed by the plugin, are specified in external files and +not in-line with the various mapping (and remapping) rules you may have +configured for your proxy. The location of this file is arbitrary, as long as +the |TS| processes have permissions to read it, though you may find it useful +to keep it in the same location as your other proxy configuration files. + +The paths given to the configuration file(s) may be absolute (leading with a +``/`` character), or they may be relative to the |TS| configuration directory. + +There are two methods for enabling this plugin, based on whether you wish it to +operate globally on every request that passes through your proxy, or only on +some subset of the requests by enabling it only for specific mapping rules. + +Enabling Globally +----------------- + +This plugin may be enabled globally, so that the conditions and header +rewriting rules are evaluated for every request made to your |TS| instance. +This is done by adding the following line to your :file:`plugin.config`:: header_rewrite.so config_file_1.conf config_file_2.conf ... -These are global rules, which would apply to all requests. Another option is -to use per remap rules in remap.config:: +You may specify multiple configuration files. Their rules will be evaluated in +the order the files are listed. + +Enabling Per-Mapping +-------------------- + +Alternatively, the plugin can be enabled for specific mapping rules, by +modifying the relevant entries in your :file:`remap.config`:: map http://a http://b @plugin=header_rewrite.so @pparam=rules1.conf ... -In the second example, hooks which are not to be executed during the remap -phase (the default) causes a transaction hook to be instantiated and used -at a later time. This allows you to setup e.g. a rule that gets executed -during the origin response header parsing, using READ_RESPONSE_HDR_HOOK. -Note that the remap mode of the plugin can only execute rules on hooks that -occur at remap phase or later (e.g. SEND_REQUEST_HDR_HOOK, READ_RESPONSE_HDR_HOOK etc), +As with the global method above, multiple configuration files may be listed, +each with its own ``@pparam=<file>`` and their contents will be evaluated in +the order the files were specified. + +Rewriting Rules +=============== + +Header rewriting rules consist of zero or more `Conditions`_ followed by one or +more `Operators`_. Conditions are used to limit the requests which will be +affected by the operator(s). Additionally, both conditions and operators may +have flags which modify their behavior. + +A complete rule, consisting of two conditions and a single operator might look +like the following:: + + cond %{STATUS} >399 [AND] + cond %{STATUS} <500 + set-status 404 + +Which converts any 4xx HTTP status code from the origin server to a 404. A +response from the origin with a status of 200 would be unaffected by this rule. + +Conditions +---------- + +Conditions are used as qualifiers, causing the associated operators to only be +evaluated if the condition(s) are met. Conditions all take the following form:: + + cond %{<condition name>[:<argument>]} <operand> [<flags>] + +Every condition begins with the literal string ``cond`` to indicate that this +line is a condition, not an operator. This is followed by the condition name, +inside curly braces and preceded by a percent sign (e.g. ``%{TRUE}`` for the +condition named ``TRUE``). Some condition names take an argument. Header +conditions, for example, take the name of the header in question, and cookie +conditions take the name of the cookie. For these, the condition name is +followed by a colon and the argument value (e.g. ``%{HEADER:User-Agent}`` for a +header condition against the ``User-Agent`` header). + +The operand of a condition provides a value, pattern, or range against which to +match. The format is described in `Condition Operands`_ below. + +Finally, a condition may optionally have various flags associated with it. +These are described in `Condition Flags`_ below. + +The following sections list all of the condition types currently supported. For +increased clarity in their usage, the optional ``[<flags>]`` portion of the +condition is omitted from all of the examples. + +ACCESS +~~~~~~ +:: + + cond %{ACCESS:<path>} + +Returns true if |TS| was able to successfully update the access time on the +file at ``<path>``. This condition will return false if the file does not exist +or |TS| cannot access it for any other reason. + +CLIENT-HEADER +~~~~~~~~~~~~~ +:: + + cond %{CLIENT-HEADER:<name>} <operand> + +Value of the header ``<name>`` from the original client request (regardless of +the hook context in which the rule is being evaluated). Note that some headers +may appear in an HTTP message more than once. In these cases, the value of the +header operated on by this condition will be a comma separated string of the +values from every occurrence of the header. More details are provided in +`Repeated Headers`_ below. + +CLIENT-IP +~~~~~~~~~ +:: + + cond %{CLIENT-IP} <operand> + +Remote IP address, as a string, of the client connection for the current +transaction. + +CLIENT-URL +~~~~~~~~~~ +:: + + cond %{CLIENT-URL:<part>} <operand> + +The URL of the original request. Regardless of the hook context in which the +rule is evaluated, this condition will always operate on the original, unmapped +URL supplied by the client. The ``<part>`` may be specified according to the +options documented in `URL Parts`_. + +COOKIE +~~~~~~ +:: + + cond %{COOKIE:<name>} <operand> + +Value of of the cookie ``<name>``. This does not expose or match against a +cookie's expiration, the domain(s) on which it is valid, whether it is protocol +restricted, or any of the other metadata; simply the current value of the +cookie as presented by the client. + +FROM-URL +~~~~~~~~ +:: + + cond %{FROM-URL:<part>} <operand> + +In a remapping context, this condition matches against the source URL from +which the remapping was generated. This condition is valid only within +configurations provided through :file:`remap.config` as described in `Enabling +Per-Mapping`_ above. + +The ``<part>`` allows the operand to match against just a component of the URL, +as documented in `URL Parts`_ below. + +HEADER +~~~~~~ +:: + + cond %{HEADER:<name>} <operand> + +Value of the header ``<name>`` from either the original client request or the +origin server's response, depending upon the hook context in which the rule is +being evaluated. Consult `Requests vs. Responses`_ for more information on how +to distinguish the two, as well as enforce that a rule is always evaluated in +the desired context. -Configuration filenames without an absolute path are searched for in the -default configuration directory. This is typically where your main -configuration files are, e.g. ``/usr/local/etc/trafficserver``. +Note that some headers may appear in an HTTP message more than once. In these +cases, the value of the header operated on by this condition will be a comma +separated string of the values from every occurrence of the header. Refer to +`Repeated Headers`_ for more information. + +If you wish to use a client request header, regardless of hook context, you may +consider using the `CLIENT-HEADER`_ condition instead. + +INCOMING-PORT +~~~~~~~~~~~~~ +:: + + cond %{INCOMING-PORT} <operand> + +TCP port, as a decimal integer, on which the incoming client connection was +made. + +INTERNAL-TRANSACTION +~~~~~~~~~~~~~~~~~~~~ +:: + + cond %{INTERNAL-TRANSACTION} + +Returns true if the current transaction was internally-generated by |TS| (using +:c:func:`TSHttpTxnIsInternal`). These transactions are not initiated by +external client requests, but are triggered (often by plugins) entirely within +the |TS| process. + +METHOD +~~~~~~~ +:: + + cond %{METHOD} <operand> + +The HTTP method (e.g. ``GET``, ``HEAD``, ``POST``, and so on) used by the +client for this transaction. + +PATH +~~~~ +:: + + cond %{PATH} <operand> + +The path component of the transaction. This includes the leading ``/`` that +immediately follows the hostname and terminates prior to the ``?`` signifying +the beginning of query parameters (or the end of the URL, whichever occurs +first). + +Refer to `Requests vs. Responses`_ for more information on determining the +context in which the transaction's URL is evaluated. + +QUERY +~~~~~ +:: + + cond %{QUERY} <operand> + +The query parameters, if any, of the transaction. Refer to `Requests vs. +Responses`_ for more information on determining the context in which the +transaction's URL is evaluated. + +RANDOM +~~~~~~ +:: + + cond %{RANDOM:<n>} <operand> + +Generates a random integer between ``0`` and ``<n>``, inclusive. + +STATUS +~~~~~~ +:: + + cond %{STATUS} <operand> + +Numeric HTTP status code of the response. + +TO-URL +~~~~~~ +:: + + cond %{TO-URL:<part>} <operand> + +In a remapping context, this condition matches against the target URL to which +the remapping is directed. This condition is valid only within configurations +provided through :file:`remap.config` as described in `Enabling Per-Mapping`_ +above. + +The ``<part>`` allows the operand to match against just a component of the URL, +as documented in `URL Parts`_ below. + +TRUE / FALSE +~~~~~~~~~~~~ +:: + + cond %{TRUE} + cond %{FALSE} + +These conditions always return a true value and a false value, respectively. +The true condition is implicit in any rules which specify no conditions (only +operators). + +TXN-COUNT +~~~~~~~~~ +:: + + cond %{TXN-COUNT} <operand> + +Returns the current HTTP client session, which permits detection of requests +which are sharing a client session. Shared client sessions occur when multiple +simultaneous requests are received for the same cache object. Instead of +contacting the origin server separately for each of those client requests, one +origin connection is used to fulfill all of the requests assigned to the shared +client session. + +URL +~~~ +:: + + cond %{URL:option} <operand> + +The complete URL of the current transaction. This will automatically choose the +most relevant URL depending upon the hook context in which the condition is +being evaluated. + +Refer to `Requests vs. Responses`_ for more information on determining the +context in which the transaction's URL is evaluated. + +Condition Operands +------------------ + +Operands provide the means to restrict the values, provided by a condition, +which will lead to that condition evaluating as true. There are currently four +types supported: + +=========== =================================================================== +Operand Description +=========== =================================================================== +/regex/ Matches the condition's provided value against the regular + expression. +<string Matches if the value from the condition is lexically less than + *string*. +>string Matches if the value from the condition is lexically greater than + *string*. +=string Matches if the value from the condition is lexically equal to + *string*. +=========== =================================================================== + +The absence of an operand for conditions which accept them simply requires that +a value exists (e.g. the content of the header is not an empty string) for the +condition to be considered true. + +Condition Flags +--------------- + +The condition flags are optional, and you can combine more than one into +a comma-separated list of flags. Note that whitespaces are not allowed inside +the brackets: + +====== ======================================================================== +Flag Description +====== ======================================================================== +AND Indicates that both the current condition and the next must be true. + This is the default behavior for all conditions when no flags are + provided. +NC Indicates that the condition operand should be matched case-insensitive. + **Not implemented.** +NOT Inverts the condition. +OR Indicates that either the current condition or the next one must be + true, as contrasted with the default behavior from ``[AND]``. +====== ======================================================================== Operators --------- -The following operators are available:: +Operators are the part of your header rewriting rules which actually modify the +header content of your requests and responses. They are always the final part +of a rule, following any of the conditions which whittled down the requests and +responses to which they will be applied. - rm-header header-name [operator_flags] - add-header header <value> [operator_flags] - set-header header <value> [operator_flags] - set-status <status-code> [operator_flags] - set-destination [qual] <value> [operator_flags] - set-redirect <status-code> <destination> [operator_flags] - set-timeout-out <value> [operator_flags] - set-status-reason <value> [operator_flags] - set-config overridable-config <value> [operator_flags] - set-conn-dscp <value> [operator_flags] - skip-remap <value> [operator_flags] - set-debug [operator_flags] - counter counter-name [operator_flags] - no-op [operator_flags] +Multiple operators may be specified for a single rule, and they will be +executed in the order listed. The end of the rule is marked either by the end +of the configuration file or the next appearance of a condition (whichever +occurs first). +The following operators are available: -Where qual is one of the support URL qualifiers:: +add-header +~~~~~~~~~~ +:: - HOST - PORT - PATH - QUERY - SCHEME - URL + add-header <name> <value> -For example (as a remap rule):: +Adds a new ``<name>`` header line with the contents ``<value>``. Note that this +operator can produce duplicate headers if one of ``<name>`` already exists, or +your configuration supplies multiple instances of this operator in different +rules which are all invoked. This is not an issue for headers which may safely +be specified multiple times, such as ``Set-Cookie``, but for headers which may +only be specified once you may prefer to use `set-header`_ instead. - cond %{HEADER:X-Mobile} = "foo" - set-destination HOST foo.mobile.bar.com [L] +The header's ``<value>`` may be specified as a literal string, or it may take +advantage of `Variable Expansion`_ to calculate a dynamic value for the header. +In contrast, `set-header`_ does not support variable expansion for the header +value. If you wish to use variable expansion and avoid duplicate headers, you +may consider using an `rm-header`_ operator followed by `add-header`_. + +counter +~~~~~~~ +:: + + counter <name> -Operator flags +Increments an integer counter called ``<name>`` every time the rule is invoked. +The counter is initialized at ``0`` if it does not already exist. The name you +give your counter is arbitrary, though it is strongly advisable to avoid +conflicts with existing |TS| statistics. + +This counter can be viewed at any time through the standard statistics APIs, +including the :ref:`Stats Over HTTP plugin <admin-plugins-stats-over-http>`. + +Counters can only increment by 1 each time this operator is invoked. There is +no facility to increment by other amounts, nor is it possible to initialize the +counter with any value other than ``0``. Additionally, the counter will reset +whenever |TS| is restarted. + +no-op +~~~~~ +:: + + no-op + +This operator does nothing, takes no arguments, and has no side effects. + +rm-header +~~~~~~~~~ +:: + + rm-header <name> + +Removes the header ``<name>``. + +set-config +~~~~~~~~~~ +:: + + set-config <name> <value> + +Allows you to override the value of a |TS| configuration variable for the +current connection. The variables specified by ``<name>`` must be overridable. +For details on available |TS| configuration variables, consult the +documentation for :file:`records.config`. You can read more about overridable +configuration variables in the developer's documentation for +:ref:`ts-overridable-config`. + +set-conn-dscp +~~~~~~~~~~~~~ +:: + + set-conn-dscp <value> + +When invoked, sets the client side `DSCP +<https://en.wikipedia.org/wiki/Differentiated_services>`_ value for the current +transaction. The ``<value>`` should be specified as a decimal integer. + +set-debug +~~~~~~~~~ +:: + + set-debug + +When invoked, this operator enables the internal transaction debugging flag +(via :c:func:`TSHttpTxnDebugSet`), which causes debug messages to be printed to +the appropriate logs even when the debug tag has not been enabled. For +additional information on |TS| debugging statements, refer to +:ref:`developer-debug-tags` in the developer's documentation. + +set-destination +~~~~~~~~~~~~~~~ +:: + + set-destination <part> <value> + +Modifies individual components of the remapped destination's address. When +changing the remapped destination, ``<part>`` should be used to indicate the +component that is being modified (see `URL Parts`_), and ``<value>`` will be +used as its replacement. You must supply a non-zero length value, otherwise +this operator will be an effective no-op (though a warning will be emitted to +the logs if debugging is enabled). + +set-header +~~~~~~~~~~ +:: + + set-header <name> <value> + +Replaces the value of header ``<name>`` with ``<value>``, creating the header +if necessary. + +Note that, unlike `add-header`_, this operator does not currently support +variable expansion. Values may only be specified according to `Header Values`_. + +set-redirect +~~~~~~~~~~~~ +:: + + set-redirect <code> <destination> + +When invoked, sends a redirect response to the client, with HTTP status +``<code>``, and a new location of ``<destination>``. If the ``QSA`` flag is +enabled, the original query string will be preserved and added to the new +location automatically. This operator supports `Variable Expansion`_ for +``<destination>``. + +set-status +~~~~~~~~~~ +:: + + set-status <code> + +Modifies the :ref:`HTTP status code <appendix-http-status-codes>` used for the +response. ``<code>`` must be a valid status code. This operator will also +update the reason in the HTTP response, based on the code you have chosen. If +you wish to override that with your own text, you will need to invoke the +`set-status-reason`_ operator after this one. + +set-status-reason +~~~~~~~~~~~~~~~~~ +:: + + set-status-reason <reason> + +Modifies the HTTP response to use ``<reason>`` as the HTTP status reason, +instead of the standard string (which depends on the :ref:`HTTP status code +<appendix-http-status-codes>` used). + +set-timeout-out +~~~~~~~~~~~~~~~ +:: + + set-timeout-out <type> <value> + +Modifies the timeout values for the current transaction to ``<value>`` +(specified in milliseconds). The ``<type>`` must be one of the following: +``active``, ``inactive``, ``connect``, or ``dns``. + +skip-remap +~~~~~~~~~~ +:: + + skip-remap <value> + +When invoked, and when ``<value>`` is any of ``1``, ``true``, or ``TRUE``, this +operator causes |TS| to abort further request remapping. Any other value and +the operator will effectively be a no-op. + +Operator Flags -------------- -The operator flags are optional, and must not contain whitespaces inside -the brackets. Two flags are available: +Operator flags are optional, are separated by commas when using more than one +for a single operator, and must not contain whitespace inside the brackets. For +example, an operator with the ``L`` flag would be written in this manner:: + + set-destination HOST foo.bar.com [L] - [L] Last rule, do not continue - [QSA] Append query string +The flags currently supported are: -Variable expansion +====== ======================================================================== +Flag Description +====== ======================================================================== +L Last rule, do not continue. +QSA Append the results of the rule to the query string. +====== ======================================================================== + +Variable Expansion ------------------ -Only limited variable expansion is supported in add-header. Supported -substitutions include:: - %<proto> Protocol - %<port> Port - %<chi> Client IP - %<cqhl> Client request length - %<cqhm> Client HTTP method - %<cquup> Client unmapped URI +Only limited variable expansion is supported in `add-header`_. Supported +substitutions are currently: -Conditions ----------- -The conditions are used as qualifiers: The operators specified will -only be evaluated if the condition(s) are met:: - - cond %{STATUS} operand [condition_flags] - cond %{RANDOM:nn} operand [condition_flags] - cond %{ACCESS:file} [condition_flags] - cond %{TRUE} [condition_flags] - cond %{FALSE} [condition_flags] - cond %{HEADER:header-name} operand [condition_flags] - cond %{COOKIE:cookie-name} operand [condition_flags] - cond %{CLIENT-HEADER:header-name} operand [condition_flags] - cond %{PATH} operand [condition_flags] - cond %{QUERY} operand [condition_flags] - cond %{INTERNAL-TRANSACTION} [condition_flags] - cond %{CLIENT-IP} operand [condition_flags] - cond %{INCOMING-PORT} operand [condition_flags] - cond %{METHOD} operand [condition_flags] - cond %{CLIENT-URL:option-name} operand [condition_flags] - cond %{URL:option-name} operand [condition_flags] - cond %{FROM-URL:option-name} operand [condition_flags] - cond %{TO-URL:option-name} operand [condition_flags] - cond %{TXN-COUNT} operand [condition_flags] - -The difference between HEADER and CLIENT-HEADER is that HEADER adapts to the -hook it's running in, whereas CLIENT-HEADER always applies to the client -request header. The %{TRUE} condition is also the default condition if no -other conditions are specified. - -These conditions have to be first in a ruleset, and you can only have one in -each rule. This implies that a new hook condition starts a new rule as well.:: - - cond %{READ_RESPONSE_HDR_HOOK} (this is the default hook for global rules) - cond %{READ_REQUEST_HDR_HOOK} - cond %{READ_REQUEST_PRE_REMAP_HOOK} - cond %{SEND_REQUEST_HDR_HOOK} - cond %{SEND_RESPONSE_HDR_HOOK} - -For remap.config plugin instanations, the default hook is named -REMAP_PSEUDO_HOOK. This can be useful if you are mixing other hooks in a -configuration, but being the default it is also optional. This hook is -executed directly as part of the remapping phase. - -Note that for configurations that are global, i.e. setup via -``plugin.config``, the default hook is READ_RESPONSE_HDR_HOOK. - -CLIENT-URL, URL, URL-FROM, and URL-TO -------------------------------------- -URL adapts to the hook it's running in and CLIENT-URL will always give you -the client URL. FROM-URL and TO-URL are from the remap rule that matched and -can only be used if the plugin is a being run as a remap plugin. An option -is required to match that section of the URL. - -Supported Option Names: - HOST - -Example: - cond %{URL:HOST} =www.example.com +============ ================================================================== +Variable Description +============ ================================================================== +%<proto> Protocol +%<port> Port +%<chi> Client IP +%<cqhl> Client request length +%<cqhm> Client HTTP method +%<cquup> Client unmapped URI +============ ================================================================== ---------------- -Condition flags +Header Values +------------- + +Setting a header with a value can take the following formats: + +- Any `condition <Conditions>`_ which extracts a value from the request. + +- ``$N``, where 0 <= N <= 9, from matching groups in a regular expression. + +- A string (which can contain the numbered matches from a regular expression as + described above). + +- Null. + +Supplying no value for a header for certain operators can lead to an effective +no-op. In particular, `add-header`_ and `set-header`_ will simply short-circuit +if no value has been supplied for the named header. + +URL Parts +--------- + +Some of the conditions and operators which use a request or response URL as +their target allow for matching against specific components of the URL. For +example, the `CLIENT-URL`_ condition can be used to test just against the query +parameters by writing it as:: + + cond %{CLIENT-URL:QUERY} <operand> + +The URL part names which may be used for these conditions and actions are: + +======== ====================================================================== +Part Description +======== ====================================================================== +HOST Full hostname. +PATH URL substring beginning with the first ``/`` after the hostname up to, + but not including, the query string. +PORT Port number. +QUERY URL substring from the ``?``, signifying the beginning of the query + parameters, until the end of the URL. Empty string if there were no + quuery parameters. +SCHEME URL scheme in use (e.g. ``http`` and ``https``). +URL The complete URL. +======== ====================================================================== + +As another example, a remap rule might use the `set-destination`_ operator to +change just the hostname via:: + + cond %{HEADER:X-Mobile} = "foo" + set-destination HOST foo.mobile.bar.com [L] + +Requests vs. Responses +====================== + +Both HTTP requests and responses have headers, a good number of them with the +same names. When writing a rule against, for example, the ``Connection`` or +``Via`` headers which are both valid in a request and a response, how can you +tell which is which, and how do you indicate to |TS| that the condition is +specifically and exclusively for a request header or just for a response +header? And how do you ensure that a header rewrite occurs against a request +before it is proxied? + +Hook Conditions --------------- -The condition flags are optional, and you can combine more than one into -a comma-separated list of flags. Note that whitespaces are not allowed inside -the brackets:: +In addition to the conditions already described above, there are a set of +special hook conditions. Only one of these conditions may be specified per +ruleset, and they must be the first condition listed. Which hook condition is +used determines the context in which the ruleset is evaluated, and whether the +other conditions will default to operating on the client request headers or the +origin response (or cache response) headers. - [NC] Not case sensitive condition (when applicable) [NOT IMPLEMENTED!] - [AND] AND with next condition (default) - [OR] OR with next condition - [NOT] Invert this condition +Hook conditions are written just like the other conditions, except that none of +them take any operands:: -Operands to conditions ----------------------- -:: + cond %{<name>} + +Because hook conditions must be the first condition in a ruleset, the use of +one forces the beginning of a new ruleset. + +READ_RESPONSE_HDR_HOOK +~~~~~~~~~~~~~~~~~~~~~~ + +Rulesets evaluated within this context will process only once the origin server +response (or cached response) has been read, but prior to |TS| sending that +response to the client. + +This is the default hook condition for all globally-configured rulesets. + +READ_REQUEST_HDR_HOOK +~~~~~~~~~~~~~~~~~~~~~ + +Evaluates as soon as the client request has been read, but prior to any further +processing (including contacting origin servers or fetching objects from cache). +Conditions and operators which adapt to matching or manipulating request or +response entities (e.g. headers) depending on their context will all operate on +the request variants when using this hook, as there is no response data yet. + +READ_REQUEST_PRE_REMAP_HOOK +~~~~~~~~~~~~~~~~~~~~~~~~~~~ - /string/ # regular expression - <string # lexically lower - >string # lexically greater - =string # lexically equal +For ruleset configurations provided via :file:`remap.config`, this forces their +evaluation as soon as the request has been read, but prior to the remapping. +For all context-adapting conditions and operators, matching will occur against +the request, as there is no response data available yet. + +REMAP_PSEUDO_HOOK +~~~~~~~~~~~~~~~~~ + +This is the default hook condition for all rulesets configured via remapping +rules in :file:`remap.config`. Functionally equivalent to +`READ_RESPONSE_HDR_HOOK`_ in that rulesets will evaluate after responses from +origin servers have been received (or the object has been retrieved from +cache), but prior to sending the client response. + +What sets this hook context apart is that in configuration files shared by both +the global :file:`plugin.config` and individual remapping entries in +:file:`remap.config`, this hook condition will force the subsequent ruleset(s) +to be valid only for remapped transactions. + +SEND_REQUEST_HDR_HOOK +~~~~~~~~~~~~~~~~~~~~~ + +Forces evaluation of the ruleset just prior to contacting origin servers (or +fetching the object from cache), but after any remapping may have occurred. + +SEND_RESPONSE_HDR_HOOK +~~~~~~~~~~~~~~~~~~~~~~ + +Evaluates rulesets just prior to sending the client response, but after any +cache updates may have been performed. This hook context provides a means to +modify aspects of the response sent to a client, while still caching the +original versions of those attributes delivered by the origin server. + +Affected Conditions +------------------- + +The following conditions are affected by the hook context in which they are +evaluated and will adjust using request or response entities automatically: + +- `HEADER`_ + +- `METHOD`_ + +- `PATH`_ + +- `QUERY`_ + +- `URL`_ + +Affected Operators +------------------ -The absence of a "matcher" means value exists. +The following operators are affected by the hook context in which they are +evaluated and will adjust modifying request or response entities automatically: -Values ------- -Setting e.g. a header with a value can take the following formats: +- `add-header`_ -- Any of the cond definitions, that extracts a value from the request -- $N 0 <= N <= 9, as grouped in a regular expression -- string (which can contain the above) -- null +- `rm-header`_ + +- `set-header`_ + +Caveats +======= + +Repeated Headers +---------------- + +Some headers may appear more than once in a request or a response. When this +occurs, all values will be collapsed into a single comma-delimited string +before the conditions see them. This avoids the problem of determining which +header instance out of several a condition's rule will be applied to, but it +may introduce unexpected behavior in your operands. + +For example, let us assume an origin response includes a header named ``X-Foo`` +which specifies a keyword of some sort. This header may appear zero or more +times and we wish to construct a `HEADER`_ condition that can handle this. + +Condition A +~~~~~~~~~~~ + +This condition will match using a direct equality operand:: + + cond %{HEADER:X-Foo} =bar + +Condition B +~~~~~~~~~~~ + +This condition will match using an unanchored regular expression:: + + cond %{HEADER:X-Foo} /bar/ + +Sample Headers +~~~~~~~~~~~~~~ + +Both conditions A and B will match this response:: + + HTTP/1.1 200 OK + Date: Mon, 08 Feb 2016 18:11:30 GMT + Content-Length: 1234 + Content-Type: text/html + X-Foo: bar + +Only condition B will match this response:: + + HTTP/1.1 200 OK + Date: Mon, 08 Feb 2016 18:11:30 GMT + Content-Length: 1234 + Content-Type: text/html + X-Foo: bar + X-Foo: baz + +That is because the `HEADER`_ condition will see the value of ``X-Foo`` as +``bar,baz``. Condition B will still match this because the regular expression, +being unanchored, finds the substring ``bar``. But condition A fails, as it is +expecting the value to be the exact string ``bar``, nothing more and nothing +less. Examples --------- -:: +======== + +Remove Origin Authentication Headers +------------------------------------ + +The following ruleset removes any authentication headers from the origin +response before caching it or returning it to the client. This is accomplished +by setting the hook context and then removing the cookie and basic +authentication headers.:: + + cond %{READ_RESPONSE_HDR_HOOK} + rm-header Set-Cookie + rm-header WWW-Authenticate + +Count Teapots +------------- + +Maintains a counter statistic, which is incremented every time an origin server +has decided to be funny by returning HTTP 418:: + + cond %{STATUS} =418 + counter plugin.header_rewrite.teapots + +Normalize Statuses +------------------ + +For client-facing purposes only (because we set the hook context to just prior +to delivering the response back to the client, but after all processing and +possible cache updates have occurred), replaces all 4xx HTTP status codes from +the origin server with ``404``:: + + cond %{SEND_RESPONSE_HDR_HOOK} + cond %{STATUS} >399 + cond %{STATUS} <500 + set-status 404 + +Remove Cache Control to Origins +------------------------------- + +Removes cache control related headers from requests before sending them to an +origin server:: + + cond %{SEND_REQUEST_HDR_HOOK} + rm-header Cache-Control + rm-header Pragma - cond %{HEADER:X-Y-Foobar} - cond %{COOKIE:X-DC} =DC1 - add-header X-Y-Fiefum %{HEADER:X-Y-Foobar} - add-header X-Forwarded-For %<chi> - rm-header X-Y-Foobar - rm-header Set-Cookie - counter plugin.header_rewrite.x-y-foobar-dc1 - cond %{HEADER:X-Y-Foobar} "Some string" [AND,NC] +Enable Debugging Per-Request +---------------------------- +Turns on |TS| debugging statements for a transaction, but only when a special +header is present in the client request:: -.. note:: Notes about header conditionals + cond %{READ_REQUEST_HDR_HOOK} + cond %{CLIENT-HEADER:X-Debug} =supersekret + set-debug - In HTTP multiple headers can be consolidated into a single comma separated string. - To avoid complex markup within header-rewrite all header conditionals are - evaluated against all values of the header normalized into a single comma separated string. - Some examples: +Remove Internal Headers +----------------------- - Conditions:: +Removes special internal/development headers from origin responses, unless the +client request included a special debug header:: - # rule 1 - cond %{HEADER:foo} /bar/ + cond %{CLIENT-HEADER:X-Debug} =keep [NOT] + rm-header X-Debug-Foo + rm-header X-Debug-Bar - # rule 2 - cond %{HEADER:foo} =bar +Return Original Method in Response Header +----------------------------------------- - Examples:: +This rule copies the original HTTP method that was used by the client into a +custom response header:: - # matches 1 and 2 - foo: bar + cond %{SEND_RESPONSE_HDR_HOOK} + set-header X-Original-Method %{METHOD} - # matches 1 - foo: bar - foo: baz +Useless Example From Purpose +---------------------------- - # matches 1 - foo: baz - foo: bar +Even that useless example from `Purpose`_ in the beginning of this document is +possible to accomplish:: - # matches 1 - foo: bar,baz + cond %{INCOMING-PORT} =8090 + cond %{METHOD} =HEAD + cond %{CLIENT-HEADER:Accept-Language} /es-py/ [NOT] + cond %{STATUS} =304 [OR] + cond %{RANDOM:500} >290 + set-status 403 - # matches 1 - foo: baz,bar
