cancel
Showing results for 
Search instead for 
Did you mean: 

STREAM::max_matchsize - HELP - Urgent

agidwani_102403
Nimbostratus
Nimbostratus
All,

 

 

We are trying to do a URI rewrite and are running into some kind of buffer limitation with streams.

 

 

We get a error message when using the following streams directive

 

 

STREAMS::max_matchsize 8192

 

 

 

01070151:3: Rule [global_rewrite] error:

 

line 21: [command is not valid in current event context (HTTP_REQUEST)] [STREAM::max_matchsize 8192]

 

 

---------------------------------------------------------

 

 

 

when HTTP_REQUEST {

 

set uri [string tolower [HTTP::uri]]

 

if { ($uri contains "/global/") }

 

{ pool acecomm }

 

elseif { ($uri contains "/AC4AC/") or

 

($uri contains "/awchs54beta/")

 

}

 

{

 

if { $uri contains "/hscs.asmx" } {

 

pool acecomm

 

Change the URI of the request, preserving the query arguments, if any.

 

set args [findstr $uri "?"]

 

HTTP::uri "/global/hscs.asmx$args"

 

 

if {[HTTP::method] equals "POST"} {

 

Look for /*/hscs.asmx and replace * with "global"

 

(if you change "global" here you need to change the hard-coded length of 6 below)

 

Note that this does not fix the Content-Length so we need to do that below

 

STREAM::expression {@/[^/]*/[Hh][Ss][Cc][Ss].[Aa][Ss][Mm][Xx]@/global/hscs.asmx@}

 

STREAM::enable

 

 

Determine what the original path was

 

set origpath [findstr $uri "/" 1 "/"]

 

 

Store original content-length for POST data

 

set origlen [HTTP::header "Content-Length"]

 

 

Assume replacement string ("global") is 6 characters long, determine difference in

 

length between "global" and the replacement path

 

set length_change [expr {6 - [string length $origpath] } ]

 

set newlen [expr {$origlen + $length_change}]

 

 

Set new content length, assuming the stream profile performed exactly one replacement

 

HTTP::header remove "Content-Length"

 

HTTP::header insert "Content-Length" [expr {$origlen + $length_change}]

 

 

log local0. "origpath=$origpath, change=$length_change, origlen=$origlen"

 

log local0. "Content length after: [HTTP::header Content-length]"

 

 

}

 

}

 

}

 

}
9 REPLIES 9

hooleylist
Cirrostratus
Cirrostratus
Hi arvgidwani,

 

 

I'm not sure how relevant this is, but the STREAM::max_matchsize command only seems to be valid in the STREAM_MATCHED command (not in RULE_INIT, CLIENT_ACCEPTED or HTTP_REQUEST). According to the wiki, the STREAM_MATCHED event is triggered when the stream filter matches the expression against the a part of the payload. To be honest, I'm not sure why you'd want to set the buffer size after you've already made a match. It would seem logical to set the buffer size prior to the stream expression being evaluated.

 

 

What is the actual issue you're seeing prior to trying to use the max_matchsize command. Also, what version are you running?

 

 

Aaron

Lance_Simon_557
Historic F5 Account
Aaron,

 

 

Apparently the iRule works when the payload is less than 4096 bytes. This is why he wants to use the max_matchsize command to see what he can do to "buffer" more payload than 4096 to get this to work.

 

 

I don't think the stream will buffer the payload.

 

 

Lance

hooleylist
Cirrostratus
Cirrostratus
Hey Lance,

 

 

I'm not sure... Anyone know what the command does and/or a suggestion for the issue?

 

 

Aaron

spark_86682
Historic F5 Account
I'll look up later what that command does, but if you want to experiment with it, I think it should be callable (by a bizarre quirk of fate) in LB_SELECTED, which should be before any serverside data is returned.

agidwani_102403
Nimbostratus
Nimbostratus
One of the F5 expert was able to help write the script, We are running version 9.3.

 

 

Production iRule

 

when HTTP_REQUEST {

 

set uri [string tolower [HTTP::uri]]

 

if { ($uri contains "/global/") }

 

{ pool acecomm }

 

elseif { ($uri contains "/name1/") or

 

($uri contains "/name2/") or

 

($uri contains "/blah/")

 

}

 

{

 

if { $uri contains "/hscs.asmx" } {

 

pool acecomm

 

Change the URI of the request, preserving the query arguments, if any.

 

set args [findstr $uri "?"]

 

HTTP::uri "/global/hscs.asmx$args"

 

 

if {[HTTP::method] equals "POST"} {

 

Determine what the original path was

 

set origpath [findstr $uri "/" 1 "/"]

 

 

Determine the search regex (case-insensitive)

 

set search ""

 

set index 0

 

while {$index < [string length $origpath]} {

 

set char [string index $origpath $index]

 

set search "$search\[$char[string toupper $char]\]"

 

incr index

 

}

 

 

Look for /*/hscs.asmx and replace * with "global"

 

(if you change "global" here you need to change the hard-coded length of 6 below)

 

Note that this does not fix the Content-Length so we need to do that below

 

STREAM::expression "@/$search/\[Cc\]\[Oo\]\[Mm\]\[Pp\].\[Aa\]\[Ss\]\[Mm\]\[Xx\]@/global/hscs.asmx@"

 

STREAM::enable

 

 

Store original content-length for POST data

 

set origlen [HTTP::header "Content-Length"]

 

 

Assume replacement string ("global") is 6 characters long, determine difference in

 

length between "global" and the replacement path

 

set length_change [expr {6 - [string length $origpath] } ]

 

 

Set new content length, assuming the stream profile performed exactly one replacement

 

HTTP::header remove "Content-Length"

 

HTTP::header insert "Content-Length" [expr {$origlen + $length_change}]

 

 

log local0. "search path $search"

 

log local0. "origpath=$origpath, change=$length_change, origlen=$origlen"

 

log local0. "origpath=$origpath, Content len after: [HTTP::header Content-length]"

 

}

 

}

 

}

 

}

Nat_Thirasutta3
F5 Employee
F5 Employee
my 2 cents

 

 

to change the data part...may be we can use HTTP_REQUEST_DATA event + regsub command. performance of STREAM profile might be better but using HTTP_REQUEST_DATA, iRule might be easier

 

 

for example, (not tested)

 

when HTTP_REQUEST {

 

 

if {[HTTP::method] equals "POST"} {

 

set len [HTTP::header Content-Length]

 

HTTP::collect $len

 

}

 

}

 

when HTTP_REQUEST_DATA {

 

regsub -nocase {/$search/\[Cc\]\[Oo\]\[Mm\]\[Pp\].\[Aa\]\[Ss\]\[Mm\]\[Xx\]} [HTTP::payload] "/global/hscs.asmx" newpayload

 

HTTP::payload replace 0 $len $newpayload

 

}

 

 

BIG-IP should be able to handle content-length modification...

hooleylist
Cirrostratus
Cirrostratus
Hi Spark,

 

 

if you think of it, could you provide more detail on STREAM::max_matchsize?

 

 

Thanks,

 

Aaron

spark_86682
Historic F5 Account
Basically, the STREAM profile will buffer data for partial matches; if more than "max_matchsize" would be buffered, the connection will be torn down. This way a regex like "foobarba[^z]+" won't keep matching until the box runs out of memory. The default is 4K, and STREAM::max_matchsize can be use to set it to something else.

What_Lies_Bene1
Cirrostratus
Cirrostratus

FYI, I hit this issue recently. I'm not sure I fully understand what a partial match is but regardless, I doubled the value of the buffer, within the HTTP_RESPONSE event:

 

when HTTP_RESPONSE { STREAM::max_matchsize 8192 STREAM::enable ... }

Note, the actual response payload that was giving me issues was around 64kB. Considering the issue was intermittent, it's possible the buffer relates to all traffic handled by the Virtual Server, not each connection.

 

Using the STREAM::max_matchsize command in the STREAM_MATCHED event (as I'd seen suggested elsewhere) doesn't work.