This modifies parsing to consider empty or not-present header fields as empty containers; serialisation omits them from output.
The SH syntax does not directly allow empty field values, such as defined for Accept, although this might be allowed by field definitions like MyField = [ sh-list ] Likewise, the list types do not allow for empty lists. sh-list = list-member *( OWS "," OWS list-member ) list-member = sh-item I think this is a very odd choice for a generic syntax because the empty set is often given semantic meaning in generic communication. It's hard to do math without zero. If this is intended, the rationale should be explained in the spec, and there should be some discussion with examples about defining fields as an optional value.
FWIW, even if empty lists may be problematic top-level, the situation is different when they are nested...
ietf104 - interest in the room in supporting empty (perhaps null?) syntax
I agree this is something important. It may be used to mean "I know I must pass the info but I don't know the info", which is different from "I don't care about the protocol" or passing a dummy value just to fill the hole.
In the original base material of header definitions, empty values were generally just not sent at all. Having a specific Null value may or not make sense, not sure.
I personally like the distinction between "known to be empty" and "not presented either because I don't know or because it's empty". Some semantics might explicitly require the presence of some fields which we would enforce by the protocol. This doesn't mean they can't be empty, they must be present, for example, to make sure they weren't dropped in the middle. For example, "Connection: foo" gets rid of the field, not just the value. Just my two cents, Willy
Do we have any RFC'ed headers where there is a difference between a non-present and an empty header ?
There's an accept-something if I remember well. Also I've been using "Host:" in many occasions with HTTP/1.1 requests when I didn't know the host name and this tends to work where no Host field fails ;-) Willy
I'm not against a '?N' null token (along the lines of true/false), but I have a hard time thinking of a use for it.
URL
Wouldn't an empty list be equivalent to an empty value, thus we don't need a new syntax?
Putting an empty list where for instance an integer is expected, just to say that there will be none, sounds counter-intuitive to me.
On Fri, Apr 05, 2019 at 01:37:11AM -0700, Julian Reschke wrote: Indeed, probably.
On Fri, Apr 05, 2019 at 03:11:00AM -0700, Poul-Henning Kamp wrote: Agreed in general. My point was that sometimes specs use "MUST send" when the sender doesn't know, resulting in stupid values appearing. That's exactly what led a number of agents to place a content-length with stupid values (0 or huge ones) with the CONNECT method a long time ago. An empty value where an integer is needed by the application is more of an application-level error than a protocol-level one in my opinion : it's up to the application to decide how to recover from this missing piece of information (is it really needed to process the request or not). For me it can mean "don't care", "don't know" or "not representable". After all floats support "NaN" for the same reason :-) Willy
If there is a "MUST send" requirement, there must also be something available in the same spec that can be sent ?
There is not, and never has been, an interop problem with sending empty field values. They are a list value of zero items or a string item of zero length. Accept and Host, respectively.
NAME how do you know that?
Because if a recipient drops an empty Host field the request will be rejected with 400. There have been no reports of such breakage in 25 years. It isn’t even a likely scenario given how message fields are parsed and reproduced.
If a recipient doesn't drop an empty host header, the request will still be rejected with 400, surely? Regardless, I'd note that many headers address this situation with a reserved value like . Is there value in standardising on one such value for future headers? I'm not convinced, but I'd note that we also have many headers that use to denote "all"; it seems to me that if we're going to do null, we should do that too (but again, I'm not convinced this is adding value).
On Mon, Apr 08, 2019 at 05:16:41PM -0700, Mark Nottingham wrote: It depends on the header field that was empty ;-) I've used the empty Host header field quite a bit (even in health check requests). My observation has been that while HTTP/1.1 without Host naturally causes a 400, HTTP/1.1 with empty Host is often processed similar to HTTP/1.0 without Host or as 1.1 with an unknown Host. I'd say "why not", but it's useful to consider lists and the iterative processing that can happen, removing one item at a time. Having to place a specific value to denote emptiness would require specific processing (i.e. check for emptiness after removing any item just for the sake of replacing it with the special value). By the way, speaking about lists makes me think we may complicate interop when a header field appears multiple times. For example if we have this in a request : List: a,b,c,d Foo: bar List: e,f,g,h It's not unreasonable to think that some simplified implementations may replace the first occurrence of List with "none" after processing it, leading to this : List: none Foo: bar List: e,f,g,h Or possibly this : List: none Foo: bar List: none Which may be processed as "List: none,e,f,g,h" or "List: none,none" respectively. Just my two cents, Willy
Willy, I think that would be clearly broken, and we should be able to catch it with tests. I think we're talking about all of the container types here (dict, list, list of lists, parameterised lists), correct? Julian, you gave as an example. Given that the behaviour recommended is exactly the same as if the header was missing, that's not very compelling. Besides the potential stripping issue (I have heard of implementations that strip empty headers, but don't have details on hand), some header libraries may not make a distinction between missing and empty headers. Overall, I don't see a lot of value in accommodating empty headers directly, and I don't think we should be promoting it as a practice.
Agree, I'm not convinced either. I see the potential, but Gettys rule applies: "The only thing worse than generalizing from one example is generalizing from no examples at all." (May actually be from Phil Karlton originally, sources differ.)
Hm, no. "A request without an Accept-Encoding header field implies that the user agent has no preferences regarding content-codings." vs. "An Accept-Encoding header field with a combined field-value that is empty implies that the user agent does not want any content-coding in response."
Yes, but in the real world, the outcome is always the same.
No. HTTP/1.1 introduced an IESG requirement that Host must always be sent and recipients must always reject with 400 if Host is not received. When I pointed out that not all URIs have a host, the response was that clients must send an empty Host field in that situation. It is a MUST requirement in Semantics section 5.4: This is ingrained in HTTP semantics and commonly used by non-browser HTTP implementations. There is only one example of an HTTP header field using "none" and that is Accept-Ranges. It isn't a good example for anything. To be clear, it would be a bug for an HTTP message processor to drop a received header field just because the value is empty. Nothing about SH will change that. What we are discussing is whether SH is capable of representing an empty list or an empty header field, both of which it is currently incapable of doing.
If that spec specifically says "empty field-value", a SH "empty" token will not be usable for Host: anyway, and we're back in the "generalizing from no example at all" again.
On Thu, Apr 11, 2019 at 03:53:15PM +0000, Poul-Henning Kamp wrote: After having thought a bit more about this, I now think that we don't need empty list elements in the end because lists are not strongly ordered, they're not arrays with a position so an empty element in a list brings no value. I'd further say that removing an element from a list must result in removing the list once the last one was removed as it is a set. So I think I'm fine with not dealing with empty lists. This then leaves us only with the empty header field alone, likely where a string or a token are expected. I don't see a reason not to support an empty string just like any other string. A header field is not just a value, it's a name+value combination. With a void value the name still serves as a boolean (present or not) and this is exactly how it's used when the field is made mandatory to distinguish between agents generations or as a signal to detect support for something. We've all filled administrative forms where the requested information was irrelevant but mandatory in the form and just left it void so that the person in charge deals with the particular case (on paper) or filled with whatever was accepted (on web forms) hoping it would just be ignored since irrelevant. For me the Accept and Host fields are exactly in this category. My concern is to be certain that a valid HTTP request can be transmitted over SH. And ironically, the only mandatory HTTP header ("Host") is also the one requiring the support for an empty value due to its mandatory nature. Willy
I have lost count of the number of packages I have received from USA where part of the address is "Denmark does not have states" :-)
Again, the purpose of SH is not to allow all possible HTTP header to be represented in the data model -- it's to solidify the 80% case and promote best (and interoperable) practice. Representing a boolean as an empty header field is not good practice.
See PR above.
I've put in the changes for the list-based header fields. It's less clear to me that it's desirable to default a missing or empty item to an empty string (strings and tokens) 0 (integers and floats), False (boolean) or a 0-length binary array (binary data); to me, those are all going to be application-specific defaults that are better specified explicitly. I'm happy to adjust the spec to make that more clear, if folks feel it already isn't.


in , NAME asks about having Parameterised Lists whose parameterised identifiers are things other than Tokens. Because of the way SH is put together, I think this would be a fairly easy change, in terms of the spec and implementations; it would require a few more tests. The only downside I can think of immediately is that specs would need to constrain the type of the parameterised identifier themselves, and specify error handling (if it weren't the default "blow up"). Thoughts? I also wonder if we should come up with a better name than "parameterised identifier", especially since we've ditched "identifier" elsewhere. member name? member id? primary identifier?
That works, since splitting lists from parameterised lists. Are you thinking , or just adding a few types? It also changes my thinking a tiny bit on , although not much. I like "parameterised element" but that introduces a new word. "parameterised item" is a nice shade, if any item is allowed there, but "primary identifier" works too. :art: :paintbrush:
The downside here is that it would be very hard to represent in JSON -- e.g., in the . At least some programming languages support hashes/dictionaries/objects with arbitrary key types (e.g., Python, JavaScript, Ruby), but I'm not sure how widespread that is -- especially if folks represent the different between and with an object for . NAME is this a nice-to-have or something that's a blocker?
(Fwiw I do think we should call this a Parameterised Token)
At this point do we just have to accept that the SH data model is essentially a subset of the JavaScript model? Numbers are bounded by JavaScript's limitations, object keys have to be stringy, nobody likes 'token' because it isn't a native JS type... I don't mind if that's the case, but it would be good to just say it outright somewhere. It would also give us a solid position to start from when considering other proposals. Hmm, C++ and Go could be have issues mixing key types within a single map, and Perl is definitely not going to like non-string keys.
It doesn't have to be -- it's just easier for me to write tests this way :)
This was a nice-to-have for me. I’d worked around it by putting an unused string as the identifier. It looks like that workaround is no longer necessary?


fixes typo in reference
FYI, there is (at least) a 180-4 now.


Fixes unused references. Removed reference to FIPS180-4 and opened issue Removed unneeded references Uses required references.
Should we update the FIPS180 reference to the latest one? NIST updated the document defining SHA-* algoritms. The latest reference is digest-headers references preserve the ones cited in RFC3230 and subsequent.
cross-posting from elsewhere, I said I think we probably want to use FIPS180-4 for SHA-256 and SHA-512, and FIPS180-1 for SHA-1.
There is also .
[x] Warning: no \ in \ targets \ [x] Warning: no \ in \ targets \ [x] Warning: no \ in \ targets \ [x] Warning: no \ in \ targets \ [x] Warning: no \ in \ targets \
Fixed in


Adds -latest to docname
[x] WARNING: The Internet-Draft name 'draft-ietf-httpbis-digest-headers' should end with a two-digit sequence number or 'latest'. (at line 20)


consistent use of instead of "http" make S1.1, P3 a bit more readable


NAME - can you take a look and see if that clarifies things?
This seems helpful given what's currently in the spec. However, I think some of the material I was talking about when I filed is no longer there. But I suspect that material may now be in other specs, and could perhaps still gain from being clarified at its current location.
I've been reading Client Hints (both and the ), and I'm having a little trouble understanding how things fit together in terms of which header fields are sent when and lead to what. My confusion started when I looked at the section and noticed (to my surprise) that was being registered as both a request header field and a response header field (when, having read the spec quickly, I was expecting it to be only a response header field, and wasn't sure what it would mean as a request header field). Then I looked back over the spec, and noticed that section 2 of the spec is called but that the entirety of the section appears (I think) to be about response header fields. I think it would help the spec be easier to understand if it: more carefully distinguished between request header fields and response header fields, and more clearly explained what the request header field is.
lgtm, thank you!


NAME - can you take a look?
Migrating .. Julian:
NAME NAME per URL, how about... Does that make sense? Would appreciate your guidance on this one :)
I'm starting to wonder if Client Hints should adopt Structured Headers to avoid having to deal with these sorts of questions. Ilya, WDYT?
NAME that would hit a major reset on all existing CH implementations and set us back another couple years, I don't think this is the right call for CH. /cc NAME Surely CH is not the first instance where we had to spell out behavior for selecting one out of N header values? That said, if we don't have established verbiage for this, I'm happy to just make up some language ourselves to clarify how it should behave.. what we're aiming for ain't rocket science. :)
I wouldn't want to set CH back that much (although it is lingering on :). I only mention it because all of the defined syntax seems like it would easily fit into SH, and Chrome already has a good start on a SH parser, thanks to NAME work on signed exchanges, etc.
As an aside, the same clarification should also apply to response headers. Currently Chrome treats multiple responses headers as an error and ignores both.
NAME my preference is to get this over the finish line without introducing dependency on SH. For one, we're also relying on Feature-Policy for delegation and we decided against SH there. WDYT of suggested text in URL — warmer? NAME ack.
NAME I hear you. My thinking is: We've already waited a good while for CH, and it's not clear that it's really really done yet (I suspect we have at least one more round of doc review). People are already using CH as a framework for new hints, so getting SH in would be best now if it's going to get in. If CH are going to be commonly sent, having well-defined parsing behaviour and the possibility of better serialisations (which SH gives us) is very attractive. To be clear -- this is me as me, not me as chair.
NAME - could you clarify what you mean by CH adopting SH? Do you mean that the / headers would be defined as /? Or that they'd be define as with extended processing model (which guarantees that the last item in the list "wins")? Or something else altogether?
Both and could be s. would be a of s. Both and would be s. would be a . I'm not really sure why its current ABNF is a list. NAME Considering that parsing and serialisation algorithms for these haven't been defined yet at all, I don't think it would take a lot of work (and would be happy to do a PR).
Good catch, I think that's an oversight and we can fix that. Stepping back, my preference is (still) to proceed at this stage without introducing dependency on SH. First off, introducing SH does not address the issue we're actually trying to solve in this bug. Second, it adds another significant dependency to CH adoption that I would like to avoid at this stage, as it's yet another reason for a browser vendor to drag their feet and delay integrating support for SH. To get CH over the last call barrier, I believe we have two outstanding tasks: Clarify Accept-CH-Lifetime definition, per above. Provide some minimum guidance on how to deal with aggregated values — see URL I don't think we'll land on perfect text for (2), but this is not a unique or new gap vs other and existing specs, and I don't think we should block on this. NAME does this sound reasonable?
friendly bump :-) NAME NAME PTAL, any thoughts or guidance on the above text?
The issue is that it's defined to only have one value. I think you'd need to say something like: Or, to really define it, define an algorithm.
This was discussed at the HTTPWG meeting today and it was decided to go ahead with Structured Headers!
Based on group discussion at IETF, everyone is on board.


Signed-off-by: Piotr Sikora
cc NAME
This field uses for a specific purpose, but that's already in the generic parameters. Suggest or similar. /cc NAME
Looks like has the same issue. Should we use for both? Note that the identifier is context-based, since if proxy configured SHA256-based validation, then would be , if it configured SPKI-based validation, then would be , etc. We could also use and instead of (and for ), but that doesn't seem very future-proof. What do you think?
Hmm, that's awkward. Maybe two fields? E.g., : [, ... ] : ... Is there a registry we can refer to, maybe?
I'm afraid that there isn't any registry that we can refer to, at least none that I know of. (opaque type) and (opaque value) seem a bit awkward. Wouldn't it be easier to just have and params? Also, in Envoy, we actually configure list of acceptable and values, and matching against any of them works, so we should probably emit both of them anyway. I could envision merging and into a single status type that lists all 3 params, e.g. See . What do you think?
Better than what we had :)


States that MUST NOT be used. Sets the MD5 status to deprecated.
Looks good, thanks!


Simplifies references to sha algorithms pointing to RFC 6234 instead of FIPS180 documents.
NAME ping :)
Should we update the FIPS180 reference to the latest one? NIST updated the document defining SHA-* algoritms. The latest reference is digest-headers references preserve the ones cited in RFC3230 and subsequent.
cross-posting from elsewhere, I said I think we probably want to use FIPS180-4 for SHA-256 and SHA-512, and FIPS180-1 for SHA-1.
There is also .


Obsolete ADLER-32 but don't forbid it.
NAME will this work for you?
I think the pull request is OK as-is, but might be improved slightly. In particularly, I'm wondering if SHOULD NOT is too strong for the server. A server could support ADLER32 without that support impacting on cryptographic data integrity provided that server also supports a cryptographically secure hash; e.g., SHA-512. Clients that wish to protect against malicious actor changes would use the SHA-512 hash and not request (or ignore) the ADLER32 value. Therefore, I would suggest that, for the server, the document says a server MAY implement ADLER32. I think it is perfectly reasonable for the document to say the client SHOULD NOT use ADLER32, for the reasons stated. That said, I can't decide if this distinction is really helpful, so I defer to your judgement, here.
I'm not so sure we want to make a distinction between client and server as you write it. Both client and server can attach Digest header to request or response. It is the receiver of Digest that is exposed to the risk of using a weak digest. The current language avoids mentioning either endpoint so we leave it to implementers. I'm not opposed to spelling things out more clearly but we'd really need to nail down what we mean by "using Digest algorithms" because that relates to requesting them, generating them, regenerating them (proxy), validating them (endpoint or proxy) etc.
That's a good point about client/server. Sorry, I had that wrong. As you say, it's the recipient of a Digest that must decide whether the algorithm is sufficient. This recipient may be either the client or the server. I think the document is right to point out the dangers of accepting a weak digest. Perhaps there is a useful distinction between generating a digest and accepting a digest; e.g., an agent MAY support generating a weak digest but SHOULD NOT accept a weak digest.
Not wrong, just partially true. That could work for me. I'll leave it to NAME to decide what he things makes sense to do.
NAME NAME as this issue is for ADLER, I moved the discussion to As it's in the listed algorithms, the server MAY already implement ADLER32, though it SHOULD NOT be used by both sides of the communication. I think sender and receiver should behave consistently (see again).
Merging as for the positive feedback from NAME and NAME comment URL


Based on discussion at IETF 105, removing explicit lifetime in favor of implicit opt-in registration and persistence. NAME can you please take a look? In particular, current language states the preference should be persisted but doesn't explicitly state for what the lifetime is.. Modulo, in privacy section we do talk about MUST criteria for clearing it. Any suggestions or recommendations for how to best approach this?
LGTM


Adds id-sha-* algorithm examples throughout the document.
draft-ietf-httpbis-digest-headers includes examples of sha-256 in the Digest header value, but no examples of the two new algorithms it introduces: id-sha-256 and id-sha-512. Examples would be extremely useful to illustrate the difference between sha-256 and id-sha-256.
That sounds reasonable to me.
NAME WDYT?


Align the I-D title with the .md file name suggested by NAME before the adoption.
We can consider to change the to the more direct .


Now that we are generalizing how the types are used, I think it might be a good idea to allow a dictionary value to be a mapping (i.e., a list of parameters). This would be a generalization. At the moment, top level elements can contain scalars, lists, or dictionaries. However, it is at the moment impossible to use a dictionary at the second level even though scalars and lists are permitted. In terms of use-case, the proposed change would allow for example something like a cache-control directive to take a mapping as an argument (see URL). Logic-wise, I assume that the added complexity would not be significant, as we can reuse the definition for the parameters of a parameterised list.
NAME are you just asking for parameters on dictionary values, in a manner that's equivalent to list values?
NAME Sorry for the belated response. Yes. I'd be fine with member-value being exactly list-member.


Is this PR meant to include ?
Yeah, oops. Need more coffee.
Try now.
Otherwise, looks alright to me.
The current definition of sh-float is surprisingly hard to serialize correctly, the best C-code I could come up with is: int serializeshfloat(char buf[18], double d) { int p = 0, l, dig; buf[0] = ''; buf[1] = '\0'; if (isnan(d)) return (-1); if (fabs(d) >= 99999999999999.95) return (-1); if (d = 99999999999999.95) return (-1); if (d < 0) { buf[p++] = '-'; d = -d; } p += snprintf(buf + p, 18 - p, "%-16f", d); while (buf[p-1] == ' ') p -= 1; buf[p] = '\0'; return (p); }
+1 from me, our primary focus should be on data types that will have good interop. That level of precision isn't necessary for any current use of HTTP headers I'm aware of, off the top of my head.
Proposal: Call these decimal. Allow a maximum of 9 digits on the left of the decimal place and 6 after. This matches the definition for int and allows storing this in the same sized slot with a or conversion factor.
ABNF gets much simpler.
NAME That would probably curtail the range too much. I think it is desirable to be able to move posix time_t timestamps in these.
If this really is an integer with fixed point semantics, why do we need it at all?
Because it's easier than making people specify "divide the number by a million to get its real value"? That said, I agree that 9 digits to the left of the point is probably not enough, so a floating point representation is more useful. This is the ABNF equivalent of NAME C code, yeah?: That easily gets us a current 32-bit time_t plus microseconds, and a whole range of other values besides.
Why do the arguments about size of integers not also apply here? is 64-bit on my system, which doesn't fit in the sh-integer definition either.
The current time is ish. You don't need to prefix it with 30 bits worth of zeroes.
I've read the IETF105 minutes, and thought about the fixed-point discussion. All the uses for "decimal number with fractional part" I can think of\ would reasonably served by at least 10 digits to the left\ and at least 3 to the right of the point. So I would support any fixed- or floating-point representation that supports that range of values. \ that's all that matters, right? \ a ten-decimal-digit time_t gives us until November 20, 2286
Using the max-six-decimal definition, and allowing 15 digits with no period or decimals, this C-code will do the job: static char * sh_float(double d) { static char buf[40]; int n; if (fabs(d) < 1000000000) { n = snprintf(buf, sizeof(buf), "%f", d); while (buf[--n] == '0') buf[n] = '\0'; if (buf[n] == '.') buf[n] = '\0'; } else { n = snprintf(buf, sizeof(buf), "%.15g", d); } return (buf); }
Sorry, wrong button.
If I take , then I can almost represent that in a JS float in the most horrific way imaginable: But that doesn't quite fit. 69999999999999999 doesn't fit into a double. If you want to remember the number of additional decimal places so that you don't lose any precision on those trailing decimal places (things like 0.3 are surprisingly tricky to re-encode), you are left with supplementary values. Can someone make a better case for any more than 10^10 values here? I couldn't see a good one. You can fit a 32-bit value in that. If you really think that time_t is valuable, which I'm totally not convinced of, then fewer steps might be acceptable. I can pack this:
PR updated. Any further comments, or ready to merge?


thx!
Boolean values can be conveyed in Structured Headers. The ABNF for a Boolean in textual HTTP headers is: sh-boolean = "?" boolean boolean = "0" / "1" Either say "0" is false and "1" is true, or maybe rephrase the ABNF to: sh-boolean = sh-false / sh-true sh-false = "?0" sh-true = "?1"


This addresses feedback from the list: URL URL NAME NAME does this look good to you?
Very nice, thanks. You almost managed to do this with a net reduction in total lines. The only additions here are my fault. Respect.


(Should I go ahead and stamp a -02 now, or wait a bit? Not sure how one usually handles such things.)
WGLC ends on Thursday, so let's wait until then to see if there's any other feedback.
It is Friday, so I've now pushed -02. It just contains this PR. URL


Fixes artwork formatting.
[x] requests and responses to use different artworks [x] artworks not containing trailing/heading carriages


to use the new "validator" name. See: URL URL
NAME I'm quite weak on that side: is this PR correct? If not feel free to fix at will :)
NAME I agree... this comes from the original RFC 3230. Merging the change as a simple terminology update. The relation b/w validators and the resource is discussed in , where I tagged you as your guidance will be great. See too.
to clarify the following passage for defining the behavior of digest with caching (eg. when Digest is returned together with Last-Modified and ETag). and to better extend the definition of Digest to POST and PATCH requests. This is because though only when they include explicit freshness information. If we go on the new http-core definition (which is cleaner) we have that eg. According to URL POST responses identify returned resources in different ways according to the following: the primary resource is identified by Content-Location the enclosed representation matches the primary resource eg. 1 eg. 2 primary resource identified by enclosed representation matches the status of the request according to the resource's own semantic eg.
re-reading the old RFC my understanding is that validator fields should just be aligned with Digest (that is: digest-value should be aligned with the values of last-modified and etag). While it is trivial, the original editor could have considered that a potential issue.
The change itself looks right. I wonder however about the whole paragraph: what does it mean to say "resource is specified"? Doesn't that also need request header fields upon which the returned representation varies?


Rationale for 503 is that the service is unavailable due to too many connections. 429 could potentially be an option as well, but that seems more specific to a single user hitting a rate limit, while seems more related to a global limit. /cc NAME NAME


Replaces the old with from URL The relations of Last-Modified and ETag with Digest are examined in


Clarifies the "returned value" expression.
There are two occurences of the fragment This is not the most helpful of statements, when we say "returned value" what exactly are we trying to convey. I think it would help to be a bit more exact.
Thanks. Longer term, I'd like to do an broad editorial sweep to tighten up document and this is an enabling step that I think this takes us most of the way there. I made some suggestions to move words around a bit.


I want to republish the CH draft as it expired, and the change logs didn't include a bunch of the recent changes. NAME NAME - Can you take a look?


An alternate can send an Alt-Svc field that overrides that sent by the origin and is cached on an equal basis.


clarify editorial rendering of binary payloads
in this example (and other), URL something like that:


For . Note that this makes missing values ; if we like that approach, I think we should do it for missing parameter values too (currently they use , which isn't part of our type system). I used because it aligns with the semantics of current uses nicely.
OK with me.
NAME This is a keen observation. Assuming that we are fine with requiring that knowledge on what the top type is, maybe we should also consider adding support for rule. It has been my understanding that the only reason we do not support rule in SH is because can only be applied for certain top types (but we are now requiring that knowledge).
We've discussed requiring knowledge of top-level types extensively, and I think we have agreement that it's OK. I"m not sure what you want regarding support for ; can you give an example (or open a new issue)?
I'm running my SH implementation against the HTTP Archive dumps (400,000,000+ HTTP requests) to see how the from BSH parse in something like the real world. A number of headers are failing because they have valueless dictionary members; e.g., , , . It should be pretty easy to accommodate these, as we already have optional values on parameters.
PTAL at the PR, especially the note about using True for missing parameter values.
Ping NAME NAME
Seems like a reasonable change. I'm happy to remove the 'null' from parameters too.
(already OK'ed in the PR)


I'm really not sure what happened there, but don't have time to investigate. I suspect GitHub didn't actually merge.


As they relate to changes in SETTINGSHEADERTABLE_SIZE. This is the strict, by-the-book interpretation. That is, if the value changes, you have to send the update, even if it is pointless (that is, you aren't changing the size of the table). Note that I'm eliding the point about multiple instructions, which are necessary if the decoder reduces the maximum below the current size. The only nod in that direction is "at least one" and a reference to the section that talks about the need for multiple updates. This pulls in more of RFC 7541 than I might have liked, but we have to deal with the integration somewhere and this seems like a reasonable place to do that. It might have been better to put this text in a -bis revision of RFC 7541, but we decided to leave that document as-is.
LGTM, this is a nice clarification that removes the possibility of a different interpretation that's known to have caused interoperability issues (nghttp2 vs haproxy). Let's merge it!
Oh I see this PR already being merged. Opened .
I think this PR is in the correct direction. Endpoints have to process instructions using dynamic table, even when they advertise SETTINGSMAXHEADERLISTSIZE of zero. That is because the default is 4096. We did fix this problem in QPACK, but HPACK had already shipped. OTOH, I have concerns regarding new text suggesting Dynamic Table Update Size be sent even when there is no change in the size.I agree with Willy, this is a really good clarification.


This reverts commit 290e381719b2fefe4e6182d3be288c48e8f5fd7e. See for most of the discussion. The key change here is to address by only requiring that the change be signaled when the table size is reduced. When I dug more into this, it's a more disruptive change, so I've made a bunch of additional changes in support of that.
I have one suggestion about a point that seems to be possible to infer from all this but is not explicitly written and may condition the sequencing of operations. Do we want to support multiple settings updates on this parameter, hence announce in the middle of a communication that we changed our local decoder size ? It seems to me that this is the case but it does not appear in the original text where it more likely sounds like the initial size. If we want to support repeated size changes from the decoder, then I agree that it's better to consider that 4096 is initial and that the setting changes it and Kazuho's wording sounds fine. But then it possibly ought to be explicitly mentioned such as: This makes sure that it's safe for an encoder to only process the settings frame once and to send a single DTSU instead of one per SETTINGS frame.
NAME I struggled a little with your text, because I think that is what this already says. However, to address your question about settings changes, I don't think that we do really want multiple settings changes, but that is the protocol we have. So multiple settings changes are possible and implied by the design of SETTINGS. Multiple changes are possible within the same SETTINGS frame, in case you were interested. The designers of this protocol seemed to love unnecessary complexity. There are some good reasons, but it's not clear that those reasons are sufficiently strong to justify the headaches they cause. I would really like it if implementations could just signal once in the preface, handle the preface from their peer and be done with settings. That's how HTTP/3 works and while we might have been forced into it there by the complexities of the QUIC integration, it turned out to be a good outcome in my view. Here, however, we need to deal with the fact that the protocol permits changes.
Hi NAME I'll have to clone your repo and run the diff here by hand then because I can't figure in this horrible interface how to view the complete set of changes at once resulting from multiple subsequent changes. And it will be easier to reread Kazuho's proposal in context. Regarding "do we want" I didn't imply that we love this situation, just "do we want in order to support this interpretation of the protocol", given that the current text never explicitly states that (as Cory mentioned a while ago, the settings change is acked by a the settings ack) and that even the protocol's original co-author back then already stated that it wasn't meant to be interpreted that way ( URL ). Sure, the result is that we have what we have and we have to deal with it in the best way possible. In that spirit I think that Kazuho's proposal tries to be as closed as possible to the current state of deployment by indicating how some implementations behave vs what others expect and suggesting not to play in the gray area there.
Hervé's post there is quite useful, yes. That supports this overall view. I've cleaned up the comments on the diff view; let me know if what you see works. The diff overall is fairly clean (it's mostly additions).
I'm just a bit confused, where am I supposed to see the unified diff ? the only way I know is by clicking on each individual commit, which is the solution I find inconvenient :-/ Do I have to add a magic ".patch" in the URL bar somewhere ?
There's a "Files changed" tab toward the top of the page: ! Adding ".patch" to the URL is a neat hack for finding something you can download, but usually I find that pulling from the branch is nicer to work with.
Thanks for pointing that one, I always thought it only contained the original PR's changes, not the latest proposed ones :-) I'm seeing this part which remains confusing: "Any change to the maximum value set by the decoder takes effect when..." which I'm reading as "the decode first sets a size, then any change to this size ...", thus reinforces what most servers currently do. I think Kazuho's proposal to move the sentence about initial values solves this: "The dynamic table has a maximum size that is set by a decoder using the SETTINGSHEADERTABLESIZE setting; see XXX. The encoder at both client and server is initialized with a dynamic table size of 4,096 bytes, the initial value of the SETTINGSHEADERTABLESIZE setting. Any change by the decoder to the maximum value takes effect...". This makes it clear that the initially advertised value is a change, which currently is the main point of disagreement. Proabably that we should wait for the end of new year holiday before merging it, so that other implementers for whom this is a change of behavior can have a look.
NAME NAME it would be nice if you, as implementers, could have a look at the proposals here, given that your implementations will need to be updated as well. In haproxy this results in a little ugly trick where the H2 layer has to inject an HPACK opcode (0x20). That's trivial but ugly enough that it warrants a second thought before jumping on any final solution.
NAME Apache is lazy and uses libnghttp2 for h2 protocol handling. It does not change the dynamic table size and all its handling and ACKs are done by nghttp2 transparently. If any changes are necessary, I'd expect them to come with an updated version of libnghttp2 and, since that is linked dynamically, no need to us to release anything new.
NAME I actually wonder if you failed to push the branch here, I saw new commits being pushed to URL instead.
Ugh, my bad. Having two remotes sometimes bites me. Sorry about that Willy. (And thanks for noticing Kazuho.)
No problem Martin, don't be sorry, you're the one doing the job :-) I'm almost fine, almost everything is OK but there remains one ambiguity in that sentence: "A decoder MUST treat a field block without a sufficiently small Dynamic Table Size Update instruction that follows an acknowledgment of a reduction of SETTINGSHEADERTABLESIZE as ...". It ought to be "a reduction of SETTINGSHEADERTABLESIZE below the current size of the header table size etc" (which is slightly different since we don't want to have to re-emit a DTSU if the previous value was already smaller). Given that this principle was explained in the previous sentence, I think we can simply address this by adding the word "such" before "a reduction": "... follows an acknowledgement of such a reduction of SETTINGSHEADERTABLE_SIZE", or probably even simpler, write "acknowledgement of such a change".
Ahh, yeah, it's hard to balance correct and clear here.
I think it's OK now. NAME NAME , care to recheck ?
Good catch indeed!
OK for me as well now. Let's hope it will not cause difficulties (e.g. for those who would pre-queue stream frames).
Enqueuing stream frames (or any frame) and then allowing a settings change to occur ahead of those frames is very risky. Anything that you do in those frames might violate a changed constraint. If you must, enqueue all frames, SETTINGS included.
I generally agree, but it's a matter of design choice (or constraints). Before this change nothing implied a possible change of headers frames representation after the requests started to flow, so that was technically possible. There are not that many H2 implementations anyway so we'll see. But I also agree that here at least we keep the option of postponing the SETTINGS ACK frame, which leaves some options open if this issue is raised. Thanks!
Hi Cory, I suspect, as you suggested in your last sentence, that writing "HPACK encoder" and "HPACK decoder" here would remove any ambiguity. Of course we know it's not the HPACK encoder in terms of code that acks for example, but it's the same endpoint and that is sufficient to declare who does what.
I've taken Mike's suggestion and mixed in a few "HPACK decoder" and "HPACK encoder" statements, using "endpoint" for protocol actions (settings, connection errors). Tell if this makes more sense to you NAME or if I've messed it up.
aside the typo above, LGTM. Thanks Martin!
NAME I guess we've left it long enough for reviews, it's probably okay to merge it by now, what do you think ? As a bonus it would close the last issue.
Opening a new issue as I notice that has been merged already. Text added by states: An encoder sends a Dynamic Table Size Update instruction after acknowledging a change of SETTINGSHEADERTABLESIZE even if it is not changing the size of the dynamic table or an increase to the maximum size is subsequently reverted before the field block is sent. I am not sure if this correct interpretation of RFC 7541, and also am concerned that this text might cause new interoperability issues. states: 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]). As can be seen, this paragraph of RFC 7541 starts "a change." When an HTTP/2 endpoint is using an HPACK encoder with a dynamic table of size 4,096 (the default) and receives SETTINGSMAXHEADERLISTSIZE of 4096, it is not changing the size of the dynamic table. My interpretation of RFC 7541 would be that it does not require Dynamic Table Update Size to be sent when the table size remains the same. Interoperability-wise, do existing servers respond with a Dynamic Table Update Size instruction when the client sends SETTINGSMAXHEADERLIST_SIZE no less than 4096? It seems to me that this newly added text suggest such behavior is required, but I'm not sure if many servers behave as such. added text indicating that endpoints MAY error-close the connection when not seeing such behavior. Even if we are to agree that Dynamic Table Size Update MUST be sent in all cases, I'm concerned that we might see more interoperability issues by suggesting that endpoints can error-close.
Yup, I think this works well. Nice work NAME


draft-ietf-httpbis-messaging is now going to be known as "HTTP/1.1". Follow suit.


It's going to happen anyway, but we can at least warn people. This doesn't specify what validation is necessary in any detail (that is somewhat involved), it only notes that simple concatenation is almost certainly not secure.
OK that's fine by me. At least they're warned, and those who want to know more will easily find info on the subject, including these conversations. Thank you Martin!
Before we definitely forget about it, could we please have a consideration for that one: URL There is nothing in H2 that prevents pseudo headers from being abused, and it's suggested that they have to be reassembled to make the whole request line, that is usually parsed later to extract the relevant parts, leading to the trouble reported in the portswigger article. And semantics only apply to the recomposed parts, which is too late. I would really like that we suggest controls there so that future implementations do not get caught by this uncovered area, and the comment above proposes the minimalist controls that protect against such attacks.
Willy, this document is now through IESG evaluation and is about to go to the RFC Editor. Adding substantial new text with requirements would require going back to the working group.
Sorry for letting that comment pass at the time NAME It's a reasonable request, but I don't think that we can go as far as specifying specific validation rules. URIs are just too complicated for that. I suggest that we add a special note to which already talks about how intermediaries might be forced to pass on bad stuff. See .
NAME I understand and your approach looks reasonable, many thanks! I've added a tiny comment so that we don't forget to mention ":method" that was also severely abused there, and it's OK for me. NAME I'm not trying to perform substantial changes but have been trying to reload that one over the last 6 months so that we don't miss it. It has been the main cause of generalized vulnerabilities coming from word-for-word implementation of the spec into code, the least we can do is warn implementers.
LGTM.


Not "of the HTTP protocol".
and 9: To avoid the appearance of "of the Hypertext Transfer Protocol protocol", should these two instances of "of the HTTP protocol" be "of HTTP" (or perhaps, in the case of , "HTTP attributes" instead of "attributes of the HTTP protocol")? Original: The frame and stream layers are tailored to the needs of the HTTP protocol. ... This section outlines attributes of the HTTP protocol that improve interoperability, reduce exposure to known security vulnerabilities, or reduce the potential for implementation variation.
Yeah, "of HTTP" is probably best here.


: We had trouble parsing this sentence. Is a word missing? If neither suggestion below is correct, please clarify what "any frame carrying ... SETTINGS" refers to. Original: A frame size error in a frame that could alter the state of the entire connection MUST be treated as a connection error (); this includes any frame carrying a field block () (that is, HEADERS, PUSHPROMISE, and CONTINUATION), SETTINGS, and any frame with a stream identifier of 0. Suggestion (... and a SETTINGS frame): A frame size error in a frame that could alter the state of the entire connection MUST be treated as a connection error (); this includes any frame carrying a field block () (that is, HEADERS, PUSHPROMISE, and CONTINUATION) and a SETTINGS frame, and any frame with a stream identifier of 0. Suggestion (... or a SETTINGS frame): A frame size error in a frame that could alter the state of the entire connection MUST be treated as a connection error (); this includes any frame carrying a field block () (that is, HEADERS, PUSH_PROMISE, and CONTINUATION) or a SETTINGS frame, and any frame with a stream identifier of 0.
Suggestion 1 is correct.
I think that the list structure is supposed to be... includes: any frame carrying a field block (...), a SETTINGS frame, and any frame with a stream identifier of 0. Which suggests option 3, in my PR.
LGTM.


This looks terrible, but it's the form that the RFC we cite uses (also, RFC 1323).
: We changed "Flow Control Performance" to "Flow-Control Performance" per the title of ("Flow-Control Principles"). Please let us know any concerns. Original: 5.2.3. Flow Control Performance Currently: 5.2.3. Flow-Control Performance
and 5.2.3: Should "bandwidth-delay product" be written as "bandwidth * delay product" per RFC 7323? Original: Note, however, that this can lead to suboptimal use of available network resources if flow control is enabled without knowledge of the bandwidth-delay product (see [RFC7323]). Even with full awareness of the current bandwidth-delay product, implementation of flow control can be difficult. ... If an endpoint cannot ensure that its peer always has available flow control window space that is greater than the peer's bandwidth-delay product on this connection, its receive throughput will be limited by HTTP/2 flow control.
I think "bandwidth-delay product" is the standard representation of the term. It's not a term specific to this document but a broader term of art. I recommend not taking this suggestion.
Thanks, I hate it.


: As this sentence seemed to indicate that the sender itself was sent, we updated the text to clarify that the GOAWAY is sent. Please let us know if this update is incorrect. Original: Once sent, the sender will ignore frames sent on streams initiated by the receiver if the stream has an identifier higher than the included last stream identifier. Currently: Once the GOAWAY is sent, the sender will ignore frames sent on streams initiated by the receiver if the stream has an identifier higher than the included last stream identifier.


: We had trouble parsing this sentence. If the suggested text is not correct, please clarify what prevents cookie-pairs from being sent on multiple field lines. Original: This header field contains multiple values, but does not use a COMMA (",") as a separator, which prevents cookie-pairs from being sent on multiple field lines (see Section 5.2 of [HTTP]). Suggested: This header field contains multiple values but does not use a COMMA (",") as a separator, thereby preventing cookie-pairs from being sent on multiple field lines (see Section 5.2 of [HTTP]).


I had to add to one use of :authority.
and subsequent: Please note that, per the rest of this cluster of documents, we have placed the terms beginning with a colon (":method", ":scheme", etc.) in double quotes where they appear in running text. Please review, and let us know any objections.


Also, use .
and 9.1.1: We quoted "https" where preceded by "resources". Please let us know if this is incorrect. Original: CONNECT is primarily used with HTTP proxies to establish a TLS session with an origin server for the purposes of interacting with https resources. ... For https resources, connection reuse additionally depends on having a certificate that is valid for the host in the URI. Currently (best viewed in the .html or .pdf output): CONNECT is primarily used with HTTP proxies to establish a TLS session with an origin server for the purposes of interacting with "https" resources. ... For "https" resources, connection reuse additionally depends on having a certificate that is valid for the host in the URI.
Folded into .
: We made quoting consistent around lowercase instances of "http" and "https" when describing URIs or schemed URIs, per quoted instances in , 3.2, and 10.1. Please let us know any objections. Original: http and https schemed URIs http or https schemed URIs http or https URIs Currently: "http" and "https" schemed URIs "http" or "https" schemed URIs "http" or "https" URIs


CLoses .
: Does "the same sequence of frames as defined in " mean "the same sequence of frames as that defined in " or "the same sequence of frames, as defined in "? It appears to us that it means "URL that defined in ", but please advise. Original: The server uses this stream to transmit an HTTP response, using the same sequence of frames as defined in
It means "as that defined in Section 8.1".


: Does "as" mean "while" or "because" in this sentence? Original: Connections that remain idle can become broken as some middleboxes (for instance, network address translators or load balancers) silently discard connection bindings.
"As" means "because" in this sentence.


This is awkward, but this is better.
and 8.8.4: Because "control data and a request header and message content" reads a bit oddly, we changed it to "control data and a request header with message content" per "control data and a request header with no message content" in Please let us know if this is incorrect. Original: An HTTP POST request that includes control data and a request header and message content is transmitted as one HEADERS frame, followed by zero or more CONTINUATION frames containing the request header, followed by one or more DATA frames, with the last CONTINUATION (or HEADERS) frame having the ENDHEADERS flag set and the final DATA frame having the ENDSTREAM flag set: ... A response that includes control data and a response header and message content is transmitted as a HEADERS frame, followed by zero or more CONTINUATION frames, followed by one or more DATA frames, with the last DATA frame in the sequence having the ENDSTREAM flag set: Currently: An HTTP POST request that includes control data and a request header with message content is transmitted as one HEADERS frame, followed by zero or more CONTINUATION frames containing the request header, followed by one or more DATA frames, with the last CONTINUATION (or HEADERS) frame having the ENDHEADERS flag set and the final DATA frame having the ENDSTREAM flag set: ... A response that includes control data and a response header with message content is transmitted as a HEADERS frame, followed by zero or more CONTINUATION frames, followed by one or more DATA frames, with the last DATA frame in the sequence having the ENDSTREAM flag set:


: This sentence reads oddly. As it appears that the problem in question causes TLS handshake failures, we updated accordingly. Please let us know if this is incorrect. Original: To avoid this problem causing TLS handshake failures, deployments of HTTP/2 that use TLS 1.2 MUST support TLSECDHERSAWITHAES128GCMSHA256 [TLS-ECDHE] with the P-256 elliptic curve [RFC8422]. Currently: To avoid this problem, which causes TLS handshake failures, deployments of HTTP/2 that use TLS 1.2 MUST support TLSECDHERSAWITHAES128GCMSHA256 [TLS-ECDHE] with the P-256 elliptic curve [RFC8422].


: Should "Content-Length" be enclosed in "" elements in the XML file? We ask because we see three instances of " header field" in the XML for Original:
Probably, yes.


: We had trouble parsing this sentence. Does "The use of field section compression and flow control depend" mean "The use of (1) field section compression and (2) flow control depends", or does it mean "Flow control and the use of field section compression depend"? Original: The use of field section compression and flow control depend on a commitment of resources for storing a greater amount of state. Possibly ("Using ... depends"): Using field section compression and flow control depends on a commitment of resources for storing a greater amount of state.
The former is the correct variant, I think.
Suggesting instead:


: Please confirm that "i.e.," is correct here (in which case "SETTINGS changes, small frames, field section compression" should be "SETTINGS changes, small frames, and field section compression") instead of "e.g.,". Original: Most of the features that might be exploited for denial of service - i.e., SETTINGS changes, small frames, field section compression - have legitimate uses.
I think that this should probably e.g., not i.e.


Values is correct in the first case, but the second should be "a value" by which it means "any value".
and 10.9: Please confirm that these instances of "value" should not be "values". Original: These include the value of settings, the manner in which flow-control windows are managed, the way priorities are allocated to streams, the timing of reactions to stimulus, and the handling of any features that are controlled by settings. ... Ensuring that processing time is not dependent on the value of secrets is the best defense against any form of timing attack. Possibly: These include the values of settings, the manner in which flow-control windows are managed, the way priorities are allocated to streams, the timing of reactions to stimulus, and the handling of any features that are controlled by settings. ... Ensuring that processing time is not dependent on secret values is the best defense against any form of timing attack.
These should both be "values".
Values is correct in the first case, but the second should be "a value" by which it means "any value".


Error when stream identifier field is 0x0 is not stream error but connection error because it is impossible to send RST_STREAM of 0x0.


It is no longer used after d5a8faeaa605bdff7b96287d72913b4b742104cf
I've avoided renumbering of codes when removing things. We probably need to have a big renumber event at some point, but there is no harm in having gaps for now.
Thanks Martin. It makes it easier for us on the SPDY side :) On Wed Jun 12 2013 at 9:37:50 AM, martinthomson EMAIL wrote:
NAME I've updated the commit just to remove only the unused error code. Please don't forget to renumber others in the future.


As discussed in the interim, 8-byte PING frame, opaque octets that MUST be included regardless of whether they are used.


Curious why the connection flow control window initial size is 64K (65536 bytes) but the stream flow control window initial size is 65535 bytes. The negative flow control example (taken from the SPDY spec) states that the initial stream flow control window is 64K (the SPDY/3 value).
I have to stop trusting Will's edits. He, rightfully, challenged the use of SETTINGS to end connection-level flow control because WINDOW_UPDATE provided another way to do the same, and two ways to do the same thing is bad. I'll fix that up.


All other frame descriptions specify explicitly if the frame type does not have any type-specific flags. The PRIORITY frame description should do the same if there are no flags.


This branch also renames the FINAL flag to ENDSTREAM and the CONTINUES flag to ENDHEADERS.
Address
I'll take it, and we can continue to discuss the redundant bit.


Also reservers flag 0x2 in DATA and HEADERS frames and renumbers flags accordingly.
Please feel free to exercise editorial privilege with respect to wording. Reserving 0x2 at NAME requests.


As discussed in the interim... (I had previously submitted this in a batch against the Layering branch... redoing against the Master)
Looks good for the most part, consider the comments as advisory only.


:Client advertising settings during Upgrade dance URL
I assume that this header field is hop-by-hop in the HTTP/1.1 sense and should appear in the Connection header field.
Ooops, yes! Just checked that in.
This issue is to track whether the client should advertise its settings (e.g. contents of SETTINGS frame) as part of the Upgrade GET (e.g. as HTTP/1.1 headers in the GET request). Normally, the first HTTP/2.0 frame the client emits is the SETTINGS frame. This means the server will receive the client's settings before getting the SYNSTREAM from the client. However, in the Upgrade Dance the server receives the GET and has to respond with a 101 HTTP/1.1 response followed by the HTTP/2.0 SYNREPLY. The ugliness here is that the server will be in a situation where it has to send the SYN_REPLY (and possibly DATA frames and possibly start push streams) without knowing the client's settings. This means the server may blow the client’s flow control buffers, or emit a pushed stream even though the client is incapable of processing pushed streams, etc. If we include the settings as part of the initial Upgrade GET then 1) Server receives the pre-requisite initials settings and the initial GET request in a single package. Makes life simpler. 2) Brings us to parity with the SSL route where the server will have the cilent's SETTINGS before it starts working on the initial request.
Discussed at SF Interim; targetting 1st implementation draft. Gabriel to make proposal.
Addressed via "HTTP2-Settings Header Field" section.


half closed (client/server) is no longer used. :scheme header MUST include HTTP Request
NAME The fixes of the commit of 73dce91fcccecce7079d7ccf6294e80350d5ce19 were somehow lost after ea5abcf90460dc300b94eb27d82162f56a1dc526 . I'm not sure why it happened without conflicting. Please fix them by your hand.
Will do. It's easy enough to fix.


I think this is strictly an editorial clarification, not a technical change, but something that came up in discussions within the team. If there's any question about that, feel free to push it back and we'll discuss on-list.
This looks like , sort of. I think that we need a little more than what you include here. This covers the initial SETTINGS frame, but there are bits in 3.8.5 that need fixing too.
Similar issue, different layer…. is talking about multiple instances of the same setting value in a single SETTINGS frame. This commit is talking about multiple instances of the “HTTP2-Settings” header in an HTTP/1.1 request that’s offering Upgrade. From: martinthomson [mailto:EMAIL] Sent: Thursday, July 18, 2013 3:49 PM To: http2/http2-spec Cc: Mike Bishop Subject: Re: [http2-spec] Clarify no duplicate instances of HTTP2-Settings () This looks like URL, sort of. I think that we need a little more than what you include here. This covers the initial SETTINGS frame, but there are bits in 3.8.5 that need fixing too. — Reply to this email directly or view it on URL
Ahh, I don't see this as a big deal, since "a header field" and "exactly one header field" seem equivalent to me. I'll pull it in.


Fixed the word "client" to "request" on "HTTP2-Settings Header Field".


We've seen varying amounts of advantage from having header table substitution enabled. Most are fairly minimal, even assuming perfect foresight. Some tests show single digit percentage improvements, others are much less. The feature adds some complexity. Is this complexity justified? Should we remove this feature?
Offline discussions: NAME and NAME agree that if this isn't removed, we should swap the opcodes so that substitution gets a worse (the longer) opcode.
Discussion in Seattle resulted in a conclusion to remove the substitution opcode from the draft.
Fixed in .


On Sun, Oct 20, 2013 at 05:23:50PM -0700, Roberto Peon wrote: Here's a proposal for that.


Instructions for Indexed Representation of entry already in header table say to add entry to header table again, don't mention reference set.


We've long since agreed that full request headers are sent in the PUSHPROMISE frame; found a lingering reference to pushed resources "inheriting" headers from the original request. Revised it to reference the request headers in the PUSHPROMISE frame like everywhere else.


This updates the concurrent streams in the XML and updates the HTML too (which picked up some other changes).
"For implementors it is recommended that this value be no smaller than 100" - what is the significance of "for implementers" here? I'm concerned this language is ambiguous enough to cause trouble. E.g., some may read it as pure advice; others might take away that values smaller than 100 can be assumed to be 100. Best way to specify is with MUST/SHOULD/MAY, identifying who it applies to (sender / recipient), and ideally specifying what should happen on both ends of the wire (when generating and receiving).
I agree this is ambiguous. I snuck in a short explanation there. I feel like we should take this back to the working group mailing list. I propose we either commit as is, as my extra explanatory clause is innocuous, and open an issue to resolve the ambiguity. Or I can withdraw this pull request for now, go back to the mailing list, and proceed with the flow control pull request first.
I'm happy to merge now and note an issue; just trying to minimise the number of such edits we cause with each change, as they have a tendency to stack up.


TLS Client Hello's between 256 and 512 bytes need to be rounded up to 512 for compatibility reasons. This incents us to keep Client Hello parameters as small as possible to avoid the rounding - this change shortens the ALPN token of HTTP/2.0 to be simply "h2"
Discussed in Zurich; we will take this and hold back the eventual heat death of the universe a byte at a time.


In URL;list=ietf-http-wg, it was proposed that the PRI method be reserved in the HTTP/1.1 method registration document to avoid possible future reservation and ensure that the magic string remains a reliable way of differentiating HTTP/1.1 connections from HTTP/2.0 connections. There was a +1 and some offline discussion along the same vein, no dissent that I heard or saw. However, I don’t see it in URL, presumably because no RFC exists to reference. The appropriate doc is probably HTTP/2.0 rather than breaking the glass on the prepopulated registrations.
There was a question whether "SM" should also be reserved; I personally don't think so, since that line will never be interpreted as a potentially-valid HTTP request line or header. However, I don't think it would break anything if we did.
Break things, no. Squat on prime name-real-estate, a little.


The sentence in 8.3: "CONNECT is primarily used with HTTP proxies to established a TLS session with a server for the purposes of interacting with https resources." ... does not read. I believe it should be: "CONNECT is primarily used with HTTP proxies to establish a TLS session with a server for the purposes of interacting with https resources." This pull request fixes this incredibly minor issue.


This is almost a straight revert of the various GOAWAY -> GTFO changes. It seems like this is the popular move as per the discussion on the httpbis mailing list. Arguments for the revert: GOAWAY is self-descriptive and serves it purpose well. Editorial changes that don't clearly improve the spec should be discouraged so we can reach a stable spec sooner (granted this change doesn't affect the wire at all, but documentation churn counts too). GTFO is crass and doesn't belong in internet standards. GTFO, if it really stands for "General Termination of Future Operations," has a surprising definition and may produce confusion. We should strive for absolute clarity above all else in editorial changes.
Boo! You guys are no fun.
goaway is just as bad as gtfo for the same reasons as the argument against gtfo... just called it disconnectclient or endcommunication if you're going to be a grumplestiltskin.
QUENCH may be a better, more descriptive word that has been used before in RFC's (for TCP Source Quench messages)
I think we should call it BIKESHED. , Sean McElroy EMAIL:
Here we go.. useless HN circle jerk.
:cat2:
How about STFU?
Boo!
:-1:
This commit should be reverted. It's time we stop behaving like oversensitive automatons and display the beautiful human quality that is a sense of humor every once in a while.
^ this
^ that
how about something like PLZSTOP? it's slightly humorous, but it actually reflects what is wanted (if I understood the spec correctly)
GOAWAY is clearer for non-native English speakers, easier to pronounce, and more professionally appropriate than the common connotational definition of GTFO. There are times and places for pushing the boundaries of professional speech, but the HTTP2 spec isn't one of them.
At least the pendulum didn't swing the other way NICETALKINGTOYOU
This revert is for the express purpose of stopping endless bikeshedding. We shouldn't encourage trivial changes to frame names. If the name is good enough, it should stay. I'm all for fun and games, but clarity and concision (as well as spec stability) come first. For those that prefer GTFO, please explain how it is clearer than GOAWAY (please consider an international audience too).
so mean spirited, this change.
Could always name it SHUTDOWN (yay SCTP) , Adrian Cole EMAIL:
"International audience" here. I'm Armenian, English isn't my native language, not even my 2nd language. GTFO to me is more meaningful and more concise than GOAWAY, or any other option mentioned in the comments. GTFO to me doesn't produce any confusion and its actual definition of "General Termination of Future Operations" is actually nice, smart, and descriptive rather than "surprising" in any negative sense. It also formally de-crasses the word. Of course you can tell me that I'm just a single example, but then again you can tell that to any amount of people. Pretty much the only valid argument out of the posted ones is that GTFO is crass (see I didn't know what "crass" meant before reading this). Everything else about descriptiveness and understandability by "international audience" are in my opinion totally irrelevant and unfair.
NAME thanks for the internationalization datapoint and on-topic discussion! Can you elaborate on how GOAWAY is not clear, and how GTFO is clearer? To me, the main argument is that GTFO is not meaningfully more clear than GOAWAY.
If folks have serious contributions to make, they should be on the mailing list, not here, as per URL Now I get to try out NAME
NAME START
NAME Neither option is appropriate or clear... they're both childish choices and neither are semantically appropriate. I've seen some much better options in this thread. if this change were actually about caring about professionalism, clarity of meaning, or necessity, the innumerable amount of better choices (SHUTDOWN, ENDCONNECTION, QUENCH, etc...) should have been used over GOAWAY or GTFO... But its not.. this is about personal preference. this change made nothing better, it made nothing worse. In my opinion, for that reason, it should be reverted.
FWIW, and for lack of anyone else talking about a pro of GTFO. When at the working group, a lot of thick topics were discussed at length and everyone there seemed 100% dedicated to having the best spec there is. GTFO, as a word, is harmless to implementation for reasons including the opcode is the same. IOTW, the binary representation is the same. There's no technical reason why it matters. I am one of the implementors of this specification. When the change was suggested towards GTFO, I felt motivated I mean the audience of this spec are implementors, some of which may be uptight about crassness others less so. If you look at github (ps this is on github) there's ample evidence that implementors are motivated by words that aren't boring. For example, there's a popular package manager called "fpm". Guess what that stands for? I'm not saying go back and re-word everything to be fresh, rather have patience with those who are literally implementing this, in open source, and are ok with the choice. Expect many more implementors to arise from github, a place relatively unburdened by crass-ness or location.
NAME I'll split the answer to 2 sections. AWAY vs. Out -- AWAY implies a certain longish physical distance, whereas Out seems to imply just "out". AWAY vs "General Termination of Future Operations" -- obviously the second is much more clear and descriptive.
GTFO would be my vote. No future operations, full connection termination, it describes the action best.
NAME if you feel strongly, mail on this thread as not everyone there are on github to see your pov URL
NAME - will do, thanks. I need to dig my W3C mailing list info; haven't used it in years. Cheers!
From the W3C mailing list: Thanks, NAME :) Cheers!
All made points aside, I couldn't find a very important one; to me actually being the most important. If you think about what "Get Out!" could also mean (the offensive TF part is actually interchangable...), it becomes even more confusing. An expression of disbelief is surely the very last thing this acronym should imply. But it did to me; even as a non-native speaker (German). "General Termination of Future Operations" is, also in my eyes, a made-up term to fit the joke. It is more fitting than GOAWAY, but once you have read GTFO your mind is sort of made up, since you spelled GTFO in full in your head, as soon as reading the acronym. My suggestion on this one is: Simply get rid of "General" / "G" and add "of" to the acronym! TOFO still has a nice ring to it, is quick and easy to pronounce and "Termination Of Future Operations" would be sufficiant descriptive. regards (yes, that's my real lastname :P ) On Jan 29, 2014 8:31 AM, "Eugene Ciurana" EMAIL wrote:


Felt that this order was clearer since the requirement then back-referenced the previous flag instead of forward-referencing it. Feel free to ignore if you disagree.
I considered that option. I think that it's easier if the order of the bits is the same as the order the fields appear. I'll reopen and take this if others point this out though.
Confused by that. In the as-written docs the flags are: [R, R, R, R, PADLOW, PADHIGH, R, ENDSTREAM] but the frame layout is: [PADHIGH (8)], [PAD_LOW(8)] so the order of the bits is opposite the field order.
Let's chalk this up as yet another case of blindness on my part.


Editorial changes through Section 3.1.2. Further updates forthcoming.
Rebased onto current master.


NAME did you just forget to create the pull request?
Didn't realize you couldn't merge from the referenced issue. What do you need from me to merge the commit?
Just some indication that you think that this is ready, that's all.
Do you think we need to add a requirement for must emit? or is the not coalesce sufficient?
Now that you mention it, MUST preserve is really what we are going for.
added "MUST preserve"
There is some usefulness from both an extensibility perspective and a load balancing perspective to indicate multiple messages over an individual stream. This issue is to un-reserve the 0x02 END_MESSAGE flag to ensure that intermediaries that are deployed proxy the flag so that they are agnostic to the layered protocol and can still successfully load balance messages appropriately.
Note that this places a requirement on proxies that they cannot coalesce data frames across "END_MESSAGE" boundaries.
Discussed in Zurich with no real conclusion. Support and opposition were weak.
Discussed in Zurich; accepted in principle. Jeff to do a pull request.
Renamed ENDMESSAGE to ENDSEGMENT to avoid any confusion with HTTP messages. Feel free to re-name. Couldn't find any text that stated intermediaries could combine frames but may want to add a requirement that intermediaries must re-emit the flag at the same byte position.


This is a really minor thing, but as I was reading the spec, I was wondering for a bit what "extensions" meant (user defined? something else?). I think the intent is to reference extensions defined by future RFCs that revise HTTP/2 protocol.


Padding is made to a frame and other frames (DATA and CONTINUATION) have these 2 bytes right after the frame header. It is easier for implementation to put the same constructs in the same position.


This simplifies the text and makes flag consistent with CONTINUATION which only bears ENDHEADERS. Technically, both have the same meaning of ending sequence of header block fragments. Therefore there is no reason to use the different flag name for the same purpose. This will also make the implementaion easier because most likely HEADERS and PUSHPROMISE handling share the same code and dancing with ENDPUSHPROMISE and END_HEADERS is not fun. Although currently they have the same number, it is not guaranteed to the last. If they are guarenteed to be the same, then it is simpler to use the same name for same value.


l.815 before: An endpoint MUST NOT send frames other than than HEADERS/x:ref or fix: An endpoint MUST NOT send frames other than HEADERS/x:ref or


I realize this is somewhat redundant given section 5.1.1, so I don't mind if this pull is rejected. The main reason I think this might be useful is since there are two different stream identifiers involved in PUSHPROMISE: the promised stream id and the stream identifier in the common header. The extra sentence just makes it explicit how PUSHPROMISE is linked to an earlier request. It also puts the following sentence in better context.


I believe that PADLOW and PADHIGH bits in DATA frame were not updated when the dependency based priority was merged. It is quite a headache for implementors if these bits differ across frames.
Yeah, my bad. I missed one.


HTTP/2 has different properties to HTTP/1 regarding server-side load, because load balancers etc. currently exploit HTTP/1's short connections. HTTP/2 has much longer-lived connections, making it more difficult to load balance traffic. A mechanism to direct the client to use a different server/port would mitigate this. While GOAWAY could be used to do this, it introduces latency as the new connection is set up.
Alt-Svc?
URL
NAME is this really in the next milestone? It doesn't seem like we're ready yet.
Should get out a draft momentarily; if we don't make it, that's fine, but if we can, it'd be good to have a bit of discussion first.
NAME this missed the boat. Can I request that you put together something we can discuss in London instead.
Yes, it's on the list for discussion there. The boat technically is delayed at dock...
Discussed in London; agreed to using ALTSVC frame for this.


This wording once existed in priority branch in github, but missing in the current draft.


The priority groups are abandoned in favor of a single weighted dependency tree. The root node of the tree is the connection, assigned the stream identifier 0x0. By default, streams are assigned a stream dependency of 0x0 with a weight of 16.
Just read through it, I think it looks good. I'd like to understand how weight of the stream is calculated and changed. Here is my understanding: The effective weight of each stream is determined by traversing tree node, taking into account of distribution of weight of parent stream among siblings. This effective weight is temporal on the tree and initial weight is unchanged for a stream, so when reprioritizing that stream, its weight is initial one. For example, suppose we have the following dependency tree: X<--(w)--Y means that Y depends on X with weight w (and w is initial weight). Calculated effective weight is like this: If parent stream is closed, then its initial weight is distributed to among the child streams and this updates initial weight of child stream. So, after A was closed, the initial weight of streams becomes like this:
NAME thanks for this. I'll have to read through this more carefully before I comment. NAME that seems right. Note that this means that a server might want to maintain more precision on it's weight values than the 8 bits we mandate in the protocol. That said, if there are deep dependency trees and you are killing off nodes that are high up, at some point you will need to round off, so I think that how much precision is allocated is largely a discretionary thing.
Looks good. , Martin Thomson EMAIL:
It seems that we can make a stream to depend on stream 0x0 exclusively, which makes all existing connections its descendant. This is not possible in the current draft version. I wonder this can be directly proxy-able since stream 0x0 is imaginable stream.
Yea, the idea is that '0' is a reserved stream ID, and so it is safe to use it as a flag for saying that (effectively) any stream with '0' as a parent has no parent. , Tatsuhiro Tsujikawa wrote:
Well, then we should explicitly say that receiver must treat exclusive bit as 0 if stream ID field is 0.
NAME I would add an explicit hint to implementers that having more than 8 bits of internal precision is a good thing. NAME I think we should leave open the possibility to insert a new stream between the connexion and all its children, even if it's probably a large re-prioritization.
I think large re-prioritization is not a problem. If proxy gets such requests and it aggregates several frontend connections to single backend connection, inserting under stream 0x0 with exclusive flag set seems to be impossible in backend.
If it aggregates to a different backend connection it is not impossible to proxy. Consider streams A and B depend on stream 0x0 and are proxied to some backend connection as streams X and Y. If we get a new streams, C, that exclusively depends on 0x0, we can proxy it as stream Z by dropping the exclusive dependency and then re-prioritizing streams X and Y to depend on stream Z.
Yes, it works like that. But if we just don't allow 0x0 with exclusive dependency, we can do all priority stuff via proxy without doing any extra handling except for stream ID mappings.
Yep, true -- I don't have much of a preference -- if clients feel like it is not an important use case than I am perfectly happy to disallow it.
Is it possible to move this discussion to the mailing list? If you need comments from a client, I'm happy to take a look later. On Tue Apr 15 2014 at 9:39:56 AM, Jeff Pinner EMAIL wrote:


A proposal for adding GZIP compression to DATA frames. One possible resolution for .
This looks good. Thanks for putting this together. We'll see how the discussion progresses.
I realise we might also want to modify Section 8.1.3.5 Malformed Messages, to explain that Content-Length either cannot be sent if any frame is compressed, or measures the length after inflation, depending on how closely this maps to transfer encoding (URL). I suppose that's a follow-up issue for the WG to discuss.
No. You are right. Content-length applies pre-compression or post-decompression. We need to that clear. On Apr 22, 2014 4:28 PM, "Matthew Kerwin" EMAIL wrote:


We left open pending some explicit text about the double GOAWAY graceful shutdown. Here is some proposed text that we can iterate on. One difference from what we discussed is the first GOAWAY has last-stream-id of 2^31 - 1. The calculation based on MAXCONCURRENTSTREAMS isn't really needed and just opens up implementations to bugs.
I first brought this up in URL but I wanted to open an issue to track this as I believe this is a design flaw with HTTP/2 as it is today. Consider an HTTP/1.1 connection to a proxy that speaks HTTP/2 to the server. If the server needs to shut down, it will send a GOAWAY acknowledging the last request it processed. However, there is a race condition where a request could be in flight or queued. When the server eventually sees the delayed requests, it will not process it and the proxy will eventually return an error (most likey 5xx) to the client. Requiring proxies to buffer the request in order to replay for this case is not feasible. One solution is to have the server send an ALTSVC frame, but this is not ideal as it implies each server must keep track of a list of alternatives. It may not make sense for the origin server itself to maintain this (potentially quickly changing) list. Another solution is to allow acknowledging unreceived streams in the GOAWAY. For instance, the server could acknowledge last-stream-id plus SETTINGSMAXCONCURRENTSTREAMS. This might work in practice, but seems hacky. Another (and in my view best) solution would be to introduce a two phase shutdown mechanism. Some strawman language: "If a server needs to shut down for maintenance, the server SHOULD immediately send a DRAINING frame on all its client HTTP/2 connections to indicate that it will soon shut down. This allows the client to stop issuing new requests and avoids unnecessary retries. After a reasonable amount of time, the server SHOULD send a GOAWAY with status NOERROR on all its connections and then close the connection. Clients MAY may open new connections to the server after receiving a DRAINING frame."
I have added some text in URL that covers some of this. I'm going to leave this one open, because I don't think that this is completely done yet. We need to discuss whether we want to be more explicit about this particular use case.
Discussed in NYC; double GOAWAY sounds good.


A proposed explanation for what to do with large header blocks.
Discussed in NYC; this can be considered editorial.


... as new priority scheme demands and implies, but does not expressly permit. For .


Proposed text for .
This would be consistent with the plan for TLS 1.3.
NAME Firefox hard fails here, which I think is the right decision. I'll confirm with the working group.


HTTP/2 requires clients to support the gzip content-coding. The justification for this has always been that it helps avoid intermediaries and other interposed software (e.g., virus filters) that strip Accept-Encoding to avoid the pain of decompressing responses. However, it has been pointed out that doing so means that intermediaries that translate from 1 to 2 are now required to synthesise new entity tags for decompressed responses, breaking semantic transparency and/or losing significant HTTP functionality.
See also .
It also requires to rewrite ETags in request headers (conditional ones), which is an open-ended list. Furthermore, ETags also appear in payloads (WebDAV properties, for instance).
The outcome of this issue also affects
Discussed in NYC; will remove implicit gzip from spec; may create new content-coding required status code or other strategy (non-blocking).


Frames can be coalesced or split -- this is antagonistic to end-to-end, per-frame compression. This requires decompression / recompression in proxies that need to coalesce or split frame.
Discussed in NYC; no implementer interest, security concerns about proxying it. We believe it can be addressed as an extension now if someone wants to scratch that itch (and can find someone to interop with); however, fixing this properly means doing it at the HTTP semantic layer (e.g., with a new range type). In the meantime, remove frame compression.


Two minor things here: more strongly recommend the use of the frame type in HTTP/2 over the header field add a frame type number (no need to defer the choice now, this lets people build code based on this)


I have written what I think is a slightly more robust Security Consideration for HPACK. This covers: the attack in the general sense, how the attack might apply in HPACK and HTTP, particular areas of concern, how HPACK inherently mitigates these attacks, what environments might need additional mitigation, and some suggested mitigation strategies. Mitigation strategies that I have described are: actor-based isolation (a generalized application of the origin isolation principle) destroy values on failed guesses (thanks here to Adam Barth for the idea), either probabilistically, or based on a count, with a recommendation that shorter values be made harder to guess specific protection for "special" header fields There are a few formatting changes in the first commit, sorry.


Two small changes here. First, adding unnegotiated semantics to reserved bits in existing frames feels like a REALLY bad idea, since you're almost guaranteed to have collisions, so I'm suggesting we remove that as something that extensions can do unannounced. Second, we permit negotiated changes to existing semantics, so I'm suggesting that instead of saying only DATA will ever be flow controlled, we say that making anything else flow-controlled is a changed semantic that has to be negotiated.
(And as a side-note, section 6.9 implies that there may be frames other than DATA which are flow-controlled defined elsewhere: "Flow control only applies to frames that are identified as being subject to flow control. Of the frame types defined in this document, this includes only DATA frame.")


Mostly minor stuff from a readthrough. Of particular note: Regarding headers, "name-value pair" implies only one value; either it's a pair, and collections may have multiple instances with the same name; or it's a name with a collection of associated values. Either is reasonable, but both is confusing. Adjusting phrasing in SETTINGSHEADERTABLE_SIZE to better reflect that HPACK now lets the encoder change the table size at will. Removing suggestion that a GOAWAY frame can get "lost", which can't happen in TCP; actual issue is that recipient may have acted on the previous GOAWAY and retried the requests the server says it didn't process.


Could have been "a" just as easily, but I felt like a two-character pull request was just overkill.


Note: adds downref to Informational spec.
It has been noted that there is an opportunity for interoperability failure with the rules we have regarding ephemeral key exchange. e.g., client has only DHE, server has only ECDHE, can't use HTTP/2 Do we want to specify a mandatory to implement cipher suite so that we can avoid this?
Yes, I think you do. TLS 1.3 will be mandating ephemeral key exchange, so I think you just want to use whatever their MTI is (presumably either DHE or ECDHE with AES-GCM). I expect to have a preliminary answer to this in YVR. Will that be soon enough?
TOR, I hope. But I think that should suffice. We can discuss whether we try to preempt that decision or leave a placeholder.
Sorry, I meant YYZ.
Discussed in NYC; will make a decision about it in Toronto. Under discussion - ECDHE / DHE + RSA + AES-GCM + SHA256. Maybe another too.
We need to settle this for WGLC. NAME any chance of getting a decision earlier?
is editor-ready.


Now that we have decided to remove the reference set, the hacks we added to address header field ordering are no longer entirely necessary. 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'
This has implications beyond ordering w.r.t. compression efficiency, especially now that the number of items incurs a cost per item. , Martin Thomson EMAIL wrote:
nice, more red than green :)
Included into HPACK. Encoder and decoder SHOULD preserve ordering. :headers MUST appear before normal headers (in both encoded and decoded lists).


Looks like I caught some trailing whitespace at the same time.
The trailing whitespace came from an automatically generated part of the spec and will reappear if I ever re-generate the examples. In addition, it really should be here ;-).


Editorial suggestions for WGLC. I don't think there's anything controversial or semantically significant here, but please have a look over it before accepting.


I think the section could benefit from rearrangement some after this, but I'll leave that until later.
Once that's done, I'll have a look to see if there is anything that can be done to improve the section structure. The expanded material might need a new section heading and maybe some re-framing. Suggestions are, as always, very welcome.
I'll tweak this to soften the SHOULD and MAY.


A couple nitpicky things that jumped out at me in another readthrough. 3.2.1: Says that the SETTINGS parameters don't need defaults because of HTTP2-Settings, but they have defaults. Removing this claim. 3.3: Says that ALPN is used for HTTPS if you don't have prior knowledge, but 3.4 says you have to use ALPN even if you do have prior knowledge. Removing the caveat in 3.3 to reconcile. 5.1: Allowing WINDOW_UPDATE to be send in reserved (remote) state. This has been discussed in-person and on-list as a reasonable client strategy (low initial window, unchoke the pushes you want), but per the current text this is actually prohibited until after receiving the HEADERS frame. 5.2.1: Fixing sentence fragment. 5.3.2: Possibly just a personal/regional style, but from/to or between/and works for me; between/to doesn't. 6.1 and 6.2 use different definitions of the padding field. Copied 6.1's to 6.2.
Thanks Mike.


If an http2 implementation receives a frame with an unexpectedly large size, what should it do? As one example, a WINDOW_UPDATE should be 4 bytes. Or should it be at least 4 bytes? The Extending HTTP/2 notes at URL aren't clear about whether an unexpectedly long frame is okay. The closest I can find is: "Implementations MUST ignore unknown or unsupported values in all extensible protocol elements. " But I can't find a definition of an "extensible protocol element". It seems that the spirit of Section 5.5 would be to permit overly long frames.
I forgot to mention: there is FRAMESIZEERROR, but it only says: "If a frame size exceeds any defined limit, or is too small to contain mandatory frame data, the endpoint MUST send a FRAMESIZEERROR error." But only PING and SETTINGS mention it or a limit. What is the intended behavior for PRIORITY, RSTSTREAM and WINDOWUPDATE?


For . Here, I moved the text that covers the calculation of the dynamic header table size up into a new section. Then, I reworded the text to reduce the direct dependency on HTTP/2 and its settings. The emphasis is now on the using protocol setting a maximum, of which the HTTP/2 setting is just an example. Apologies for the diff, I'll try to split the move commit out to make it more readable.
OK, the first commit does the rewording, the second only moves text around.


This is an update of :
There have been a number of discussions about scenarios where we may want the client to fall back to 1.1 (a server forcing gzip, APIs incompatible with HPACK, etc.). HTTP/1.1 defines status code 505 as indicating that the server "refuses to support the major version of HTTP that was used in the request message [and] is unable or unwilling to complete the request using the same major version as the client [...] other than with this error message." However, that doesn't define a programmatic way to tell the user agent what version to retry with, simply a representation to be shown to the user. We should define a way to inform the client what HTTP version to retry with (presumably 1.1).
Discussed in NYC; task force-ish to come up with a proposal either using 505 or a new status code + header to point to the version(s) to bounce to.
Mark to write draft. use 505 extra header what version to down/upgrade to what the scope of applicability is (server vs resource) cache-control applies
Discussed in person, but capturing here: Scope could also be a path prefix, not just a single resource.
Marking this one as non-blocking. We need to discuss adoption of a mechanism for this; and that's not going to happen in the sorts of time frames we're talking about.
Can this be closed -- i.e., do we need to actually reference the new draft in HTTP/2?
Yep.
Reopening (preliminary) based upon feedback from Mike.


I think "an" is correct.
An is generally used only before a vowel. As in, "A, E, I, O, and U". An can be used before a "vowel sound" as well. But "h" in "http" is neither in my book. See URL for more info.
In (British?) English, 'h' can be pronounced either as 'aytch' or as 'haytch' so I would say that both 'a' and 'an' HTTP something should be considered fine.
Let's at least be consistent.
If you pronounce 'a' as 'ahh' then "a HTTP" sounds ok. If you pronounce 'a' as 'aye' then it sounds wrong as you have two 'aye' sounds in a row unless you pronounce your 'h' as 'haytch'. American English would generally expect "an" to be used here, I think. Dialects might disagree. RFC 2616 & RFC 7230 use "an".
We had this fight (almost verbatim) for bis; "an" won. As Martin says, let's be consistent.


Bits seem to be numbered from 1 to N, which is very confusing since almost every software starts at zero. Also it's common to find macros like : #define BIT(N) (1 << (N)) and here that would introduce mistakes since one constantly has to think about shifting bits before using the macro (eg: BIT(3) to check bit called "4" in the spec, corresponding to value 0x8). Since there are not that many places where this happens, this commit aims at fixing them. Note that the hexadecimal values for each of them were already correct and non-ambiguous.


Two changes here, one editorial and one probably-editorial: The endpoint might send a connection or a stream error of HTTP11_REQUIRED, depending on the scope of the requirement. Note that this was non-normative language, so removing the implication that it would always be a connection error simply makes clearer what was already permitted. The server might know as soon as the connection is established that it will want the cert, but want it protected by the handshake. Either endpoint, not just the client, may choose to renegotiate before sending their preface.


As discussed on the mailing list.
:+1:
Make it so that PRIORITY can be sent on a stream in ANY state. i.e., change so that PRIORITY is permitted in the "idle" state.
Discussed in Honolulu; seems reasonable and no objection. Take to list to confirm.