<div>Dear all,</div>
<div> </div>
<div>While I was exploring my options to implement NTLM authentication, I found some strange behavior of Zope HTTP server.</div>
<div> </div>
<div>in zope.server.http.wsgihttpserver.WSGIHTTPServer, </div>
<div>It use below function to handle response's head:</div>
<div>
<p> def start_response(status, headers):<br> # Prepare the headers for output<br> status, reason = re.match('([0-9]*) (.*)', status).groups()<br> task.setResponseStatus(status, reason)
<br> task.appendResponseHeaders(['%s: %s' % i for i in headers])</p>
<p> # Return the write method used to write the response data.<br> return fakeWrite<br></p>
<p>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.</p>
<p> def appendResponseHeaders(self, lst):<br> """See zope.publisher.interfaces.http.IHeaderOutput"""<br> accum = self.accumulated_headers<br> if accum is None:<br>
self.accumulated_headers = accum = []<br> accum.extend(lst)<br></p>
<p>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.
</p>
<p> def prepareResponseHeaders(self):<br> version = self.version<br> # Figure out whether the connection should be closed.<br> connection = self.request_data.headers.get('CONNECTION', '').lower()<br>
close_it = 0<br> response_headers = self.response_headers</p>
<p> if version == '1.0':<br> if connection == 'keep-alive':<br> if not ('Content-Length' in response_headers):<br> close_it = 1<br> else:<br> response_headers['Connection'] = 'Keep-Alive'
<br> else:<br> close_it = 1<br> elif version == '1.1':<br> thisflag = False<br> <br> if connection == 'close':<br> close_it = 1<br> elif 'Transfer-Encoding' in response_headers:
<br> if not response_headers['Transfer-Encoding'] == 'chunked':<br> close_it = 1<br> elif self.status == '304':<br> # Replying with headers only.<br> pass
<br> elif not ('Content-Length' in response_headers):<br> close_it = 1<br> else:<br> # Close if unrecognized HTTP version.<br> close_it = 1</p>
<p> self.close_on_finish = close_it<br> if close_it:<br> self.response_headers['Connection'] = 'close'<br> </p>
<p>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?</p>
<p>Thanks,<br>Simon</p>
<p> </p></div>