Skip to content

Commit

Permalink
Merge pull request #24 from zazuko/http-purge
Browse files Browse the repository at this point in the history
Purge cache entry using `PURGE` HTTP method
  • Loading branch information
ludovicm67 authored Apr 23, 2024
2 parents 527ede6 + 0a37f35 commit 98b64dd
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 16 deletions.
5 changes: 5 additions & 0 deletions .changeset/violet-lizards-chew.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"varnish-post": minor
---

Support `PURGE` method to purge the cache
26 changes: 16 additions & 10 deletions config/default.vcl
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ vcl 4.1;
import std;
import bodyaccess;

# this is the backend that should be cached
# Backend server that should be cached
backend default {
.host = "$BACKEND_HOST";
.port = "$BACKEND_PORT";
.first_byte_timeout = $BACKEND_FIRST_BYTE_TIMEOUT;
}

# remove cookies from response
# Remove cookies and other non-cache-friendly headers from the backend response
sub vcl_backend_response {
if (beresp.http.Cache-Control) {
unset beresp.http.Cache-Control;
Expand All @@ -22,20 +22,25 @@ sub vcl_backend_response {

set beresp.ttl = $CACHE_TTL;

# handle errors
# Decide not to cache error responses
if ($DISABLE_ERROR_CACHING && beresp.status >= 400) {
# send requests directly to the backend for the next ttl period
set beresp.ttl = $DISABLE_ERROR_CACHING_TTL;
set beresp.uncacheable = true;
return (deliver);
}
}

# remove incoming cookies and allow caching POST requests
# Handles incoming requests and removes incoming cookies
sub vcl_recv {
unset req.http.X-Body-Len;
unset req.http.cookie;

# Handle PURGE requests
if (req.method == "PURGE") {
return (purge);
}

# Caching POST requests by caching the request body
if (req.method == "POST") {
std.cache_req_body($BODY_SIZE);
set req.http.X-Body-Len = bodyaccess.len_req_body();
Expand All @@ -52,12 +57,12 @@ sub vcl_recv {
return (hash);
}

# https://docs.varnish-software.com/tutorials/caching-post-requests/#step-3-change-the-hashing-function
# Alter the hashing method to include POST bodies
# See: https://docs.varnish-software.com/tutorials/caching-post-requests/#step-3-change-the-hashing-function
sub vcl_hash {
hash_data(req.http.Authorization);
hash_data(req.url);

# to cache POST and PUT requests
if (req.http.X-Body-Len) {
bodyaccess.hash_req_body();
} else {
Expand All @@ -67,16 +72,17 @@ sub vcl_hash {
return (lookup);
}

# https://docs.varnish-software.com/tutorials/caching-post-requests/#step-4-make-sure-the-backend-gets-a-post-request
# Adjust the request method in the backend fetch phase
# See: https://docs.varnish-software.com/tutorials/caching-post-requests/#step-4-make-sure-the-backend-gets-a-post-request
sub vcl_backend_fetch {
if (bereq.http.X-Body-Len) {
set bereq.method = "POST";
}
}

# add a header to see if it was a cache miss or a cache hit
# Indicate whether the response was served from cache or not
# See: https://happyculture.coop/blog/varnish-4-comment-savoir-si-votre-page-vient-du-cache
sub vcl_deliver {
# https://happyculture.coop/blog/varnish-4-comment-savoir-si-votre-page-vient-du-cache
if (resp.http.X-Varnish ~ "[0-9]+ +[0-9]+") {
set resp.http.X-Cache = "HIT";
} else {
Expand Down
2 changes: 0 additions & 2 deletions test/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
version: "3"

services:
backend:
build: ./app
Expand Down
20 changes: 16 additions & 4 deletions test/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ BACKEND_ENDPOINT="http://localhost:8080"
CACHED_ENDPOINT="http://localhost:8081"

# build and start the stack
docker-compose build
docker-compose up -d
docker compose build
docker compose up -d

# Some useful functions

# Display error message and exit
## $1: error message to display
error () {
echo "ERROR: $1" >&2
docker-compose down
docker compose down
exit 1
}

Expand Down Expand Up @@ -220,8 +220,20 @@ if [ "${res1}" -ge "${res2}" ]; then
error "timestamp is not increasing"
fi

info "Check if we can purge a cache entry…"
sleep 3
# do a request after TTL to invalidate the cache
res_tmp=$(fetch_time "${CACHED_ENDPOINT}")
res1=$(fetch_time "${CACHED_ENDPOINT}")
sleep 1
curl -sL -X PURGE "${CACHED_ENDPOINT}" >/dev/null
res2=$(fetch_time "${CACHED_ENDPOINT}")
if [ "${res1}" -eq "${res2}" ]; then
error "cache was not purged"
fi


# If we are at this point, no test failed
info "All tests passed :)"
docker-compose down
docker compose down
exit 0

0 comments on commit 98b64dd

Please sign in to comment.