Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouwe Maan <douwe@gitlab.com>2016-03-08 01:05:15 +0300
committerDouwe Maan <douwe@gitlab.com>2016-03-08 01:05:15 +0300
commitafb8d76f3c7ce51fdab9cf05c4348ac89fc7ee38 (patch)
tree64faec9f70f64b104a27ae7cab95fa2707f9b317
parent903aa7c95e82949ca0a7b18e1f6d2f25fe1b04f4 (diff)
parenta284d307838adf44080c43e4f553fe60b3495ffe (diff)
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.rb3
-rw-r--r--app/controllers/projects/raw_controller.rb2
-rw-r--r--app/helpers/blob_helper.rb21
-rw-r--r--app/models/blob.rb3
-rw-r--r--app/views/projects/blob/_image.html.haml2
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))}