Rack map and subdomains
The situation: you are using subdomains for locales such as en.example.com and th.example.com. Your app is Rack based and is behind Nginx with a ‘wildcard’ server_name directive such as:
server {
server_name .example.com;
...
}
You are also using Rack’s map abilities to have two different applications mounted on different paths on your domain. This could be done like this in your config.ru file:
map '/users' do
run Example::Admin
end
map '/' do
run Example::Public
end
The problem
If the URL http://th.example.com is hit, Nginx will set ‘HTTP_HOST’ as ’th.example.com’ but ‘SERVER_NAME’ will be ’example.com’. What his means is that tests within Rack fail and result in neither of the above ‘maps’ matching so a 404 is returned.
A solution
In Rack apps you are able to modify the environment. This means that one way to fix this is to simply set the environment’s’ SERVER_NAME’ to equal ‘HTTP_HOST’ by including something like this in your config.ru file, before your map calls:
module Rack
class Blah
def initialize app
@app = app
end
def call env
env['SERVER_NAME'] = env['HTTP_HOST']
@app.call env
end
end
end
use Rack::Blah
map '/users' do
...etc.