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 = []

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
                    response_headers['Connection'] = 'Keep-Alive'
                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.
            elif not ('Content-Length' in response_headers):
                close_it = 1
            # 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?



Zope3-dev mailing list

Reply via email to