STREAM_MATCHED¶
Description¶
Triggered when the stream profile matches some data-stream octets* to
a match value (regular expresssion) specified in the Stream Profile or
by an iRule using STREAM::expression.
(*See STREAM::encoding for details on how
data-stream octets are matched.)
This event may be used to examine the matched string (see
STREAM::match) and optionally use
STREAM::replace to specify a replacement
string or avoid replacing the matched data at all.
Examples¶
This example shows how you can use
STREAM::match in the
STREAM_MATCHED event to check if the matched
string meets some condition that can’t easily be checked for using a
regular expression in
STREAM::expression.
when HTTP_REQUEST {
# Disable the stream filter for all requests
STREAM::disable
}
when HTTP_RESPONSE {
# Check if response type is text
if {[HTTP::header value Content-Type] starts_with "text"} {
# Match an "http://imageserver-NNNN.example.com" URL (and replace
# it with nothing yet. We'll figure out the replacement later)
STREAM::expression {=http://imageserver-[0-9]{1,4}\.example\.com==}
# Enable the stream filter for this response only
STREAM::enable
}
}
when STREAM_MATCHED {
# Check if the matched string meets some condition that can't easily be checked
# for using a single regex in STREAM::expression. For example, regex's are not
# very good at arithmetic
# extract the imageserver number
regexp {http://imageserver-([0-9]+)[.]example[.]com} [STREAM::match] url server_nbr
# want to switch protocol to HTTPS only for newer imageservers, numbers over 379
if {$server_nbr > 379} {
set url [string replace $url 0 3 "https"]
}
# now put the URL back into the data stream (otherwise it will be deleted by the
# empty replacement value we set with STREAM::expression)
STREAM::replace $url
log local0.info "[IP::client_addr]_[TCP::local_port]: matched [STREAM::match], replaced with: ${url}"
}
Log output:
Rule stream_expression_rule <STREAM_MATCHED>: 10.0.0.1_3413: matched: http://imageserver-99.example.com, replaced with: http://imageserver-99.example.com
Rule stream_expression_rule <STREAM_MATCHED>: 10.0.0.1_3413: matched: http://imageserver-425.example.com, replaced with: https://imageserver-425.example.com
This example just reads the stream match in the STREAM_MATCHED event
and adds a persistence record.
# Look for a JSESSIONID cookie in response content and add a persistence record when it is found.
# To use STREAM commands a Stream Profile must be attached to the virtual server. Use /Common/stream.
when HTTP_RESPONSE {
# Clear the jsessionid if it exists already on this TCP connection
if {[info exists jsessionid]} {
unset jsessionid
}
# Only look for the jsessionid in text responses
if {[HTTP::header value "Content-Type"] starts_with "text"} {
log local0.info "[IP::client_addr]_[TCP::client_port]: text response, enabling stream profile"
# match the JSESSIONID string and value
# We'll parse out the value in STREAM_MATCHED
# Assume the jsessionid is 1 to 100 alphameric characters
STREAM::expression {/Set-Cookie: [^\s]+;JSESSIONID=[A-Za-z0-9]{1,100}//}
STREAM::enable
# Enable the STREAM_MATCHED event as it could have been disabled if there was a prior
# response on this TCP connection
event STREAM_MATCHED enable
} else {
# Disable the stream filter as this wasn't a text response
log local0. "[IP::client_addr]_[TCP::client_port]: No Content-Type match, disabling stream filter"
STREAM::disable
}
}
when STREAM_MATCHED {
# Save the matched value (example: ;JSESSIONID=a9bh35uy)
regexp {Set-Cookie: [^\s]+;JSESSIONID=([A-Za-z0-9]{1,100})} [STREAM::match] junk jsessionid
log local0.info "[IP::client_addr]_[TCP::client_port]: Found JSESSIONID=${jsessionid}"
# Prevent deletion of matched data which will occur if we don't do something (because
# the stream expression replacement value is empty)
# (STREAM::replace with no argument means don't replace anything, just leave it alone)
STREAM::replace
# Not sure why, but the parser doesn't allow the persist command in some TMOS versions
# It works though, so hide the command from the parser
set persist_cmd "persist add uie ${jsessionid}"
log local0.info "[IP::client_addr]_[TCP::client_port]: Will persist on JSESSIONID (command '${persist_cmd}')"
eval $persist_cmd
# Assume the first match is the same as any other jsessionids, so stop checking for them
log local0.info "[IP::client_addr]_[TCP::client_port]: Added persistence record. No longer scanning this response for JSESSIONID"
event STREAM_MATCHED disable
}
Log output:
Rule persist_on_response_content_stream_rule <HTTP_RESPONSE>: 1.2.3.4_2418: text response, enabling stream profile
Rule persist_on_response_content_stream_rule <STREAM_MATCHED>: 1.2.3.4_2418: Found JSESSIONID=a111111111111111111z
Rule persist_on_response_content_stream_rule <STREAM_MATCHED>: 1.2.3.4_2418: Will persist on JSESSIONID (command 'persist add uie a111111111111111111z')
Rule persist_on_response_content_stream_rule <STREAM_MATCHED>: 1.2.3.4_2418: Added persistence record. No longer scanning this response for JSESSIONID