Я надеюсь, что кто-то может разрешить что-то для меня. Я использую направляющие 2.3.5, и я могу получить доступ к заголовкам запроса в действии контроллера как это:
def index
if request.headers['...'] == '...'
...
end
end
Или что-то подобное. request.headers является экземпляром ActionController:: Http:: Заголовки, который, кажется, Хеш. Я ожидал бы, поэтому, что заголовки включаются на имени, которое я отправляю. Если я отправляю запрос однако, с заголовком Авторизации, как так:
curl -H 'Authorization: OAuth realm="MyRealm",...' http://app/path
Следующий код в действии возвращает false:
if request.headers.include?('Authorization') ...
Принимая во внимание, что следующий echos значение я отправляю в заголовке:
render :text => request.headers['Authorization']
Следующая проверка возвращает true, интересно достаточно:
if request.headers.include?('HTTP_AUTHORIZATION') ...
И точно так же следующее эхо значение я отправляю в заголовке:
render :text => request.headers['HTTP_AUTHORIZATION']
Кажется, что существует некоторое волшебство, происходящее это, я не знаю. Я полностью смущен относительно того, почему проверка ключевые сбои 'Авторизации', но рендеринг значения request.headers ['Авторизация'] успешно выполняется. Я также смущен как, туда, где 'HTTP_AUTHORIZATION' прибывает из того, поскольку это не название заголовка, я отправляю с запросом. Кто-либо знает то, что продолжается точно?
Вы правы - метод заголовков
для ActionController :: Request
возвращает экземпляр ActionController :: Http :: Headers
, наследуемый от Hash. Если мы взломаем исходный код, мы увидим следующее:
class Headers < ::Hash
extend ActiveSupport::Memoizable
def initialize(*args)
if args.size == 1 && args[0].is_a?(Hash)
super()
update(args[0])
else
super
end
end
def [](header_name)
if include?(header_name)
super
else
super(env_name(header_name))
end
end
private
# Converts a HTTP header name to an environment variable name.
def env_name(header_name)
"HTTP_#{header_name.upcase.gsub(/-/, '_')}"
end
memoize :env_name
end
Итак, при доступе к хешу через []
, есть вторая проверка, чтобы увидеть, есть ли значение из env_name
(которое просто увеличивает регистр ключа и добавляет ] HTTP_
) существует.
Вот почему вы не можете получить истинное значение из request.headers.include? ('Авторизация')
- include?
не переопределяется в подклассе для проверки как для нормальной, так и для обновленной версии заголовка. Я полагаю, вы могли бы последовать этому примеру и реализовать это самостоятельно следующим образом:
module ActionController
module Http
class Headers < ::Hash
def include?(header_name)
self[header_name].present?
end
end
end
end
Бросьте это в lib / extensions / action_controller.rb
или что-то в этом роде, при необходимости потребуйте его в environment.rb
, и все будет в порядке. Я бы порекомендовал просто изменить код вашего контроллера, чтобы использовать []
и present?
для проверки, тем не менее:)
причина того, что заголовки преобразованы в верхний регистр и имеют префикс HTTP_
, я полагаю, происходит от Rack, промежуточного программного обеспечения HTTP Rails. Вероятно, он делает это, чтобы оставаться беспристрастным к регистру, дополнительно добавляя HTTP_
, чтобы избежать конфликтов с другими входящими элементами среды, не являющимися заголовками.
Так что, да, немного волшебно, но не слишком сложно для понимания после взгляда на исходный код, который я всегда рекомендую :) У Rails есть очень хороший источник, из которого я многому научился за эти годы.