apple / swift-nio-http2

HTTP/2 support for SwiftNIO
https://swiftpackageindex.com/apple/swift-nio-http2/main/documentation/niohttp2
Apache License 2.0
462 stars 82 forks source link

Correctly respect changes to HEADER_TABLE_SIZE #374

Closed Lukasa closed 1 year ago

Lukasa commented 1 year ago

Motivation:

When remote peers set the value of HEADER_TABLE_SIZE to any non-default value, or when we update it, we should respect that value when we're emitting headers.

Unfortunately, right now we don't. In particular, we manage to update the wrong setting: when the peer sets HEADER_TABLE_SIZE we bound the maximum size of the dynamic table they can use, not the maximum size we can use. That's incorrect by the spec, which says:

This setting allows the sender to inform the remote endpoint of the maximum size of the compression table used to decode field blocks, in units of octets. The encoder can select any size equal to or less than this value by using signaling specific to the compression format inside a field block (see [COMPRESSION]).

If a peer sent us SETTINGS_HEADER_TABLE_SIZE with a value of 0, we'd restrict them to only using a maximum table size of 0, instead of us. This is wrong.

Additionally, when we updated the encoder we used the wrong method, so the encoder would never send dynamic table size changes. This was also incorrect!

In general this managed to get missed because, as RFC 9113 notes:

Implementers are advised that reducing the value of SETTINGS_HEADER_TABLE_SIZE is not widely interoperable. Use of the connection preface to reduce the value below the initial value of 4,096 is somewhat better supported, but this might fail with some implementations.

It turns out one of those implementations this might fail with is us! The result, however, is that very few implementations actually try to reduce the value of the header table size, so we rarely ran into this issue. nginx does actually try this in some cases, however, which is how we found this problem.

Modifications:

Result:

Vastly better handling of peers reducing the value of SETTINGS_HEADER_TABLE_SIZE.