Subject: [quicwg/base-drafts] HTTP SETTINGS: define setting content encoding (#1556)

From: Luca Niccolini <[email-masked]>
Date: Fri, 13 Jul 2018 09:08:35 -0700

The current draft says:
> The payload of a SETTINGS frame consists of zero or more parameters,
   each consisting of an unsigned 16-bit setting identifier and a
   length-prefixed binary value.

This leaves the encoding of the setting content to the implementor and may be cause of ambiguity.
I believe we should define the encoding more explicitly for each setting, e.g. 
is `SETTINGS_NUM_PLACEHOLDERS` encoded as a fixed-length 4 or 2 (given its maximum value) bytes integer, or perhaps it can also be variable-length, e.g. can the value be encoded in just 1 byte if less than 256 ? 

Also, do we expect arbitrarily large setting contents ?
Implementors would likely enforce some sensible maximum values whenever the length is encoded as a quic-integer, do you think there is value in the RFC suggesting these maximum values ? 
This is probably a larger scope question, but in the settings frame seems more prominent

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/1556

---

From: afrind <[email-masked]>
Date: Mon, 16 Jul 2018 20:50:39 +0000 (UTC)

> 4.2.6.1.  Integer encoding
>
>   Settings which are integers use the QUIC variable-length integer encoding.

So I don't think there's anything ambiguous in the current draft.  It is strange however that there is both a variable-length integer specifying the length of the integer setting AND the setting itself is a variable-length integer, so its length is self-describing and redundant.  

We could instead define settings that are integers use all of the `Contents` octets to specify the integer and take the length exclusively from the `Length` field of the parameter.  This would save a byte on the wire here and there (eg a parameter with value 100 currently requires 3 bytes to encode), and possibly make things a little less confusing, at the cost of having yet another way to encode integers.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/1556#issuecomment-405377723

---

From: Lucas Pardue <[email-masked]>
Date: Mon, 16 Jul 2018 14:29:49 -0700

That is weird, especially when

> A zero-length content indicates that the setting value is a Boolean and true. False is indicated by the absence of the setting.

What is expected there, a `Length` of 0 **and** a `Content` varint of length 0?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/1556#issuecomment-405388047

---

From: Lucas Pardue <[email-masked]>
Date: Mon, 16 Jul 2018 14:31:26 -0700

However,

> An implementation MUST ignore the contents for any SETTINGS identifier it does not understand.

justifies externalising the length such that you can skip over unknown settings parameters within a SETTINGS frame

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/1556#issuecomment-405388445

---

From: afrind <[email-masked]>
Date: Mon, 16 Jul 2018 14:39:44 -0700

@LPardue I think for boolean it's 0 `Length` and no content.

I agree that externalizing the length is good to skip unknown settings.  I'm not a fan of the implicit boolean false either, it's much safer to make things explicit.  SETTINGS are not so frequent or large that we need to apply QPACKian levels of byte squeezing.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/1556#issuecomment-405390338

---

From: Lucas Pardue <[email-masked]>
Date: Mon, 16 Jul 2018 14:43:06 -0700

I agree @afrind . What examples of boolean settings are there anyway? The one's that I am familiar with use an integer of 0 or 1, but it isn't boolean ;)

https://tools.ietf.org/id/draft-ietf-httpbis-h2-websockets-02.html#rfc.section.3

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/1556#issuecomment-405391126

---

From: Luca Niccolini <[email-masked]>
Date: Mon, 16 Jul 2018 15:23:49 -0700

ouch! I totally missed section 4.2.6.1 and I think (as you pointed out) the fact that we have a length field before a varint that also includes the length threw me off. 

@LPardue, FYI: I was looking at your implementation and it seems that you also made my same assumption that integers are 4-bytes long 
https://github.com/bbc/nghq/blob/master/lib/frame_parser.c#L235

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/1556#issuecomment-405400097

---

From: Luca Niccolini <[email-masked]>
Date: Mon, 16 Jul 2018 22:39:33 +0000 (UTC)

ouch! I completely missed section 4.2.6.1, but the fact that (as @afrind pointed out) we have a length field before a quic-varint that also includes its own length threw me off. 

I also agree on the fact that the current encoding for booleans could be more friendly

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/1556#issuecomment-405403114

---

From: Lucas Pardue <[email-masked]>
Date: Mon, 16 Jul 2018 15:42:07 -0700

@lnicco: thanks for identifiying the issue, I captured it on https://github.com/bbc/nghq/issues/3

@MikeBishop: generally speaking, issues like thiscould be shaken out with some minimal HTTP/QUIC handshake interop 

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/1556#issuecomment-405403534

---

From: afrind <[email-masked]>
Date: Fri, 27 Jul 2018 11:36:07 -0700

There's a related issue in CANCEL_PUSH, MAX_PUSH_ID and GOAWAY.  There's a variable length frame length but the frame contains only a single variable length integer, so its length is effectively specified twice.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/1556#issuecomment-408504045

---

From: Mike Bishop <[email-masked]>
Date: Fri, 27 Jul 2018 12:52:27 -0700

@afrind, that's an interesting point.  Could you split that out into a separate issue?

The current boolean encoding is intended to save bytes in the case of turning something on/off and not needing to convey any other data (e.g. "I support extension Foo").  If you don't send anything, the default case, it's false; it takes the minimum possible length to send true.  Because HQ doesn't allow modifying settings after the initial setup, we don't need an affordance for turning something that was true back to false.  In HTTP/2, you got 32 bytes regardless of how much or little you needed to convey, so settings of this sort use 0/1 and make other value invalid, or they use 0/non-zero.  However, most extensions to HTTP/2 so far have defined non-critical frames that didn't need a setting.

I'm not opposed to saying the payload of the integer settings isn't a varint, but it seems like that introduces additional complexity to deal with oddly-sized integers.  Is that a noticeably different level of complexity from having to check that the varint is the size claimed by the setting?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/1556#issuecomment-408522332

---

From: afrind <[email-masked]>
Date: Tue, 31 Jul 2018 16:58:04 +0000 (UTC)

We could define integer settings values to be 1, 2, 4 or 8 bytes, specified by a length byte, to avoid oddly-sized integers.  I'm not wildly crazy about having multiple ways of specifying integers, but I do think the current var-len-len plus var-len-value is both confusing and redundant.

Regarding booleans: I prefer making things explicit rather than implicit by their absence.  I don't think saving a byte or two in SETTINGS is a huge win.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/1556#issuecomment-409293078