changeset 3672:fee546fba271

fix xmlrpc request.read() call to use content-length, if available
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Fri, 06 Jun 2008 23:02:06 +0200
parents 6bd61e4063e3
children bcb50d97d2ef
files MoinMoin/request/__init__.py MoinMoin/request/request_cgi.py MoinMoin/request/request_cli.py MoinMoin/request/request_fcgi.py MoinMoin/request/request_modpython.py MoinMoin/request/request_standalone.py MoinMoin/request/request_twisted.py MoinMoin/request/request_wsgi.py MoinMoin/xmlrpc/__init__.py docs/CHANGES
diffstat 10 files changed, 61 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/request/__init__.py	Wed Jun 04 11:32:20 2008 +0200
+++ b/MoinMoin/request/__init__.py	Fri Jun 06 23:02:06 2008 +0200
@@ -410,6 +410,10 @@
         self.request_method = env.get('REQUEST_METHOD', None)
         self.remote_addr = env.get('REMOTE_ADDR', '')
         self.http_user_agent = env.get('HTTP_USER_AGENT', '')
+        try:
+            self.content_length = int(env.get('CONTENT_LENGTH'))
+        except (TypeError, ValueError):
+            self.content_length = None
         self.if_modified_since = env.get('If-modified-since') or env.get(cgiMetaVariable('If-modified-since'))
         self.if_none_match = env.get('If-none-match') or env.get(cgiMetaVariable('If-none-match'))
 
@@ -1001,7 +1005,7 @@
         name = u'/'.join(normalized)
         return name
 
-    def read(self, n=None):
+    def read(self, n):
         """ Read n bytes from input stream. """
         raise NotImplementedError
 
--- a/MoinMoin/request/request_cgi.py	Wed Jun 04 11:32:20 2008 +0200
+++ b/MoinMoin/request/request_cgi.py	Fri Jun 06 23:02:06 2008 +0200
@@ -9,6 +9,9 @@
 """
 import sys, os, cgi
 
+from MoinMoin import log
+logging = log.getLogger(__name__)
+
 from MoinMoin.request import RequestBase, RemoteClosedConnection
 
 class Request(RequestBase):
@@ -33,9 +36,10 @@
         form = cgi.FieldStorage(keep_blank_values=1)
         return RequestBase._setup_args_from_cgi_form(self, form)
 
-    def read(self, n=None):
+    def read(self, n):
         """ Read from input stream. """
         if n is None:
+            logging.warning("calling request.read(None) might block")
             return sys.stdin.read()
         else:
             return sys.stdin.read(n)
--- a/MoinMoin/request/request_cli.py	Wed Jun 04 11:32:20 2008 +0200
+++ b/MoinMoin/request/request_cli.py	Fri Jun 06 23:02:06 2008 +0200
@@ -8,6 +8,9 @@
 """
 import sys
 
+from MoinMoin import log
+logging = log.getLogger(__name__)
+
 from MoinMoin.request import RequestBase, RemoteClosedConnection
 
 class Request(RequestBase):
@@ -26,6 +29,7 @@
         self.http_host = 'localhost'
         self.http_referer = ''
         self.script_name = '.'
+        self.content_length = None
         self.if_modified_since = None
         self.if_none_match = None
         RequestBase.__init__(self, properties)
@@ -38,9 +42,10 @@
         #return RequestBase._setup_args_from_cgi_form(self, form)
         return {}
 
-    def read(self, n=None):
+    def read(self, n):
         """ Read from input stream. """
         if n is None:
+            logging.warning("calling request.read(None) might block")
             return sys.stdin.read()
         else:
             return sys.stdin.read(n)
--- a/MoinMoin/request/request_fcgi.py	Wed Jun 04 11:32:20 2008 +0200
+++ b/MoinMoin/request/request_fcgi.py	Fri Jun 06 23:02:06 2008 +0200
@@ -7,6 +7,9 @@
                 2003-2006 MoinMoin:ThomasWaldmann
     @license: GNU GPL, see COPYING for details.
 """
+from MoinMoin import log
+logging = log.getLogger(__name__)
+
 from MoinMoin.request import RequestBase, RemoteClosedConnection
 
 class Request(RequestBase):
@@ -35,9 +38,10 @@
         # thfcgi used keep_blank_values=1 internally for fcgform
         return RequestBase._setup_args_from_cgi_form(self, self.fcgform)
 
-    def read(self, n=None):
+    def read(self, n):
         """ Read from input stream. """
         if n is None:
+            logging.warning("calling request.read(None) might block")
             return self.fcgreq.stdin.read()
         else:
             return self.fcgreq.stdin.read(n)
--- a/MoinMoin/request/request_modpython.py	Wed Jun 04 11:32:20 2008 +0200
+++ b/MoinMoin/request/request_modpython.py	Fri Jun 06 23:02:06 2008 +0200
@@ -6,6 +6,9 @@
                 2003-2006 MoinMoin:ThomasWaldmann
     @license: GNU GPL, see COPYING for details.
 """
+from MoinMoin import log
+logging = log.getLogger(__name__)
+
 from MoinMoin import wikiutil
 from MoinMoin.request import RequestBase, RemoteClosedConnection
 
@@ -116,9 +119,10 @@
         """
         return RequestBase.run(self)
 
-    def read(self, n=None):
+    def read(self, n):
         """ Read from input stream. """
         if n is None:
+            logging.warning("calling request.read(None) might block")
             return self.mpyreq.read()
         else:
             return self.mpyreq.read(n)
--- a/MoinMoin/request/request_standalone.py	Wed Jun 04 11:32:20 2008 +0200
+++ b/MoinMoin/request/request_standalone.py	Fri Jun 06 23:02:06 2008 +0200
@@ -8,6 +8,9 @@
 """
 import cgi
 
+from MoinMoin import log
+logging = log.getLogger(__name__)
+
 from MoinMoin.request import RequestBase, RemoteClosedConnection
 
 class Request(RequestBase):
@@ -30,6 +33,10 @@
             self.http_accept_language = (sa.headers.getheader('accept-language')
                                          or self.http_accept_language)
             self.http_user_agent = sa.headers.getheader('user-agent', '')
+            try:
+                self.content_length = int(sa.headers.getheader('content-length'))
+            except (TypeError, ValueError):
+                self.content_length = None
             co = [c for c in sa.headers.getheaders('cookie') if c]
             self.saved_cookie = ', '.join(co) or ''
             self.if_modified_since = sa.headers.getheader('if-modified-since')
@@ -61,23 +68,13 @@
                                 keep_blank_values=1)
         return RequestBase._setup_args_from_cgi_form(self, form)
 
-    def read(self, n=None):
-        """ Read from input stream
-
-        Since self.rfile.read() will block, content-length will be used instead.
-
-        TODO: test with n > content length, or when calling several times
-        with smaller n but total over content length.
-        """
+    def read(self, n):
+        """ Read from input stream """
         if n is None:
-            try:
-                n = int(self.headers.get('content-length'))
-            except (TypeError, ValueError):
-                import warnings
-                warnings.warn("calling request.read() when content-length is "
-                              "not available will block")
-                return self.rfile.read()
-        return self.rfile.read(n)
+            logging.warning("calling request.read(None) might block")
+            return self.rfile.read()
+        else:
+            return self.rfile.read(n)
 
     def write(self, *data):
         """ Write to output stream. """
--- a/MoinMoin/request/request_twisted.py	Wed Jun 04 11:32:20 2008 +0200
+++ b/MoinMoin/request/request_twisted.py	Fri Jun 06 23:02:06 2008 +0200
@@ -7,6 +7,9 @@
     @license: GNU GPL, see COPYING for details.
 """
 
+from MoinMoin import log
+logging = log.getLogger(__name__)
+
 from MoinMoin.request import RequestBase, MoinMoinFinish, RemoteClosedConnection
 
 class Request(RequestBase):
@@ -21,6 +24,10 @@
             self.http_accept_language = self.twistd.getHeader('Accept-Language')
             self.saved_cookie = self.twistd.getHeader('Cookie')
             self.http_user_agent = self.twistd.getHeader('User-Agent')
+            try:
+                self.content_length = int(self.twistd.getHeader('Content-Length'))
+            except (TypeError, ValueError):
+                self.content_length = None
             self.if_modified_since = self.twistd.getHeader('If-Modified-Since')
             self.if_none_match = self.twistd.getHeader('If-None-Match')
 
@@ -73,7 +80,7 @@
         # All of the arguments, including URL and POST arguments (using keep_blank_values=1 internally).
         return self.decodeArgs(self.twistd.args)
 
-    def read(self, n=None):
+    def read(self, n):
         """ Read from input stream. """
         # XXX why is that wrong?:
         #rd = self.reactor.callFromThread(self.twistd.read)
@@ -82,6 +89,7 @@
         # XXX if yes, why doesn't it work?
         self.twistd.content.seek(0, 0)
         if n is None:
+            logging.warning("calling request.read(None) might block")
             rd = self.twistd.content.read()
         else:
             rd = self.twistd.content.read(n)
--- a/MoinMoin/request/request_wsgi.py	Wed Jun 04 11:32:20 2008 +0200
+++ b/MoinMoin/request/request_wsgi.py	Fri Jun 06 23:02:06 2008 +0200
@@ -8,6 +8,9 @@
 """
 import cgi, StringIO
 
+from MoinMoin import log
+logging = log.getLogger(__name__)
+
 from MoinMoin.request import RequestBase, RemoteClosedConnection
 
 class Request(RequestBase):
@@ -39,22 +42,10 @@
         form = cgi.FieldStorage(fp=self.stdin, environ=self.env, keep_blank_values=1)
         return RequestBase._setup_args_from_cgi_form(self, form)
 
-    def read(self, n=None):
+    def read(self, n):
         if n is None:
-            # We can't do that, because wsgi 1.0 requires n:
-            #return self.stdin.read()
-            # Thus, if we have no n, we have to simulate the usual behaviour (or
-            # it won't work e.g. with mod_wsgi 1.3 and maybe other wsgi 1.0 servers).
-            # Note: just requesting a extremely large amount (expecting it to never
-            # be reached, but still all data returned) also does not work (mod_wsgi
-            # 1.3 gives a MemoryError when doing that):
-            data = []
-            while True:
-                read_data = self.stdin.read(4000)
-                if not read_data:
-                    break
-                data.append(read_data)
-            return ''.join(data)
+            logging.warning("calling request.read(None) might block")
+            return self.stdin.read()
         else:
             return self.stdin.read(n)
 
--- a/MoinMoin/xmlrpc/__init__.py	Wed Jun 04 11:32:20 2008 +0200
+++ b/MoinMoin/xmlrpc/__init__.py	Fri Jun 06 23:02:06 2008 +0200
@@ -132,7 +132,7 @@
                 # we do not handle xmlrpc v1 and v2 differently
                 response = xmlrpclib.Fault(1, "This moin wiki does not allow xmlrpc method calls.")
             else:
-                data = self.request.read()
+                data = self.request.read(self.request.content_length)
 
                 try:
                     params, method = xmlrpclib.loads(data)
--- a/docs/CHANGES	Wed Jun 04 11:32:20 2008 +0200
+++ b/docs/CHANGES	Fri Jun 06 23:02:06 2008 +0200
@@ -27,6 +27,12 @@
     USE BOTH ON YOUR OWN RISK!
 
 
+Version 1.7.0current:
+
+  Bug Fixes:
+    * fix xmlrpc request.read() call to use content-length header, if available
+
+
 Version 1.7.0rc2:
 
   Bug Fixes: