Subject: improved caching in HTTP: new draft

From: Chris Drechsler <[email-masked]>
Date: Mon, 19 May 2014 09:13:40 +0200

Dear editors of [Part6],
dear working group members,

I've written a draft about an improved caching mechanism in HTTP 
especially for shared caches (to improve caching efficiency and reduce 
costly Interdomain traffic). It can deal with personalization (e.g. 
cookies, session IDs in query strings) and varying URLs due to load 
balancing or the use of CDNs. The caching mechanism ensures that all 
headers (request and response messages) are exchanged between origin 
server and client even if the real content is coming from a cache.

The draft is available under the following URL:

http://tools.ietf.org/id/draft-drechsler-httpbis-improved-caching-00.txt

I kindly request you for comments - thank you!.

Sincerely,
Chris Drechsler

[Part6] http://tools.ietf.org/wg/httpbis/draft-ietf-httpbis-p6-cache/

---

From: Amos Jeffries <[email-masked]>
Date: Tue, 20 May 2014 02:34:59 +1200

> I kindly request you for comments - thank you!.

* The introduction states several abuses and deliberate non-use of
HTTP/1.1 features as the reasons for this proposal.

 Which would not usually be bad, but it is actually simpler for the few
problematic systems to start using existing DNS and HTTP features
properly than it is for the entire existing software environment to be
re-implemented to support this proposed mechanism.

* Section 2.1 appears to be proposing a new header. But what does "NT" mean?
 The use of this header seems wsimilar to an extension of the RFC 3230
message digest mechanism.

* Section 2.2 things get really weird:
 - 2.2.1 is requiring mandatory disabling of all conditional request
mechanisms in HTTPbis part4.
 - 2.2.2 is requiring mandatory TCP connection termination after every
duplicate response. Effectively removing all benefits HTTP/1.1 pipeline
and persistent connections bring. It does this in order to replicate the
304 conditional response using just 200 status code + TCP termination.
 - 2.2.2 also places several impossible requirements on intermediaries:
  1) to re-open a just closed TCP connection, presumably without delays
which would violate TCP TIME_WAIT requirements.
  2) to decode the Content-Encoding of responses to compare SHA-256
values. Even if the response was a 206 status with byte range from
within an encoding such as gzip.

In summary, the proposed feature completely disables the two most
valuable cache features of HTTP/1.1 and replaces them with an equivalent
process requiring mandatory use of the worst behaviours from HTTP/1.0.

Amos

---

From: Chris Drechsler <[email-masked]>
Date: Tue, 20 May 2014 13:25:19 +0200

Hi Amos,

thank you for your comments! They are very useful for me! Below are my 
answers:

> HTTP/1.1 features as the reasons for this proposal.

In a way I agree: varying URLs due to load balancing/CDNs or the use of 
session IDs in query strings are some kind of abuses. I think 
personalization via cookies is not. On the other hand they are widely 
used in the Internet and ISPs have to deal with it. And especially 
caching is suffering from it.

> re-implemented to support this proposed mechanism.

How would you properly solve it via DNS and HTTP features to ensure that 
a representation from URL A is the same as from URL B? I think it is 
very difficult because you don't know how all kinds of CDNs work internally.

> message digest mechanism.

I looked for a header field name different to cache-control and named it 
that way - NT means new technology. And right, it is similar to RFC 3230 
but there is no extra RTT due to negotiation of the hash algorithm.

> mechanisms in HTTPbis part4.

Maybe my formulation is not clear. If cache-control is used by the 
content producer then [Part6] caching should be applied and conditional 
requests make sense and should not be disabled.

If the content producer uses CDNs and/or personalization and wants to 
benefit from caching then he can make use of the new caching mechanism 
(and would omit the cache-control header). Then there is no need of 
conditional requests because the cache system will abort the transfer if 
the hash values match.

It's always controlled by the content producer.

> 304 conditional response using just 200 status code + TCP termination.

You are right. In reality persistent connections and pipelining are not 
so widely used (see [1]). Especially pipelining is only used in roughly 
6% of all connections. When it is used then for relatively small 
contents. The caching mechanism in my draft should be applied for large 
contents (significant larger than 20KB) like bigger images or videos for 
example.

> which would violate TCP TIME_WAIT requirements.

I've written re-open but thats not the right word - I meant open a new 
connection (with a new port) - I will fix it in the draft. And your are 
absolutely right: re-open the same TCP connection would violate TCP 
TIME_WAIT requirements.

> within an encoding such as gzip.

No, you can not compare the hash value until you have the full (range) 
of the transfered representation. So the cache system would store the 
byte range from the 206 response and would wait until other responses 
bring the missing parts. After that the cache can compute the hash value 
and if it is correct (in comparison to the Cache-NT fields of the former 
responses) then the cache would store it and would use it for following 
requests. The computation should/can be done during low load (not in 
busy hour).

> process requiring mandatory use of the worst behaviours from HTTP/1.0.

In a way I agree. For HTTP/1.0 and HTTP/1.1 my draft is a workaround. 
What I would need there is something like a STOP-sending-this-response 
request. In general the new caching mechanism is more useful for larger 
representations and they are seldom pipelined.

What about HTTP2? As each HTTP request-response exchange is assigned to 
a single stream no side effects will arise - in my opinion. What do you 
think, can you see side effects?

> Amos

Thanks a lot,
Chris

[1]
Fabian Schneider, Bernhard Ager, Gregor Maier, Anja Feldmann, and Steve 
Uhlig. 2012. Pitfalls in HTTP traffic measurements and analysis. In 
Proceedings of the 13th international conference on Passive and Active 
Measurement (PAM'12), Nina Taft and Fabio Ricciato (Eds.). 
Springer-Verlag, Berlin, Heidelberg, 242-251.

---

From: Guille -bisho- <[email-masked]>
Date: Wed, 21 May 2014 09:10:20 -0700

My 2 cents after reading the draft:

Etag and If-None-Match already give a conditional get feature with
hash that does not need a reset of the connection.

Your proposal adds very little caching for bad practices. Nobody
should be using two urls for the same resource, if you need load
balancing between two cdns, you should be consistent and js1 always be
requested from site1 and js2 from site2. And this is being improved by
HTTP2 that will elimitate the need for sharding among domains to
overcome limits if parallel requests and head-of-line blocking.

The Cache-NT header can only be applied  within a domain, and even
there is risky. A malicious user could inject malicious content with a
Cache-NT header that matches other resource to poison the cache. Even
if intermediate caches check the hash, there is still pre-image
attacks, won't be hard to find a collision and append malicious code
to a js file.

With Cache-NT you are only avoiding the transfer of the content, but
still incurring in the request to the backend server. Most of the
times that is the expensive part, and before you reset the connection
the backend would have probably sent you another 8 packets of
information (the recommended initcwnd is 9 by this days). If the
request should be cached, better get the provider to configure cache
properly to avoid doing the request altogether than this oportunistic
but dangerous way of avoiding some extra transfers over the wire.

Guille -bisho-
<[email-masked]|fb.com>
:wq

---

From: Chris Drechsler <[email-masked]>
Date: Fri, 23 May 2014 10:06:04 +0200

Hi Guille,

thank you for reading my draft and giving me feedback - this is very 
helpful! My answers are below:

> hash that does not need a reset of the connection.

You are right, Etag + If-None-Match is an option but there are some 
drawbacks:

1) The Etag is only consistent within one domain. The SHA-256 hash value 
in the Cache-NT header identifies the transfered representation 
absolutely independent of the used URLs (and therefore across domains).

2) Caching via Etag + If-None-Match in [Part6] can only be used in 
combination with the URL. If content providers use varying URLs for one 
specific resource (e.g. due to load balancing/CDNs or session IDs in the 
query string) then the cache system stores several copies of the same 
resource.

> overcome limits if parallel requests and head-of-line blocking.

I agree to you, nobody should be using two URLs for the same resource. 
But reality looks different:

1) Due to load balancing/use of CDNs one specific resource is available 
via different URLs. Especially larger ISPs with connects to several 
Internet exchange points and/or several transit links are redirected to 
different server locations of the same resource. This can change within 
minutes due to changing BGP routes and/or due to load balance mechanisms 
of the content producer/CDN provider.

2) URLs can change for another reason: changing parameters in the query 
string. For example if content producers use personalization via session 
IDs or implement access mechanisms via parameters in the query string 
then the cache system would store several copies of the same content. 
Mostly caching is disabled in this use case by the content producer 
(e.g. via cache-control header).

The proposed caching mechanism in my draft exchanges all headers of 
request and response messages so all information like parameters in the 
query string are exchanged. There is no need to disable caching. The 
SHA-256 hash value identifies resources independent of the used URL so 
varying URLs don't matter.

> attacks, won't be hard to find a collision and append malicious code

I don't see how the cache can be poisoned. Can you please explain it in 
more detail?

I see the following: The used SHA-256 has a strong collision resistance 
so it's nearly impossible to find two different inputs that result in 
the same hash value. When the cache system receives a response with a 
specific hash value in the Cache-NT header for the first time it 
computes the SHA-256 value on the received representation in the body. 
If both hash value are equal the cache system stores a copy of the 
representation and uses it for following requests. If they are not equal 
then nothing is stored (but the response is still forwarded to the 
client). So the cache stores and uses only validated content.

One security concern is that an origin server sends a hash value that 
does not fit to the representation in the body of the response message 
(by mistake or intention). Then the client will get a different body, if 
the cache system has an cache item which fits to the hash value in the 
Cache-NT header of the response from the origin server. I think this 
isn't a drawback of my proposed caching mechanism - I think this is a 
problem that we have already today: If the origin server is compromised 
(or intermediates in between) the clients would get malicious content 
already today.

What do you think?

> but dangerous way of avoiding some extra transfers over the wire.

You are right, INITCWND can be 9 or larger and if a HTTP transfer is 
stopped then some KB will go over the wire. Therefore the proposed 
caching mechanism in my draft should only be applied for larger 
representations (significant larger than 20KB) e.g. like larger images 
or videos.

Many content providers disable caching for several reasons: 
implementation of access mechanisms (e.g. via cookies or session IDs), 
user tracking, statistics (to evaluate the usage of a service or to 
account advertisement), transferring client specific information in the 
query string (e.g. like youtube does). They all want to get the client 
request and disable caching (as in [Part6] the client request terminates 
at the cache in case of a cache hit). My draft is building a bridge: all 
headers are exchanged and caching is possible.

> <[email-masked]|fb.com>

Thank you again for reading my draft and taking the time! I'm really 
looking forward for your answer.

Chris

---

From: "Poul-Henning Kamp" <[email-masked]>
Date: Fri, 23 May 2014 09:46:46 +0000

>absolutely independent of the used URLs (and therefore across domains).

I don't think this would work as you suspect.

Case 1:  SHA-256 input is the body of the object.
-------------------------------------------------

That means you cannot generate this header until you have generated the
entire object, ruling out progressive and optimistic delivery.

It's also not enough I belive, you may need to stick some of the
HTTP headers into the hash too, to get the expected behaviour.

Transfer-encoding, Content-type ?

This may not matter in anybodys actual reality, but I think it would
violate some of the many decorative rococo features in the RFCs.

Case 2:  You allow the content owner to define what goes into the SHA256
------------------------------------------------------------------------

Now you just lost the "globably unique" property because everybody
and his nephew are going to do use SHA256("FOOBAR" + URL) because
it's the cheapest.  A lot of them will not even understand why
"FOOBAR" would be necessary.

You need to construct the object identifier from a FQDN name and a
site-controlled nonce:

	Cache-Key: FQDN ":" <nonce_max_128_hex_chars>

Which FQDN the origin organization decides to use is entirely their
own choice, as long as it's theirs to control.  Likewise, the nonce
can be anything they care to use.

And that however opens the door wide to cache-poisoning, since you
cannot really check that the FQDN is legit, without starting some
kind of X.509 certificate song and dance...

I don't dispute the validity of the use-case you're trying to handle,
but I have a hard time seeing it pay off.

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

---

From: Chris Drechsler <[email-masked]>
Date: Fri, 23 May 2014 15:52:48 +0200

Hi Poul-Henning,

thank you for your comments! My answers are below:

> Case 1:  SHA-256 input is the body of the object.

No, not exactly. The SHA-256 value is being computed over that 
representation of the resource which would be send by the server to the 
client in case of a successful response with status code 200 OK and 
before applying Content-Encoding and/or Transfer-Encoding (these can be 
undone).

> entire object, ruling out progressive and optimistic delivery.

Right, you need the entire object. For "static" content this is no problem.

> Transfer-encoding, Content-type ?

Why do you believe in this - can you explain it in more detail?

As I see it: caching should/must ensure that the client will get exactly 
what the origin server has sent. The SHA-256 identifies the content in 
the body of the response which is coming from the origin server. The 
cache does the following:
-it uses the locally stored body (which fits to the hash value)
-applies Content-Encoding, Content-Range, Transfer-Encoding if present 
in the header of the origin server
-send this together with the header of the origin server to the client

So the client gets exactly the same response like the response which was 
coming from the origin server.

> Case 2:  You allow the content owner to define what goes into the SHA256

No, I don't allow the content owner to define what goes into the SHA256. 
It's clearly defined how the hash value should be computed.

Chris

---

From: "Poul-Henning Kamp" <[email-masked]>
Date: Fri, 23 May 2014 14:20:33 +0000

>Why do you believe in this - can you explain it in more detail?

The way HTTP is defined, the headers are an unholy mix of transport
encapsulation and object metadata.  Some headers are both.

Although I have yet to see any non-contrived examples, there is
absolutely nothing preventing the exact same body from having
two entirely different meanings, depending on the headers.

For instance:
	Content-Encoding: gzip
	Content-Type: text/html
	<gzip'ed body>
vs.
	Content-Type: application/x-gzip
	<exact same gzip'ed body>
	
Are two very different responses for any sensible client, yet your
proposal would deliver either one for the other.

Just SHA256()'ing the body will not be enough to work with all the
pathological corner-cases inherent in HTTP's lack of architecture.

You could try to divine which headers you have to feed into the SHA256
to unravel the mess.  I wouldn't bother,

>what the origin server has sent.

Yes, *including* some of the headers under *certain* conditions.

>It's clearly defined how the hash value should be computed.

And that doesn't work, see above.

And neither does case 2, as detailed in my previous email.

If the HTTPbis working group had as goal to make HTTP work better
than it does today, something like your proposal could have been
accomodated by eliminating some past mistakes, most notably
the mingling of transport/ metadata headers.

But given the WG's laser-like focus on compatibility with the limited
past, with almost no regard to the potentially infinite future,
your proposal is impossible to make work, and would just add to the
already overwhelming complexity of HTTP.

Poul-Henning

---

From: Guille -bisho- <[email-masked]>
Date: Fri, 23 May 2014 10:19:36 -0700

> 1) The Etag is only consistent within one domain. The SHA-256 hash value in
> the Cache-NT header identifies the transfered representation absolutely
> independent of the used URLs (and therefore across domains).

I know, just saying that a If-Modified-Since is the way to go, not
closing the connection prematurely, leaving packages on the fly
belonging to a closed connection.

> query string) then the cache system stores several copies of the same

The cache system can do whatever they want. They can freely
de-duplicate content if they wish to do so. They will of course need
to download the content before being able to cache, that's true.

> I agree to you, nobody should be using two URLs for the same resource. But
> reality looks different:
>
> 1) Due to load balancing/use of CDNs one specific resource is available via
> different URLs. Especially larger ISPs with connects to several Internet
> exchange points and/or several transit links are redirected to different
> server locations of the same resource. This can change within minutes due to
> changing BGP routes and/or due to load balance mechanisms of the content
> producer/CDN provider.

A single domain can be served from multiple locations without having a
different url for each one. The sites that can afford having different
datacenters to deliver content closed to users can really solve that
issue. Simply each user will resolve to a different ip depending on
location, or single ip but with multiple bgp routes.

Say you live in California. You will use google.com, no
california.google.com to grab your content, yet you can bet you are
connecting to servers very close to californa.

> string. For example if content producers use personalization via session IDs
> or implement access mechanisms via parameters in the query string then the
> cache system would store several copies of the same content. Mostly caching
> is disabled in this use case by the content producer (e.g. via cache-control
> header).

And if someone is doing that kind of things, you think you will be
able to convince them to add a new http header to facilitate content
caching?

And anyway, the cache system can do de-duplication on it's own, you
can freely choose to hash the content and try to combine several cache
entries.

> The proposed caching mechanism in my draft exchanges all headers of request
> and response messages so all information like parameters in the query string
> are exchanged. There is no need to disable caching. The SHA-256 hash value
> identifies resources independent of the used URL so varying URLs don't
> matter.

Caching is disabled on resources that are subject to be private for a
user, not because any technical limitation.

So if caching is not possible is because: a) There is some reason for
it (logging, then with minimal payload and no benefits from your
proposal) b) bad usage

I agree that for bad usages your proposal might help, but the people
doing things wrong are the least likely to start adding a new http
header to they responses.

> I don't see how the cache can be poisoned. Can you please explain it in more
> detail?
>
> I see the following: The used SHA-256 has a strong collision resistance so
> it's nearly impossible to find two different inputs that result in the same
> hash value. When the cache system receives a response with a specific hash
> value in the Cache-NT header for the first time it computes the SHA-256
> value on the received representation in the body. If both hash value are
> equal the cache system stores a copy of the representation and uses it for
> following requests. If they are not equal then nothing is stored (but the
> response is still forwarded to the client). So the cache stores and uses
> only validated content.

Preimage attacks are the easier ones, and here we have hashes of file
contents. I can grab a js file from google, and try to find a preimage
collision suffixing js code until I found one. There has been a lot of
advances on this: https://eprint.iacr.org/2009/479.pdf

So if you want to safely use a hash cross-domain you will need to
avoid preimage, because even sha256 that is currently highly resistant
will become eventually weaker.

> One security concern is that an origin server sends a hash value that does
> not fit to the representation in the body of the response message (by
> mistake or intention). Then the client will get a different body, if the
> cache system has an cache item which fits to the hash value in the Cache-NT
> header of the response from the origin server. I think this isn't a drawback
> of my proposed caching mechanism - I think this is a problem that we have
> already today: If the origin server is compromised (or intermediates in
> between) the clients would get malicious content already today.

The cache boxes will need to check the validity of the hash to be able
to serve safely.

Imagine:
- google.com/some.js sha256=xxxx
- You could trick the user to visit first badserver.com/malicious.js
and serve it with sha256=xxx (same as google)
- The cache system stores malicious.js as content for sha256 xxx.
- user goes to google.com, but the some.js will contain malicious.js instead.

> You are right, INITCWND can be 9 or larger and if a HTTP transfer is stopped
> then some KB will go over the wire. Therefore the proposed caching mechanism
> in my draft should only be applied for larger representations (significant
> larger than 20KB) e.g. like larger images or videos.

People serving big files a lot of times will get caching right, believe me.

> Many content providers disable caching for several reasons: implementation
> of access mechanisms (e.g. via cookies or session IDs), user tracking,
> statistics (to evaluate the usage of a service or to account advertisement),
> transferring client specific information in the query string (e.g. like
> youtube does). They all want to get the client request and disable caching
> (as in [Part6] the client request terminates at the cache in case of a cache
> hit). My draft is building a bridge: all headers are exchanged and caching
> is possible.

The way this is working currently with providers is that content
providers with enough needs place their own boxes in the internet
providers, close to the users and deliver content from there.

-- 
Guille -ℬḭṩḩø- <[email-masked]>
:wq

---

From: Chris Drechsler <[email-masked]>
Date: Tue, 27 May 2014 12:10:17 +0200

> proposal would deliver either one for the other.

In the first case the input is for example an html document and the 
server computes the SHA256 value before the document is compressed 
during the process of sending. The client decompresses it and gets the 
html document and displays it (see RFC2616 14.11).

foo.html:
     Content-Encoding: gzip
     Content-Type: text/html
     Cache-NT: sha256=AAAAAA....
     <gzip'ed body>

In the second case the input is an already compressed file, e.g. 
foo.html.gz. It will not be compressed again by the server during the 
process of sending (no Content-Encoding is applied). The SHA256 value is 
different to the former case:

foo.html.gz:
     Content-Type: application/x-gzip
     Cache-NT: sha256=BBBBBB....
     <same gzip'ed body>

The client should not decompress it (in the process of receiving) 
because there is no Content-Encoding header (see RFC2616 14.11). If the 
client does decompress the body then the Content-Type will be text/html 
afterwards and not application/x-gzip - so the identity of the media 
type get lost.

 From the point of the cache system two different SHA256 values mean two 
different cache items although they are bit-identical. This can be fixed 
internally in the cache system but is not in my focus. As compressed 
text/html documents are often very small (mean compression gain by 
roughly 75 %, see [1]) the Cache-NT header should not be applied. The 
focus is more on larger transfers.

Thank you for this pathological corner case - this helps me very much. 
Do you see other corner cases in the context of my draft?

> Yes, *including* some of the headers under *certain* conditions.

Let's figure out how many corner cases we have and how they influence 
the caching in my draft. At the moment I think there is no need to 
include some of the headers under certain conditions as there is no 
significant loss of caching performance due to not including them. The 
main subject is that the client will get the response the origin server 
has sent. I think this subject is always fulfilled by my draft.

> already overwhelming complexity of HTTP.

Thanks again for your comments!

Chris

[1]
P. Destounis, J. Garofalakis, P. Kappos, J. Tzimas, (2001) "Measuring 
the mean Web page size and its compression to limit latency and improve 
download time", Internet Research, Vol. 11 Iss: 1, pp.10 - 17

---

From: "Poul-Henning Kamp" <[email-masked]>
Date: Tue, 27 May 2014 10:46:49 +0000

>[...]

Would you be surprised if I tell you that most high-performance
servers and caches try their damnest to avoid running a gzip
compressor during delivery ?

In the first case the server would often have to run a gzip
decompressor to calculate the SHA256...

---

From: Chris Drechsler <[email-masked]>
Date: Wed, 28 May 2014 12:40:23 +0200

> decompressor to calculate the SHA256...

No, I'm not surprised. The SHA256 value can be computed when the 
document is made available on the server or when the document changes 
(like it is compressed and stored before any client requests it). So 
there is no need for computing it again for every single request.

For the cache system it is different. I suggest to store an incoming 
response with a Cache-NT header field. During low load the cache system 
can compute the SHA256 value and validate it with the hash value in the 
response message. If both are equal then the cache system can reuse the 
cache item for subsequent requests.

---

From: Chris Drechsler <[email-masked]>
Date: Wed, 28 May 2014 13:51:08 +0200

> connecting to servers very close to californa.

This mechanism is often called DNS redirection and is/was also used in 
the context of CDNs. Actually it is very coarse grained in selecting a 
server near the client because it only works on domain/subdomain level. 
 From the point of HTTP and caching it has one big advantage: it is 
absolutely transparent to the application layer.

Today the trend is to use URL rewriting/dynamic request redirection 
(e.g. have a look at how youtube redirects requests to servers in [1]) 
because it is more fine grained. Unfortunately this is not transparent 
to the application layer and results in different URLs for one specific 
content.

[1]
Adhikari, Vijay Kumar, et al. "Reverse engineering the youtube video 
delivery cloud." Proc. of IEEE Hot Topics in Media Delivery Workshop. 2011.

> can freely choose to hash the content and try to combine several cache

There are several benefits: If caching within an ISP is used then the 
content can be located much closer to the clients as it is possible from 
outside the ISP. On the side of the clients this means faster downloads 
and better QoE. ISPs can profit from reduced Interdomain traffic (which 
is often costly) and content producer can improve their QoS and can make 
use of a natural load balancing mechanism.

> advances on this: https://eprint.iacr.org/2009/479.pdf

As the authors conclude in this document SHA256 is secure and you will 
currently not find preimage collisions (in acceptable time). I've 
checked the literature for other publications (e.g. have a look at [2]) 
but the result is always the same: no preimage collisions in acceptable 
time.

[2]
Dmitry Khovratovich, Christian Rechberger and Alexandra Savelieva 
(2011). "Bicliques for Preimages: Attacks on Skein-512 and the SHA-2 
family". IACR Cryptology ePrint Archive. 2011:286

> will become eventually weaker.

If SHA256 will become weaker then a new hash algorithm must be used for 
the Cache-NT header (e.g. one of the SHA3 family).

> The cache boxes will need to check the validity of the hash to be able

As long as SHA256 fulfill the requirements of an cryptographic hash 
algorithm then there is no need to check the validity of the hash. 
Otherwise a new hash algorithm must be used (see above).

> - user goes to google.com, but the some.js will contain malicious.js instead.

No, that will not work. The cache system computes the hash value again 
and compares it to the hash value in the Cache-NT header. Only when both 
are equal the cache system will reuse the content for following requests.

> People serving big files a lot of times will get caching right, believe me.

I don't think so. Have look at youtube traffic and how they exclude 
shared caches in operator networks.

> providers, close to the users and deliver content from there.

The problem is not that they serve the content from their boxes, the 
problem is that they disable caching. It's better to serve popular 
contents from within the ISP network (reduced Interdomain traffic, 
faster downloads, better QoS/QoE)

Thanks again for the discussion!

Chris

---

From: Amos Jeffries <[email-masked]>
Date: Sat, 31 May 2014 23:29:16 +1200

> caching is suffering from it.

I was speaking there of the non-use of conditional requests. And the
abuse of 20 status code to perform operations for which other status
codes (3xx) were explicitly created.

As others have repeated. Content providers which are already using URL
and Cookies "incorrectly" despite the available HTTP conditional request
and caching features are not going to change for this.

> very difficult because you don't know how all kinds of CDNs work

Correct use of DNS is to have a single domain name authoritative for
each object. One uniform DNS name may point at several servers or load
balancers or CDN gateways. Causing a single URL to be fetched from any
one of multiple sources in a load balanced fashion while simultaneously
benefiting from existing HTTP caching.

How CDNs operate internally is irrelevant. There is a limited set of API
which the HTTP firendly CDN all present for public access:
 1) URL hostname with multiple A/AAAA records routed to one of many
separate servers.
 2) URL hostname with single A/AAAA record routed to one of multiple
backend servers.

The ones picking the third option of domain sharding are operating
"incorrectly". Getting them to change into one of the above API forms is
easier (being a DNS config file and possibly script change) than getting
them to implement whole new HTTP service stacks.

Note that under your scheme the cache has to down load a copy from each
different URL it sees *in full* before it can confirm the hash assigned
is correct. Only then discard one. So there is no bandwidth savings for
the domain sharding CDNs. Just a benefit of on-disk storage space in the
cache.

I propose that a completely internal SHA-256 de-duplication of cached
contents (or ZFS/XFS backend storage?) on the cache machine itself would
perform equally well for disk savings and has no need of any HTTP level
changes.

> but there is no extra RTT due to negotiation of the hash algorithm.

There does not have to be any lost RTT at all. Simply define that
SHA-256 is that algorithm for your header (Content-SHA256: ??) and the
same criteria for generation you have now.

Any future algorithm changes will need to work out how to integrate (or
make another header name). But that is not a burden on you.

> conditional requests because the cache system will abort the transfer if

The need of conditional requests is to target specific resource
representations (via ETag) and to prevent unwanted content bytes being
sent (via 304 status) and connection closures (via 304 again).

> contents (significant larger than 20KB) like bigger images or videos for

Is that 6% measured for general traffic or in relation to traffic going
through a cache? for server connectison or client connections?
Because web servers tend to benefit from quickly closing persistent
connections and proxy caches from keeping them open.

> absolutely right: re-open the same TCP connection would violate TCP

Either way this restricts the cache to operating with 64K sockets per 15
minute period (the TIME_WAIT on the closed sockets). With 2-4 sockets
per transaction that becomes a hard limit of between 270 and 540
requests per second.

Individual proxy caches today need to service up to 500K requests per
second, and these numbers are only going upward as end-users get better
access technology.

> bring the missing parts.

This is a complete waste of bandwidth. The reason for the range being
requested in the first place is likely to be that the rest is not going
to be requested, and/or that the content is so large that its not worth
getting in full.

> After that the cache can compute the hash value

There is no guaranteed period of low load. Caches are used for example
by Wikipedia, the throughput there is measured in whole TB per second
minute after minute all day long. That is typical of a caching system.
By the time any slack period is encountered it is far too late to do
checksum validation of responses.

Popular objects will have already been requested a great many times and
potentially invalid content delivered to a wide variety of clients. This
is enough of a problem to make the delaying of hash calculation a major
security vulnerability. You have a nasty loop situation here, the
proposed mechanism causes a problem and the workarounds only cause worse
problems.

> In a way I agree. For HTTP/1.0 and HTTP/1.1 my draft is a workaround.

It is an outright regression for the majority of services which properly
use the HTTP protocol caching features.

> representations and they are seldom pipelined.

Do you have any numbers to support that claim? there is no technical
reason in working HTTP for large objects to be treated any differently
than small objects.

> think, can you see side effects?

All the side effects of disabling conditional requests and responses remain.
As does the wasted bandwidth from several RTT worth of traffic being
emitted before transaction termination.
As does the cache corruption and DoS possibilities impicit in the lack
of checksum verification under load. Which is caused directly by this
scheme avoiding existing HTTP mechanisms.

Amos

---

From: Amos Jeffries <[email-masked]>
Date: Sun, 01 Jun 2014 00:05:46 +1200

> to the application layer and results in different URLs for one specific

YouTube is a good case to use here. Numerous people have been working on
ways to cache their content for years. Every time a method is found and
published the YT systems mysteriously change in ways which happen to
break just that published caching mechanism.

In fact the first caching method which I know of having been broken
explicitly by their changes was to identify a SHA hash of the video file
in the URL and cache the file under that hash until another URL was
fetched with the same hash. Sound familiar? these days the videos are
VBR encoded live to avoid hashes being duplicated even for consecutive
requests to the same server with the same URL and HTTP request headers.

What does that tell you about that and similar services willingness to
pick up your proposed mechanism?

> delivery cloud." Proc. of IEEE Hot Topics in Media Delivery Workshop. 2011.

3 years old. YT have changed mechanism at least 3 times since that was
published.

> use of a natural load balancing mechanism.

Those are the same benefits of the existing HTTP mechanisms. There is no
change towards any gain from your proposal in any of those respects.

>>> request

None of this matters. The attackers is free to deliver an arbitrary
compressed (or Range) version of an object stating that it hash is XYZ
on the identity form. The cache is not able to verify the hash accuracy
yet is expected to deliver that object to all clients who request
*other* URLs which have valid hash XZY.

Finding a collision is not required to generate a false "collision".

All an attacker needs to do is:
step 1) request the object they want to attack, see its hash header, and
replay that header on their attack payload object.
step 2) get the cache expiry details (in HTTP headers) of any valid
content at the victum URL,
step 3) fetch the attack URL repeatedly at the time of expiry, until the
attack payload is confirmed cached under the given hash.

 Voila! arbitrary content corruption from time X until the cache has
enough "slow down period" to validate the hash independently.

>>> does

Indeed see above. If the cache does not validate the hash independent of
the sender then it does not even have to go to the bother of hiding its
attack object inside a content-encoding compression the cache does not
understand.

> are equal the cache system will reuse the content for following requests.

"As long as SHA256 fulfill the requirements of an cryptographic hash
algorithm then there is no need to check the validity of the hash".

So surely the cache does not need to re-compute and check the validity
of the hash sent to it?

You contradict yoruself.

>>> stopped

YT are a special case. They are *actively* changing things in ways that
prevent caching. For unexplained reasons.

>>> implementation

The answer then is to get them to stop actively disabling caching and
start using the available caching mechanisms properly. For both their
benefit and everyone elses. This is not a new issue and the problem is
generally one of developer understanding and/or business policy - not
lack of caching mechanisms.

Amos