NAME - can you review?
The client hint spec does not seem to specify if there's a maximum lifetime for the origin opt-in preferences. There seem to be spec that the data should be cleared when site data, cookies, cache, etc. are cleared, but barring that should there be some sort of reasonable limit?
I'm new to this process; I'm not sure how to add the "client-hints" label
NAME thoughts? You were the one pushing for an implicit lifetime. Do we want to cap it?
I think that what you should say is that the browser can discard this state, but it should do so only when it drops all other state for the origin (e.g., when clearing cookies). Modeling this as part of origin-bound state like that is far easier to reason about and more reliable for sites.
We already have "Implementers SHOULD support Client Hints opt-in mechanisms and MUST clear persisted opt-in preferences when any one of site data, browsing history, browsing cache, or similar, are cleared." Do we need to also add something around origin-bound state to that?
As Safari is already capping script-set storage lifetime to 7 days (Brave does w/ cookies, plans to do for all storage too), and some other vendors have hinted at the same, I suggest a max lifetime of 7 days. Especially given the possibility that these values can be tracking vectors (discussed in the fingerprinting conversation).
The text above means that browsers that choose to set max lifetime to storage/cookies will MUST do the same for Client Hints. I don't think we need to bake in the specific max age that some UAs chose into an IETF draft.
I hear what you're saying, but the purpose of a standard is not to say "some people will act X and some folks will act Y", its to bring X and Y as close as possible. What is the use case for a lifetime of > 7 days? Like any cache value, its perf utility decreases as life time increases, but the privacy risk stays constant. Put differently, what is the concern w/ a maximum value, to at least partially constrain the privacy risk?
Sounds like the restriction you're talking about is of larger scope than Client Hints, and applies the origin storage in general. I suggest you'd try to enforce those specific values e.g. on session cookies, and Client Hints will follow out of that. At the same time, I was under the impressions that when we , we tied the lifetime of Client-Hints persistence to session cookies, but looks like we did not. I'll submit a PR on that front.


An alternative to - removes HTAB everywhere, replaces with .
Right now we use OWS, and suggests moving from SP to RWS for inner list separation. Should we allow tabs in SH? Error on them? If we want to allow them, 983 makes sense, as it's more consistent. However, we'll need to test for tabs...
What's the reason to allow tabs? Compatibility with current headers? Do actual tab characters show up in the wild that often?
We had them in there because we were reusing OWS, not purposefully. AFAICT they don't appear in the wild much at all. So +1 for .
LGTMThank you for working on this. LGTM.


... and allow token to start with "*".
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. It looks like some headers are failing because AcceptAccess-Control-Allow-Origin`. If we were to use a different character to delimit Byte Sequences, we could include in Token (necessarily as a first character, as well as in the rest, I assume). Worthwhile? If so, what should we use for Byte Sequences?
(via ) already allows , but not as a first character. '%' is short in HPACK and unlikely to trigger funny handling, but maybe it will conflict with pct-encoding to start. '=' has the virtue of being already allowed. It has the drawback of causing byte array parameters to look funny ( for instance). Interestingly, it makes removal of padding easier (base64 padding is silly).
How about ? I don't' think is a good idea; if an implementation enforces padding (which we caution against, but do not prohibit), it's confusing.
Checking with NAME NAME - any issues changing byte sequence delimiters from to ?
(the only conflicting use that comes to mind ATM for is that if someone wants to refer to H2 pseudo-headers like in a field that uses tokens, they'll be out of luck. I think that's OK, because existing fields that take header names as a list-of-tokens don't refer to pseudo-headers, and new fields can be defined as lists of tokens-or-strings.)
is free


(Related to now-closed ) Should implementations be able to store parsed floats in IEEE754 binary64? And if so, should we expect that they round trip between parsing and serialization? It seems like the current limits were designed to support that notion, but there are cases where they do not. (Note, this isn't about being able to serialize arbitrary C++ doubles; the spec sensibly only supports a tiny subset of all possible 64-bit floats. This is about whether should always be true) IEEE 754 guarantees that if a string with no more than 15 digits is converted to a double and then back to a string, it should result in the original string, but that appears to require rounding in some cases; truncation, which the serialization algorithm calls for, can change the string representation. Parsing the string "12345678901234.1" as a float, for instance, results in a binary64 representation with value 0x42a674e79c5fe433, whose exact decimal expansion is 12345678901234.099609375. Following the text of the serialization algorithm, will be 1, and so the number will be serialized as "12345678901234.0" It appears, as an implementer, that the only way to ensure that a float parsed from a valid string can be serialized back to the original string is to store it as a fixed point decimal in two parts, or else use a float with >64 bits of precision for storage.
Would it be adequate to change truncation to rounding in step 9 of Serializing a Float?
That's a can of worms. Which rounding? (nearest-or-even, nearest-or-away from zero, to zero, up, down?)
I know nearest-or-even is the recommended rounding technique. Can we specify that?
Round, nearest-or-even, to fractionaldigitsavail digits? While we're at it, should the spec be stricter about trailing zeros? My implementation currently strips any trailing zeros after the first position past the decimal point (so 1.230000 is serialized as 1.23, but 1.000000 is serialized as 1.0, as is 1.0000001, after rounding/truncation), which passes the test cases in URL The spec just says "at most fractionaldigitsavail digits, but that allows multiple "correct" serializations of a given float.
It's also weird to only require roundtripping for floats that can be represented in binary64. The simplest might solution here might be to just accept that floats are lossy. If an implementer needs precision, use a string. This trade-off seems to work well enough for JSON parsers.
The spec already restricts floats to those which can theoretically be round-tripped into a binary64 and back; this is just about ensuring that that actually happens, if a binary64 is used as the backing store (which is natural for at least C++ and JS implementations)
nearest-or-even SGTM. Stripping trailing zeros as well as leading ones in the integer component sounds good as well. I'll do a PR...
PTAL at the commit. I've added a test for this ("tricky precision float") -- NAME are you using the tests?
/me reads above - yes you are, sorry for the noise.
I do not think we should make stripping trailing zeros decimal digits a strict requirement, the number of decimals presented can be out-of-band metadata about the actual precision involved. For instace a timeinterval serialized as 3.0 vs 3.000 vs. 3.000000 might be used to communicate the precision of the measurements as tenths of seconds / milliseconds / microseconds respectively. But we should probably recommend stripping trailing zero decimal digits for bandwidth reasons, if there is no communicative reason to retain them.
If someone wants to use the precision of measurement that way, it'd need to be available in all implementations to be interoperable -- i.e., we'd have to require implementations to preserve that precision. I'm pretty dubious on that being possible and correctly implemented across the board. E.g., requiring every implementation to parse "0.42000" and make the trailing zeros correctly available.
If we're going to round, we probably need to do it before serializing the integer part, since the rounded fractional part may round up to 1.0, as well.
For floats, I think there are two things that we want from this spec (and please let me know if that's not right): Any string which parses as an float can have that float's value stored in a binary64, and serializing that value should reproduce the original string. (modulo some number of 0's at either end) Any real value (regardless of storage implementation) in the range -(1e14-0.05) to (1e14-0.05), exclusive, should serialize to its closest valid sh-float representation. (rounding ties towards an even least-significant-digit) Is that reasonable?
Discussed in Singapore: will discuss on list, but sense in the room is to have a fixed point. Hum in the room prefers fixed point. (Need to still determine number of decimals; q-value uses 3).
Specifically pinging NAME NAME NAME for thoughts re: moving float to fixed-point (straw-man: three digits). This seemed to have strong support in the room, but wanted to make sure you're comfortable with it.
Would fixed point be materially different that what is currently specced? Currently, the spec implies a fixed-point with 6 digits of precision, and a maximum of 15 total digits, which (not at all coincidentally) is the same range that is guaranteed to round trip through an IEEE-754 binary64 representation, which is useful for actual implementations. Edit: I see the three-digit difference now; would the integer portion be restricted to 12 digits in that case?
Yes.
I don't have a strong opinion on switching to 12+3 fixed; I think it would cover all of the use cases that I can currently imagine (and I'm trying hard to discount any sunk costs from implementing the previous draft :stuckouttongue:) If implementation complexity (or perceived complexity) factors in to the decision at all, Chrome's current sh-float serializer, which passes the public test suite, is
If people think it's useful to have a fixed-point number, and can settle on the optimal number of digits for most of their use-cases, then
The (only!) two "real" reason we have float/decimal in the first place is values and subsecond resolution time-{intervals,stamps}, and the one "unreal" reason is that JSON offered that. I think has three decimals, either by norm or convention. Time-intervals such as "process-time for this request" are often sub-millisecond, and that has by and large been the argument for "at least six decimals". Time-intervals do not convincingly overcome Gettys 1st rule[1] or Phil Karltons rule[2]. so 12.3 would be fine with me. [1] Do not add new functionality unless an implementor cannot complete a real application without it. [2] The only thing worse than generalizing from one example is generalizing from no examples at all.
These days at least, it's by specification. It's a number in the range 0.000 to 1.000, and all algorithms I know of that use it would be just as well served by an integer from 0 to 1000. So the only reason to include the dot is if we want to backport existing headers as-is. Not backporting existing headers was a justification for some decisions earlier on, so if that's been reversed, should we revisit some of those other decisions?
Although thinking more about it, most of the earlier decisions are sort of OBE, so it's maybe not such a big deal.
PTAL


Missed in
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. It looks like some headers are failing because AcceptAccess-Control-Allow-Origin`. If we were to use a different character to delimit Byte Sequences, we could include in Token (necessarily as a first character, as well as in the rest, I assume). Worthwhile? If so, what should we use for Byte Sequences?
(via ) already allows , but not as a first character. '%' is short in HPACK and unlikely to trigger funny handling, but maybe it will conflict with pct-encoding to start. '=' has the virtue of being already allowed. It has the drawback of causing byte array parameters to look funny ( for instance). Interestingly, it makes removal of padding easier (base64 padding is silly).
How about ? I don't' think is a good idea; if an implementation enforces padding (which we caution against, but do not prohibit), it's confusing.
Checking with NAME NAME - any issues changing byte sequence delimiters from to ?
(the only conflicting use that comes to mind ATM for is that if someone wants to refer to H2 pseudo-headers like in a field that uses tokens, they'll be out of luck. I think that's OK, because existing fields that take header names as a list-of-tokens don't refer to pseudo-headers, and new fields can be defined as lists of tokens-or-strings.)
is free


Explicitly disallow thirteen digits before the dot.
NAME I think this is the right way to validate the number of digits in a decimal.


This patch replaces with , and corrects inadvertant usage of non-example domains in the hopes of avoiding confusion. Closes httpwg/http-extensions.
NAME mind taking a look?
Landing this. NAME if you object, let me know.
There are still com TLD remaining: and
is real domain. (currently not owned) seems better to use example domain in rfc.
Should we use the .example TLD or stay with URL It's easier to contextualize with .example, in this case webmail.example and projects.example.
SGTM in projects.example, webmail.example etc also URL are fine too.


This patch alters the cookie parsing algorithm to treat as creating a cookie with an empty name and a value of "token". It also rejects cookies with neither names nor values (e.g. and . Tests in web-platform-tests/wpt. Closes httpwg/http-extensions.
NAME Ping?
Landing this based on the discussion in . NAME If the wording needs more cleanup, I'd appreciate feedback!
The cookie-pair ABNF rule still requires presence of . Is it intentional?
As a part of discussion in whatwg/html I've made a of the modern browsers compatibility with the RFC 6265. It appears that all browsers nowadays allows cookies without key or (in case of Safari) without value, thus making it de facto standard. However, it's debatable how cookies like should be treated: as the cookie without value or without key. Thinking of cookie jar as some kind of key/value store makes it more logical to treat such cookie as cookies without value, but on the other hand, currently most implementers treats them as the cookies with the special empty key.
Discussed at Berlin IETF; Julian points out that we should check previous discussion in cookie WG. Martin points out that we should talk to the implementation that has divergent behaviour.
Context: around URL, ticket in URL
For clarity, are we saying Chrome, Firefox, and Edge treat such a cookie as key: "" and value "foo", and Safari treats it like key: "foo" and value: ""?
Per the table linked in OP Safari serializes input as whereas others serialize as . Firefox attempted to be more strict on cookie setting lacking and found it broke a router: URL
URL is the relevant test, in particular the following subtests: sends . Chromium stores a cookie with an empty name and value of , serialized as . Firefox does the same. Safari drops the cookie entirely. Given Firefox's experience with and related bugs above, this seems like it might be baked into some user-visible sites that are unlikely to update. I'd suggest that we change this test expectation to , and update the spec accordingly. sends , , and . Chromium stores three cookies: , , and , serialized as . Firefox and Safari store two cookies: and , serialized as . The latter is clearly correct and matches the spec; filed URL to change Chromium's behavior. sends , , and . Chromium stores three cookies: , , and , serialized as . Firefox does the same. Safari stores two cookies: and , serialized as . If we change 0004 above, then we'd update this test as well to match Chromium and Firefox. sends , , and . Chromium stores three cookies: , , and , serialized as . Firefox does the same. Safari also stores the same three cookies, but serializes them as . I think this ordering problem is similarly represented in and , and is something that can be dealt with separately from this issue. sends and . Chromium stores , and then overwrites it with . Firefox stores and ignores the empty cookie. Safari ignores both (as per 0004 and 0021 above). I think Firefox's behavior is most correct here as a logical consequence of the spec change to fix 0004, and I believe Chromium will match it once the bug filed for 0020 above is addressed. sends and . Chromium stores , and then overwrites it with . Firefox does the same. Safari ignores both. If we change 0004 as above, then Firefox and Chromium's behavior will match the spec, and the test should be updated. I'll put up a PR against the spec if folks are on board with the suggestions above.
Putting together a , I ran into more excitement: 0024 (, ), 0025 (, ), and 0026 (, ) show that Firefox overwrites with , and serializes it as "". 0028 would show the same, but it's incorrect in the WPT repository; it should contain a tab character, and the expectations are simply wrong (also in the original repo). I'd suggest that this behavior doesn't make much sense, and that it would be better for browsers to align on requiring cookies to have either a name or a value, and to ignore headers that parse with empty names and empty values. That would change the expectations for these four tests to expect a serialization of "Cookie: foo". WDYT, NAME NAME
For clarity: https://chromium-URL shows the test expectations I'd suggest we end up with.
Tl;dr: I think changing the spec to match current implementations for to produce (i.e. 0004 case) makes sense. I think disallowing (0020 case) and (0023 case) would make sense too, but that might break things. In the 0004 case: We've been parsing as an empty name with a non-empty value for a long time, afaict. Since Firefox seems to do the same thing, I think we should definitely update the spec to match the implementations (i.e. for a Set-Cookie line without a but with a valid token, treat the token as the value and, for cookies without a name, don't put a when serializing). In the 0020 () and 0023 (empty ) cases: Judging by Chrome metrics for Cookie.HeaderLength, there is definitely non-zero usage of empty cookies, so I'm concerned that rejecting empty cookies would break things... (In the 0020 case, one could also argue that explicitly sending a Set-Cookie header of indicates intent to create a cookie, even if it is empty.) I agree it's a bit silly to allow cookies with both empty name and empty value, though. I think that's a reasonable change to make to the spec, and maybe we don't care about potentially breaking things.
Thanks, NAME I agree with you for the 0004 case. NAME would Apple be willing to change CFNetwork's behavior to match the suggestions above? For 0020 and 0023: Looking at the stable channel on for the 28 days ending on Dec 31st, 0.0025% of headers were empty, spread over 0.12% of users. This is a pretty small number in total, and a pretty small number per user; certainly within the range of changes we've been successful with in the past. I wouldn't be surprised if it broke something (because everything we do with cookies breaks something!), but I would be surprised if it broke anything critical enough to retain the behavior. It would signify an intent to create a cookie without a name and without a value. What would that intent mean? I'd like it to mean "Don't create a cookie." :)
I'm okay with your proposed changes. cc NAME NAME NAME
URL should cover the proposed changes above. (I kinda want to rewrite the whole parsing algorithm in terms of Infra to be a bit more precise, but that's a task for another patch. :) )
I’ve pinged the relevant folks to take a look at this thread. Like me, many won’t be back until Monday.
Not sure if it's the same thing, but I've seen facebook send an empty header frequently. For example visiting URL loads a 1 pixel gif with the following URL: URL (replacing XXXX with your unique tracking reference) with the following response headers (note the blank header, third from the bottom): This then gets set in the Chrome Cookie jar with the following: ! I can't seem to find this showing in Firefox's cookie jar (even when turning off the default Enhance Tracking Protection) nor in Safari. Anyway, I'm sure a good few of us wouldn't care if this "cookie" died a death, or if Chrome changed to ignore this "cookie", and not even sure if it DOES anything (it doesn't seem to be sent in follow up HTTP requests, but that's not to say it's not looked at by some local JavaScript). However, given the prevalence of Facebook tracking I'm really surprised these sorts of cookies are only seen by 0.12% of users so thought I'd comment to note this in case those estimates are not accurate? Perhaps the stats are not picking up these cases? I've seen this on many sites and only picked the Guardian as a well-known example and guessed first time it would be on there (news sites are good ones to pick when looking for tracking pixel examples!). URL sets the same if you prefer something US based and URL sets the same (but not on the main domain) for those of you in that side of the world.
The number of 0-byte Cookie headers is only a lower bound on how many no-name-no-value cookies are in use. If such a cookie were sent along with some other cookies, it would not be logged as a 0-byte header. I don't think we have any metrics on per-cookie length, just the total length of the Cookie header. So it might be worth collecting more data? Also, that metric doesn't include cookies accessed via .
Regarding NAME comments on Facebook; I pinged someone there who will forward this to the appropriate team. It sounds like a bug to me, and not something that I think should stop us from making a decision here on the underlying question of whether an empty cookie is a thing we should support. NAME I read your comments above as generally approving of the change suggested in URL, but cautious about how to ship it in Chrome? That feels like an important part of an eventual "Intent to Ship", rather than a discussion of what we'd like the spec to say. If we decide to accept the suggestions above, then I'm pretty confident that we can work out how and when to ship it (especially given that there's no real agreement among browsers today, so the status quo is already trifurcated as per URL above). Indeed! You're exactly right, and I should have been more clear. The 0.0025% is the number of requests (not page views, FWIW) for which we'd shift from sending an empty header to sending no header at all. That seems to me to be a change more likely to invalidate an application's expectations than shifting from to . I think this is the easier case, actually, as the serialization of an empty cookie is indistinguishable from a empty cookie jar.
Thanks for sending on NAME . I more meant it as a concern that the 0.12% of users figure sounds way too low to me given Facebooks prevalence. Note you don’t need to be a Facebook user or visit a Facebook site to get this cookie - just a site that uses Facebook advertising pixels (of which there are many!). So I still have that concern that this figure sounds way too low to me. Which then begs the question as to whether there are more cases than we think there are? Now I agree that particular example sounds like a bug and I doubt this empty cookie is being used and so don’t think blocking it off will cause a breakage, but still, I’m uneasy that the stats seem wrong and that we are using this (potentially incorrect) stat to justify the low chance of breakage with this change. There might be other cookies on other sites that will cause breakage. To be clear, I don’t actually think it will cause a lot of breakage, but would rather than was based on a stat we are comfortable to stand behind than one that we have potential concerns with. Is there any way to double check that 0.12% stat given this example? Maybe a lot less users than I think are getting this cookie but given I’ve spotted it on 3 major news paper sites in 3 distinct countries, without having to look too far for these examples, makes me suspect that is not the case. says Facebook assets are being used on 2.38% of the most used 5.7 million sites and I’d guess they all come with some cookies for free. And that stat treats each of those 5.7 million sites equally when actual usage will be heavily skewed to the sites at the top end than the tail so usage will likely be more than that as top end sites are more likely to use Facebook advertising in my opinion. And again, I’m not concerned with this Facebook example - but more that it seems to suggest the 0.12% stat feels wrong. Or maybe it’s not being included since this empty cookie doesn’t seem to be sent in follow up requests, and that’s what that stat is measuring? If that’s the reason, and we’re comfortable with that explanation and the risks that entails (I am for what it’s worth), then that’s fine, but thought it worth asking the question.
As NAME notes above, we don't have statistics on cookie size generally; just aggregate numbers on header length. The "0.12% of users" statistic is the set of users who have ever sent an empty header (e.g. the only cookie they have for a given request is empty). If nameless/valueless cookies are set for other sites, they'll be serialized as , which we don't track specifically. I noted above that I'm less concerned about this case than I am about the "We used to get a header, but now we don't get anything at all!" case, but I'm honestly not terribly concerned about either given the existing diversity in the way browsers handle .
OK makes sense. Thanks for answering.
Yes, that's right.
The CFNetwork team approves of the change and is tracking the work in rdar://problem/58358759.
Given that, I'd suggest that we land something like URL along with the tests from https://chromium-URL Thanks! If you'd like to improve compatibility with IE and Firefox, you might consider representing these as nameless cookies instead of valueless cookie. You can observe the difference via test 0027: Set-Cookie: foo Set-Cookie: bar


NAME thanks for the review, see latest commit. is talking about the abstract model for dictionaries, so they are required to be unique. I've removed "required to be" so that people don't misread this.
allows a sender to generate multiple header fields with the same name, if the field is defined as a comma-separated list [i.e., #(values)], and that such duplicates are semantically equivalent to them concatenated into a single header field. I think that this property has been useful for us, when annotating header fields. Can we allow such duplicates for Structured Headers too, when a list or a dictionary is being used? Note that we have merged based on the assumption that it is okay to require the consumer of SH header fields to have the knowledge on what the top type is.
That's always been the intent; are you saying that we should have text specifically enabling this for serialisation of dictionaries and lists?
Good to know that that has been the intent. Yes, I think we should clarify that explicitly for dictionaries and lists, because RFC 7230 can be interpreted to allow duplicates only for those using notation (which we do not use in SH). Also, it might be a good idea to revisit the rule for duplicate dictionary values, as I'd assume that people would try to append a header field without checking the values that already exist. IMO, the rule should be that the dictionary element that appears later overwrites the one that precedes.
PTAL
NAME Thank you! cb76bf1 looks good to me. Is your intention to retain the forbidding of duplicate dictionary values, even when the dictionary members are split into different header fields? For example, in the hypothetical world where cache-control is sent using SH, all the cache-control directives in the following example would be considered invalid and ignored. I am not strongly opposed to that, though my weak preference goes to requiring decoders to use the dictionary member that appears later when there is a collision.
NAME the problem is that ignoring duplicates can cause security issues for some headers (the headers that WebAppSec in the W3C are particularly sensitive about this). The only way to address it would be to add a flag to the API to control what to do with dups -- but that adds complexity (more to specifications than to implementations, but still). I'm not crazy about that; what do others think?
NAME Thank you for the explanation. But I wonder if it is actually the case that what those specifications forbid is having duplicate header fields, rather than forbidding duplicate dictionary members (or maybe both). By quickly searching on URL, I was able to find the prohibition on having duplicate header fields, but could not find a rule that forbids having duplicate policy tokens. Assuming that at least such specifications forbid having duplicate header fields, and based on the fact that SH draft does not forbid that (when a list or dictionary is used), I think there is no reason for the SH draft to forbid having duplicate dictionary members.
NAME NAME any comments re: the above? Specifically, if SH swallowed duplicate dictionary values rather than raising an error, would that be a concern from a security standpoint?
Given a header like , it seems like we have a few options: Fail parsing. Return . Return . Return . I think I can come up with arguments for any of these options, though I'd find 4 a bit surprising as a spec author, insofar as I'd have to deal with unexpected lists for all my dictionary values. of URL skips duplicate CSP directives. That is, it picks 2 out of the list above, choosing to retain only the first value for a given name. I do wonder whether that was the right decision, but it is consistent across browsers and provides developers with predictable behavior. We throw a warning into the console in Chrome for this case, and that's probably Good Enough.
This sounds like a bad API for working with structured header values. I'd hope that eventually we offer better APIs for operating on (what Fetch calls) header lists. I think historically there were some arguments for always using first or last based on likelihood of where header injection would happen. But I'm not sure how sound any of that rationale was. I don't think a client can reasonably protect against it. Therefore, what's most important is that the result is unambiguous and that it doesn't matter how you "spell" multiple values (commas or multiple fields or a combination) in the traditional header syntax.
Anyone have preferences between Mike's options 2 and 3?
NAME I think option 3 is preferable, because that would allow server administrators to override parameters by appending header fields. I agree that NAME that it's a hack, though sadly, I do not think we can get rid of such practice through API design on the server side. People are so used to dealing with each line of header fields than working through a API that deals with a set of header fields as a whole.
There are CDNs that offer JS or Wasm APIs effectively using et al. Once structured header values are more baked and have dedicated on-the-wire support I'd definitely like to add first-class support to objects.
I weakly prefer "first one wins" (2). It's only an aesthetic preference, however: I don't have any principled reason to pick 2 over 3 or vice-versa. I can live with either for the reasons NAME spells out.
If I had pick, I probably agree with NAME reasoning.
PTAL
Thank you for the changes. Looks good to me now. FWIW, I was bit surprised to learn that we do not mention how a duplicate is processed alongside the type definitions in . I checked and now I understand that the formal definition is provided in section 4.


URL was incomplete, leaving a number of inadvertant references to sites, or the TLD. This patch, hopefully, is less incomplete. h/t NAME and NAME for pointing this out.
WDYT, NAME


Allow "." in . Also consistently reorders character lists for key.
I'm getting a high failure rate on parsing (but with a very low number of occurrences; it's not exactly a popular header). The failure seems to occur because of keys like this: Allowing in key would address this, but I'm not sure it's worth the change. Additionally, key currently only allows lowercase alpha; this is mainly to avoid confusion between and , etc. So far this seems to be pretty supportable in cache-control, accept- and elsewhere, with the vast majority of headers seeming to choose the lowercase form. However, it does cause issues in a couple of cases: In , the parameter isn't compatible, leading to a high failure rate for that header In cookies, this makes a number of things incompatible, but it's not clear that we can treat them as a direct mapping anyway.
I have no opinion about dots. As to case, though; I think the options are: say lower-case only – the current option we should probably instruct individual headers' specifications to define how to get into/out of SH, which is harder for extant specs open it up to anycase and be case-sensitive this means that parses to and if someone wants to collapse / they have to do it after the fact open it up to anycase and be case-insensitive still requires instructions for individual headers' specs to define how to get out of SH Incidentally we don't say anything about case for tokens, not that it matters as far as SH is concerned (we never have to compare them.) It might not hurt to say something to the effect that "tokens are case-sensitive so you aren't allowed to change them, but an individual specification that uses sh-token may have special rules for comparing tokens that only differ in case".
WRT lower-case -- I think your analysis is correct; my inclination is to either stay lc only, or to force to LC when parsing textual headers (much like H2 does for field names). WRT instructions for existing headers -- that's out of scope for SH "officially."
Your patch for looks good. Force-lowercasing makes me a bit nervous, because the wire form for h1 will be materially different than what appears in the data model. We'll have to be careful to distinguish between the h1 wire format and the abstract model for keys (which we currently are pretty sloppy about). More seriously, even if we did force-lc, I realise it wouldn't be possible to round-trip things like includeSubDomains, so it probably isn't going to be useful on its own; there will always need to be some application knowledge / mapping. So, I'm inclined to leave casing in keys as-is.
I don't know what you mean by "force-lowercasing". Is that different from leaving it as-is?
i.e., forcing LC when parsing textual headers, as per above.
Oh, do you mean converting "FooBar" to "foobar" as part of some algorithm? Right, yeah, no, I don't like the idea of coercing data into the model if it can't be round-tripped back out. If an individual header field's spec supports a different data model (e.g. strings), then it's up to that header field's spec to define how to convert their string to an sh-key, and back again. I.e. don't do anything in SH, and punt it to RFC6797bis (or draft-mnot-bsh).
Agreed. Could you make the change into a PR?
It is.


NAME Fetch Metadata will add a bunch of headers that are supposedly structured headers, but given their simplicity can be compared using equality on servers. If servers did that it would likely prevent adding parameters in the future however or making other supposedly-compatible extensions. Should we accept this for headers clients transmit to servers or should we do something akin to TLS's GREASE?
In general, greasing HTTP headers is interesting -- although I'm a little wary, given the extent of the grease-related discussions we've had in QUIC. As a baseline -- I think that the goal of grease should be to prevent casually incomplete implementation (e.g., someone using regex or splitting on commas and extracting the raw values). It can never assure complete and correct implementation overall. I think the interesting thing to grease in SH is parameters, since that's a primary extensibility mechanism, and is (now) uniform across values. Ideally, grease parameters would contain values that frustrate the casual approaches above; e.g., strings with commas in them. A couple of options I can see; We could advise / require sending implementations to generate extra parameters sporadically (not super-often, so as to limit bandwidth consumption, but not so rarely that it creates debugging nightmares). To be recognisable as grease to the receiving application, their names would have to have some convention. We could advise / require headers using SH to define their own greasing mechanisms when appropriate. I suspect that truly automatic greasing might increase friction against adoption of SH, since some people's reaction will be "what is this thing doing to my header?!?". Invoking in on a header-by-header basis (perhaps by adding an appendix with guidance) might help.
I think the main benefit is derived from clients doing this so the main party to convince would be the user agents (who are already generally on board with SH).
So, should anything in the spec change? At this point the most I can see is adding something like:
I guess I'm mainly interested if implementations are willing to do this uniformly. NAME NAME NAME
I think NAME suggestion is reasonable to recommend (though it risks a quagmire when we attempt to ship a new header defining a quotient of quietly quixotic quilting), but I'll defer to NAME or NAME to weigh in from Chromium's networking team's broader perspective for headers generally.
I am, unsurprisingly, in favor of GREASEing things on general principle. :-) Although the network stack only produces a few core headers while others, like Fetch metadata, mostly come from outside anyway. GREASE would want to be applied where the header is produced, most likely. (Well, we could implement some generic post-processing scheme, but then all the headers would need compatible mechanisms and we'd need to know which they are.)
I also think this sounds reasonable. One problem is reproducibility - if we modify a header 1 in 100 times, then a developer would have trouble reproducing the issue. If we apply the same modification per browser session, it would become a new cross-site tracking vector, unless we also took NIK into account when deciding whether/how to modify the header.
For TLS, we've never fed state in as input to GREASE, which is the safest option privacy-wise. But you're right that you then need to worry about reproducibility. To that end, if we GREASE some TLS codepoint, we always GREASE it, with the randomness coming in only in the particular values, as a low-pass discouragement against hardcoding values. But if the implementation is intolerant to only values that start with 5, it is indeed unlikely to be reproducible enough.
If we always grease something, couldn't that result in problems around servers always expecting an extra value?
It could, but that'd be a really weird bug for servers to have, whereas not properly skipping over unknown keys is much easier to do on accident. (Maybe I just parse the whole thing with a giant regex and make assumptions about the order.)
I don't think it's that weird - if I want to test parsing something with a variable number of fields, I'd test on 0, 1, 2, and possible something much greater than 2 (like 3!). I think it's very easy to mess up on any one of those cases, and get the others right. Could assume an initiate search for a delimiter will always succeed, or use a regexp with "+" instead of "*", etc.
Beyond the text above, we could add a character to those allowed to start keys, and reserve it for greasing. E.g., . I think I'd do that purely at the parse/serialise layer, so a grease value never appears in the actual data model. Is that attractive?
NAME I'm not sure if that is beneficial. I think our goal is to let every HTTP extension that uses a SH list or a SH dictionary to be extensible. To achieve that, greasing has to carry a value that can be recognized by the extensions. Assuming that that would happen for a fair number of HTTP extensions, the SH codec shared among those HTTP extensions would encode / decode arbitrary number of undefined values. I think that would be sufficient.
Maybe you can use "X-". One of the reasons we avoided reserving a range of values was to make grease values a little harder to separate from genuine values. The point being that they need to be seen by the code that processes them without filtering. From that, I take two conclusions: A prefix won't work as it is too easy to distinguish. Having a generic processor strip grease values would mean that the code we want inoculated would never get the opportunity to benefit from our attempts at inoculation. Therefore, I suggest that we find a subset of valid strings that we will reserve. Maybe that is all strings of 8 characters or more that fit a certain pattern. We don't have any established pattern for strings, but anything should do as long as new values can be generated cheaply and it doesn't take too much of the available space.
I'm going to disagree on pretty much all points, NAME The target here is assuring that a consuming implementation isn't grepping, string-mangling, etc. If they're aware of it being a SH and actively NOT using a SH parser, there's not much we can do, reasonably. To that end, is just as effective as, and hiding it from the application is a benefit, because we don't pollute their data model, we don't make them think about it, and once it's parsed into the data model, they CAN'T interfere in the ways we're trying to prevent.
NAME what does "recognised by the extensions" mean? Are you saying that a recipient has to be aware of grease's presence AFTER parsing to serve the purpose?
NAME Let me use an example. Consider the case of the Priority header field. The header would be generated, encoded, decoded, and used in the following manner: We would definitely want to grease (4), so that it would be possible to define new keys. Therefore, there is no benefit in letting (3) absorb the keys used for greasing. We should prohibit (3) doing such thing. That is my argument. Who adds the greasing keys is debatable. That could happen purely in (1) or in cooperation between (1) and (2). Or we could define a common vocabulary, so that it could be done purely in (2). I do not have a strong opinion here.
OK, so you want to protect against an additional case -- someone using an SH parser (rather than grep, etc.) but raising an error if any parameters are present. Personally, I'm not as concerned about this case; someone is going to have to go out of their way to write that code. What I'm concerned about is lazy programmers doing some quick string hacks.
While I might agree that we might not need to be concerned about this case, I wonder if there would be a benefit in requiring an SH parser (3) to absorb certain keys, assuming that most, if not all of the extensions that use SH dictionary or SH array would allow future extensions. How about saying that "a SH encoder MAY add a greasing entry (i.e. a key that starts from ""), unless the extension using SH forbids that", and that "a SH decoder MUST NOT absorb the greasing entries"? That would give us end-to-end greasing by default with least hassle.
I'm not against that. The only thing bothering me is that "unless the extension using SH forbids that" means that APIs will need another bump on them...
Yeah we can remove "unless", if the key names used for greasing is not going to be a valid key name in terms of the spec. E.g., grease keys added by SH encoder starts with "", while applications are forbidden from using a key starting from underscores.
That's what I was suggesting up-thread :)
Yeah you stated "do that purely at the parse/serialise layer," and my complaint was absorbing the values in the parsing logic. Sorry I wasn't clear about what I am complaining about.
SGTM - anyone else have thoughts?
Looking at how to specify this, having grease parameters appear in the data model don't make me very happy; we either have to make them valid but tell people not to use them (which is likely to be abused), or we have to make them invalid but say they might appear anyway, just to be ignored, which is weird. Either way, it's confusing to write/read the spec, and I suspect some people will use the grease prefix for some purpose because it works (most of the time). Stepping back, I think the scenario we're talking about is the possibility that a consumer of a specific SH header (i.e., post-parse) is likely to erroneously reject headers that has unrecognised parameters, even when the header allows them (keeping in mind that some header definitions might disallow them, even though that's not a great extensibility strategy). To me, that's not the purpose of greasing, because there are lots of other possible erroneous constraints that a consumer (rather than an SH implementation) might put on a header, and we don't try to prevent that. If someone wants to purposefully reject something in a way that's contrary to the header's spec, they're going to do it. Rather, greasing (to me) is about making sure that someone who's ignorant of the spec / too lazy to read it doesn't just do the "natural" thing and e.g., feed an integer into a parser, or split a string on commas. So, to me adding parameters / dict members and "disappearing them" at parse is adequate. I'm not against addressing the case NAME points out, but I don't want to complicate things to achieve it. Do other folks on this thread have any leaning in one direction or the other?
I wouldn't say that that is mutually exclusive with greasing each user (e.g., priority). Obviously it is true that the SH spec would be simpler if we grease only SH parser. Though, the flip side of that would be that each user (e.g., priority) will have its own greasing scheme. That's the reason why I tend to think that the total cost might become smaller if we recommend: SH serializers add members using keys that users would never generate require them to be passed through by the SH parser so that each user would be required to ignore members using unknown keys PS. Besides, assuming that we want grease the SH parser, I think it might be a good idea to allow ordinary character to use the escaped encoding (e.g., \x4A), so that parsers incapable of unescaping those characters can be detected at an earlier point.
I'm not at all sure that header authors are going to find greasing desirable across the board; it's very intrusive into the application (unlike other forms of greasing). And, as I said above, it's not at all clear that all header authors are going to be happy to ignore unrecognised keys. I'd rather be conservative here -- we haven't done this kind of greasing before (into the application space, rather than just within a protocol), and we're not sure how it will work out (especially considering the potential performance overhead; for small header values, it might seriously inflate their size, even if just in the dynamic table). But, again, folks other than us have an opinion, it'd be good to hear it.
I've said my part, you disagreed, but I haven't really changed my mind. If we're building something with must-ignore-unknown semantics, and if we do grease (and we don't have to), then it needs to reach as far as possible.
SH is only a data model and a serialisation, it can't say anything about semantics of values (including must-ignore or must-not). I mean, you could introduce weird sentinel values, but that seems like a bad kind of kluge. (And adding to my lazy regexp isn't the intended outcome.) It is up to individual header fields' spec authors to define the semantics of values in the context of that header field, including which SH types are allowed, what parameter names are ok, what to do about unrecognised ones, etc. That includes greasing their header field_ for extensibility. Maybe if we had a way of discussing a schema – for example a formal grammar an application could pass to the parser to allow it to fail on valid-but-disallowed data – we could talk about greasing there. But in the data model itself, it doesn't make much sense.
NAME that's the thing; we're not enforcing must-ignore-unknown, merely suggesting it as a default. Whether that's the semantic or not is up to individual header definitions. I'll do a PR shortly based upon the text above.
Late to the party... I've been doing some thinking on GREASE and request headers in the last few days as part of URL As part of the feedback that we received on that, there are . If the GREASEd request headers are used for content adaptation, each new GREASE variant may create another copy in the cache, at least if is involved. Not saying that this means we should avoid GREASEing - just saying that it's a consideration that will apply to UA Client Hints, and is probably applicable in the general case as well.
I'm going to merge the PR and (since this is our last open issue) cut a new I-D.


Round to three decimal places first, then check the domain, then do all the actual serialising. It's potentially not very l13n-friendly; feel free to change "decimal point" or "to the left" etc., if something is more appropriate.
... still isn't right, as Kari noticed. E.g., a value of won't get rounded to .
Step 1 of all serialisation algorithms could be related to sanitising/casting/failing-on noncanonical data. Turn your random number into a Decimal, including rounding to three digits. Fail if it's or no worries from here on Actually, Key, Integer, String, Token, Byte Sequence, and Boolean already do this, so Decimal is the only scalar type that doesn't.
With the current algorithm, if it is allowed as input, -0.0004 will get serialized as , rather than . corrects that as well.


Small editorial fix. I'm also not comfortable with "a integer", maybe remove "a"? Anyway that's a nitpick.
Thanks NAME
LGTM


NAME I'm just going to land this (as it's trivial), and roll an -05 today.
This should use a named section reference, no? Otherwise it can break again when section numbers change.
In URL under sub heading # 1 there is a paragraph, "Attackers can still pop up new windows or trigger...", which references section 2.1 for more information on that topic. However section 2.1 is "Conformance Criteria" so that doesn't seem the intended target.
Thanks!


In URL under sub heading # 1 there is a paragraph, "Attackers can still pop up new windows or trigger...", which references section 2.1 for more information on that topic. However section 2.1 is "Conformance Criteria" so that doesn't seem the intended target.
Thanks!


The term COMMA is not defined anywhere in this document, or in any of the documents it imports. But we can just use the literal instead.
Thanks.
The structured headers draft imports and uses a number of productions from RFC 5234 for typographically awkward characters and character classes (, , etc), but there is no definition of provided anywhere. Similar to the way that , , , , and are used without special treatment, can probably be replaced with wherever it occurs.


When merging the different PRs, the "Cost of adding hints" section was misplaced and it wound up in the middle of the security section. This fixes that (and bumps the revision number).


We still had usage of the term override, so while thinking how to address that I took the opportunity to state explicitly that no guidance is provided for how an intermediary might merge.
LGTM!


cc: NAME
Thank you for the fix.
RFC8586 is very clear about other uses of : The current priority draft uses it to detect whether there upstream intermediaries, not loop detection. This should be removed.


The intent here is to say that your requirements for trusting a secondary certificate should be at least as strict as for trusting additional names in the primary certificate.
Add text noting the DNS check / not-check guidance in RFCs 7540 and 8336, respectively. Explicitly side-step the issue by saying that if you would do a DNS lookup for a hostname in the primary cert, you MUST do the DNS check for a hostname in a secondary cert as well; if you would omit the DNS lookup for a hostname in the primary cert, you MAY omit the DNS check for a hostname in the secondary cert as well.


I believe that NAME comment on that issue is already covered by the following section on Denial of Service.
If a malicious server claims support for a variety of common hostnames for which it doesn't actually possess certificates, browser clients with a long-lived connection to the attacker will probe for certificates when the user attempts to access those sites. This allows the server to monitor user behavior during the lifetime of the connection, even without valid certificates. One obvious strategy is to probe everything "interesting" ASAP after the ORIGIN frame, but that obviously leaks what the client considers interesting, which is its own privacy leak. Note that a DNS lookup of claimed hostnames prior to requesting the cert prevents this attack. Should probably recommend that clients which omit the DNS lookup never solicit secondary server certificates, but probably don't need to mandate anything.
In addition to monitoring user behavior, depending on client behavior (do you race two connections? fallback on error?), the malicious server could also deny access to other hostname or degrade performance.


We landed a change to remove the semantic meanings of urgency levels but neglected to remove a considerations section that discussed this. This PR moves some of the still relevant text out of the section and nukes the stuff no longer needed.
oops, this will need a rebase...


Address some build warnings and fix typos.
and
Thank you for the fix. Merged.
Changes in structured headers means that boolean parameter values are reduced to their parameter name: -- URL
Q: should this be labeled ?
No, this issue addresses the minor editorial problem that needs fixing in the priorities spec e.g. URL just needs some tweaks to be compliant with structured headers.
The lowercase headings in the document imply that they represent field or parameter names, but these are concepts. For instance "incremental" doesn't appear on the wire, "i" does.


This change to the key syntax allows dictionaries and parameters to use "" as a starting character for names, allowing keys like value mygoditsfullofstars*
LGTM. Do you want to add the change note, or shall I do that after merging?
BTW - would take a PR with an example key that looks like the last one above :)
In URL, NAME asks for as a dictionary member name. I think this just means adding it to valid start characters in key.


NAME I was tired of the warnings of line too long, so I've reflowed a lot of the examples and also most of the text while I was at it. The Python code example was tricky, please pay attention to that as I may have mangled it.
LGTM


Ping NAME
LGTM from here, thanks!
Julian asked in e-mail why we can't have a dictionary with a default True value that is parameterised:
I think we could replace: With:
NAME NAME NAME thoughts?
Example-Field: ;param=on-default-boolean Is this a dictionary? What is the key here? (I see that the value is supposed to be implicit true, but I'm not grokking the implied syntax) If I ignore that (assuming I've misinterpreted something), I like the idea of allowing implicit True. The serialization algorithm needs a bit more surgery to support this as the canonical form, probably replacing: with something like: (unless we also modify Serializing an Item to optionally omit True values, but we can't just do that unconditionally, or else a simple Item header would be empty if True.) This is the same issue as URL, I think -- back in December you thought that it would take more drastic changes. If this is everything that it needs, though, it seems reasonable. None of the canonical tests break with this (except for a couple of serialization tests, which just need to be updated), and I don't see any obvious cases that would be parsed incorrectly.
Sorry, that was unrelated, accidentally copied from the email. Ignore. I'll work up a PR and see how it looks.
Awesome. Now, how about also collapsing the "false" value a bit. So instead of having a=?0 just say !a ?
IMHO explicit is better than implicit: I am not sure that is a good choice. I am not even sure that defaulting is a good choice.
Tantalizingly close to making Dictionary a superset of List. I can't think of anything that would break.


LGTM! thx
Some of this is very nit-picky; feel free to do what you like with it... ^ There's something weird going on with tense in this sentence. "Such techniques are expensive... are not portable... and make it hard..." The third doesn't fit with the first two. "Client Hints mitigate the performance concerns..." probably just "Client Hints mitigate performance concerns..." Likewise for "the privacy concerns" below. "This document defines the Client Hints infrastructure, a framework that enables servers to opt-in to specific proactive content negotiation features, which will enable them to adapt their content accordingly." --> "This document defines Client Hints, a framework that enables servers to opt-in to specific proactive content negotiation features, adapting their content accordingly." as a normative reference probably isn't going to fly, given its status. Why is it normative? maybe instead: Be aware that HTTP doesn't require presence of when proactive conneg is in use; if the response is truly uncacheable, it isn't necessary. maybe instead: instead: BTW, nothing is said about precedence between the two different mechanisms; separate issue? The reference to 6454 is spurious, and it's pretty indirect. Perhaps: It's kind of weird to have this list just appear. Perhaps turn these into prose? Put "For example" above the example to introduce it. Limits CH to just "optimisation." Probably should just be:
Thanks for reviewing! :) PR underway The here is conditional on cacheability. Is that OK? We're now considering removing http-equiv support for this: URL Maybe it's best to simply remove that reference here?
Ah, I missed that, sorry. WRT http-equiv; that might be best, then.


A few editorial tweaks to improve readability, including some x-refs to the Header / frames. The most contentious change is at L262, the sentence read a bit weird so I juggled it around to make the intent (as I understand it) clearer.
Thank you for the changes. L262 reads better now. Thank you.


Moves Digest Algorithms down
I verified the formatting here URL
This looks good but note the similar comment I made elsewhere about the trailing spaces after colons e.g. we need or else the formatting seems to get screwed up


Reorder Digest section. Cumulative PR of: NAME this patch ends the reordering and achieves: Digest header defined at §3 (pag. 7) Non-normative section moved in Annex Replaces
NAME WDYT about this roadmap? I'd address each one in a separate PR. If you agree, I can cherry-pick the first ones from your PR so you won't have to do it twice :) Digest Headers to be reordered: [x] move the "deprecated algorithms" security consideration directly in {{digest-agorithms}} [x] merge the {{digest-algorithm-encoding-examples}} in its parent section {{representation-digest}} [x] move Digest Header and Want-Digest header outside Header Field Specifications [x] move {{representation-digest}} under {{digest-header}} [x] move {{digest-algorithms}} down [x] move {{resource-representation}} examples to Annex B [x] ensure people start reading from {{representation-digest}} [x] refactor Digest to be more direct Optional: [ ] integrate examples from into {{resource representation}}
That sounds like a good plan, thanks. Please action it and I'll review promptly. This is a set of editorial changes that I think would add value to the specification readability. My jumbo PR () had some problems, so lets focus on landing the easy-to-agree items and not try to rush everything through before the submission deadline if we are uncomfortable. We can continue working on the thornier editorials even after the submission deadline.
Here's a first bunch of PRs. PTAL :) thanks for all the support!
NAME I'm trying to refactor and I have this proposal: URL we need rewording but just look at the sections ordering and let me know. The next PR to merge is
This section outline looks good. I approved, so let's merge it. What's next?
Now we have and which should end the refactoring. I think that's a reasonable cutout for IETF107 but we are clearly not over :)
All the PRs look good, even the optional one. Thanks for your work on this. Let's get them merged, then take a once-over review to catch any basic errors that might have crept in. Then one of us can cut the release.


Some of this is rewording. There are two new paragraphs talking about extensions: one deals with dictionaries, the other deals with extensions to a SH definition. I also removed the "starts with 'h'" example for greasing. We know that X- lead to all sorts of mess, so choosing a bad example here could be just as bad. I'm happy to split that out or be talked into backing it out, of course.


This is a simple editorial change of the "changes" section, to add the latest PRs.
Landing as this change is not substantive


Non substantive change to improve the list's style, after feedback on URL
Landing, as this is non-substantive


Apparently the removal of one appendix now has moved all remaining appendics into the main section. They need to be moved back.
LGTM! Thanks for catching that :)


"validator" refers to validator fields used in preconditions. The term validator fields seems more faithful to the original cache-validators in RFC3230. URL and URL


Nameless cookies serialize as . Valueless cookies serialize as . No, this isn't what we would have chosen if we were designing cookies from scratch, but it's Chromium and Firefox's shipping behavior, and it's reasonable to just accept. This specification change is covered by 0021 and 0022 in the WPT repository (see URL). Closes URL
WDYT, NAME / NAME ?
Step 4 says: However looking at WPT tests (for example [1] / [2]) I can see that when we have (empty name with value ) the expectation is to have back, so perhaps these instructions should include a special case when the cookie name is empty. [1] URL [2] URL
Minor suggestion, OK for me either way.


The 'secure-only-flag' is never "not set". It is either "true" or "false". This patch fixes two places where we should have been checking for falsity. Closes URL
NAME / NAME WDYT?
Good. I should have sent a PR. :-)
URL Step 8 says: But then Step 12 says: It's impossible to reach step 12 with the not set because it's always set in step 8. I believe a better wording would be .


Editorial: add one reference to Structured Trailers in a list of the types, and correct what appears to be a typo of Structured Field --> Structured Trailer.
Happened to spot these when perusing the structured headers spec; apologies if I've misread and the original text was correct.
Thanks!


Instead of a four-byte exporter, uses an eight-byte exporter and splits into two values. Support for exchanging server certificates and client certificates is now indicated separately.
The current advertisement scheme does not allow for a client to decide it is willing to implement secondary server certificates but not client certificates or vice versa. It may be worth having two SETTINGS values, one for whether you're willing to do either of the two flows.


though I'm not sure it's yet precise enough. There are three general classes of errors: The peer did something wrong. There are relatively few of these possible -- indicating more certificates to use than were requested, or more than one unsolicited certificate; sending CERTIFICATE_NEEDED to a peer that didn't indicate support for this extension. The authenticator is corrupt. This might indicate a problem with the TLS connection. The certificate isn't acceptable. There are lots of reasons this might happen. The first two should be at least stream and possibly connection errors. The latter should be handled at the HTTP layer, but previously had error codes defined for them. This PR removes several error codes and recommends handling at the HTTP layer if the certificate isn't accepted.
It is very unclear from the draft how exactly the client should handle a secondary server certificate it rejects. Presumably a bad secondary certificate should not be fatal to streams which don't use it. The draft seems to handwaive at this (though not very clearly, which means uncertainty for the server) in section 4. At the same time, the draft says: This is inconsistent with that idea. Suppose the server pushes some CERTIFICATE frame along with some resources it thinks the client would want. If the client rejects that certificate, this text implies the client must tear down the entire connection, interrupting unrelated requests. A useful heuristic for reasoning through all this would be to consider a client which blindly rejects every secondary certificate. This is especially relevant if the draft does not act on .
The restriction on the server is that it not push unless it has first sent the certificate. If the client rejects the certificate, clearly it will discard the push; the question is whether the client will be able to differentiate failure-to-send from cert-not-accepted. That depends on whether you assume that clients will look at the certificates, even if they aren't accepted; otherwise, I suspect that it can't. However, I think you're right that this is an overreaction. RFC7540 requires that a PUSH_PROMISE for an unproven origin be treated as a stream error, but doesn't specify on which stream. The parent stream still seems excessive, since the server can't know for which origins the client considers it authoritative.


Automatic use of client-proffered certificates was removed a while back; clients can indicate which certificate (if any) they want the server to consider by sending a frame with the flag set. There was text talking about automatic use of the server-proffered certificates, but there wasn't corresponding text disallowing that behavior for client certificates, simply the absence of permission. This PR forbids considering "available" certificates until the client indicates which certificate to use.
The secondary certificates draft leaves the authentication state of exchanges like the following unclear: In stream 1, the client is unambiguously using certificate A in the request to . Is it also using it for ? If the client believes the answer is no, while the server believes the answer is yes, secondary certificates introduces a . Some examples to consider: HTTP/2 cross-name pooling means one connection may service multiple origins. The client may choose to use a client certificate with some origins but not others. The web platform makes both anonymous and credentialed requests (see CORS). Keeping those straight is critical to avoid CSRF attacks. For now, browsers do not pool them due to various problematic connection-level auth mechanisms in HTTP/1.1, but there is discussion on relaxing this for the vast majority of connections that don't use these. This puts a heavier dependency on protocols getting these kinds of details right. This is especially important to make unambiguous because the original renegotiation-based hack for reactive client auth did rely on ambient authority. Once you renegotiated with a certificate, the unwritten interpretation was that all subsequent requests on this connection pick up the certificate. A server implementation may then be tempted to apply a similar logic to client certificates. The spec needs a MUST-level requirement not to do this, and make it clear that this is a server security vulnerability. Instead, client wishing to approximate the original renegotiation-based hack would send proactive frames on subsequent credentialed requests. This is especially important for HTTP/2, where there is both larger scope of pooling from cross-name bits and where multiplexing means we requests overlap temporally.


Deprecates SHA-1 as it's now vulnerable to collisions.
SHA-1 to be deprecated in because of https://sha-URL It's NOT RECOMMENDED When we decided to NOT RECOMMEND sha-1, we knew that collisions were possible. Now researchers states that The latest paper is here URL
Some feedback I've had is that we should deprecate. I'd like to hear from the WG if there is any pushback to doing so.
I'm in favour of deprecation.
3GPP TLS Profile 6 also makes SHA-1 a "must not" for TLS 1.2 [1]. [1] - URL
lgtm


adds an example of a request with no payload body (eg. HEAD) mention an use-case in the Signature section.
NAME do you think this is consistent with content-coding like aes128gcm?
An example of using Digest in a request with no payload body. There is a misconceptions that Digest does not apply to request with no payload body. As it's not a special case URL for sha-256 we can just use Other algorithms are free to define a different computation, and the examples will only be tied to sha-256


References I-D.httpbis-semantics using an inline referece to {{SEMANTICS}}. This will ease the transition once SEMANTICS is updated to RFC.


NAME noticed that is messed up. I think the fix is to indent the top-level 2-5 -- but I want to have a good look at it, compare to implementation, and I'd like others to verify, as I'm wary of making changes at this late stage. Blame seems to be , which I vaguely remember as being... surprising. That will teach me to slow down when something weird happens with Git...
Ping NAME NAME NAME to look over my shoulder...
Looking at URL the problem is that what became top-level 3 and 4 should have been steps inside top-level 2. Further changes have happened so now that applies to top-level 5 as well. (Top-level 2 itself seems good as that initiates the loop.) (Other for each statements do appear to have correct indenting.)
Like that?
Looks good to me.


When we discussed removing the semantics of urgency levels, we also thought it would be a good idea to change the default from 1 to 3. We agreed to do this and landed a change that removed the semantic text but unfortunately forgot to also change the default. This change simple fixes the oversight.
See URL for background
Thank you for the fix!


From Magnus's feedback
also NAME PTAL
This does not instill much of a panicked reaction in me, which is probably a good sign. I trust it is intentional to not apply a similar treatment to inner lists (which also has a prose description I had commented on previously) on the grounds of them not resembling existing top-level header field structures? That's certainly defensible, though I have to wonder whether someone will simply assume that it must be the same (not that we have much hope of changing such a person's behavior).
How does this vibe with ? I know we spent a bit of time on it, but it's long enough ago that I can't recall detail.
Ah, right, I think I remember. Doing it this way means inner-list is different: The original motivation to remove tabs was because the above was going to be but there was consternation about RWS. Most of the discussion is in
NAME was where my mind went first too, but that seems to be just about in inner lists (which makes sense). I think this is separate; intermediaries that don't know about the semantics and syntactic limitations of a given field shouldn't be meddling inside it (which inner list delimitation is).
NAME I think so -- that's the only reason to allow this. Existing servers may already legitimately be using TAB when combining multiple field lines. And I suppose it makes sense, given the recent discussion about not breaking up individual list or dictionary members over multiple lines, that we don't need to replace *SP with OWS everywhere. I'm okay with this change -- does it warrant a note in the prose somewhere that this special case only exists to accommodate field concatenation? Let's hope we don't need to add VTAB or FF to this, too :)
NAME I don't know that that's necessary; we already pretty clearly. In SF, I looked at changing "whitespace", but in each case the ABNF and algorithms make it clear what we're talking about, so I don't see a strong need to disambiguate.
I'm ok with the change over here; that said, the Semantics spec could be clearer. Opened URL
NAME and I have been talking about this, and have come to the conclusion that this change went too far. Specifically, steps 1 and 5 in "Parsing Structured Fields" should just be SP, not OWS, because there isn't any risk of an intermediary inserting TAB before the first field line or after the last field line; it's only between List and Dictionary members that we need to be concerned. Reverting that part of the change also makes writing the test cases considerably simpler. See 6842793e.
This is so that field line combination as per the Semantics spec can happen, right? I note that currently says: Note that it says "comma an optional whitespace", not "OWS". Depending on how you read it, it might include other whitespace characters. I believe this needs to be fixed in the Semantics spec.I dont think I ever saw a TAB in a HTTP header in real life, but I am OK with this.


Add what seems to be a missing word in the __Host example text.
Thanks!
Thank you!


and . I've left Security Consideration as TBD, I'll fill that out in a separate PR.
The text in about the client using priority to inform request scheduling is a good one, but it belongs elsewhere.
The whole discussion about fairness is worth having, but it doesn't really go to the usual security concerns. Security concerns might cover things like DoS through over-use of prioritization (see ), or use of priority to starve others (which might cross-reference the fairness text). But I think that the fairness text should be bumped up to the top level.


Since fairness is being moved out of security considerations, (URL) it makes the section empty. Seems reasonable to add some prose about the considerations of this scheme as compared to HTTP/2. However, this also depends on the outcome of the reprioritization discussion, so I'm being a little weasly with TBD and TODOs. Might want to just hold onto this for a while but WDYT NAME ?
Thank you for working on this. LGTM modulo the point below.


Strengthened requirement for content identifiers for header fields to be lower-case (changed from SHOULD to MUST). Relaxed guidance on processing Creation Time and Expiration Time to only require verifiers to examine them and test against the verifier’s requirements. Minor editorial corrections and readability improvements.
The current text allows mixed-case header field names when they are being used as content identifiers. This is unnecessary – header field names are case-insensitive – and creates opportunity for incompatibility. Instead, content identifiers should always be lowercase.
The processing instructions for Creation Time and Expiration Time imply that verifiers are not permitted to account for clock skew during signature verification.
This can safely be fixed adding a -like claim, so that the signer remains in control of the signature validity. This is especially important if the signature is created with the signer's private key. imho this kind of document should not define a clock-skew tolerance threshold, and implementors shoud be suggested to fix their clocks. There may be corner cases (eg. IoT/disconnected devices ) that we should address properly
I'd split the clock-skew part in a separate PR. The rest LGTM.


Fixes .
Done
Currently according to the spec, any cookies set with a header should be ignored if their name and value are empty. However, this check is not applied in section 5.4 of the spec, and as a result the CookieStore had a allowed for sites to work around this check. To me, this is a symptom of a bigger issue: 6265bis treats non-HTTP cookies as an afterthought, . I think it's worth opening a separate issue just to track whether we add the empty-name-empty-value check to 5.4 of 6265bis, and if there are other checks on the header in 5.3 that are implied in 5.4 but not made explicit.
CC NAME
As you've noticed, the document currently assumes that 5.4 is only going to be exercised after 5.3. I think this particular issue is distinct from the issue you raise in the other bug, as the only non-HTTP APIs that existed before the async API you're working through used cookie strings, which were parsed just as the header was. Given that new mechanism, it does make sense to move "If both the name string and the value string are empty, ignore the set-cookie-string entirely." from 5.3 to 5.4. Skimming through, I think that's the only restriction that causes cookies to be ignored at the parsing stage.
Minor change so that we won't break "links" if ordering changes, and to explain the change.


PTAL NAME NAME NAME
Looks reasonable to me!
NAME PTAL; I'll merge tomorrow if I don't hear anything.
NAME how do you distinguish between a proxy certificate and the certificate used for the next hop?
By "proxy certificate" I mean the certificate sent by the CDN (when acting as a client) to the origin server for the purpose of mutual authentication. In contrast, would apply (at least in my mind) only to the certificate presented by the origin server.
So, I think the argument is that is either a (i.e., the server you're connecting to gave you an error to the effect that you need to present a client certificate), or a (i.e., you realised you need to present a certificate before connecting, but don't have one) depending on exactly how the error occurred. Is that sufficient?
As someone who spent countless hours debugging connection issues to various origin servers, my main concern is that alone doesn't provide enough information as to why the connection failed, it only narrows it down to a TLS certificate issue, but for anything definitive that you would want to share with the customer, you'd still need to go and dig further into logs, or try to replicate the issue. Yes, I know that you could put more information in the "details" field, but I'm not a big fan of implementation-specific free-form text. Having said that, I'm not going to oppose if you prefer to have only those 3 generic fields.
Thanks. As Ryan points out, the problem is that implementations have different terminology and granularity of error reporting, and it's not the place of this specification to impose that on them.
Looking at what to map x509 errors (as returned by into, the most obvious one is . However, there's also , which is one of these errors. It seems odd to have these two, but not any of the many other verification errors. At first glance, I suspect it may be better to have a single error, and let the convey the reason - whether it's expiration or something else.
Ultimately, there is a fine balance between providing a generic "catch-all" error, and enumerating all possible errors. The linked lists 69 possible reasons for success or failure, and including all of them clearly doesn't make sense, especially when only a few of them will happen in practice. However, having only a generic "catch-all" error with the real reason "hidden" in a free-form text in , that's going to vary from implementation to implementation, is going to make this less useful for any kind of automated processing and/or analysis. Ideally, I think, we should have specific enums that cover 95%+ of reasons happening in production, and only use the generic "catch-all" error for things not covered by them... So, playing the devil's advocate, perhaps we should add a few more? (Note that there is already raised on mismatched identity, SHA256, SPKI or other missed expectations.) Also, if you can get your hands on errors happening in production, that could help us make more informed decision here.
I agree we shouldn't do a 1:1 mapping (especially with a library), but the hierarchy needs to be clear, and mapped to terminology used in the standards. I.e., there should be a generic catch-all 'cert error' code, and then more specific ones for the major classes of problems.
TLS itself also contains a pile of certificate-verification-related alerts. Although I think the set is mostly just carried over from SSL. URL NAME may also have some thoughts on certificate verification error-reporting.
Despite what libraries may provide, for their developers, is fairly clear: the only defined result is a I think coupling any protocol-level expectation about diagnostics for errors is fundamentally misaligned. It should not matter, for example, whether a particular library checks the validity period of the certificate before the signature. We know, empirically, that different libraries do very different things there: macOS vs Mozilla NSS vs Microsoft CryptoAPI each verify something like validity at different points within their verification algorithms. We know it's deeply flawed to view there being "the" certificate chain for a server, because by definition, the chain is defined by the client's policy and set of trust anchors. As a consequence, we know that clients SHOULD implement certificate path building, to explore possible certificate chains, and we know that TLS 1.3 was explicitly updated to reflect those decades of running code and the emergent rough consensus that the message, beyond the first , is an attempt to aid/influence that. is a huge collection of different ways verifiers can process and examine errors, during forward path building and reverse verification, and notes that the trade-offs are heavily dependent upon client and use cases. While I can understand the appeal for providing 'informational' statuses, any suggestion beyond a level of is probably too normative, and unsupported by the underlying specifications and best practices.
NAME the context here is a CDN or other reverse proxy reporting back errors in HTTP response headers, for debugging. There are no requirements around sending them (and senders are cautioned against leaking information that could aid an attacker). So, at one end a Boolean doesn't really help, and at the other end, the full list of errors by any one library (or all of them) is impractical. The list of alerts from NAME seems promising, and I note that we already have , whose value can be any TLS Alert string. However, That's intended to convey alerts received (and perhaps we should communicate that more clearly). The desired semantics here are that the problem indicated by the alert is generated in the client itself, not received by it. That leads me to believe that there are two viable paths forward: Rearrange the errors so that they mirror the alerts above (leaving 's semantic as stated above); e.g., we'd have , , and so forth Reduce everything into two errors, and or similar. Both would carry the TLS Alert value as an additional payload item. I think the difference is mostly stylistic, so NAME and I can figure that out. The bigger question is whether this is the right set of errors to focus upon.
But I think this is missing an important detail: from the perspective of a client, the only stable output is the boolean. For example, OpenSSL's reporting of errors is symptomatic of deeper flaws within its certificate verification; fixing those errors necessarily means some existing errors can't effectively be reported. This is covered at some length in . Ultimately, the set of errors that are relevant are, to an extent, subject to local policy: it's rare for certificate validators to think of errors in the ontology laid out by the TLS layer. Typically, a client just does a "best guess" (or just maps straight to ) when trying to map to the TLS layer, in part so it doesn't disclose extra information. This is certainly true when you think about local policy, such as limits on validity or the requirement of associated metadata, potentially delivered over TLS, such as Certificate Transparency or OCSP Must-Staple. I think the core question is whether you expect the client and the proxy to be in the same management domain. If they aren't, and the ED seems to be oriented around this scenario (where server and proxy are likely same administrative domain, but proxy and client aren't), then it seems better served as an opaque diagnostic string. As RFC 4158 calls out, beyond the 'boolean' is really just an administrative/diagnostic capability, not something meant to be semantically rich, meaningful, or stable, and certainly not to allow next-hop policy decision making.
Just to be clear - the user agent isn't involved in this at all, beyond receiving the header so as to make it available to someone diagnosing a problem (Likely someone from the origin, from the CDN/reverse proxy operator, and/or a help desk talking to an end user). What I think I hear you saying is that we should define a generic error and allow implementations to convey textual detail in it. Does that make sense? I also still see some value in distinguishing a TLS alert received from the origin by the proxy (in its role as TLS client) from this case (a problem it encounters as a TLS client).
Yes. This matches with Criterion 2 of URL and the dual mode trade-off in URL , which perhaps more clearly highlights the local policy aspect ("Ultimately, the developer determines how to handle the trade-off between efficiency and provision of information"). 100% agreed here. I was only commenting to the extent at which the proxy validates the peer certificate independent of the TLS layer framing. Perhaps poorly stated, but my comment in URL was trying to capture that Option 2 from URL () would likely just reduce to a boolean anyways, in a well-behaved TLS client.


HTTP 1.1 messaging is not normative replaced "message body" with a periphrases
Digest to be indepentent from http/1.1 (messaging) See URL
NAME iiuc the only MESSAGING-depending parts is: URL The spec references the term "message body" 3 times too, which is defined in MESSAGING. Do you think we should replace it? How would you do it?
trailers: you may want to reference URL message body: this might be "payload" (URL)


is preliminary to Consistently use instead of . In case we need to further focus on the value, we can say or . Looking at "content-coding" vs "content coding" in URL I think that this choice makes the document more readable.


Aligns a part of the doc with the SHA-1 deprecation we decided in We correctly deprecated SHA-1 but in this part we left it as NOT RECOMMENDED.


cc NAME since it closes your issue.
I believe this is now good to go, please approve or speak up if you disagree.
In there is a rather firm recommendation to erase priorities at servers that are served by coalescing intermediaries: This seems wrong to me. The Priority header field provides information about what the User Agent thinks of priority. This might be adjusted by intermediaries on the path, and it might not be globally consistent, but that does not mean the information should be discarded. Instead, I would prefer that we say that when an intermediary coalesces requests from multiple clients, servers need to be aware of that and account for that in their processing. The remainder of this text is fine in the sense that it identifies information the server can use to more fairly allocate resources to different requests, but - again - this is just information the server uses when making prioritization decisions. The model we operate on should not assume be that Priority is an instruction to the server, but that it provides the server (or intermediary) clues about how it might decide to allocate resources.
No one responded to this for a while, sorry. The text is mostly untouched but I did change the example to just . My read of this today, I'm concerned that the requirement is a bit specific. It's not clear if a server applying this would also discard any additional priority parameters. I don't know if NAME original point was along those lines or not, but I'll try to make a PR to address what I think needs fixing


NAME correctly pointed out that the draft contained a made up error code. On inspection, we need to define specific error codes for both H2 and H3. This change does that.
The latest version of the draft states: There is no such error either in or in . Perhaps HTTP/3's H3FRAMEERROR was meant?
Dang, I worked from memory and should've spent 2 minutes for checking. I'll get this fixed up thanks.


details encryption quirks: encryption functions may produce different results with the same data this means that if I GET an encrypted resource twice, I could get two different digest values so the digest value is just good to validate the ongoing message and not for further processing of the data at rest, unless I store the encrypted data or use an algorithm which in turn might disclose information. This
looks good, just some nits.


[x] avoid ambiguous statement on digest protecting from compressed content-coding URL i[x] t can protect from intermediaries altering representation metadata (content-type, content-coding)


Replaced unstructured header with and Dictionary Structured Header Fields. Defined content identifiers for individual Dictionary members, e.g., . Defined content identifiers for first N members of a List, e.g., . A signature in a request now looks like this:
I like this PR! We just need some tweaks, but it greatly improves the way the spec can be used.
This PR also fixes . Should we remove that appendix in this PR?
Redefine the Signature header field to use . This will simplify both the definition and the parsing of this header field value.
The Covered Content list, Algorithm, and Verification Key identifier should all be part of the Signature Input, to protect against malicious changes.
The Covered Content list contains identifiers for more than just headers, so the parameter name is no longer appropriate. Some alternatives: "content", "signed-content", "covered-content".
I like the direction this PR is taking: spec is more focused because it outsources spec of field format to draft-kamp-httpbis-structure dictionary format is more flexible and allows multiple signatures (important)


separates MESSAGING and SEMANTICS concepts (Eg. fields)
Thanks! :tada:
The spec relies only on HTTP Semantics and not on HTTP/1.1 messaging. [ ] improve wording [ ] switch to http-core Check all references to Messaging and consider replacing them using Semantic. See URL
NAME NAME NAME I was re-reading the spec after the more recent filed issues, and I think that switching this draft to HTTP Core terminology (eg. I-D.ietf-httpbis-semantics ) we could have a more consistent background for taking the right decisions about things like transformations, intermediaries.
This should be taken care of with , NAME please re-open with comment if there are more things to be done.


reuses existing definitions for S-F and Unix time.
Doesn't make this PR redundant? (or regressive, really, because references the exact definitions to use - and from structured headers)
This probably


removes algorithm specific rules for content identifiers Current layout is not backward compatible with http-signatures, so it's safe to do it.
The rules that restrict when the signer can or must include certain identifiers appear to be related to the pseudo-revving of the Cavage draft that happened when the algorithm was introduced. We should drop these rules, as it can be expected that anyone implementing this draft will support all content identifiers.


includes security considerations from
NAME probably those considerations are redundant: implementers know that computing digest has a cost. Do you think it's worth spending more time to land this PR or we can close it?
I'd go with a simpler statement such as or say nothing.
NAME this PR contains your proposal.
A threat model for . is this useful/required? should this go into Security Considerations or in another document?
User User-Agent: see RFC7230 Intermediaries that do not do TLS termination Intermediaries that do TLS termination.Application: the application actually running the service Intermediaries can alter HTTP messages Intermediaries that do transport-layer termination can alter HTTP messages The application can erroneously or purposedly alter the message User can forge messages with the same checksum values An intermediary can alter an HTTP header by chance or purpose. [x] Use an end-to-end transport-layer security mechanism. A TLS-terminator intermediary can alter representation-metadata by chance or purpose. [x] Use a signature mechanism that covers both and the representation-metadata. A TLS-terminator intermediary can replace the representation-data with another one having the same digest-algorithm. A malicious User can forge two messages with: different representation-data same Digest header values send an HTTP message with the first representation-data then pretend he sent the one with the second representation-data. A malicious Server could implement a similar behavior. [x] Use a digest-algorithm that is not subject to collision (eg. sha-256), or refuse to use digest-algorithms subject to collision. A User could exhaust server resources by chance or purpose via: 1- sending a huge representation 2- digest calculation of the complete representation 3- forcing the server to evaluate the digest of the included representation [x] To consume huge representation-data, you may consider mechanisms sending progressive integrity checksums in the payload body and just use to provide the last checksum value. A malicious User could exhaust server resources via: 1- reconstruction of the complete representation 2- digest calculation of the complete representation 3- forcing the server to evaluate many different digest-algorithms for a given representation If you are exposed to this kind of attack because reconstructing complete representations of your objects is computationally intensive, avoid using [ ] Digest with mechanisms like Range-Requests and PATCH. If you support multiple digest-algorithms: [ ] limit the supported digest-algorithms to the ones you really care for; [ ] establish a policy for validating only the digest using the stronger digest-algorithm. The recipient may skip Digest header validation by chance or purpose and still be compliant to the specification: as explained in {#digest-header} the recipient MAY ignore any or all the received representation-data-digests. This is because Digest was originally conceived in RFC3230 as a tool for the recipient to validate the received representation, but not for the sender to receive an integrity proof of the communication. [ ] You should not rely on the recipient having correctly verified the Digest value of the selected representation. If you want the recipient to validate the : [ ] agree on processing with your peer, like it is done in
Let's see if we can incorporate some of this into the security considerations.
all considerations should be inside the I-D once is merged
Thank, this works for me. Let's merge and we can iterate later if anyone thinks of something to add.


It looks like this was forgotten in , when unknown values were switched from None to Default. /cc NAME this caused us some confusion over in Go, if you have time I'd appreciate hearing what you think we should do in golang/go. Thank you!
Thanks! LGTM.


Fixes field ordering reference
In 12.6: "Any mangling of Digest, including de-duplication of representation-data-digest values or combining different field values (see 5.3.1 of [SEMANTICS]) might affect signature validation." But 5.3.1 is "Request". (note that I didn't catch this earlier because it doesn't use the "Section X of [Y]" pattern; this should be gixed as well)


This ended up being more changes than I first intended but I think most of them are uncontroversial and simply improve consistency through the document.
LGTM. Thanks NAME and Happy New Year!


This is a proposal to address issue /cc NAME
I've updated the graph in section 2 to note the new range. PTAL.
Each record currently includes between 1 and 256 octets of padding, while the default record size is set to 4096 octets. This is in many cases not sufficient, for example in the pad-to-next-power-of-two case. Extending the padding length to two octets will allow up to 65537 octets (65KB) of padding. I raised this on the ietf-http-wg list here: URL Martin about an upgrade path for existing users. I'll reply on the mailing list to not split the discussion.
This was fixed in and .


The I-D contains the following TODO we might add a SETTINGS parameter that indicates the next hop that the connection is NOT coalesced (see URL). I'd like to track that discussion here. Namely, with all the changes in the meantime, does NAME think that there is still a problem that needs fixing? OR can we close with no action?
I don't think anything additional is needed. We've got the two standard header options to indicate an intermediary is involved, that was the main point of the original discussion in Singapore IIRC. I think this won't matter all that much in practice, given warmed up edge-to-origin connections, pops being able to serve cached resources in between, etc. Origin owners really concerned with performance will know if their setup is coalescing or not (then the question is if origin server software allows tweaking prioritization behavior, but that's a general concern). CDN owners seeing bad origin behaviour will probably just overwrite the priority information instead of forwarding in practice. In short, I think the current text should suffice here, as I don't think many servers would support switching to RR when seeing an explicit "warning: coalescing intermediary" signal either way.
Thanks NAME In that case I've created to simply remove the TODO text, which will act to resolve this issues.