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.


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.
  # Disable the stream filter for all requests

  # Check if response type is text
  if {[HTTP::header value Content-Type] starts_with "text"} {

    # Match an "" 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

  # 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 "[IP::client_addr]_[TCP::local_port]: matched [STREAM::match], replaced with: ${url}"

Log output:
Rule stream_expression_rule <STREAM_MATCHED>: matched:, replaced with:
Rule stream_expression_rule <STREAM_MATCHED>: matched:, replaced with:

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.

  # 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 "[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}//}

    # 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"

  # Save the matched value (example: ;JSESSIONID=a9bh35uy)
  regexp {Set-Cookie: [^\s]+;JSESSIONID=([A-Za-z0-9]{1,100})} [STREAM::match] junk jsessionid
  log "[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)

  # 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 "[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 "[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>: text response, enabling stream profile
Rule persist_on_response_content_stream_rule <STREAM_MATCHED>: Found JSESSIONID=a111111111111111111z
Rule persist_on_response_content_stream_rule <STREAM_MATCHED>: Will persist on JSESSIONID (command 'persist add uie a111111111111111111z')
Rule persist_on_response_content_stream_rule <STREAM_MATCHED>: Added persistence record. No longer scanning this response for JSESSIONID