CodeShare
Have some code. Share some code.
cancel
Showing results for 
Search instead for 
Did you mean: 
Custom Alert Banner
Jason_Adams
F5 Employee
F5 Employee

Problem this snippet solves:

This iRule was written with the goal to persist on only the last jsessionid that is present when multiple jsessionid HTTP Paremeters are present..

How to use this snippet:

I ran into a particular challenge where a customer was receiving a request where a jsessionid was expected to be set in an HTTP Request Parameter.
  • For those of you who are not familiar, see where the parameters lye below:

    <scheme>://<username>:<password>@<host>:<port>/<path>;<parameters>?<query>#<fragment>
    

REF: http://www.skorks.com/2010/05/what-every-developer-should-know-about-urls/

Here is an example of a full request:
http://www.example.com/my/resource.html;jsessionid=0123456789abcdef;jsessionid=0123456789abcdef?alice=mouse
In the above example, there are two jsessionid parameters, both of which are the same value.
This is what was being used to Persist
"*jsessionid*" {
   #Parse the URI and look for jsessionid. Skip 11 characters and match up to the next "?"
   set session_id [findstr [HTTP::uri] jsessionid 11 "?"]
}

Code :

when CLIENT_ACCEPTED {
set debug 1
}
when HTTP_REQUEST {
set logTuple "[IP::client_addr]:[TCP::client_port] - [IP::local_addr]:[TCP::local_port]"
set parameters [findstr [HTTP::path] ";" 1]
set session_id ""

foreach parameter [split $parameters ";"] {
scan $parameter {%[^=]=%s} name value
if {$debug}{log local0.debug "$logTuple :: Multiple JsessionID in: [HTTP::host][HTTP::uri]"}
if {$name equals "jsessionid"} {set session_id $value}
}
if {$session_id ne ""}{
#Persist on the parsed session ID for X seconds
if {$debug}{log local0.debug "$logTuple :: Single JsessionID in: [HTTP::host][HTTP::uri]"}
persist uie $session_id 86400
}
}
Comments
Stanislas_Piro2
Cumulonimbus
Cumulonimbus

Hi,

 

you can do it with a simpler code:

 

when HTTP_REQUEST {
    set parameters [findstr [HTTP::path] ";" 1]
    foreach parameter [split $parameters ";"] {
        scan $parameter {%[^=]=%s} name value
        if {$name equals "jsessionid"} {set session_id $value}
    }
    if {$session_id ne ""}{
            Persist on the parsed session ID for X seconds
            if {$debug}{log local0.debug "$logTuple :: Single JsessionID in: [HTTP::host][HTTP::uri]"}
            persist uie $session_id 86400
    }
}
Jason_Adams
F5 Employee
F5 Employee

Thank you Stanislas.

 

I have updated the main code to represent your example.

 

Stanislas_Piro2
Cumulonimbus
Cumulonimbus

more efficient code:

 

when CLIENT_ACCEPTED {
    set debug 1
}
when HTTP_REQUEST {
    set path [HTTP::path]
    set logTuple "[IP::client_addr]:[TCP::client_port] - [IP::local_addr]:[TCP::local_port]"
    if {[set last_jsessionid_pos [string last "jsessionid=" $path]] ne -1} {
        if {[set semicolon_pos [string first ";" $path $last_jsessionid_pos]] ne -1} {
            set session_id [string range $path [expr {$last_jsessionid_pos + 11}] [expr {$semicolon_pos -1}]]
        } else {
            set session_id [string range $path [expr {$last_jsessionid_pos + 11}] end]
        }
        Persist on the parsed session ID for X seconds
        if {$debug}{log local0.debug "$logTuple :: Single JsessionID in: [HTTP::host][HTTP::uri]"}
        persist uie $session_id 86400        
    }
}
Version history
Last update:
‎05-Jun-2023 22:41
Updated by: