Hello,
I'm working on a simple http client program using the httpclient module. While trying to parse Set-Cookie: headers, I noticed I was only getting access to the last header since a StringTable is used. Has anyone else run into this issue? Am I doing something wrong?
Thanks!
Hrm. That's an interesting issue.
Looks like a bug and I'm not sure what the solution is. How do other libraries represent HTTP headers?
resp.Header["Set-Cookie"][0]
will grab the first Set-Cookie header.
Apache's HttpClient (Java) stores them as an array of Header objects I believe, or that's at least how they're returned to you.
Unfortunately, I think the "fix" will be code breaking. Maybe instead of a StringTable, a table of sequence of strings? Or maybe a header object? I'm a nim noob, but I'd be happy to work on a pull request if needed or desired.
Another option is to use two fields, one StringTable that only stores the last header value (this is for the vast majority of headers that have only one value), and another that maps header -> list of values. This way you can preserve backward compatibility.
But yes.. one header can have multiple values so the current representation is broken.
Golang uses a map of string slices
How does that work? The keys are supposed to be case insensitive, I think.
Yes, per RFC2616, header field names are case-insensitive.
Golang stores them in the map with the keys in a canonicalized format (i.e. "accept-encoding" becomes "Accept-Encoding"). There are some provided helper methods that do this conversion for you (Header.Get(), Header.Set(), etc.). However, accessing multiple values of the same header name requires you to access the map directly.
I suppose the "correct" version of my previous example would be:
resp.Header[http.CanonicalHeaderKey("Set-Cookie")][0]