Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Http request from Chrome hangs python webserver

I have a very basic python (2.7.12) web server (I've stripped it down as much as possible), code given below

import time
import ssl
from BaseHTTPServer import HTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler

class Management(SimpleHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        SimpleHTTPRequestHandler.end_headers(self)
        self.wfile.write(time.asctime() + "\n")

httpd = HTTPServer(('', 4443), Management)
httpd.socket = ssl.wrap_socket (httpd.socket, certfile='./server.pem', server_side=True)
httpd.serve_forever()

All it does is return the time. It works fine when I access it via https, but when I access it via http using (the latest version of) chrome on a different computer, it frequently (but not always) causes the entire server to hang in the python code, specifically ssl.py in the do_handshake function in the line

self._sslobj.do_handshake()

I was expecting the connection to fail and get dropped because I am trying to access an https page via http, but I don't expect it to cause the entire process to hang. It only happens with chrome (not firefox or microsoft edge), and only when chrome is run on a different computer than the computer the server is running on.

I've also tried creating a python3 version of the code, and I see the same issue. I've tried running it in both Cygwin on windows 10, and the terminal in Ubuntu 14.04, and I get the same problem.

like image 896
rbaber Avatar asked Mar 31 '17 17:03

rbaber


1 Answers

Just finished wrestling around with this for 2 days :(

Turns out user Ami Bar was exactly right in his/her answer. Google Chrome holds open the connection and causes the multiplexing in the selector library to register the connection as readable. Essentially it forces multiplexing to fail and thus you have to thread the server to handle requests separately.

You can thread your HTTP server by implementing socketserver.ThreadingMixIn. However if it's easier (this is what I did) you can simply upgrade python to 3.7+ and have your server inherit from http.server.ThreadingHTTPServer, which natively implements ThreadingMixIn

Hope this saves some poor soul two days...

like image 118
Jamie Marshall Avatar answered Nov 10 '22 13:11

Jamie Marshall