jiebi/CodeConvo huggingface dataset:
Code change:
1.3 in 0-RTT mode), a client can reuse the settings value found in previous connections to that origin RFC6454 to make assumptions. <del> 4. </del> <ins> 5. </ins> This document registers the following entry in the Permanent Message Headers Registry, as per RFC3864:

Related discussion:
text: The reason is that I think the distinction doesn't make much sense, and maintaining it adds a lot of complexity, basically forcing browsers to recreate the digest for every connection at O(N) cost. Under this premise what servers should do is: Push all the resources that are known not to be in the cache digest Push 304 responses for resources that are in the cache digest, but are likely to be stale (short freshness lifetime, etc) Don't push resources that are in the cache digest and have a long term freshness lifetime or are immutable. Does that make sense? I'm not sure I understand your reference to the push cache vs. the HTTP cache in your comment. In light of my explanation, is there still an issue there in your view?
URL is the reference implementation. Happy to change it. Do you have any specific changes in mind?
NAME Thank you for the explanation. I now understand the intent better. I think that we need to consider two issues regarding the approach. First is the fact that a browser cache may contain more stale responses than fresh resources. Below are the numbers of cached objects found in my Firefox's cache (to be honest the date is from 2016, I haven't been using Firefox in recent weeks and therefore cannot provide up-to-date data). total ---: 2,273 1,003 As you can see, large scale websites tend to have more stale objects than fresh objects. In other words, including information of stale-cached objects increases the size of the digest roughly three times in this case. Since performance-sensitive resources (that we need to push) are likely to be stored fresh (since they are the most likely ones marked as immutable, or near-immutable), transmitting only the digest of freshly-cached responses makes sense. Second is a configuration issue on the server side. One strategy that can be employed by an H2 server (under the current draft) is to receive a digest of freshly cached resources only, compare the digest against the list of resources the browser should preload by only using the URL, and push the missing resources to the client. It is possible for a H2 server to perform the comparison without actually fetching the resource (from origin or from cache) since only the URL would be required for calculating the digest.
Code change:
1.3 in 0-RTT mode), a client can reuse the settings value found in previous connections to that origin RFC6454 to make assumptions. <del> 4. </del> <ins> 5. </ins> This document registers the following entry in the Permanent Message Headers Registry, as per RFC3864:

Related discussion:
text: The proposal prevents such strategy from being deployed since it requires the ETag values to be always taken into consideration (should they be associated to the HTTP responses). In other words, servers would be required to load response headers of the resources to determine if it needs to be pushed, which could be a huge performance degradation on some deployments. Fortunately, servers could avoid the issue by not including ETags for resources that it may push. I think such change on the server-side configuration would be possible, but we need to make sure if we are to take the path (of removing the fresh vs. stale distinction). Let me explain using an example. Consider the following case: client has with and on server-side, the resource has been updated to When receiving a new request from the client, the server cannot determine if the client has URL in its cache. Therefore, would be pushed. The client, when observing (or equivalent tag), tries to load the resource. Since the fresh resource exists within the browser cache, that would be used. The pushed version is ignored and gets discarded (). This would be repeated every time until the cached object either becomes stale or gets removed from the cache. My understanding is that the browser behavior (explained in ) is true for Firefox and also for Chrome. Am I wrong, or missing something? Thank you for the link. I will try to use it. OTOH, do you have some working code that can actually calculate the cache-digest value taking a list of URLs as an input (something like URL)? I ask this because it would give us a better sense in how the actual size of the digest would be. One way to proceed would be to split the discussion of from Cuckoo filters into a separate issue or a PR. I do not have a strong opinion on the naming or the codepoints. What do you think? NAME
NAME Have you considered the approach using Cuckoo filter to generate GCS? I can understand the fact that you do not want to iterate through the browser cache when sending a cache digest. Per-host Cuckoo hash seems like a good solution to the issue. OTOH, as I described in my previous comment, it seems that sending the hash directly has several issues.
Code change:
1.3 in 0-RTT mode), a client can reuse the settings value found in previous connections to that origin RFC6454 to make assumptions. <del> 4. </del> <ins> 5. </ins> This document registers the following entry in the Permanent Message Headers Registry, as per RFC3864:

Related discussion:
text: That is why I am wondering if it would be viable to generate GCS from the per-host Cuckoo filter that would be maintained within the browser. I can see three benefits in the approach, compared to sending the values of Cuckoo filter directly: the size of the digest will be smaller we can keep the distinction between fresh vs. cache. Sending digest of fresh resources only would end up in even smaller digests. Retaining the distinction lowers the bar to deploy cache-digests on the server side. note: you can store the time when the cached object becomes stale in the data associated to the Cuckoo filter entry (assuming that you would have associated data to handle resize, as we discussed in URL). That information can be used when builiding the GCS to determine if a particular object should go into a GCS of fresh resources or that of stale ones less change to the browser push handling (no need to handle pushes of 304 or replace a freshly cached object when an object with the same URL is being pushed) In case of or in the comment above, sending fresh-only digests using GCS would be about 1/3 the size of sending fresh & stale digests using Cuckoo filter. The biggest cost of calculating GCS from Cuckoo hash would be the sort operation. But I think that the cost could be negligible compared to the ECDH operation that we would be doing for every connection, considering the fact that the number of entries that we would need to sort would be small (e.g., up to 1,000 entries of uint32_t), and the fact that sort algorithms faster than O(n log n) radix sort can be deployed (e.g. radix sort). WDYT?
So have a cuckoo filter digest and then put its fingerprints in a GCS? I have not considered that. Need to give it some thought... At the same time, it's not clear to me how that would enable a "stale" vs. "fresh" digests, or handling of improperly cached resources (fresh resources that were replaced on the server).
I would appreciate it if you could consider. To me it seems it's worth giving a thought. Under the approach proposed in this PR, structure that stores the per-host digest would look like below. is required for resizing the filter (e.g., when doubling or halving ).
Code change:
1.3 in 0-RTT mode), a client can reuse the settings value found in previous connections to that origin RFC6454 to make assumptions. <del> 4. </del> <ins> 5. </ins> This document registers the following entry in the Permanent Message Headers Registry, as per RFC3864:

Related discussion:
text: What I am suggesting that you could change the structure to the following. In addition to the hash value, each entry will contain the moment when the entry becomes stale. The moment can be calculated when the entry is added. For example, if the entry represents a HTTP response with a , can be calculated as . If the entry represents an immutable HTTP response, then should be set to a very large value (e.g.. assuming that underlying type of is ). When building a GCS digest, you would do the following: step 1. prepare an empty list that would contain hashes of fresh responses step 2. prepare an empty list that would contain hashes of stale responses step 3. foreach entry in cuckoofilter: step 3-1. check if the entry is fresh or not, by checking the value of step 3-2. if the entry is fresh, append of the entry to the list of the hashes of fresh responses step 3-3. otherwise, append of the entry to the list of the hashes of stale responses step 4. sort the list of hashes of the fresh responses, encode as GCS, and send step 5. sort the list of hashes of the stale responses, encode as GCS, and send You can skip the operations related to stale objects (i.e. step 2, 3-3, 5) if the server is unwilling to receive stale digests. Whether the approach can be implemented depends on if a client can determine the moment a response becomes stale. I anticipate that it is possible to determine that when you register the entry to Cuckoo filters (which is when you receive the response from the server).
NAME NAME I'm planning to attend the IETF 100 hackathon this weekend in Singapore. (First timer here. ) I'm happy to collaborate on a (URL) implementation of this spec if either of you are around and interested. I'm fairly familiar with the current spec, having implemented it and .
NAME Wonderful! I'll be attending the hackathon on both days (i.e. Saturday and Sunday). I do not think that I would have time to work on Cache Digests, but would love to discuss with you (or help, if you need) about your work on Cache Digests.
Code change:
1.3 in 0-RTT mode), a client can reuse the settings value found in previous connections to that origin RFC6454 to make assumptions. <del> 4. </del> <ins> 5. </ins> This document registers the following entry in the Permanent Message Headers Registry, as per RFC3864:

Related discussion:
text: I've got an incomplete initial reference implementation at URL It doesn't yet include removal and querying (that's what I'll be adding next), but I did run it on a list of ~3250 URL (which I got out of my main profile chrome://cache/) and it seems to be creating reasonable sized digests. One more advantage, the digests seem to be highly compressible when sparse. Results so far: Digest with 1021 entries (so room for ~4K URLs): 5621 in-memory, 5233 gzipped (when filled with 3250 URLs). Digest with 2503 entries (so room for ~10K URLs): 13772 in-memory, 6879 gzipped (same 3250 URLs). Digest with 7919 entries (so room for ~31K URLs): 43560 in-memory, 9984 gzipped (same 3250 URLs). In practice, I think ~1000 entries is most probably enough, but it's good to know we can increase the digest size (to avoid having to recreate it), without significant over-the-wire penalty.
OK, I now have a complete reference implementation and it seems to be working fine. It also exposed an issue with the initial algorithm, forcing table allocation to accommodate a power of 2 number of entries. Latest results for 3250 URLs taken from my cache: One note: the 1021 entries table had 35 collisions, so it seems like it's insufficient for that number of URLs, unless we're willing to absorb extra pushes for ~1% of the resources.
NAME Interesting! It's good to know that we have numbers now. What is the value of P (the false positive ratio) that you used?
P=8 (so 1/256 false positive)
Note that the numbers here may be possible to further optimize. One example is semi-sorting of the buckets which the Cuckoo-Filters paper mentions, and which I have not yet implemented. It adds some runtime complexity, but can reduce the fingerprint size per resource by a full bit, so could have resulted in ~9% smaller digests in this case.
NAME Awesome! Me not being familiar with these data structures (despite reading Wikipedia article ), why does the 1/256 probability (~4/1000) result in 35 collisions?
Code change:
1.3 in 0-RTT mode), a client can reuse the settings value found in previous connections to that origin RFC6454 to make assumptions. <del> 4. </del> <ins> 5. </ins> This document registers the following entry in the Permanent Message Headers Registry, as per RFC3864:

Related discussion:
text: The 35 collisions are on top of the false positive rates, and represents resources that we failed to put into the table to begin with (due to both their buckets being full). That rate of collisions seems high compared to the results in the paper, so I need to dig further to see who's wrong...
The collisions are now fixed. It was an algorithm issue, where the entry to be pushed was always the same one at the end of the bucket. I've change that to be a random fingerprint from the bucket, which significantly improved things. The ref implementation is now collision free almost up to the point where the digest is full.
Code change:
therefore likely to be more appropriate for use for performance, security or other reasons. <del> Implementations MUST negotiate - and therefore use - ephemeral cipher suites, such as ephemeral Diffie-Hellman (DHE) or the elliptic curve variant (ECDHE) with a minimum size of 2048 bits (DHE) or security level of 128 bits (ECDHE).  Clients MUST accept DHE sizes of up to 4096 bits. Implementations are encouraged not to negotiate TLS cipher suites with known vulnerabilities, such as RC4. An implementation that negotiates a TLS connection that does not meet the requirements in this section, or any policy-based constraints, SHOULD NOT negotiate HTTP/2.  Removing HTTP/2 protocols from consideration could result in the removal of all protocols from the set of protocols offered by the client.  This causes protocol negotiation failure, as described in TLSALPN. Due to implementation limitations, it might not be possible to fail TLS negotiation based on all of these requirements.  An endpoint MUST terminate an HTTP/2 connection that is opened on a TLS session that does not meet these minimum requirements with a ConnectionErrorHandler of type </del> <ins> The set of TLS cipher suites that are permitted in HTTP/2 is restricted.  HTTP/2 MUST only be used with cipher suites that have ephemeral key exchange, such as the TLS12 or the RFC4492.  Ephemeral key exchange MUST have a minimum size of 2048 bits for DHE or security level of 128 bits for ECDHE.  Clients MUST accept DHE sizes of up to 4096 bits.  HTTP MUST NOT be used with cipher suites that use stream or block ciphers.  Authenticated Encryption with Additional Data (AEAD) modes, such as the RFC5288 are acceptable. Clients MAY advertise support of other cipher suites in order to allow for connection to servers that do not support HTTP/2 to complete without the additional latency imposed by using a separate connection for fallback. An implementation SHOULD NOT negotiate a TLS connection for HTTP/2 without also negotiating a cipher suite that meets these requirements.  Due to implementation limitations, it might not be possible to fail TLS negotiation.  An endpoint MUST immediately terminate an HTTP/2 connection that does not meet these minimum requirements with a ConnectionErrorHandler of type </ins> .

Related discussion:
text: Proposed text for .
This would be consistent with the plan for TLS 1.3.
NAME Firefox hard fails here, which I think is the right decision. I'll confirm with the working group.
Code change:
There are 4 types of filters: Latest Group (0x1) : Specifies an open-ended subscription with <del> objects from the beginning of the current group. </del> <ins> objects from the beginning of the current group.  If no content has been delivered yet, the subscription starts with the first published or received group. </ins> Latest Object (0x2): Specifies an open-ended subscription beginning <del> from the current object of the current group. </del> <ins> from the current object of the current group.  If no content has been delivered yet, the subscription starts with the first published or received group. </ins> AbsoluteStart (0x3): Specifies an open-ended subscription beginning from the object identified in the StartGroup and StartObject fields.

Related discussion:
text: This came up during interop - A relay received a subscribe with start={g=RelativeNext/0 o=Absolute/0}. Since the relay had not received any objects, it defaulted largest to 0 and interpreted the subscribe as starting at {g=1, o=0}. When {g=0,o=0} arrived, it was not forwarded. But there's a reasonable interpretation that it should have forwarded treated this as the beginning of the next subscription. This is partially related to and maybe
If the subscriber wanted to get the largest group, it would have made request start = {g=RelativePrevious/0, o=None} .. This would have the interpretation that subscribe starts at {g=0, o=0} when {g=0, o=0} arrives. This would also work when {g=0, o=22} arrives. If my understanding of locations is correct, then the original request of {g=RelativeNext/0 o=Absolute/0} is incorrect for the answer being expected ..
I think it's reasonable to return 0,0 The subscriber uses RelativeNext if it doesn't want old data. If no data has been generated, then that requirement is still met.
But that's ambiguous. Since Group and Object IDs are zero-based, that response also describes the situation in which the relay has received the first object from the first group, which is clearly a different state. Can we solve this problem by specifying that both GroupID and Object ID are >= 1 of they exist, and 0 if they do not? This can be used to describe the situation in which the subscription is active but the publisher has not yet produced any objects.
Oh to clarify, the SUBSCRIBE_OK should return None/None as the latest group/object. The first OBJECT delivered would be 0/0. And yeah we could switch object/group to be 1-indexed instead of 0-indexed. None=0
Individual Comment: Agreed that in this particular case, the client was not really asking for what they wanted. The "Largest group/object" language comes from the draft, though, and I think it's ambiguous what it means to a relay that hasn't seen any objects.
Code change:
There are 4 types of filters: Latest Group (0x1) : Specifies an open-ended subscription with <del> objects from the beginning of the current group. </del> <ins> objects from the beginning of the current group.  If no content has been delivered yet, the subscription starts with the first published or received group. </ins> Latest Object (0x2): Specifies an open-ended subscription beginning <del> from the current object of the current group. </del> <ins> from the current object of the current group.  If no content has been delivered yet, the subscription starts with the first published or received group. </ins> AbsoluteStart (0x3): Specifies an open-ended subscription beginning from the object identified in the StartGroup and StartObject fields.

Related discussion:
text: My interpretation of the spirit of the draft is that 0/0 would be forwarded in this case if the client asked to start Next/0 (eg: there's a bug in my relay), but if so, we should make it clear in the draft how it's supposed to work.
Is this
I think I can see the intent with what's there, but the draft could use some editorial text clarifying what "next/0" means when subscribe OK was "no content available".
I thought we decided on call that we were not going to steal bits from the group id / object id to indicate meta data what is going on. After that call I was expecting to see some explicit flag for "no content available" if that is what needed to be sent.
After merging , Subscribe OK has the flag you are referring to: https://moq-URL I left this issue open because I think there's still some ambiguity that can be resolved with editorial text.
makes sense - thanks
NAME can you write some editorial text to clarify this if you have something in mind?
I tried to write some text, but I got confused. Ignoring object locations for a second and just focusing on groups, I think this is what we want, but I'm unsure how to define "current" when there are no objects: I think the simplest way to resolve this is to treat the next seen group ID as the "next" one and anything attempting to match only "current" matches either a) nothing or b) . I recognize that b) may be controversial in that we don't require unitary increase in group IDs. Practically I think subscribers should usually ask for [RelativePrev/0, None] (give me the current group if you know it or the next seen group if you don't). If we assume that the publisher only says "ContentExists: false" when it hasn't published anything, and relays only repeat this when they get it from publishers, then it's somewhat easier to assume that anything before "next" simply doesn't exist. I'm unsure if this covers publisher restart cases well enough though. There's also an asymmetry in this case in that there's no message to communicate how the relative requests were interpreted, as SUBSCRIBE_OK now does when the largest object is known.
Code change:
There are 4 types of filters: Latest Group (0x1) : Specifies an open-ended subscription with <del> objects from the beginning of the current group. </del> <ins> objects from the beginning of the current group.  If no content has been delivered yet, the subscription starts with the first published or received group. </ins> Latest Object (0x2): Specifies an open-ended subscription beginning <del> from the current object of the current group. </del> <ins> from the current object of the current group.  If no content has been delivered yet, the subscription starts with the first published or received group. </ins> AbsoluteStart (0x3): Specifies an open-ended subscription beginning from the object identified in the StartGroup and StartObject fields.

Related discussion:
text: Further, the algorithm for how to interpret relative object locations in groups with an unknown "largest object" may be even murkier, but let's agree what the groups mean and then move on to objects.
Now that is merged I think I can make a PR to address the concern. I think it would be something like:
LGTM
Code change:
7. <ins> Clients that send HTTP CONNECT requests on behalf of untrusted TCP clients MUST wait for a 2xx (Successful) response before sending any TCP payload data. To mitigate vulnerabilities from any clients that do not conform to this requirement, proxy servers MAY close the underlying connection when rejecting an HTTP CONNECT request, without processing any further data sent to the proxy server on that connection.  Note that this behavior may impair performance, especially when returning a "407 (Proxy Authentication Required)" response. 8. </ins> This document has no IANA actions.

Related discussion:
text: This includes changing the title, adjusting the language to be more generic, and adding a section with guidance for HTTP CONNECT.
Most of the considerations in optimistic-upgrade, which originally emerged from consideration of "connect-tcp", also apply to HTTP CONNECT. We should consider expanding the scope of the draft to cover that topic as well. cc NAME
Code change:
5.2.1. <del> A proposed congestion control algorithm SHOULD be evaluated when competing using standard IETF congestion controls, e.g.  RFC5681, </del> <ins> A proposed congestion control algorithm MUST be evaluated when competing against standard IETF congestion controls, e.g.  RFC5681, </ins> RFC9002, RFC9438.  A proposed congestion control algorithm that has a significantly negative impact on flows using standard congestion control might be suspect, and this aspect should be part of the

Related discussion:
text: A few clarifying nits, as resolving the tension between a global "MUST evaluate" and some local "SHOULD evaluate"s.
Merge!