quetz-mod_python-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Nicolas Lehuen <nicolas.leh...@gmail.com>
Subject Re: [mod_python] Cookie patch
Date Sun, 16 Jan 2005 08:52:20 GMT
On Sat, 15 Jan 2005 21:25:38 -0500 (EST), Gregory (Grisha) Trubetskoy
<grisha@apache.org> wrote:
> On Sat, 15 Jan 2005, Nicolas Lehuen wrote:
> > Anyway, my advice is that we should support RFC 2965 cookies
> There isn't much to "support" per se, the actual support belongs on the
> browser side (obeying $Path, $Max-Age, etc.).
> > either by silently discarding $ attributes
> I think discarding is bad (and that's what the patch seems to do). $Path
> is not the same thing as Path and we should not silently replace one with
> the other. (And what if a cookie has both Path and $Path)?
> > or by fully supporting them;
> Which pretty much just means adding them to _valid_attr.
> > but we cannot keep throwing exceptions at the users whose browser is
> > unlucky enough to use RFC 2965.
> Cookies come from servers, I'm not sure I understand this.
> > I must confess I didn't do my homework properly - I've only read the
> > first RFC, not the 2965. So I'll have a look at the link you mentioned
> > above to get a little perspective on the subject.
> My main point is that this thread and subsequent patches were triggered by
> a cookie that appears to be completely bogus in the first place, and
> perhaps it's not so bad that an exception was triggered.
> In any event, I think we need to keep this discussion going, because I
> don't have a good feeling that due dilligence has been done here.
> Admittedly, the Cookie.py module isn't perfect, but I'm not sure that
> we're making it any better... I'd prefer something took more time, but
> we were certain it was done right :-)
> Grisha

I also think we should discuss this issue, that's why I didn't hurry
and use my brand new check-in rights ;)

First, a few URLs :

RFC2109 : http://www.faqs.org/rfcs/rfc2109.html
RFC2965 : http://www.faqs.org/rfcs/rfc2965.html
Netscape : http://wp.netscape.com/newsref/std/cookie_spec.html

There is an important thing to notice in the three specs : the headers
sent by the server to the browser (Set-Cookie or Set-Cookie2) are not
symetric to the headers sent by the browser to the server (Cookie or

The answer to your question "And what if a cookie has both Path and
$Path ?" is "It cannot, because Path belongs to a Set-Cookie header,
and $Path to a Cookie header", let's see why.

In all three specs, when the server wants to set a cookie on the
browser, it sends a Set-Cookie (or Set-Cookie2 in RFC2965)  header, in
the form :

(Netscape) Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/acme
(RFC2109) Set-Cookie: Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"
(RFC2965) Set-Cookie2: Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"

Let's imagine, as in the various spec examples, that the server needs
to send another cookie. In the same response, the server adds another
Set-Cookie header :

(Netscape) Set-Cookie: Part_Number=Rocket_Launcher_0001; path=/acme
(RFC2109) Set-Cookie: Part_Number="Rocket_Launcher_0001"; Version="1";
(RFC2965) Set-Cookie2: Part_Number="Rocket_Launcher_0001";
Version="1"; Path="/acme"

In all three specs, when the browser request a document within the
scope of a set of cookies, it must (or MUST, in RFC parlance ;) send a
Cookie header, in the form :

(Netscape) Cookie: CUSTOMER=WILE_E_COYOTE; Part_Number=Rocket_Launcher_0001
(RFC2109) Cookie: $Version="1";
                            Customer="WILE_E_COYOTE"; $Path="/acme";
                            Part_Number="Rocket_Launcher_0001"; $Path="/acme";
(RFC2109) Cookie: $Version="1";
                            Customer="WILE_E_COYOTE"; $Path="/acme";
                            Part_Number="Rocket_Launcher_0001"; $Path="/acme";

As you can see, the main difference between Netscape cookies and RFC
cookies is that in the RFCs, the browser is supposed to send back some
of the cookies attributes to the browser.

Since they did not send cookie attributes with the cookies, the
Netscape guys had no trouble with the browser sending a single Cookie
headers with all the cookies in it (whereas, remember, we had one
Set-Cookie header per cookie).

The problem is that the RFC guys decided to maintain this *and* pass
some of the cookies attributes. So, instead of cleanly fixing the
problem and making Set-Cookie and Cookie symetric (same syntax, same
1:1 mapping with the cookie they represent), they thought about this
corny $-prefixed notation.

Now, when you are writing the server-side cookie parsing code, which
is the one we're talking about, you are trying to parse a Cookie (not
Cookie2 - more on that later) header. The good news is that it's not
so difficult to write some parsing code that parses both
Netscape-style and RFC style headers.

That what the rewrite does : it just builds cookies, but when findind
a $-prefixed cookie name, it knows it is an attribute for the last
defined cookie. There is just a special case for the first $Version
attribute, since there is no last defined cookie. I chose a *very* lax
implementation which allows for other attributes than $Version in
front of the Cookie header. But apart from potential problems here,
the implementation pretty much does the job.

Now, what about the differences between RFC2109 and RFC2965 ? First,
RFC2965 uses Set-Cookie2 instead of Set-Cookie, but that doesn't
change anything to our code, which is designed to parse the Cookie
header. The RFC2965 also defines a few more cookie attributes (namely
CommentURL and Port). Finally, the RFC2965 defines a Cookie2 header,
which allows the browser to tell the server which cookie version it
understands the best (and that's all).

Of course, I guess all this stuff about Set-Cookie2 is widely
unsupported, both by servers and browsers. All this mess is perfectly
ridiculous, still, we have to support it. As far as I'm concerned, the
Netscape spec was OK, and the RFCs should simply have formalized it as
it was. Sigh...

Anyway, there may be some browsers that when sent a Netscape or
RFC2109 Set-Cookie header (it's difficult to differentiate the two
from a browser perspective), send a RFC2109 or RFC2965 Cookie header
to the server. So, for those browsers, we have to support the RFCs,
hence the fix to Cookie.py.

I'd really like Craig to tell us more about the User-Agent which sent
him the RFC-style cookie ?



View raw message