Forum Discussion
Need to parse the [HTTP::uri] and modify it for a redirect
Hello - I found a really useful irule from Joe Pruitt for parsing the uri
`when HTTP_REQUEST {
log local0. "‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐"
log local0. "URI Information"
log local0. "‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐"
log local0. "HTTP::uri: [HTTP::uri]"
log local0. "‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐"
log local0. "Path Information"
log local0. "‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐"
log local0. "HTTP::path: [HTTP::path]"
set depth [URI::path [HTTP::uri] depth]
for {set i 1} {$i <= $depth} {incr i} {
set dir [URI::path [HTTP::uri] $i $i]
log local0. "dir\[$i\]: $dir"
}
log local0. "Basename: [URI::basename [HTTP::uri]]"
log local0. "‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐"
log local0. "Query Information"
log local0. "‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐"
log local0. "HTTP::query: [HTTP::query]"
set namevals [split [HTTP::query] "&"]
for {set i 0} {$i < [llength $namevals]} {incr i} {
set params [split [lindex $namevals $i] "="]
set pnum [expr $i+1]
log local0. "Param\[$pnum\]: [lindex $params 0]"
log local0. "Value\[$pnum\]: [lindex $params 1]"
log local0. "Value\[$pnum\]: [URI::query [HTTP::uri] [lindex $params 0]]"
}
}`
The following is the output from running this IRULE.
Dec 27 16:26:09 slot1/oit-lbw-ltmmgd info tmm[12383]: Rule /IDM/log_URI : HTTP::uri: /~geverest/home/data-modeling-course/course-flyer
Dec 27 16:26:09 slot1/oit-lbw-ltmmgd info tmm[12383]: Rule /IDM/log_URI : Path Information
Dec 27 16:26:09 slot1/oit-lbw-ltmmgd info tmm[12383]: Rule /IDM/log_URI : HTTP::path: /~geverest/home/data-modeling-course/course-flyer
Dec 27 16:26:09 slot1/oit-lbw-ltmmgd info tmm[12383]: Rule /IDM/log_URI : dir[1]: /~geverest/
Dec 27 16:26:09 slot1/oit-lbw-ltmmgd info tmm[12383]: Rule /IDM/log_URI : dir[2]: /home/
Dec 27 16:26:09 slot1/oit-lbw-ltmmgd info tmm[12383]: Rule /IDM/log_URI : dir[3]: /data-modeling-course/
Dec 27 16:26:09 slot1/oit-lbw-ltmmgd info tmm[12383]: Rule /IDM/log_URI : Basename: course-flyer
Dec 27 16:26:09 slot1/oit-lbw-ltmmgd info tmm[12383]: Rule /IDM/log_URI : Query Information
Dec 27 16:26:09 slot1/oit-lbw-ltmmgd info tmm[12383]: Rule /IDM/log_URI : &8208;&8208;&8208;&8208;&8208;&8208;&8208;&8208;&8208;&8208;&8208;&8208;&8208;&8208;&8208;&8208;&8208;&8208;&8208;&8208;&8208;&8208;
Dec 27 16:26:09 slot1/oit-lbw-ltmmgd info tmm[12383]: Rule /IDM/log_URI : HTTP::query:
Dec 27 16:26:09 slot1/oit-lbw-ltmmgd info tmm[12383]: Rule /IDM/log_http_header : =============================================
the path = HTTP::path: /~geverest/home/data-modeling-course/course-flyer the uri = HTTP::uri: /~geverest/home/data-modeling-course/course-flyer /IDM/log_URI : dir[1]: /~geverest/
What I need help with is I need to rebuild the uri to be /home/data-modeling-course/course-flyer (that's just this one example)" from what it was to not have the dir[1] as part of the uri.
All of the uri's have varying depths of directories but "/~something" is always first after the host name and I just need to do the redirect without it.
I have a couple hundred old apache redirects that are in this similar format that are being moved to the f5 as just a virtual server with an IRULE and no pool that just does redirects.
Here is a snippet of the irule
`when HTTP_REQUEST {
Check the requested path with wildcard matching
switch -glob [HTTP::uri] {
"/~geverest*"
{
set uri [HTTP::uri]
set path [HTTP::path]
HTTP::redirect "http://xxxxx.com${uri}"
event disable all
}`
could you please explain what exactly the code is doing especially the regular expression part and the string map ?
/~ is literal chars (i.e. it matches /~)
%[^/] matches every chars but not / and the matching string will be stored in variable specified later (e.g. it matches geverest and geverest will be stored in first variable)
[scan [HTTP::uri] {/~%[^/]} first] returns number of matching string. so, we can use it to determine whether it is uri we are interested (i.e. 1).
[string map "/~$first/ /" [HTTP::uri]] replace /~$first/ with / in uri (e.g. it replaces /~geverest/ with /).
[root@bip1a:Active:In Sync] config tclsh % set uri "/~geverest/home/data-modeling-course/course-flyer" /~geverest/home/data-modeling-course/course-flyer % scan $uri {/~%[^/]} first 1 % put $first geverest % string map "/~$first/ /" $uri /home/data-modeling-course/course-flyer
- nitassEmployee
may this be usable?
e.g.
// config [root@ve13a:Active:In Sync] config tmsh list ltm virtual bar ltm virtual bar { destination 172.28.24.10:80 ip-protocol tcp mask 255.255.255.255 profiles { http { } tcp { } } rules { qux } source 0.0.0.0/0 translate-address enabled translate-port enabled vs-index 4 } [root@ve13a:Active:In Sync] config tmsh list ltm rule qux ltm rule qux { when HTTP_REQUEST { if { [scan [HTTP::uri] {/~%[^/]} first] } { HTTP::respond 301 noserver Location "http://[HTTP::host][string map "/~$first/ /" [HTTP::uri]]" } } } // test [root@ve13a:Active:In Sync] config curl -I http://172.28.24.10/~geverest/home/data-modeling-course/course-flyer HTTP/1.0 301 Moved Permanently Location: http://172.28.24.10/home/data-modeling-course/course-flyer Connection: Keep-Alive Content-Length: 0 [root@ve13a:Active:In Sync] config curl -I http://172.28.24.10/~helloworld/home/data-modeling-course/course-flyer HTTP/1.0 301 Moved Permanently Location: http://172.28.24.10/home/data-modeling-course/course-flyer Connection: Keep-Alive Content-Length: 0
- Tom_K_185554Nimbostratus
Thank you, This is awesome - does exactly what I need. I am not that great with irules at this level - could you please explain what exactly the code is doing especially the regular expression part and the string map ?
`when HTTP_REQUEST { if { [scan [HTTP::uri] {/~%[^/]} first] } { HTTP::respond 301 noserver Location "http://[HTTP::host][string map "/~$first/ /" [HTTP::uri]]" } }`
- nitass_89166Noctilucent
may this be usable?
e.g.
// config [root@ve13a:Active:In Sync] config tmsh list ltm virtual bar ltm virtual bar { destination 172.28.24.10:80 ip-protocol tcp mask 255.255.255.255 profiles { http { } tcp { } } rules { qux } source 0.0.0.0/0 translate-address enabled translate-port enabled vs-index 4 } [root@ve13a:Active:In Sync] config tmsh list ltm rule qux ltm rule qux { when HTTP_REQUEST { if { [scan [HTTP::uri] {/~%[^/]} first] } { HTTP::respond 301 noserver Location "http://[HTTP::host][string map "/~$first/ /" [HTTP::uri]]" } } } // test [root@ve13a:Active:In Sync] config curl -I http://172.28.24.10/~geverest/home/data-modeling-course/course-flyer HTTP/1.0 301 Moved Permanently Location: http://172.28.24.10/home/data-modeling-course/course-flyer Connection: Keep-Alive Content-Length: 0 [root@ve13a:Active:In Sync] config curl -I http://172.28.24.10/~helloworld/home/data-modeling-course/course-flyer HTTP/1.0 301 Moved Permanently Location: http://172.28.24.10/home/data-modeling-course/course-flyer Connection: Keep-Alive Content-Length: 0
- Tom_K_185554Nimbostratus
Thank you, This is awesome - does exactly what I need. I am not that great with irules at this level - could you please explain what exactly the code is doing especially the regular expression part and the string map ?
`when HTTP_REQUEST { if { [scan [HTTP::uri] {/~%[^/]} first] } { HTTP::respond 301 noserver Location "http://[HTTP::host][string map "/~$first/ /" [HTTP::uri]]" } }`
- nitassEmployee
could you please explain what exactly the code is doing especially the regular expression part and the string map ?
/~ is literal chars (i.e. it matches /~)
%[^/] matches every chars but not / and the matching string will be stored in variable specified later (e.g. it matches geverest and geverest will be stored in first variable)
[scan [HTTP::uri] {/~%[^/]} first] returns number of matching string. so, we can use it to determine whether it is uri we are interested (i.e. 1).
[string map "/~$first/ /" [HTTP::uri]] replace /~$first/ with / in uri (e.g. it replaces /~geverest/ with /).
[root@bip1a:Active:In Sync] config tclsh % set uri "/~geverest/home/data-modeling-course/course-flyer" /~geverest/home/data-modeling-course/course-flyer % scan $uri {/~%[^/]} first 1 % put $first geverest % string map "/~$first/ /" $uri /home/data-modeling-course/course-flyer
- Tom_K_185554Nimbostratus
Thank you very much - this is incredibly helpful.
- nitass_89166Noctilucent
could you please explain what exactly the code is doing especially the regular expression part and the string map ?
/~ is literal chars (i.e. it matches /~)
%[^/] matches every chars but not / and the matching string will be stored in variable specified later (e.g. it matches geverest and geverest will be stored in first variable)
[scan [HTTP::uri] {/~%[^/]} first] returns number of matching string. so, we can use it to determine whether it is uri we are interested (i.e. 1).
[string map "/~$first/ /" [HTTP::uri]] replace /~$first/ with / in uri (e.g. it replaces /~geverest/ with /).
[root@bip1a:Active:In Sync] config tclsh % set uri "/~geverest/home/data-modeling-course/course-flyer" /~geverest/home/data-modeling-course/course-flyer % scan $uri {/~%[^/]} first 1 % put $first geverest % string map "/~$first/ /" $uri /home/data-modeling-course/course-flyer
- Tom_K_185554Nimbostratus
Thank you very much - this is incredibly helpful.
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