Search code examples
pythoncherrypy

Handling HTTP/1.1 Upgrade requests in CherryPy


I'm using CherryPy for a web server, but would like it to handle HTTP/1.1 Upgrade requests. Thus, when a client sends:

OPTIONS * HTTP/1.1
Upgrade: NEW_PROTOCOL/1.0
Connection: Upgrade

I'd like the server to hand the connection off to some NEW_PROTOCOL handler after responding with the necessary HTTP/1.1 101 Switching Protocols..., as specified in RFC 2817.

I'm pretty new to CherryPy, and couldn't find anything in the documentation on how to handle specific client requests such as the above. If someone could point me to a tutorial or parts of the CherryPy documentation or even a solution, that would be very helpful.


Solution

  • This is fairly easy to do in trunk (which will eventually be 3.2 final). I'm sure it's possible in older versions but much more convoluted.

    All you need to do is make a new subclass of wsgiserver.Gateway that looks for the headers in question and then either hands off the conn or proceeds to the usual gateway. For example:

    class UpgradeGateway(Gateway):
        def respond(self):
            h = self.req.inheaders
            if h.get("Connection", "") == "Upgrade":
                # Turn off auto-output of HTTP response headers
                self.req.sent_headers = True
                # Not sure exactly what you want to pass or how, here's a start...
                return protocols[h['Upgrade']].handle(self.req.rfile, self.req.wfile)
            else:
                return old_gateway(self.req).respond()
    
    old_gateway = cherrypy.server.httpserver.gateway
    cherrypy.server.httpserver.gateway = UpgradeGateway
    

    There may be a couple other fine points but that's the general technique.