我的应用的基本url是什么?

在Camping / Rack中,如何获取应用的基本URL? 我想知道,所以我可以把它放在它发送的电子邮件中。

它可能是(正在开发中)

要么

http://localhost:9292 

要么

 http://localhost:80/game 

或在生产中

 http://fancy-snake.heroku.com 

Camping有一个名为URL的帮助器,它返回应用程序的绝对URL:

 URL() # => # URL() + "view/12" # => # URL("/view/12") # => # 

到目前为止我有

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

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

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

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

请求的方案位于rack.url_scheme下的env哈希中,但这仅适用于请求的“最后一段”。 如果您的应用程序位于某种代理(Nqinx,Apache等)后面,那么您希望获得实际请求的方案,而不是从代理到您的应用程序运行的计算机的请求。 如果您已正确配置代理,则应设置标题,以便了解原始方案的内容。 Rack::Request有一个scheme方法 ,可以考虑这些标头。

url的主机可能位于HTTP_HOST键下的env哈希中,但此标头不一定存在(诚然,现在它非常不合适)。 您应该回到SERVER_NAMESERVER_PORT 。 此外还有处理代理请求的问题,您需要原始请求的主机名,而不是后端服务器。 同样, Rack::Request提供了host_with_port和处理这些问题的host方法。

Rack::Request还提供了一个结合方案和主机的base_url方法 ,另外只包括端口(如果与默认端口不同)(80或443)。

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

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

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

看起来很简单,但为您提供各种可能性。

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