http-headersnshttpurlresponse

What Format Do HTTP Headers Return As?


I have been trying to unit test HTTP response headers. I need to receive a cookie from the headers. I get two Set-Cookie headers back, but I need one for authentication. The returned headers are:

HTTP/1.1 200 OK
Server: Cowboy
Connection: close
Set-Cookie: heroku-session-affinity=ADaDaANoA24IARpRKtf///8HYgABgzdiAAJZ5WECbAAAAAJtAAAABXdlYi4ybQAAAAV3ZWIuMWpcXMFamSToBPxyiOHM7o5AwvVZ3g__; Version=1; Expires=Thu, 12-Jan-2017 01:45:27 GMT; Max-Age=86400; Domain=xxxxxxxx.xxxx.xx; Path=/; HttpOnly
X-Powered-By: Express
Vary: Origin
Access-Control-Allow-Credentials: true
Content-Type: application/json; charset=utf-8
Content-Length: 30914
Etag: W/"78c2-veX2kgrO3zh118nYsOP80A"
Set-Cookie: connect.sid=s%3Adl1_47SY9vlKlHOguBvjZpmaa2WTUhHG.O2j9YOShB4AX0rAC5RRj%2BeCXAB11s5q1DB4x4fiHE4A; Path=/; Expires=Fri, 13 Jan 2017 01:45:27 GMT; HttpOnly
Date: Wed, 11 Jan 2017 01:45:27 GMT
Via: 1.1 vegur

I added a test file which includes these values:

{
    "Server": "Cowboy",
    "Connection": "close",
    "Set-Cookie": "heroku-session-affinity=ADaDaANoA24IAXtpQOD///8HYgAAKehiAA6V12ECbAAAAAJtAAAABXdlYi4ybQAAAAV3ZWIuMWrNqkap0u4H0uG3Btrtlamaq2nQ5w__; Version=1; Expires=Wed, 11-Jan-2017 01:12:09 GMT; Max-Age=86400; Domain=xxxxxxxx.xxxx.xx; Path=/; HttpOnly",
    "X-Powered-By": "Express",
    "Vary": "Origin",
    "Access-Control-Allow-Credentials": "true",
    "Content-Type": "application/json; charset=utf-8",
    "Content-Length": "30914",
    "Etag": "W/\"78c2-veX2kgrO3zh118nYsOP80A\"",
    "Set-Cookie": "connect.sid=s%3ACX3tfhPk9nlRtU8e8gtouQIx1kpP07h9.iExm%2F96Dgzuh289nmjwbYO49E0Bq0WwUHmN539IkudI; Path=/; Expires=Thu, 12 Jan 2017 01:12:09 GMT; HttpOnly",
    "Date": "Tue, 10 Jan 2017 01:12:09 GMT",
    "Via": "1.1 vegur"
}

I need the second Set-Cookie value, but when I try to access its value, I get the first Set-Cookie instead. I am assuming because I put the headers in a dictionary. But when I am stubbing responses in my unit tests, the required format for the headers is a dictionary. I am only getting one Set-Cookie header since I can't have two of the same keys in a dictionary.

Am I doing something incorrectly?


Solution

  • RFC 7230, Section 3.2.2 covers how HTTP headers should be handled; it supersedes RFC 2616. In particular, it says:

    A sender MUST NOT generate multiple header fields with the same field name in a message unless either the entire field value for that header field is defined as a comma-separated list [i.e., #(values)] or the header field is a well-known exception (as noted below).

    And, unfortunately for your use case, the Set-Cookie is one of those noted "well-known exceptions", because its syntax (covered by RFC 6265) does not readily lend itself to a comma-separated list of cookie values.

    This means that using a dictionary/hashtable structure for representing HTTP headers usually works, but breaks for cases like Set-Cookie. There are other ways of obtaining the headers; see, for example, this StackOverflow post. Or, if you can do your unit testing for headers other than Set-Cookie, that might be another approach.

    Hope this helps!