Какой базовый URL для моего приложения?

Как я могу получить базовый URL для моего приложения в Camping/Rack? Я хочу знать, чтобы я мог поместить это в электронное письмо, которое он посылает.

Это может быть (в разработке)

или же

http://localhost:9292

или же

http://localhost:80/game

или в производстве

http://fancy-snake.heroku.com

3 ответа

Решение

У кемпинга есть помощник по имени 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>

Пока у меня есть

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

Который, кажется, работает для первого и третьего случаев. Я не знаю, если это написать, если приложение в localhost/prefix

Вы должны быть немного осторожны с этим, поскольку есть некоторые тонкие потенциальные ловушки. Rack::Request класс, вероятно, будет полезен здесь.

Во-первых, вы не можете получить URL-адрес приложения, так как оно может отвечать на несколько URL-адресов (через Rack-маршруты, конфигурацию Apache и т. Д.), Поэтому вы смотрите на получение URL-адреса для конкретного запроса. Если вы обслуживаете только запросы с одного URL, это не имеет значения.

Схема для запроса находится в env хеш под rack.url_scheme, но это только для "последнего этапа" запроса. Если ваше приложение находится за каким-то прокси-сервером (Nqinx, Apache и т. Д.), То вы хотите получить схему реального запроса, а не запрос от прокси на компьютер, на котором работает ваше приложение. Если вы правильно настроили свой прокси, он должен установить заголовок, чтобы вы могли сказать, какова была оригинальная схема. Rack::Request имеет scheme метод, который принимает эти заголовки во внимание.

Хост для URL, вероятно, находится в env хеш под HTTP_HOST ключ, но этот заголовок не обязательно присутствует (по общему признанию это довольно непривычно в настоящее время). Вы должны отступить на SERVER_NAME а также SERVER_PORT, Кроме того, существует проблема обработки прокси-запросов: вам нужно имя хоста исходного запроса, а не внутренний сервер. Снова, Rack::Request обеспечивает host_with_port а также host методы, которые решают эти проблемы.

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 хэш.

Другие вопросы по тегам