web-dev-qa-db-fra.com

Rack :: Demande - Comment puis-je obtenir tous les en-têtes?

Le titre est assez explicite. Y a-t-il un moyen d'obtenir les en-têtes (sauf pour Rack::Request.env[])?

34
PJK

Les en-têtes HTTP sont disponibles dans l'environnement de rack transmis à votre application:

HTTP_ Variables: variables correspondant aux en-têtes de requête HTTP fournis par le client (c'est-à-dire des variables dont les noms commencent par http_). La présence ou l'absence de ces variables doit correspondre à la présence ou à l'absence de l'en-tête HTTP approprié dans la demande.

Les en-têtes HTTP sont donc préfixés avec "http_" et ajoutés au hachage.

Voici un petit programme qui extrait et les affiche:

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

Lorsque j'exécute cela, en plus des en-têtes HTTP, comme indiqué par Chrome ou firefox, il y a une "version: htpp/1.1" (c'est-à-dire une entrée avec clé "http_version" et valeur "http /1.1 "est ajouté au hachage env).

43
matt

Basé sur la réponse de @ Matt, mais cela vous donne vraiment les en-têtes de demande dans un hachage à la demande de la question:

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]

Selon la convention de clé que vous préférez, vous voudrez peut-être utiliser autre chose au lieu de: capitaliser.

7
Gavriel

Comme la réponse de @ Gavriel, mais en utilisant transform_keys (plus simple):

class Request
  def headers
    env.select { |k,v| k.start_with? 'HTTP_'}.
      transform_keys { |k| k.sub(/^HTTP_/, '').split('_').map(&:capitalize).join('-') }
  end
end

Vous pouvez même le faire, les recherches fonctionnent toujours même si le cas est différent:

  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

Donc, par exemple, même si headers normalise les clés afin de le renvoyer:

{
  Dnt: '1',
  Etag: 'W/"ec4454af5ae1bacff1afc5a06a2133f4"',
  'X-Xss-Protection': '1; mode=block',
}

vous pouvez toujours rechercher les en-têtes en utilisant les noms les plus naturels/communs de ces en-têtes:

headers['DNT']
headers['ETag']
headers['X-XSS-Protection']
2
Tyler Rick