-
-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Description
How to use GitHub
- Please use the 👍 reaction to show that you are interested into the same feature.
- Please don't comment if you have no relevant information to add. It's just extra noise for everyone subscribed to this issue.
- Subscribe to receive notifications on status change and new comments.
Is your feature request related to a problem? Please describe.
When sharing a file or folder via a public link, Nextcloud serves the download in a way that does not enable functioning caching. It sets cache-control: must-revalidate, post-check=0, pre-check=0, which asks browsers to revalidate each request (which could be okay), but it does not set last-modified or etag, and it does not respect if-modified-since or if-none-match requests.
For an image file preview of a public share, caching works: cache-control includes a max-age, the last-modified response header gives the date the preview was first requested (I assume), and conditional requests with a recent enough if-modified-since return status 304.
(On a side note, "pragma: no-cache" in the response is deprecated, and "post-check" and "pre-check" were never standardized in the "cache-control" header.)
Describe the solution you'd like
The PublicPreviewController uses a FileDisplayResponse to serve the file preview with proper cache control.
Something similar would be nice for the ShareController. That is, instead of forbidding caching in sendHeaders, set the last-modified header to the file modification date and possibly set an etag, and return a 304 response in getSingleFile when appropriate.
Describe alternatives you've considered
My use case is to embed shared files in web pages. The alternative would be to set up a web server to serve static files. Using Nextcloud to do so is not very efficient, but can be handy. For this, it would be useful to avoid needless re-requests of downloads by clients.
Additional context
Simulation of getting a preview URL for the first time:
$ curl -I 'https://SERVER/index.php/apps/files_sharing/publicpreview/SHAREID?file=/&fileId=FILEID&x=1920&y=1200&a=true&etag=ETAG'
HTTP/2 200
date: Fri, 17 May 2024 17:38:01 GMT
pragma: no-cache
x-request-id: ZkeV-S6ejSRIelV3YpDT0wAAAQc
cache-control: private, max-age=86400, must-revalidate
content-security-policy: default-src 'none';base-uri 'none';manifest-src 'self';frame-ancestors 'none'
feature-policy: autoplay 'none';camera 'none';fullscreen 'none';geolocation 'none';microphone 'none';payment 'none'
x-robots-tag: noindex, nofollow
content-disposition: inline; filename="512-512-max.jpg"
expires: Sat, 18 May 2024 17:38:01 +0000
set-cookie: SOME COOKIES
referrer-policy: no-referrer
x-permitted-cross-domain-policies: none
x-xss-protection: 1; mode=block
last-modified: Fri, 17 May 2024 14:20:28 GMT
etag: "98ce490be53325b5f254d210cbab4624"
content-length: 60210
content-type: image/jpeg
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
strict-transport-security: max-age=31536000
Simulation of getting a preview URL for the second time:
$ curl -I 'https://SERVER/index.php/apps/files_sharing/publicpreview/SHAREID?file=/&fileId=FILEID&x=1920&y=1200&a=true&etag=ETAG' -H 'If-Modified-Since: Fri, 17 May 2024 17:38:01 GMT'
HTTP/2 304
(followed by all the same headers as before)
Getting a download URL:
$ curl -I 'https:/SERVER/index.php/s/SHAREID/download/test.jpg'
HTTP/2 200
date: Fri, 17 May 2024 17:41:41 GMT
content-security-policy: default-src 'self'; script-src 'self' 'nonce-NONCE'; style-src 'self' 'unsafe-inline'; frame-src *; img-src * data: blob:; font-src 'self' data:; media-src *; connect-src *; object-src 'none'; base-uri 'self';
pragma: no-cache
content-disposition: attachment; filename*=UTF-8''test.jpg; filename="test.jpg"
content-transfer-encoding: binary
expires: 0
cache-control: must-revalidate, post-check=0, pre-check=0
x-accel-buffering: no
set-cookie: SOME COOKIES
referrer-policy: no-referrer
x-permitted-cross-domain-policies: none
x-robots-tag: noindex, nofollow
x-xss-protection: 1; mode=block
content-length: 63834
content-type: image/jpeg
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
strict-transport-security: max-age=31536000
Adding an if-modified-since to the last request does not change the outcome.