[Zope3-checkins] SVN: Zope3/trunk/ Merging Tarek's and Andreas' work on making the HTTP sub-protocols

Stephan Richter srichter at cosmos.phy.tufts.edu
Tue Oct 11 19:09:36 EDT 2005


Log message for revision 39083:
  Merging Tarek's and Andreas' work on making the HTTP sub-protocols 
  pluggable. This will make Jim Washington, who wrote the JSON server, 
  really happy. :-)
  
  

Changed:
  U   Zope3/trunk/doc/CHANGES.txt
  U   Zope3/trunk/src/zope/app/configure.zcml
  U   Zope3/trunk/src/zope/app/onlinehelp/__init__.py
  U   Zope3/trunk/src/zope/app/onlinehelp/onlinehelp.py
  U   Zope3/trunk/src/zope/app/publication/configure.zcml
  U   Zope3/trunk/src/zope/app/publication/ftests.py
  U   Zope3/trunk/src/zope/app/publication/httpfactory.py
  A   Zope3/trunk/src/zope/app/publication/httpfactory.txt
  U   Zope3/trunk/src/zope/app/publication/interfaces.py
  A   Zope3/trunk/src/zope/app/publication/meta.zcml
  A   Zope3/trunk/src/zope/app/publication/metaconfigure.py
  A   Zope3/trunk/src/zope/app/publication/metadirectives.py
  A   Zope3/trunk/src/zope/app/publication/requestpublicationfactories.py
  A   Zope3/trunk/src/zope/app/publication/requestpublicationregistry.py
  UU  Zope3/trunk/src/zope/app/publication/tests/test_browserpublication.py
  _U  Zope3/trunk/src/zope/app/publication/tests/test_http.py
  UU  Zope3/trunk/src/zope/app/publication/tests/test_httpfactory.py
  A   Zope3/trunk/src/zope/app/publication/tests/test_requestpublicationfactories.py
  A   Zope3/trunk/src/zope/app/publication/tests/test_requestpublicationregistry.py
  _U  Zope3/trunk/src/zope/app/publication/tests/test_simplecomponenttraverser.py
  _U  Zope3/trunk/src/zope/app/publication/tests/test_xmlrpcpublication.py
  _U  Zope3/trunk/src/zope/app/publication/tests/test_zopepublication.py
  U   Zope3/trunk/src/zope/app/publication/zopepublication.py
  U   Zope3/trunk/src/zope/app/testing/tests.py
  U   Zope3/trunk/src/zope/app/wsgi/tests.py

-=-
Modified: Zope3/trunk/doc/CHANGES.txt
===================================================================
--- Zope3/trunk/doc/CHANGES.txt	2005-10-11 22:46:43 UTC (rev 39082)
+++ Zope3/trunk/doc/CHANGES.txt	2005-10-11 23:09:36 UTC (rev 39083)
@@ -12,9 +12,10 @@
 
       - The ZServer has been replaced with the Twisted server. The Twisted
         server supports all that the ZServer supporting has well has HTTP over
-        SSL natively and SFTP (disabled for now because of error handling problems).
-        Also in the future it brings a better chance of other non-HTTP related
-        protocols from being implemented for Zope3, like SMTP-in and IMAP.
+        SSL natively and SFTP (disabled for now because of error handling
+        problems).  Also in the future it brings a better chance of other
+        non-HTTP related protocols from being implemented for Zope3, like
+        SMTP-in and IMAP.
 
       - Added modified description for sequence-like interfaces.
 
@@ -79,7 +80,7 @@
 
           zope.i18nmessageid.Message{Factory}
 
-        instead of 
+        instead of
 
           zope.i18nmessageid.MessageID{Factory}
 
@@ -93,6 +94,15 @@
 
         Zope itself now uses immutable messages everywhere.
 
+      - The publisher machinery is now completely pluggable. Publishers can be
+        registered and configured through ZCML (using the new 'publisher' ZCML
+        directive.  see zope/app/publication/configure.zcml). Publishers are
+        registered for a sequence of request methods and a configurable list
+        of mimetypes.  To register multiple publishers for the same request
+        method and the same mimetype (e.g. POST+text/xml: SOAP, XMLRPC)
+        publishers can be priorized and publishers can introspect the request
+        environment to decide if they can handle a request or not.
+
     Bug Fixes
 
       - Fixed issue #450: ignore python level CookieError and report them
@@ -113,8 +123,12 @@
     Much thanks to everyone who contributed to this release:
 
       Stephan Richter, Roger Ineichen, Marius Gedminas, Julien Anguenot, Benji
+<<<<<<< .working
       York, Gary Poster, Jim Fulton, Michael Kerrin, Torsten Kurbad,
       Philipp von Weitershausen
+=======
+      York, Gary Poster, Jim Fulton, Tarek Ziadé, Andreas Jung
+>>>>>>> .merge-right.r39082
 
     Note: If you are not listed and contributed, please add yourself. This
           note will be deleted before the release.

Modified: Zope3/trunk/src/zope/app/configure.zcml
===================================================================
--- Zope3/trunk/src/zope/app/configure.zcml	2005-10-11 22:46:43 UTC (rev 39082)
+++ Zope3/trunk/src/zope/app/configure.zcml	2005-10-11 23:09:36 UTC (rev 39083)
@@ -30,7 +30,11 @@
   <include package="zope.app.container" />
 
   <include package="zope.app.publisher" />
+
+  <include package="zope.app.publication" file="meta.zcml" />
   <include package="zope.app.publication" />
+
+
   <include package="zope.app.traversing" />
   <include package="zope.app.pagetemplate" />
   <include package=".generations" />

Modified: Zope3/trunk/src/zope/app/onlinehelp/__init__.py
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/__init__.py	2005-10-11 22:46:43 UTC (rev 39082)
+++ Zope3/trunk/src/zope/app/onlinehelp/__init__.py	2005-10-11 23:09:36 UTC (rev 39083)
@@ -13,7 +13,7 @@
 ##############################################################################
 """OnlineHelp System.
 
-Create the global `OnlineHelp` instance. 
+Create the global `OnlineHelp` instance.
 
 $Id$
 """

Modified: Zope3/trunk/src/zope/app/onlinehelp/onlinehelp.py
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/onlinehelp.py	2005-10-11 22:46:43 UTC (rev 39082)
+++ Zope3/trunk/src/zope/app/onlinehelp/onlinehelp.py	2005-10-11 23:09:36 UTC (rev 39083)
@@ -127,7 +127,6 @@
         if class_ is None:
             class_ = OnlineHelpTopic
 
-
         # Create topic base on the custom class or OnlinHelpTopic
         topic = class_(id, title, doc_path, parent_path, interface, view)
 

Modified: Zope3/trunk/src/zope/app/publication/configure.zcml
===================================================================
--- Zope3/trunk/src/zope/app/publication/configure.zcml	2005-10-11 22:46:43 UTC (rev 39082)
+++ Zope3/trunk/src/zope/app/publication/configure.zcml	2005-10-11 23:09:36 UTC (rev 39083)
@@ -10,4 +10,36 @@
       permission="zope.Public"
       />
 
+  <publisher
+      name="SOAP"
+      factory=".requestpublicationfactories.SOAPFactory"
+      methods="POST"
+      mimetypes="text/xml"
+      priority="30"
+      />
+
+  <publisher
+      name="XMLRPC"
+      factory=".requestpublicationfactories.XMLRPCFactory"
+      methods="POST"
+      mimetypes="text/xml"
+      priority="20"
+      />
+
+  <publisher
+      name="BROWSER"
+      factory=".requestpublicationfactories.BrowserFactory"
+      methods="GET POST HEAD"
+      mimetypes="*"
+      priority="10"
+      />
+
+  <publisher
+      name="HTTP"
+      factory=".requestpublicationfactories.HTTPFactory"
+      methods="*"
+      mimetypes="*"
+      priority="0"
+      />
+
 </configure>

Modified: Zope3/trunk/src/zope/app/publication/ftests.py
===================================================================
--- Zope3/trunk/src/zope/app/publication/ftests.py	2005-10-11 22:46:43 UTC (rev 39082)
+++ Zope3/trunk/src/zope/app/publication/ftests.py	2005-10-11 23:09:36 UTC (rev 39083)
@@ -22,6 +22,7 @@
     return unittest.TestSuite((
         functional.FunctionalDocFileSuite('notfound.txt'),
         functional.FunctionalDocFileSuite('methodnotallowed.txt'),
+        functional.FunctionalDocFileSuite('httpfactory.txt'),
         ))
 
 if __name__ == '__main__':

Modified: Zope3/trunk/src/zope/app/publication/httpfactory.py
===================================================================
--- Zope3/trunk/src/zope/app/publication/httpfactory.py	2005-10-11 22:46:43 UTC (rev 39082)
+++ Zope3/trunk/src/zope/app/publication/httpfactory.py	2005-10-11 23:09:36 UTC (rev 39083)
@@ -17,44 +17,24 @@
 """
 __docformat__ = 'restructuredtext'
 
-from zope import component, interface
+from zope import interface
 
-from zope.publisher.http import HTTPRequest
-from zope.publisher.browser import BrowserRequest
 from zope.publisher.interfaces.browser import IBrowserRequest
-from zope.publisher.xmlrpc import XMLRPCRequest
 
 from zope.app.publication import interfaces
-from zope.app.publication.http import HTTPPublication
-from zope.app.publication.browser import BrowserPublication, setDefaultSkin
-from zope.app.publication.xmlrpc import XMLRPCPublication
-from zope.app.publication.soap import SOAPPublication
+from zope.app.publication.browser import setDefaultSkin
+from zope.app.publication.requestpublicationregistry import factoryRegistry
 
 
 def chooseClasses(method, environment):
-    if method in ('GET', 'POST', 'HEAD'):
-        content_type = environment.get('CONTENT_TYPE', '')
-        if method == 'POST' and content_type.startswith('text/xml'):
-            soap_req = component.queryUtility(interfaces.ISOAPRequestFactory)
-            if environment.get('HTTP_SOAPACTION') and soap_req is not None:
-                request_class = soap_req
-                publication_class = SOAPPublication
-            else:
-                request_class = component.queryUtility(
-                    interfaces.IXMLRPCRequestFactory, default=XMLRPCRequest)
-                publication_class = XMLRPCPublication
-        else:
-            request_class = component.queryUtility(
-                interfaces.IBrowserRequestFactory, default=BrowserRequest)
-            publication_class = BrowserPublication
-    else:
-        request_class = component.queryUtility(
-            interfaces.IHTTPRequestFactory, default=HTTPRequest)
-        publication_class = HTTPPublication
+    """Given the method and environment, choose the correct request and
+    publication factort."""
+    content_type = environment.get('CONTENT_TYPE', '')
+    factory = factoryRegistry.lookup(method, content_type, environment)
+    request_class, publication = factory()
+    return request_class, publication
 
-    return request_class, publication_class
 
-
 class HTTPPublicationRequestFactory(object):
     interface.implements(interfaces.IPublicationRequestFactory)
 

Copied: Zope3/trunk/src/zope/app/publication/httpfactory.txt (from rev 39082, Zope3/branches/ajung-target-requestpublication-next-try-branch/src/zope/app/publication/httpfactory.txt)

Modified: Zope3/trunk/src/zope/app/publication/interfaces.py
===================================================================
--- Zope3/trunk/src/zope/app/publication/interfaces.py	2005-10-11 22:46:43 UTC (rev 39082)
+++ Zope3/trunk/src/zope/app/publication/interfaces.py	2005-10-11 23:09:36 UTC (rev 39083)
@@ -82,3 +82,38 @@
     /.  In particular, if the content included HTML, relative links in
     the HTML are relative to the container the content is in.
     """
+
+
+class IRequestPublicationFactory(interface.Interface):
+    """ request-publication factory """
+
+    def canHandle(environment):
+        """ returns True if it can handle the request,
+            otherwise False. 'environment' can be used by the factory 
+            to make a decision based on the HTTP headers.
+        """
+
+    def __call__():
+        """ returns a tuple (request, publication) """
+
+class IRequestPublicationRegistry(interface.Interface):
+    """ A registry to lookup a RequestPublicationFactory by
+        request method + mime-type. Multiple factories can be configured
+        for the same method+mimetype. The factory itself can introspect
+        the environment to decide if it can handle the request as given
+        by the environment or not. Factories are sorted in the order
+        of their registration in ZCML.
+    """
+
+    def register(method, mimetype, name, priority, factory):
+        """ registers a factory for method+mimetype """
+
+    def lookup(method, mimetype, environment):
+        """ Lookup a factory for a given method+mimetype and a 
+            environment. 
+        """
+
+    def getFactoriesFor(method, mimetype):
+        """ return the internal datastructure representing the configured
+            factories (basically for testing, not for introspection)
+        """

Copied: Zope3/trunk/src/zope/app/publication/meta.zcml (from rev 39082, Zope3/branches/ajung-target-requestpublication-next-try-branch/src/zope/app/publication/meta.zcml)

Copied: Zope3/trunk/src/zope/app/publication/metaconfigure.py (from rev 39082, Zope3/branches/ajung-target-requestpublication-next-try-branch/src/zope/app/publication/metaconfigure.py)

Copied: Zope3/trunk/src/zope/app/publication/metadirectives.py (from rev 39082, Zope3/branches/ajung-target-requestpublication-next-try-branch/src/zope/app/publication/metadirectives.py)

Copied: Zope3/trunk/src/zope/app/publication/requestpublicationfactories.py (from rev 39082, Zope3/branches/ajung-target-requestpublication-next-try-branch/src/zope/app/publication/requestpublicationfactories.py)

Copied: Zope3/trunk/src/zope/app/publication/requestpublicationregistry.py (from rev 39082, Zope3/branches/ajung-target-requestpublication-next-try-branch/src/zope/app/publication/requestpublicationregistry.py)

Modified: Zope3/trunk/src/zope/app/publication/tests/test_browserpublication.py
===================================================================
--- Zope3/trunk/src/zope/app/publication/tests/test_browserpublication.py	2005-10-11 22:46:43 UTC (rev 39082)
+++ Zope3/trunk/src/zope/app/publication/tests/test_browserpublication.py	2005-10-11 23:09:36 UTC (rev 39083)
@@ -13,7 +13,7 @@
 ##############################################################################
 """Browser Publication Tests
 
-$Id$
+$Id: test_browserpublication.py 38357 2005-09-07 20:14:34Z srichter $
 """
 import unittest
 from zope.testing import doctest
@@ -289,6 +289,21 @@
 
 class HTTPPublicationRequestFactoryTests(BasePublicationTests):
 
+    def setUp(self):
+        super(BasePublicationTests, self).setUp()
+        from zope.app.publication.requestpublicationregistry import \
+             factoryRegistry
+        from zope.app.publication.requestpublicationfactories \
+            import SOAPFactory, XMLRPCFactory, HTTPFactory, BrowserFactory
+
+        factoryRegistry.register('*', '*', 'HTTP', 0, HTTPFactory())
+        factoryRegistry.register('POST', 'text/xml', 'SOAP', 20, SOAPFactory())
+        factoryRegistry.register('POST', 'text/xml', 'XMLRPC', 10,
+                                 XMLRPCFactory())
+        factoryRegistry.register('GET', '*', 'BROWSER', 10, BrowserFactory())
+        factoryRegistry.register('POST', '*', 'BROWSER', 10, BrowserFactory())
+        factoryRegistry.register('HEAD', '*', 'BROWSER', 10, BrowserFactory())
+
     def testGetBackSamePublication(self):
         factory = HTTPPublicationRequestFactory(db=None)
         args = (None, {})


Property changes on: Zope3/trunk/src/zope/app/publication/tests/test_browserpublication.py
___________________________________________________________________
Name: svn:keywords
   - Id
   + __init__.py


Property changes on: Zope3/trunk/src/zope/app/publication/tests/test_http.py
___________________________________________________________________
Name: svn:keywords
   - Id
   + __init__.py

Modified: Zope3/trunk/src/zope/app/publication/tests/test_httpfactory.py
===================================================================
--- Zope3/trunk/src/zope/app/publication/tests/test_httpfactory.py	2005-10-11 22:46:43 UTC (rev 39082)
+++ Zope3/trunk/src/zope/app/publication/tests/test_httpfactory.py	2005-10-11 23:09:36 UTC (rev 39083)
@@ -13,7 +13,7 @@
 ##############################################################################
 """Tests for the HTTP Publication Request Factory.
 
-$Id$
+$Id: test_httpfactory.py 38357 2005-09-07 20:14:34Z srichter $
 """
 from unittest import TestCase, TestSuite, main, makeSuite
 
@@ -31,6 +31,9 @@
 from zope.app.publication.xmlrpc import XMLRPCPublication
 from zope.app.testing import ztapi
 from zope.app.publication import interfaces
+from zope.app.publication.requestpublicationregistry import factoryRegistry
+from zope.app.publication.requestpublicationfactories import \
+     HTTPFactory, SOAPFactory, BrowserFactory, XMLRPCFactory
 
 class DummyRequestFactory(object):
     def __call__(self, input_stream, env):
@@ -53,6 +56,16 @@
             'GATEWAY_INTERFACE':  'TestFooInterface/1.0',
             }
 
+        # Simulate standard configuration
+        factoryRegistry.register('GET', '*', 'browser', 0, BrowserFactory())
+        factoryRegistry.register('POST', '*', 'browser', 0, BrowserFactory())
+        factoryRegistry.register('HEAD', '*', 'browser', 0, BrowserFactory())
+        factoryRegistry.register('*', '*', 'http', 0, HTTPFactory())
+        factoryRegistry.register('POST', 'text/xml', 'xmlrpc', 20,
+                                 XMLRPCFactory())
+        factoryRegistry.register('POST', 'text/xml', 'soap', 30,
+                                 SOAPFactory())
+
     def test_override(self):
         # TODO: making a SOAP request without configuring a SOAP request
         # currently generates an XMLRPC request.  Not sure what the right thing
@@ -100,7 +113,6 @@
             self.assertEqual(r.publication.__class__, BrowserPublication)
 
     def test_http(self):
-
         for method in ('PUT', 'put', 'ZZZ'):
             self.__env['REQUEST_METHOD'] = method
             r = self.__factory(StringIO(''), self.__env)


Property changes on: Zope3/trunk/src/zope/app/publication/tests/test_httpfactory.py
___________________________________________________________________
Name: svn:keywords
   - Id
   + __init__.py

Copied: Zope3/trunk/src/zope/app/publication/tests/test_requestpublicationfactories.py (from rev 39082, Zope3/branches/ajung-target-requestpublication-next-try-branch/src/zope/app/publication/tests/test_requestpublicationfactories.py)


Property changes on: Zope3/trunk/src/zope/app/publication/tests/test_requestpublicationfactories.py
___________________________________________________________________
Name: svn:keywords
   + __init__.py

Copied: Zope3/trunk/src/zope/app/publication/tests/test_requestpublicationregistry.py (from rev 39082, Zope3/branches/ajung-target-requestpublication-next-try-branch/src/zope/app/publication/tests/test_requestpublicationregistry.py)


Property changes on: Zope3/trunk/src/zope/app/publication/tests/test_requestpublicationregistry.py
___________________________________________________________________
Name: svn:keywords
   + __init__.py


Property changes on: Zope3/trunk/src/zope/app/publication/tests/test_simplecomponenttraverser.py
___________________________________________________________________
Name: svn:keywords
   - Id
   + __init__.py


Property changes on: Zope3/trunk/src/zope/app/publication/tests/test_xmlrpcpublication.py
___________________________________________________________________
Name: svn:keywords
   - Id
   + __init__.py


Property changes on: Zope3/trunk/src/zope/app/publication/tests/test_zopepublication.py
___________________________________________________________________
Name: svn:keywords
   - Id
   + __init__.py

Modified: Zope3/trunk/src/zope/app/publication/zopepublication.py
===================================================================
--- Zope3/trunk/src/zope/app/publication/zopepublication.py	2005-10-11 22:46:43 UTC (rev 39082)
+++ Zope3/trunk/src/zope/app/publication/zopepublication.py	2005-10-11 23:09:36 UTC (rev 39083)
@@ -26,7 +26,6 @@
 
 from zope.event import notify
 from zope.security.interfaces import Unauthorized
-from zope.component.exceptions import ComponentLookupError
 from zope.interface import implements, providedBy
 from zope.publisher.publish import mapply
 from zope.publisher.interfaces import Retry, IExceptionSideEffects, IHeld
@@ -38,8 +37,6 @@
 from zope.app import zapi
 from zope.app.applicationcontrol.applicationcontrol \
      import applicationControllerRoot
-from zope.app.component.hooks import getSite
-from zope.app.error.error import RootErrorReportingUtility
 from zope.app.error.interfaces import IErrorReportingUtility
 from zope.app.exception.interfaces import ISystemErrorView
 from zope.app.location import LocationProxy

Modified: Zope3/trunk/src/zope/app/testing/tests.py
===================================================================
--- Zope3/trunk/src/zope/app/testing/tests.py	2005-10-11 22:46:43 UTC (rev 39082)
+++ Zope3/trunk/src/zope/app/testing/tests.py	2005-10-11 23:09:36 UTC (rev 39083)
@@ -22,6 +22,8 @@
 from zope.testing.doctestunit import DocTestSuite
 
 import zope.app.testing
+from zope.app.publication.requestpublicationregistry import factoryRegistry
+from zope.app.publication.requestpublicationfactories import BrowserFactory
 from zope.app.testing import functional
 from zope.app.testing.dochttp import dochttp
 
@@ -170,6 +172,8 @@
     def test_chooseRequestClass(self):
         from zope.publisher.interfaces import IRequest, IPublication
 
+        factoryRegistry.register('GET', '*', 'browser', 0, BrowserFactory())
+
         caller = functional.HTTPCaller()
         request_class, publication_class = caller.chooseRequestClass(
             method='GET', path='/', environment={})

Modified: Zope3/trunk/src/zope/app/wsgi/tests.py
===================================================================
--- Zope3/trunk/src/zope/app/wsgi/tests.py	2005-10-11 22:46:43 UTC (rev 39082)
+++ Zope3/trunk/src/zope/app/wsgi/tests.py	2005-10-11 23:09:36 UTC (rev 39083)
@@ -18,12 +18,18 @@
 import unittest
 from zope.testing import doctest
 from zope.app.testing import placelesssetup
+from zope.app.publication.requestpublicationregistry import factoryRegistry
+from zope.app.publication.requestpublicationfactories import BrowserFactory
 
+def setUp(test):
+    placelesssetup.setUp(test)
+    factoryRegistry.register('GET', '*', 'browser', 0, BrowserFactory())
+
 def test_suite():
     return unittest.TestSuite((
         doctest.DocFileSuite(
             'README.txt',
-            setUp=placelesssetup.setUp,
+            setUp=setUp,
             tearDown=placelesssetup.tearDown,
             optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS),
         ))



More information about the Zope3-Checkins mailing list