Comment puis-je obtenir tous les en-têtes de requête dans Django?
107
J'ai besoin de tous les en-têtes de requête Django. D'après ce que j'ai lu, Django vide simplement tout dans la request.METAvariable avec beaucoup d'autres données. Quelle serait la meilleure façon d'obtenir tous les en-têtes que le client a envoyés à mon application Django?
Je vais les utiliser pour créer une httplibrequête.
Selon la documentation, ilrequest.META existe un "dictionnaire Python standard contenant tous les en-têtes HTTP disponibles". Si vous souhaitez obtenir tous les en-têtes, vous pouvez simplement parcourir le dictionnaire.
La partie de votre code pour cela dépend de vos besoins exacts. N'importe quel endroit qui a accès requestdevrait faire.
Mettre à jour
J'ai besoin d'y accéder dans une classe Middleware, mais lorsque je l'itère, j'obtiens beaucoup de valeurs en dehors des en-têtes HTTP.
De la documentation:
À l'exception de CONTENT_LENGTHet CONTENT_TYPE, comme indiqué ci-dessus, tous les en- HTTPtêtes de la demande sont convertis en METAclés en convertissant tous les caractères en majuscules, en remplaçant les tirets par des traits de soulignement et en ajoutant un HTTP_préfixe au nom .
(Je souligne)
Pour obtenir les en- HTTPtêtes seuls, filtrez simplement par clés précédées du préfixe HTTP_.
Mise à jour 2
pourriez-vous me montrer comment je pourrais construire un dictionnaire d'en-têtes en filtrant toutes les clés de la variable request.META qui commencent par HTTP_ et suppriment la partie HTTP_ principale.
J'ai besoin d'y accéder dans une classe Middleware, mais lorsque je l'itère, j'obtiens beaucoup de valeurs en dehors des en-têtes HTTP.
Mridang Agarwalla
Merci Manoj. Juste par curiosité - pourriez-vous me montrer comment je pourrais construire un dictionnaire d'en-têtes en filtrant toutes les clés de la request.METAvariable qui commencent par a HTTP_et en supprimant la HTTP_partie principale . Est-ce possible grâce aux fonctions lambda? (Je pense qu'on les appelle des fonctions lambda) Je pose cette question parce que je continuerais probablement à le faire le long du chemin en les itérant d'abord, puis en vérifiant si cela commence par un HTTP_et en l'ajoutant au nouveau dictionnaire. Merci encore.
Mridang Agarwalla
Merci encore Manoj. Je l'ai légèrement modifié pour l'utiliser à la lstrip('HTTP_')place de l'expression régulière. :)
Mridang Agarwalla
3
@Mridang Agarwalla: lstripne fera pas ce que vous lui demandez de faire. lstripsupprimera tous les premiers caractères qui correspondent à tous les caractères de la chaîne que vous lui donnez, donc si vous avez un en-tête, "HTTP_TOKEN_ID"il vous le rendra "OKEN_ID", car "T"au début de "TOKEN"correspond un caractère dans la chaîne passée à lstrip. La façon de le faire est prefix = 'HTTP_'; header = header[len(prefix):].
Un objet de type dict insensible à la casse qui donne accès à tous les en-têtes préfixés HTTP (plus Content-Length et Content-Type) à partir de la requête.
Le nom de chaque en-tête est stylisé avec une casse de titre (par exemple, User-Agent) lorsqu'il est affiché. Vous pouvez accéder aux en-têtes sans tenir compte de la casse:
>>> request.headers
{'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6',...}>>>'User-Agent'in request.headers
True>>>'user-agent'in request.headers
True>>> request.headers['User-Agent']Mozilla/5.0(Macintosh;IntelMac OS X 10_12_6)>>> request.headers['user-agent']Mozilla/5.0(Macintosh;IntelMac OS X 10_12_6)>>> request.headers.get('User-Agent')Mozilla/5.0(Macintosh;IntelMac OS X 10_12_6)>>> request.headers.get('user-agent')Mozilla/5.0(Macintosh;IntelMac OS X 10_12_6)
Pour obtenir tous les en-têtes, vous pouvez utiliser request.headers.keys()ou request.headers.items().
Cela récupérera également les en CONTENT_TYPE- CONTENT_LENGTHtêtes et request, ainsi que HTTP_ceux. request_headers['some_key]==request.META['some_key'] .
Je ne pense pas qu'il existe un moyen facile d'obtenir uniquement des en-têtes HTTP. Vous devez parcourir request.META dict pour obtenir tout ce dont vous avez besoin.
django-debug-toolbar adopte la même approche pour afficher les informations d'en-tête. Jetez un œil à ce fichier chargé de récupérer les informations d'en-tête.
Pour ce que cela vaut, il semble que votre intention soit d'utiliser la requête HTTP entrante pour former une autre requête HTTP. Un peu comme une passerelle. Il existe un excellent module django-revproxy qui accomplit exactement cela.
La source est une assez bonne référence sur la façon d'accomplir ce que vous essayez de faire.
>>> request.headers
{'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6',...}>>>'User-Agent'in request.headers
True>>>'user-agent'in request.headers
True>>> request.headers['User-Agent']Mozilla/5.0(Macintosh;IntelMac OS X 10_12_6)>>> request.headers['user-agent']Mozilla/5.0(Macintosh;IntelMac OS X 10_12_6)>>> request.headers.get('User-Agent')Mozilla/5.0(Macintosh;IntelMac OS X 10_12_6)>>> request.headers.get('user-agent')Mozilla/5.0(Macintosh;IntelMac OS X 10_12_6)
request.META
variable qui commencent par aHTTP_
et en supprimant laHTTP_
partie principale . Est-ce possible grâce aux fonctions lambda? (Je pense qu'on les appelle des fonctions lambda) Je pose cette question parce que je continuerais probablement à le faire le long du chemin en les itérant d'abord, puis en vérifiant si cela commence par unHTTP_
et en l'ajoutant au nouveau dictionnaire. Merci encore.lstrip('HTTP_')
place de l'expression régulière. :)lstrip
ne fera pas ce que vous lui demandez de faire.lstrip
supprimera tous les premiers caractères qui correspondent à tous les caractères de la chaîne que vous lui donnez, donc si vous avez un en-tête,"HTTP_TOKEN_ID"
il vous le rendra"OKEN_ID"
, car"T"
au début de"TOKEN"
correspond un caractère dans la chaîne passée à lstrip. La façon de le faire estprefix = 'HTTP_'; header = header[len(prefix):]
.HttpRequest.headers
.À partir de Django 2.2, vous pouvez utiliser
request.headers
pour accéder aux en-têtes HTTP. À partir de la documentation sur HttpRequest.headers :Pour obtenir tous les en-têtes, vous pouvez utiliser
request.headers.keys()
ourequest.headers.items()
.la source
Voici une autre façon de le faire, très similaire à la réponse de Manoj Govindan ci-dessus:
Cela récupérera également les en
CONTENT_TYPE
-CONTENT_LENGTH
têtes et request, ainsi queHTTP_
ceux.request_headers['some_key]
==request.META['some_key']
.Modifiez en conséquence si vous devez inclure / omettre certains en-têtes. Django en répertorie un certain nombre, mais pas tous, ici: https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.META
L'algorithme de Django pour les en-têtes de requête:
-
d' union par un trait de soulignement_
HTTP_
à tous les en-têtes de la demande d'origine, à l'exception deCONTENT_TYPE
etCONTENT_LENGTH
.Les valeurs de chaque en-tête ne doivent pas être modifiées.
la source
re.compile(r'^(HTTP_.+|CONTENT_TYPE|CONTENT_LENGTH)$')
request.META.get ('HTTP_AUTHORIZATION')
/python3.6/site-packages/rest_framework/authentication.py
vous pouvez cependant l'obtenir à partir de ce fichier ...
la source
Je ne pense pas qu'il existe un moyen facile d'obtenir uniquement des en-têtes HTTP. Vous devez parcourir request.META dict pour obtenir tout ce dont vous avez besoin.
django-debug-toolbar adopte la même approche pour afficher les informations d'en-tête. Jetez un œil à ce fichier chargé de récupérer les informations d'en-tête.
la source
Si vous souhaitez obtenir la clé client à partir de l'en-tête de la demande, vous pouvez essayer de suivre:
la source
Pour ce que cela vaut, il semble que votre intention soit d'utiliser la requête HTTP entrante pour former une autre requête HTTP. Un peu comme une passerelle. Il existe un excellent module django-revproxy qui accomplit exactement cela.
La source est une assez bonne référence sur la façon d'accomplir ce que vous essayez de faire.
la source
la source
Vous pouvez simplement utiliser HttpRequest.headers à partir de Django 2.2 . L'exemple suivant est directement tiré de la documentation officielle de Django dans la section Objets de requête et de réponse .
la source