[Checkins] SVN: zope.app.http/trunk/ - Fix for an edge case:

Adam Groszer agroszer at gmail.com
Thu Jan 28 11:07:05 EST 2010


Log message for revision 108613:
  - Fix for an edge case:
    If someone does a defaultView for the context object and someone comes with
      a not allowed method, the exception view fails on getAdapters
  

Changed:
  U   zope.app.http/trunk/CHANGES.txt
  U   zope.app.http/trunk/src/zope/app/http/exception/methodnotallowed.py
  U   zope.app.http/trunk/src/zope/app/http/exception/tests/test_methodnotallowed.py

-=-
Modified: zope.app.http/trunk/CHANGES.txt
===================================================================
--- zope.app.http/trunk/CHANGES.txt	2010-01-28 16:02:15 UTC (rev 108612)
+++ zope.app.http/trunk/CHANGES.txt	2010-01-28 16:07:04 UTC (rev 108613)
@@ -5,7 +5,9 @@
 3.6.2 (unreleased)
 ------------------
 
-- Nothing changed yet.
+- Fix for an edge case:
+  If someone does a defaultView for the context object and someone comes with
+  a not allowed method, the exception view fails on getAdapters
 
 
 3.6.1 (2010-01-08)

Modified: zope.app.http/trunk/src/zope/app/http/exception/methodnotallowed.py
===================================================================
--- zope.app.http/trunk/src/zope/app/http/exception/methodnotallowed.py	2010-01-28 16:02:15 UTC (rev 108612)
+++ zope.app.http/trunk/src/zope/app/http/exception/methodnotallowed.py	2010-01-28 16:07:04 UTC (rev 108613)
@@ -26,15 +26,22 @@
     def __init__(self, error, request):
         self.error = error
         self.request = request
-        self.allow = [
-            name for name, adapter
-            in getAdapters((error.object, error.request), Interface)
-            if hasattr(adapter, name)]
-        self.allow.sort()
+        allow = []
 
+        try:
+            # see test_methodnotallowed.TestMethodNotAllowedView.test_defaultView
+            # I could not solve this with a while ... next() iterator
+            # because it seems like once the generator had an exception it
+            # stops returning items
+            self.allow = [
+                name for name, adapter
+                in getAdapters((error.object, error.request), Interface)
+                if hasattr(adapter, name)]
+            self.allow.sort()
+        except TypeError:
+            self.allow = []
+
     def __call__(self):
         self.request.response.setHeader('Allow', ', '.join(self.allow))
         self.request.response.setStatus(405)
         return 'Method Not Allowed'
-
-

Modified: zope.app.http/trunk/src/zope/app/http/exception/tests/test_methodnotallowed.py
===================================================================
--- zope.app.http/trunk/src/zope/app/http/exception/tests/test_methodnotallowed.py	2010-01-28 16:02:15 UTC (rev 108612)
+++ zope.app.http/trunk/src/zope/app/http/exception/tests/test_methodnotallowed.py	2010-01-28 16:07:04 UTC (rev 108613)
@@ -52,12 +52,23 @@
 
     def setUp(self):
         from zope.publisher.interfaces.http import IHTTPRequest
+
         PlacelessSetup.setUp(self)
         ztapi.provideView(I, IHTTPRequest, Interface, 'GET', GetView)
         ztapi.provideView(I, IHTTPRequest, Interface, 'DELETE', DeleteView)
         ztapi.provideView(I, IHTTPRequest, Interface, 'irrelevant', GetView)
         ztapi.provideView(I, IHTTPRequest, Interface, 'also_irr.', DeleteView)
 
+        from zope.publisher.interfaces import IDefaultViewName
+        from zope.publisher.interfaces.browser import IBrowserRequest
+        #do the same as defaultView would for something like:
+        #<defaultView
+        #    for=".test_methodnotallowed.I"
+        #    name="index.html"
+        #    />
+
+        ztapi.provideAdapter((I, IBrowserRequest), IDefaultViewName, u'index.html')
+
     def test(self):
         from zope.publisher.interfaces.http import MethodNotAllowed
         from zope.app.http.exception.methodnotallowed \
@@ -76,6 +87,34 @@
         self.assertEqual(result, 'Method Not Allowed')
 
 
+    def test_defaultView(self):
+        # do the same with a BrowserRequest
+        # edge case is that if someone does a defaultView for the context object
+        # but the app is not prepared for webdav or whatever
+        # and someone comes with a not allowed method, the exception
+        # view fails on getAdapters
+        # this might be an issue with zope.publisher, as it provides
+        # a unicode object with provideAdapter, but I don't think I can
+        # change zope.publisher
+        from zope.publisher.interfaces.http import MethodNotAllowed
+        from zope.app.http.exception.methodnotallowed \
+             import MethodNotAllowedView
+        from zope.publisher.browser import BrowserRequest
+
+        context = C()
+        request = BrowserRequest(StringIO('PUT /bla/bla HTTP/1.1\n\n'), {})
+
+        error = MethodNotAllowed(context, request)
+        view = MethodNotAllowedView(error, request)
+
+        result = view()
+
+        self.assertEqual(request.response.getStatus(), 405)
+        #well this is empty, but we're grateful that it does not break
+        self.assertEqual(request.response.getHeader('Allow'), '')
+        self.assertEqual(result, 'Method Not Allowed')
+
+
 def test_suite():
     return TestSuite((
         makeSuite(TestMethodNotAllowedView),



More information about the checkins mailing list