[Zope-Checkins] SVN: Zope/trunk/ HTTPResponse: for XML content the encoding specified within

Andreas Jung andreas at andreas-jung.com
Wed Dec 21 13:53:31 EST 2005


Log message for revision 40965:
  HTTPResponse: for XML content the encoding specified within
  the XML preamble is adjusted to the real encoding of the content
  as specified through the 'charset' within the content-type
  property.
  

Changed:
  U   Zope/trunk/doc/CHANGES.txt
  U   Zope/trunk/lib/python/ZPublisher/HTTPResponse.py
  U   Zope/trunk/lib/python/ZPublisher/tests/testHTTPResponse.py

-=-
Modified: Zope/trunk/doc/CHANGES.txt
===================================================================
--- Zope/trunk/doc/CHANGES.txt	2005-12-21 17:33:31 UTC (rev 40964)
+++ Zope/trunk/doc/CHANGES.txt	2005-12-21 18:53:31 UTC (rev 40965)
@@ -176,6 +176,12 @@
 
     Bugs Fixed
 
+      - HTTPResponse: for XML content the encoding specified within
+        the XML preamble is adjusted to the real encoding of the content
+        as specified through the 'charset' within the content-type
+        property.
+
+
       - Collector #1939: When running as a service, Zope could
         potentially collect too much log output filling the NT Event
         Log. When that happened, a 'print' during exception handling

Modified: Zope/trunk/lib/python/ZPublisher/HTTPResponse.py
===================================================================
--- Zope/trunk/lib/python/ZPublisher/HTTPResponse.py	2005-12-21 17:33:31 UTC (rev 40964)
+++ Zope/trunk/lib/python/ZPublisher/HTTPResponse.py	2005-12-21 18:53:31 UTC (rev 40965)
@@ -444,13 +444,26 @@
                                               r'charset=([-_0-9a-z]+' +
                                               r')(?:(?:\s*;)|\Z)',
                                               re.IGNORECASE)):
+
+        def fix_xml_preamble(body, encoding):
+            """ fixes the encoding in the XML preamble according
+                to the charset specified in the content-type header.
+            """
+
+            if body.startswith('<?xml'):
+                pos_right = body.find('?>')  # right end of the XML preamble
+                body = ('<?xml version="1.0" encoding="%s" ?>' % encoding) + body[pos_right+2:]
+            return body
+
         # Encode the Unicode data as requested
 
         if self.headers.has_key('content-type'):
             match = charset_re.match(self.headers['content-type'])
             if match:
                 encoding = match.group(1)
-                return body.encode(encoding)
+                body = body.encode(encoding)
+                body = fix_xml_preamble(body, encoding)
+                return body
             else:
 
                 ct = self.headers['content-type']
@@ -458,7 +471,9 @@
                     self.headers['content-type'] = '%s; charset=%s' % (ct, default_encoding)
 
         # Use the default character encoding
-        return body.encode(default_encoding,'replace')
+        body = body.encode(default_encoding,'replace')
+        body = fix_xml_preamble(body, default_encoding)
+        return body
 
     def setBase(self,base):
         """Set the base URL for the returned document.

Modified: Zope/trunk/lib/python/ZPublisher/tests/testHTTPResponse.py
===================================================================
--- Zope/trunk/lib/python/ZPublisher/tests/testHTTPResponse.py	2005-12-21 17:33:31 UTC (rev 40964)
+++ Zope/trunk/lib/python/ZPublisher/tests/testHTTPResponse.py	2005-12-21 18:53:31 UTC (rev 40965)
@@ -98,6 +98,14 @@
         self.assertEqual(response.headers.get('content-type'), 'application/foo; charset=utf-8')
         self.assertEqual(response.body, unicode('ärger', 'iso-8859-15').encode('utf-8'))
 
+    def test_XMLEncodingRecoding(self):
+        xml = u'<?xml version="1.0" encoding="iso-8859-15" ?>\n<foo><bar/></foo>'
+        response = self._makeOne(body=xml, headers={'content-type': 'application/foo; charset=utf-8'})
+        self.assertEqual('encoding="utf-8"' in response.body, True)
+        response = self._makeOne(body=xml, headers={'content-type': 'application/foo; charset=iso-8859-15'})
+        self.assertEqual('encoding="iso-8859-15"' in response.body, True)
+
+
 def test_suite():
     suite = unittest.TestSuite()
     suite.addTest(unittest.makeSuite(HTTPResponseTests, 'test'))



More information about the Zope-Checkins mailing list