¿Cómo puedo obtener todos los encabezados de solicitud en Django?
107
Necesito obtener todos los encabezados de solicitud de Django. Por lo que he leído, Django simplemente vierte todo en la request.METAvariable junto con muchos otros datos. ¿Cuál sería la mejor manera de obtener todos los encabezados que el cliente envió a mi aplicación Django?
Según la documentación,request.META es un "diccionario estándar de Python que contiene todos los encabezados HTTP disponibles". Si quieres conseguir todo los encabezados, simplemente puede recorrer el diccionario.
La parte de su código para hacer esto depende de sus requisitos exactos. Cualquier lugar al que tenga acceso requestdebería hacerlo.
Actualizar
Necesito acceder a él en una clase de Middleware, pero cuando lo repito, obtengo muchos valores además de los encabezados HTTP.
De la documentación:
Con la excepción de CONTENT_LENGTHy CONTENT_TYPE, como se indicó anteriormente, los HTTPencabezados de la solicitud se convierten en METAclaves convirtiendo todos los caracteres a mayúsculas, reemplazando los guiones con guiones bajos y agregando un HTTP_prefijo al nombre .
(Énfasis añadido)
Para obtener HTTPsolo los encabezados, simplemente filtre por claves con el prefijoHTTP_ .
Actualización 2
¿Podría mostrarme cómo podría construir un diccionario de encabezados filtrando todas las claves de la variable request.META que comienza con HTTP_ y elimina la parte principal de HTTP_?
Necesito acceder a él en una clase de Middleware, pero cuando lo repito, obtengo muchos valores además de los encabezados HTTP.
Mridang Agarwalla
Gracias Manoj. Solo por curiosidad, ¿podría mostrarme cómo podría construir un diccionario de encabezados filtrando todas las claves de la request.METAvariable que comienzan con HTTP_ay quitan la HTTP_parte inicial ? ¿Es esto posible a través de funciones lambda? (Creo que se llaman funciones lambda) Estoy preguntando esto porque probablemente continuaría haciéndolo por el camino largo primero iterando sobre ellas, luego verificando si comienza con HTTP_ay luego agregándolo al nuevo diccionario. Gracias de nuevo.
Mridang Agarwalla
Gracias de nuevo Manoj. Lo modifiqué ligeramente para usarlo en lstrip('HTTP_')lugar de la expresión regular. :)
Mridang Agarwalla
3
@Mridang Agarwalla: en lstriprealidad no hará lo que le pides que haga. lstripeliminará todos los caracteres iniciales que coincidan con cualquier carácter de la cadena que le proporcione, por lo que si tiene un encabezado "HTTP_TOKEN_ID", lo devolverá "OKEN_ID", porque "T"al principio de "TOKEN"coincide con un carácter en la cadena pasada a lstrip. La forma de hacerlo es prefix = 'HTTP_'; header = header[len(prefix):].
Un objeto similar a un dict que no distingue entre mayúsculas y minúsculas que proporciona acceso a todos los encabezados con prefijo HTTP (más Content-Length y Content-Type) desde la solicitud.
El nombre de cada encabezado se estiliza con el título en mayúsculas (por ejemplo, User-Agent) cuando se muestra. Puede acceder a los encabezados sin distinción entre mayúsculas y minúsculas:
>>> 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)
Para obtener todos los encabezados, puede usar request.headers.keys()o request.headers.items().
No creo que haya una manera fácil de obtener solo encabezados HTTP. Tienes que iterar a través de request.META dict para obtener todo lo que necesitas.
django-debug-toolbar adopta el mismo enfoque para mostrar la información del encabezado. Eche un vistazo a este archivo responsable de recuperar la información del encabezado.
Por lo que vale, parece que su intención es utilizar la solicitud HTTP entrante para formar otra solicitud HTTP. Una especie de puerta de entrada. Existe un excelente módulo django-revproxy que logra exactamente esto.
La fuente es una referencia bastante buena sobre cómo lograr lo que está tratando de hacer.
>>> 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 que comienzan conHTTP_
ay quitan laHTTP_
parte inicial ? ¿Es esto posible a través de funciones lambda? (Creo que se llaman funciones lambda) Estoy preguntando esto porque probablemente continuaría haciéndolo por el camino largo primero iterando sobre ellas, luego verificando si comienza conHTTP_
ay luego agregándolo al nuevo diccionario. Gracias de nuevo.lstrip('HTTP_')
lugar de la expresión regular. :)lstrip
realidad no hará lo que le pides que haga.lstrip
eliminará todos los caracteres iniciales que coincidan con cualquier carácter de la cadena que le proporcione, por lo que si tiene un encabezado"HTTP_TOKEN_ID"
, lo devolverá"OKEN_ID"
, porque"T"
al principio de"TOKEN"
coincide con un carácter en la cadena pasada a lstrip. La forma de hacerlo esprefix = 'HTTP_'; header = header[len(prefix):]
.HttpRequest.headers
.A partir de Django 2.2, puede utilizar
request.headers
para acceder a los encabezados HTTP. De la documentación en HttpRequest.headers :Para obtener todos los encabezados, puede usar
request.headers.keys()
orequest.headers.items()
.fuente
Esta es otra forma de hacerlo, muy similar a la respuesta de Manoj Govindan anterior:
Eso también tomará los encabezados
CONTENT_TYPE
yCONTENT_LENGTH
solicitará, junto conHTTP_
los.request_headers['some_key]
==request.META['some_key']
.Modifique en consecuencia si necesita incluir / omitir ciertos encabezados. Django enumera un montón, pero no todos, aquí: https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.META
Algoritmo de Django para encabezados de solicitud:
-
con bajo_
HTTP_
a todos los encabezados en la solicitud original, exceptoCONTENT_TYPE
yCONTENT_LENGTH
.Los valores de cada encabezado no deben modificarse.
fuente
re.compile(r'^(HTTP_.+|CONTENT_TYPE|CONTENT_LENGTH)$')
request.META.get ('HTTP_AUTHORIZATION')
/python3.6/site-packages/rest_framework/authentication.py
aunque puede obtenerlo de este archivo ...
fuente
No creo que haya una manera fácil de obtener solo encabezados HTTP. Tienes que iterar a través de request.META dict para obtener todo lo que necesitas.
django-debug-toolbar adopta el mismo enfoque para mostrar la información del encabezado. Eche un vistazo a este archivo responsable de recuperar la información del encabezado.
fuente
Si desea obtener la clave del cliente del encabezado de la solicitud, puede intentar lo siguiente:
fuente
Por lo que vale, parece que su intención es utilizar la solicitud HTTP entrante para formar otra solicitud HTTP. Una especie de puerta de entrada. Existe un excelente módulo django-revproxy que logra exactamente esto.
La fuente es una referencia bastante buena sobre cómo lograr lo que está tratando de hacer.
fuente
fuente
Simplemente puede usar HttpRequest.headers desde Django 2.2 en adelante. El siguiente ejemplo se toma directamente de la oficial de documentación de Django bajo solicitud y los objetos de respuesta sección.
fuente