Why I call FastCGI complex and SCGI much simpler

March 4, 2011

In a comment on this entry, Daniel Martin took issue with with my description of SCGI as much simpler than FastCGI. As it happens, I have a straightforward reason for describing FastCGI this way: it's a protocol that uses encoded binary structures.

Any protocol that uses encoded binary structures requires you to write decoders and encoders, or at least a protocol description for your encoder/decoder generator. This is annoying even with simple fixed-format binary structures; it is an outright pain in the rear if the protocol has multiple structures, structures with variable fields, or complex switching logic (where you don't always have a common prefix that you can do simple switch dispatching on). FastCGI has multiple levels of decoding (where you have structures inside structures) and at least one case of an excessively clever structure encoding.

(The excessively clever structure encoding is worth special note, because in the name of saving six bytes FastCGI has four variations on the same basic structure that are differentiated not by an explicit type field, but by which of the first two bytes have their high bits set. In the process, it re-orders structure fields. I could go on about this particular encoding mistake, but this is not the entry for it.)

Regardless of the inherent simplicity or complexity of the protocol in an abstract sense (ie in terms of what the flow of messages is), using encoded binary structures makes you (much) more complicated than an equivalent protocol that uses a simpler, easier to parse and generate encoding. Since FastCGI uses encoded binary structures and SCGI doesn't, I say that SCGI is much simpler than FastCGI.

(FastCGI is also a more involved protocol than SCGI. I could easily call it over-engineered, in part because it reimplements OS-level concepts on its own and generally does this worse than the OS does.)

Sidebar: one OS-level concept that FastCGI reimplements

FastCGI needs to pass multiple communication channels between the web server and the FastCGI server process. As it happens, Unix OSes have a simple and well supported way of doing this; you open up multiple file descriptors between you and the other end and use each file descriptor for a separate channel. FastCGI would still need to do a little bit of multiplexing to handle standard output and standard error over the same channel, but that is much easier than the multiplexing job that it has taken on for itself.

(Doing this does not require multiple processes; you can perfectly well handle all connections with select() et al in one process. It does give you an easy way of using multiple processes, which can be handy.)

Written on 04 March 2011.
« The POSIX shell and the three sorts of Unixes
FastCGI's encoding mistakes and how not to design a wire protocol »

Page tools: View Source, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Fri Mar 4 02:09:41 2011
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.