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', _______________________________________________ Zope-Checkins maillist - Zope-Checkins@zope.org http://mail.zope.org/mailman/listinfo/zope-checkins