Forum Discussion
redirects with get / post
We have created iRules to perform redirects on existing web services. All the rules appear to work correctly when performing a HTTPGet. However, when connecting from another application, the request comes across as an HTTPPost and is never redirected. I have verfied in the IIS logs that the request is never sent to its final destination (the server trying to redirect to). Is this something that can be fixed on the iRule, profile or the vip?
below is my irule.
when HTTP_REQUEST { if { ([string tolower [HTTP::host]]) contains "unity.mysite.com" } { switch -glob -- [string tolower [HTTP::uri]] { "akcelrons.asmx" { HTTP::redirect "https://webservice.mysite.com/Unity/akcelrons.asmx" } "credispher.asmx" { HTTP::redirect "http://webservice.mysite.com/Unity/credispher.asmx.asmx" } "interfaceser.asmx" { HTTP::redirect "https://webservice.mysite.com/Unity/interfaceser.asmx" } ::"meridian.asmx" { HTTP::redirect "https://webservice.mysite.com/Unity[HTTP::uri]" } "unitysale.asmx" { HTTP::redirect "https://webservice.mysite.com/Unity/unitysale.asmx" } "unitywep.asmx" { HTTP::redirect "https://webservice.mysite.com/Unity/unitysale.asmx" } "weblott.asmx" { HTTP::redirect "https://webservice.mysite.com/Unity/Unityweblott.asmx" } } } }
It get redirected to a GET request
- Richard__HarlanHistoric F5 Account
If you look through the IIS logs there will most likely be a get request. When a POST request get a redirect it will be retried as a get request. you can use the following iRule to force the browser to send the request to the correct location
https://devcentral.f5.com/wiki/iRules.HTTP_POST_redirectNew118.ashx
- Gill_32697NimbostratusPlease explain in more detail. If i already have the iRule from above where would I place HTTP_POST_redirectNew118.ashx. So how and where would I use your example?
the basic issue is that you can't redirect (HTTP 3xx) a POST request, that is simply how redirects were designed.
the iRule that Richard mentions uses a trick to still be able to get the POST data through. it builds a piece of javascript that will take the information from the POST and send it again when the page loads.
if you want to include this into your code you could include the HTTP_REQUEST section completely. add a HTTP_REQUEST_DATA section and build a similar switch statement for the different POST urls based on URI.
- Kevin_StewartEmployee
Not to throw the conversation into a tangent, but are you certain that the iRule works with GET requests? You're using a glob switch but no glob patterns, so not sure where the matches are being made. Here's a slightly modified version of your iRule:
when HTTP_REQUEST { if { ( [string tolower [HTTP::host]]) contains "unity.mysite.com" } { switch -glob [string tolower [HTTP::uri]] { "*akcelrons.asmx*" { HTTP::redirect "https://webservice.mysite.com/Unity/akcelrons.asmx" } "*credispher.asmx*" { HTTP::redirect "http://webservice.mysite.com/Unity/credispher.asmx.asmx" } "*interfaceser.asmx*" { HTTP::redirect "https://webservice.mysite.com/Unity/interfaceser.asmx" } "*meridian.asmx*" { HTTP::redirect "https://webservice.mysite.com/Unity[HTTP::uri]" } "*unitysale.asmx*" { HTTP::redirect "https://webservice.mysite.com/Unity/unitysale.asmx" } "*unitywep.asmx*" { HTTP::redirect "https://webservice.mysite.com/Unity/unitysale.asmx" } "*weblott.asmx*" { HTTP::redirect "https://webservice.mysite.com/Unity/Unityweblott.asmx" } } } }
- Gill_32697Nimbostratus
First, thank you all for your help, Still having trouble understanding. Below is the exact irule from the LTM, other comments are from the Web Developer. Im in the middle F5 Admin and the HTTP Developer says it fails the Post. So help me to bridge the gap. Lets startover.. Kevin, let me give you the current iRule, below. Richard, Boneyard, are your comments for me of http developer?
when HTTP_REQUEST { if { ([string tolower [HTTP::host]]) contains "unitynet.mysite.com" } { switch -glob -- [string tolower [HTTP::uri]] { "akcelerantws.asmx" { HTTP::redirect "https://webservices.mysite.com/Unity/Akcelerantws.asmx" } "credispherewsv2.asmx" { HTTP::redirect "http://webservices.mysite.com/Unity/CrediSphereWSV2.asmx" } "interfaceservice.asmx" { HTTP::redirect "https://webservices.mysite.com/Unity/InterfaceService.asmx" } ::"meridianlinkws.asmx" { HTTP::redirect "https://webservices.mysite.com/Unity[HTTP::uri]" } "unitysailws.asmx" { HTTP::redirect "https://webservices.mysite.com/Unity/UnitySAILWS.asmx"
- Richard__HarlanHistoric F5 AccountThe iRule was for the f5. The browser sending the post request will not resend the post request to the 302, it mite work if you send it a 307 that depends on the browser but it open up a security risk. The iRule in question will cause the browser to run some Javascript to redirect to the post to the correct location.
- Kevin_StewartEmployee
So are you saying that a POST request doesn't get redirected at all, or that a POST request gets redirected, but is turned into a GET?
- Richard__HarlanHistoric F5 Account
It get redirected to a GET request
- Gill_32697Nimbostratus
Ok guys, so I have my original iRule and sample link from Richard. Now how in the heck to I merge these irule. Im not at the admin level need to script this, so I f you could help please.
- Gill_32697Nimbostratus::! This is my irule. : when HTTP_REQUEST { if { ([string tolower [HTTP::host]]) contains "unitynet.mysite.com" } { switch -glob -- [string tolower [HTTP::uri]] { "*akcelerantws.asmx*" { HTTP::redirect "https://webservices.mysite.com/Unity/Akcelerantws.asmx" } "*credispherewsv2.asmx*" { HTTP::redirect "http://webservices.mysite.com/Unity/CrediSphereWSV2.asmx" } "*interfaceservice.asmx*" { HTTP::redirect "https://webservices.mysite.com/Unity/InterfaceService.asmx" } ::"*meridianlinkws.asmx*" { HTTP::redirect "https://webservices.mysite.com/Unity[HTTP::uri]" } "*unitysailws.asmx*" { HTTP::redirect "https://webservices.mysite.com/Unity/UnitySAILWS.asmx" } "*unityweblet.asmx*" { HTTP::redirect "https://webservices.mysite.com/Unity/UnityWeblet.asmx" } "*weblet.asmx*" { HTTP::redirect "https://webservices.mysite.com/Unity/UnityWeblet.asmx" } } } } ================================= ::! This is from https://clouddocs.f5.com/api/irules/HTTP_POST_redirectNew118.html : when HTTP_REQUEST { Check if request was a POST if { [string tolower [HTTP::method]] eq "post" } { Check if there is a Content-Length header if { [HTTP::header exists "Content-Length"] } { if { [HTTP::header "Content-Length"] > 1048000 }{ Content-Length over 1Mb so collect 1Mb set content_length 1048000 } else { Content-Length under 1Mb so collect actual length set content_length [HTTP::header "Content-Length"] } } else { Response did not have Content-Length header, so use default of 1Mb set content_length 1048000 } Don't collect content if Content-Length header value was 0 if { $content_length > 0 } { HTTP::collect $content_length } } } when HTTP_REQUEST_DATA { set content "< script type=text/javascript language=javascript> \ function s(){ document.f.submit(); } \ " HTTP::respond 200 content $content switch -glob -- [string tolower [HTTP::uri]] { "*akcelerantws.asmx*" { HTTP::redirect "https://webservices.mysite.com/Unity/Akcelerantws.asmx" } "*credispherewsv2.asmx*" { HTTP::redirect "http://webservices.mysite.com/Unity/CrediSphereWSV2.asmx" } "*interfaceservice.asmx*" { HTTP::redirect "https://webservices.mysite.com/Unity/InterfaceService.asmx" } ::"*meridianlinkws.asmx*" { HTTP::redirect "https://webservices.mysite.com/Unity[HTTP::uri]" } "*unitysailws.asmx*" { HTTP::redirect "https://webservices.mysite.com/Unity/UnitySAILWS.asmx" } "*unityweblet.asmx*" { HTTP::redirect "https://webservices.mysite.com/Unity/UnityWeblet.asmx" } "*weblet.asmx*" { HTTP::redirect "https://webservices.mysite.com/Unity/UnityWeblet.asmx" } } }
- Gill_32697Nimbostratus
So how can I merge these to iRules.
- as i posted earlier: if you want to include this (get into put irule) into your code you could include the HTTP_REQUEST section completely. add a HTTP_REQUEST_DATA section and build a similar switch statement for the different POST urls based on URI. just start with something simple and expand on it. please remember everyone here is answering in their spare time, cant expect them to do all the work for you. also try to format your posts, like they are now makes it really hard to read.
- nitassEmployee
e.g.
root@(ve11a)(cfg-sync Not All Devices Synced)(Active)(/Common)(tmos) list ltm virtual bar ltm virtual bar { destination 172.28.20.111:80 ip-protocol tcp mask 255.255.255.255 pool foo profiles { http { } tcp { } } rules { myrule } source 0.0.0.0/0 source-address-translation { type automap } vs-index 28 } root@(ve11a)(cfg-sync Not All Devices Synced)(Active)(/Common)(tmos) list ltm rule myrule ltm rule myrule { when HTTP_REQUEST { if { ([string tolower [HTTP::host]]) contains "unitynet.mysite.com" } { switch -glob -- [string tolower [HTTP::uri]] { "*akcelerantws.asmx*" { set ext_url "https://webservices.mysite.com/Unity/Akcelerantws.asmx" } "*credispherewsv2.asmx*" { set ext_url "http://webservices.mysite.com/Unity/CrediSphereWSV2.asmx" } "*interfaceservice.asmx*" { set ext_url "https://webservices.mysite.com/Unity/InterfaceService.asmx" } "*meridianlinkws.asmx*" { set ext_url "https://webservices.mysite.com/Unity[HTTP::uri]" } "*unitysailws.asmx*" { set ext_url "https://webservices.mysite.com/Unity/UnitySAILWS.asmx" } "*unityweblet.asmx*" { set ext_url "https://webservices.mysite.com/Unity/UnityWeblet.asmx" } "*weblet.asmx*" { set ext_url "https://webservices.mysite.com/Unity/UnityWeblet.asmx" } default { return } } } else { return } if { [string tolower [HTTP::method]] eq "get" } { HTTP::redirect $ext_url } elseif { [string tolower [HTTP::method]] eq "post" } { if { [HTTP::header exists "Content-Length"] } { if { [HTTP::header "Content-Length"] > 1048000 }{ set content_length 1048000 } else { set content_length [HTTP::header "Content-Length"] } } else { set content_length 1048000 } if { $content_length > 0 } { HTTP::collect $content_length } } else { do something } } when HTTP_REQUEST_DATA { set content "< script type=text/javascript language=javascript> \ function s(){ document.f.submit(); } \ " foreach p [split [HTTP::payload] &] { set name [URI::decode [getfield $p = 1]] set value [URI::decode [getfield $p = 2]] set content "${content}" } set content "${content}" HTTP::respond 200 content $content } } GET [root@ve11a:Active:Not All Devices Synced] config curl -i http://172.28.20.111/something/akcelerantws.asmx -H "Host: unitynet.mysite.com" HTTP/1.0 302 Found Location: https://webservices.mysite.com/Unity/Akcelerantws.asmx Server: BigIP Connection: Keep-Alive Content-Length: 0 POST [root@ve11a:Active:Not All Devices Synced] config curl -i --data "para1=value1¶2=value2" http://172.28.20.111/something/akcelerantws.asmx -H "Host: unitynet.mysite.com" HTTP/1.0 200 OK Server: BigIP Connection: Keep-Alive Content-Length: 372 < script type=text/javascript language=javascript> function s(){ document.f.submit(); }
- Gill_32697Nimbostratus
I trying to work on it and so are our developers. But we are having a problem understanding. Even if you could help with a sample. So I have the first part is by iRule and second part is your recommendation. We are havinging problems adding our current irule to your sample.
- check what nitass posted, most of the work is done there already
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