[Zope3-checkins] SVN: Zope3/trunk/ The request's PATH_INFO variable is a unicode string now, so that

Bjorn Tillenius bjoti777 at student.liu.se
Tue Jun 1 16:51:46 EDT 2004


Log message for revision 25163:
The request's PATH_INFO variable is a unicode string now, so that
the error service doesn't bail out when unicode urls are used.



-=-
Modified: Zope3/trunk/doc/CHANGES.txt
===================================================================
--- Zope3/trunk/doc/CHANGES.txt	2004-06-01 20:32:54 UTC (rev 25162)
+++ Zope3/trunk/doc/CHANGES.txt	2004-06-01 20:51:45 UTC (rev 25163)
@@ -29,6 +29,9 @@
       - Changed ILocation interface: __name__ is not required anymore
         and its default is None.
 
+      - The request's PATH_INFO variable is a unicode string now, so that
+        the error service doesn't bail out when unicode urls are used.
+
     Restructuring
 
       - New api for getting sublocations and adapters for containers

Modified: Zope3/trunk/src/zope/app/errorservice/tests.py
===================================================================
--- Zope3/trunk/src/zope/app/errorservice/tests.py	2004-06-01 20:32:54 UTC (rev 25162)
+++ Zope3/trunk/src/zope/app/errorservice/tests.py	2004-06-01 20:51:45 UTC (rev 25163)
@@ -20,6 +20,7 @@
 from zope.app.errorservice import ErrorReportingService
 from zope.testing.cleanup import CleanUp
 from zope.exceptions.exceptionformatter import format_exception
+from zope.publisher.tests.httprequest import TestRequest
 
 
 class C1:
@@ -66,8 +67,24 @@
         self.assertEquals(tb_text,
                           errService.getLogEntryById(err_id)['tb_text'])
 
+    def test_ErrorLog_Unicode_urls(self):
+        # Emulate a unicode url, it gets encoded to utf-8 before it's passed
+        # to the request. Also add some unicode field to the request's
+        # environment
+        request = TestRequest(environ={'PATH_INFO': '/\xd1\x82',
+                                       'SOME_UNICODE': u'\u0441'})
+        errService = ErrorReportingService()
+        exc_info = C1().getAnErrorInfo()
+        errService.raising(exc_info, request=request)
+        getErrLog = errService.getLogEntries()
+        self.assertEquals(1, len(getErrLog))
 
+        tb_text = ''.join(format_exception(*exc_info, **{'as_html': 0}))
 
+        err_id =  getErrLog[0]['id']
+        self.assertEquals(tb_text,
+                          errService.getLogEntryById(err_id)['tb_text'])
+        
 
 def test_suite():
     loader=TestLoader()

Modified: Zope3/trunk/src/zope/publisher/http.py
===================================================================
--- Zope3/trunk/src/zope/publisher/http.py	2004-06-01 20:32:54 UTC (rev 25162)
+++ Zope3/trunk/src/zope/publisher/http.py	2004-06-01 20:51:45 UTC (rev 25163)
@@ -54,6 +54,7 @@
     # return an environment mapping which has been cleaned of
     # funny business such as REDIRECT_ prefixes added by Apache
     # or HTTP_CGI_AUTHORIZATION hacks.
+    # It also makes sure PATH_INFO is a unicode string.
     dict = {}
     for key, val in env.items():
         while key.startswith('REDIRECT_'):
@@ -61,6 +62,8 @@
         dict[key] = val
     if 'HTTP_CGI_AUTHORIZATION' in dict:
         dict['HTTP_AUTHORIZATION'] = dict.pop('HTTP_CGI_AUTHORIZATION')
+    if 'PATH_INFO' in dict:
+        dict['PATH_INFO'] = dict['PATH_INFO'].decode('utf-8')
     return dict
 
 # Possible HTTP status responses
@@ -364,18 +367,9 @@
             self._parseCookies(cookie_header, self._cookies)
 
     def __setupPath(self):
-        # The recommendation states that:
-        #
-        # Unless there is some compelling reason for a
-        # particular scheme to do otherwise, translating character sequences
-        # into UTF-8 (RFC 2279) [3] and then subsequently using the %HH
-        # encoding for unsafe octets is recommended.
-        #
-        # See: http://www.ietf.org/rfc/rfc2718.txt, Section 2.2.5
+        # PATH_INFO is unicode here, so setupPath_helper sets up the
+        # traversal stack correctly.
         self._setupPath_helper("PATH_INFO")
-        stack = self.getTraversalStack()
-        stack = [unquote(seg).decode('utf-8') for seg in stack]
-        self.setTraversalStack(stack)
 
     def supportsRetry(self):
         'See IPublisherRequest'

Modified: Zope3/trunk/src/zope/publisher/tests/test_http.py
===================================================================
--- Zope3/trunk/src/zope/publisher/tests/test_http.py	2004-06-01 20:32:54 UTC (rev 25162)
+++ Zope3/trunk/src/zope/publisher/tests/test_http.py	2004-06-01 20:51:45 UTC (rev 25163)
@@ -369,10 +369,13 @@
         self.assertEquals(deduceServerURL(), 'http://example.com')
 
     def testUnicodeURLs(self):
+        # The request expects PATH_INFO to be utf-8 encoded when it gets it.
         req = self._createRequest(
-            {'PATH_INFO': '/%C3%A4%C3%B6/%C3%BC%C3%9F/foo/bar.html'})
+            {'PATH_INFO': '/\xc3\xa4\xc3\xb6/\xc3\xbc\xc3\x9f/foo/bar.html'})
         self.assertEqual(req._traversal_stack,
                          [u'bar.html', u'foo', u'üß', u'äö'])
+        # the request should have converted PATH_INFO to unicode
+        self.assertEqual(req['PATH_INFO'], u'/äö/üß/foo/bar.html')
 
 
 class ConcreteHTTPTests(HTTPTests):

Modified: Zope3/trunk/src/zope/server/http/tests/test_httprequestparser.py
===================================================================
--- Zope3/trunk/src/zope/server/http/tests/test_httprequestparser.py	2004-06-01 20:32:54 UTC (rev 25162)
+++ Zope3/trunk/src/zope/server/http/tests/test_httprequestparser.py	2004-06-01 20:51:45 UTC (rev 25163)
@@ -63,7 +63,7 @@
 
     def testComplexGET(self):
         data = """\
-GET /foo/a+%2B%2F%3D%26a%3Aint?d=b+%2B%2F%3D%26b%3Aint&c+%2B%2F%3D%26c%3Aint=6 HTTP/8.4
+GET /foo/a+%2B%2F%C3%A4%3D%26a%3Aint?d=b+%2B%2F%3D%26b%3Aint&c+%2B%2F%3D%26c%3Aint=6 HTTP/8.4
 FirstName: mickey
 lastname: Mouse
 content-length: 10
@@ -80,8 +80,10 @@
                           'LASTNAME': 'Mouse',
                           'CONTENT_LENGTH': '10',
                           })
-        self.assertEqual(parser.path, '/foo/a++/=&a:int')
-        self.assertEqual(parser.query, 'd=b+%2B%2F%3D%26b%3Aint&c+%2B%2F%3D%26c%3Aint=6')
+        # path should be utf-8 encoded
+        self.assertEqual(parser.path, '/foo/a++/\xc3\xa4=&a:int')
+        self.assertEqual(parser.query,
+                         'd=b+%2B%2F%3D%26b%3Aint&c+%2B%2F%3D%26c%3Aint=6')
         self.assertEqual(parser.getBodyStream().getvalue(), 'Hello mick')
 
 




More information about the Zope3-Checkins mailing list