Future Work¶
This is future intended work and so may change radically. The essence should remain similar.
Session¶
inbound-local-addr
inbound-remote-port
inbound-local-port
Features¶
- ts-uuid
Process UUID for Traffic Server.
Feature Modifiers¶
The extracted feature can be post processed using options in the with
. This is done by
having a pair where the first element is the feature extraction, and the second is a map of options.
Currently the only planned modifier is “hash”.
- hash
“hash: <number>”
Hash the feature and reduce it to the range 1 .. :
number
. Something likewith: - "{creq.url}" - hash: 4096
This will get the client request URL, hash it, then (as evenly as possibl) reduce it to a number in the range 1 .. 4096.
- slice
Extract elements of a list. This takes two arguments, the left and right slice points. These are positions between elements of a list. Position 0 is before any element, and position -0 (represented by “*”) is past the last element. Other slice points count up from 0 (1, 2, 3, …) left to right and down from -0 ( -1, -2, -3, …) right to left.
Comparisons¶
Directives¶
- apply
“apply: [ <regex>, <string> ]”
Apply the regular expression :
regex
to :string
. This updates the extraction argument list such that capture groups in the regular expression can be extracted via numbered extractors. E.g. “{2}” is replaced by the second capture group. Groups that do not exist or were not part of the regular expression match yield the empty string.- call
“call: <plugin>”
“call: [ <plugin>, <args>, … ]”
Invoke a callback provided by a plugin.
Note
Implementation
Should the entry point be specifiable in the directive? That could be very nice.
Feature Tuples¶
Do_with a list feature, the matching is done across elements of the list. This can be done in an iterative style where a comparison is made against each element in the list, or tuple style where there is a different comparison for each element in the list.
The list style matching operators require a value that is another comparison.
for-all
The match succeeds if the base comparison succeeds for every element.
for-any
The match succeeds if the base comparison succeeds for any element.
for-none
The match succeeds if the base comparison fails for all elements.
The tuple style match is tuple
. It requires a list of comparisons and applies the
comparisons against the list in the same order. It matches if all of the comparisons match. Elements
that do not have a comparison do not match. This means by default if the feature list is a different
length that the comparison list, the match will fail. This is the common case. For less common cases
there are other options.
Tuple elements can be skipped with the whatever
comparison which accepts any feature type
and always matches.
Trailing elements can be matched with any of the list comparisons. This must always be the last comparison in a tuple and applies to all elements that do not have an explicit comparison.
These can be combined to ignore all elements past a fixed initial set by using a list comparison after the last significant comparison.
- for-all:
- otherwise:
This is useful if there are different comparisons in the same selection. Otherwise it might be
better to use modifiers to shape the list. E.g., if only the first two elements are relevant then
the slice
modifier can be used to reduce the list to the first two elements. Using
modifiers is faster and more compact but has the cost of limiting all of the comparisons in the
selection.
Matching can be done in a more explicitly iterative style by use of ...
and modifiers. This
can be used to process successively smaller subsequences of the list.
For examples of all this, consider working with the Via header. This is a multi-valued field. Suppose it was required to check for having been through the local instance of Traffic Server by looking for the process UUID in the fields. If the first element is the current instance, that’s a direct loop and an error. Otherwise, if the UUID is any other element that is an error unless the k8-routing field is present, indicating that there is active routing that sent it back.
Note
This is a real life example.
The design here is to split the Via header and then work with the list. The ts-uuid
extractor gets the UUID for the Traffic Server process which is used in the Via header.
with: [ creq-field@Via , { split: "," } ] # split in to list
select:
- tuple:
- contains: ts-uuid # only check first
- for-all:
- whatever:
do:
- txn-status: [ 400 , "Loop detected" ]
- tuple:
- whatever: # skip first element.
- for-any: # otherwise, see if it's any other element.
- contains: ts-uuid
do: # found it, fail if there's no routing flag.
- with: creq-field@k8-routing::present
select:
- eq: false
do:
txn-status: [ 400 , "Loop detected" ]
Issues
Matching on just the first value is annoyingly verbose. This would be noticeably better if there was an “apply” directive which loaded the
with
context, e.g. regular expression groups and...
without even trying to do matches.e43seDo_with support for
do
in each comparison, this may be of more limited utility. But that would be verbose to (for instance) do something for every tuple with a specific first element if there are multiple cases that match with that element.