Hi,

I had a thinko in my previous patch
(http://mail.zope.org/pipermail/zope-dev/2004-August/023630.html)
which is corrected in the attached version of the patch.  Sorry for
any inconvenience, I might have caused.

As I'm sort of protocol challenged (thanks to corporate firewall), svn
unfortunately isn't an option for me.  Thus I created the patch
against lib/python/ZPublisher/HTTPRequest.py as released in 2.7.2-0.
As the patch is almost trivial it shouldn't be a problem to apply it
even manually against other vesions (at least 2.7.0, 2.7.1 and 2.7.2
should work OOTB i.e. by using /usr/bin/patch).

To sum up its purpose again:  It's meant to avoid the stdin.seek()
call in the HTTPRequest class so that non-seekable streams can be used
as stdin.  It also potentially avoids unnecessary (blocking) disk I/O
in retries (this depends on the according request that's being worked
on) and repeated request parsing in cgi.FieldStorage.  The immediate
cause for the patch is that AJPServer uses non-seekable streams as
input for the ZPublisher.  To change this locally I'd need to go with
disk buffering.  Nevertheless I think this could provide a general
performance improvement.

To this end I just save the cgi.FieldStorage instance, that is created
by HTTPRequest.processInputs, when the request is worked upon for the
first time, across retry boundaries.

Questions:

- Is this the right forum/place to send patches to?

- Is there any chance that this could be applied to Zope's mainline?
  (If not I will proceed with a local disk buffering scheme in the
  long term.)


cheers,

andreas



--- lib.orig/python/ZPublisher/HTTPRequest.py	2004-08-18 16:37:18.000000000 +0200
+++ lib/python/ZPublisher/HTTPRequest.py	2004-08-18 16:39:55.000000000 +0200
@@ -125,10 +125,12 @@
 
     def retry(self):
         self.retry_count=self.retry_count+1
-        self.stdin.seek(0)
+        if not self._fs:
+            raise ValueError, "Retrying on partially initialized request is not supported.  Call processInputs()."
         r=self.__class__(stdin=self.stdin,
                          environ=self._orig_env,
-                         response=self.response.retry()
+                         response=self.response.retry(),
+                         fs = self._fs
                          )
         r.retry_count=self.retry_count
         return r
@@ -138,6 +140,7 @@
         # removing tempfiles.
         self.stdin = None
         self._file = None
+        self._fs = None
         self.form.clear()
         # we want to clear the lazy dict here because BaseRequests don't have
         # one.  Without this, there's the possibility of memory leaking
@@ -237,7 +240,7 @@
         """
         return self._client_addr
 
-    def __init__(self, stdin, environ, response, clean=0):
+    def __init__(self, stdin, environ, response, clean=0, fs=None):
         self._orig_env=environ
         # Avoid the overhead of scrubbing the environment in the
         # case of request cloning for traversal purposes. If the
@@ -261,6 +264,7 @@
         self.steps=[]
         self._steps=[]
         self._lazies={}
+        self._fs = fs
 
 
         if environ.has_key('REMOTE_ADDR'):
@@ -382,23 +386,24 @@
         taintedform=self.taintedform
 
         meth=None
-        fs=FieldStorage(fp=fp,environ=environ,keep_blank_values=1)
-        if not hasattr(fs,'list') or fs.list is None:
+        if not self._fs:
+            self._fs=FieldStorage(fp=fp,environ=environ,keep_blank_values=1)
+        if not hasattr(self._fs,'list') or self._fs.list is None:
             # Hm, maybe it's an XML-RPC
-            if (fs.headers.has_key('content-type') and
-                fs.headers['content-type'] == 'text/xml' and
+            if (self._fs.headers.has_key('content-type') and
+                self._fs.headers['content-type'] == 'text/xml' and
                 method == 'POST'):
                 # Ye haaa, XML-RPC!
                 global xmlrpc
                 if xmlrpc is None: import xmlrpc
-                meth, self.args = xmlrpc.parse_input(fs.value)
+                meth, self.args = xmlrpc.parse_input(self._fs.value)
                 response=xmlrpc.response(response)
                 other['RESPONSE']=self.response=response
                 self.maybe_webdav_client = 0
             else:
-                self._file=fs.file
+                self._file=self._fs.file
         else:
-            fslist=fs.list
+            fslist=self._fs.list
             tuple_items={}
             lt=type([])
             CGI_name=isCGI_NAME
_______________________________________________
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://mail.zope.org/mailman/listinfo/zope-announce
 http://mail.zope.org/mailman/listinfo/zope )

Reply via email to