[wwwsearch-commits] r23242 - in wwwsearch/ClientCookie/trunk: .
ClientCookie
jjlee at codespeak.net
jjlee at codespeak.net
Sun Feb 12 03:17:37 CET 2006
Author: jjlee
Date: Sun Feb 12 03:17:29 2006
New Revision: 23242
Modified:
wwwsearch/ClientCookie/trunk/ClientCookie/_Util.py
wwwsearch/ClientCookie/trunk/ClientCookie/_urllib2_support.py
wwwsearch/ClientCookie/trunk/functional_tests.py
Log:
Fix dangling-reference problem, in which all but one of a set of copied responses broke after closing a single member of the set. Fixed by moving most of response_seek_wrapper down into urllib.addinfourl level (replacing the latter class with a work-alike that still works after .close()).
Modified: wwwsearch/ClientCookie/trunk/ClientCookie/_Util.py
==============================================================================
--- wwwsearch/ClientCookie/trunk/ClientCookie/_Util.py (original)
+++ wwwsearch/ClientCookie/trunk/ClientCookie/_Util.py Sun Feb 12 03:17:29 2006
@@ -13,7 +13,7 @@
True = 1
False = 0
-import re, string, time, copy
+import re, string, time, copy, urllib
from types import TupleType
from cStringIO import StringIO
@@ -538,17 +538,38 @@
xreadlines = __iter__
def __repr__(self):
- return ("<%s at %s whose wrapped object = %s>" %
- (self.__class__.__name__, `id(self)`, `self.wrapped`))
+ return ("<%s at %s whose wrapped object = %r>" %
+ (self.__class__.__name__, hex(id(self)), self.wrapped))
+
+
+class response_seek_wrapper(seek_wrapper):
+
+ """
+ Supports copying response objects and setting response body data.
+
+ """
+
+ def __init__(self, wrapped):
+ seek_wrapper.__init__(self, wrapped)
+ self._headers = self.wrapped.info()
+
+ def __copy__(self):
+ cpy = seek_wrapper.__copy__(self)
+ # copy headers from delegate
+ cpy._headers = copy.copy(self.info())
+ return cpy
+
+ def info(self):
+ return self._headers
+
+ def set_data(self, data):
+ self.seek(0)
+ self.read()
+ self.close()
+ cache = self._seek_wrapper__cache = StringIO()
+ cache.write(data)
+ self.seek(0)
- def close(self):
- self.__cache = None
- self.read = None
- self.readline = None
- self.readlines = None
- self.seek = None
- if self.wrapped: self.wrapped.close()
- self.wrapped = None
class eoffile:
# file-like object that always claims to be at end-of-file...
@@ -558,9 +579,21 @@
def next(self): return ""
def close(self): pass
-class response_seek_wrapper(seek_wrapper):
+class eofresponse(eoffile):
+ def __init__(self, url, headers, code, msg):
+ self._url = url
+ self._headers = headers
+ self.code = code
+ self.msg = msg
+ def geturl(self): return self._url
+ def info(self): return self._headers
+
+
+class closeable_response:
"""Avoids unnecessarily clobbering urllib.addinfourl methods on .close().
+ Only supports responses returned by ClientCookie.HTTPHandler.
+
After .close(), the following methods are supported:
.read()
@@ -574,8 +607,7 @@
.next()
.close()
- and the following attributes are supported if present (i.e. in Python 2.4
- or newer):
+ and the following attributes are supported:
.code
.msg
@@ -585,48 +617,43 @@
"""
- def __init__(self, wrapped):
- seek_wrapper.__init__(self, wrapped)
- self.url = self.wrapped.geturl()
- try:
- self.msg = wrapped.msg
- self.code = wrapped.code
- except AttributeError:
- pass # pre-2.4
- self._headers = self.wrapped.info()
-
- def close(self):
- wrapped = self.wrapped
- wrapped.close()
+ def __init__(self, fp, headers, url, code, msg):
+ self._set_fp(fp)
+ self._headers = headers
+ self._url = url
+ self.code = code
+ self.msg = msg
+
+ def _set_fp(self, fp):
+ self.fp = fp
+ self.read = self.fp.read
+ self.readline = self.fp.readline
+ if hasattr(self.fp, "readlines"): self.readlines = self.fp.readlines
+ if hasattr(self.fp, "fileno"):
+ self.fileno = self.fp.fileno
+ else:
+ self.fileno = lambda: None
+ if hasattr(self.fp, "__iter__"):
+ self.__iter__ = self.fp.__iter__
+ if hasattr(self.fp, "next"):
+ self.next = self.fp.next
- new_wrapped = eoffile()
- new_wrapped.url = self.url
- try:
- new_wrapped.url = self.url
- new_wrapped.code = self.code
- except AttributeError:
- pass # pre-2.4
- new_wrapped._headers = self._headers
- self.wrapped = new_wrapped
+ def __repr__(self):
+ return '<%s at %s whose fp = %r>' % (
+ self.__class__.__name__, hex(id(self)), self.fp)
def info(self):
return self._headers
def geturl(self):
- return self.url
+ return self._url
- def __copy__(self):
- cpy = seek_wrapper.__copy__(self)
- cpy._headers = copy.copy(self._headers)
- return cpy
-
- def set_data(self, data):
- self.seek(0)
- self.read()
- self.close()
- cache = self._seek_wrapper__cache = StringIO()
- cache.write(data)
- self.seek(0)
+ def close(self):
+ wrapped = self.fp
+ wrapped.close()
+ new_wrapped = eofresponse(
+ self._url, self._headers, self.code, self.msg)
+ self._set_fp(new_wrapped)
def __getstate__(self):
# There are three obvious options here:
@@ -641,5 +668,7 @@
# So we do 1.
state = self.__dict__.copy()
- state["wrapped"] = eoffile()
+ new_wrapped = eofresponse(
+ self._url, self._headers, self.code, self.msg)
+ state["wrapped"] = new_wrapped
return state
Modified: wwwsearch/ClientCookie/trunk/ClientCookie/_urllib2_support.py
==============================================================================
--- wwwsearch/ClientCookie/trunk/ClientCookie/_urllib2_support.py (original)
+++ wwwsearch/ClientCookie/trunk/ClientCookie/_urllib2_support.py Sun Feb 12 03:17:29 2006
@@ -15,7 +15,7 @@
import ClientCookie
from _ClientCookie import CookieJar, request_host
-from _Util import isstringlike, startswith, getheaders
+from _Util import isstringlike, startswith, getheaders, closeable_response
from _HeadersUtil import is_html
from _Debug import getLogger
debug = getLogger("ClientCookie.cookies").debug
@@ -629,9 +629,8 @@
r.recv = r.read
fp = socket._fileobject(r, 'rb', -1)
- resp = urllib.addinfourl(fp, r.msg, req.get_full_url())
- resp.code = r.status
- resp.msg = r.reason
+ resp = closeable_response(fp, r.msg, req.get_full_url(),
+ r.status, r.reason)
return resp
Modified: wwwsearch/ClientCookie/trunk/functional_tests.py
==============================================================================
--- wwwsearch/ClientCookie/trunk/functional_tests.py (original)
+++ wwwsearch/ClientCookie/trunk/functional_tests.py Sun Feb 12 03:17:29 2006
@@ -51,11 +51,11 @@
install_opener(o)
try:
r = urlopen("http://wwwsearch.sf.net/cgi-bin/cookietest.cgi")
- except URLError, e:
- print e.read()
+ except urllib2.URLError, e:
+ #print e.read()
raise
data = r.read()
- print data
+ #print data
self.assert_(
string.find(data, "Your browser supports cookies!") >= 0)
self.assert_(len(cj) == 1)
More information about the wwwsearch-commits
mailing list