diff options
author | Nick Thomas <nick@gitlab.com> | 2017-12-05 18:47:54 +0000 |
---|---|---|
committer | Nick Thomas <nick@gitlab.com> | 2017-12-22 15:09:16 +0000 |
commit | a0c4f0059592c788b14f8cb71e655c05f1fc1dd7 (patch) | |
tree | 194010b7c872a2f5bb839550780fb4b5b688aa9e /lib | |
parent | 299e04e318728d4ee5857379f8fb350c944a0b4e (diff) | |
download | gitlab-ce-a0c4f0059592c788b14f8cb71e655c05f1fc1dd7.tar.gz |
Use relative URLs when linking to uploaded files
Diffstat (limited to 'lib')
-rw-r--r-- | lib/banzai/filter/relative_link_filter.rb | 46 | ||||
-rw-r--r-- | lib/banzai/filter/upload_link_filter.rb | 60 | ||||
-rw-r--r-- | lib/banzai/pipeline/gfm_pipeline.rb | 1 |
3 files changed, 39 insertions, 68 deletions
diff --git a/lib/banzai/filter/relative_link_filter.rb b/lib/banzai/filter/relative_link_filter.rb index 758f15c8a67..c1f933ec54b 100644 --- a/lib/banzai/filter/relative_link_filter.rb +++ b/lib/banzai/filter/relative_link_filter.rb @@ -2,19 +2,21 @@ require 'uri' module Banzai module Filter - # HTML filter that "fixes" relative links to files in a repository. + # HTML filter that "fixes" relative links to uploads or files in a repository. # # Context options: # :commit + # :group # :project # :project_wiki # :ref # :requested_path class RelativeLinkFilter < HTML::Pipeline::Filter - def call - return doc unless linkable_files? + include Gitlab::Utils::StrongMemoize + def call @uri_types = {} + clear_memoization(:linkable_files) doc.search('a:not(.gfm)').each do |el| process_link_attr el.attribute('href') @@ -31,13 +33,35 @@ module Banzai protected def linkable_files? - context[:project_wiki].nil? && repository.try(:exists?) && !repository.empty? + 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?('//') + if html_attr.value.start_with?('/uploads/') + process_link_to_upload_attr(html_attr) + elsif linkable_files? + process_link_to_repository_attr(html_attr) + end + end + + def process_link_to_upload_attr(html_attr) + uri_parts = [html_attr.value] + + if group + uri_parts.unshift(relative_url_root, 'groups', group.full_path, '-') + elsif project + uri_parts.unshift(relative_url_root, project.full_path) + end + + html_attr.value = File.join(*uri_parts) + end + + 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 @@ -51,7 +75,7 @@ module Banzai uri.path = [ relative_url_root, - context[:project].full_path, + project.full_path, uri_type(file_path), Addressable::URI.escape(ref), Addressable::URI.escape(file_path) @@ -123,11 +147,19 @@ module Banzai end def ref - context[:ref] || context[:project].default_branch + context[:ref] || project.default_branch + end + + def group + context[:group] + end + + def project + context[:project] end def repository - @repository ||= context[:project].try(:repository) + @repository ||= project&.repository end end end diff --git a/lib/banzai/filter/upload_link_filter.rb b/lib/banzai/filter/upload_link_filter.rb deleted file mode 100644 index d64f9ac4eb6..00000000000 --- a/lib/banzai/filter/upload_link_filter.rb +++ /dev/null @@ -1,60 +0,0 @@ -require 'uri' - -module Banzai - module Filter - # HTML filter that "fixes" relative upload links to files. - # Context options: - # :project (required) - Current project - # - class UploadLinkFilter < HTML::Pipeline::Filter - def call - return doc unless project || group - - doc.xpath('descendant-or-self::a[starts-with(@href, "/uploads/")]').each do |el| - process_link_attr el.attribute('href') - end - - doc.xpath('descendant-or-self::img[starts-with(@src, "/uploads/")]').each do |el| - process_link_attr el.attribute('src') - end - - doc - end - - protected - - def process_link_attr(html_attr) - html_attr.value = build_url(html_attr.value).to_s - end - - def build_url(uri) - base_path = Gitlab.config.gitlab.url - - if group - urls = Gitlab::Routing.url_helpers - # we need to get last 2 parts of the uri which are secret and filename - uri_parts = uri.split(File::SEPARATOR) - file_path = urls.show_group_uploads_path(group, uri_parts[-2], uri_parts[-1]) - File.join(base_path, file_path) - else - File.join(base_path, project.full_path, uri) - end - end - - def project - context[:project] - end - - def group - context[:group] - end - - # Ensure that a :project key exists in context - # - # Note that while the key might exist, its value could be nil! - def validate - needs :project - end - end - end -end diff --git a/lib/banzai/pipeline/gfm_pipeline.rb b/lib/banzai/pipeline/gfm_pipeline.rb index 55874ad50a3..c746f6f64e9 100644 --- a/lib/banzai/pipeline/gfm_pipeline.rb +++ b/lib/banzai/pipeline/gfm_pipeline.rb @@ -15,7 +15,6 @@ module Banzai Filter::MathFilter, Filter::MermaidFilter, - Filter::UploadLinkFilter, Filter::VideoLinkFilter, Filter::ImageLazyLoadFilter, Filter::ImageLinkFilter, |