diff options
author | Aaron Patterson <aaron.patterson@gmail.com> | 2015-09-04 14:18:16 -0700 |
---|---|---|
committer | Aaron Patterson <aaron.patterson@gmail.com> | 2015-09-04 14:18:16 -0700 |
commit | 568cf7294d3c8abb84825514e91cf98c58a5e503 (patch) | |
tree | 1f0fb9dec64674238fcca2043ebdacd8c4dc5f61 | |
parent | 978eb9b9935d388ca8cc45fe31c870b9bc0aaab2 (diff) | |
download | rack-568cf7294d3c8abb84825514e91cf98c58a5e503.tar.gz |
use `Rack::Utils.unescape_path` to unescape path_info
Unescaping paths is different from unescaping query parameters. This commit changes the unescape to use the URI parser to unescape the path, which leaves `+` as `+`. Fixes #265 References rails/rails#11816
-rw-r--r-- | HISTORY.md | 6 | ||||
-rw-r--r-- | lib/rack/file.rb | 2 | ||||
-rw-r--r-- | test/spec_file.rb | 15 |
3 files changed, 22 insertions, 1 deletions
@@ -1,3 +1,9 @@ +Fri Sep 4 14:15:32 2015 Aaron Patterson <tenderlove@ruby-lang.org> + + * Files and directories with + in the name are served correctly. + Rather than unescaping paths like a form, we unescape with a URI + parser using `Rack::Utils.unescape_path`. Fixes #265 + Thu Aug 27 15:43:48 2015 Aaron Patterson <tenderlove@ruby-lang.org> * Tempfiles are automatically closed in the case that there were too diff --git a/lib/rack/file.rb b/lib/rack/file.rb index 1efa15a7..5b755f56 100644 --- a/lib/rack/file.rb +++ b/lib/rack/file.rb @@ -30,7 +30,7 @@ module Rack return fail(405, "Method Not Allowed", {'Allow' => ALLOW_HEADER}) end - path_info = Utils.unescape request.path_info + path_info = Utils.unescape_path request.path_info clean_path_info = Utils.clean_path_info(path_info) path = ::File.join(@root, clean_path_info) diff --git a/test/spec_file.rb b/test/spec_file.rb index 71828b90..2d0919a9 100644 --- a/test/spec_file.rb +++ b/test/spec_file.rb @@ -10,6 +10,21 @@ describe Rack::File do Rack::Lint.new Rack::File.new(*args) end + it 'serves files with + in the file name' do + Dir.mktmpdir do |dir| + File.write File.join(dir, "you+me.txt"), "hello world" + app = file(dir) + env = Rack::MockRequest.env_for("/you+me.txt") + status,_,body = app.call env + + assert_equal 200, status + + str = '' + body.each { |x| str << x } + assert_match "hello world", str + end + end + it "serve files" do res = Rack::MockRequest.new(file(DOCROOT)).get("/cgi/test") |