diff --git a/lib/gollum/frontend/app.rb b/lib/gollum/frontend/app.rb index 26dd397e..af2e70a5 100644 --- a/lib/gollum/frontend/app.rb +++ b/lib/gollum/frontend/app.rb @@ -90,19 +90,24 @@ module Precious redirect File.join(settings.wiki_options[:base_path].to_s, 'Home') end + def clean_url url + url.gsub('%2F','/').gsub(/^\/+/,'') + end + # path is set to name if path is nil. # if path is 'a/b' and a and b are dirs, then # path must have a trailing slash 'a/b/' or # extract_path will trim path to 'a' # name, path, version - def wiki_page( name, path = nil, version = nil) + def wiki_page(name, path = nil, version = nil, exact = true) path = name if path.nil? name = extract_name(name) path = extract_path(path) + path = '/' if exact && path.nil? wiki = wiki_new - OpenStruct.new(:wiki => wiki, :page => wiki.paged(name, path, version), + OpenStruct.new(:wiki => wiki, :page => wiki.paged(name, path, exact, version), :name => name, :path => path) end @@ -141,7 +146,9 @@ module Precious end post '/edit/*' do - wikip = wiki_page(CGI.unescape(params[:page]), sanitize_empty_params(params[:path])) + # TODO: Why does exact = true break /edit unit tests? + # name, path, version = nil, exact = false + wikip = wiki_page(CGI.unescape(params[:page]), sanitize_empty_params(params[:path]), nil, true) path = wikip.path wiki = wikip.wiki page = wikip.page @@ -187,6 +194,7 @@ module Precious post '/create' do name = params[:page].to_url path = sanitize_empty_params(params[:path]) + path = '' if path.nil? format = params[:format].intern # write_page is not directory aware so use wiki_options to emulate dir support. @@ -195,8 +203,7 @@ module Precious begin wiki.write_page(name, format, params[:content], commit_message) - page = wiki.page(name) - redirect to("/#{page.escaped_url_path}") unless page.nil? + redirect to("/#{clean_url(CGI.escape(::File.join(path,name)))}") rescue Gollum::DuplicatePageError => e @message = "Duplicate page: #{e.message}" mustache :error @@ -343,7 +350,7 @@ module Precious path = '/' if path.nil? - if page = wiki.paged(name, path) + if page = wiki.paged(name, path, exact = true) @page = page @name = name @editable = true @@ -356,7 +363,7 @@ module Precious file.raw_data else page_path = [path, name].compact.join('/') - redirect to("/create/#{encodeURIComponent(page_path).gsub('%2F','/')}") + redirect to("/create/#{clean_url(encodeURIComponent(page_path))}") end end diff --git a/lib/gollum/page.rb b/lib/gollum/page.rb index d5135e80..fa825cb5 100644 --- a/lib/gollum/page.rb +++ b/lib/gollum/page.rb @@ -372,9 +372,9 @@ module Gollum # version - The String version ID to find. # # Returns a Gollum::Page or nil if the page could not be found. - def find(name, version, dir = nil) + def find(name, version, dir = nil, exact = false) map = @wiki.tree_map_for(version.to_s) - if page = find_page_in_tree(map, name, dir) + if page = find_page_in_tree(map, name, dir, exact) page.version = version.is_a?(Grit::Commit) ? version : @wiki.commit_for(version) page.historical = page.version.to_s == version.to_s @@ -391,12 +391,14 @@ module Gollum # to be in. The string should # # Returns a Gollum::Page or nil if the page could not be found. - def find_page_in_tree(map, name, checked_dir = nil) + def find_page_in_tree(map, name, checked_dir = nil, exact = false) return nil if !map || name.to_s.empty? if checked_dir = BlobEntry.normalize_dir(checked_dir) checked_dir.downcase! end + checked_dir = '' if exact && checked_dir.nil? + map.each do |entry| next if entry.name.to_s.empty? next unless checked_dir.nil? || entry.dir.downcase == checked_dir diff --git a/lib/gollum/wiki.rb b/lib/gollum/wiki.rb index e803a297..596d577c 100644 --- a/lib/gollum/wiki.rb +++ b/lib/gollum/wiki.rb @@ -196,9 +196,9 @@ module Gollum # dir - The directory String relative to the repo. # # Returns a Gollum::Page or nil if no matching page was found. - def page(name, version = @ref, dir = nil) + def page(name, version = @ref, dir = nil, exact = false) version = @ref if version.nil? - @page_class.new(self).find(name, version, dir) + @page_class.new(self).find(name, version, dir, exact) end # Public: Convenience method instead of calling page(name, nil, dir). @@ -208,8 +208,8 @@ module Gollum # dir - The directory String relative to the repo. # # Returns a Gollum::Page or nil if no matching page was found. - def paged(name, dir = nil, version = @ref) - page(name, version, dir) + def paged(name, dir = nil, exact = false, version = @ref) + page(name, version, dir, exact) end # Public: Get the static file for a given name. diff --git a/test/test_app.rb b/test/test_app.rb index a3ae1afc..c18c715f 100644 --- a/test/test_app.rb +++ b/test/test_app.rb @@ -176,7 +176,8 @@ context "Frontend" do name = "A" post "/create", :content => 'abc', :page => name, :format => 'markdown', :message => 'def' - assert last_response.ok? + # create redirects on success + assert_equal last_response.status, 302 @wiki.clear_cache page = @wiki.page(name)