[Zope3-Users] Re: Is this a bug of HTTP response's head handling? (publisherhttpserver.py)

Simon Hang hangzhiyun at gmail.com
Thu Sep 21 03:33:49 EDT 2006


Thanks Philipp, here is the unified diffs.
--- httptask.py.orig    Fri Jan 06 02:15:48 2006
+++ httptask.py Thu Sep 21 17:31:17 2006
@@ -126,6 +126,15 @@
             else:
                 close_it = 1
         elif version == '1.1':
+            #modified by Simon
+            thisflag = False
+            for each in self.accumulated_headers:
+                if each.lower() == 'connection: keep-alive':
+                    thisflag = True
+                    break
+            if thisflag == False:
+                close_it = 1
+
             if connection == 'close':
                 close_it = 1
             elif 'Transfer-Encoding' in response_headers:
@@ -134,8 +143,15 @@
             elif self.status == '304':
                 # Replying with headers only.
                 pass
+            #modified by simon
             elif not ('Content-Length' in response_headers):
-                close_it = 1
+                thisflag = False
+                for each in self.accumulated_headers:
+                    if each[:14].lower() == 'content-length':
+                        thisflag = True
+                        break
+                if thisflag == False: #only content_length not exist in
accumulated headers too
+                    close_it = 1
         else:
             # Close if unrecognized HTTP version.
             close_it = 1


On 9/21/06, Philipp von Weitershausen <philipp at weitershausen.de> wrote:
>
> Simon Hang wrote:
> > How about below changes?
>
> There aren't many of us who know the zope.server code that well,
> unfortunately. This is one of the reasons we want to "get out of the
> server business".
>
> That said, it would *much* easier to understand what you're trying to do
> if you provided *unified diffs* (create them with "svn diff" or "diff
> -u").
>
> Philipp
>
>
> >
> > in httptask.py
> >
> >     def prepareResponseHeaders(self):
> >         version = self.version
> >         # Figure out whether the connection should be closed.
> >         connection = self.request_data.headers.get('CONNECTION',
> '').lower()
> >         close_it = 0
> >         response_headers = self.response_headers
> >
> >         if version == '1.0':
> >             if connection == 'keep-alive':
> >                 if not ('Content-Length' in response_headers):
> >                     close_it = 1
> >                 else:
> >                     response_headers['Connection'] = 'Keep-Alive'
> >             else:
> >                 close_it = 1
> >         elif version == '1.1':
> >             #insert by Simon
> >             thisflag = False
> >             for each in self.accumulated_headers:
> >                 if each.lower() == 'connection: keep-alive':
> >                     thisflag = True
> >                     break
> >             if thisflag == False:
> >                 close_it = 1
> >             #end of insert
> >             if connection == 'close':
> >                 close_it = 1
> >             elif 'Transfer-Encoding' in response_headers:
> >                 if not response_headers['Transfer-Encoding'] ==
> 'chunked':
> >                     close_it = 1
> >             elif self.status == '304':
> >                 # Replying with headers only.
> >                 pass
> >             #insert by simon
> >             elif not ('Content-Length' in response_headers):
> >                 thisflag = False
> >                 for each in self.accumulated_headers:
> >                     if each[:14].upper() == 'CONTENT-LENGTH':
> >                         thisflag = True
> >                         break
> >                 if thisflag == False: #only CONTENT_LENGTH not exist in
> > accumulated headers too
> >
> >               #end of insert
> >                     close_it = 1
> >         else:
> >             # Close if unrecognized HTTP version.
> >             close_it = 1
> >
> >         self.close_on_finish = close_it
> >         if close_it:
> >             self.response_headers['Connection'] = 'close'
> >
> >
> >
> >
> > On 9/19/06, *Simon Hang*
> > <hangzhiyun at gmail.com
> > <mailto:hangzhiyun at gmail.com>> wrote:
> >
> >     Dear all,
> >
> >     While I was exploring my options to implement NTLM authentication, I
> >     found some strange behavior of Zope HTTP server.
> >
> >     in zope.server.http.wsgihttpserver.WSGIHTTPServer,
> >     It use below function to handle response's head:
> >
> >             def start_response(status, headers):
> >                 # Prepare the headers for output
> >                 status, reason = re.match('([0-9]*) (.*)',
> status).groups()
> >                 task.setResponseStatus(status, reason)
> >                 task.appendResponseHeaders(['%s: %s' % i for i in
> headers])
> >
> >                 # Return the write method used to write the response
> data.
> >                 return fakeWrite
> >
> >     The result is all response's head from the content part of program
> >     will be stored in task.accumulated_headers. See below function from
> >     zope.server.http.httptask.HTTPTask.
> >
> >         def appendResponseHeaders(self, lst):
> >             """See zope.publisher.interfaces.http.IHeaderOutput"""
> >             accum = self.accumulated_headers
> >             if accum is None:
> >                 self.accumulated_headers = accum = []
> >             accum.extend(lst)
> >
> >     But, the problem is while httptask to determin whether to close the
> >     connection or not, it use below code. The code is only checking
> >     self.response_headers which has nothing to do with the response our
> >     application generated. So zope ends up to disconnect connection for
> >     each single request.
> >
> >        def prepareResponseHeaders(self):
> >             version = self.version
> >             # Figure out whether the connection should be closed.
> >             connection = self.request_data.headers.get('CONNECTION',
> >     '').lower()
> >             close_it = 0
> >             response_headers = self.response_headers
> >
> >             if version == '1.0':
> >                 if connection == 'keep-alive':
> >                     if not ('Content-Length' in response_headers):
> >                         close_it = 1
> >                     else:
> >                         response_headers['Connection'] = 'Keep-Alive'
> >                 else:
> >                     close_it = 1
> >             elif version == '1.1':
> >                 thisflag = False
> >
> >                 if connection == 'close':
> >                     close_it = 1
> >                 elif 'Transfer-Encoding' in response_headers:
> >                     if not response_headers['Transfer-Encoding'] ==
> >     'chunked':
> >                         close_it = 1
> >                 elif self.status == '304':
> >                     # Replying with headers only.
> >                     pass
> >                 elif not ('Content-Length' in response_headers):
> >                     close_it = 1
> >             else:
> >                 # Close if unrecognized HTTP version.
> >                 close_it = 1
> >
> >             self.close_on_finish = close_it
> >             if close_it:
> >                 self.response_headers['Connection'] = 'close'
> >
> >
> >     Can somebody tell me why the thing is implement like this, is there
> >     special reason to do this? Or can we change it a little bit to let
> >     zope support persistence connection?
> >
> >     Thanks,
> >     Simon
> >
> >
> >
> >
> >
> > ------------------------------------------------------------------------
> >
> > _______________________________________________
> > Zope3-users mailing list
> > Zope3-users at zope.org
> > http://mail.zope.org/mailman/listinfo/zope3-users
>
> _______________________________________________
> Zope3-users mailing list
> Zope3-users at zope.org
> http://mail.zope.org/mailman/listinfo/zope3-users
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.zope.org/pipermail/zope3-users/attachments/20060921/1ce36676/attachment-0001.htm


More information about the Zope3-users mailing list