summary refs log tree commit
diff options
context:
space:
mode:
authorDaisuke Koide <disk2id@gmail.com>2019-03-15 20:15:32 +0900
committerDaisuke Koide <disk2id@gmail.com>2019-06-06 09:18:02 +0900
commit78e837e4d0ef95bcf2dce8c38a1b411032240afa (patch)
tree009920b0e37d5843e24f823e1926e04bb72fbed6
parent70c838f7204f9bb08992d2b68b1d52b80c97b016 (diff)
downloadrack-78e837e4d0ef95bcf2dce8c38a1b411032240afa.tar.gz
Set X-Accel-Redirect to percent-encoded path
-rw-r--r--lib/rack/sendfile.rb3
-rw-r--r--test/spec_sendfile.rb19
2 files changed, 18 insertions, 4 deletions
diff --git a/lib/rack/sendfile.rb b/lib/rack/sendfile.rb
index 6113f858..51ba4db5 100644
--- a/lib/rack/sendfile.rb
+++ b/lib/rack/sendfile.rb
@@ -117,7 +117,8 @@ module Rack
           path = ::File.expand_path(body.to_path)
           if url = map_accel_path(env, path)
             headers[CONTENT_LENGTH] = '0'
-            headers[type] = url
+            # '?' must be percent-encoded because it is not query string but a part of path
+            headers[type] = ::Rack::Utils.escape_path(url).gsub('?', '%3F')
             obody = body
             body = Rack::BodyProxy.new([]) do
               obody.close if obody.respond_to?(:close)
diff --git a/test/spec_sendfile.rb b/test/spec_sendfile.rb
index cae458e4..8688df9f 100644
--- a/test/spec_sendfile.rb
+++ b/test/spec_sendfile.rb
@@ -8,10 +8,10 @@ require 'rack/mock'
 require 'tmpdir'
 
 describe Rack::Sendfile do
-  def sendfile_body
-    FileUtils.touch File.join(Dir.tmpdir,  "rack_sendfile")
+  def sendfile_body(filename = "rack_sendfile")
+    FileUtils.touch File.join(Dir.tmpdir,  filename)
     res = ['Hello World']
-    def res.to_path ; File.join(Dir.tmpdir,  "rack_sendfile") ; end
+    res.define_singleton_method(:to_path) { File.join(Dir.tmpdir,  filename) }
     res
   end
 
@@ -74,6 +74,19 @@ describe Rack::Sendfile do
     end
   end
 
+  it "sets X-Accel-Redirect response header to percent-encoded path" do
+    headers = {
+      'HTTP_X_SENDFILE_TYPE' => 'X-Accel-Redirect',
+      'HTTP_X_ACCEL_MAPPING' => "#{Dir.tmpdir}/=/foo/bar%/"
+    }
+    request headers, sendfile_body('file_with_%_?_symbol') do |response|
+      response.must_be :ok?
+      response.body.must_be :empty?
+      response.headers['Content-Length'].must_equal '0'
+      response.headers['X-Accel-Redirect'].must_equal '/foo/bar%25/file_with_%25_%3F_symbol'
+    end
+  end
+
   it 'writes to rack.error when no X-Accel-Mapping is specified' do
     request 'HTTP_X_SENDFILE_TYPE' => 'X-Accel-Redirect' do |response|
       response.must_be :ok?