Hoofdstuk 8
Caching en voorwaardelijke verzoeken
Mag ik dit antwoord hergebruiken?
Hoofdstuk 7 liet de leeslijst beschermd achter: een sessie zegt wie er is ingelogd, en alleen het token van een schrijver mag een boek wijzigen. Elke client downloadt echter nog steeds de hele GET /books te sturen. De boeken veranderen een paar keer per dag, dus bijna elk antwoord herhaalt het vorige byte voor byte. De server bouwt dezelfde
Het antwoord van
De vier directieven
Die header is Cache-Control. De cache-control: max-age=60, private. Een directief is een naam, soms gevolgd door = en een waarde. Vier ervan dekken het meeste van wat servers zeggen:
| Directief | Wat een client mag doen met een kopie die hij heeft bewaard |
|---|---|
max-age=N | hem zonder te vragen hergebruiken tot hij N seconden oud is; daarna is hij verlopen |
no-cache | hem bewaren, maar vóór elk hergebruik de server vragen |
no-store | hem helemaal niet bewaren |
private | een cache die één gebruiker bedient, mag hem bewaren; een gedeelde cache die veel gebruikers bedient, niet |
Een cache is alles wat antwoorden bewaart om ze te hergebruiken. Je client krijgt er in les 5 een, en die bedient één gebruiker: wie hem ook draait. Een gedeelde cache zit tussen veel clients en een server, bijvoorbeeld een proxy van een bedrijf, en geeft één opgeslagen antwoord aan iedereen die om dezelfde private: een antwoord met de gegevens van één persoon mag niet aan de volgende persoon worden gegeven. Deze cursus draait geen gedeelde cache; je hoeft het woord alleen te herkennen.
no-cache is het directief waarvan de naam misleidt. Het betekent niet “niet cachen”. Het betekent “je mag hem bewaren, maar vraag het mij voordat je hem gebruikt”. Navragen kost weinig, zoals les 4 laat zien, omdat de server “nog steeds hetzelfde” kan antwoorden zonder de body opnieuw te sturen. no-store is het directief dat “bewaar hem niet” betekent, en een server stuurt het mee met antwoorden die nooit in een cache horen te staan, zoals een antwoord dat noemt wie er is ingelogd. Les 6 zet het precies op die antwoorden.
Namen van directieven zijn niet hoofdlettergevoelig (RFC 9111, sectie 5.2), dus Max-Age=60 betekent hetzelfde als max-age=60. Een antwoord kan ook meer dan één regel cache-control dragen, en samen vormen die één lijst. In echte antwoorden kom je andere directieven tegen, zoals public, must-revalidate en s-maxage; deze cursus gebruikt ze niet.
De header lezen
Een Cache-Control-waarde lezen is splitsen bij komma’s, zoals hoofdstuk 1
Wat drukt dit af?
print("max-age=60, private".split(","))
Het tweede stuk begint met een spatie, omdat de spatie na de komma bij geen enkel directief hoort. Daarom wordt elk stuk gestript voordat het wordt vergeleken, en in kleine letters gezet, omdat de namen hoofdletters negeren. Voer dit uit:
Verander value in "no-store" of in "private,max-age=5" en voer het opnieuw uit. De stukken komen er hetzelfde uit, of er nu een spatie na de komma staat of niet.
Expires en de regel Date
Voordat Cache-Control bestond, zei een server met de header expires hoe lang een antwoord goed bleef. Die bevat een datum en een tijd, geen aantal seconden, in het HTTP-datumformaat: hetzelfde formaat als de regel Date die http.server op elk antwoord van je server zet. De email.utils van Python schrijft dat formaat:
import email.utils
print(email.utils.formatdate(0, usegmt=True)) # Thu, 01 Jan 1970 00:00:00 GMT
0 is de eerste seconde van time.time() teruggeeft. http.server schrijft zijn regel Date met dezelfde
Een datum heeft een zwakte die een aantal seconden niet heeft: hij werkt alleen als de klok van de client het eens is met die van de server. Als een antwoord beide draagt, wint dus max-age. RFC 9111 (sectie 5.3) zegt een cache expires te negeren zodra max-age aanwezig is. Je ziet expires nog steeds op echte antwoorden, meestal naast een max-age die voor nieuwere clients hetzelfde zegt. Je server stuurt alleen max-age.
Een antwoord draagt cache-control: no-cache. Mag de client het antwoord bewaren?
Wat staat cache-control: private toe?
Een antwoord heeft expires een uur vooruit en cache-control: max-age=60. Hoe lang is het vers?
Hergebruik is de helft van het verhaal. Als een opgeslagen kopie verloopt, moet de client nog steeds de hele body opnieuw downloaden, ook als er niets in veranderd is. De volgende lessen laten een client vragen “is het veranderd?” en een kort antwoord ontvangen, en die vraag heeft een naam nodig voor één versie van een body. Les 2 maakt die naam: een vingerafdruk berekend uit de bytes van de body.