Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Tools & Tips

HTTP: El protocolo que todo desarrollador web debería conocer - Parte 1

by
Difficulty:IntermediateLength:LongLanguages:

Spanish (Español) translation by Eva Collados Pascual (you can also view the original English article)

HTTP significa protocolo de transferencia de hipertexto. Es un protocolo de nivel de aplicación para la comunicación entre sistemas distribuidos, y es la base de la web moderna. Como desarrollador web, todos debemos tener una fuerte comprensión de este protocolo.

Revisemos este potente protocolo a través de la lente de un desarrollador web. Abordaremos el tema en dos partes. En este primer tutorial, cubriremos los conceptos básicos y describiremos los distintas cabeceras de solicitud y respuesta. En el artículo que seguirá a este, revisaremos partes concretas de HTTP, es decir, el almacenamiento en caché, el control de conexiones y la autenticación.

Aunque mencionaré algunos detalles relacionados con las cabeceras, es mejor consultar en su lugar el RFC (RFC 2616) para obtener información en profundidad. Voy a señalar partes específicas de la RFC a lo largo del artículo.


Fundamentos de HTTP

HTTP permite la comunicación entre una variedad de hosts y clientes, y admite una combinación de configuraciones de red.

Para hacer esto posible, asume muy poco en relación a un sistema en particular, y no mantiene el estado entre diferentes intercambios de mensajes.

Esto hace que HTTP sea un protocolo sin estado. La comunicación suele tener lugar a través de TCP/IP, pero se puede utilizar cualquier transporte confiable. El puerto predeterminado para TCP/IP es el número 80, pero también pueden utilizarse otros.

Las cabeceras personalizadas también pueden ser creadas y enviadas por el cliente.

La comunicación entre un host y un cliente se produce a través de un par de solicitud/respuesta. El cliente inicia un mensaje de solicitud HTTP, que es enviado a cambio a través de un mensaje de respuesta HTTP. Veremos este par fundamental de mensajes en la siguiente sección.

La versión actual del protocolo es HTTP/1.1, la cual añade algunas características adicionales a la anterior versión 1.0. La más importante de ellas, en mi opinión, incluye conexiones persistentes, codificación de transferencia fragmentada y cabeceras de almacenamiento en caché detalladas. Tocaremos brevemente estas características en este artículo; la explicación en profundidad se proporcionará en la segunda parte.

URLs

En el corazón de las comunicaciones web está el mensaje de solicitud, que se envían a través de localizadores uniformes de recursos (URL). Estoy seguro de que ya estás familiarizado con las URLs, pero para ser exhaustivo, lo incluiré aquí. Las direcciones URL tienen una estructura simple que consta de los siguientes componentes:

El protocolo suele ser http, pero también puede ser https para las comunicaciones seguras. El puerto predeterminado es 80, pero se puede establecer uno explícitamente, como se ilustra en la imagen anterior. La ruta de acceso del recurso es la ruta de acceso local al recurso en el servidor.

Verbos

También hay proxies de depuración web, como Fiddler en Windows y Charles Proxy para OSX.

Las direcciones URL revelan la identidad del host concreto con el que queremos comunicarnos, pero la acción que se debe realizar en el host es especificada a través de verbos HTTP. Por supuesto, existen varias acciones que a un cliente le gustaría que realizase el host. HTTP ha formalizado unos pocos que capturan lo esencial y que son universalmente aplicables a todo tipo de aplicaciones.

Estos verbos de solicitud son:

  • GET: captura un recurso existente. La dirección URL contiene toda la información necesaria que el servidor necesita para localizar y devolver el recurso.
  • POST: crea un nuevo recurso. Las solicitudes POST suelen llevar una carga que especifica los datos para el nuevo recurso.
  • PUT: actualiza un recurso existente. La carga puede contener los datos actualizados para el recurso.
  • DELETE: elimina un recurso existente.

Los cuatro verbos anteriores son los más populares, y la mayoría de las herramientas y frameworks exponen explícitamente estos verbos de solicitud. PUT y DELETE a veces se consideran versiones especializadas del verbo POST, y pueden ser empaquetados como solicitudes POST con la carga que contiene la acción exacta: crear, actualizar o eliminar.

Hay algunos verbos menos utilizados que también admite HTTP:

  • HEAD: es similar a GET, pero sin el cuerpo del mensaje. Se usa para recuperar las cabeceras del servidor de un recurso determinado, generalmente para comprobar si el recurso ha cambiado, a través de sellos de tiempo.
  • TRACE: se utiliza para recuperar los saltos que tarda una solicitud en el viaje de ida y vuelta desde el servidor. Cada proxy intermedio o puerta de enlace inyectaría su IP o nombre DNS en el campo de cabecera Via. Esto se puede utilizar con fines de diagnóstico.
  • OPTIONS: se utiliza para recuperar las capacidades del servidor. En el lado del cliente, se puede utilizar para modificar la solicitud en función de lo que el servidor puede admitir.

Códigos de estado

Con direcciones URL y verbos, el cliente puede iniciar solicitudes al servidor. A cambio, el servidor responde con códigos de estado y cargas de mensajes. El código de estado es importante e indica al cliente cómo interpretar la respuesta del servidor. La especificación HTTP define ciertos rangos de números para tipos específicos de respuestas:

1xx: Mensajes informativos

Todos los clientes HTTP/1.1 deben aceptar el encabezado Transfer-Encoding.

Esta clase de códigos se introdujo en HTTP/1.1 y es puramente provisional. El servidor puede enviar un mensaje Expect: 100-continue, indicándole al cliente que continúe enviando el resto de la solicitud, o a ignorarlo si ya lo ha enviado. Se supone que los clientes HTTP/1.0 ignoran esta cabecera.

2xx: Exitoso

Esto le indica al cliente que la solicitud ha sido procesada correctamente. El código más común es 200 OK. Para una solicitud GET, el servidor envía el recurso en el cuerpo del mensaje. Hay otros códigos menos utilizados:

  • 202 Aceptado: la solicitud fue aceptada pero no se ha podido incluir el recurso en la respuesta. Esto es útil para el procesamiento asincrónico en el lado del servidor. El servidor puede optar por enviar información para la supervisión.
  • 204 Sin contenido: no hay ningún cuerpo del mensaje en la respuesta.
  • 205 Restablecer contenido: indica al cliente que restablezca su visualización de documento.
  • 206 Contenido parcial: indica que la respuesta solo contiene contenido parcial. Las cabeceras adicionales indican el rango exacto y la información de caducidad del contenido.

3xx: Redirección

404 indica que el recurso no es válido y no existe en el servidor.

Esto requiere que el cliente tome medidas adicionales. El caso de uso más común es saltar a una URL distinta para capturar el recurso.

  • 301 Movido permanentemente: el recurso se encuentra ahora en una nueva dirección URL.
  • 303 Véase otro: el recurso se encuentra de forma temporal en una nueva dirección URL. La cabecera de respuesta Location contiene la dirección URL temporal.
  • 304 No modificado: el servidor ha determinado que el recurso no ha cambiado y el cliente debe utilizar su copia almacenada en caché. Esto se basa en el hecho de que el cliente está enviando ETag (Etiqueta de entidad) información que es un hash del contenido. El servidor compara esto con su propia ETag calculada para comprobar si hay modificaciones.

4xx: Error del cliente

Estos códigos se utilizan cuando el servidor piensa que el error parte del cliente, ya sea solicitando un recurso no válido o realizando una solicitud incorrecta. El código más popular en esta clase es 404 Not Found, con el que creo que todos nos identificamos. 404 indica que el recurso no es válido y no existe en el servidor. El resto de códigos en esta clase incluyen:

  • 400 Mala petición: la solicitud está mal formada.
  • 401 No autorizado: la solicitud requiere autenticación. El cliente puede repetir la solicitud con la cabecera Authorization. Si el cliente ya incluyó la cabecera Authorization, las credenciales eran incorrectas.
  • 403 Prohibido: el servidor ha denegado el acceso al recurso.
  • 405 Método no permitido: verbo HTTP no válido utilizado en la línea de solicitud o el servidor no admite ese verbo.
  • 409 Conflicto: el servidor no pudo completar la solicitud porque el cliente está intentando modificar un recurso que es más reciente que el sello de tiempo del cliente. Los conflictos surgen principalmente para las solicitudes PUT durante las ediciones colaborativas en un recurso.

5xx: Error del servidor

Esta clase de códigos se utiliza para indicar un error del servidor al procesar la solicitud. El código de error más utilizado es 500 Error interno del servidor. Los otros en esta clase son:

  • 501 No implementado: el servidor aún no admite la funcionalidad solicitada.
  • 503 Servicio no disponible: esto podría suceder si un sistema interno en el servidor ha fallado o el servidor está sobrecargado. Normalmente, el servidor ni siquiera responderá y la solicitud agotará el tiempo de espera.

Formatos de mensajes de solicitud y respuesta

Hasta ahora, hemos visto que las URLs, los verbos y los códigos de estado conforman partes fundamentales de un par de solicitud/respuesta HTTP.

Echemos ahora un vistazo al contenido de estos mensajes. La especificación HTTP indica que un mensaje de solicitud o una respuesta tiene la siguiente estructura genérica:

Es obligatorio colocar una nueva línea entre las cabeceras del mensaje y el cuerpo. El mensaje puede contener una o más cabeceras, las cuales se clasifican de forma general en:

El cuerpo del mensaje puede contener los datos completos de la entidad, o puede ser fragmentado si se utiliza la codificación fragmentada (Transfer-Encoding: chunked). Todos los clientes HTTP/1.1 deben aceptar la cabecera Transfer-Encoding.

Cabeceras genéricas

Hay algunas cabeceras (cabeceras genéricas) que son compartidas por los mensajes de solicitud y respuesta:

Ya hemos visto algunas de estas cabeceras, específicamente Via y Transfer-Encoding. Cubriremos Cache-Control y Connection en la segunda parte.

El código de estado es importante e indica al cliente cómo interpretar la respuesta del servidor.

  • La cabecera Via se utiliza en un mensaje TRACE y se actualiza por todos los proxies intermitentes y puertas de enlace
  • Pragma es considerada una cabecera personalizada y puede usarse para incluir cabeceras específicas de implementación. La directiva pragma más utilizada es Pragma: no-cache, que realmente es Cache-Control: no-cache bajo HTTP/1.1. Esto se tratará en la Parte 2 del artículo.
  • El campo Date de la cabecera se utiliza para marcar el mensaje de solicitud/respuesta con una sello del tiempo
  • Upgrade se utiliza para cambiar los protocolos y permitir una transición suave a un protocolo más reciente.
  • Transfer-Encoding se utiliza generalmente para dividir la respuesta en partes más pequeñas con el valor Transfer-Codification: chunked. Esta es una nueva cabecera en HTTP/1.1 y permite la transmisión de respuesta al cliente en sustitución de una carga grande.

Cabeceras de entidad

Los mensajes de solicitud y respuesta también pueden incluir cabeceras de entidad para proporcionar metainformación sobre el contenido (también conocido como Message Body o Entity). Estas cabeceras incluyen:

Todos las cabeceras con prefijo Content- proporcionan información sobre la estructura, la codificación y el tamaño del cuerpo del mensaje. Algunas de estas cabeceras deben estar presentes si la entidad forma parte del mensaje.

La cabecera Expires indica un sello de tiempo que indica cuándo expira la entidad. Curiosamente, una entidad "nunca caduca" se envía con un sello de tiempo de un año adelante. La cabecera Last-Modified indica el último sello de tiempo de modificación de la entidad.

Las cabeceras personalizadas también pueden ser creadas y enviadas por el cliente; serán tratadas como cabeceras de entidad por el protocolo HTTP.

Esto es realmente un mecanismo de extensión, y algunas implementaciones cliente-servidor pueden optar por comunicarse específicamente a través de estas cabeceras de extensión. Aunque HTTP admite cabeceras personalizadas, lo que realmente busca son las cabeceras de solicitud y respuesta, algo que vamos a tratar a continuación.

Formato de solicitud

El mensaje de solicitud tiene la misma estructura genérica que la anterior, excepto para la línea de solicitud que tiene el siguiente aspecto:

SP es el separador de espacio entre los tokens. HTTP-Version se especifica como "HTTP/1.1" y después va seguido de una nueva línea. Por lo tanto, un mensaje de solicitud típico podría tener el siguiente aspecto:

Observa como la línea de solicitud va seguida de muchas cabeceras de solicitud. La cabecera Host es obligatoria para los clientes HTTP/1.1. Las solicitudes GET no tienen un cuerpo de mensaje, pero las solicitudes POST pueden contener los datos de entrada en el cuerpo.

Las cabeceras de solicitud actúan como modificadores del mensaje de solicitud. La lista completa de cabeceras de solicitud conocidas no es demasiado larga y la proporcionamos a continuación. Las cabeceras desconocidas se tratan como campos de cabecera de entidad.

Las cabeceras con prefijo Accept indican los tipos de medios, idiomas y conjuntos de caracteres aceptables por el cliente. From, Host, Referer y User-Agent identifican los detalles sobre el cliente que inició la solicitud. Las cabeceras con prefijo If- se utilizan para hacer que una solicitud sea más condicional y el servidor devuelve el recurso solo si la condición se cumple. De lo contrario, devuelve un 304 Not Modified. La condición se puede basar en un sello de tiempo o un ETag (un hash de la entidad).

Formato de respuesta

El formato de respuesta es similar al mensaje de solicitud, excepto la línea de estado y las cabeceras. La línea de estado tiene la siguiente estructura:

  • La versión HTTP se envía como HTTP/1.1
  • El código de estado es uno de los muchos estados discutidos anteriormente.
  • La frase de motivo es una versión legible del código de estado.

Una línea de estado típica para una respuesta correcta podría tener ese aspecto:

Las cabeceras de respuesta también son bastante limitadas, y el conjunto completo se muestra a continuación:

  • Age es el tiempo en segundos desde que se generó el mensaje en el servidor.
  • ETag es el hash MD5 de la entidad y se utiliza para comprobar si hay modificaciones.
  • Location se utiliza cuando se envía una redirección y contiene la nueva dirección URL.
  • Server identifica el servidor que genera el mensaje.

Ha habido mucha teoría hasta este punto, así que no te culparé si sientes los ojos somnolientos. Las siguientes secciones, serán más prácticas y realizaremos una encuesta sobre las herramientas, frameworks y bibliotecas.


Herramientas para ver el tráfico HTTP

Existen una serie de herramientas para supervisar la comunicación HTTP. Aquí, enumeramos algunas de las más populares.

Sin duda, el inspector de Chrome/Webkit es uno de los favoritos entre los desarrolladores web:

También hay proxies de depuración web, como Fiddler para Windows y Charles Proxy para OSX. Mi colega, Rey Bango escribió un excelente artículo sobre este tema.

Fiddler
Charles Proxy

Para la línea de comandos, disponemos de utilidades como curl, tcpdump y tshark para supervisar el tráfico HTTP.


Uso de HTTP en frameworks y bibliotecas web

Ahora que hemos examinado los mensajes de solicitud/respuesta, es hora de que aprendamos cómo las bibliotecas y los frameworks los exponen en forma de una API. Usaremos ExpressJS for Node, Ruby on Rails y jQuery Ajax como nuestros ejemplos.

ExpressJS

Si estás creando servidores web en NodeJS, es muy probable que hayas considerado ExpressJS. ExpressJS se inspiró originalmente en un framework Ruby Web, llamado Sinatra. Como era de esperar, la API también está igualmente influenciada.

Dado que estamos tratando con un framework del lado del servidor, hay dos tareas principales en relación a los mensajes HTTP:

  • Leer fragmentos de URL y cabeceras de solicitud.
  • Escribir cabeceras y cuerpos de respuesta

Es crucial comprender HTTP para tener una interfaz limpia, simple y tranquila entre dos puntos finales.

ExpressJS proporciona una API sencilla para hacer precisamente eso. No cubriremos los detalles de la API. En su lugar, proporcionaremos enlaces a la documentación detallada disponible en las guías de ExpressJS. Los métodos de la API se explican por sí mismos en la mayoría de los casos. A continuación se muestra una muestra de la API relacionada con la solicitud:

Al salir al cliente, ExpressJS proporciona la siguiente API de respuesta:

  • res.status: establece un código de estado explícito.
  • res.set: establece una cabecera de respuesta específica.
  • res.send: envia HTML, JSON o un octet-stream.
  • res.sendFile: transfiere un archivo al cliente.
  • res.render: representa una plantilla de vista rápida.
  • res.redirect: redirige a una ruta diferente. Express añade automáticamente el código de redirección predeterminado de 302.

Ruby on Rails

Los mensajes de solicitud y respuesta son en su mayoría los mismos, excepto para las cabeceras de primera línea y mensaje.

En Rails, los módulos ActionController y ActionDispatch proporcionan la API para controlar los mensajes de solicitud y respuesta.

ActionController proporciona una API de alto nivel para leer la dirección URL de la solicitud, representar la salida y redirigir a un punto final diferente. Un punto final (también conocido como  "aka route") es controlado como un método de acción. La mayor parte de la información de contexto necesaria dentro de un método de acción se proporciona a través de los objetos request, response y params.

  • params: da acceso a los parámetros de URL y datos POST.
  • request: contiene información sobre el cliente, las cabeceras y la dirección URL.
  • response: se utiliza para establecer cabeceras y códigos de estado.
  • render: renderiza vistas expandiendo plantillas.
  • redirect_to: redirige a un método de acción o una URL diferente.

ActionDispatch proporciona acceso detallado a los mensajes de solicitud/respuesta, a través de las clases ActionDispatch::Request y ActionDispatch::Response. Expone un conjunto de métodos de consulta para comprobar el tipo de solicitud (get?(), post?(), head?(), local?()). Se puede acceder directamente a las cabeceras de solicitud a través del método request.headers() .

En el lado de la respuesta, proporciona métodos para establecer cookies(), location=() y status=(). Si te sientes aventurero, también puedes configurar body=() y omitir el sistema de renderizado de Rails.

jQuery Ajax

Dado que jQuery es principalmente una biblioteca del lado cliente, su API de Ajax proporciona lo contrario a un framework del lado del servidor. En otras palabras, le permite leer mensajes de respuesta y modificar mensajes de solicitud. jQuery expone una API simple a través de jQuery.ajax(settings):

Al pasar un objeto settings con la devolución de llamada beforeSend, podemos modificar las cabeceras de solicitud. La devolución de llamada recibe el objeto jqXHR (jQuery XMLHttpRequest) que expone un método, denominado setRequestHeader() para establecer las cabeceras.

  • El objeto jqXHR también se puede utilizar para leer las cabeceras de respuesta con jqXHR.getResponseHeader().
  • Si deseas realizar acciones específicas para varios códigos de estado, puedes utilizar la devolución de llamada statusCode:

Resumen

Así que esto resume nuestro rápido recorrido por el protocolo HTTP.

Hemos revisado la estructura de URLs, los verbos y los códigos de estado: los tres pilares de la comunicación HTTP.

Los mensajes de solicitud y respuesta son en su mayoría los mismos, excepto para las cabeceras de primera línea y mensaje. Por último, hemos revisado cómo puedes modificar las cabeceras de solicitud y respuesta en frameworks y bibliotecas web.

Comprender HTTP es crucial para tener una interfaz limpia, simple y tranquila entre dos puntos finales. A mayor escala, también ayuda a diseñar la infraestructura de tu red y proporcionar una gran experiencia a los usuarios finales.

En la segunda parte, ¡revisaremos la gestión de conexiones, la autenticación y el almacenamiento en caché! Hasta luego.


Referencias

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.