Clarification of dynamic table size change

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

Clarification of dynamic table size change

Tatsuhiro Tsujikawa
Hi,

I got the bug report from nghttp2 user: https://github.com/tatsuhiro-t/nghttp2/issues/396

When nghttp client sends SETTINGS_HEADER_TABLE_SIZE=4096 in the first SETTINGS, it looks like google server does not send back dynamic table size update.  This is probably because they think that it is not necessary because table size is not changed.

I'd like to clarify this is a valid behavior.  Specification is not clear enough in this special case.
So the question is whether we are required to send dynamic table size update as acknowledgement for SETTINGS_HEADER_TABLE_SIZE if it is included in SETTINGS?

In https://tools.ietf.org/html/rfc7540#section-6.5.2
```
  SETTINGS_HEADER_TABLE_SIZE (0x1):  Allows the sender to inform the
      remote endpoint of the maximum size of the header compression
      table used to decode header blocks, in octets.  The encoder can
      select any size equal to or less than this value by using
      signaling specific to the header compression format inside a
      header block (see [COMPRESSION]).  The initial value is 4,096
      octets.
```
In https://tools.ietf.org/html/rfc7541#section-4.2
```
   A change in the maximum size of the dynamic table is signaled via a
   dynamic table size update (see Section 6.3).  This dynamic table size
   update MUST occur at the beginning of the first header block
   following the change to the dynamic table size.  In HTTP/2, this
   follows a settings acknowledgment (see Section 6.5.3 of [HTTP2]).
```

In https://tools.ietf.org/html/rfc7541#section-6.3
```
   The new maximum size MUST be lower than or equal to the limit
   determined by the protocol using HPACK.  A value that exceeds this
   limit MUST be treated as a decoding error.  In HTTP/2, this limit is
   the last value of the SETTINGS_HEADER_TABLE_SIZE parameter (see
   Section 6.5.2 of [HTTP2]) received from the decoder and acknowledged
   by the encoder (see Section 6.5.3 of [HTTP2]).
```

I can read that dynamic table size update is always necessary as acknowledgement of SETTINGS_HEADER_TABLE_SIZE if it is present in SETTINGS.
But someone can read in the other way.

Best regards,
Tatsuhiro Tsujikawa

Reply | Threaded
Open this post in threaded view
|

Re: Clarification of dynamic table size change

Cory Benfield

> On 19 Oct 2015, at 16:59, Tatsuhiro Tsujikawa <[hidden email]> wrote:
>
> I can read that dynamic table size update is always necessary as acknowledgement of SETTINGS_HEADER_TABLE_SIZE if it is present in SETTINGS.
> But someone can read in the other way.

Yeah, see, I read it the other way. My reading of section 4.2 of RFC 7541 emphasises this: “a *change* in the maximum size […] is signalled”. But you’re right that it’s ambiguous. In this case, I’d say that an implementation MAY emit a dynamic table size update if the size is unchanged (because it’s a no-op), but MUST do so if it has changed. For implementation simplicity, many implementations will chose to always emit that size update, but equally many implementations will not. If we’re counting, my own implementation does the same thing as Google’s: see here[0].

Specifically, I don’t think the HPACK layer should complain because a dynamic table size update was not received when the dynamic table size did not change. In this instance I believe nghttp2 is being overly strict about the relationship between the HTTP/2 layer and the HPACK layer.

Cory

[0]: https://github.com/python-hyper/hpack/blob/master/hpack/table.py#L188

signature.asc (817 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Clarification of dynamic table size change

Tatsuhiro Tsujikawa
Hi,

On Tue, Oct 20, 2015 at 1:12 AM, Cory Benfield <[hidden email]> wrote:

> On 19 Oct 2015, at 16:59, Tatsuhiro Tsujikawa <[hidden email]> wrote:
>
> I can read that dynamic table size update is always necessary as acknowledgement of SETTINGS_HEADER_TABLE_SIZE if it is present in SETTINGS.
> But someone can read in the other way.

Yeah, see, I read it the other way. My reading of section 4.2 of RFC 7541 emphasises this: “a *change* in the maximum size […] is signalled”. But you’re right that it’s ambiguous. In this case, I’d say that an implementation MAY emit a dynamic table size update if the size is unchanged (because it’s a no-op), but MUST do so if it has changed. For implementation simplicity, many implementations will chose to always emit that size update, but equally many implementations will not. If we’re counting, my own implementation does the same thing as Google’s: see here[0].

Specifically, I don’t think the HPACK layer should complain because a dynamic table size update was not received when the dynamic table size did not change. In this instance I believe nghttp2 is being overly strict about the relationship between the HTTP/2 layer and the HPACK layer.


​Could be.  But I don't think we mixed HTTP/2 layer and HPACK layer.  More specifically, we input the max header table size to HPACK, and see what it react to it in this case.  It is specific to HPACK implementation behaviour.

In general, we choose simpler path in HTTP/2​, I mean single execution path rather than "do this if we have x otherwise do that".  For example, we require client preface even if we negotiated HTTP/2 over ALPN.
We send HTTP2-Settings in HTTP Upgrade request, but still we need to send SETTINGS frame in client preface.
Taking into account of this split, it is more natural to always send header table size update as acknowledgement for SETTINGS_HEADER_TABLE_SIZE.  We can do more strict validation about the peer; it might forget to implement it anyway.

Best regards,
Tatsuhiro Tsujikawa


 
Cory

[0]: https://github.com/python-hyper/hpack/blob/master/hpack/table.py#L188

Reply | Threaded
Open this post in threaded view
|

Re: Clarification of dynamic table size change

Cory Benfield

On 19 Oct 2015, at 17:26, Tatsuhiro Tsujikawa <[hidden email]> wrote:
​Could be.  But I don't think we mixed HTTP/2 layer and HPACK layer.  More specifically, we input the max header table size to HPACK, and see what it react to it in this case.  It is specific to HPACK implementation behaviour.

In general, we choose simpler path in HTTP/2​, I mean single execution path rather than "do this if we have x otherwise do that".  For example, we require client preface even if we negotiated HTTP/2 over ALPN.
We send HTTP2-Settings in HTTP Upgrade request, but still we need to send SETTINGS frame in client preface.
Taking into account of this split, it is more natural to always send header table size update as acknowledgement for SETTINGS_HEADER_TABLE_SIZE.  We can do more strict validation about the peer; it might forget to implement it anyway.

I don’t know that I buy that. The acknowledgement for SETTINGS_HEADER_TABLE_SIZE is a SETTINGS frame with the ACK flag set. Why is further acknowledgement required? As far as I can see it, there are two (slightly different) values here:

- SETTINGS_HEADER_TABLE_SIZE is the *maximum* value the encoder may use.
- Whatever is sent by the HPACK encoder in a dynamic table size update is the *actual* value being used.

You may be able to change the first without affecting the second (e.g. if you raise or leave unchanged the value of SETTINGS_HEADER_TABLE_SIZE). In the case that the second is not affected, it seems like unnecessary noise for the encoder to be forced to emit a dynamic table size update that has no change.

I don’t strongly object to adding an erratum to RFC 7541 that requires that a dynamic table update be emitted for any change to SETTINGS_HEADER_TABLE_SIZE, even if that change does not actually affect the size of the table the encoder will use, but my current reading of the specification does not require that such an update be emitted.

Cory

signature.asc (817 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Clarification of dynamic table size change

RUELLAN Herve
I agree that the wording is ambiguous here.

However, my reading is the same a Cory's: you don't have to send a dynamic table update if the *actual* value is not changed.

Hervé

On 19/10/15 19:15, Cory Benfield wrote:

>
> > On 19 Oct 2015, at 17:26, Tatsuhiro Tsujikawa <[hidden email]
> > <mailto:[hidden email]>> wrote:
> > ​Could be.  But I don't think we mixed HTTP/2 layer and HPACK layer.
> > More specifically, we input the max header table size to HPACK, and
> > see what it react to it in this case.  It is specific to HPACK
> > implementation behaviour.
> >
> > In general, we choose simpler path in HTTP/2​, I mean single execution
> > path rather than "do this if we have x otherwise do that".  For
> > example, we require client preface even if we negotiated HTTP/2 over ALPN.
> > We send HTTP2-Settings in HTTP Upgrade request, but still we need to
> > send SETTINGS frame in client preface.
> > Taking into account of this split, it is more natural to always send
> > header table size update as acknowledgement for
> > SETTINGS_HEADER_TABLE_SIZE.  We can do more strict validation about
> > the peer; it might forget to implement it anyway.
>
> I don’t know that I buy that. The acknowledgement for
> SETTINGS_HEADER_TABLE_SIZE is a SETTINGS frame with the ACK flag set.
> Why is further acknowledgement required? As far as I can see it, there
> are two (slightly different) values here:
>
> - SETTINGS_HEADER_TABLE_SIZE is the *maximum* value the encoder may use.
> - Whatever is sent by the HPACK encoder in a dynamic table size update
> is the *actual* value being used.
>
> You may be able to change the first without affecting the second (e.g.
> if you raise or leave unchanged the value of
> SETTINGS_HEADER_TABLE_SIZE). In the case that the second is not
> affected, it seems like unnecessary noise for the encoder to be forced
> to emit a dynamic table size update that has no change.
>
> I don’t strongly object to adding an erratum to RFC 7541 that requires
> that a dynamic table update be emitted for any change to
> SETTINGS_HEADER_TABLE_SIZE, even if that change does not actually affect
> the size of the table the encoder will use, but my current reading of
> the specification does not require that such an update be emitted.
>
> Cory


Reply | Threaded
Open this post in threaded view
|

Re: Clarification of dynamic table size change

Tatsuhiro Tsujikawa
Hi,

On Fri, Oct 23, 2015 at 1:18 AM, Hervé Ruellan <[hidden email]> wrote:
I agree that the wording is ambiguous here.

However, my reading is the same a Cory's: you don't have to send a dynamic table update if the *actual* value is not changed.


​I also found the discussion in this ML indicating you are right.  Thank you for clarification.
I have to ask one more question: what is *actual* value? Is it the table size both peer agreed before reading SETTINGS, or the value in SETTINGS_HEADER_TABLE_SIZE decoder sent?

I think this is a good item to add in FAQ section..


Best regards,
Tatsuhiro Tsujikawa
​​


 
Hervé

On 19/10/15 19:15, Cory Benfield wrote:

> On 19 Oct 2015, at 17:26, Tatsuhiro Tsujikawa <[hidden email]
> <mailto:[hidden email]>> wrote:
> ​Could be.  But I don't think we mixed HTTP/2 layer and HPACK layer.
> More specifically, we input the max header table size to HPACK, and
> see what it react to it in this case.  It is specific to HPACK
> implementation behaviour.
>
> In general, we choose simpler path in HTTP/2​, I mean single execution
> path rather than "do this if we have x otherwise do that".  For
> example, we require client preface even if we negotiated HTTP/2 over ALPN.
> We send HTTP2-Settings in HTTP Upgrade request, but still we need to
> send SETTINGS frame in client preface.
> Taking into account of this split, it is more natural to always send
> header table size update as acknowledgement for
> SETTINGS_HEADER_TABLE_SIZE.  We can do more strict validation about
> the peer; it might forget to implement it anyway.

I don’t know that I buy that. The acknowledgement for
SETTINGS_HEADER_TABLE_SIZE is a SETTINGS frame with the ACK flag set.
Why is further acknowledgement required? As far as I can see it, there
are two (slightly different) values here:

- SETTINGS_HEADER_TABLE_SIZE is the *maximum* value the encoder may use.
- Whatever is sent by the HPACK encoder in a dynamic table size update
is the *actual* value being used.

You may be able to change the first without affecting the second (e.g.
if you raise or leave unchanged the value of
SETTINGS_HEADER_TABLE_SIZE). In the case that the second is not
affected, it seems like unnecessary noise for the encoder to be forced
to emit a dynamic table size update that has no change.

I don’t strongly object to adding an erratum to RFC 7541 that requires
that a dynamic table update be emitted for any change to
SETTINGS_HEADER_TABLE_SIZE, even if that change does not actually affect
the size of the table the encoder will use, but my current reading of
the specification does not require that such an update be emitted.

Cory


Reply | Threaded
Open this post in threaded view
|

Re: Clarification of dynamic table size change

Ilari Liusvaara-2
On Sat, Oct 24, 2015 at 12:45:49AM +0900, Tatsuhiro Tsujikawa wrote:

> Hi,
>
> On Fri, Oct 23, 2015 at 1:18 AM, Hervé Ruellan <[hidden email]>
> wrote:
>
> > I agree that the wording is ambiguous here.
> >
> > However, my reading is the same a Cory's: you don't have to send a dynamic
> > table update if the *actual* value is not changed.
> >
> >
> ​I also found the discussion in this ML indicating you are right.  Thank
> you for clarification.
> I have to ask one more question: what is *actual* value? Is it the table
> size both peer agreed before reading SETTINGS, or the value in
> SETTINGS_HEADER_TABLE_SIZE decoder sent?
>
> I think this is a good item to add in FAQ section..

The way negotiation works:
- Decoder side sets the upper bound via SETTINGS_HEADER_TABLE_SIZE.
- Encoder side sets the actual size via dynamic table updates (inside
  HPACK bitstream) within limits set by decoder.
- If between headers decoder reduces the limit below size signaled by
  encoder, the encoder must first reduce the table size to the minimum
  it was between the frames or less (it can then increase it up to
  current limit).

As example of the last point:
[4k dynamic table size in use]
--> HEADERS
<-- SETTINGS(SETTINGS_HEADER_TABLE_SIZE=4k)
<-- SETTINGS(SETTINGS_HEADER_TABLE_SIZE=2k)
<-- SETTINGS(SETTINGS_HEADER_TABLE_SIZE=4k)
<-- SETTINGS(SETTINGS_HEADER_TABLE_SIZE=8k)
<-- SETTINGS(SETTINGS_HEADER_TABLE_SIZE=6k)
--> HEADERS

The second HEADERS must first reduce the dynamic table to at most
2k. It can then increase dynamic table size to up to 6k.


-Ilari

Reply | Threaded
Open this post in threaded view
|

Re: Clarification of dynamic table size change

Bence Béky
Hi all,

I'm sorry to revive this old thread, but there is one more case that I would
like to request clarification for.  I was looking at both RFC 7540 and 7541, but
could not find a definitive answer to the following question:  What is the
initial maximum size of the dynamic table if there was a
SETTINGS_HEADER_TABLE_SIZE value in the initial SETTINGS frame (the one part of
the connection preface)?

For example, suppose that the decoder sends a SETTINGS_HEADER_TABLE with value
64 * 1024 in the initial SETTINGS frame.  Do we think about the HPACK context to
be created after the connection preface is sent, with a maximum dynamic table
size of the current SETTINGS_HEADER_TABLE_SIZE value of 64 kB?  Or do we think
about the HPACK context to be created before the connection preface is sent,
with a default maximum dynamic table size of 4 kB?  Note that there is no
synchronization issue even in the former case: if the decoder only evicts
dynamic table entries above 64 kB from the very beginning, there is no harm in
the encoder not starting to reference entries above 4 kB until it processes the
decoder's initial SETTINGS frame.

Suppose that the encoder does not emit a "dynamic table size update" HPACK
instruction after this.  The consensus on this e-mail thread seems to be that
this is acceptable as long as the encoder means "no change" to the maximum
dynamic table size.  It is, however, important that the encoder and the decoder
are in agreement about the initial maximum dynamic table size, relative to which
the encoder means "no change".  For example, if the decoder is under the
impression that the maximum dynamic table size is 4 kB, while the encoder takes
it to be 64 kB, then the decoder will signal a CONNECTION_ERROR as soon as the
encoder references an entry above 4 kB.  If, on the other hand, the encoder
thinks it's 4 kB and never references entries above that, then the decoder would
waste memory if it kept 64 kB worth of entries.

Given that a decoder can send a SETTINGS_HEADER_TABLE_SIZE with a value lower
than the default, and the encoder can start compressing headers before receiving
the initial SETTINGS frame, it seems necessary to me to understand the initial
maximum dynamic table size to be 4 kB, and to require the decoder to store this
much entries until it receives the dynamic table size update HPACK instruction
from the encoder.  Otherwise a COMPRESSION_ERROR arises due to the
synchronization issue even if the peers agree that the initial size is the new
(lower) value.  Unless, of course,  we want to formulate different requirements
depending on whether the SETTINGS_HEADER_TABLE_SIZE value is greater than or
less than the default.

If I implement a decoder in this spirit, that is, one that sends a
SETTINGS_HEADER_TABLE_SIZE of 64 kB in the initial SETTINGS frame, but does not
allow more than default memory for the dynamic table until it receives a dynamic
table size update from the encoder, would it be incompatible with anybody's
current implementation?

Best regards,

Bence Béky


On Fri, Oct 23, 2015 at 12:15 PM, Ilari Liusvaara <[hidden email]> wrote:
On Sat, Oct 24, 2015 at 12:45:49AM +0900, Tatsuhiro Tsujikawa wrote:
> Hi,
>
> On Fri, Oct 23, 2015 at 1:18 AM, Hervé Ruellan <[hidden email]>
> wrote:
>
> > I agree that the wording is ambiguous here.
> >
> > However, my reading is the same a Cory's: you don't have to send a dynamic
> > table update if the *actual* value is not changed.
> >
> >
> ​I also found the discussion in this ML indicating you are right.  Thank
> you for clarification.
> I have to ask one more question: what is *actual* value? Is it the table
> size both peer agreed before reading SETTINGS, or the value in
> SETTINGS_HEADER_TABLE_SIZE decoder sent?
>
> I think this is a good item to add in FAQ section..

The way negotiation works:
- Decoder side sets the upper bound via SETTINGS_HEADER_TABLE_SIZE.
- Encoder side sets the actual size via dynamic table updates (inside
  HPACK bitstream) within limits set by decoder.
- If between headers decoder reduces the limit below size signaled by
  encoder, the encoder must first reduce the table size to the minimum
  it was between the frames or less (it can then increase it up to
  current limit).

As example of the last point:
[4k dynamic table size in use]
--> HEADERS
<-- SETTINGS(SETTINGS_HEADER_TABLE_SIZE=4k)
<-- SETTINGS(SETTINGS_HEADER_TABLE_SIZE=2k)
<-- SETTINGS(SETTINGS_HEADER_TABLE_SIZE=4k)
<-- SETTINGS(SETTINGS_HEADER_TABLE_SIZE=8k)
<-- SETTINGS(SETTINGS_HEADER_TABLE_SIZE=6k)
--> HEADERS

The second HEADERS must first reduce the dynamic table to at most
2k. It can then increase dynamic table size to up to 6k.


-Ilari


Reply | Threaded
Open this post in threaded view
|

Re: Clarification of dynamic table size change

Tatsuhiro Tsujikawa
​Hi,​

On Thu, Aug 18, 2016 at 10:31 PM, Bence Béky <[hidden email]> wrote:
Hi all,

I'm sorry to revive this old thread, but there is one more case that I would
like to request clarification for.  I was looking at both RFC 7540 and 7541, but
could not find a definitive answer to the following question:  What is the
initial maximum size of the dynamic table if there was a
SETTINGS_HEADER_TABLE_SIZE value in the initial SETTINGS frame (the one part of
the connection preface)?

For example, suppose that the decoder sends a SETTINGS_HEADER_TABLE with value
64 * 1024 in the initial SETTINGS frame.  Do we think about the HPACK context to
be created after the connection preface is sent, with a maximum dynamic table
size of the current SETTINGS_HEADER_TABLE_SIZE value of 64 kB?  Or do we think
about the HPACK context to be created before the connection preface is sent,
with a default maximum dynamic table size of 4 kB?  Note that there is no
synchronization issue even in the former case: if the decoder only evicts
dynamic table entries above 64 kB from the very beginning, there is no harm in
the encoder not starting to reference entries above 4 kB until it processes the
decoder's initial SETTINGS frame.

Suppose that the encoder does not emit a "dynamic table size update" HPACK
instruction after this.  The consensus on this e-mail thread seems to be that
this is acceptable as long as the encoder means "no change" to the maximum
dynamic table size.  It is, however, important that the encoder and the decoder
are in agreement about the initial maximum dynamic table size, relative to which
the encoder means "no change".  For example, if the decoder is under the
impression that the maximum dynamic table size is 4 kB, while the encoder takes
it to be 64 kB, then the decoder will signal a CONNECTION_ERROR as soon as the
encoder references an entry above 4 kB.  If, on the other hand, the encoder
thinks it's 4 kB and never references entries above that, then the decoder would
waste memory if it kept 64 kB worth of entries.

Given that a decoder can send a SETTINGS_HEADER_TABLE_SIZE with a value lower
than the default, and the encoder can start compressing headers before receiving
the initial SETTINGS frame, it seems necessary to me to understand the initial
maximum dynamic table size to be 4 kB, and to require the decoder to store this
much entries until it receives the dynamic table size update HPACK instruction
from the encoder.  Otherwise a COMPRESSION_ERROR arises due to the
synchronization issue even if the peers agree that the initial size is the new
(lower) value.  Unless, of course,  we want to formulate different requirements
depending on whether the SETTINGS_HEADER_TABLE_SIZE value is greater than or
less than the default.

If I implement a decoder in this spirit, that is, one that sends a
SETTINGS_HEADER_TABLE_SIZE of 64 kB in the initial SETTINGS frame, but does not
allow more than default memory for the dynamic table until it receives a dynamic
table size update from the encoder, would it be incompatible with anybody's
current implementation?


According to this thread, ​I'm under impression ​that this is OK, and until you get dynamic table size update, default 4KiB dynamic table limit still applies.

As for initial value of dynamic table size, I think it is 4KiB regardless of SETTINGS.  We create HTTP/2 session before doing any parameter modification, including header table size change.  At this moment, table size if 4KiB, RFC default.  After that, decoder send SETTINGS_HEADER_TABLE_SIZE with whatever value they want.  Then after SETTINGS ACK, and HPACK table size update, dynamic table size is finally synchronized, and changed to the value encoder sent in HPACK table size update (as long as it is equal or smaller than decoder sent in SETTINGS).

Best regards,
Tatsuhiro Tsujikawa


 
Best regards,

Bence Béky


On Fri, Oct 23, 2015 at 12:15 PM, Ilari Liusvaara <[hidden email]> wrote:
On Sat, Oct 24, 2015 at 12:45:49AM +0900, Tatsuhiro Tsujikawa wrote:
> Hi,
>
> On Fri, Oct 23, 2015 at 1:18 AM, Hervé Ruellan <[hidden email]>
> wrote:
>
> > I agree that the wording is ambiguous here.
> >
> > However, my reading is the same a Cory's: you don't have to send a dynamic
> > table update if the *actual* value is not changed.
> >
> >
> ​I also found the discussion in this ML indicating you are right.  Thank
> you for clarification.
> I have to ask one more question: what is *actual* value? Is it the table
> size both peer agreed before reading SETTINGS, or the value in
> SETTINGS_HEADER_TABLE_SIZE decoder sent?
>
> I think this is a good item to add in FAQ section..

The way negotiation works:
- Decoder side sets the upper bound via SETTINGS_HEADER_TABLE_SIZE.
- Encoder side sets the actual size via dynamic table updates (inside
  HPACK bitstream) within limits set by decoder.
- If between headers decoder reduces the limit below size signaled by
  encoder, the encoder must first reduce the table size to the minimum
  it was between the frames or less (it can then increase it up to
  current limit).

As example of the last point:
[4k dynamic table size in use]
--> HEADERS
<-- SETTINGS(SETTINGS_HEADER_TABLE_SIZE=4k)
<-- SETTINGS(SETTINGS_HEADER_TABLE_SIZE=2k)
<-- SETTINGS(SETTINGS_HEADER_TABLE_SIZE=4k)
<-- SETTINGS(SETTINGS_HEADER_TABLE_SIZE=8k)
<-- SETTINGS(SETTINGS_HEADER_TABLE_SIZE=6k)
--> HEADERS

The second HEADERS must first reduce the dynamic table to at most
2k. It can then increase dynamic table size to up to 6k.


-Ilari



Reply | Threaded
Open this post in threaded view
|

Re: Clarification of dynamic table size change

Patrick McManus
Tatsuhiro's description matches my understanding.

-Patrick


On Thu, Aug 18, 2016 at 9:50 AM, Tatsuhiro Tsujikawa <[hidden email]> wrote:
​Hi,​

On Thu, Aug 18, 2016 at 10:31 PM, Bence Béky <[hidden email]> wrote:
Hi all,

I'm sorry to revive this old thread, but there is one more case that I would
like to request clarification for.  I was looking at both RFC 7540 and 7541, but
could not find a definitive answer to the following question:  What is the
initial maximum size of the dynamic table if there was a
SETTINGS_HEADER_TABLE_SIZE value in the initial SETTINGS frame (the one part of
the connection preface)?

For example, suppose that the decoder sends a SETTINGS_HEADER_TABLE with value
64 * 1024 in the initial SETTINGS frame.  Do we think about the HPACK context to
be created after the connection preface is sent, with a maximum dynamic table
size of the current SETTINGS_HEADER_TABLE_SIZE value of 64 kB?  Or do we think
about the HPACK context to be created before the connection preface is sent,
with a default maximum dynamic table size of 4 kB?  Note that there is no
synchronization issue even in the former case: if the decoder only evicts
dynamic table entries above 64 kB from the very beginning, there is no harm in
the encoder not starting to reference entries above 4 kB until it processes the
decoder's initial SETTINGS frame.

Suppose that the encoder does not emit a "dynamic table size update" HPACK
instruction after this.  The consensus on this e-mail thread seems to be that
this is acceptable as long as the encoder means "no change" to the maximum
dynamic table size.  It is, however, important that the encoder and the decoder
are in agreement about the initial maximum dynamic table size, relative to which
the encoder means "no change".  For example, if the decoder is under the
impression that the maximum dynamic table size is 4 kB, while the encoder takes
it to be 64 kB, then the decoder will signal a CONNECTION_ERROR as soon as the
encoder references an entry above 4 kB.  If, on the other hand, the encoder
thinks it's 4 kB and never references entries above that, then the decoder would
waste memory if it kept 64 kB worth of entries.

Given that a decoder can send a SETTINGS_HEADER_TABLE_SIZE with a value lower
than the default, and the encoder can start compressing headers before receiving
the initial SETTINGS frame, it seems necessary to me to understand the initial
maximum dynamic table size to be 4 kB, and to require the decoder to store this
much entries until it receives the dynamic table size update HPACK instruction
from the encoder.  Otherwise a COMPRESSION_ERROR arises due to the
synchronization issue even if the peers agree that the initial size is the new
(lower) value.  Unless, of course,  we want to formulate different requirements
depending on whether the SETTINGS_HEADER_TABLE_SIZE value is greater than or
less than the default.

If I implement a decoder in this spirit, that is, one that sends a
SETTINGS_HEADER_TABLE_SIZE of 64 kB in the initial SETTINGS frame, but does not
allow more than default memory for the dynamic table until it receives a dynamic
table size update from the encoder, would it be incompatible with anybody's
current implementation?


According to this thread, ​I'm under impression ​that this is OK, and until you get dynamic table size update, default 4KiB dynamic table limit still applies.

As for initial value of dynamic table size, I think it is 4KiB regardless of SETTINGS.  We create HTTP/2 session before doing any parameter modification, including header table size change.  At this moment, table size if 4KiB, RFC default.  After that, decoder send SETTINGS_HEADER_TABLE_SIZE with whatever value they want.  Then after SETTINGS ACK, and HPACK table size update, dynamic table size is finally synchronized, and changed to the value encoder sent in HPACK table size update (as long as it is equal or smaller than decoder sent in SETTINGS).

Best regards,
Tatsuhiro Tsujikawa


 
Best regards,

Bence Béky


On Fri, Oct 23, 2015 at 12:15 PM, Ilari Liusvaara <[hidden email]> wrote:
On Sat, Oct 24, 2015 at 12:45:49AM +0900, Tatsuhiro Tsujikawa wrote:
> Hi,
>
> On Fri, Oct 23, 2015 at 1:18 AM, Hervé Ruellan <[hidden email]>
> wrote:
>
> > I agree that the wording is ambiguous here.
> >
> > However, my reading is the same a Cory's: you don't have to send a dynamic
> > table update if the *actual* value is not changed.
> >
> >
> ​I also found the discussion in this ML indicating you are right.  Thank
> you for clarification.
> I have to ask one more question: what is *actual* value? Is it the table
> size both peer agreed before reading SETTINGS, or the value in
> SETTINGS_HEADER_TABLE_SIZE decoder sent?
>
> I think this is a good item to add in FAQ section..

The way negotiation works:
- Decoder side sets the upper bound via SETTINGS_HEADER_TABLE_SIZE.
- Encoder side sets the actual size via dynamic table updates (inside
  HPACK bitstream) within limits set by decoder.
- If between headers decoder reduces the limit below size signaled by
  encoder, the encoder must first reduce the table size to the minimum
  it was between the frames or less (it can then increase it up to
  current limit).

As example of the last point:
[4k dynamic table size in use]
--> HEADERS
<-- SETTINGS(SETTINGS_HEADER_TABLE_SIZE=4k)
<-- SETTINGS(SETTINGS_HEADER_TABLE_SIZE=2k)
<-- SETTINGS(SETTINGS_HEADER_TABLE_SIZE=4k)
<-- SETTINGS(SETTINGS_HEADER_TABLE_SIZE=8k)
<-- SETTINGS(SETTINGS_HEADER_TABLE_SIZE=6k)
--> HEADERS

The second HEADERS must first reduce the dynamic table to at most
2k. It can then increase dynamic table size to up to 6k.


-Ilari