How to Use a Rack Middleware Only for Certain Paths

How do I use a Rack middleware only for certain paths?

You could have MyMiddleware check the path and not pass control to the next piece of middle ware if it matches.

class MyMiddleware
def initialize app
@app = app
end
def call env
middlewary_stuff if env['PATH_INFO'] == '/foo'
@app.call env
end

def middlewary_stuff
#...
end
end

Or, you could use URLMap w/o the dslness. It would look something like this:

main_app = MainApp.new
Rack::URLMap.new '/'=>main_app, /^(foo|bar)/ => MyMiddleWare.new(main_app)

URLMap is actually pretty simple to grok.

Ruby on rails: how to exclude certain path from rack middleware authentication?

If you want to exclude only "home/users/" path then you middleware should have following structure,

def call(env)
request = Rack::Request.new(env)
return @app.call(env) if request.path == "home/users/"
# your middleware logic of authentication here.
end

For more information of rack, you can refer this.

Ruby on Rails Rack middleware exclude

Damien Matheiu's answer to the question you link will absolutely work for you. You'll just need to write an appropriate filter expression.

For the example above, that would be something like:

unless env['REQUEST_PATH'].match /^\/api\/v2\/gadgets\/(\d+)\/specs$/
middleware = BasicAuth.new #... args ...
env = middleware.call(env)
end

So you will call the BasicAuth middleware only when the path doesn't match any of your excluded paths.

Rack Middleware in Rack Middleware?

Right, I'm not entirely sure what you're trying to do. But you can do this

class CorsWired
def initialize(app)
@app = app
end

def call(env)
cors = Rack::Cors.new(@app, {}) do
allow do
origins '*'
resource '*', :headers => :any, :methods => [:get, :post, :put, :options, :delete], :credentials => false
end
end
cors.call(env)
end
end

Your config.ru should have use CorsWired though, not use CorsWired.new

This is I think what you were asking but I think you're missing the point of middleware. You should just change your config.ru to use rack-cors before/after your middleware depending on what you want to do.

require 'rack'
require 'rack/cors'
require './cors_wired'

app = Rack::Builder.new do
use Rack::Cors do
allow do
origins '*'
resource '*', :headers => :any, :methods => [:get, :post, :put, :options, :delete], :credentials => false
end
end
use CorsWired
run lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['OK']] }
end
run app

Rack Middleware: use and run constructs

The article you have linked to mentions that Rack comes with a sample application Lobster so yes, for a start, that is an app.

The Shrimp class is just a Ruby class which is how a middleware should be written.

In the config.ru file, you require the modules, register the middleware, and then run the application.

use adds Shrimp to the middleware stack and run passes Lobster
instance into the Shrimp constructor?

You are right when you say use adds Shrimp to the middleware stack but run does not necessarily pass a Lobster instance into the Shrimp constructor. run just executes the Rack application and passing the app instance is how Rack works internally. The real thing happens in the use part where you register the middleware.

For example:

# config.ru
require 'rack'
require 'rack/lobster'
require 'shrimp_1'
require 'shrimp_2'
require 'shrimp_3'

use Shrimp_1
use Shrimp_2
use Shrimp_3
run Rack::Lobster.new </pre>

All three Shrimp classes will be passed the app(Lobster) instance in that order and this will be handled by Rack itself.



Related Topics



Leave a reply



Submit