[Checkins] SVN: z3c.jsonrpc/branches/adamg-retryfix/src/z3c/jsonrpc/ reproduced the 599 error

Adam Groszer agroszer at gmail.com
Wed Jan 30 12:15:25 EST 2008


Log message for revision 83318:
  reproduced the 599 error

Changed:
  U   z3c.jsonrpc/branches/adamg-retryfix/src/z3c/jsonrpc/publisher.py
  A   z3c.jsonrpc/branches/adamg-retryfix/src/z3c/jsonrpc/tests/retry.txt
  A   z3c.jsonrpc/branches/adamg-retryfix/src/z3c/jsonrpc/tests/test_retry.py

-=-
Modified: z3c.jsonrpc/branches/adamg-retryfix/src/z3c/jsonrpc/publisher.py
===================================================================
--- z3c.jsonrpc/branches/adamg-retryfix/src/z3c/jsonrpc/publisher.py	2008-01-30 15:11:42 UTC (rev 83317)
+++ z3c.jsonrpc/branches/adamg-retryfix/src/z3c/jsonrpc/publisher.py	2008-01-30 17:15:25 UTC (rev 83318)
@@ -18,6 +18,8 @@
 
 import traceback
 import logging
+from StringIO import StringIO
+from tempfile import TemporaryFile
 
 import zope.interface
 import zope.component
@@ -26,6 +28,7 @@
 from zope.publisher.http import HTTPRequest
 from zope.publisher.http import HTTPResponse
 from zope.publisher.http import getCharsetUsingRequest
+from zope.publisher.http import HTTPInputStream
 from zope.security.proxy import isinstance
 
 from z3c.json.interfaces import IJSONReader
@@ -73,6 +76,18 @@
     def publishTraverse(self, request, name):
         return getattr(self.context, name)
 
+class JSONInputStream(HTTPInputStream):
+    def __init__(self, stream, environment):
+        self.stream = stream
+        size = environment.get('CONTENT_LENGTH')
+        # There can be no size in the environment (None) or the size
+        # can be an empty string, in which case we treat it as absent.
+        if not size:
+            size = environment.get('HTTP_CONTENT_LENGTH')
+        if not size or int(size) < 65536:
+            self.cacheStream = StringIO()
+        else:
+            self.cacheStream = TemporaryFile()
 
 class JSONRPCRequest(HTTPRequest):
     """JSON-RPC request implementation based on IHTTPRequest."""
@@ -87,8 +102,13 @@
         self.form = {}
         self._args = ()
         self.charsets = None
+
         super(JSONRPCRequest, self).__init__(body_instream, environ, response)
 
+        #this fixes that the input stream gets str instead of unicode
+        #HTTPInputStream breaks it with cStringIO
+        self._body_instream = JSONInputStream(body_instream, environ)
+
     def _createResponse(self):
         """return a response"""
         return JSONRPCResponse()
@@ -199,7 +219,24 @@
     def __getitem__(self,key):
         return self.get(key)
 
+    #def retry(self):
+    #    #retry
+    #    #implemented here, because HTTPRequest's retry messes up unicode to str
+    #    count = getattr(self, '_retry_count', 0)
+    #    self._retry_count = count + 1
+    #
+    #    new_response = self.response.retry()
+    #    request = self.__class__(
+    #        # Use the cache stream as the new input stream.
+    #        body_instream=self._body_instream.getCacheStream(),
+    #        environ=self._orig_env,
+    #        response=new_response,
+    #        )
+    #    request.setPublication(self.publication)
+    #    request._retry_count = self._retry_count
+    #    return request
 
+
 class JSONRPCResponse(HTTPResponse):
     """JSON-RPC Response"""
 

Added: z3c.jsonrpc/branches/adamg-retryfix/src/z3c/jsonrpc/tests/retry.txt
===================================================================
--- z3c.jsonrpc/branches/adamg-retryfix/src/z3c/jsonrpc/tests/retry.txt	                        (rev 0)
+++ z3c.jsonrpc/branches/adamg-retryfix/src/z3c/jsonrpc/tests/retry.txt	2008-01-30 17:15:25 UTC (rev 83318)
@@ -0,0 +1,107 @@
+=======
+JSONRPC
+=======
+
+
+JSON-RPC server
+---------------
+
+The JSON server looks for content-type "application/json", and handles those
+requests as JSON-RPC. The official mime-type for JSON is "application/json"
+The old content type ``application/json-rpc`` is supported too.
+
+Let's define a content object:
+
+  >>> import zope.interface
+  >>> class IDemoContent(zope.interface.Interface):
+  ...     """Demo content interface."""
+
+  >>> import persistent
+  >>> class DemoContent(persistent.Persistent):
+  ...     """Demo content."""
+  ...     zope.interface.implements(IDemoContent)
+
+And define a JSONRPC method view:
+
+  >>> class Conflict(Exception):
+  ...     pass
+  >>> from zope.publisher.interfaces import Retry
+
+  >>> from z3c.jsonrpc import publisher
+  >>> import sys
+  >>> class DemoView(publisher.MethodPublisher):
+  ...     """Sample JSON view."""
+  ...
+  ...     def fail(self):
+  ...         try:
+  ...             raise Conflict
+  ...         except:
+  ...             raise Retry(sys.exc_info())
+
+Make them available under the fake package ``jsonsamples``:
+
+  >>> import sys
+  >>> sys.modules['custom'] = type('Module', (), {})()
+  >>> sys.modules['custom'].IDemoContent = IDemoContent
+  >>> sys.modules['custom'].DemoContent = DemoContent
+  >>> sys.modules['custom'].DemoView = DemoView
+
+Let's show how we can register a jsonrpc view:
+
+  >>> from zope.configuration import xmlconfig
+  >>> import z3c.jsonrpc
+  >>> context = xmlconfig.file('meta.zcml', z3c.jsonrpc)
+  >>> context = xmlconfig.string("""
+  ... <configure
+  ...     xmlns:z3c="http://namespaces.zope.org/z3c">
+  ...   <z3c:jsonrpc
+  ...       for="custom.IDemoContent"
+  ...       class="custom.DemoView"
+  ...       permission="zope.Public"
+  ...       methods="fail"
+  ...       layer="z3c.jsonrpc.testing.IJSONRPCTestSkin"
+  ...       />
+  ... </configure>
+  ... """, context)
+
+Now we will setup a content object in our site:
+
+  >>> site  = getRootFolder()
+  >>> content = DemoContent()
+  >>> site['content'] = content
+
+  >>> siteURL = 'http://localhost/++skin++JSONRPCTestSkin'
+
+Now we can call the method from our JSONRPC view:
+
+  >>> from z3c.jsonrpc import testing
+  >>> request = testing.TestRequest()
+  >>> demoView = DemoView(content, request)
+  >>> demoView.fail()
+  Traceback (most recent call last):
+  ...
+  Retry: None
+
+
+JSON-RPC proxy
+--------------
+
+The jsonrpc package provides also a JSON-RPC proxy implementation. This
+implementation is similar to the one known from xmlrpclib except that it can
+handle JSON instead of XML.
+
+Let's try to call our method called ``hello`` we defined before:
+
+  >>> from z3c.jsonrpc.testing import JSONRPCTestProxy
+  >>> proxy = JSONRPCTestProxy(siteURL + '/content')
+  >>> proxy.fail()
+  u'Hello World'
+
+
+
+cleanup
+-------
+
+Now we need to clean up the custom module.
+
+  >>> del sys.modules['custom']


Property changes on: z3c.jsonrpc/branches/adamg-retryfix/src/z3c/jsonrpc/tests/retry.txt
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: z3c.jsonrpc/branches/adamg-retryfix/src/z3c/jsonrpc/tests/test_retry.py
===================================================================
--- z3c.jsonrpc/branches/adamg-retryfix/src/z3c/jsonrpc/tests/test_retry.py	                        (rev 0)
+++ z3c.jsonrpc/branches/adamg-retryfix/src/z3c/jsonrpc/tests/test_retry.py	2008-01-30 17:15:25 UTC (rev 83318)
@@ -0,0 +1,34 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation 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.
+#
+##############################################################################
+"""
+$Id:$
+"""
+__docformat__ = "reStructuredText"
+
+import unittest
+from zope.testing import doctest
+from z3c.jsonrpc import testing
+
+
+def test_suite():
+    return unittest.TestSuite((
+        testing.FunctionalDocFileSuite('retry.txt',
+            setUp=testing.setUp, tearDown=testing.tearDown,
+            optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+            ),
+        ))
+
+
+if __name__=='__main__':
+    unittest.main(defaultTest='test_suite')


Property changes on: z3c.jsonrpc/branches/adamg-retryfix/src/z3c/jsonrpc/tests/test_retry.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native



More information about the Checkins mailing list