Re: HTTP router point-of-view concerns

On 11/07/2013 9:49 p.m., Christian Parpart wrote:
> On Thu, Jul 11, 2013 at 4:53 AM, Amos Jeffries <squid3@treenet.co.nz 
> <mailto:squid3@treenet.co.nz>> wrote:
>
>     On 11/07/2013 10:52 a.m., Christian Parpart wrote:
>
>         Hey guys,
>
>         I am just new to this list and I've just recently started
>         working through the HTTP/2 draft and all the blog articles
>         found about.
>         That being said, I myself have also very concerns others have
>         noticed as well, and would like to deeply show my intention to
>         help standing aside :)
>
>         I am the implementor of one of the many HTTP servers that's
>         being used in production, and one major feature is HTTP
>         routing / load balancing,
>         and I would really love to implement an HTTP/1.1 successor
>         that is (to be) officially labeled HTTP/2[.0].
>
>         However, as a varnish [1] and a BSD [2] guy also raised there
>         hands on, is the lag of easy extraction of envelop information
>         of an HTTP request message, such as method, path, but most
>         certainly the host.
>
>         Please forgive me if this is already on-topic somewhere
>         hidden, however, I would really highly encourage you to consider
>         adding some dedicated frame type for this kind of envelope
>         information.
>
>         With that in mind, one might say that an HTTP/2 stream is not
>         initiated by a HEADERS frame but the ENVELOPE frame that
>         contains the actual
>         uncompressed and unmystified but compact information about
>         this request message.
>
>         One humble proposal might indeed be:
>
>         type: (something unassigned)
>         flags: bit 1 = END_STREAM /* this HTTP message is complete
>         with just these envelope frame, e.g. a simple GET, and no need
>         for user-agent etc. */
>         id: unique stream ID, semantics like any other stream ID
>         body: a key/value table of the envelope data
>
>         ENVELOPE FRAME DATA:
>
>         The envelope data table is a simple table of key/value pairs
>         where the key is an 8bit value identifying the entry
>         and a variable length value that is interpreted depending on
>         the key. The list of provided envelope fields ends
>         as the end of the envelope frame has been reached. that means,
>         an envelope must always fit into a single (first) frame.
>
>         ENVELOPE KEY/VALUE FIELDS:
>
>           * :scheme => uint8: 0x01
>               o http => uint8: 0x01
>               o https => uint8: 0x02
>               o custom => same as in method (if this is distinction is
>         really
>                 demanded)
>           * :method => uint8: 0x02
>               o GET => uint8: 0x01
>               o POST => uint8: 0x02
>               o PUT => uint8: 0x03
>               o DELETE => uint8:0x04
>               o custom => uint8: 0xFF, followed by one uint8 encoding
>         the size
>
>                 of the following bytes declaring the plaintext method
>         value,
>                 e.g. "PROPFIND"
>           * :path => uint8: 0x03, uint16 length in network byte order,
>
>             followed by $length octects declaring the path's value.
>           * :host => uint8: 0x04, uint16: length in network byte order,
>
>             $length octets declaring the host's value.
>           * :route => uint8: 0x05, uint8: length, $length octets that
>         declare
>
>             this value. (field is only specified if known, thus
>         previousely
>             announced by the remote server or this frame is part of a
>         response
>             and we are to announce a routing identifier)
>           * :status => uint8: 0x06, uint16: code in network byte order
>          /* if
>
>             HTTP/2 considers starting response streams the same way */
>
>         This is the exact information an HTTP client
>         (scheme,method,path,host) or server (status) MUST currently
>         sent as part of the (first) HEADERS frame.
>         So the change I propose is, to extract this information from
>         the HEADERS frame and put it into its own frame that also
>         initiates the stream implicitly.
>
>         Having this in mind, it is a pleasure to implement HTTP
>         routers because those now don't have to decode the full
>         HEADERS frames but just decode the ENVELOPE frame and pass any
>         continued frame to the directed next-hop server.
>
>
>     Sadly the compression draft as written is completely incompatible
>     with this type of load balancing. It operates a *stateful*
>     compressor, such that every single HEADERS frame being received
>     has to be decoded in order to re-encode using a separate
>     connection-specific stateful compressor on the next-hop
>     connections. This is mandatory for the compressed frames
>     regardless of whether the ENVELOPE header is used to provide
>     uncompressed details.
>
>
> I hope we did not misunderstand each other, with "ENVELOPE" I meant a 
> frame on its own that 1.) initiates a stream and 2.) contains the most 
> important envelope information needed to route a message.

I think I understand you. We considered something very similar early in 
the arguments against original SPDY design.

Consider that the client may send the load banacer a set of HEADERS 
after your ENVELOPE block. One of these HEADERS (doesn't matter which 
one) contains a header which is added to the decompressor state table 
and then used by teh following HEADERS blocks.
Your load balancer which does not do compression may send that HEADERS 
lock to server #1 and the others which depend on it to server #2, #3... etc.
The net result is corrupted decompression state at the servers #2 etc, 
and over time unpredictable HTTP syntax being received and acted on by 
all servers.


>      The best load balancers can do under the current compression
>     draft is to avoid complex re-encoding by emiting only Literal
>     header representations and skipping all the traffic optimizations
>     compression offers. Which converts them into near perfect DDoS
>     bandwidth-amplification sources.
>
>
> here I don't think that will be much of the case, since HTTP/2 header 
> encoding should still be a way smaller in bytes than HTTP/1.1 and prior.

Only in compressed form. The Literal form is equivalent to 
non-compressed HTTP/1.1 syntax. So the bandwidth is being expanded from 
HTTP/2 size up to HTTP/1 size. Low input causing the relay to generate 
large output is the very definition of amplification.


>
>     The sad state of affairs is that the *only* type of middleware
>     which benefits from the proposed HTTP/2 is those which performs
>     transparent interception and passive monitoring/recording of users
>     traffic (ie the worst kind). Anything which starts modifying or
>     manipulating (ie doing something useful for the ISP or CDN) MUST
>     implement a full compressor/decompressor pair in order to keep the
>     HTTP/2 statefulness in order.
>
>
> If HTTP/2 now would just put the routing information (method, path, 
> host, scheme [, routing-key]) cleartext upfront (still binary) an 
> active HTTP router could just parse this and pass the remaining as-is 
> (e.g. unmodified) to the next-hop. Although, if it then still whishes 
> to add special headers (such as Via), it could do so via the trailing 
> HEADERS frame) - if I am not too wrong.

See my example about the HEADERS block state inter-dependency.

Amos

Received on Thursday, 11 July 2013 10:09:23 UTC