Skip to content

Caching and HTTP behavior

ernolf edited this page Oct 8, 2026 · 2 revisions

🚀 Caching and HTTP behavior

Tip

TL;DR Public responses are cached for 5 minutes, private ones not. ETag and Last-Modified allow cheap 304 revalidation.

🗄️ Cache-Control

Key Type Default Effect
raw_cache_public_max_age int, seconds 300 max-age for public URLs
raw_cache_public_stale_while_revalidate int, seconds 30 stale-while-revalidate, 0 omits it
raw_cache_public_stale_if_error int, seconds 86400 stale-if-error, 0 omits it
raw_cache_private_no_store bool false adds no-store for private URLs

Resulting headers with the defaults:

URL form Cache-Control
public, /raw/<token>/... public, max-age=300, stale-while-revalidate=30, stale-if-error=86400
private, /raw/u/<user>/... private, max-age=0
private with raw_cache_private_no_store private, no-store, max-age=0

304 Not Modified responses carry the same Cache-Control as a 200, so caches behave the same on revalidation.

🏷️ ETag and Last-Modified

  • The ETag is built from mtime and size. Only when the storage does not report both, it falls back to an MD5 of the content.
  • Last-Modified is sent whenever the mtime is known.
  • If-None-Match is checked first. It accepts lists, weak validators (W/"...") and *.
  • If-Modified-Since is checked only when no ETag matched. It accepts an HTTP date or a plain Unix timestamp, optionally in quotes. A date equal to or newer than the mtime gives 304.
curl -i 'https://cloud.example.com/raw/<token>/file.ext'
curl -i -H 'If-None-Match: "<etag>"' 'https://cloud.example.com/raw/<token>/file.ext'
curl -i -H 'If-Modified-Since: Sun, 25 May 2025 21:40:02 GMT' 'https://cloud.example.com/raw/<token>/file.ext'
curl -i -H 'If-Modified-Since: 1748209203' 'https://cloud.example.com/raw/<token>/file.ext'

<token> is the share token, <etag> the value from the ETag header of the first response.

🍪 Cookie-free responses

Raw responses do not set cookies. An active session is closed, session cookies are disabled for the rest of the request and already queued Set-Cookie headers are removed. A reverse proxy in front of Nextcloud can still add cookies of its own.

📁 Folders and index.html

A URL that points to a folder serves the index.html inside it.

🔎 HEAD requests

HEAD returns the same headers as GET without reading the file content.

🚫 Plain 404

Public URLs answer every failure the same way: unknown token, share without raw access, missing path. The response is a short text/plain Not found with Cache-Control: no-store, so it reveals nothing about which of these applies.

✉️ Content-Type and charset

text/*, application/xml and *+xml types get ; charset=utf-8. For files without an extension, or with the generic type application/octet-stream, the type is detected from the first bytes of the content.

➡️ Next

Webserver offload

Clone this wiki locally