<div>How about below changes?</div>
<div> </div>
<div>in httptask.py</div>
<div>
<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> #insert by Simon<br> thisflag = False<br> for each in self.accumulated_headers:<br> if
each.lower() == 'connection: keep-alive':<br> thisflag = True<br> break<br> if thisflag == False:<br> close_it = 1<br> #end of insert<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> #insert by simon<br> elif not ('Content-Length' in response_headers):<br> thisflag = False
<br> for each in self.accumulated_headers:<br> if each[:14].upper() == 'CONTENT-LENGTH':<br> thisflag = True<br> break<br> if thisflag == False: #only CONTENT_LENGTH not exist in accumulated headers too
</p>
<p> #end of insert<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><br><br> </div>
<div><span class="gmail_quote">On 9/19/06, <b class="gmail_sendername">Simon Hang</b> <<a href="mailto:hangzhiyun@gmail.com">hangzhiyun@gmail.com</a>> wrote:</span>
<blockquote class="gmail_quote" style="PADDING-LEFT: 1ex; MARGIN: 0px 0px 0px 0.8ex; BORDER-LEFT: #ccc 1px solid">
<div>
<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></div></blockquote></div><br>