Re: Cannot have multiple Set-Cookie headers in response
Jacob Smullyan <[email protected]>
| Newsgroups | gmane.comp.web.skunkweb |
|---|---|
| Message-ID | <[email protected]> |
I've checked in a fix to SkunkWeb/Services/httpd/protocol.py. Attached are two diffs, against CVS and against 3.4b5. js On Sat, Nov 22, 2003 at 11:16:54AM -0500, Jacob Smullyan wrote: > I've verified that the problem is with httpd. Here is the same page > (which puts two cookies in the response), first with mod_skunkweb, > then with httpd: > > # wget -q -O- -s http://localhost/cookietest.html > HTTP/1.1 200 OK > Date: Sat, 22 Nov 2003 16:11:48 GMT > Server: Apache/2.0.48 (Gentoo/Linux) mod_ssl/2.0.48 OpenSSL/0.9.6k DAV/2 SVN/0.31.0 SkunkWeb/3.4b5 > Etag: mNmJNYtGMbTH2rUrZKTrWw== > Set-Cookie: a=4; > Set-Cookie: b=4; > Content-Length: 13 > Keep-Alive: timeout=15, max=100 > Connection: Keep-Alive > Content-Type: text/html; charset=ISO-8859-1 > > > > cookie set. > > > # wget -q -O- -s http://localhost:8080/cookietest.html > HTTP/1.0 200 OK > Content-Length: 13 > Etag: mNmJNYtGMbTH2rUrZKTrWw== > Date: Sat, 22 Nov 2003 16:12:52 GMT > Set-Cookie: b=4; > Content-Type: text/html > Server: SkunkWeb 3.4b5 > > > > cookie set. > > > Fix will follow shortly. > > js > > On Sat, Nov 22, 2003 at 08:23:49AM -0500, Jacob Smullyan wrote: > > On Fri, Nov 21, 2003 at 10:37:46PM -0800, Dan Chow wrote: > > > I'm new to skunkweb and have been building my website with it. Skunkweb > > > is pretty cool, but I ran into a problem that I saw that someone had > > > posted and then said it might be resolved. But I still see that behavior. > > > I'm using Skunkweb 3.4b5 with python 2.3.2 on a redhat 9.0 linux box. The > > > problem I am seeing is that if I try to set multiple cookies in a single > > > response, my browser (mozilla1.5) shows that only one is set. Also, > > > when I use tcptrace, I only see the second cookie being sent over the > > > wire. My test is the following: > > > > > > foo.html: > > > ========= > > > <:component /en/foo.pycomp connection=`CONNECTION`:> > > > <html> > > > Cookies sent > > > </html> > > > > > > foo.pycomp: > > > =========== > > > # put in two cookies and see which is set > > > connection.responseCookie["cookie1"] = "test1" > > > connection.responseCookie["cookie2"] = "test2" > > > > > > foo.html calls foo.pycomp which sets two session cookies. And returns > > > some html. I get back the page, but only one cookie is set. > > > > > > I've looked at Cookie.py and that doesn't seem to be the problem > > > Also invoking skunkweb's > > > HTTPConnection.response method in lib/Services/web/protocol.py returns > > > both cookies in the response, so I am at a loss as to what is happening. > > > > Thanks for bringing this to my attention. If it has been brought up > > before, it went by me completely, or I'd have fixed it. > > > > I believe you must be using the httpd service and that that is where > > the bug lies. If you use apache/mod_skunkweb, I think you'll get both > > Set-Cookie lines. > > > > The bug is that httpd currently takes the response headers and turns > > them back into a dictionary, discarding duplicate keys (see > > httpd.protocol._getHeaderDict). This is just plain wrong, obviously, > > so I'll try to get a fix out later today. > > > > js > >
DIFF_CVS
(text/plain, 1.3 KB)
Index: protocol.py
===================================================================
RCS file: /cvsroot/skunkweb/skunkweb/SkunkWeb/Services/httpd/protocol.py,v
retrieving revision 1.11
diff -c -r1.11 protocol.py
*** protocol.py 8 Sep 2003 00:49:20 -0000 1.11
--- protocol.py 22 Nov 2003 16:35:23 -0000
***************
*** 471,479 ****
if not server:
respp['server'] = 'SkunkWeb %s' % Configuration.SkunkWebVersion
resl = ["%s %s" % (httpVersion, status)]
! for k,v in respp.items():
! resl.append("%s: %s" % (self._fixHeader(k), v))
! return "\r\n".join(resl)+"\r\n\r\n"+respp.fp.read()
def marshalException(self, exc_text, sessionDict):
res=RequestFailed(constants.WEB_JOB, exc_text, sessionDict)
--- 471,481 ----
if not server:
respp['server'] = 'SkunkWeb %s' % Configuration.SkunkWebVersion
resl = ["%s %s" % (httpVersion, status)]
! for k in respp.keys():
! kf=self._fixHeader(k)
! for v in respp.getheaders(k):
! resl.append("%s: %s" % (kf, v))
! return "%s\r\n\r\n%s" % ("\r\n".join(resl), respp.fp.read())
def marshalException(self, exc_text, sessionDict):
res=RequestFailed(constants.WEB_JOB, exc_text, sessionDict)
DIFF_34b5
(text/plain, 2.8 KB)
Index: protocol.py
===================================================================
RCS file: /cvsroot/skunkweb/skunkweb/SkunkWeb/Services/httpd/protocol.py,v
retrieving revision 1.10
retrieving revision 1.12
diff -c -r1.10 -r1.12
*** protocol.py 7 Jun 2003 20:50:06 -0000 1.10
--- protocol.py 22 Nov 2003 16:38:09 -0000 1.12
***************
*** 5,11 ****
# Public License or the SkunkWeb License, as specified in the
# README file.
#
! # $Id: protocol.py,v 1.10 2003/06/07 20:50:06 smulloni Exp $
# Time-stamp: <01/05/04 13:27:08 smulloni>
########################################################################
--- 5,11 ----
# Public License or the SkunkWeb License, as specified in the
# README file.
#
! # $Id: protocol.py,v 1.12 2003/11/22 16:38:09 smulloni Exp $
# Time-stamp: <01/05/04 13:27:08 smulloni>
########################################################################
***************
*** 17,22 ****
--- 17,23 ----
import exceptions
import re
import socket
+ from urllib import unquote
##NEW
import rfc822
***************
*** 197,203 ****
#'AUTH_TYPE' : '',
# this may need to be fudged later too
# (for index documents, for instance)
! 'SCRIPT_NAME' : match.group('path'),
'QUERY_STRING' : match.group('query') or '',
'REMOTE_ADDR' : peeraddress,
'REMOTE_PORT' : peerport }
--- 198,204 ----
#'AUTH_TYPE' : '',
# this may need to be fudged later too
# (for index documents, for instance)
! 'SCRIPT_NAME' : unquote(match.group('path')),
'QUERY_STRING' : match.group('query') or '',
'REMOTE_ADDR' : peeraddress,
'REMOTE_PORT' : peerport }
***************
*** 470,478 ****
if not server:
respp['server'] = 'SkunkWeb %s' % Configuration.SkunkWebVersion
resl = ["%s %s" % (httpVersion, status)]
! for k,v in respp.items():
! resl.append("%s: %s" % (self._fixHeader(k), v))
! return "\r\n".join(resl)+"\r\n\r\n"+respp.fp.read()
def marshalException(self, exc_text, sessionDict):
res=RequestFailed(constants.WEB_JOB, exc_text, sessionDict)
--- 471,481 ----
if not server:
respp['server'] = 'SkunkWeb %s' % Configuration.SkunkWebVersion
resl = ["%s %s" % (httpVersion, status)]
! for k in respp.keys():
! kf=self._fixHeader(k)
! for v in respp.getheaders(k):
! resl.append("%s: %s" % (kf, v))
! return "%s\r\n\r\n%s" % ("\r\n".join(resl), respp.fp.read())
def marshalException(self, exc_text, sessionDict):
res=RequestFailed(constants.WEB_JOB, exc_text, sessionDict)
signature.asc
(application/pgp-signature, 189 B)
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.3 (GNU/Linux) iD8DBQE/v5KEuqamFyFXXLIRAhO0AJ90GXCtrFG6b2zV0FEDU3gNG02+2wCfUu6E bL+7el9b6BlzkwXL/m6gu4g= =+Gdw -----END PGP SIGNATURE-----