Forum Discussion
Any way to use payload data in headers / cookies?
Never mind, answered my own question....
I have patterend data in the response of a web page that I need to capture and then modify ( I don't know the exact data, and it's unique per user session, I do know how to match the pattern), but also pass it to the client in a header / cookie for reuse on subsequent requests to the backend servers...
Example
href="./URIXXYYZZ/blah'
I need to capture /URIXXYYZZ/
Rewrite the content href='./GOODURI/blah'
Pass what was rewritten back to the client in a header or a cookie
HTTP::header insert ORIG_URL URIXXYYZZ
Then i'll check for the existence of the header for particular URI's and rewrite the request being sent to the backend server with the origional URI?
-------------------------------------------------------------------------------------------------------
In my case, there is only 1 issue of bad data, so the indicies can go away, and i'll only fix one thing.
But, there could be a case to have multiple headers / cookies to contain multiple fixed data elements from the page ( hope I don't have to do it )
------------------------------------------------------------------------------------
here is the ugly first hack at it - with barely any checks in palce
------------------------------------------------------------------------------------
when HTTP_REQUEST {
set scrub_content 1
set FIXEDURL ""
if { [HTTP::cookie exists "BIGIPFIXEDURL" ] } {
set FIXEDURL [HTTP::cookie "BIGIPFIXEDURL"]
if { [HTTP::uri] contains "THIS_IS_SCRUBBED_DATA" } {
set uri [HTTP::uri]
set find "THIS_IS_SCRUBBED_DATA"
set replace [HTTP::cookie "BIGIPFIXEDURL"]
set newuri [ regsub -all $find $uri $replace ]
HTTP::uri $newuri
}
}
}
when HTTP_RESPONSE {
if { $scrub_content } {
if { [HTTP::header exists "Content-Length"] } {
set content_length [HTTP::header "Content-Length"]
} else {
set content_length 4294967295
}
if { $content_length > 0 } {
HTTP::collect $content_length
}
set bad_data_indices [regexp -all -inline -indices {TestParamater=\d{7}} [HTTP::payload]]
foreach bad_dataidx $bad_data_indices {
set bad_datastart [lindex $bad_dataidx 0]
set bad_dataend [lindex $bad_dataidx 1]
set bad_datalen [expr {[lindex $bad_dataidx 1] - $bad_datastart + 1}]
set bad_datadata [string range [HTTP::payload] $bad_datastart $bad_dataend]
HTTP::cookie insert name BIGIPFIXEDURL value $bad_datadata
HTTP::payload replace $bad_datastart $bad_datalen "THIS_IS_SCRUBBED_DATA"
}
}
}
1 Reply
- Kevin_Stewart
Employee
This was indeed a challenge, and maybe the following isn't exactly what you're looking for, but here goes:
Here's how it works: 1. Issue a collect statement in the HTTP_RESPONSE event 2. In the HTTP_RESPONSE_DATA event perform a regexp command that builds a list of lists - a list of the start and end indexes for every "a href=..." string in the payload. 3. If the list isn't empty, start a loop 4. Use catch and scan commands to extract the first part of the URI from the anchor string (full and relative URLs). 5. Once found, create a new URL by string mapping the predefined GOODURI over the matched old URI. 6. Add the new and old URLs to a list (STREAMLIST). 7. After the loop, if the STREAMLIST list isn't empty, create a STREAM expression from the list (@old url@new url@ @old url@new url@ @old url@new url@...) and evaluate the expression to replace all of the old content in the payload. 8. During the loop, another list was created to store the matched URIs. After the STREAM expression, loop through this list to produce the values you need for cookies. This will create a different cookie for each matched URI (if more than one). A header won't be returned to the server, so a cookie is probably the better route. Not having enough information to know exactly how the application works, I had to assume that 1) there might be more than one offending URI in the payload, 2) you have a specific pattern that you're looking for, and 3) you'll need to devise a method to remap the incoming URI back to the original, which would be a bit more complicated if there was more than one replacement. It might actually make more sense to send the entire old URI in the cookie values, or perhaps even better to encode the original URI as a query string object at the end of each replaced URI. Example: a href="./GOODURI/blah/F5_URL=unnf89sdfnds98dsn32..."when RULE_INIT { User-defined: New URI value for replacement set static::GOODURI "GOODURI" User-defined: Old URI pattern to match (starts_with?) set static::URIPATTERN "uri" } when HTTP_RESPONSE { STREAM::disable if { [HTTP::header Content-Type] contains "text" } { HTTP::collect [HTTP::header Content-Length] } } when HTTP_RESPONSE_DATA { Find the HREF elements set indices [regexp -all -inline -indices -nocase { Full URL catch { if { [scan $url {<%*s %*[^:]://%*[^/]/%[^/]} URI] } { If scanned URI value matches the predefined pattern... if { [string tolower $URI] starts_with $static::URIPATTERN } { Create a new URL with the replaced value set new_url [string map "$URI $static::GOODURI" $url] Append the found/matched URI to the URILIST list lappend URILIST $URI Append the old and new URLs to the STREAMLIST list lappend STREAMLIST $url lappend STREAMLIST $new_url } } } } else { Relative URL catch { if { [scan $url {<%*s %*[^/]/%[^/]} URI] } { If scanned URI value matches the predefined pattern... if { [string tolower $URI] starts_with $static::URIPATTERN } { Create a new URL with the replaced value set new_url [string map "$URI $static::GOODURI" $url] Append the found/matched URI to the URILIST list lappend URILIST $URI Append the old and new URLs to the STREAMLIST list lappend STREAMLIST $url lappend STREAMLIST $new_url } } } } } If STREAMLIST is not empty (matched href values), generate a STREAM expression and replace the payload if { $STREAMLIST ne "" } { Create a STREAM expression from the STREAMLIST list set STREAMTEXT "" for { set i 0 } { $i < [llength $STREAMLIST] } { incr i } { if { [expr { $i %2 }] == 0 } { first string (old) append STREAMTEXT "@[lindex $STREAMLIST $i]" } else { second string (new) append STREAMTEXT "@[lindex $STREAMLIST $i]@" } } Evaluate the STREAM expression to replace all of the payload content STREAM::expression "$STREAMTEXT" STREAM::enable } We created a list of found/matched URIs. This can be used to send headers/cookies to the client for { set x 0 } { $x < [llength $URILIST] } { incr x } { HTTP::cookie insert name ORG_URL_${x} value [lindex $URILIST $x] } } }
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
