1. Create a new file called #{RAILS_ROOT}/lib/action_controller_request_ext.rb.
  2. Edit the new file, paste in the following code and save it.
module ActionController
  class AbstractRequest
    # override to fix certain ambiguities with IIS and Fast CGI and Rewrite
    def request_uri
      if uri = env['REQUEST_URI']
        (%r{^\w+\://[^/]+(/.*|$)$} =~ uri) ? $1 : 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
        # remove the script file name (dispatch.fcgi) from the URI
        uri = env['PATH_INFO'] 
        uri = uri.sub("#{env['SCRIPT_NAME']}", "") unless env['SCRIPT_NAME'].nil?
        # replace the isapi rewrite query string with the original path and query (opnq)
        unless( opnq = env["QUERY_STRING"]).nil? || opnq.empty?
          env["QUERY_STRING"] = opnq.sub("?","&") # overwrite the invalid query string
          uri << opnq.sub("opnq=", "") # remove the "opnq=" that Rewrite put on the request_uri
        end
        uri
      end
    end
  end
end
  1. Edit your #{RAILS_ROOT}/config/environment.rb file and append the following snippet to ensure your application uses the new request_uri method instead of the default one.
# Include your app's configuration here:
require 'action_controller_request_ext.rb'
  • Note: This solution was derived from some that I found on the web. There was a small issue in that if more than one query string variable is appended to a path http://localhost/mycontroller/dosomething?var1=123&var2=abc, then QUERY_STRING["var1"] = nil but QUERY_STRING["/mycontroller/dosomething?var1"] = 123 and QUERY_STRING["var2"] = abc. This is obviously a problem and others have come up with solutions similar to mine however, conforming to "proper" query string syntax, it is best if you replace the original path and query string as a variable, hence the opnq=. The only side effect (not necessarily negative) of using my solution is the fact that QUERY_STRING["opnq"] = /mycontroller/dosomething?var1=123&var2=abc and the fact that it shows up in the IIS log files under the query string column.
  • If you wish, you can test the request_uri extension by browsing to http://localhost/dispatch.fcgi?opnq=/mycontroller/dosomething?var1=123&var2=abc and verifying that things are working properly.

Note: Your IsapiRewite4.ini file needs to have a rewrite rule like this one:
IterationLimit 0

# note: does not support files (see example below)
RewriteRule ^(/[^.]+)$ /dispatch.fcgi?opnq=$1


Below you can see why the default implementation does not work together nicely with Fast-CGI and IsapiRewrite4.
how_iis_fcgi_works.gif

Resulting Outputs:
request_uri_override.gif

Files:
IsapiRewrite4.ini
action_controller_request_ext.rb

Last edited Feb 19, 2007 at 9:57 PM by bheinz, version 3

Comments

No comments yet.