问题
For one of my ruby applications i need the server to route requests based on the subdomain. There are ways to do this using other gems but i decided to make my own "middleware". This code runs applications based on where the request is going to.
config.ru
require './subdomain'
require './www'
run Rack::Subdomain.new([
{
:subdomain => "test",
:application => Sinatra::Application
}
]);
subdomain.rb
module Rack
class Subdomain
def initialize(app)
@app = app
end
def call(env)
@app.each do |app|
match = 'test'.match(app[:subdomain])
if match
return app[:application].call(env)
end
end
end
end
end
My question is how can i modify this working code to work exactly the same but have it called by code that looks like this:
run Rack::Subdomain do
map 'www' do
Example::WWW
end
map 'api' do
Example::API
end
end
With suggested code:
config.ru
require './subdomain'
require './www'
run Rack::Subdomain.new do |x|
x.map 'test' do
Sinatra::Application
end
end
subdomain.rb
module Rack
class Subdomain
def initialize(routes = nil)
@routes = routes
yield self
end
def map(subdomain)
@routes << { subdomain: subdomain, application: yield }
end
def call(env)
@routes.each do |route|
match = 'test'.match(route[:subdomain])
if match
return route[:application].call(env)
end
end
end
end
end
回答1:
You call the above "working code" but it doesn't seem to detect the subdomain at all, but wires it to the literal 'test'. At any rate, you can implement a pattern similar to what you want by making a map method which adds entries to your list of subdomain->application routes. I've renamed your @app
to @routes
since it is a hash of routes, not an application reference.
module Rack
class Subdomain
def initialize(routes = [])
@routes = routes
yield self if block_given?
end
def map(subdomain)
@routes << { subdomain: subdomain, application: yield }
end
def call(env)
@routes.each do |route|
match = 'test'.match(route[:subdomain])
if match
return route[:application].call(env)
end
end
end
end
end
rsd = Rack::Subdomain.new do |x|
x.map 'www' do
Example::WWW
end
x.map 'api' do
Example::API
end
end
run rsd
来源:https://stackoverflow.com/questions/15325002/modify-rack-app