The strangeness of RFC-2109

Matts on 2006-08-05T14:33:07

Yesterday I had cause to implement cookie parsing and generation within AxKit2. I had browsed a couple of modules for it, but they're all wrapped up in other means of getting the cookie header, so just to be certain I went to the source - the Cookie spec - RFC 2109.

What's very strange is that the cookie spec is only vaguely similar to what people send to the browser and expect back in the perl world.

Things that are different from what I've seen in perl implementations:

  • Expires isn't really valid (it's from the old Netscape implementation). The correct parameter is Max-Age. CGI::Cookie supports this but most other cookie libraries don't.
  • There's a Version attribute which is supposed to be sent in both directions. When it comes back it's $Version. Most cookie libraries will give you access to receive this, but not set it.
  • The Path attribute is sent back with the cookies from the client as $Path. Because cookie libraries compress all the cookies into a hash you can probably only access one of these.
  • When you send Set-Cookie you're also supposed to send Expires: [date far in past]
So now I'm trying to do the right thing with making all this work, but I'm not sure it's worth the effort.


HTTP::Cookies

cbrandtbuffalo on 2006-08-07T14:11:46

Did you happen to look at HTTP::Cookies while you were looking at cookie handling modules?

I'm currently debugging some warnings that seem to be coming out of HTTP::Cookies, specifically 'not defined' type warnings. But I haven't seen any other reports of this, so I'm wondering if I'm just dealing with some malformed or non-standard cookies. I'm thinking I should look at the cookies first, but maybe the module could use a tweak too.

Re:HTTP::Cookies

Matts on 2006-08-07T14:45:11

No, I don't think I looked at that module.

I say: don't bother

bart on 2006-08-13T08:02:38

I've been both reading up a little and trying some stuff out on various browsers. The state of things is well summarized on this page:
Even though there are official IETF RFC's describing HTTP State Management Mechanism using cookies, the de facto standard supported by most browsers is the original Netscape specification. Furthermore, true compliance with IETF standards is actually incompatible with many popular browsers, even those that claim to be RFC-compliant.

Check out the reading list at the bottom, the bottom link to the PDF is quite interesting, especially the addenda.

From what I gathered from experimenting with Firefox 1.5, MSIE 6, and Opera 9, cookies adhere to the original cookie spec from Netscape — the PDF talks about it as "version 0", while your RFC is "version 1". Thus: this RFC is largely a waste of time. Yes, in theory, Max-Age makes more sense than Expires, because your server's and the client's clock may be out of sync; the standard solution to that is not to forget to include a Date HTTP header. There are a few more warts, such as the tiny difference between the format in cookie dates and standard HTTP dates. But, as a whole: cookies v0 work, and that's why implementors are reluctant to upgrade. For what? It'd likely just break working stuff.

From what I gather, no browser sends back the path. Opera 9 sends back a Cookie2 header, even when it's empty, probably to inform the server that it can handle more modern cookies. But the plain Cookie header tends to be a v0 header: just "name=value" pairs.

And your caution about hashes to store the data is justified, because a browser can send back multiple cookies of the same name, when each has its own path — which is unknown. Using a hash, you'll only keep the last one sent.

Re:I say: don't bother

Matts on 2006-08-13T12:57:07

Wow, thanks for the research. Nice work!