[Zope3-checkins] SVN: Zope3/trunk/src/zope/ Implemented a
WSGI-compliant server based on ZServer's HTTP server. Also
Stephan Richter
srichter at cosmos.phy.tufts.edu
Tue Apr 12 16:34:37 EDT 2005
Log message for revision 29956:
Implemented a WSGI-compliant server based on ZServer's HTTP server. Also
removed some duplication of the WSGI code.
Changed:
U Zope3/trunk/src/zope/app/server/configure.zcml
A Zope3/trunk/src/zope/app/server/wsgi.py
U Zope3/trunk/src/zope/app/wsgi/README.txt
U Zope3/trunk/src/zope/app/wsgi/__init__.py
U Zope3/trunk/src/zope/app/wsgi/tests.py
D Zope3/trunk/src/zope/publisher/tests/test_wsgi.py
D Zope3/trunk/src/zope/publisher/wsgi.py
D Zope3/trunk/src/zope/publisher/wsgi.txt
A Zope3/trunk/src/zope/server/http/wsgihttpserver.py
-=-
Modified: Zope3/trunk/src/zope/app/server/configure.zcml
===================================================================
--- Zope3/trunk/src/zope/app/server/configure.zcml 2005-04-12 20:32:33 UTC (rev 29955)
+++ Zope3/trunk/src/zope/app/server/configure.zcml 2005-04-12 20:34:35 UTC (rev 29956)
@@ -17,6 +17,12 @@
/>
<utility
+ name="WSGI-HTTP"
+ component=".wsgi.http"
+ provides=".servertype.IServerType"
+ />
+
+ <utility
name="FTP"
component=".ftp.server"
provides=".servertype.IServerType"
Copied: Zope3/trunk/src/zope/app/server/wsgi.py (from rev 29953, Zope3/branches/srichter-wsgi-zserver/src/zope/app/server/wsgi.py)
Property changes on: Zope3/trunk/src/zope/app/server/wsgi.py
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: Zope3/trunk/src/zope/app/wsgi/README.txt
===================================================================
--- Zope3/trunk/src/zope/app/wsgi/README.txt 2005-04-12 20:32:33 UTC (rev 29955)
+++ Zope3/trunk/src/zope/app/wsgi/README.txt 2005-04-12 20:34:35 UTC (rev 29956)
@@ -25,7 +25,7 @@
We can now initialize the application:
>>> from zope.app import wsgi
- >>> app = wsgi.PublisherApp(db)
+ >>> app = wsgi.WSGIPublisherApplication(db)
The callable ``app`` object accepts two positional arguments, the environment
and the function that initializes the response and returns a function with
Modified: Zope3/trunk/src/zope/app/wsgi/__init__.py
===================================================================
--- Zope3/trunk/src/zope/app/wsgi/__init__.py 2005-04-12 20:32:33 UTC (rev 29955)
+++ Zope3/trunk/src/zope/app/wsgi/__init__.py 2005-04-12 20:34:35 UTC (rev 29956)
@@ -77,7 +77,7 @@
self.wsgi_write(data)
-class PublisherApp(object):
+class WSGIPublisherApplication(object):
"""A WSGI application implemenation for the zope publisher
Instances of this class can be used as a WSGI application object.
@@ -105,8 +105,6 @@
publish(request)
- request.close()
-
# since the response is written using the WSGI ``write()`` callable
# return an empty iterable (see PEP 333).
return ""
Modified: Zope3/trunk/src/zope/app/wsgi/tests.py
===================================================================
--- Zope3/trunk/src/zope/app/wsgi/tests.py 2005-04-12 20:32:33 UTC (rev 29955)
+++ Zope3/trunk/src/zope/app/wsgi/tests.py 2005-04-12 20:34:35 UTC (rev 29956)
@@ -17,19 +17,13 @@
"""
import unittest
from zope.testing import doctest
-from zope.app.testing import setup, ztapi, placelesssetup
+from zope.app.testing import placelesssetup
-def setUp(test):
- placelesssetup.setUp(test)
-
-def tearDown(test):
- placelesssetup.tearDown(test)
-
-
def test_suite():
return unittest.TestSuite((
doctest.DocFileSuite('README.txt',
- setUp=setUp, tearDown=tearDown,
+ setUp=placelesssetup.setUp,
+ tearDown=placelesssetup.tearDown,
optionflags=doctest.NORMALIZE_WHITESPACE),
))
Deleted: Zope3/trunk/src/zope/publisher/tests/test_wsgi.py
===================================================================
--- Zope3/trunk/src/zope/publisher/tests/test_wsgi.py 2005-04-12 20:32:33 UTC (rev 29955)
+++ Zope3/trunk/src/zope/publisher/tests/test_wsgi.py 2005-04-12 20:34:35 UTC (rev 29956)
@@ -1,27 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2004 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""WSGI tests
-
-$Id$
-"""
-import unittest
-from zope.testing.doctestunit import DocTestSuite
-
-def test_suite():
- return unittest.TestSuite((
- DocTestSuite('zope.publisher.wsgi'),
- ))
-
-if __name__ == '__main__':
- unittest.main(defaultTest='test_suite')
Deleted: Zope3/trunk/src/zope/publisher/wsgi.py
===================================================================
--- Zope3/trunk/src/zope/publisher/wsgi.py 2005-04-12 20:32:33 UTC (rev 29955)
+++ Zope3/trunk/src/zope/publisher/wsgi.py 2005-04-12 20:34:35 UTC (rev 29956)
@@ -1,212 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2004 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""A WSGI Application wrapper for zope
-
-$Id$
-"""
-
-from zope.interface import implements
-from zope.publisher.publish import publish
-from zope.publisher.http import HTTPRequest
-from zope.publisher.interfaces.http import IHeaderOutput
-from zope.publisher.browser import BrowserRequest
-from zope.publisher.xmlrpc import XMLRPCRequest
-
-class WsgiOutput(object):
- """This class handles the output generated by
- the publisher. It is used to collect the headers
- and as an outstream to output the response body.
-
- When write is first called by the response, it initiates
- the reponse by invoking the WSGI start_response callable.
-
- Create a mock implementation of the wsgi write callable
- >>> from StringIO import StringIO
- >>> data = StringIO('')
- >>> def start_response(status, headers):
- ... data.write('status and headers.')
- ... return data.write
- ...
-
- create an instance
- >>> output = WsgiOutput(start_response)
-
- Set the response status
- >>> output.setResponseStatus("200", "OK")
- >>> output._statusString
- '200 OK'
-
- Set the headers as a mapping
- >>> output.setResponseHeaders({'a':'b', 'c':'d'})
-
- They must be returned as a list of tuples
- >>> output.getHeaders()
- [('a', 'b'), ('c', 'd')]
-
- calling setResponseHeaders again adds new values
- >>> output.setResponseHeaders({'x':'y', 'c':'d'})
- >>> h = output.getHeaders()
- >>> h.sort()
- >>> h
- [('a', 'b'), ('c', 'd'), ('x', 'y')]
-
- Headers that can potentially repeat are added using
- appendResponseHeaders
- >>> output.appendResponseHeaders(['foo: bar'])
- >>> h = output.getHeaders()
- >>> h.sort()
- >>> h
- [('a', 'b'), ('c', 'd'), ('foo', ' bar'), ('x', 'y')]
- >>> output.appendResponseHeaders(['foo: bar'])
- >>> h = output.getHeaders()
- >>> h.sort()
- >>> h
- [('a', 'b'), ('c', 'd'), ('foo', ' bar'), ('foo', ' bar'), ('x', 'y')]
-
- Headers containing a colon should also work
- >>> output.appendResponseHeaders(['my: brain:hurts'])
- >>> h = output.getHeaders()
- >>> h.sort()
- >>> h
- [('a', 'b'), ('c', 'd'), ('foo', ' bar'), \
-('foo', ' bar'), ('my', ' brain:hurts'), ('x', 'y')]
-
- The headers should not be written to the output
- >>> output.wroteResponseHeader()
- False
- >>> data.getvalue()
- ''
-
- now write something
- >>> output.write('Now for something')
-
- The headers should be sent and the data written to the stream
- >>> output.wroteResponseHeader()
- True
- >>> data.getvalue()
- 'status and headers.Now for something'
-
- calling write again the headers should not be sent again
- >>> output.write(' completly different!')
- >>> data.getvalue()
- 'status and headers.Now for something completly different!'
- """
-
- def __init__(self, start_response):
- self._headers = {}
- self._accumulatedHeaders = []
- self._statusString = ""
- self._headersSent = False
-
- self.wsgi_write = None
- self.start_response = start_response
-
- def setResponseStatus(self,status, reason):
- """Sets the status code and the accompanying message.
- """
- self._statusString = str(status)+' '+reason
-
- def setResponseHeaders(self, mapping):
- """Sets headers. The headers must be Correctly-Cased.
- """
- self._headers.update(mapping)
-
- def appendResponseHeaders(self, lst):
- """Sets headers that can potentially repeat.
-
- Takes a list of strings.
- """
- self._accumulatedHeaders.extend(lst)
-
- def wroteResponseHeader(self):
- """Returns a flag indicating whether the response
-
- header has already been sent.
- """
- return self._headersSent
-
- def setAuthUserName(self, name):
- """Sets the name of the authenticated user so the name can be logged.
- """
- pass
-
- def getHeaders(self):
- """return the response headers as a list of tuples according
- to the WSGI spec
- """
- response_headers = self._headers.items()
-
- accum = [ tuple(line.split(':',1)) for line in self._accumulatedHeaders]
-
- response_headers.extend(accum)
- return response_headers
-
-
- def write(self, data):
- """write the response.
- If the reponse has not begun, call the wsgi servers
- 'start_reponse' callable to begin the response
- """
- if not self._headersSent:
- self.wsgi_write = self.start_response(self._statusString,
- self.getHeaders())
- self._headersSent = True
-
- self.wsgi_write(data)
-
-
-class PublisherApp(object):
- """A WSGI application implemenation 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.
-
- """
-
-
- def __init__(self, publication):
- self.publication = publication
-
- def __call__(self, env, start_response,
- _browser_methods = ('GET', 'POST', 'HEAD'),
- ):
- """makes instances a WSGI callable application object
- """
-
- wsgi_output = WsgiOutput(start_response)
- input_stream = env['wsgi.input']
-
- method = env.get('REQUEST_METHOD', 'GET').upper()
- if method in _browser_methods:
- if (method == 'POST' and
- env.get('CONTENT_TYPE', '').startswith('text/xml')
- ):
- request = XMLRPCRequest(input_stream, wsgi_output, env)
- else:
- request = BrowserRequest(input_stream, wsgi_output, env)
- else:
- request = HTTPRequest(input_stream, wsgi_output, env)
-
- request.setPublication(self.publication)
- request.response.setHeaderOutput(wsgi_output)
-
- publish(request)
-
- request.close()
-
- # since the response is written using the WSGI write callable
- # return an empty iterable (see
- return ""
Deleted: Zope3/trunk/src/zope/publisher/wsgi.txt
===================================================================
--- Zope3/trunk/src/zope/publisher/wsgi.txt 2005-04-12 20:32:33 UTC (rev 29955)
+++ Zope3/trunk/src/zope/publisher/wsgi.txt 2005-04-12 20:34:35 UTC (rev 29956)
@@ -1,43 +0,0 @@
-=====================
-Zope WSGI Application
-=====================
-
-About
------
-This package contains a WSGI application for Zope.
-
-WSGI is the Python Web Server Gateway Interface, an
-upcoming PEP to standardize the interface between web servers
-and python applications to promote portability.
-
-For more information, refer to the WSGI specification: http://www.python.org/peps/pep-0333.html
-
-Usage
------
-To use Zope as a WSGI application, the following steps must be taken
-
-* configure and setup Zope
-
-* create an instance of ``zope.app.wsgi.PublisherApp`` must be created
- with a refernce to an open database
-
-* This instance must be set as the WSGI servers application object
-
-
-Example::
-
- from zope.app.server.main import setup, load_options
- from zope.app.wsgi import PublisherApp
-
- args = ["-C/path/to/zope.conf"]
- db = setup(load_options(args))
-
- my_app = PublisherApp(db)
-
- wsgi_server.set_app(my_app)
-
-This assumes, that Zope is available on the ``PYTHONPATH``.
-Note that you may have to edit ``zope.conf`` to provide
-an absolute path for ``site.zcml``.
-
-
Copied: Zope3/trunk/src/zope/server/http/wsgihttpserver.py (from rev 29953, Zope3/branches/srichter-wsgi-zserver/src/zope/server/http/wsgihttpserver.py)
Property changes on: Zope3/trunk/src/zope/server/http/wsgihttpserver.py
___________________________________________________________________
Name: svn:eol-style
+ native
More information about the Zope3-Checkins
mailing list