diff --git a/puppet/zulip/files/nginx/zulip-include-frontend/uploads-internal.conf b/puppet/zulip/files/nginx/zulip-include-frontend/uploads-internal.conf index 8afaf3ac78..a8a2a70418 100644 --- a/puppet/zulip/files/nginx/zulip-include-frontend/uploads-internal.conf +++ b/puppet/zulip/files/nginx/zulip-include-frontend/uploads-internal.conf @@ -43,6 +43,16 @@ location ~ ^/internal/s3/(?[^/]+)/(?.*) { # the first response. Django explicitly unsets the first, and # does not set the latter two. + # We slice the content into 5M chunks; this means that the client + # doesn't need to wait for nginx to download and cache the full + # content if the client just requested a small range (e.g. for + # showing a thumbnail of a large video). 5M is chosen to be + # enough for videos to be able to thumbnail in one slice, but not + # take overly long to retrieve from S3, or cause overwhelming + # numbers of cache entries for large files. + slice 5m; + proxy_set_header Range $slice_range; + proxy_pass $download_url$is_args$args; proxy_cache uploads; # If the S3 response doesn't contain Cache-Control headers (which @@ -50,12 +60,12 @@ location ~ ^/internal/s3/(?[^/]+)/(?.*) { # long time. The size of the cache is controlled by # `s3_disk_cache_size` and read frequency, set via # `s3_cache_inactive_time`. - proxy_cache_valid 200 1y; + proxy_cache_valid 200 206 1y; - # We only include the requested content-disposition in the cache - # key, so that we cache "Content-Disposition: attachment" - # separately from the inline version. - proxy_cache_key $download_url$s3_disposition_cache_key; + # We only include the requested content-disposition (and range + # slice) in the cache key, so that we cache "Content-Disposition: + # attachment" separately from the inline version. + proxy_cache_key $download_url$s3_disposition_cache_key$slice_range; } # Internal file-serving