[Checkins] SVN: zope.server/branches/achapman-exc-info/src/zope/server/http/ 1. Reset "response_headers" in addition to "accumulated_headers".

Satchidanand Haridas satchit at zope.com
Tue May 17 17:53:01 EDT 2011


Log message for revision 121703:
  1. Reset "response_headers" in addition to "accumulated_headers".
  
  2. Make code comply with DRY.
  
  

Changed:
  U   zope.server/branches/achapman-exc-info/src/zope/server/http/tests/test_wsgiserver.py
  U   zope.server/branches/achapman-exc-info/src/zope/server/http/wsgihttpserver.py

-=-
Modified: zope.server/branches/achapman-exc-info/src/zope/server/http/tests/test_wsgiserver.py
===================================================================
--- zope.server/branches/achapman-exc-info/src/zope/server/http/tests/test_wsgiserver.py	2011-05-17 17:59:26 UTC (rev 121702)
+++ zope.server/branches/achapman-exc-info/src/zope/server/http/tests/test_wsgiserver.py	2011-05-17 21:53:01 UTC (rev 121703)
@@ -348,7 +348,10 @@
             status = None
             reason = None
             response = []
-            accumulated_headers = []
+            accumulated_headers = None
+            def __init__(self):
+                self.accumulated_headers = []
+                self.response_headers = {}
             getCGIEnvironment = lambda _: {}
             class request_data:
                 getBodyStream = lambda _: StringIO.StringIO()
@@ -374,6 +377,7 @@
         orig_app = self.server.application
         self.server.application, task = self._getFakeAppAndTask()
         task.accumulated_headers = ['header1', 'header2']
+        task.accumulated_headers = {'key1': 'value1', 'key2': 'value2'}
 
         self.server.executeRequest(task)
 
@@ -382,6 +386,9 @@
         # any headers written before are cleared and
         # only the most recent one is added.
         self.assertEqual(task.accumulated_headers, ['Content-type: text/plain'])
+        # response headers are cleared. They'll be rebuilt from
+        # accumulated_headers in the prepareResponseHeaders method
+        self.assertEqual(task.response_headers, {})
 
         self.server.application = orig_app
 

Modified: zope.server/branches/achapman-exc-info/src/zope/server/http/wsgihttpserver.py
===================================================================
--- zope.server/branches/achapman-exc-info/src/zope/server/http/wsgihttpserver.py	2011-05-17 17:59:26 UTC (rev 121702)
+++ zope.server/branches/achapman-exc-info/src/zope/server/http/wsgihttpserver.py	2011-05-17 21:53:01 UTC (rev 121703)
@@ -26,6 +26,31 @@
         "Zope 3's HTTP Server does not support the WSGI write() function.")
 
 
+def curriedStartResponse(task):
+    def start_response(status, headers, exc_info=None):
+        if task.wroteResponseHeader() and not exc_info:
+            raise AssertionError("start_response called a second time "
+                                 "without providing exc_info.")
+        if exc_info:
+            try:
+                if task.wroteResponseHeader():
+                    raise exc_info[0], exc_info[1], exc_info[2]
+                else:
+                    # As per WSGI spec existing headers must be cleared
+                    task.accumulated_headers = None
+                    task.response_headers = {}
+            finally:
+                exc_info = None
+        # Prepare the headers for output
+        status, reason = re.match('([0-9]*) (.*)', status).groups()
+        task.setResponseStatus(status, reason)
+        task.appendResponseHeaders(['%s: %s' % i for i in headers])
+
+        # Return the write method used to write the response data.
+        return fakeWrite
+    return start_response
+
+
 class WSGIHTTPServer(HTTPServer):
     """Zope Publisher-specific WSGI-compliant HTTP Server"""
 
@@ -76,33 +101,8 @@
         """Overrides HTTPServer.executeRequest()."""
         env = self._constructWSGIEnvironment(task)
 
-        def start_response(status, headers, exc_info=None):
-            if task.wroteResponseHeader() and not exc_info:
-                raise AssertionError("start_response called a second time "
-                                     "without providing exc_info.")
-            if exc_info:
-                try:
-                    if task.wroteResponseHeader():
-                        # higher levels will catch and handle raised exception:
-                        # 1. "service" method in httptask.py
-                        # 2. "service" method in severchannelbase.py
-                        # 3. "handlerThread" method in taskthreads.py
-                        raise exc_info[0], exc_info[1], exc_info[2]
-                    else:
-                        # As per WSGI spec existing headers must be cleared
-                        task.accumulated_headers = None
-                finally:
-                    exc_info = None
-            # Prepare the headers for output
-            status, reason = re.match('([0-9]*) (.*)', status).groups()
-            task.setResponseStatus(status, reason)
-            task.appendResponseHeaders(['%s: %s' % i for i in headers])
-
-            # Return the write method used to write the response data.
-            return fakeWrite
-
         # Call the application to handle the request and write a response
-        result = self.application(env, start_response)
+        result = self.application(env, curriedStartResponse(task))
 
         # By iterating manually at this point, we execute task.write()
         # multiple times, allowing partial data to be sent.
@@ -118,30 +118,9 @@
         env = self._constructWSGIEnvironment(task)
         env['wsgi.handleErrors'] = False
 
-        def start_response(status, headers, exc_info=None):
-            if task.wroteResponseHeader() and not exc_info:
-                raise AssertionError("start_response called a second time "
-                                     "without providing exc_info.")
-            if exc_info:
-                try:
-                    if task.wroteResponseHeader():
-                        raise exc_info[0], exc_info[1], exc_info[2]
-                    else:
-                        # As per WSGI spec existing headers must be cleared
-                        task.accumulated_headers = None
-                finally:
-                    exc_info = None
-            # Prepare the headers for output
-            status, reason = re.match('([0-9]*) (.*)', status).groups()
-            task.setResponseStatus(status, reason)
-            task.appendResponseHeaders(['%s: %s' % i for i in headers])
-
-            # Return the write method used to write the response data.
-            return fakeWrite
-
         # Call the application to handle the request and write a response
         try:
-            result = self.application(env, start_response)
+            result = self.application(env, curriedStartResponse(task))
             # By iterating manually at this point, we execute task.write()
             # multiple times, allowing partial data to be sent.
             for value in result:



More information about the checkins mailing list