Help parsing headers of HTTP response

I could use some help parsing the headers of an HTTP GET response.

Here's the code that I've got so far for trying to get the value, but it doesn't work (errors below)


> httpGet(params) { resp ->
>             LOG("HTTP GET Response: ${resp?.data} with status ${resp?.status}", 3, "debug")
>             if(resp.status == 200) {
>                 def headers = resp?.getAllHeaders()
>                 LOG("headers: ${headers}", 3, "debug")
>                 if (headers && headers.getAt('X-RateLimit-Remaining')) {
>                     state.apiCallsLeft = headers.getAt('X-RateLimit-Remaining')
>                 }
>                 return resp?.data
>             }

This produces:

_httpGet exception: Exception evaluating property 'X-RateLimit-Remaining' for java.util.Arrays$ArrayList, Reason: groovy.lang.MissingPropertyException: No such property: X-RateLimit-Remaining for class: org.apache.http.message.BufferedHeader

[debug] headers: [Date: Sat, 01 Jun 2024 22:48:11 GMT, Content-Type: application/json, Transfer-Encoding: chunked, Connection: keep-alive, Cache-Control: no-cache, no-store, max-age=0, must-revalidate, Pragma: no-cache, Expires: 0, X-XSS-Protection: 1; mode=block, X-Frame-Options: DENY, X-Content-Type-Options: nosniff, X-RateLimit-Limit: 1700, X-RateLimit-Remaining: 1268, X-RateLimit-Reset: 2024-06-02T00:00:00Z]

which looks like the headers print as an accessible groovy Map. But they are not accessible as a map it seems:

Exception Error: groovy.lang.MissingPropertyException: Exception evaluating property 'X-RateLimit-Remaining' for java.util.Arrays$ArrayList, Reason: groovy.lang.MissingPropertyException: No such property: X-RateLimit-Remaining for class: org.apache.http.message.BufferedHeader

And I can't figure out how to access a BufferedHeader either. Help?

What comes out from the LOG() call?

The "headers" output is listed as:
headers: [Date: Sat, 01 Jun 2024 22:48:11 GMT, Content-Type: application/json, Transfer-Encoding: chunked, Connection: keep-alive, Cache-Control: no-cache, no-store, max-age=0, must-revalidate, Pragma: no-cache, Expires: 0, X-XSS-Protection: 1; mode=block, X-Frame-Options: DENY, X-Content-Type-Options: nosniff, X-RateLimit-Limit: 1700, X-RateLimit-Remaining: 1268, X-RateLimit-Reset: 2024-06-02T00:00:00Z]

(to be clear, I had included by accident some code trying to iterate through using .each but that through an error too)

You could try playing around with the use of the getAt(). Either removing it in places to make sure it is what is causing the problem, but also try another header entry to see if it is something about the name of the header entry.

You could also try using headers.X-RateLimit-Remaining instead of the getAt(), to see if that yields a different result.

Or try double-quotes...

Try this instead:

headers?.find { it.getName() == 'X-RateLimit-Remaining' }

It's a List of BufferedHeader, not a Map.

https://hc.apache.org/httpcomponents-core-4.4.x/current/httpcore/apidocs/org/apache/http/message/BufferedHeader.html

2 Likes

I wonder why there is a colon after X-XSS-Protection and not a comma...?

@sburke781 @tomw you guys are awesome. Thanks for leading me to working code.

This did the trick for me:
> def headers = resp?.getAllHeaders()

            def limitRemaining = headers?.find { it.getName() == 'X-RateLimit-Remaining' }
            if (headers && limitRemaining) {
                state.apiCallsLeft = limitRemaining.value
            }
2 Likes

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.