iRule [string range...] not chunking data properly
I have an irule (much of which I found here) that is to gather some much needed troubleshooting data I need in regards to the headers and payload I have coming in. The payload is obvisouly too large for a single log line so this was supposed to chunk it into manageable bytes. I had to make some modifications to the original irule which did not work, but now it is working, sort of. It logs the first 900 bytes as it should, then something happens and skips a bunch, and then logs the final bytes of data. I can't understand why it's not grabbing either the proper amount of data or failing to output this second chunk of missing data before making its final loop. iRule is here: when RULE_INIT { # Log debug to /var/log/ltm? 1=yes, 0=no set static::payload_dbg 1 # Limit payload collection to 5Mb set static::max_collect_len 5368709 # Max characters to log locally (must be less than 1024 bytes) # https://clouddocs.f5.com/api/irules/log.html set static::max_chars 900 set static::min_chars 0 } when HTTP_REQUEST { # Only collect POST request payloads if {[HTTP::method] equals "POST"}{ if {$static::payload_dbg}{log local0. "POST request"} # Get the content length so we can request the data to be processed in the HTTP_REQUEST_DATA event. if {[HTTP::header exists "Content-Length"]}{ set content_length [HTTP::header "Content-Length"] } else { set content_length 0 } # content_length of 0 indicates chunked data (of unknown size) if {$content_length > 0 && $content_length < $static::max_collect_len}{ set collect_length $content_length } else { set collect_length $static::max_collect_len } if {$static::payload_dbg}{log local0. "Content-Length: $content_length, Collect length: $collect_length"} foreach aHeader [HTTP::header names] { log local0. "HTTP Request Headers: $aHeader: [HTTP::header value $aHeader]" } #set payload [HTTP::collect $collect_length] HTTP::collect $collect_length } } when HTTP_REQUEST_DATA { # Log the bytes collected if {$static::payload_dbg}{log local0. "Collected [HTTP::payload length] bytes"} # Log the payload locally if {[HTTP::payload length] < $static::max_chars}{ log local0. "Payload=[HTTP::payload]" } else { # Initialize variables set remaining [HTTP::payload] set position 0 set count 1 set bytes_logged 0 # Loop through and log each chunk of the payload while {[string length $remaining] > $static::min_chars}{ #chunk = 899 set chunk [expr {$position + $static::max_chars -1}] log local0. "Chunk: $chunk" log local0. "Position start: $position" # Get the current chunk to log (subtract 1 from the end as string range is 0 indexed) set current [string range $remaining $position $chunk] log local0. "chunk $count=$current" log local0. "Current chunks bytes: [string length $current]" # Add the length of the current chunk to the position for the next chunk incr position [string length $current] # Get the next chunk to log set remaining [string range $remaining $position end] incr count incr bytes_logged $position log local0. "remaining bytes=[string length $remaining], \$position=$position, \$count=$count, \$bytes_logged=$bytes_logged" } if {[string length $remaining]}{ log local0. "chunk $count=$current" incr bytes_logged [string length $remaining] } log local0. "Logged $count chunks for a total of $bytes_logged bytes" } } when HTTP_RESPONSE { foreach aHeader [HTTP::header names] { log local0. "HTTP Request Headers: $aHeader: [HTTP::header value $aHeader]" } } The image below shows what I'm talking about - it even says "Oh I found 3 chunks", but I'm only being presented 2. I added some logging around the position, chunk value (aka end position), and bytes logged to help illustrate that it's clearly skipping over something. Any help would be appreciated! ThanksSolved2.2KViews0likes6Comments