classification
Title: Cookie and multiple names
Type: behavior Stage: test needed
Components: Library (Lib) Versions: Python 2.6
process
Status: closed Resolution: duplicate
Dependencies: Superseder: http.cookies, Cookie.py: Improper handling of duplicate cookies
View: 1375011
Assigned To: Nosy List: BreamoreBoy, jjlee, loewis, valankar
Priority: normal Keywords:

Created on 2005-12-04 03:47 by valankar, last changed 2010-08-30 16:53 by BreamoreBoy. This issue is now closed.

Messages (11)
msg26971 - (view) Author: Viraj Alankar (valankar) Date: 2005-12-04 03:47
The cookie specification described here:

http://wp.netscape.com/newsref/std/cookie_spec.html

states that multiple names of cookies can be sent. This does not seem 
to parse correctly with the Cookie module due to its dictionary storage.  
When parsing cookies via modpython, only the last cookie is used. I 
think it would be better to only use the first value, since that is what 
the specification says. Or provide for a way to store multiple names 
with different paths.
msg26972 - (view) Author: John J Lee (jjlee) Date: 2005-12-04 15:52
Logged In: YES 
user_id=261020

I don't get it:

>>> import Cookie
>>> c = Cookie.SimpleCookie()
>>> c.load("foo=bar; bar=baz")
>>> c
<SimpleCookie: bar='baz' foo='bar'>


Where's the problem?

In general, don't pay too much attention to that standard, BTW:

http://wwwsearch.sourceforge.net/ClientCookie/doc.html#standards
msg26973 - (view) Author: Viraj Alankar (valankar) Date: 2005-12-04 16:07
Logged In: YES 
user_id=107970

Basically, sometimes a web client will send 2 instances of the same name:

Cookie: mycookie=foo; mycookie=bar

The specs say that the first one is the one that should be used. The other 
cookies listed are the inherited ones from paths that a prefix of the current 
URL. When this is parsed by the Cookie module, mycookie gets set to bar 
when it should be foo.

Another example might be:

Cookie: mycookie=foo; path=bar
Cookie: mycookie=foo; path=baz

In this case there should be 2 cookies with the name 'mycookie'. The 
uniqueness is determined by the different paths.

Thanks.
msg26974 - (view) Author: John J Lee (jjlee) Date: 2005-12-04 18:16
Logged In: YES 
user_id=261020

OK, I see.

I agree that it's a bug, but I'm undecided whether the
existing behaviour should be fixed.  It's true that clients
are supposed to (and do) send the most specific cookie last,
so this bug could cause servers to see the cookie from, eg
path '/cgi-bin' instead of from path '/mystuff/cgi-bin'. 
However, module Cookie is old and stable, and a patch might
break servers expecting the current behaviour.  I *suppose*
such breakage is fairly unlikely, so I wouldn't object to a
patch.

I certainly don't see anybody objecting to a patch to add a
new method to allow access to multiple cookies of the same
name  without altering the existing dict interface (repr()
could change, but not eg. .get()).

Either way, I suspect a patch is only likely to appear from
somebody who is actually using such cookies, though :-)
msg26975 - (view) Author: Viraj Alankar (valankar) Date: 2005-12-04 22:46
Logged In: YES 
user_id=107970

Heh I guess that means I should try to write a patch. Might be a good learning 
experience for me.
msg26976 - (view) Author: Martin v. Löwis (loewis) * (Python committer) Date: 2006-12-03 12:44
I fail to see the bug. Where in the spec does it say that the first value should be used? On the contrary, the spec seems to say that the last value should be used:

# Instances of the same path and name will overwrite each other, 
# with the latest instance taking precedence.

So if that's what the current module does, there is no bug.
msg26977 - (view) Author: John J Lee (jjlee) Date: 2006-12-03 16:49
loewis: In the Netscape cookie protocol (which is specified approximately, though ambiguously, and incorrectly in places, by cookie_spec.html), cookies sent from client to server in the Cookie: header do not include the path (neither as "path=/foo/bar", nor even as "$path=/foo/bar").  In valankar's first example of 2005-12-04 16:07, the two cookies must be interpreted as having different paths (if they do not have different paths, the client is not behaving correctly).  See the section titled "Second Example transaction sequence:" in cookie_spec.html for an example of this.  So, the part of cookie_spec.html you quote is not relevant (in fact, it refers to client behaviour, not server behaviour -- though it doesn't say so explicitly!).

BTW, I said earlier: "clients are supposed to (and do) send the most specific cookie last".  That's backwards: in fact, clients send the most specific (longest-path) cookie first.  Cookie.py always ignores all but the last cookie (it overwrites the first), so it will only store the least-specific cookie, so my point stands.

Also note that valankar's second example of 2005-12-04 16:07 is incorrect (unless he meant Set-Cookie: instead of Cookie:): the Cookie header should never contain path cookie-attributes (see penultimate paragraph of this comment, and perhaps more clearly, method cookielib.CookieJar._cookie_attrs()).  By "cookie-attribute" I mean a string of the form "<name>=<value>", i.e. the same thing as represented by instances of Cookie.Morsel .

AFAIK (not 100% sure here) when several cookies are returned, none of the cookie standards defines which cookie servers should or should not look at, so Cookie.py should probably make all of the cookies available through some interface.  If it chooses to only provide one cookie (as it does), it would seem that a good choice would be the first cookie in the string passed to .load(), since that should be the one with the longest path.  Cookie.py instead takes the last cookie (probably by accident).  That's not good, but I'm unsure whether it should be changed, since it may break old code.

I'm puzzled by Cookie.py's design: First, poor naming: BaseCookie (and therefore a SimpleCookie instance) seems to represent multiple HTTP cookies.  Second, BaseCookie.load(string) treats attributes like "path" specially, and I do not understand why.  The documentation says you're intended to pass the value of HTTP_COOKIE to that string, but AFAICS, if the client obeys any of the cookie protocols (either the de facto Netscape protocol or any of the RFCs) then HTTP_COOKIE should never contain a string like "; path=x", where x is replaced by any arbitrary string (assuming here that HTTP_COOKIE is always simply the value of the HTTP header named "Cookie", and for simplicity that there are no quoted strings in the Cookie header).  Third, BaseCookie does not allow storing several cookies of the same name.  As I understand it, this last problem is the one valankar was complaining about.

I've always found cookies highly confusing, I must say, so it's always possible I've got something mixed up by now... but I don't think so.
msg26978 - (view) Author: John J Lee (jjlee) Date: 2007-01-31 23:00
The discussion of this issue is here:

http://python.org/sf/1372650


No conclusion has been reached about whether it should be applied.  I've said all I want to say about it already...
msg26979 - (view) Author: John J Lee (jjlee) Date: 2007-01-31 23:15
Ignore last comment.  I thought a patch had been added, but it seems I mixed up the bug and patch trackers.  Curse this SF bug/patch tracker distinction!
msg81971 - (view) Author: John J Lee (jjlee) Date: 2009-02-13 21:04
A patch for this bug is attached to issue1375011.
msg115233 - (view) Author: Mark Lawrence (BreamoreBoy) * Date: 2010-08-30 16:53
A patch is attached to #1375011.
History
Date User Action Args
2010-08-30 16:53:05BreamoreBoysetstatus: open -> closed

dependencies: - http.cookies, Cookie.py: Improper handling of duplicate cookies
superseder: http.cookies, Cookie.py: Improper handling of duplicate cookies

nosy: + BreamoreBoy
messages: + msg115233
resolution: duplicate
2009-02-16 03:57:53ajaksu2setdependencies: + http.cookies, Cookie.py: Improper handling of duplicate cookies
2009-02-13 21:04:36jjleesetmessages: + msg81971
2009-02-13 01:17:02ajaksu2setstage: test needed
type: behavior
versions: + Python 2.6, - Python 2.4
2005-12-04 03:47:22valankarcreate