diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..eb84e13 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,5 @@ +language: ruby +rvm: + - 1.9.3-p551 + - 2.3.0 +before_install: gem install bundler diff --git a/http_router.gemspec b/http_router.gemspec index 0dc6d00..f40eda6 100644 --- a/http_router.gemspec +++ b/http_router.gemspec @@ -24,7 +24,7 @@ Gem::Specification.new do |s| s.add_runtime_dependency 'url_mount', '~> 0.2.1' s.add_development_dependency 'minitest', '~> 2.0.0' s.add_development_dependency 'code_stats' - s.add_development_dependency 'rake', '~> 0.8.7' + s.add_development_dependency 'rake', '~> 10.5.0' s.add_development_dependency 'rbench' s.add_development_dependency 'json' s.add_development_dependency 'phocus' diff --git a/lib/http_router.rb b/lib/http_router.rb index a7a378c..85b5167 100644 --- a/lib/http_router.rb +++ b/lib/http_router.rb @@ -220,8 +220,14 @@ def clone(klass = self.class) end def rewrite_partial_path_info(env, request) - env['PATH_INFO'] = "/#{request.path.join('/')}" - env['SCRIPT_NAME'] += request.rack_request.path_info[0, request.rack_request.path_info.size - env['PATH_INFO'].size] + path_info_before = request.rack_request.path_info.dup + if request.path.empty? + env['PATH_INFO'] = "/" + env['SCRIPT_NAME'] += path_info_before + else + env['PATH_INFO'] = "/#{URI.encode(request.path.join('/'))}" + env['SCRIPT_NAME'] += path_info_before[0, path_info_before.size - env['PATH_INFO'].size] + end end def rewrite_path_info(env, request) diff --git a/test/rack/test_route.rb b/test/rack/test_route.rb index dabb35a..2a7ed4c 100644 --- a/test/rack/test_route.rb +++ b/test/rack/test_route.rb @@ -36,4 +36,58 @@ def test_custom_status def test_raise_error_on_invalid_status assert_raises(ArgumentError) { router.get("/index.html").redirect("/", 200) } end + + def test_path_info_from_partial_match + request_env = nil + router do + add("/sidekiq*").to { |env| request_env = env; [200, {}, []] } + end + router.call(Rack::MockRequest.env_for("/sidekiq/queues")) + assert_equal('/queues', request_env['PATH_INFO']) + end + + def test_script_name_from_partial_match + request_env = nil + router do + add("/sidekiq*").to { |env| request_env = env; [200, {}, []] } + end + router.call(Rack::MockRequest.env_for("/sidekiq/queues")) + assert_equal('/sidekiq', request_env['SCRIPT_NAME']) + end + + def test_path_info_from_partial_match_of_single + request_env = nil + router do + add("/sidekiq*").to { |env| request_env = env; [200, {}, []] } + end + router.call(Rack::MockRequest.env_for("/sidekiq")) + assert_equal('/', request_env['PATH_INFO']) + end + + def test_script_name_from_partial_match_of_single + request_env = nil + router do + add("/sidekiq*").to { |env| request_env = env; [200, {}, []] } + end + router.call(Rack::MockRequest.env_for("/sidekiq")) + assert_equal('/sidekiq', request_env['SCRIPT_NAME']) + end + + def test_path_info_with_encoded_request_path + request_env = nil + router do + add("/sidekiq*").to { |env| request_env = env; [200, {}, []] } + end + router.call(Rack::MockRequest.env_for("/sidekiq/queues/some%20path")) + assert_equal('/queues/some%20path', request_env['PATH_INFO']) + end + + def test_script_name_with_encoded_request_path + request_env = nil + router do + add("/sidekiq*").to { |env| request_env = env; [200, {}, []] } + end + router.call(Rack::MockRequest.env_for("/sidekiq/queues/some%20path")) + assert_equal('/sidekiq', request_env['SCRIPT_NAME']) + end end