Learn F5 Technologies, Get Answers & Share Community Solutions Join DevCentral

Filter by:
  • Solution
  • Technology
code share

HTTP POST redirect preserving POST data

Problem this snippet solves:

Use Javascript in an iRule to redirect HTTP POST requests to HTTPS. When an HTTP 30x redirect it sent to a client that has sent a POST request, the user-agent transparently issues a new GET request. As a result, the original POST request payload is lost.

The idea behind this iRule is when client sends a POST to an HTTP virtual server, LTM replies with an HTML page which contains a form. The form contains post-data that the client just sent. The form will be auto-submitted by Javascript via HTTPS.

Here is how this iRule works:

  1. if method = post, it issues HTTP::collect, which will invoke HTTP_REQUEST_DATA
  2. then it scans POST-data and prepares new content to respond to client. the new content will include
    • form with all INPUT field names retrieved from POST-data
    • the "action" parameter in the form points to external server
    • all input fields are set as hidden (so client won't see the data during the process)
    • Javascript that submits the form automatically
  3. then iRule replies to client with HTTP::respond command with content prepared in step 2
Comments on this Snippet
Comment made 01-Nov-2017 by Victor Plohod 0

Hello, I'm trying to use your code on a VS where I configured https://devcentral.f5.com/codeshare/redirect-non-ssl-requests-on-ssl-virtual-server-rule I'm a noob in the irule world. 1. What is the role of ext_url ""; . 2. Should I merge the code into one irule or apply two distinct irules on the VS

Comment made 02-Nov-2017 by Stanislas Piron 10237


A 307 status code is created to ask the client to preserve the method and the content on the new location

Comment made 03-Nov-2017 by Stanislas Piron 10237

@victor Plohod, try this irule

when HTTP_REQUEST {    
    # Check if the client used an SSL cipher 
    if {not ([catch {SSL::cipher version} result]) && [string tolower $result] ne "none"}{    
        # Client did use a cipher 
        log local0. "\$result: $result. Allowing encrypted request." 
    } else { 
        # Client did not use a cipher 
        log local0. "\$result: $result. Redirecting unencrypted request."
        if { [HTTP::method] eq "POST" } {
            HTTP::respond 307 "https://[HTTP::host]/"
        } else {
            HTTP::respond 302 "https://[HTTP::host]/"
Comment made 2 weeks ago by Chris Baiocchetti 11


Am curios about the statement:

set static::ext_url "";

is test.post generic and able to be used anywhere, or would I need to replace it with an entry specific to my environment?

Thanks in advance,