How can I get the cookies from an HTTP response?

I’m working with an API where I’m trying to grab one of the cookies from the response of a POST request.

Coming from R - with the httr package, I can do something like this because cookies is a field in the response, much like status code, headers, etc:

response <- POST(url,
                 add_headers(.headers = c("Content-Type" = "application/json;charset=UTF-8")),
                 body = request_body)

token <-
    response |>
    pluck("cookies") |>
    filter(name == "cookie_name") |>
    pull(cookie_value)

In HTTP.jl, the only things I see in the documentation are version, status, headers, body, and request. Is there something like HTTP.response.cookies available that I’m missing?

My uninformed, hacky solution is to get the cookie from the header like this, but my emphasis is on hacky:

function get_cookie(resp::HTTP.Messages.Response; cookie_name::String)
    cookie_headers = filter(headers -> headers[1] == "Set-Cookie", resp.headers)

    # get the index where the cookie is
    idx = map(1:length(cookie_headers)) do x 
        cookie_headers[x][2] |>
        cookie_values -> occursin(cookie_name, cookie_values)
    end 

    # get the cookie values
    cookie_values = map(1:length(cookie_headers)) do x 
        cookie_headers[x][2]
    end 
    
    # index into the values to extract the cookie in question
    #  (I already know the length of the token in question...)
    cookie_values[idx][1][10:559]
end

get_cookie(response, cookie_name = "name_of_the_cookie")
#> "a string containing the token in question"

Looks like you can use HTTP.Cookies.cookies on the response.

That gives me a method error:

resp = HTTP.request("POST", request_url, request_headers, request_body)
HTTP.Cookies.cookies(resp)

#> ERROR: MethodError: no method matching cookies(::HTTP.Messages.Response)
#> Closest candidates are:
#>   cookies(::HTTP.Messages.Request) at ~/.julia/packages/HTTP/aTjcj/src/cookies.jl:314

Which seems odd, as the documentation seems to suggest that there is a method for the response type.

You probably just need to update; HTTP.cookies(resp) was added in the 1.0 release, but wasn’t available in the 0.9.17 release.

1 Like

Aha - yep, being behind on updates will do that :sweat_smile:

What I end up doing then is:

cookies = HTTP.cookies(resp)

token_value = filter(x -> x.name == "cookie_name", cookies)[1].value