Forum Discussion

Stefano_E__1814's avatar
Stefano_E__1814
Icon for Nimbostratus rankNimbostratus
Feb 19, 2015

Get value from HTTP POST request body

Hi all,

 

I can retrieve the value of the JSON boby for HTTP POST request.

 

This is the call to F5: curl --insecure -H "Content-type: application/json" -H "Content-Length: 92" -X POST -d '{ \"username\" : \"abc\", \"password\" : \"def\"}'

 

My iRule code is:

 

 

  when HTTP_REQUEST {
     Keeping request lenght to collect the payload for POST JSON request parameters
    if {[HTTP::method] equals "POST"} {

        set content_length 0
        if { [HTTP::header exists "Content-Length"] } {
            if { [HTTP::header "Content-Length"] > 1048000 }{
                if {$logDebug}{log local0. "=>|$logId|      Content-Length over 1Mb so discard the request\n"}

                HTTP::respond 403
                return
            } else { 
                set content_length [HTTP::header "Content-Length"]
                if {$logDebug}{log local0. "=>|$logId|      post request Content-Length is $content_length\n"}
            }
        } else {
            if {$logDebug}{log local0. "=>|$logId|      Content-Length HEADER does not exist: discarding the request\n"}
            HTTP::respond 403
            return
        }

         Collecting the http request byte  
        if { $content_length > 0 } {
            HTTP::collect $content_length
            set payload_collect true
            if {$logDebug}{log local0. "=>|$logId|      Payload collected. we pass on HTTP_REQUEST_DATA event\n"}
        }
    }
}

when HTTP_REQUEST_DATA {

     ==================================================================================
     We need to retrieve parameters from POST body
     ==================================================================================

     Looking for json POST parameter
    if { $payload_collect } {  
        set payload [HTTP::payload]
        if {$logDebug}{log local0. "=>|$logId| payload: $payload \n"}

        I need to retrieve username and password from json
        ....

    }
}

 

How can I manage the json for retrieve the values of username and password?

 

Thx, Stefano

 

4 Replies

  • this is just an example. it may not be fully correct.

     

     

     configuration
    
    root@(ve11b)(cfg-sync In Sync)(Active)(/Common)(tmos) 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
        vs-index 2
    }
    root@(ve11b)(cfg-sync In Sync)(Active)(/Common)(tmos) list ltm rule qux
    ltm rule qux {
        proc key2value {l k} {
      foreach elm [split $l ,] {
        set kv [split $elm :]
        if { $k eq [string trim [lindex $kv 0] { }] } {
          return [string trim [lindex $kv 1] { }]
        }
      }
    }
    when HTTP_REQUEST {
      HTTP::collect [HTTP::header Content-Length]
    }
    when HTTP_REQUEST_DATA {
      set payload [HTTP::payload]
      log local0. "payload=$payload "
      log local0. "username=[call key2value [lindex $payload 0] \\"username\\"]"
      log local0. "password=[call key2value [lindex $payload 0] \\"password\\"]"
      HTTP::release
    }
    }
    
     client
    
    [root@centos1 ~] curl -X POST -H "Content-type: application/json" -d '{\"username\" : \"abc\", \"password\" : \"def\"}' http://172.28.24.10
    curl: (52) Empty reply from server
    [root@centos1 ~]
    
     /var/log/ltm
    
    [root@ve11b:Active:In Sync] config  tail -f /var/log/ltm
    Feb 19 19:38:15 ve11b info tmm1[14140]: Rule /Common/qux : payload={\"username\" : \"abc\", \"password\" : \"def\"}
    Feb 19 19:38:15 ve11b info tmm1[14140]: Rule /Common/qux : username=\"abc\"
    Feb 19 19:38:15 ve11b info tmm1[14140]: Rule /Common/qux : password=\"def\"
    

     

  • Thx.

     

    I put your code in my iRule and it run correctly.

     

    There is only a problem. If there is a new line in the JSON, the "parsing" doesn't work correctly.

     

    This is the JSON that creates problems:

     

    { "username" : "abc",

     

    "password" : "def" }

     

    How can I remove the new line in the JSON (therefore in the payload)?

     

    Thx again, Stefano

     

  • How can I remove the new line in the JSON (therefore in the payload)?

     

    can you try string trim without chars?

     

     

    If chars is not specified then white space is removed (spaces, tabs, newlines, and carriage returns).
    

     

    string trim

     

     

    http://wiki.tcl.tk/10174

     

     

     configuration
    
    [root@ve11b:Active:In Sync] config  tmsh list ltm rule qux
    ltm rule qux {
        proc key2value {l k} {
      foreach elm [split $l ,] {
        set kv [split $elm :]
        if { $k eq [string trim [lindex $kv 0]] } {
          return [string trim [lindex $kv 1]]
        }
      }
    }
    when HTTP_REQUEST {
      HTTP::collect [HTTP::header Content-Length]
    }
    when HTTP_REQUEST_DATA {
      set payload [HTTP::payload]
      log local0. "payload=$payload "
      log local0. "username=[call key2value [lindex $payload 0] \"username\"]"
      log local0. "password=[call key2value [lindex $payload 0] \"password\"]"
      HTTP::release
    }
    }
    
     client
    
    [root@centos1 ~] curl -X POST -H "Content-type: application/json" -d $'{ "username" : "abc",\n"password" : "def" }' http://172.28.24.10
    curl: (52) Empty reply from server
    
     /var/log/ltm
    
    [root@ve11b:Active:In Sync] config  tail -f /var/log/ltm
    Feb 20 09:58:13 ve11b info tmm[14140]: Rule /Common/qux : payload={ "username" : "abc", "password" : "def" }
    Feb 20 09:58:13 ve11b info tmm[14140]: Rule /Common/qux : username="abc"
    Feb 20 09:58:13 ve11b info tmm[14140]: Rule /Common/qux : password="def"
    

     

  • Hi nitass,

     

    your code works correctly.

     

    Now I have to authenticate the user with the found username/password through LDAP Auth.

     

    After creating a access profile, what should I do to call the profile into irule?