Subject: Consequences of removing the reference set

From: Martin Thomson <[email-masked]>
Date: Thu, 24 Jul 2014 08:07:24 -0700

We have some artifacts in HTTP/2 that were as a consequence of having
the reference set.

I have opened a pull request to remove those artifacts, and to add a
new requirement to have pseudo-header fields appear first.  This is
something that we all agreed would be good, but we couldn't do with
HPACK in its previous form.

  https://github.com/http2/http2-spec/pull/568

This change does the following:

* remove the requirement to concatenate with '\0'
* require pseudo-header fields to all appear before regular header fields
* change 'header set' to 'header list'

Please comment if you think that these changes are inappropriate.

---

From: "Poul-Henning Kamp" <[email-masked]>
Date: Thu, 24 Jul 2014 15:39:30 +0000

In message <CABkgnnXnPmJ5WgHTeHgKv-f0yUBMx3D=[email-masked]>

>Please comment if you think that these changes are inappropriate.

The cookie stuff needs a little more work:

This bit makes no sense for a HTTP/2 proxy, since it MAY split the
just assembled cookie header again for transmission:

	If there are multiple Cookie header fields after
	decompression, these MUST be concatenated into a single octet string
	using the two octet delimiter of 0x3B, 0x20 (the ASCII string "; ").

Is there are good reason (and is it in scope?) to MUST this for servers ?

If so, we should make it apply only to servers.

Otherwise we should delete it.

-- 
Poul-Henning Kamp       | UNIX since Zilog Zeus 3.20
[email-masked]         | TCP/IP since RFC 956
FreeBSD committer       | BSD since 4.3-tahoe    
Never attribute to malice what can adequately be explained by incompetence.

---

From: Martin Thomson <[email-masked]>
Date: Thu, 24 Jul 2014 08:44:33 -0700

> If so, we should make it apply only to servers.

Maybe it's just the qualification that is missing: ..." before passing
the header field to applications" or something like that.  Yes, this
is something that only origin servers need to worry about.

---

From: "Poul-Henning Kamp" <[email-masked]>
Date: Thu, 24 Jul 2014 15:52:57 +0000

In message <CABkgnnXBw6w-ED9BY8JANYuDKTADpn=[email-masked]>
>is something that only origin servers need to worry about.

Is the server/app interface even something that should concern us in
this context ?

---

From: Mark Nottingham <[email-masked]>
Date: Thu, 24 Jul 2014 13:32:49 -0400

Martin,

In general I think this is fine; it’s been discussed on-list before and there seemed to be good support for it. I do want to make sure it gets good review (and it’s good to see feedback from PHK already), since last-minute changes can cause unpredictable outcomes.

Cheers,

--
Mark Nottingham   http://www.mnot.net/

---

From: Roberto Peon <[email-masked]>
Date: Thu, 24 Jul 2014 10:44:59 -0700

> Please comment if you think that these changes are inappropriate.
Despite what the text said, there was never a requirement to use '\0' to
preserve ordering (and there was a section near the top saying how to
accomplish ordering). It exists solely to allow ordering to be done
efficiently, as the alternate mechanism would have required more bytes.

In other words, one could always have accomplished ordering (of any kind)
by emitting up-to two references to each item explicitly.

Now, since we don't have the reference set, the use of merging values with
'\0' is more important, since the number of key-values has a direct
relationship to the inefficiency of the compressor.
I don't believe this part has been discussed on list yet; taking this part
out (so we can discuss it separately) would probably be good.
-=R

---

From: Martin Thomson <[email-masked]>
Date: Thu, 24 Jul 2014 10:57:43 -0700

> relationship to the inefficiency of the compressor.

I think that you might need to try explaining this again.  I'm not
understanding you.

Do you mean to say that you want to have same-named header fields
referenced by a single op-code?

---

From: Roberto Peon <[email-masked]>
Date: Thu, 24 Jul 2014 11:03:36 -0700

Correct.
I believe that it would make sense to potentially (at the compressor's
option) have same-named header fields referenced by a single op-code.
Analysis may prove that this is a needless concern though.
-=R

---

From: Martin Thomson <[email-masked]>
Date: Thu, 24 Jul 2014 11:26:37 -0700

> Analysis may prove that this is a needless concern though.

What do you suggest that we do?  Based on the information we have on
the two options, the reduced complexity suggests that '\0'-concat
isn't worth it.  Unless you would like to find some more information
to tilt the scales in the other direction.  I'd suggest that would
need to happen quickly, just as I suggested the same to Herve when he
suggested we use ranges for header table references (though that would
require tuning in addition to tests).

---

From: Roberto Peon <[email-masked]>
Date: Thu, 24 Jul 2014 11:30:28 -0700

I'd suggest keeping it unless we have data suggesting it isn't necessary.
It isn't exactly the most complex of things.
-=R

---

From: Greg Wilkins <[email-masked]>
Date: Fri, 25 Jul 2014 09:20:28 +1000

In the test data there are 38037 fields in 3267 headers of which 161 have
duplicate header names:

     58 Duplicate: cache-control
     43 Duplicate: content-type
     19 Duplicate: pragma
     19 Duplicate: expires
      9 Duplicate: set-cookie
      7 Duplicate: x-content-type-options
      2 Duplicate: last-modified
      2 Duplicate: content-length
      2 Duplicate: accept-ranges

However, I think this says more about the quality of the data set than it
says about the likelyhood of duplicate headers - duplicate cache-control
and content-type fields are almost certainly not good.

For my part, I'm not that interested in the byte saving of avoiding
encoding a duplicate name.  It is more work to discover if the name is
duplicate than to invest a few bits to just encode it and move on.

cheers

On 25 July 2014 04:30, Roberto Peon <[email-masked]> wrote:

> On Thu, Jul 24, 2014 at 11:26 AM, Martin Thomson <[email-masked]
> > wrote:
>

-- 
Greg Wilkins <[email-masked]>
http://eclipse.org/jetty HTTP, SPDY, Websocket server and client that scales
http://www.webtide.com  advice and support for jetty and cometd.

---

From: Greg Wilkins <[email-masked]>
Date: Fri, 25 Jul 2014 09:23:44 +1000

>         using the two octet delimiter of 0x3B, 0x20 (the ASCII string ";

This makes no sense for an origin server either.

The origin server has to parse the cookie field into individual fields
anyway, so asking for them to be combined, just to be split again waste CPU
and memory.     Servers have to handle multiple cookie fields from h1
anyway - so Jetty will just not do this and nobody will be the wiser as the
same Cookies will be handed over to the application either way.

What benefit is being sought by requiring this merge?

If it is a significant benefit, can't we put the burden on the client to
not send multiple cookie headers rather than make the poor server have to
receive the multiple headers, merge them and then split them?

cheers

---

From: Greg Wilkins <[email-masked]>
Date: Fri, 25 Jul 2014 09:29:24 +1000

> * change 'header set' to 'header list'

This is a good move.  Judging by the existence of duplicate content-type
headers in the example data set then having an ordering to resolve is
good.   Probably need to now say that if a header that cannot have multiple
values is repeated then which value do we use, the first, the last,
undefined or 400 ?

cheers

---

From: Amos Jeffries <[email-masked]>
Date: Fri, 25 Jul 2014 12:23:05 +1200

On 25/07/2014 11:23 a.m., Greg Wilkins wrote:
> On 25 July 2014 01:39, Poul-Henning Kamp wrote:
> 

IMO it only makes sense for 2->1.1 gateways.

Even for display purposes it does not matter what delimiter is selected
by the implementation.

Amos

---

From: "Martin Nilsson" <[email-masked]>
Date: Fri, 25 Jul 2014 06:59:43 +0200

On Fri, 25 Jul 2014 01:20:28 +0200, Greg Wilkins <[email-masked]> wrote:

>
> In the test data there are 38037 fields in 3267 headers of which 161  
> have duplicate header names:
>

In my mobile testdata I have 2086062 fields in 203586 headers with the  
following duplicates

2738 user-agent
2517 accept-encoding
782 via
298 accept
213 accept-language
209 host
207 surrogate-capability
203 accept-charset
173 x-wap-profile
114 referer
95 connection
91 x-wap-profile-diff
21 cookie
16 x-forwarded-for
15 x-up_devcap-screendepth
15 range
14 x-up-devcap-screendepth
14 x-up-devcap-screenpixels
13 if-modified-since
10 cookie2
8 x-nokia-musicshop-bearer
8 x-nokia-musicshop-version
7 cache-control
7 wap-connection
6 drm-version
6 x-nokia-msisdn
5 x-nokia-gateway-id
5 x-nokia-bearer
5 http_x_msisdn
5 x-nokia-localsocket
5 x-nokia-remotesocket
3 pragma
3 x-nokia-imsi
3 content-type
3 proxy-connection
3 x-nokia-chargingid
3 x-nokia-ipaddress
2 x-network-info
2 x-nokia-rattype
2 pnp
2 x-nokia-prepaidind
2 x-imei
2 x-nokia-roamingind
2 msisdn
1 content-length
1 x-ucbrowser-ua
1 x-nokia-prepaidid
1 x-nokia-roamingid
1 x-nokia-sgsnipaddress
1 encoding-version
1 keep-alive
1 x-ucbrowser-device-ua
1 x-nokia-maxuplinkbitrate
1 x-up-calling-line-id
1 x-ebo-ua
1 x-nokia-ggsnipaddress
1 x-nokia-maxdownlinkbitrate
1 x-ucbrowser-device

/Martin Nilsson

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/

---

From: Matthew Kerwin <[email-masked]>
Date: Fri, 25 Jul 2014 15:12:48 +1000

> In my mobile testdata I have 2086062 fields in 203586 headers with the

Sorry, just so I'm reading this right, do you have 2,738 instances
​​
where
​a
 client sent two user-agent headers in the one request?

-- 
  Matthew Kerwin
  http://matthew.kerwin.net.au/

---

From: Willy Tarreau <[email-masked]>
Date: Fri, 25 Jul 2014 07:54:32 +0200

> values is repeated then which value do we use, the first, the last,

We had this issue already in H/1 and since H/2 must keep the same semantics,
I think we won't really address this case as it's implementation-dependant.
We processed the special case of content-length since it was a major issue
for the framing, but that's all.

BTW, good job Martin, the spec really looks great and simpler now.

Willy

---

From: Martin Thomson <[email-masked]>
Date: Fri, 25 Jul 2014 07:23:36 -0700

> What benefit is being sought by requiring this merge?

It's a logical construct only.  Feel free to take shortcuts.  I can
add the word "logically" if you are especially concerned about being
able to follow the spec to the letter.

---

From: Martin Thomson <[email-masked]>
Date: Fri, 25 Jul 2014 07:37:20 -0700

> In my mobile testdata I have 2086062 fields in 203586 headers with the

Assuming that all those headers were encoded based on the a previous
request, the incremental cost of having to index the extra name-value
pairs is 10k (at 2 bytes per reference) at the absolute extreme if we
remove '\0'.  That's generous in the extreme.  Any that appear once do
not benefit from '\0'; any that appear on different connections do not
benefit; and any that have changing values do not benefit.

If you really care, a header field that uses valid syntax can be
concatenated with a comma.

---

From: Roberto Peon <[email-masked]>
Date: Fri, 25 Jul 2014 10:55:20 -0700

So, we probably need to regenerate the huffman encoding (assuming we care)
because we've changed how the compressor works, and thus changed the
frequencies of various things that will appear.

The huffman table offers clues about the frequency of concatenating various
key's values together:

  0)  |11111111|11000                             1ff8  [13]

I'd assume that this is mainly from set-cookie, but the nature of the input
is such that we cannot know (it was computed in aggregate).
At that size, it is likely to be cheaper to encode set-cookie without using
'\0', and so I think there is some evidence that Martin's change is neutral.

I really do hate that we have no idea of what these all of these changes
will actually do, btw.

-=R

---

From: "Martin Nilsson" <[email-masked]>
Date: Fri, 25 Jul 2014 21:15:57 +0200

On Fri, 25 Jul 2014 07:12:48 +0200, Matthew Kerwin <[email-masked]>  
wrote:

>> ​​where ​a client sent two user-agent headers in the one request?
>

Yes. Essentially all of the duplicates are prefixed SAMSUNG-GT- and both  
of them containing the same data. I don't feel this is a use case to  
optimize for.

/Martin Nilsson