[Zope3-Users] Re: Is this a bug of HTTP response's head handling?
(publisherhttpserver.py)
Philipp von Weitershausen
philipp at weitershausen.de
Thu Sep 21 03:08:30 EDT 2006
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
More information about the Zope3-users
mailing list