Search code examples
rubyruby-on-rails-4rack

My rack middleware in Rails 4 not executing


I am trying to build cms application using Ruby on Rails 4.Inorder to get proper controller.I need to preprocess the querystring before using it
in match method as shown below

# config/routes.rb    
Cms::Application.routes do         
varparameter=ENV["QUERY_STRING"]    
 @controller=preprocessqstring(varparameter)
 match '/cms/home', to: 'login#show', via: [:get, :post]
 match 'cms/:content(/:action(/:id(.:format)))',to: @controller+'#show', via: [:get, :post]
end

To set ENV["QUERY_STRING"] I am using the following rack middleware

 # lib/httpvariables.rb
    require 'rack'
    class Httpvariables
        def initialize(app)
          @app = app
        end

        def call(env)
           @status, @headers, @response = @app.call(env)
          request=Rack::Request.new(env)
           ENV["REQUEST_URI"]=request.env["REQUEST_URI"]
           ENV["QUERY_STRING"]=request.env["QUERY_STRING"]
           ENV["SERVER_PORT"]=request.env["SERVER_PORT"]
           ENV["SERVER_PROTOCOL"]=request.env["SERVER_PROTOCOL"]
        [@status, @headers, self]
        end
     end

I have added this line in application.rb

# config/application.rb
config.middleware.use Rack::Httpvariables

To my suprise if try to start rails server it's failing showing:

mundile@mundile-HP:~/RoR-workspace/workspace/cms$ rails server
=> Booting WEBrick
=> Rails 4.1.1 application starting in development on http://0.0.0.0:3000
=> Run `rails server -h` for more startup options
=> Notice: server is listening on all interfaces (0.0.0.0). Consider using 127.0.0.1 (--binding option)
=> Ctrl-C to shutdown server
Exiting
/home/mundile/RoR-workspace/workspace/cms/config/routes.rb:68:in `block in <top (required)>': undefined method `+' for nil:NilClass (NoMethodError)

I need your help out there to identify the cause of the problem. It seems ENV["QUERY_STRING"] is giving nil but why ? Thanks.


Solution

  • I changed middleware code to:

     # lib/httpvariables.rb
        require 'rack'
        class Httpvariables
            def initialize(app)
              @app = app
            end
            def call(env)
          request=Rack::Request.new(env)
          ENV["REQUEST_URI"]=request.env["REQUEST_URI"]
          ENV["QUERY_STRING"]=request.env["QUERY_STRING"]
          ENV["SERVER_PORT"]=request.env["SERVER_PORT"]
          ENV["BASE_URL"]=request.base_url
          @app.call(env)
        end
        end
    

    This works like charm.
    I have also used this code to answer this question: Rails access request in routes.rb for dynamic routes