views:

20

answers:

1

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.

A: 

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.

fumanchu
Thanks! I'm using 3.1 and ended up subclassing HTTPConnection and HTTPRequest to get it working. It was pretty ugly, but kind of fun... I'll refactor to the above technique when 3.2 is ready.