Skip to content

feat: let the content app return 304 Not Modified for unchanged files - #7995

Open
carlosthe19916 wants to merge 1 commit into
pulp:mainfrom
carlosthe19916:add-if-modified-since-content-app
Open

feat: let the content app return 304 Not Modified for unchanged files#7995
carlosthe19916 wants to merge 1 commit into
pulp:mainfrom
carlosthe19916:add-if-modified-since-content-app

Conversation

@carlosthe19916

@carlosthe19916 carlosthe19916 commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Summary

  • After content guards allow the request, the content app can answer If-Modified-Since with 304 Not Modified and no body, so an edge cache can keep its copy instead of downloading the file again.
  • Last-Modified is when that unit joined the served repository version (RepositoryContent.pulp_created). Disk mtime moves on copy/restore, and the version’s created time would make every cached file look stale on each publish.
  • This only applies when Pulp sends the bytes (filesystem or ArtifactResponse). Object-storage 302s get neither Last-Modified nor Cache-Control: public, because a signed URL must not be stored or reused as if it were the file.

Fixes #7929.

Guards still run first. A matching If-Modified-Since is 304; otherwise the response is 200 with Last-Modified and the body. If there is no membership row (publish-generated metadata, remote-only distribution), Pulp omits Last-Modified and never returns 304.

Artifact 200s and 304s include Cache-Control: public, max-age=0, must-revalidate so the edge revalidates on every use. Plugins can still override headers with content_headers_for. This change does not add ETag.

_serve_ca is the single place that looks up the timestamp and may 304 (published files, pass-through, repository versions, plugin content_handler(), grace-period fallback, pull-through). Grace-period fallback uses the old publication’s version so the timestamp is not the current one. On-demand streams 304 before opening the remote. A stream that has already started writing is never turned into a 304.

aiohttp’s FileResponse would overwrite Last-Modified with disk mtime. PulpFileResponse stops that, does not send a disk-time ETag, and does not clear If-Range.

When Redis is on, the handler returns a cacheable 200 and the cache layer owns the 304: it stores last_modified, 304s a hit without rebuilding the response, and never writes a 304 into Redis.

Not in this PR: 304 on S3/Azure/GCS redirects, ETag / If-None-Match, or a fallback timestamp for metadata with no membership row.

Test plan

  • Handler: 200 vs 304; no handler 304 when Redis is on; 302s stay unmodified; 304 beats an unsatisfiable Range; on-demand 304 before the remote fetch; timestamp from repository membership
  • PulpFileResponse does not 304 on file mtime and does not clear If-Range
  • Redis stores last_modified, 304s a hit without rebuilding, and never caches a 304

@carlosthe19916
carlosthe19916 force-pushed the add-if-modified-since-content-app branch 3 times, most recently from 2246d02 to 95c8958 Compare August 20, 2026 14:05
@carlosthe19916
carlosthe19916 force-pushed the add-if-modified-since-content-app branch 3 times, most recently from 2e9b68b to a193f54 Compare August 21, 2026 08:44
run, without downloading the file again. Last-Modified is
RepositoryContent.pulp_created for the served version, not disk mtime.
Filesystem and ArtifactResponse get Cache-Control: public, max-age=0,
must-revalidate; object-storage 302s do not. Redis can 304 from a
cached last_modified without rebuilding the body.

Signed-off-by: Carlos Feria <2582866+carlosthe19916@users.noreply.github.com>
@carlosthe19916
carlosthe19916 force-pushed the add-if-modified-since-content-app branch from a193f54 to 46bc167 Compare August 21, 2026 09:20
@carlosthe19916
carlosthe19916 marked this pull request as ready for review August 21, 2026 09:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add If-Modified-Since / 304 Not Modified support to the content app

1 participant