
--text follows this line-- Hi, I'm trying to write a hybrid server that serves either HTTP or my own custom protocol depending on how it's addressed (distantly inspired by the IRC bouncer ZNC). If it receives a standard GET, POST, HEAD, etc. it sends HTTP traffic, or if it receives the bareword `CORDELIA', it switches to Cordelia mode. HTTP works fine with Twisted.Web. I can serve pages over HTTP (which is my desired outcome). However, I'm not sure how to write the Cordelia handling code. I've tried my own custom `render_CORDELIA' function, but it acts too much like HTTP (ie. it returns a result and terminates the connection), which is not what I want, as the protocol I've designed involves establishing a two-way conversation, not a single request and response pair. So I'm pretty much stuck in a rut. I don't want to totally reinvent the wheel just to be able to protocol-switch; I'd prefer to make use of existing code from Twisted. How do I hijack Twisted.Web to add protocol switching? Jashank -- Jashank Jeremy PGP: 0x25A5C309

Jashank Jeremy <jashank.jeremy@optusnet.com.au> writes:
So I'm pretty much stuck in a rut. I don't want to totally reinvent the wheel just to be able to protocol-switch; I'd prefer to make use of existing code from Twisted. How do I hijack Twisted.Web to add protocol switching?
The default HTTPFactory (of which Site is a subclass) is going to create an HTTPChannel protocol for a new connection. HTTPChannel is based on LineReceiver, so lineReceived() is your hook for incoming data. To insert your own protocol code, you want to set the "protocol" attribute of your Site (or HTTPFactory if using that directly) instance to your own "hybrid" protocol class. That protocol class needs to be able to use HTTPChannel for web connections, so you can choose between subclassing or composition. Subclassing is probably simpler, at least at first, since you won't have to worry about mirroring instance parameters or attributes getting set on your protocol instance by the factory, though composition may perhaps keep your protocols separate more cleanly. In your protocol's lineReceived() method, check for your flag value, and adjust state appropriately. Depending on the state you are in, either pass along control to HTTPChannel.lineReceived, or just process the data yourself. Note that if your protocol is binary so you are implementing rawDataReceived, you'll also want to check state and pass along to HTTPCHannel if not in your local mode since that can be used on web connections too. If you're subclassing be aware that any standard protocol method you implement might also get called on behalf of the HTTPChannel code and not just your own protocol so always pass along such calls if your local protocol mode isn't enabled. HTTPChannel also includes policies.TimeoutMixin, so if you end up switching to your own protocol, calling setTimeout(None) should prevent it from deciding to close down your transport beneath you. Unless you're subclassing and you'd like the same timeout to be in effect for your own protocol, of course. -- David

On Apr 4, 2011, at 7:51 PM, David Bolen wrote:
Jashank Jeremy <jashank.jeremy@optusnet.com.au> writes:
So I'm pretty much stuck in a rut. I don't want to totally reinvent the wheel just to be able to protocol-switch; I'd prefer to make use of existing code from Twisted. How do I hijack Twisted.Web to add protocol switching?
To insert your own protocol code, you want to set the "protocol" attribute of your Site (or HTTPFactory if using that directly) instance to your own "hybrid" protocol class.
It would be slightly better to override buildProtocol, because that way you can call the superclass's implementation more idiomatically. But, the idea is the same. Note that we'd really like to have protocol switch functionality built into Twisted proper so that you don't have to jump through all these hoops. Please feel free to contribute patches to fix this ticket: <http://twistedmatrix.com/trac/ticket/3204>.

Glyph Lefkowitz <glyph@twistedmatrix.com> writes:
On Apr 4, 2011, at 7:51 PM, David Bolen wrote:
Jashank Jeremy <jashank.jeremy@optusnet.com.au> writes:
So I'm pretty much stuck in a rut. I don't want to totally reinvent the wheel just to be able to protocol-switch; I'd prefer to make use of existing code from Twisted. How do I hijack Twisted.Web to add protocol switching?
To insert your own protocol code, you want to set the "protocol" attribute of your Site (or HTTPFactory if using that directly) instance to your own "hybrid" protocol class.
It would be slightly better to override buildProtocol, because that way you can call the superclass's implementation more idiomatically. But, the idea is the same.
Good point. For myself, I guess I use the attribute patching in cases where I subclass an existing protocol, but won't be changing the initialization. That way I didn't need to keep an independent factory class in sync with the library version over time in terms of any buildProtocol processing, which feels more robust. But a custom factory with its own buildProtocol is definitely more flexible, not to mention required if the new protocol class needs a different initialization signature. -- David
participants (3)
-
David Bolen
-
Glyph Lefkowitz
-
Jashank Jeremy