Search code examples
node.jsexpresshttp-headersnode.js-connect

Is ExpressJS using invalid set-cookie headers?


I'm using the ExpressJS res.cookie function to add cookies to the header res.cookie('mycookie', x, y);

But digging into ExpressJS and Connect I found that the joins used to string parameters together for the cookie function doesnt append a trailing semicolon

express/res.js

res.cookie = function(name, val, options){
  options = options || {};
  if ('maxAge' in options) options.expires = new Date(Date.now() + options.maxAge);
  if (undefined === options.path) options.path = this.app.set('basepath');
  var cookie = utils.serializeCookie(name, val, options);
  this.header('Set-Cookie', cookie);
};

connect/utils.js

exports.serializeCookie = function(name, val, obj){
  var pairs = [name + '=' + encodeURIComponent(val)]
    , obj = obj || {};

  if (obj.domain) pairs.push('domain=' + obj.domain);
  if (obj.path) pairs.push('path=' + obj.path);
  if (obj.expires) pairs.push('expires=' + obj.expires.toUTCString());
  if (obj.httpOnly) pairs.push('httpOnly');
  if (obj.secure) pairs.push('secure');
  //this doesnt append semi colon
  return pairs.join('; ');
};

Then I looked up the spec for Set-Cookie header ( http://www.ietf.org/rfc/rfc2109.txt )

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

The language structure seems to imply that there should be a trailing semi-colon.

I just wanted to be clear on this because some parsers I have running against cookies Ive set using res.cookie() are returning 'invalid Set-Cookie header' errors.

Is ExpressJS setting invalid Set-Cookie headers via Connect.js ?


Solution

  • The trailing semicolor is required only if additional attribute-value pairs are present. Notation "*(";" cookie-av)" indicates zero or more occurences → a semicolon is only required for every additional value of cookie-av.

    From the spec:

    Informally, the Set-Cookie response header comprises the token Set-Cookie:, followed by a comma-separated list of one or more cookies. Each cookie begins with a NAME=VALUE pair, followed by zero or more semi-colon-separated attribute-value pairs. The syntax for attribute-value pairs was shown earlier.

    Stricly speaking, what doesn't go according to the spec is the extra space that is inserted by express after each semicolon. I'm pretty confident though that every sane browser knows how to handle the non-standard extra whitespaces.