For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

Forum Discussion

NoamRotter's avatar
NoamRotter
Icon for Altostratus rankAltostratus
Apr 26, 2020
Solved

Extract value from json

Hi,

I have a webapp which accepts a POST with JSON payload.

the JSON has only one key:value

I need to write to log the value of the key.

For example:

This is the payload of the JSON:

{ 
    "token": "c71c56b0-7590-4785-b490-0f060c563aee" 
} 

I need to write to the LTM log:

c71c56b0-7590-4785-b490-0f060c563aee

I need a simple iRule which parses the payload, find the value of "token" and writes it to the ltm log.

Can someone help please?

Noam.

  • Great! HTTP::payload must be able to retrieve it because it comes in a single packet so it doesn't need to accumulate. Note that if the payload was larger ( eg 1K ) then this might fail and you'd have to use HTTP::collect.

    We can use regexp in multiple ways to retrieve the substring. Try this:

    when HTTP_REQUEST {
      if { [HTTP::method] == "POST"} {
        log local0. ">>> Method is POST<<<"
        if {  [ regexp -- {"token": "(.+)"} [HTTP::payload] a b ] } {
            log local0.debug "Token Found a:$a b:$b"
        }
      }
    }

    $a should be the whole of the line, $b should be only the token part.

    Take a look here for more detail on how to use regexp:

    PS the other way we could have done it is this:

    set token [lindex [ regexp -inline -- {"token": "(.+)"} [HTTP::payload] ] 1]

5 Replies

  • when HTTP_REQUEST {
      if { [HTTP::method] == "POST"} {
        HTTP::collect
      }
    }
    when HTTP_REQUEST_DATA {
      set token [ regexp -inline -- {"token": "(.+)"} [HTTP::payload] ]
      log local0.debug "Token: $token" 
    }

    Try the above - I haven't tested it out but it looks ok

    • NoamRotter's avatar
      NoamRotter
      Icon for Altostratus rankAltostratus

      Hi Pete,

      Thank you for your answer.

      I tested your iRule.

      When using postman to post the JSON,

      the postman keeps saying "Sending Request" until I hit the cancel button

      I have added 2 logs line:

      when HTTP_REQUEST {
        if { [HTTP::method] == "POST"} {
        log local0. ">>> Method is POST<<<"
      	HTTP::collect
          log local0. ">>> HTTP Collected<<<"
        }
      }
      when HTTP_REQUEST_DATA {
        set token [ regexp -inline -- {"token": "(.+)"} [HTTP::payload] ]
        log local0.debug "Token: $token" 
      }

      In the ltm log I see:

      Apr 29 08:27:43 bigip1 info tmm2[18399]: Rule /Common/test-iRule <HTTP_REQUEST>: >>> Method is POST<<<

      Apr 29 08:27:43 bigip1 info tmm2[18399]: Rule /Common/test-iRule <HTTP_REQUEST>: >>> HTTP Collected<<<

      When I disable the HTTP::collect line

      Postman sends the request and finishes. Does not keep saying "Sending request"

      But, the when HTTP_REQUEST_DATA part is not executed.

      I moved these lines to HTTP_REQUEST part:

      set token [ regexp -inline -- {"token": "(.+)"} [HTTP::payload] ]

      log local0.debug "Token: $token"

      like this:

      when HTTP_REQUEST {
        if { [HTTP::method] == "POST"} {
          log local0. ">>> Method is POST<<<"
          set token [ regexp -inline -- {"token": "(.+)"} [HTTP::payload] ]
          log local0.debug "Token: $token" 
        }
      }

      And now I get in the ltm log:

      Apr 29 08:33:45 bigip1 debug tmm2[18399]: Rule /Common/test-iRule <HTTP_REQUEST>: Token: {"token": "01593317-66f9-4e8a-8467-6f4652e680e3"} 01593317-66f9-4e8a-8467-6f4652e680e3

      And I expected to get:

      Apr 29 08:33:45 bigip1 debug tmm2[18399]: Rule /Common/test-iRule <HTTP_REQUEST>: Token: 01593317-66f9-4e8a-8467-6f4652e680e3

      Thank you for your time.

      Noam.

  • Great! HTTP::payload must be able to retrieve it because it comes in a single packet so it doesn't need to accumulate. Note that if the payload was larger ( eg 1K ) then this might fail and you'd have to use HTTP::collect.

    We can use regexp in multiple ways to retrieve the substring. Try this:

    when HTTP_REQUEST {
      if { [HTTP::method] == "POST"} {
        log local0. ">>> Method is POST<<<"
        if {  [ regexp -- {"token": "(.+)"} [HTTP::payload] a b ] } {
            log local0.debug "Token Found a:$a b:$b"
        }
      }
    }

    $a should be the whole of the line, $b should be only the token part.

    Take a look here for more detail on how to use regexp:

    PS the other way we could have done it is this:

    set token [lindex [ regexp -inline -- {"token": "(.+)"} [HTTP::payload] ] 1]
    • NoamRotter's avatar
      NoamRotter
      Icon for Altostratus rankAltostratus

      Hi Pete,

      Thank you very much,

      This is working as well as the PS.

      👍