From 3b9bf64130df2512d058d841341d9a082493141e Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Mon, 18 Apr 2005 15:43:07 +0000 Subject: [PATCH] Added support for web servers that use PATH_INFO instead of REQUEST_URI like IIS #1014 [BradG/Nicholas Seckar] git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1211 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- actionpack/CHANGELOG | 2 + .../lib/action_controller/cgi_process.rb | 6 ++- actionpack/lib/action_controller/request.rb | 12 ++++- actionpack/test/controller/request_test.rb | 45 ++++++++++++++++++- 4 files changed, 61 insertions(+), 4 deletions(-) diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index f4b2327ec0..511e6a2a89 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,5 +1,7 @@ *SVN* +* Added support for web servers that use PATH_INFO instead of REQUEST_URI like IIS #1014 [BradG/Nicholas Seckar] + * Added graceful handling of PUT, DELETE, and OPTIONS requests for a complete coverage of REST functionality #1136 [joshknowles@gmail.com] * Fixed that you can now pass an alternative :href option to link_to_function/remote in order to point to somewhere other than # if the javascript fails or is turned off. You can do the same with form_remote_tag by passing in :action. #1113 [Sam Stephenson] diff --git a/actionpack/lib/action_controller/cgi_process.rb b/actionpack/lib/action_controller/cgi_process.rb index 4e3a1d270c..fb46c6d353 100644 --- a/actionpack/lib/action_controller/cgi_process.rb +++ b/actionpack/lib/action_controller/cgi_process.rb @@ -48,7 +48,11 @@ module ActionController #:nodoc: def query_string return @cgi.query_string unless @cgi.query_string.nil? || @cgi.query_string.empty? - parts = env['REQUEST_URI'].split('?') + unless env['REQUEST_URI'].nil? + parts = env['REQUEST_URI'].split('?') + else + return env['QUERY_STRING'] || '' + end parts.shift return parts.join('?') end diff --git a/actionpack/lib/action_controller/request.rb b/actionpack/lib/action_controller/request.rb index 032b19d6eb..f16a109cc7 100755 --- a/actionpack/lib/action_controller/request.rb +++ b/actionpack/lib/action_controller/request.rb @@ -74,8 +74,16 @@ module ActionController end def request_uri - (%r{^\w+\://[^/]+(/.*|$)$} =~ env['REQUEST_URI']) ? $1 : env['REQUEST_URI'] # Remove domain, which webrick puts into the request_uri. - end + unless env['REQUEST_URI'].nil? + (%r{^\w+\://[^/]+(/.*|$)$} =~ env['REQUEST_URI']) ? $1 : env['REQUEST_URI'] # Remove domain, which webrick puts into the request_uri. + else # REQUEST_URI is blank under IIS - get this from PATH_INFO and SCRIPT_NAME + script_filename = env["SCRIPT_NAME"].to_s.match(%r{[^/]+$}) + request_uri = env["PATH_INFO"] + request_uri.sub!(/#{script_filename}\//, '') unless script_filename.nil? + request_uri += '?' + env["QUERY_STRING"] unless env["QUERY_STRING"].nil? || env["QUERY_STRING"].empty? + return request_uri + end + end def protocol env["HTTPS"] == "on" ? 'https://' : 'http://' diff --git a/actionpack/test/controller/request_test.rb b/actionpack/test/controller/request_test.rb index 09c1dd7ce3..372d5929fa 100644 --- a/actionpack/test/controller/request_test.rb +++ b/actionpack/test/controller/request_test.rb @@ -83,7 +83,50 @@ class RequestTest < Test::Unit::TestCase @request.set_REQUEST_URI "/collaboration/hieraki/books/edit/2" @request.env['SCRIPT_NAME'] = "/collaboration/hieraki/dispatch.cgi" assert_equal "/collaboration/hieraki/books/edit/2", @request.request_uri - assert_equal "/books/edit/2", @request.path + assert_equal "/books/edit/2", @request.path + + # The following tests are for when REQUEST_URI is not supplied (as in IIS) + @request.set_REQUEST_URI nil + @request.env['PATH_INFO'] = "/path/of/some/uri?mapped=1" + @request.env['SCRIPT_NAME'] = nil #"/path/dispatch.rb" + assert_equal "/path/of/some/uri?mapped=1", @request.request_uri + assert_equal "/path/of/some/uri", @request.path + + @request.env['PATH_INFO'] = "/path/of/some/uri?mapped=1" + @request.env['SCRIPT_NAME'] = "/path/dispatch.rb" + assert_equal "/path/of/some/uri?mapped=1", @request.request_uri + assert_equal "/of/some/uri", @request.path + + @request.env['PATH_INFO'] = "/path/of/some/uri" + @request.env['SCRIPT_NAME'] = nil + assert_equal "/path/of/some/uri", @request.request_uri + assert_equal "/path/of/some/uri", @request.path + + @request.env['PATH_INFO'] = "/" + assert_equal "/", @request.request_uri + assert_equal "/", @request.path + + @request.env['PATH_INFO'] = "/?m=b" + assert_equal "/?m=b", @request.request_uri + assert_equal "/", @request.path + + @request.env['PATH_INFO'] = "/" + @request.env['SCRIPT_NAME'] = "/dispatch.cgi" + assert_equal "/", @request.request_uri + assert_equal "/", @request.path + + @request.env['PATH_INFO'] = "/hieraki/" + @request.env['SCRIPT_NAME'] = "/hieraki/dispatch.cgi" + assert_equal "/hieraki/", @request.request_uri + assert_equal "/", @request.path + + # This test ensures that Rails uses REQUEST_URI over PATH_INFO + @request.env['REQUEST_URI'] = "/some/path" + @request.env['PATH_INFO'] = "/another/path" + @request.env['SCRIPT_NAME'] = "/dispatch.cgi" + assert_equal "/some/path", @request.request_uri + assert_equal "/some/path", @request.path + end