La petición y la respuesta HTTP pueden contener lo que se llama un cuerpo (body).
Ya sabemos que una petición HTTP consta de encabezados y un cuerpo opcional de petición. Hay reglas específicas para separar los encabezados del cuerpo. Veamos un ejemplo de cómo trabajar con el cuerpo y cómo enviar datos además de los encabezados. Realicemos una petición HTTP al host codica.la:
telnet codica.la 80
GET / HTTP/1.1
Host: codica.la
HTTP/1.1 301 Moved Permanently
Cache-Control: private
Content-Type: text/html; charset=UTF-8
Referrer-Policy: no-referrer
Location: https://34.102.241.4/
Content-Length: 218
Date: Tue, 07 Jul 2020 03:50:16 GMT
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="https://34.102.241.4/">here</A>.
</BODY></HTML>
Obtenemos algunos encabezados como respuesta y luego viene el cuerpo, que es lo que nos interesa. En este caso, no es una página de nuestro sitio web, sino simplemente una página que devuelve el servidor. Está relacionada con una redirección.
Si entendemos los encabezados, se separan entre sí por una nueva línea y para enviarlos agregamos otra nueva línea que se ve como una línea vacía, ¿pero qué pasa con el cuerpo de la petición? Puede contener cualquier cosa. No podemos codificar un salto de línea como un carácter especial. Después de todo, esos dos saltos de línea pueden estar dentro del cuerpo de la petición. Pero también hay otras razones por las que en un protocolo de texto no se puede determinar fácilmente cuándo termina el cuerpo. Si aceptáramos una respuesta sin ningún mecanismo especial, después de que el servidor enviara los primeros dos saltos de línea, veríamos inmediatamente la respuesta y todo lo que se envió después no se consideraría parte de la respuesta HTTP. Para resolver este problema, se inventó otro mecanismo más universal. Se basa en el envío de un encabezado especial.
Durante el envío de una respuesta, el servidor genera un encabezado especial llamado Content-Length. Esto es lo que nos permite trabajar con el cuerpo. Antes de enviar el cuerpo de la respuesta, se calcula su longitud y se registra la cantidad de bytes.
# número: cantidad de bytes
Content-Length: 218
Después de enviar ese encabezado, la otra parte esperará exactamente la cantidad de bytes que se indica en él. Como recordamos, esto funciona de la misma manera para la respuesta y la petición HTTP. Después de enviar el último carácter, la conexión se cierra. Vale la pena aclarar que se cierra la sesión HTTP en sí. El servidor puede tener keep-alive activado, pero el punto clave es que la petición se considera completa y se muestra.
La indicación del tamaño del cuerpo no solo es necesaria para enviar una respuesta, sino también para peticiones en las que se envían datos de formulario, por ejemplo.
La práctica muestra que no todos los servidores funcionan correctamente solo con el encabezado Content-Length. Les falta otro. El tipo de contenido de la petición o respuesta que contiene el cuerpo debe ser identificado de alguna manera. Por defecto, el estándar dice que el servidor puede intentar determinar el contenido en función de varios métodos. Por ejemplo, hacemos una petición image.png en la query string.
POST /image.png HTTP/1.1
No es obligatorio, pero el servidor puede entender que es una imagen en formato png y usarla de alguna manera. En todos los demás casos, cuando el servidor no puede determinar el tipo de contenido, debe usar el encabezado Content-Type: application/octet-stream. Esto significa que se envía simplemente un flujo de bytes en el cuerpo de la petición. Aunque los servidores deben funcionar de esta manera, a menudo ocurre de manera diferente. Si solo se especifica Content-Length, el servidor se niega a aceptar los datos. Simplemente cierra la conexión después de los dos saltos de línea, antes del cuerpo. Este detalle se descubrió experimentalmente.
Otra observación sobre el cuerpo. Desde el punto de vista del estándar HTTP, el cuerpo puede estar presente en cualquier petición y no está relacionado con el verbo. Se puede enviar un cuerpo en HEAD, POST, PUT y otras peticiones. Si enviamos un cuerpo con GET, aunque no está descrito en el estándar, el servidor no reaccionará de ninguna manera, además, no debería hacerlo, ya que desde un punto de vista práctico no tiene sentido. También hay tipos de peticiones en las que no se enviará un cuerpo en absoluto. Por ejemplo, una respuesta a HEAD, cuando solo solicitamos los encabezados, ya que esa es la semántica de ese verbo. Además, el cuerpo no se envía cuando recibimos respuestas con estados como 204 - sin contenido y algunos otros.
Materiales adicionales
- Wikipedia / Cuerpo del mensaje
- Formato de las solicitudes HTTP
- Formato de las respuestas HTTP
- Códigos de estado de respuesta HTTP
Para acceder completo a curso necesitas un plan básico
El plan básico te dará acceso completo a todos los cursos, ejercicios y lecciones de Códica, proyectos y acceso de por vida a la teoría de las lecciones completadas. La suscripción se puede cancelar en cualquier momento.