Rack::Request - как мне получить все заголовки?
Название довольно очевидно. Есть ли способ получить заголовки (кроме Rack::Request.env[]
)?
2 ответа
Заголовки HTTP доступны в среде Rack и передаются вашему приложению:
HTTP_
Переменные: переменные, соответствующие предоставленным клиентом заголовкам HTTP-запроса (т. Е. Переменные, имена которых начинаются с HTTP_). Наличие или отсутствие этих переменных должно соответствовать наличию или отсутствию соответствующего HTTP-заголовка в запросе.
Таким образом, заголовки HTTP имеют префикс "HTTP_" и добавляются в хеш.
Вот небольшая программа, которая извлекает и отображает их:
require 'rack'
app = Proc.new do |env|
headers = env.select {|k,v| k.start_with? 'HTTP_'}
.collect {|key, val| [key.sub(/^HTTP_/, ''), val]}
.collect {|key, val| "#{key}: #{val}<br>"}
.sort
[200, {'Content-Type' => 'text/html'}, headers]
end
Rack::Server.start :app => app, :Port => 8080
Когда я запускаю это, в дополнение к заголовкам HTTP, как показано в Chrome или Firefox, появляется "VERSION: HTPP/1.1" (т. Е. В env добавляется запись с ключом "HTTP_VERSION" и значением "HTTP/1.1"). хэш).
На основании ответа @matt, но это действительно дает вам заголовки запроса в хэше, как и было задано в вопросе:
headers = Hash[*env.select {|k,v| k.start_with? 'HTTP_'}
.collect {|k,v| [k.sub(/^HTTP_/, ''), v]}
.collect {|k,v| [k.split('_').collect(&:capitalize).join('-'), v]}
.sort
.flatten]
В зависимости от того, какое ключевое соглашение вы предпочитаете, вы можете использовать что-то другое вместо: прописные.
Как и ответ @ Гавриила, но используя transform_keys
(Проще):
class Request
def headers
env.select { |k,v| k.start_with? 'HTTP_'}.
transform_keys { |k| k.sub(/^HTTP_/, '').split('_').map(&:capitalize).join('-') }
end
end
Вы даже можете сделать так, чтобы поиск продолжал работать, даже если дело обстоит иначе:
def headers
env.
select { |k,v| k.start_with? 'HTTP_'}.
transform_keys { |k| k.sub(/^HTTP_/, '').split('_').map(&:capitalize).join('-') }.
sort.to_h.
tap do |headers|
headers.define_singleton_method :[] do |k|
super(k.split(/[-_]/).map(&:capitalize).join('-'))
end
end
end
Так, например, даже если headers
нормализует ключи, поэтому возвращает:
{
Dnt: '1',
Etag: 'W/"ec4454af5ae1bacff1afc5a06a2133f4"',
'X-Xss-Protection': '1; mode=block',
}
вы все еще можете искать заголовки, используя более естественные / общие имена для этих заголовков:
headers['DNT']
headers['ETag']
headers['X-XSS-Protection']