#############################################################################
# setup a static directory with ETag caching
static_dir = file.path(tempdir(), "static")
if (!dir.exists(static_dir)) dir.create(static_dir)
file_path = file.path(static_dir, "example.txt")
writeLines("Hello World", file_path)
# get the time the file was last modified in UTC time
last_modified = as.POSIXlt(file.info(file_path)[["mtime"]], tz = "UTC")
file_hash = digest::digest(file = file_path, algo = "crc32")
time_fmt = "%a, %d %b %Y %H:%M:%S GMT"
#############################################################################
# setup the Application with the ETag Middleware
app = Application$new()
app$append_middleware(ETagMiddleware$new())
app$add_static(path = "/", static_dir)
#############################################################################
# Example Requests
# Request the file returns the file with ETag headers
req = Request$new(path = "/example.txt")
# note that it also returns the Last-Modified and ETag headers
app$process_request(req)
# provide matching hash of the file in the If-None-Match header to check Etag
# => 304 Not Modified (Can be cached)
req = Request$new(path = "/example.txt",
headers = list("If-None-Match" = file_hash))
# note status_code 304 Not Modified
app$process_request(req)
# provide a wrong hash, returns the file normally
req = Request$new(path = "/example.txt",
headers = list("If-None-Match" = "WRONG HASH"))
app$process_request(req)
# alternatively, you can provide a timestamp in the If-Modified-Since header
# => 304 Not Modified (Can be cached)
modified_since = format(last_modified + 1, time_fmt)
req = Request$new(path = "/example.txt",
headers = list("If-Modified-Since" = modified_since))
app$process_request(req)
# provide both headers: If-None-Match takes precedence
# in this case:
# - if none match => modified (No cache)
# - if modified since => NOT MODIFIED (cached)
# => Overall: modified = no cache
modified_since = format(last_modified + 1, time_fmt)
req = Request$new(path = "/example.txt",
headers = list("If-None-Match" = "CLEARLY WRONG",
"If-Modified-Since" = modified_since))
app$process_request(req)
# provide matching hash of the file in the If-Match header to check Etag
# => 412 Precondition Failed
req = Request$new(path = "/example.txt",
headers = list("If-Match" = "OTHER HASH"))
# note status_code 412 Precondition Failed
app$process_request(req)
# Use If-Unmodified-Since
unmodified_since = format(last_modified - 1, time_fmt)
req = Request$new(path = "/example.txt",
headers = list("If-Unmodified-Since" = unmodified_since)
)
# note status_code 412 Precondition Failed
app$process_request(req)
#############################################################################
# use an alternative hash function (use name of the file)
hash_on_filename = function(x) x
# also use an alternate last_modified time function
always_1900 = function(x) as.POSIXlt("1900-01-01 12:34:56", tz = "GMT")
# setup the app again
app = Application$new(middleware = list(
ETagMiddleware$new(hash_function = hash_on_filename,
last_modified_function = always_1900)
))
app$add_static(path = "/", file_path = static_dir)
# test the requests
req = Request$new(path = "/example.txt")
(res = app$process_request(req))
filename = res$body[["file"]]
req = Request$new(path = "/example.txt",
headers = list("If-None-Match" = filename))
app$process_request(req)
Run the code above in your browser using DataLab