Coderer
Coderer

Reputation: 27274

Can I get the base URL of my Rack service outside of a request handler?

I'd like to be able to retrieve the base URL of my web app from within the Rack initialization code in my config.ru. Something along the lines of:

puts "Starting up on http://#{ENV['SERVER_NAME']}:#{ENV['SERVER_PORT']}/#{ENV['MOUNT_POINT']}..."

but I haven't found anything like this that's available from outside of a request handler. Obviously, I can do something like:

...
def get
  puts "Got a request for #{ENV['rack.url_scheme']}://#{ENV['HTTP_HOST']}#{ENV['REQUEST_PATH']}"
  ...

because the request is defined at that point. But at the start of my config file, none of those variables appear to be defined.

Is there a Rack method I can use to access this information? Is this one of those cases where those things aren't finalized until Rack startup is finished? I seem to remember other frameworks having a way to pass a proc to a method that will execute it once the environment is "ready". Does Rack have anything like that?

Upvotes: 5

Views: 1375

Answers (2)

nex
nex

Reputation: 685

It's about a year later but I was just struggling with the same problem and found your thread.

Every Rack application provides a call-method that gets called by the Rack handler. For example see the code of Sinatra::Base#call. This call method gets called once per request and has one parameter which is a hash that contains environment variables. Within these there is everything you need and the "mount_point" you were asking for is called "SCRIPT_NAME".

See http://www.rubydoc.info/github/rack/rack/file/SPEC for details. Unfortunately this information is only available to you during a request and not before as far as I know. Hope it helps others.

Upvotes: 2

Patrick
Patrick

Reputation: 5994

I don't believe it's possible for a Rack application can know ahead of time the "mount point". For example, this config.ru mounts the same app at multiple mount points:

require 'rack'

app = proc { |env|
  [200, {'Content-Type' => 'text/plain'}, ['hello, world!']]
}

run Rack::URLMap.new('/myapp' => app,
                     '/' => app)

Rack also does not provide any standard method that is called at initialization time. I suspect this is because Rack tries to support plain CGI, where a whole Ruby process may be created to handle each request, with the process exiting at each request. In that situation, there isn't much use for an "init" method.

Upvotes: 2

Related Questions