2

In Camping/Rack, how can I get the base URL for my app? I want to know so I can put it in an email it sends.

It might be (in development)

or

http://localhost:9292

or

http://localhost:80/game

or in production

http://fancy-snake.heroku.com
4

3 回答 3

2

你必须要小心一点,因为有一些微妙的潜在陷阱。这Rack::Request门课在这里可能会有所帮助。

首先,您无法真正获取应用程序的 url ,因为它可能会响应多个 url(通过 Rack 路由、Apache 配置等),因此您正在查看获取特定请求的 url 。如果您只提供来自一个 url 的请求,这无关紧要。

请求的方案在env下的哈希中rack.url_scheme,但这仅适用于请求的“最后一站”。如果您的应用程序位于某种代理(Nqinx、Apache 等)之后,那么您想要获取真实请求的方案,而不是从代理到运行您的应用程序的机器的请求。如果您正确配置了代理,它应该设置一个标头,这样您就可以知道原始方案是什么。Rack::Request有一种scheme将这些标头考虑在内的方法。

url 的主机可能在keyenv下的 hash 中HTTP_HOST,但是这个 header 不一定存在(诚然,现在这不太可能)。你应该依靠SERVER_NAMEand SERVER_PORT。此外还有处理代理请求的问题,您需要原始请求的主机名,而不是后端服务器。再次,Rack::Request提供处理这些问题的方法host_with_porthost

Rack::Request还提供了一种结合方案和主机的base_url方法,如果与默认值(80 或 443)不同,则仅包含端口。

您的应用程序的挂载位置位于键env下的哈希中SCRIPT_NAME。这将/game在您的第二个示例中,如果您的应用程序安装在服务器的根目录中,则可以为空。同样,Rack::Request提供了一个script_name方法,虽然这个方法只是简单地返回env散列中条目的值。

所以,总而言之,你可能想要使用这样的东西:

req = Rack::Request.new env
url = req.base_url + req.script_name

这看起来很简单,但正在为您处理各种可能性。

此外,您可能会发现Rack 规范对阅读很有用,它包含应该在env散列中的各种条目的详细信息。

于 2012-10-14T23:20:47.083 回答
2

到目前为止我有

url = @env['rack.url_scheme'] + "://" + @env['HTTP_HOST'] + R(LoginX, u.secret)

这似乎适用于第一种和第三种情况。我不知道它是否写如果应用程序在localhost/prefix

于 2012-10-14T18:20:37.373 回答
1

Camping 有一个助手调用URL,它返回绝对 URL 到你的应用程序:

URL()               # => #<URL:http://test.ing/blog/>
URL() + "view/12"   # => #<URL:http://test.ing/blog/view/12>
URL("/view/12")     # => #<URL:http://test.ing/blog/view/12>
于 2012-10-15T08:38:28.187 回答