[Zope-Checkins] SVN: Zope/trunk/ Launchpad #363780: preserve interfaces and class of cloned request.
Tres Seaver
tseaver at palladion.com
Sun Apr 19 16:41:20 EDT 2009
Log message for revision 99298:
Launchpad #363780: preserve interfaces and class of cloned request.
o Preserve response class as well.
Changed:
U Zope/trunk/doc/CHANGES.rst
U Zope/trunk/src/ZPublisher/HTTPRequest.py
U Zope/trunk/src/ZPublisher/tests/testHTTPRequest.py
-=-
Modified: Zope/trunk/doc/CHANGES.rst
===================================================================
--- Zope/trunk/doc/CHANGES.rst 2009-04-19 20:31:16 UTC (rev 99297)
+++ Zope/trunk/doc/CHANGES.rst 2009-04-19 20:41:20 UTC (rev 99298)
@@ -27,6 +27,8 @@
Bugs Fixed
++++++++++
+- Launchpad #363780: preserve request interfaces and class, as well as
+ response class, when cloning an HTTPRequest.
2.12.0a3 (2009-04-19)
---------------------
Modified: Zope/trunk/src/ZPublisher/HTTPRequest.py
===================================================================
--- Zope/trunk/src/ZPublisher/HTTPRequest.py 2009-04-19 20:31:16 UTC (rev 99297)
+++ Zope/trunk/src/ZPublisher/HTTPRequest.py 2009-04-19 20:41:20 UTC (rev 99298)
@@ -32,6 +32,8 @@
from zope.i18n.interfaces import IUserPreferredLanguages
from zope.i18n.locales import locales, LoadLocaleError
+from zope.interface import directlyProvidedBy
+from zope.interface import directlyProvides
from zope.interface import implements
from zope.publisher.base import DebugFlags
from zope.publisher.interfaces.browser import IBrowserRequest
@@ -268,9 +270,7 @@
if path[:vhbl] == vhbase:
path = path[vhbl:]
else:
- raise ValueError, (
- 'Url does not match virtual hosting context'
- )
+ raise ValueError('Url does not match virtual hosting context')
vrpp = other.get('VirtualRootPhysicalPath', ('',))
return list(vrpp) + map(unquote, path)
@@ -1150,7 +1150,7 @@
# match that of the current request), a ValueError will
# be raised.
if url.find(self.script) != 0:
- raise ValueError, 'Different namespace.'
+ raise ValueError('Different namespace.')
path = url[len(self.script):]
while path and path[0] == '/':
path = path[1:]
@@ -1201,8 +1201,13 @@
environ['REQUEST_METHOD'] = 'GET'
if self._auth:
environ['HTTP_AUTHORIZATION'] = self._auth
- clone = HTTPRequest(None, environ, HTTPResponse(), clean=1)
+ if self.response is not None:
+ response = self.response.__class__()
+ else:
+ response = None
+ clone = self.__class__(None, environ, response, clean=1)
clone['PARENTS'] = [self['PARENTS'][-1]]
+ directlyProvides(clone, *directlyProvidedBy(self))
return clone
def getHeader(self, name, default = None, literal = False):
Modified: Zope/trunk/src/ZPublisher/tests/testHTTPRequest.py
===================================================================
--- Zope/trunk/src/ZPublisher/tests/testHTTPRequest.py 2009-04-19 20:31:16 UTC (rev 99297)
+++ Zope/trunk/src/ZPublisher/tests/testHTTPRequest.py 2009-04-19 20:41:20 UTC (rev 99298)
@@ -921,6 +921,61 @@
self.assertEqual(request.getHeader('Not-existant', default='Whatever'),
'Whatever')
+ def test_clone_updates_method_to_GET(self):
+ request = self._makeOne(environ={'REQUEST_METHOD': 'POST'})
+ request['PARENTS'] = [object()]
+ clone = request.clone()
+ self.assertEqual(clone.method, 'GET')
+
+ def test_clone_keeps_preserves__auth(self):
+ request = self._makeOne()
+ request['PARENTS'] = [object()]
+ request._auth = 'foobar'
+ clone = request.clone()
+ self.assertEqual(clone._auth, 'foobar')
+
+ def test_clone_doesnt_re_clean_environ(self):
+ request = self._makeOne()
+ request.environ['HTTP_CGI_AUTHORIZATION'] = 'lalalala'
+ request['PARENTS'] = [object()]
+ clone = request.clone()
+ self.assertEqual(clone.environ['HTTP_CGI_AUTHORIZATION'], 'lalalala')
+
+ def test_clone_keeps_only_last_PARENT(self):
+ PARENTS = [object(), object()]
+ request = self._makeOne()
+ request['PARENTS'] = PARENTS
+ clone = request.clone()
+ self.assertEqual(clone['PARENTS'], PARENTS[1:])
+
+ def test_clone_preserves_response_class(self):
+ class DummyResponse:
+ pass
+ request = self._makeOne(None, TEST_ENVIRON.copy(), DummyResponse())
+ request['PARENTS'] = [object()]
+ clone = request.clone()
+ self.failUnless(isinstance(clone.response, DummyResponse))
+
+ def test_clone_preserves_request_subclass(self):
+ class SubRequest(self._getTargetClass()):
+ pass
+ request = SubRequest(None, TEST_ENVIRON.copy(), None)
+ request['PARENTS'] = [object()]
+ clone = request.clone()
+ self.failUnless(isinstance(clone, SubRequest))
+
+ def test_clone_preserves_direct_interfaces(self):
+ from zope.interface import directlyProvides
+ from zope.interface import Interface
+ class IFoo(Interface):
+ pass
+ request = self._makeOne()
+ request['PARENTS'] = [object()]
+ directlyProvides(request, IFoo)
+ clone = request.clone()
+ self.failUnless(IFoo.providedBy(clone))
+
+
TEST_ENVIRON = {
'CONTENT_TYPE': 'multipart/form-data; boundary=12345',
'REQUEST_METHOD': 'POST',
More information about the Zope-Checkins
mailing list