Patrick McManus (a Firefox developer) added the following comment directly on the blog posting. An underlying/implied point is that SPDY is already shipped [1].
"
Your premise seems to be that SPDY is a complex binary protocol and we don't need that achieve mux. I don't see much evidence for your complexity assertion - especially when compared with HTTP/1.
Consider the difference in finding the message boundaries of a SPDY message with an HTTP/1.1 one.
To process the SPDY message you
* buffer 8 bytes of data
* determine that it is a data packet by confirming (buf[0] & 0x80 == 0)
* determine the length of the data by ntohl(((uint32_t)buf)[1)& 0x00ffffff
* find out if there are more chunks to come by looking at (buf[4] & 1).
All done. It is very straightforward, efficient, well bounded, and testable.
Contrast that with parsing a HTTP/1 message.
* read "enough" data from the network. You don't know how much that is and if you read too much you have to implement some facility for "putting it back" so the next message can use it. This inevitably leads to streaming parsers and their inherent complexity and lack of efficiency.
* parse the headers so you can determine which message delimiter is being used. To parse the header you have to implement line folding, implement a tokenizer aware of various rules around quotation marks and colons, and adopt to a number of real-world variations in the use of line endings other than just CRLF. To do this you have to run a state machine against every byte of input rather than directly address fixed offsets.
* Implement strategies to deal with conflicts such "Content-Length: 42, 17" and "Content-Length: 95\r\nTransfer-Encoding: chunked\r\n"
* you need to implement an ascii to integer conversion routine to determine the status code because some status codes implicitly impact message delimiters (e.g. 304).
* now you have to implement no less than 5 message delimiting schemes - chunked encodings, EOF, content-length, implicit (304), and everyone's favorite multibyte/ranges.
* If you have content-length or a chunk you'll need to convert a text string to an integer again.. and http/1 doesn't bound the size of the text string so you'll either have a common bug with an overflow or you'll implement an undiscoverable constraint in your implementation leading to cases of failing interop.
* you'll still have exposure to a whole class of CRLF injection attacks inherent in the text format.
The binary framing is so much less complex and significant improvement. Sure, to the naked eye in a log it may not look that way but that is optimizing for all the wrong things and can be quite misleading - do you really interpret a HTTP header with line folding or \n\r instead of \r\n sequences correctly when eyeballing it?)
Now there certainly is some complexity in SPDY but it doesn't come, in my opinion, from the binary framing that you're talking about here. That is a a significant simplification over HTTP/1.
Developers of almost any skill level can write an HTTP/1.1 compatible implementation (and its fault tolerant enough that compatible-ish is ok). Soon we will live in a world with 3 or 4 HTTP/2.0 libraries and developers will have almost no knowledge of how the thing works under the hood.
It's not as if it needs to become opaque to developers. If people need a way to introspect a SPDY connection, someone will write a tool.
This is in the same vein as TCP, TLS, or DNS. Developers use these technologies all the time, and it exposes a simple interface to them, but all of them are quite complicated under the covers. I don't believe that Nagle's algorithm or the UDP framing for DNS is common knowledge amongst the majority of developers.
Similarly, SPDY or HTTP/2.0 will expose a simple interface to developers, but internally transport the content in an efficient, if somewhat inscrutable, manner.
While I appreciate the sentiment that HTTP is easy to understand as it stands, I'd rather not optimize for "developers of almost any skill level". While it would be totally OK for you to write a HTTP/1.1 parser as a toy, it would be somewhat crazy for you to use that implementation in a production scenario.
There, everybody uses a small set of implementations that have been vetted: Firefox, Chrome, Apache, Nginx, etc. These guys work extremely hard to make sure that their implementation is solid not merely "compatible-ish". I'd rather optimize for them, rather than the beginners. I'd rather make it easy for them to write correct implementations. I'd rather jettison the "fault tolerant enough that compatible-ish is ok" design of HTTP/1.1 that makes their life so difficult.
I think you made the point for me. TCP, TLS, and DNS (with the exception of OpenDNS a good 20 years later) see no innovation or hacking from startups. Compare to plain text protocols like HTTP.
"
Your premise seems to be that SPDY is a complex binary protocol and we don't need that achieve mux. I don't see much evidence for your complexity assertion - especially when compared with HTTP/1.
Consider the difference in finding the message boundaries of a SPDY message with an HTTP/1.1 one.
To process the SPDY message you
* buffer 8 bytes of data
* determine that it is a data packet by confirming (buf[0] & 0x80 == 0)
* determine the length of the data by ntohl(((uint32_t)buf)[1)& 0x00ffffff
* find out if there are more chunks to come by looking at (buf[4] & 1).
All done. It is very straightforward, efficient, well bounded, and testable.
Contrast that with parsing a HTTP/1 message.
* read "enough" data from the network. You don't know how much that is and if you read too much you have to implement some facility for "putting it back" so the next message can use it. This inevitably leads to streaming parsers and their inherent complexity and lack of efficiency.
* parse the headers so you can determine which message delimiter is being used. To parse the header you have to implement line folding, implement a tokenizer aware of various rules around quotation marks and colons, and adopt to a number of real-world variations in the use of line endings other than just CRLF. To do this you have to run a state machine against every byte of input rather than directly address fixed offsets.
* Implement strategies to deal with conflicts such "Content-Length: 42, 17" and "Content-Length: 95\r\nTransfer-Encoding: chunked\r\n"
* you need to implement an ascii to integer conversion routine to determine the status code because some status codes implicitly impact message delimiters (e.g. 304).
* now you have to implement no less than 5 message delimiting schemes - chunked encodings, EOF, content-length, implicit (304), and everyone's favorite multibyte/ranges.
* If you have content-length or a chunk you'll need to convert a text string to an integer again.. and http/1 doesn't bound the size of the text string so you'll either have a common bug with an overflow or you'll implement an undiscoverable constraint in your implementation leading to cases of failing interop.
* you'll still have exposure to a whole class of CRLF injection attacks inherent in the text format.
The binary framing is so much less complex and significant improvement. Sure, to the naked eye in a log it may not look that way but that is optimizing for all the wrong things and can be quite misleading - do you really interpret a HTTP header with line folding or \n\r instead of \r\n sequences correctly when eyeballing it?)
Now there certainly is some complexity in SPDY but it doesn't come, in my opinion, from the binary framing that you're talking about here. That is a a significant simplification over HTTP/1.
"
[1] https://hacks.mozilla.org/2012/02/spdy-brings-responsive-and...