From 1022456bb15d18b05c14fe344950fb75c7c69f48 Mon Sep 17 00:00:00 2001 From: Sean McGivern Date: Fri, 7 Oct 2016 16:49:48 +0100 Subject: Allow browsing branches that end with '.atom' We need to do two things to support this: 1. Simplify the regex capture in the routing for the CommitsController to not exclude the '.atom' suffix. That's a perfectly valid git branch name, so we shouldn't blow up if we get it. 2. Because Rails now can't automatically detect the request format, add some code to do so in `ExtractPath` when there is no path. This means that, given branches 'foo' and 'foo.atom', the Atom feed for the former is unroutable. To fix this: don't do that! Give the branches different names! --- lib/extracts_path.rb | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) (limited to 'lib/extracts_path.rb') diff --git a/lib/extracts_path.rb b/lib/extracts_path.rb index a4558d157c0..e4d996a3fb6 100644 --- a/lib/extracts_path.rb +++ b/lib/extracts_path.rb @@ -52,8 +52,7 @@ module ExtractsPath # Append a trailing slash if we only get a ref and no file path id += '/' unless id.ends_with?('/') - valid_refs = @project.repository.ref_names - valid_refs.select! { |v| id.start_with?("#{v}/") } + valid_refs = ref_names.select { |v| id.start_with?("#{v}/") } if valid_refs.length == 0 # No exact ref match, so just try our best @@ -74,6 +73,19 @@ module ExtractsPath pair end + # If we have an ID of 'foo.atom', and the controller provides Atom and HTML + # formats, then we have to check if the request was for the Atom version of + # the ID without the '.atom' suffix, or the HTML version of the ID including + # the suffix. We only check this if the version including the suffix doesn't + # match, so it is possible to create a branch which has an unroutable Atom + # feed. + def extract_ref_without_atom(id) + id_without_atom = id.sub(/\.atom$/, '') + valid_refs = ref_names.select { |v| "#{id_without_atom}/".start_with?("#{v}/") } + + valid_refs.max_by(&:length) + end + # Assigns common instance variables for views working with Git tree-ish objects # # Assignments are: @@ -86,6 +98,10 @@ module ExtractsPath # If the :id parameter appears to be requesting a specific response format, # that will be handled as well. # + # If there is no path and the ref doesn't exist in the repo, try to resolve + # the ref without an '.atom' suffix. If _that_ ref is found, set the request's + # format to Atom manually. + # # Automatically renders `not_found!` if a valid tree path could not be # resolved (e.g., when a user inserts an invalid path or ref). def assign_ref_vars @@ -103,6 +119,13 @@ module ExtractsPath @commit = @repo.commit(@options[:extended_sha1]) end + if @path.empty? && !@commit + @id = @ref = extract_ref_without_atom(@id) + @commit = @repo.commit(@ref) + + request.format = :atom if @commit + end + raise InvalidPathError unless @commit @hex_path = Digest::SHA1.hexdigest(@path) @@ -125,4 +148,10 @@ module ExtractsPath id += "/" + params[:path] unless params[:path].blank? id end + + def ref_names + return [] unless @project + + @ref_names ||= @project.repository.ref_names + end end -- cgit v1.2.1 From d60d5fe4e422ecd83437653bc5764c6269162125 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Sat, 15 Oct 2016 01:36:05 +0300 Subject: Improve ExtractsPath logic related to atom format * Don't set request format to atom if '.atom' suffix was not provided * Don't try '.atom' detection logic on request that uses extended_sha1 Signed-off-by: Dmitriy Zaporozhets --- lib/extracts_path.rb | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'lib/extracts_path.rb') diff --git a/lib/extracts_path.rb b/lib/extracts_path.rb index e4d996a3fb6..9b74364849e 100644 --- a/lib/extracts_path.rb +++ b/lib/extracts_path.rb @@ -113,17 +113,18 @@ module ExtractsPath @id = get_id @ref, @path = extract_ref(@id) @repo = @project.repository - if @options[:extended_sha1].blank? - @commit = @repo.commit(@ref) - else - @commit = @repo.commit(@options[:extended_sha1]) - end - if @path.empty? && !@commit - @id = @ref = extract_ref_without_atom(@id) + if @options[:extended_sha1].present? + @commit = @repo.commit(@options[:extended_sha1]) + else @commit = @repo.commit(@ref) - request.format = :atom if @commit + if @path.empty? && !@commit && @id.ends_with?('.atom') + @id = @ref = extract_ref_without_atom(@id) + @commit = @repo.commit(@ref) + + request.format = :atom if @commit + end end raise InvalidPathError unless @commit -- cgit v1.2.1