Transcript
This transcript was autogenerated. To make changes, submit a PR.
Hello everybody, thanks for joining me to this conference.
For the next 30 minutes we will talk together about
the past, the present, and the future of the HTTP cache.
Let's see together how to accelerate your APIs or your
web writes using only the HTTP features. So first let
me introduce myself. My name is Silver Kombrak. I'm a
freelance goling architect and the creator
of the HTTP cache tool
called Swamp. I'm also a french baguette, so sorry for my baguette
accent. And I'm the maintainer
of the Caddy cache on lure module and
an active open source contributor. By the way, you can find me on GitHub
caching Darkwick and on Twitter searching Darkwick underscore
dev. So we have to go back in time.
Near the end of 1998,
HTTP 10 was released for two years,
but the chaos between each providers, like Google
or Akamai because of HTTP 10
wasn't as extensible as they wanted. So they implemented
some other features on their own way, and it was really
painful to support each provider, all providers with
all of their features and all of their specific features.
So HTTP 1.0 didn't explain in depth
what is a request, a response, an HTTP either,
or a comment in your
HTTP request, for example. And it didn't explain
the way to handle and manage the incoming data
or what is prohibited, and let the providers be
free of the implementation. In June 1999,
Matrix, the first movie was released to theaters.
We discovered Neo and the red
and blue pills. Meanwhile,
webfathers started to write and release
an RFC to standardize. HTTP 1.1
RFC is for request for comments, and it's like a big
budget blog that define how a protocol
must work and
its code is RFC 20 616
or also known as HTTP
1.1 was. It's the very first
RFC to really standardize things. It will define the
grammar. So what's an HTTP eater,
what resource identifier and
on UI that tells one URL must match to one
thing on your server. It will also define what is an HTTP
request, how to build it,
which parts can receive comments, which parts must be
by the server, and it defines most of the HTTP
users always used nowadays. More specifically
in this RFC, there is an interesting part
about the caching in HTTP, and it's
the first try to standards that and it starts with the following
sentence. Caching would be useless if it
didn't significantly improve
performances. That means if your cache server responds slower
than your upstream,
you don't need this cache server.
But nowadays there are some other points
if your cache server is more energy energy
consuming than the upstream,
or is more cost expensive
than the upstream. You may not need a cache server too.
We can't only take in consideration the power and the speed
to serve the data, as it's the first standard,
there are some missing points, like the
following. If a stored
response is not fresh enough, the cache may still return
the response with the appropriated
warning eater first.
Who knew the warning HTTP
either existence to be
honest, I discovered that by reading this rfc,
and I'm pretty sure most of recent applications
doesn't choose that either. But that's a back
order from the past.
And the most weird part is that the cache can return a
not fresh enough response,
so you are free to return a cache response to
your client, even if it's considered as Taylor
the RFC 20 616 introduced
the cache control HTTP Eater and its own directives.
There are the common directives that can be used in the request and
the response context. The wellknown no cache directive
won't use a cache response in the request context, and won't
store the specified response either. In the response context,
the no store directive won't store the upstream
response. The max edge will tell to the
cache server to store that for at most x
seconds in the response context and in the request context,
it should return the cache response only if it's stored
for less than x seconds. The not transform directive
will tell to the cache to not try to transform the request
or the response. Depending the context. It should
not remove or add extra editors and not
try to jzip the response to reduce its
size. The request or the response must stay unchanged.
The HTTP request cache control directive contains
the max tail to explain okay, you can serve a stale response
that means not fresh enough and is
that stale since x
second less than x second.
The Minfresh directive is not really used in production
because it's here to be able to tell to the cache okay,
serve the stored response only if it's stored since
at least x seconds, so you cannot
have a stored response that is fresher
than x second. I don't have the use case for
that I don't know,
and only if cached directive
serves the cached response only if it's present in the storage.
So if your storage was
a storage response, it will serve it even if it's
tail or anything else. The HTTP response cache
control directive contains the public that ensure
the response can be stored by the shared cache,
and opposed to that, the private that can be
stored only by the private caches. Like the browser,
the must and proxy will revalidate
the response with the upstream and if no errors
appears, it will return the stored response to the
client and the fmaxage will manage
the stored duration on shared cache. There is a
last directive named cache extension.
This directive allows the user to add more custom directives
only understood by the cache system itself.
The first example, add the
extension community with the value UCI.
The cache system could increase the
time to live for the response storage
if the value is UCI, for example.
And that's the same for only if my case match
with the given value that
should. So during the summer 2001
major improvement has been made.
That's not the loft winners,
but that's ESI language.
To be honest, this is not a validated rfc,
but it's currently accepted by the w three
C and integrated in most of your
CDN or cache servers. The ESI
language allows the templates,
cache the templates and only request the dynamic parts.
In this example we request the article
HTML content and this page have a
static article and a dynamic header
called user PHP. The ESI
processor here varnish will get from its cache
the article HTML file, parse it,
and will see there is an ESI tag and will process
it. It will send a request to the user PHp
endpoints on the upstream server, grab the response and replace
in the article HTML body the
ASI tag by the user php received value
if you already wrote some HTML, you'll find that
easy to use. And as the tag is not understood
by the browser, it won't be shown to the end user
or display an additional div if it cannot be processed.
So it's really transparent to the user unless
it tries to read the source code of the received
HTML file. Here the ESI include
tag will request the source attribute
here example one HTML
if it throws an error while doing the request this
request, it will request the alternateback example
two HTML and if we set the on
error property with the value continue, it will just ignore
the errors. A more complex one we
can do some try catches the ESI
try will try was its
name the attempt sub block if can error
occurs in this block, it will just process the ESI
accept tag. You can see at
the lines three and seven some ESI
comments that should be removed by the ESI
processor. Even you return them
to the browser. Even if you return them
to the browser, it will only increase the body
size, but your browser won't interpret them,
won't display them, et cetera. You can also load some variables
from the request and more precisely from the request cookies or
request host request path and some
predefined variables.
And using the ESI vars,
sorry, we will generate the image
HTML tag. The computed source will take
the value from the cookie name type.
Imagine we set human as a value in the type
cookie, your source and your alt will
contain and your user, your end user will
see only the computed image HTML tag.
So that's demo time.
So that is demo time to show you a
more complex example and to prove that very powerful.
So I will use caddy was
a proxy. So here is caddy file
here up.
My proxy will be running on the HTTP port.
I said okay that's 80 and the
common HTTP port and
I have some routes that return ESI tags
here I have a server route
to proxy to a server.
The request that will serve also its
own HTML
or HTTP response and
all unmatched pattern
here will
try to load the features and will compute the response
because of the ESI directive in the woodblock here
that's cadify syntax. But it's really easy to understand
and it's easier than the Nginx config
or Apache configuration.
Okay, in the features I
have the complex example here named full
HTML that contains all
ESI tags. We have some variables interpretations,
some include some escaped contents and many
other cases. So if I run the caddy
server here make run,
okay it will take some seconds
to build that, I think.
And it run it here. So my Kg
is running and here make run
server. So it will go in the
middleware and just run main
go for make run server and in Kadi it will
run, make run here make build and
make run. So it will build the ESi
module for KG from the sources.
So I have my two servers
here and if I try
to request it, I can now send
can HTTP request to the servers pass for example.
So httpdomain.com,
that's a local domain. I edited
my host on
my laptop for that. And if
I send on server,
yes I would
like you to use curl for that.
So it returns the readers because
in the main go I'm flushing the
response each time I'm writing something and I
wait 9 seconds in total and
it will take whats HTML
code and we'll pass the ESI include
here, here it's an escaped content
from ESI and I'm removing
this include and I'm using HTTP host
here. So we have that in the response and
the more complex example because here it's
a bit simple I can
say okay, try to load full HTML
and okay,
why?
Okay, it's the
demo effect. I think we
will debug that together.
Why that's
this port here
and if I retry it works.
Okay, so it works and
I have my tags and other things.
Okay,
I think I show you
everything so
I hope you enjoyed the demo. So we
we will jump some years later and
go at the summer 2014.
That's the year the new
Zelda EwOL warriors was released
also. But some
people prefer to write and publish RFC during
their holidays instead of chilling.
And the RFC
724434 2014
sorry as
known as the HTTP one one caching
will add more context and more details and
more use cases to the previous caching RFC
and will invalidate them.
First of all, we got a new HTTP response
eater called age.
The age Eater explicits the number of seconds
the response is stored. The second example should
not occur. It should take the max between your
edge, your either edge and
zero so
it details the cache invalidation.
Imagine you store your getresponse because it has
to contact the database and that's IO consuming, et cetera.
If you build an rest API, you'll have
the same path but only the verb differ to
manage your resource. If you send a
get request on books one, for example,
you will store your response and after that
if you send one of put, post or delete HTTP
request on your resource, you'll have to invalidate your stored getresponse
for this resource id because these HTTP verbs
will alterate your stored resource.
This RFC adds a new HTTP request cache
control directive named Stalewire validate.
This one allows the cache server to serve a stale response
and try to revalidate in the background with the upstream
and store the freshly response and replace the stale one
that ensure client will receive data even
if your upstream is done. Add this leader to every request
when you think it's okay, even if your clients have some stale
data. In June 2022
I was in Greece, but Mark Notingham decided to release
two rfcs to the cache status RFC
and the targeted cache control HTTP Eater
about the cache status Eder.
It defines some useful directives. The first one is
it and I missed that.
You can now detect if it was it
by your cache server or missed
forward. Add more context about the cache server that
forwards the request to the upstream forward statues returns
the statues from the upstream or another cache server.
The TTL shows how many seconds the cache
response will be considered as fresh.
By the way, the edge eater
plus the TTL should be equal to your storage duration
and must be equal to that. The collapsed
directive tell you if the response has been built from one
part of the cache response and the second part from
the upstream. For example the
key give you the stored
key in your cache index and the detail give you
some details from. For example, if it's not stored
because the response storage is unreachable,
so the cache whats you see there is like that.
You have your server cache name if
it's it or not. If it's it,
you have a TTL, you can have the key,
et cetera.
And in the last one example you have the case that
the storage is unreachable.
Now the targeted cache control RFC allow
you to manage automatically the cache control.
Imagine this infrastructure. Your client
would send a request to your servers. His request
goes through the CDN and it will proxy
to your varnish cache server.
It will send the request to your CAD instance that will
transfer to the upstream so
the upstream returns a response
with four headers, the well known cache control,
the CDN cache control, the varnish cache control,
and the KD cache control with
their own duration, their own storage
directive. Imagine you can have
for the CDN cache control private directive,
and the caddy instance will check if
the Caddy cache controller is present and will store
the response for 1 hour. Then varnish
will store for five minutes and the CDN will store
for will store the response for two minutes,
and the client will store that, but won't use it because of the no cache
directive. And if the
wildcard cache control either is
present and interpreted by your cache.
For example, imagine varnish doesn't recognize
the varnish cache control. It should, and it must fall back
on the basic cache control either.
And here our clients will
store it, but won't use it because of the no cache.
Okay, thank you for your attention.
Thank you to the organizers team. Don't hesitate
to ask your question if you have any, and I hope you
found that interesting.