Bugs item #1660009, was opened at 2007-02-14 19:52
Message generated for change (Comment added) made by jjlee
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1660009&group_id=5470

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: Python Library
Group: Python 2.3
Status: Open
Resolution: None
Priority: 5
Private: No
Submitted By: David Margrave (davidma)
Assigned to: Nobody/Anonymous (nobody)
Summary: continuing problem with httplib multiple set-cookie headers

Initial Comment:

This is related to [ 432621 ] httplib: multiple Set-Cookie headers, which I was 
unable to re-open.

The workaround that was adopted in the previous bug tracker item was to combine 
multiple set-cookie headers received from the server, into a single set-cookie 
element in the headers dictionary, with the cookies joined into a 
comma-separated string.

The problem arises when a comma character appears inside the 'expires' field of 
one of the cookies.  This makes it difficult to split the cookie headers back 
apart.  The comma character should be escaped, or a different separator 
character used.

i.e.

expires=Sun, 17-Jan-2038 19:14:07 GMT

For now I am using the workaround that gstein suggested, use 
response.msg.getallmatchingheaders()

Python 2.3 has this behavior, and probably later versions.



----------------------------------------------------------------------

Comment By: John J Lee (jjlee)
Date: 2007-03-15 20:46

Message:
Logged In: YES 
user_id=261020
Originator: NO

Hold on, httplib.HTTPMessage.addheader() is undocumented, hence private. 
httplib.HTTPMessage.readheaders() itself calls that method, but also keeps
the raw multiple-header data in the .headers list, so
.getallmatchingheaders() still works.

So the only bug I see is that the documentation for APIs that return
should point out the fact that Set-Cookie is an oddity, and that
.getallmatchingheaders() should be used in that case.


----------------------------------------------------------------------

Comment By: John J Lee (jjlee)
Date: 2007-03-15 20:19

Message:
Logged In: YES 
user_id=261020
Originator: NO

OK, thanks!

That certainly does look wrong.  The Set-Cookie case should be
special-cased in that method, I think.


----------------------------------------------------------------------

Comment By: David Margrave (davidma)
Date: 2007-03-15 00:58

Message:
Logged In: YES 
user_id=31040
Originator: YES


See the addheader method of the HTTPMessage class in httplib.py

    def addheader(self, key, value):
        """Add header for field key handling repeats."""
        prev = self.dict.get(key)
        if prev is None:
            self.dict[key] = value
        else:
            combined = ", ".join((prev, value))
            self.dict[key] = combined


also see the original tracker entry where this fix was first discussed &
implemented

https://sourceforge.net/tracker/index.php?func=detail&aid=432621&group_id=5470&atid=105470






----------------------------------------------------------------------

Comment By: John J Lee (jjlee)
Date: 2007-03-15 00:45

Message:
Logged In: YES 
user_id=261020
Originator: NO

Huh?

1. *What* behaviour is correct?  You still have not said which bit of code
you're talking about, or even which module.

2. You seem to have got the sense of what I said backwards.  As I said,
RFC 2616 is (in practice) WRONG about joining with commas being OK for
Set-Cookie.  Set-Cookies headers must NOT be joined with commas, despite
what RFC 2616 says.


----------------------------------------------------------------------

Comment By: David Margrave (davidma)
Date: 2007-03-15 00:30

Message:
Logged In: YES 
user_id=31040
Originator: YES


fair enough, the RFC says thay have to be joinable with commas, so the
behavior is correct.  I can get by with getallmatchingheaders if I need
access to the original individual cookie values.

thanks,

dave


----------------------------------------------------------------------

Comment By: John J Lee (jjlee)
Date: 2007-03-14 23:57

Message:
Logged In: YES 
user_id=261020
Originator: NO

SimpleHTTPRequestHandler is not part of httplib.  Did you mean to refer to
module SimpleHTTPServer rather than httplib, perhaps?

I don't see the particular bit of code you refer to (neither in httplib
nor in module SimpleHTTPServer), but re the general issue:

Regardless of the fact that RFC 2616 ss. 4.2 says headers MUST be able to
be combined with commas, Netscape Set-Cookie headers simply don't work that
way, and Netscape Set-Cookie headers are here to stay.  So, Set-Cookie
headers must not be combined.

(Quoting does not help, because Netscape Set-Cookie headers contain cookie
values that 1. may contain commas and 2. do not support quoting -- any
quote (") characters are in fact part of the cookie value itself rather
than being part of a quoting mechanism.  And there is no precedent for any
choice of delimter other than a comma, nor for any other Netscape
Set-Cookie cookie value quoting mechanism.)


----------------------------------------------------------------------

Comment By: David Margrave (davidma)
Date: 2007-03-14 21:10

Message:
Logged In: YES 
user_id=31040
Originator: YES


getallmatchingheaders() works fine.

The problem is with the self.headers in the SimpleHTTPRequestHandler and
derived classes.

A website may send multiple set-cookie headers, using gmail.com as an
example: 

Set-Cookie: GMAIL_RTT=EXPIRED; Domain=.google.com; Expires=Tue, 13-Mar-07
21:03:04 GMT; Path=/mail
Set-Cookie: GMAIL_LOGIN=EXPIRED; Domain=.google.com; Expires=Tue,
13-Mar-07 21:03:04 GMT; Path=/mail

The SimpleHTTPRequestHandler class combines multiple set-cookie response
headers into a single comma-separated string which it stores in the headers
dictionary

i.e. 

self.headers ['set-cookie'] =  GMAIL_RTT=EXPIRED; Domain=.google.com;
Expires=Tue, 13-Mar-07 21:03:04 GMT; Path=/mail, GMAIL_LOGIN=EXPIRED;
Domain=.google.com; Expires=Tue, 13-Mar-07 21:03:04 GMT; Path=/mail

The problem is if you try to use code that uses self.headers['set-cookie']
and use string.split to get the original distinct cookie values on the
comma delimiter, you'll run into trouble because of the use of the comma
character within the cookies' expiration tags, such as Expires=Tue,
13-Mar-07 21:03:04 GMT

Again, getallmatchingheaders() is fine as an alternative, but as long as
you are going to the trouble of storing multiple set-cookie response
headers in the self.headers dict, using a delimiter of some sort, I'd argue
you might as well also take care that your delimiter is either unique or
escaped within the fields you are delimiting.




----------------------------------------------------------------------

Comment By: John J Lee (jjlee)
Date: 2007-03-14 20:48

Message:
Logged In: YES 
user_id=261020
Originator: NO

I'm not sure what your complaint is.  What's wrong with
response.msg.getallmatchingheaders()?


----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1660009&group_id=5470
_______________________________________________
Python-bugs-list mailing list 
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to