diff options
Diffstat (limited to 'lib/gitlab/asciidoc/include_processor.rb')
-rw-r--r-- | lib/gitlab/asciidoc/include_processor.rb | 44 |
1 files changed, 34 insertions, 10 deletions
diff --git a/lib/gitlab/asciidoc/include_processor.rb b/lib/gitlab/asciidoc/include_processor.rb index 6c4ecc04cdc..ae83dbedf04 100644 --- a/lib/gitlab/asciidoc/include_processor.rb +++ b/lib/gitlab/asciidoc/include_processor.rb @@ -9,6 +9,8 @@ module Gitlab class IncludeProcessor < Asciidoctor::IncludeExt::IncludeProcessor extend ::Gitlab::Utils::Override + NoData = Class.new(StandardError) + def initialize(context) super(logger: Gitlab::AppLogger) @@ -16,6 +18,7 @@ module Gitlab @repository = context[:repository] || context[:project].try(:repository) @max_includes = context[:max_includes].to_i @included = [] + @included_content = {} # Note: Asciidoctor calls #freeze on extensions, so we can't set new # instance variables after initialization. @@ -31,9 +34,10 @@ module Gitlab doc = reader.document max_include_depth = doc.attributes.fetch('max-include-depth').to_i + allow_uri_read = doc.attributes.fetch('allow-uri-read', false) return false if max_include_depth < 1 - return false if target_http?(target) + return false if target_http?(target) && !allow_uri_read return false if included.size >= max_includes true @@ -42,6 +46,7 @@ module Gitlab override :resolve_target_path def resolve_target_path(target, reader) return unless repository.try(:exists?) + return target if target_http?(target) base_path = reader.include_stack.empty? ? requested_path : reader.file path = resolve_relative_path(target, base_path) @@ -51,12 +56,15 @@ module Gitlab override :read_lines def read_lines(filename, selector) - blob = read_blob(ref, filename) + content = read_content(filename) + raise NoData, filename if content.nil? + + included << filename if selector - blob.data.each_line.select.with_index(1, &selector) + content.each_line.select.with_index(1, &selector) else - blob.data + content.lines end end @@ -67,7 +75,17 @@ module Gitlab private - attr_reader :context, :repository, :cache, :max_includes, :included + attr_reader :context, :repository, :cache, :max_includes, :included, :included_content + + def read_content(filename) + return included_content[filename] if included_content.key?(filename) + + included_content[filename] = if target_http?(filename) + read_uri(filename) + else + read_blob(ref, filename) + end + end # Gets a Blob at a path for a specific revision. # This method will check that the Blob exists and contains readable text. @@ -75,16 +93,22 @@ module Gitlab # revision - The String SHA1. # path - The String file path. # - # Returns a Blob + # Returns a string containing the blob content def read_blob(ref, filename) blob = repository&.blob_at(ref, filename) - raise 'Blob not found' unless blob - raise 'File is not readable' unless blob.readable_text? + raise NoData, 'Blob not found' unless blob + raise NoData, 'File is not readable' unless blob.readable_text? - included << filename + blob.data + end + + def read_uri(uri) + r = Gitlab::HTTP.get(uri) + + raise NoData, uri unless r.success? - blob + r.body end # Resolves the given relative path of file in repository into canonical |