[Zope-Checkins] SVN: Zope/branches/regebro-wsgi_refactor/ A first attempt to tear the ZServer away from the ZPublisher, and put a wsgi

Lennart Regebro regebro at gmail.com
Wed Apr 26 10:49:51 EDT 2006


Log message for revision 67619:
  A first attempt to tear the ZServer away from the ZPublisher, and put a wsgi 
  interface inbetween.
  

Changed:
  A   Zope/branches/regebro-wsgi_refactor/
  U   Zope/branches/regebro-wsgi_refactor/lib/python/Testing/ZopeTestCase/framework.py
  U   Zope/branches/regebro-wsgi_refactor/lib/python/Testing/ZopeTestCase/testPlaceless.py
  U   Zope/branches/regebro-wsgi_refactor/lib/python/Testing/ZopeTestCase/testSkeleton.py
  U   Zope/branches/regebro-wsgi_refactor/lib/python/Testing/ZopeTestCase/threadutils.py
  U   Zope/branches/regebro-wsgi_refactor/lib/python/Testing/ZopeTestCase/zopedoctest/framework.py
  U   Zope/branches/regebro-wsgi_refactor/lib/python/Testing/ZopeTestCase/zopedoctest/testAuthHeaderTest.py
  U   Zope/branches/regebro-wsgi_refactor/lib/python/Testing/ZopeTestCase/zopedoctest/testWarningsTest.py
  U   Zope/branches/regebro-wsgi_refactor/lib/python/Testing/ZopeTestCase/zopedoctest/testZopeDocTest.py
  U   Zope/branches/regebro-wsgi_refactor/lib/python/ZPublisher/HTTPRequest.py
  U   Zope/branches/regebro-wsgi_refactor/lib/python/ZPublisher/Publish.py
  U   Zope/branches/regebro-wsgi_refactor/lib/python/ZServer/HTTPResponse.py
  U   Zope/branches/regebro-wsgi_refactor/lib/python/ZServer/HTTPServer.py
  U   Zope/branches/regebro-wsgi_refactor/lib/python/ZServer/PubCore/ZServerPublisher.py

-=-
Copied: Zope/branches/regebro-wsgi_refactor (from rev 67592, Zope/trunk)

Modified: Zope/branches/regebro-wsgi_refactor/lib/python/Testing/ZopeTestCase/framework.py
===================================================================
--- Zope/trunk/lib/python/Testing/ZopeTestCase/framework.py	2006-04-25 10:10:07 UTC (rev 67592)
+++ Zope/branches/regebro-wsgi_refactor/lib/python/Testing/ZopeTestCase/framework.py	2006-04-26 14:49:50 UTC (rev 67619)
@@ -43,7 +43,7 @@
   if __name__ == '__main__':
       framework()
 
-$Id:$
+$Id$
 """
 
 __version__ = '0.2.4'

Modified: Zope/branches/regebro-wsgi_refactor/lib/python/Testing/ZopeTestCase/testPlaceless.py
===================================================================
--- Zope/trunk/lib/python/Testing/ZopeTestCase/testPlaceless.py	2006-04-25 10:10:07 UTC (rev 67592)
+++ Zope/branches/regebro-wsgi_refactor/lib/python/Testing/ZopeTestCase/testPlaceless.py	2006-04-26 14:49:50 UTC (rev 67619)
@@ -12,7 +12,7 @@
 ##############################################################################
 """Placeless setup tests
 
-$Id:$
+$Id$
 """
 
 import os, sys

Modified: Zope/branches/regebro-wsgi_refactor/lib/python/Testing/ZopeTestCase/testSkeleton.py
===================================================================
--- Zope/trunk/lib/python/Testing/ZopeTestCase/testSkeleton.py	2006-04-25 10:10:07 UTC (rev 67592)
+++ Zope/branches/regebro-wsgi_refactor/lib/python/Testing/ZopeTestCase/testSkeleton.py	2006-04-26 14:49:50 UTC (rev 67619)
@@ -12,7 +12,7 @@
 ##############################################################################
 """Skeleton ZopeTestCase
 
-$Id:$
+$Id$
 """
 
 import os, sys

Modified: Zope/branches/regebro-wsgi_refactor/lib/python/Testing/ZopeTestCase/threadutils.py
===================================================================
--- Zope/trunk/lib/python/Testing/ZopeTestCase/threadutils.py	2006-04-25 10:10:07 UTC (rev 67592)
+++ Zope/branches/regebro-wsgi_refactor/lib/python/Testing/ZopeTestCase/threadutils.py	2006-04-26 14:49:50 UTC (rev 67619)
@@ -13,7 +13,7 @@
 """Parts of ZServer support are in this module so they can
 be imported more selectively.
 
-$Id: threadutils.py,v 1.6 2004/08/19 15:31:26 shh42 Exp $
+$Id$
 """
 
 from threading import Thread

Modified: Zope/branches/regebro-wsgi_refactor/lib/python/Testing/ZopeTestCase/zopedoctest/framework.py
===================================================================
--- Zope/trunk/lib/python/Testing/ZopeTestCase/zopedoctest/framework.py	2006-04-25 10:10:07 UTC (rev 67592)
+++ Zope/branches/regebro-wsgi_refactor/lib/python/Testing/ZopeTestCase/zopedoctest/framework.py	2006-04-26 14:49:50 UTC (rev 67619)
@@ -43,7 +43,7 @@
   if __name__ == '__main__':
       framework()
 
-$Id:$
+$Id$
 """
 
 __version__ = '0.2.4'

Modified: Zope/branches/regebro-wsgi_refactor/lib/python/Testing/ZopeTestCase/zopedoctest/testAuthHeaderTest.py
===================================================================
--- Zope/trunk/lib/python/Testing/ZopeTestCase/zopedoctest/testAuthHeaderTest.py	2006-04-25 10:10:07 UTC (rev 67592)
+++ Zope/branches/regebro-wsgi_refactor/lib/python/Testing/ZopeTestCase/zopedoctest/testAuthHeaderTest.py	2006-04-26 14:49:50 UTC (rev 67619)
@@ -12,7 +12,7 @@
 ##############################################################################
 """Test for auth_header
 
-$Id: testAuthHeaderTest.py,v 1.2 2005/03/26 18:07:08 shh42 Exp $
+$Id$
 """
 
 import os, sys

Modified: Zope/branches/regebro-wsgi_refactor/lib/python/Testing/ZopeTestCase/zopedoctest/testWarningsTest.py
===================================================================
--- Zope/trunk/lib/python/Testing/ZopeTestCase/zopedoctest/testWarningsTest.py	2006-04-25 10:10:07 UTC (rev 67592)
+++ Zope/branches/regebro-wsgi_refactor/lib/python/Testing/ZopeTestCase/zopedoctest/testWarningsTest.py	2006-04-26 14:49:50 UTC (rev 67619)
@@ -12,7 +12,7 @@
 ##############################################################################
 """Example doctest
 
-$Id: testWarningsTest.py,v 1.2 2005/03/26 18:07:08 shh42 Exp $
+$Id$
 """
 
 import os, sys

Modified: Zope/branches/regebro-wsgi_refactor/lib/python/Testing/ZopeTestCase/zopedoctest/testZopeDocTest.py
===================================================================
--- Zope/trunk/lib/python/Testing/ZopeTestCase/zopedoctest/testZopeDocTest.py	2006-04-25 10:10:07 UTC (rev 67592)
+++ Zope/branches/regebro-wsgi_refactor/lib/python/Testing/ZopeTestCase/zopedoctest/testZopeDocTest.py	2006-04-26 14:49:50 UTC (rev 67619)
@@ -12,7 +12,7 @@
 ##############################################################################
 """Example Zope doctest
 
-$Id: testZopeDocTest.py,v 1.2 2005/03/26 18:07:08 shh42 Exp $
+$Id$
 """
 
 import os, sys

Modified: Zope/branches/regebro-wsgi_refactor/lib/python/ZPublisher/HTTPRequest.py
===================================================================
--- Zope/trunk/lib/python/ZPublisher/HTTPRequest.py	2006-04-25 10:10:07 UTC (rev 67592)
+++ Zope/branches/regebro-wsgi_refactor/lib/python/ZPublisher/HTTPRequest.py	2006-04-26 14:49:50 UTC (rev 67619)
@@ -1484,12 +1484,12 @@
 
             else:
                 # Broken Cookie without = nor value.
- 		broken_p = paramlessre.match(text)
- 		if broken_p:
- 		    l = len(broken_p.group(1))
- 		    name = broken_p.group(2)
- 		    value = ''
-
+                broken_p = paramlessre.match(text)
+                if broken_p:
+                    l = len(broken_p.group(1))
+                    name = broken_p.group(2)
+                    value = ''
+                    
                 else:
                     return result
 

Modified: Zope/branches/regebro-wsgi_refactor/lib/python/ZPublisher/Publish.py
===================================================================
--- Zope/trunk/lib/python/ZPublisher/Publish.py	2006-04-25 10:10:07 UTC (rev 67592)
+++ Zope/branches/regebro-wsgi_refactor/lib/python/ZPublisher/Publish.py	2006-04-26 14:49:50 UTC (rev 67619)
@@ -21,7 +21,6 @@
 from maybe_lock import allocate_lock
 from mapply import mapply
 from zExceptions import Redirect
-from zope.app.publication.browser import setDefaultSkin
 
 class Retry(Exception):
     """Raise this to retry a request
@@ -57,7 +56,7 @@
 
 def set_default_authentication_realm(realm):
     global _default_realm
-    _default_realm = realm
+    _default_realm = realm        
 
 def publish(request, module_name, after_list, debug=0,
             # Optimize:
@@ -169,13 +168,125 @@
                 transactions_manager.abort()
             raise
 
+from HTTPRequest import HTTPRequest
+from ZServer.HTTPResponse import make_response
 
+class WSGIPublisherApplication(object):
+    """A WSGI application implementation for the zope publisher
+
+    Instances of this class can be used as a WSGI application object.
+
+    The class relies on a properly initialized request factory.
+    """
+    #implements(interfaces.IWSGIApplication)
+    def __init__(self, response):
+        self.response = response
+
+    def __call__(self, environ, start_response):
+        """See zope.app.wsgi.interfaces.IWSGIApplication"""
+        from ZServer.HTTPResponse import ZServerHTTPResponse, is_proxying_match, proxying_connection_re
+        from ZServer.medusa import http_server
+        from cStringIO import StringIO
+        
+        response = ZServerHTTPResponse(stdout=environ['wsgi.output'], stderr=StringIO())
+        response._http_version = environ['SERVER_PROTOCOL'].split('/')[1]
+        response._http_connection = environ['CONNECTION_TYPE']
+        response._server_version = environ['SERVER_SOFTWARE']
+
+        request = HTTPRequest(environ['wsgi.input'], environ, response)
+
+        # Let's support post-mortem debugging
+        handle_errors = environ.get('wsgi.handleErrors', True)
+        
+        try:
+            response = publish(request, 'Zope2', after_list=[None], 
+                               debug=handle_errors)
+        except SystemExit, v:
+            must_die=sys.exc_info()
+            request.response.exception(must_die)
+        except ImportError, v:
+            if isinstance(v, tuple) and len(v)==3: must_die=v
+            elif hasattr(sys, 'exc_info'): must_die=sys.exc_info()
+            else: must_die = SystemExit, v, sys.exc_info()[2]
+            request.response.exception(1, v)
+        except:
+            request.response.exception()
+            status=response.getStatus()
+
+        if response:
+            # Start the WSGI server response
+            start_response(response.getHeader('status'), 
+                           response.headers.items())
+            result=str(response)
+        # Return the result body iterable.
+        request.close()
+        #response._finish(0)
+        return (result,)
+    
+
+def fakeWrite(body):
+    raise NotImplementedError(
+        "Zope 2's HTTP Server does not support the WSGI write() function.")
+
 def publish_module_standard(module_name,
                    stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr,
                    environ=os.environ, debug=0, request=None, response=None):
+    # The WSGI way!
+
+    def wsgi_start_response(status,response_headers,exc_info=None):
+        # I don't understand what to do here. Start writing? At what?
+        return fakeWrite
+
     must_die=0
     status=200
     after_list=[None]
+    if request is None:
+        env = environ.copy()
+    else:
+        env = request
+        
+    env['wsgi.input']        = sys.stdin
+    env['wsgi.errors']       = sys.stderr
+    env['wsgi.version']      = (1,0)
+    env['wsgi.multithread']  = True
+    env['wsgi.multiprocess'] = True
+    env['wsgi.run_once']     = True
+    env['wsgi.url_scheme']   = env['SERVER_PROTOCOL'].split('/')[0]
+    if not env.has_key('wsgi.output'):
+        env['wsgi.output'] = stdout
+
+    application = WSGIPublisherApplication(None)
+    body = application(env, wsgi_start_response)
+    env['wsgi.output'].write(body[0])
+    env['wsgi.output'].close()
+        
+    # The module defined a post-access function, call it
+    if after_list[0] is not None: after_list[0]()
+
+    if must_die:
+        # Try to turn exception value into an exit code.
+        try:
+            if hasattr(must_die[1], 'code'):
+                code = must_die[1].code
+            else: code = int(must_die[1])
+        except:
+            code = must_die[1] and 1 or 0
+        if hasattr(request.response, '_requestShutdown'):
+            request.response._requestShutdown(code)
+
+        try: raise must_die[0], must_die[1], must_die[2]
+        finally: must_die=None
+
+    return status
+
+
+
+def publish_module_standard_old(module_name,
+                   stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr,
+                   environ=os.environ, debug=0, request=None, response=None):
+    must_die=0
+    status=200
+    after_list=[None]
     try:
         try:
             if response is None:

Modified: Zope/branches/regebro-wsgi_refactor/lib/python/ZServer/HTTPResponse.py
===================================================================
--- Zope/trunk/lib/python/ZServer/HTTPResponse.py	2006-04-25 10:10:07 UTC (rev 67592)
+++ Zope/branches/regebro-wsgi_refactor/lib/python/ZServer/HTTPResponse.py	2006-04-26 14:49:50 UTC (rev 67619)
@@ -194,7 +194,7 @@
 
     _retried_response = None
 
-    def _finish(self):
+    def _finish(self, close_output=1):
         if self._retried_response:
             try:
                 self._retried_response._finish()
@@ -209,7 +209,8 @@
             self._tempfile=None
 
         stdout.finish(self)
-        stdout.close()
+        if close_output:
+            stdout.close()
 
         self.stdout=None # need to break cycle?
         self._request=None
@@ -318,7 +319,6 @@
 def make_response(request, headers):
     "Simple http response factory"
     # should this be integrated into the HTTPResponse constructor?
-
     response=ZServerHTTPResponse(stdout=ChannelPipe(request), stderr=StringIO())
     response._http_version=request.version
     if request.version=='1.0' and is_proxying_match(request.request):

Modified: Zope/branches/regebro-wsgi_refactor/lib/python/ZServer/HTTPServer.py
===================================================================
--- Zope/trunk/lib/python/ZServer/HTTPServer.py	2006-04-25 10:10:07 UTC (rev 67592)
+++ Zope/branches/regebro-wsgi_refactor/lib/python/ZServer/HTTPServer.py	2006-04-26 14:49:50 UTC (rev 67619)
@@ -261,13 +261,31 @@
             s=0
         DebugLogger.log('I', id(request), s)
 
+        #import pdb;pdb.set_trace()
         env=self.get_environment(request)
-        zresponse=make_response(request,env)
-        if self._force_connection_close:
-            zresponse._http_connection = 'close'
-        zrequest=HTTPRequest(sin, env, zresponse)
+        from HTTPResponse import ChannelPipe, is_proxying_match, proxying_connection_re
+        env['wsgi.output'] = ChannelPipe(request)
+        version = request.version
+        if version=='1.0' and is_proxying_match(request.request):
+            # a request that was made as if this zope was an http 1.0 proxy.
+            # that means we have to use some slightly different http
+            # headers to manage persistent connections.
+            connection_re = proxying_connection_re
+        else:
+            # a normal http request
+            connection_re = CONNECTION
+        
+        env['http_connection'] = get_header(connection_re,
+                                                           request.header).lower()
+        env['server_version']=request.channel.server.SERVER_IDENT
+    
+        
+        #zresponse=make_response(request,env)
+        #if self._force_connection_close:
+            #zresponse._http_connection = 'close'
+        #zrequest=HTTPRequest(sin, env, zresponse)
         request.channel.current_request=None
-        request.channel.queue.append((self.module_name, zrequest, zresponse))
+        request.channel.queue.append((self.module_name, env, None))
         request.channel.work()
 
     def status(self):

Modified: Zope/branches/regebro-wsgi_refactor/lib/python/ZServer/PubCore/ZServerPublisher.py
===================================================================
--- Zope/trunk/lib/python/ZServer/PubCore/ZServerPublisher.py	2006-04-25 10:10:07 UTC (rev 67592)
+++ Zope/branches/regebro-wsgi_refactor/lib/python/ZServer/PubCore/ZServerPublisher.py	2006-04-26 14:49:50 UTC (rev 67619)
@@ -22,5 +22,5 @@
                     request=request,
                     response=response)
             finally:
-                response._finish()
+                #response._finish()
                 request=response=None



More information about the Zope-Checkins mailing list