Subject: Re: [quicwg/base-drafts] HTTP header compression: static table fit for QUIC (#904)

From: Mike Bishop <[email-masked]>
Date: Wed, 25 Apr 2018 12:24:29 -0700

Based on those queries, tweaking the parameters, and scrubbing for obvious vendor bias, I've got a first draft static table [here](https://github.com/quicwg/base-drafts/wiki/QPACK-Static-Table).  I've also manually added pseudo-headers.  Take a look -- feedback welcome.

-- 
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/904#issuecomment-384405096

---

From: Lucas Pardue <[email-masked]>
Date: Wed, 25 Apr 2018 12:32:50 -0700

58 | :scheme | http
-- | -- | --

Is that really appropriate for QPACK? Is this a result of a client being Alt-Svc'd up from plaintext HTTP to HTTP/QUIC?

-- 
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/904#issuecomment-384407355

---

From: MikkelFJ <[email-masked]>
Date: Wed, 25 Apr 2018 12:36:34 -0700

While still young, zstd is likely to be important over time

https://tools.ietf.org/html/draft-kucherawy-dispatch-zstd-01#section-3

content-encoding: zstd
application/zstd

-- 
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/904#issuecomment-384408450

---

From: Lucas Pardue <[email-masked]>
Date: Wed, 25 Apr 2018 12:39:34 -0700

0 | content-type | application/x-www-form-urlencoded
-- | -- | --

Given that GET is more popular than POST, it seems odd that this content-type value comes out top.

-- 
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/904#issuecomment-384409349

---

From: Lucas Pardue <[email-masked]>
Date: Wed, 25 Apr 2018 12:41:26 -0700

Or in other words, do we optimise for requests or responses? The proposed table seems to treat both equally fairly.

-- 
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/904#issuecomment-384409896

---

From: MikkelFJ <[email-masked]>
Date: Wed, 25 Apr 2018 19:42:23 +0000 (UTC)

These are used in quite heavy traffic

x-forwarded-for
x-forwarded-ip
x-forwarded-port
x-forwarded-proto ?

https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/x-forwarded-headers.html
https://stackoverflow.com/questions/19366090/what-is-the-difference-between-x-forwarded-for-and-x-forwarded-ip

-- 
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/904#issuecomment-384410189

---

From: Mike Bishop <[email-masked]>
Date: Wed, 25 Apr 2018 19:43:44 +0000 (UTC)

@LPardue, yes, that's the idea.  RFC 8164 and all.  And you're right -- there are some odd duck in there, some removed and some not.

  - 53% of Content-Disposition headers give a filename of "f.txt"
  - 17% of Content-Length headers are 0; another 5% are 531
  - The 6th most common ACAH header asks to allow "x-customheader," which I'm fairly sure is an example someone copied without customizing

@mikkelfj, given that the other application/* compressed types aren't frequent enough to show up in the query, I'd probably skip that content-type entry regardless. We could add some things still in draft.  The addition of things that are used on the proxy side would be useful, since Internet Archive doesn't have visibility into that.

-- 
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/904#issuecomment-384410561

---

From: MikkelFJ <[email-masked]>
Date: Wed, 25 Apr 2018 12:50:27 -0700

X-forwarded-* isn't really standard, and there is an effort to standardize, but I'm sure if it is actually being used - and if it is, X- is probably still there just to not break things.

That said, any gateway towards QUIC has the chance of remapping such headers, so QUIC could take a position here.

e.g. X-Forward-For -> Forwarded

https://tools.ietf.org/html/rfc7239
https://tools.ietf.org/html/rfc7239#section-7.4

-- 
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/904#issuecomment-384412460

---

From: Lucas Pardue <[email-masked]>
Date: Wed, 25 Apr 2018 19:56:21 +0000 (UTC)

This verges on bikeshed commentary. How much "space" is there for this table. The indexing stops at 121 for the reasons you describe, what is the upper limit? Could QPACK static table be extended in future if there is a strong demand? (which raises the other point of how closely coupled is QPACK to v1 of QUIC, doh).

-- 
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/904#issuecomment-384414155

---

From: Mike Bishop <[email-masked]>
Date: Wed, 25 Apr 2018 20:03:34 +0000 (UTC)

One of the reasons for #1141 was that it allowed this table to be "larger" without hurting the dynamic table.  What constitutes "larger" is flexible, though.  Basically, as large as implementations can tolerate.

There's discussion up-thread about defining a way to change static tables.  I haven't come up with a design for that which doesn't feel painful, though.

-- 
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/904#issuecomment-384416152

---

From: Lucas Pardue <[email-masked]>
Date: Wed, 25 Apr 2018 13:12:46 -0700

> There's discussion up-thread about defining a way to change static tables. I haven't come up with a design for that which doesn't feel painful, though.

I meant more something like a formal extension process, similar to Frame types or Status codes. An author could propose new entries be appended to the static table, an "expert" decides if this should become a formal entry. Endpoints could exchange the highest index of static entry they would like to use for any given connection. This value indicates that the endpoint supports all entries up to and including the highest index.

While HPACK was noble in its statement of not being extendable, the barrier to HPACK2 is high. Instead we have QPACK :)

-- 
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/904#issuecomment-384418758

---

From: MikkelFJ <[email-masked]>
Date: Wed, 25 Apr 2018 13:16:07 -0700

> There's discussion up-thread about defining a way to change static tables. I haven't come up with a design for that which doesn't feel painful, though.

Not sure it is a good idea, but there could be a default static table. A DNS entry could list alternatives from a known short-list, and the client could identify which was chosen.

-- 
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/904#issuecomment-384419728

---

From: Mike Bishop <[email-masked]>
Date: Wed, 25 Apr 2018 14:19:48 -0700

DNS makes me nervous, simply because it's not guaranteed to be fresh.  You need something that can be confirmed directly with the peer at the time of the connection.  A single continuously-growing table is hard because in a few years, in some application space, someone's going to find the low end of the table totally useless and be forced to support it to get the high end.

The best sketch I've got right now is to capitalize on the fact that there are two encoder-decoder pairs.  So each endpoint publishes a list, in preference order, of the static tables it supports.  Each encoder will use the most preferred item from its list which also appears somewhere on the decoder's list.  They might well end up using different static tables in the opposite directions, but that's okay; each peer can choose the table that best suits the headers it plans to send.  If we went with such a design, it would probably make sense to separate out a client table and a server table.

However, if it's going to be in SETTINGS, that adds a new limitation that the client can't send requests in 1-RTT until it has seen the server's (hopefully 0.5-RTT) SETTINGS frame, a requirement that doesn't currently exist.  (Or we permit changing tables mid-connection, which has serious synchronization issues.)  If we want to guarantee that it has been seen, then it would have to be a transport parameter, but that then gets into cross-layer settings and that's ugly.

-- 
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/904#issuecomment-384437819

---

From: Kazuho Oku <[email-masked]>
Date: Wed, 25 Apr 2018 22:09:15 +0000 (UTC)

Regarding static table selection, I'd prefer using what will be defined in #1068 rather than trying to invent our own wheel.

Having a concrete use-case might also have a positive effect in driving the design discussion on #1068 as well.

-- 
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/904#issuecomment-384449861

---

From: Lucas Pardue <[email-masked]>
Date: Wed, 25 Apr 2018 22:21:30 +0000 (UTC)

> A single continuously-growing table is hard because in a few years, in some application space, someone's going to find the low end of the table totally useless and be forced to support it to get the high end.

At that point, nulke it from orbit and make a QPACK2 or whatever from scratch. My intention was to permit modest growth of "QPACK for general purpose HTTP on the Web".

Saying that, for all the problems that "pluggable" static tables might have, I like your proposal @MikeBishop, and it would obviate my slow-growth extension model.

-- 
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/904#issuecomment-384452426

---

From: Mike Bishop <[email-masked]>
Date: Thu, 26 Apr 2018 16:16:24 +0000 (UTC)

@kazuho, that doesn't make sense to me, as this isn't a QUIC extension.  It would change nothing about the transport.  I'd be perfectly happy *mimicking* that in an HTTP setting, but I'd really like to stay away from shoving application-layer state into the transport parameters.

-- 
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/904#issuecomment-384701162

---

From: Kazuho Oku <[email-masked]>
Date: Thu, 26 Apr 2018 09:27:33 -0700

@MikeBishop I would argue that QUIC should provide a way for application protocols (e.g., HTTP) to negotiate their parameters.

And I do not think that the negotiation mechanism for a transport extension and an application protocol extension needs to be different. There could be certain properties specific to a transport extension from QUIC's viewpoint (e.g., frame type mappings being negotiated), but the general requirements (e.g., the need to finish negotiation before sending first application data, the need to exchange a extension ID and optionally some parameters) will be the same.

-- 
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/904#issuecomment-384704755

---

From: Mike Bishop <[email-masked]>
Date: Thu, 26 Apr 2018 14:07:11 -0700

That's certainly a possible design, but not what we've currently defined for HTTP/QUIC; we've followed the HTTP/2 path instead.  One reason we haven't gone that way so far is that, during the handshake, you're also offering a list of protocols in ALPN in parallel with TPs.  That means anything which lives in TP needs to be sent for each of the protocols you're offering the server to select from.  (Imagine a future in which you support multiple HQ versions.)  Also, since client's TP are only under handshake keys, there can't be any privacy concerns around disclosing the client's parameters.

Neither is a killer, but certainly a pain, and a reason I prefer to keep other options on the table.

-- 
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/904#issuecomment-384789205

---

From: Kazuho Oku <[email-masked]>
Date: Fri, 27 Apr 2018 00:20:15 -0700

I think the way HTTP/2 negotiates (or rather, unilaterally sends the configuration) is pretty cool. OTOH, as you have described, the issue with static table negotiation is that it needs to be negotiated rather than just sending the configuration to the peer.

I can understand the hesitation to running ALPN and protocol-specific negotiation at the same time.

However, I might argue that running all things parallel (for less connection establishment latency) is the spirit of QUIC. Transport negotiation, TLS handshake, 0-RTT, they are all done in parallel. Therefore, I would estimate that people would want to do the same for negotiating the parameters of the application layer protocols. I see static table negotiation being one of them.

Just my two cents.

-- 
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/904#issuecomment-384887433