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
path: root/lib
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-09-24 15:06:20 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2019-09-24 15:06:20 +0300
commit9c8edcd6163f03b5ffe3af3c8fbe0706e80c4306 (patch)
tree3acfff342020d2c5e18da300b9292318bdb3aefe /lib
parentbc89882970d6a14b1f72eb9c715fae90b26d066c (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'lib')
-rw-r--r--lib/banzai/filter/relative_link_filter.rb116
-rw-r--r--lib/gitlab/gitaly_client/blob_service.rb34
2 files changed, 130 insertions, 20 deletions
diff --git a/lib/banzai/filter/relative_link_filter.rb b/lib/banzai/filter/relative_link_filter.rb
index e8001889ca3..8799b0b9a80 100644
--- a/lib/banzai/filter/relative_link_filter.rb
+++ b/lib/banzai/filter/relative_link_filter.rb
@@ -20,16 +20,12 @@ module Banzai
def call
return doc if context[:system_note]
- @uri_types = {}
clear_memoization(:linkable_files)
- doc.search('a:not(.gfm)').each do |el|
- process_link_attr el.attribute('href')
- end
+ load_uri_types
- doc.css('img, video').each do |el|
- process_link_attr el.attribute('src')
- process_link_attr el.attribute('data-src')
+ linkable_attributes.each do |attr|
+ process_link_attr(attr)
end
doc
@@ -37,16 +33,81 @@ module Banzai
protected
+ def load_uri_types
+ return unless linkable_files?
+ return {} unless repository
+
+ clear_memoization(:linkable_attributes)
+
+ @uri_types = request_path.present? ? get_uri_types([request_path]) : {}
+
+ paths = linkable_attributes.flat_map do |attr|
+ [get_uri(attr).to_s, relative_file_path(get_uri(attr))]
+ end
+
+ paths.reject!(&:blank?)
+ paths.uniq!
+
+ @uri_types.merge!(get_uri_types(paths))
+ end
+
def linkable_files?
strong_memoize(:linkable_files) do
context[:project_wiki].nil? && repository.try(:exists?) && !repository.empty?
end
end
- def process_link_attr(html_attr)
- return if html_attr.blank?
- return if html_attr.value.start_with?('//')
+ def linkable_attributes
+ strong_memoize(:linkable_attributes) do
+ attrs = []
+
+ attrs += doc.search('a:not(.gfm)').map do |el|
+ el.attribute('href')
+ end
+
+ attrs += doc.search('img, video').flat_map do |el|
+ [el.attribute('src'), el.attribute('data-src')]
+ end
+
+ attrs.reject do |attr|
+ attr.blank? || attr.value.start_with?('//')
+ end
+ end
+ end
+
+ def get_uri_types(paths)
+ return {} if paths.empty?
+
+ uri_types = Hash[paths.collect { |name| [name, nil] }]
+
+ get_blob_types(paths).each do |name, type|
+ if type == :blob
+ blob = ::Blob.decorate(Gitlab::Git::Blob.new(name: name), project)
+ uri_types[name] = blob.image? || blob.video? ? :raw : :blob
+ else
+ uri_types[name] = type
+ end
+ end
+
+ uri_types
+ end
+
+ def get_blob_types(paths)
+ revision_paths = paths.collect do |path|
+ [current_commit.sha, path.chomp("/")]
+ end
+
+ Gitlab::GitalyClient::BlobService.new(repository).get_blob_types(revision_paths, 1)
+ end
+
+ def get_uri(html_attr)
+ uri = URI(html_attr.value)
+ uri if uri.relative? && uri.path.present?
+ rescue URI::Error, Addressable::URI::InvalidURIError
+ end
+
+ def process_link_attr(html_attr)
if html_attr.value.start_with?('/uploads/')
process_link_to_upload_attr(html_attr)
elsif linkable_files? && repo_visible_to_user?
@@ -81,6 +142,7 @@ module Banzai
def process_link_to_repository_attr(html_attr)
uri = URI(html_attr.value)
+
if uri.relative? && uri.path.present?
html_attr.value = rebuild_relative_uri(uri).to_s
end
@@ -89,7 +151,7 @@ module Banzai
end
def rebuild_relative_uri(uri)
- file_path = relative_file_path(uri)
+ file_path = nested_file_path_if_exists(uri)
uri.path = [
relative_url_root,
@@ -102,13 +164,29 @@ module Banzai
uri
end
- def relative_file_path(uri)
- path = Addressable::URI.unescape(uri.path).delete("\0")
- request_path = Addressable::URI.unescape(context[:requested_path])
- nested_path = build_relative_path(path, request_path)
+ def nested_file_path_if_exists(uri)
+ path = cleaned_file_path(uri)
+ nested_path = relative_file_path(uri)
+
file_exists?(nested_path) ? nested_path : path
end
+ def cleaned_file_path(uri)
+ Addressable::URI.unescape(uri.path).delete("\0").chomp("/")
+ end
+
+ def relative_file_path(uri)
+ return if uri.nil?
+
+ build_relative_path(cleaned_file_path(uri), request_path)
+ end
+
+ def request_path
+ return unless context[:requested_path]
+
+ Addressable::URI.unescape(context[:requested_path]).chomp("/")
+ end
+
# Convert a relative path into its correct location based on the currently
# requested path
#
@@ -136,6 +214,7 @@ module Banzai
return path[1..-1] if path.start_with?('/')
parts = request_path.split('/')
+
parts.pop if uri_type(request_path) != :tree
path.sub!(%r{\A\./}, '')
@@ -149,14 +228,11 @@ module Banzai
end
def file_exists?(path)
- path.present? && !!uri_type(path)
+ path.present? && uri_type(path).present?
end
def uri_type(path)
- # https://gitlab.com/gitlab-org/gitlab-foss/issues/58657
- Gitlab::GitalyClient.allow_n_plus_1_calls do
- @uri_types[path] ||= current_commit.uri_type(path)
- end
+ @uri_types[path] == :unknown ? "" : @uri_types[path]
end
def current_commit
diff --git a/lib/gitlab/gitaly_client/blob_service.rb b/lib/gitlab/gitaly_client/blob_service.rb
index 8ccefb00d20..5cde06bb6aa 100644
--- a/lib/gitlab/gitaly_client/blob_service.rb
+++ b/lib/gitlab/gitaly_client/blob_service.rb
@@ -76,6 +76,30 @@ module Gitlab
GitalyClient::BlobsStitcher.new(response)
end
+ def get_blob_types(revision_paths, limit = -1)
+ return {} if revision_paths.empty?
+
+ request_revision_paths = revision_paths.map do |rev, path|
+ Gitaly::GetBlobsRequest::RevisionPath.new(revision: rev, path: encode_binary(path))
+ end
+
+ request = Gitaly::GetBlobsRequest.new(
+ repository: @gitaly_repo,
+ revision_paths: request_revision_paths,
+ limit: limit
+ )
+
+ response = GitalyClient.call(
+ @gitaly_repo.storage_name,
+ :blob_service,
+ :get_blobs,
+ request,
+ timeout: GitalyClient.fast_timeout
+ )
+
+ map_blob_types(response)
+ end
+
def get_new_lfs_pointers(revision, limit, not_in, dynamic_timeout = nil)
request = Gitaly::GetNewLFSPointersRequest.new(
repository: @gitaly_repo,
@@ -132,6 +156,16 @@ module Gitlab
end
end
end
+
+ def map_blob_types(response)
+ types = {}
+
+ response.each do |msg|
+ types[msg.path.dup.force_encoding('utf-8')] = msg.type.downcase
+ end
+
+ types
+ end
end
end
end