Python - BaseHTTPServer keep alive does not work

7.5k views Asked by At

I have the following code for a simple BaseHTTPServer based server.

class myHandler(BaseHTTPRequestHandler):
    #Handler for the GET requests
    def do_GET(self):
        # Parse the query_str
        query_str = self.path.strip().lower()
        if query_str.startswith("/download?"):
            query_str = query_str[10:]
            opts = urlparse.parse_qs(query_str)

            # Send the html message and download file
            self.protocol_version = 'HTTP/1.1'
            self.send_response(200)
            self.send_header("Content-type", 'text/html')
            self.send_header("Content-length", 1)
            self.end_headers()
            self.wfile.write("0")

            # Some code to do some processing
            # ...
            # -----------

            self.wfile.write("1")

I was expecting the HTML page to show "1", but it shows "0". How can I update the response through keep alive?

4

There are 4 answers

3
doog abides On

Not sure what you are trying to accomplish, but if you want the 1 to be sent, you need to set your content-length to 2 or remove it entirely. The 1 is not going to overwrite the 0, so you will see 01.

0
apeuralahti On

https://docs.python.org/2/library/basehttpserver.html

protocol_version

This specifies the HTTP protocol version used in responses. If set to 'HTTP/1.1', the server will permit HTTP persistent connections; however, your server must then include an accurate Content-Length header (using send_header()) in all of its responses to clients. For backwards compatibility, the setting defaults to 'HTTP/1.0'.

0
whitehatboxer On

I faced same question. I tried set protocol_version in my do_METHOD() function which doesn't work. My code look like this.

def _handle(self, method):
    self.protocol_version = "HTTP/1.1"
    # some code here

def do_GET(self):
    self._handle("GET")

I used ss and tcpdump to detect network and finally find server will reset connection after send response although it use http/1.1.

So I try set protocol_version just under my class which inherited from standard library class and it works. Because of cost of time, I don't dive into source code. Hope it works for others.

1
Martin Del Vecchio On

I believe you are setting self.protocol_version to 'HTTP/1.1' too late. You are doing it in your do_GET() method, at which point your request handler has already been instantiated, and the server has already inspected that instance's protocol_version property.

Better to set it on the class:

class myHandler(BaseHTTPRequestHandler):
    protocol_version = 'HTTP/1.1'