Tuesday, November 22, 2011

so many cookies

I was reading upon HTTP cookies and it is actually quite confusing. Because there are many different cookie specs and browsers not necessarily support all of them.

Original Netscape Cookie Spec: http://curl.haxx.se/rfc/cookie_spec.html

Very simple and straightforward format:

Set-Cookie: NAME=VALUE; expires=DATE;
path=PATH; domain=DOMAIN_NAME; secure

RFC 2109 (based on Netscape spec with minor tweaks): http://tools.ietf.org/html/rfc2109

The syntax for the Set-Cookie response header is

   set-cookie      =       "Set-Cookie:" cookies
   cookies         =       1#cookie
   cookie          =       NAME "=" VALUE *(";" cookie-av)
   NAME            =       attr
   VALUE           =       value
   cookie-av       =       "Comment" "=" value
                   |       "Domain" "=" value
                   |       "Max-Age" "=" value
                   |       "Path" "=" value
                   |       "Secure"
                   |       "Version" "=" 1*DIGIT

RFC 2965, obsoletes RFC 2109: http://tools.ietf.org/html/rfc2965

It adds more syntax items. It is very interesting to read 9.1 section about the compatibility with existing cookie implementation. Basically, it should overwrite an existing cookie value set by Set-Cookie if domain and path both matches.

The syntax for the Set-Cookie2 response
   header is

   set-cookie      =       "Set-Cookie2:" cookies
   cookies         =       1#cookie
   cookie          =       NAME "=" VALUE *(";" set-cookie-av)
   NAME            =       attr
   VALUE           =       value
   set-cookie-av   =       "Comment" "=" value
                   |       "CommentURL" "=" <"> http_URL <">
                   |       "Discard"
                   |       "Domain" "=" value
                   |       "Max-Age" "=" value
                   |       "Path" "=" value
                   |       "Port" [ "=" <"> portlist <"> ]
                   |       "Secure"
                   |       "Version" "=" 1*DIGIT
   portlist        =       1#portnum
   portnum         =       1*DIGIT

RFC 6265, obsoletes RFC 2965: http://tools.ietf.org/html/rfc6265

It admits the same confusion that I had, and deprecates the Cookie2 and Set-Cookie2 headers introduced in RFC 2965!

"Prior to this document, there were at least three descriptions of
   cookies: the so-called "Netscape cookie specification" [Netscape],
   RFC 2109 [RFC2109], and RFC 2965 [RFC2965].  However, none of these
   documents describe how the Cookie and Set-Cookie headers are actually
   used on the Internet (see [Kri2001] for historical context).  In
   relation to previous IETF specifications of HTTP state management
   mechanisms, this document requests the following actions:

   1.  Change the status of [RFC2109] to Historic (it has already been
       obsoleted by [RFC2965]).

   2.  Change the status of [RFC2965] to Historic.

   3.  Indicate that [RFC2965] has been obsoleted by this document.

   In particular, in moving RFC 2965 to Historic and obsoleting it, this
   document deprecates the use of the Cookie2 and Set-Cookie2 header

The actual format is getting updated as well. Notice that now both Expires and Max-Age are supported with Max-Age overriding Expires if both exist. If not, the cookie is kept by user agent till the current session ends.

 set-cookie-header = "Set-Cookie:" SP set-cookie-string
 set-cookie-string = cookie-pair *( ";" SP cookie-av )
 cookie-pair       = cookie-name "=" cookie-value
 cookie-name       = token
 cookie-value      = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE )
 cookie-octet      = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E
                       ; US-ASCII characters excluding CTLs,
                       ; whitespace DQUOTE, comma, semicolon,
                       ; and backslash
 token             = <token, defined in [RFC2616], Section 2.2>

 cookie-av         = expires-av / max-age-av / domain-av /
                     path-av / secure-av / httponly-av /
 expires-av        = "Expires=" sane-cookie-date
 sane-cookie-date  = <rfc1123-date, defined in [RFC2616], Section 3.3.1>
 max-age-av        = "Max-Age=" non-zero-digit *DIGIT
                       ; In practice, both expires-av and max-age-av
                       ; are limited to dates representable by the
                       ; user agent.
 non-zero-digit    = %x31-39
                       ; digits 1 through 9
 domain-av         = "Domain=" domain-value
 domain-value      = <subdomain>
                       ; defined in [RFC1034], Section 3.5, as
                       ; enhanced by [RFC1123], Section 2.1
 path-av           = "Path=" path-value
 path-value        = <any CHAR except CTLs or ";">
 secure-av         = "Secure"
 httponly-av       = "HttpOnly"
 extension-av      = <any CHAR except CTLs or ";">

To conclude, here is a paper providing a good overview and discussion about the cookie: "HTTP Cookie: Standards, Privacy and Politics".