diff options
author | Douwe Maan <douwe@gitlab.com> | 2016-03-07 22:05:15 +0000 |
---|---|---|
committer | Douwe Maan <douwe@gitlab.com> | 2016-03-07 22:05:15 +0000 |
commit | afb8d76f3c7ce51fdab9cf05c4348ac89fc7ee38 (patch) | |
tree | 64faec9f70f64b104a27ae7cab95fa2707f9b317 | |
parent | 903aa7c95e82949ca0a7b18e1f6d2f25fe1b04f4 (diff) | |
parent | a284d307838adf44080c43e4f553fe60b3495ffe (diff) | |
download | gitlab-ce-afb8d76f3c7ce51fdab9cf05c4348ac89fc7ee38.tar.gz |
Merge branch 'cache-raw-2' into 'master'
Set cache headers for raw blobs
This changes allows browsers and (in the case of public projects)
proxy caches to cache raw Git blob responses.
See merge request !3113
-rw-r--r-- | app/controllers/projects/avatars_controller.rb | 3 | ||||
-rw-r--r-- | app/controllers/projects/raw_controller.rb | 2 | ||||
-rw-r--r-- | app/helpers/blob_helper.rb | 21 | ||||
-rw-r--r-- | app/models/blob.rb | 3 | ||||
-rw-r--r-- | app/views/projects/blob/_image.html.haml | 2 |
5 files changed, 30 insertions, 1 deletions
diff --git a/app/controllers/projects/avatars_controller.rb b/app/controllers/projects/avatars_controller.rb index b64dbbd89ce..a6bebc46b06 100644 --- a/app/controllers/projects/avatars_controller.rb +++ b/app/controllers/projects/avatars_controller.rb @@ -7,6 +7,9 @@ class Projects::AvatarsController < Projects::ApplicationController @blob = @repository.blob_at_branch('master', @project.avatar_in_git) if @blob headers['X-Content-Type-Options'] = 'nosniff' + + return if cached_blob? + headers.store(*Gitlab::Workhorse.send_git_blob(@repository, @blob)) headers['Content-Disposition'] = 'inline' headers['Content-Type'] = safe_content_type(@blob) diff --git a/app/controllers/projects/raw_controller.rb b/app/controllers/projects/raw_controller.rb index d9723acb1d9..10de0e60530 100644 --- a/app/controllers/projects/raw_controller.rb +++ b/app/controllers/projects/raw_controller.rb @@ -13,6 +13,8 @@ class Projects::RawController < Projects::ApplicationController if @blob headers['X-Content-Type-Options'] = 'nosniff' + return if cached_blob? + if @blob.lfs_pointer? send_lfs_object else diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb index 7f63a2e2cb4..0f77b3b299a 100644 --- a/app/helpers/blob_helper.rb +++ b/app/helpers/blob_helper.rb @@ -152,4 +152,25 @@ module BlobHelper 'application/octet-stream' end end + + def cached_blob? + stale = stale?(etag: @blob.id) # The #stale? method sets cache headers. + + # Because we are opionated we set the cache headers ourselves. + response.cache_control[:public] = @project.public? + + if @ref && @commit && @ref == @commit.id + # This is a link to a commit by its commit SHA. That means that the blob + # is immutable. The only reason to invalidate the cache is if the commit + # was deleted or if the user lost access to the repository. + response.cache_control[:max_age] = Blob::CACHE_TIME_IMMUTABLE + else + # A branch or tag points at this blob. That means that the expected blob + # value may change over time. + response.cache_control[:max_age] = Blob::CACHE_TIME + end + + response.etag = @blob.id + !stale + end end diff --git a/app/models/blob.rb b/app/models/blob.rb index 8ee9f3006b2..72e6c5fa3fd 100644 --- a/app/models/blob.rb +++ b/app/models/blob.rb @@ -1,5 +1,8 @@ # Blob is a Rails-specific wrapper around Gitlab::Git::Blob objects class Blob < SimpleDelegator + CACHE_TIME = 60 # Cache raw blobs referred to by a (mutable) ref for 1 minute + CACHE_TIME_IMMUTABLE = 3600 # Cache blobs referred to by an immutable reference for 1 hour + # Wrap a Gitlab::Git::Blob object, or return nil when given nil # # This method prevents the decorated object from evaluating to "truthy" when diff --git a/app/views/projects/blob/_image.html.haml b/app/views/projects/blob/_image.html.haml index 3c11b97921f..18caddabd39 100644 --- a/app/views/projects/blob/_image.html.haml +++ b/app/views/projects/blob/_image.html.haml @@ -6,4 +6,4 @@ - blob = sanitize_svg(blob) %img{src: "data:#{blob.mime_type};base64,#{Base64.encode64(blob.data)}"} - else - %img{src: namespace_project_raw_path(@project.namespace, @project, @id)} + %img{src: namespace_project_raw_path(@project.namespace, @project, tree_join(@commit.id, blob.path))} |