HTTP
Cómo se nombra un recurso, qué es exactamente el modelo petición-respuesta, cómo están construidos los dos mensajes, qué cabeceras hay que reconocer y cómo se valida la caché.
URI, URL y URN: nombrar y localizar
Antes de pedir nada hay que saber nombrarlo. Una URI es un identificador de recurso: una cadena que designa una cosa de forma inequívoca. Es el concepto general, y de él cuelgan dos formas concretas que se confunden a menudo.
| Forma | Qué aporta | Esquemas típicos |
|---|---|---|
| URL | Localiza: dice dónde está el recurso y cómo llegar a él | http:, https:, ftp:, mailto:, file: |
| URN | Nombra: identifica el recurso de forma persistente, sin decir dónde está | urn: |
Una URN sigue identificando el mismo recurso aunque este cambie de servidor, precisamente porque no menciona ninguno. Su formato es urn seguido del espacio de nombres y del identificador dentro de ese espacio, como en urn:isbn:9788412345678, donde isbn es la temática y el resto el valor.
https://www.llegandoalcorte.com/estudio/sistemas/internet-http-y-tls?nivel=1#tls
https esquema (protocolo)
www.llegando… autoridad (nombre de máquina y, si hiciera falta, puerto)
/estudio/… ruta del recurso dentro del servidor
nivel=1 cadena de consulta, tras el signo de interrogación
tls fragmento, tras la almohadilla: no viaja al servidorToda URL es una URI y toda URN es una URI, pero no al revés. La diferencia está en el verbo: la URL localiza, la URN identifica.
Para el examen
URI: el concepto general
URL: LOCALIZA: dice dónde y cómo
URN: solo NOMBRA, de forma persistente
Relación: toda URL es una URI, pero no al revés
Qué es HTTP y por qué no tiene estado
HTTP es el protocolo de la capa de aplicación con el que un cliente pide recursos a un servidor. Funciona con un modelo de petición y respuesta: el cliente envía una petición, el servidor devuelve exactamente una respuesta, y ahí se acaba el intercambio. Hasta HTTP/1.1 los mensajes eran texto legible, igual que en SMTP, POP3 o FTP.
Se apoya en TCP, en el puerto 80 cuando va en claro y en el 443 cuando va sobre TLS. Antes de que salga la primera petición hacen falta dos pasos que no son de HTTP: resolver el nombre del servidor a una dirección IP, que es cosa del servicio de nombres, y establecer la conexión de transporte, que es cosa de TCP. Los dos tienen su tema propio en este bloque.
La decisión de diseño que más consecuencias tiene es que HTTP no tiene estado. El servidor atiende cada petición como si fuese la primera que ve: no recuerda quién preguntó hace un segundo ni qué le contestó. Se pensó así para servir documentos enlazados entre sí, no para sostener aplicaciones con usuarios identificados, y por eso hizo falta añadir por encima un mecanismo que devolviera la memoria perdida, que son las cookies.
Sin estado significa que la petición número dos no sabe nada de la número uno. Todo lo que el servidor necesite saber tiene que venir dentro de cada petición.
Para el examen
Su propiedad clave: no tiene estado
Qué implica: cada petición es independiente
Por eso hacen falta: cookies, sesiones y testigos
Cómo está hecha una petición
Una petición tiene siempre las mismas cuatro partes y en el mismo orden: la línea de petición, las cabeceras, una línea en blanco y, si lo hay, el cuerpo.
- Línea de petición: el método, la ruta del recurso y la versión del protocolo, separados por espacios.
- Cabeceras: una por línea, con el formato nombre, dos puntos y valor. Aportan el contexto de la petición.
- Línea en blanco: no es decorativa, es el separador. Marca dónde acaban las cabeceras.
- Cuerpo: los datos que se envían, si el método los lleva. En un GET normalmente no hay cuerpo.
POST /api/intentos HTTP/1.1
Host: www.llegandoalcorte.com
User-Agent: Mozilla/5.0
Accept: application/json
Accept-Language: es-ES
Accept-Encoding: gzip, deflate
Content-Type: application/json
Content-Length: 74
{"alumno": 482, "tema": "internet-http-y-tls", "aciertos": 47, "total": 50}La cabecera Host es obligatoria desde HTTP/1.1 y tiene un motivo muy concreto: la petición viaja a una dirección IP, y en una sola dirección IP puede haber alojados decenas de sitios distintos. Sin Host, el servidor no sabría cuál de ellos se le está pidiendo.
Para el examen
Línea inicial: método, recurso y versión
Después: cabeceras, línea en blanco y cuerpo opcional
Cabecera obligatoria desde HTTP/1.1: Host
Cómo está hecha una respuesta
La respuesta es simétrica y cambia solo la primera línea. En lugar de una línea de petición lleva una línea de estado, con la versión del protocolo, el código numérico y una frase corta que lo describe y que solo está ahí para que una persona lo lea.
HTTP/1.1 201 Created
Date: Sun, 16 Aug 2026 09:14:22 GMT
Server: nginx
Location: /api/intentos/9137
Content-Type: application/json; charset=utf-8
Content-Length: 58
Cache-Control: no-store
{"id": 9137, "aciertos": 47, "total": 50, "nota": 9.4}El cuerpo de la respuesta no tiene por qué ser una página: puede ser una imagen, un PDF, un JSON o nada en absoluto. Lo que declara de qué se trata es Content-Type, con un tipo MIME, y lo que declara cuánto ocupa es Content-Length. Si el servidor no sabe de antemano el tamaño, usa Transfer-Encoding: chunked y va enviando el cuerpo por trozos.
Petición y respuesta comparten estructura: primera línea, cabeceras, línea en blanco y cuerpo. Lo único que cambia es esa primera línea, que en la petición lleva el método y en la respuesta el código de estado.
Para el examen
Línea inicial: versión, código y frase
Content-Type: dice de qué tipo es lo que llega
Las cabeceras que hay que reconocer
Las cabeceras son el mecanismo con el que cliente y servidor se ponen de acuerdo sin cambiar el protocolo. Las genera el navegador en la petición y el servidor en la respuesta, y casi todas las preguntas van de saber a cuál de los dos lados pertenece cada una.
| Cabecera de petición | Para qué sirve |
|---|---|
| Host | Qué sitio de los alojados en esa IP se está pidiendo |
| User-Agent | Identifica al navegador o programa cliente |
| Accept | Qué tipos MIME sabe interpretar el cliente |
| Accept-Language | En qué idioma prefiere la respuesta |
| Accept-Encoding | Qué compresiones acepta, como gzip o deflate |
| Accept-Charset | Qué juego de caracteres admite |
| Authorization | Las credenciales, por ejemplo con el esquema Basic o Bearer |
| Cookie | Devuelve al servidor todas las cookies válidas para ese dominio |
| Content-Type y Content-Length | Tipo y tamaño del cuerpo que se envía |
| Range | Pide solo un fragmento del recurso, en bytes |
| Connection | Si la conexión se mantiene abierta (keep-alive) o se cierra |
| Cabecera de respuesta | Para qué sirve |
|---|---|
| Server | Identifica al servidor web, por ejemplo Nginx o Apache |
| Date | Fecha y hora en que se generó la respuesta |
| Content-Type y Content-Length | Tipo MIME y tamaño del cuerpo devuelto |
| Content-Encoding | Con qué algoritmo viene comprimido el cuerpo |
| Content-Range | Qué fragmento se devuelve, cuando se pidió un rango |
| Content-Disposition | Si el contenido se muestra o se descarga, y con qué nombre |
| Transfer-Encoding | Envío por trozos cuando no se conoce el tamaño total |
| Location | A qué dirección debe ir el cliente, en redirecciones y creaciones |
| Last-Modified | Cuándo cambió por última vez el recurso |
| Cache-Control | Durante cuánto tiempo y en qué condiciones se puede guardar |
| WWW-Authenticate | El reto de autenticación que acompaña a un 401 |
| Set-Cookie | Ordena al navegador guardar una cookie |
| Access-Control-Allow-Origin | Qué orígenes pueden leer la respuesta desde otro dominio |
Conviene fijarse en las parejas que se responden entre sí: Accept-Encoding en la petición con Content-Encoding en la respuesta, Range con Content-Range, Set-Cookie con Cookie, y WWW-Authenticate con Authorization. Reconocer la pareja resuelve la pregunta aunque no se recuerde la definición exacta.
Para el examen
De identificación: Host y User-Agent
De contenido: Accept, Content-Type y Content-Length
De sesión y seguridad: Authorization, Cookie y Set-Cookie
De control: Location y Cache-Control
Caché y peticiones condicionales: ETag y el 304
Volver a descargar algo que no ha cambiado es tirar ancho de banda. HTTP lo evita con dos mecanismos encadenados: primero decide cuánto tiempo puede darse por buena una copia guardada, y después, cuando ese tiempo expira, comprueba si de verdad ha cambiado algo antes de descargar de nuevo.
Lo primero lo gobierna Cache-Control. Con max-age el servidor dice cuántos segundos vale la copia. Con no-cache no está prohibiendo guardarla, que es el error de interpretación clásico: está exigiendo que se revalide antes de usarla. Quien prohíbe guardar es no-store.
Lo segundo es la petición condicional. El servidor etiqueta el recurso con ETag, un código calculado a partir de su contenido, y el navegador lo guarda junto a la copia. En la siguiente visita lo devuelve en If-None-Match. Si el código sigue siendo el mismo, el servidor responde 304 Not Modified, sin cuerpo, y el navegador reutiliza lo que ya tenía. Existe la variante por fecha, con Last-Modified en la respuesta e If-Modified-Since en la petición.
GET /temario/internet-http-y-tls HTTP/1.1
Host: www.llegandoalcorte.com
If-None-Match: "a41f9c-2b"
HTTP/1.1 304 Not Modified
ETag: "a41f9c-2b"
Cache-Control: max-age=3600El 304 es la respuesta a una petición condicional y nunca lleva cuerpo: su mensaje es «lo que tienes guardado sigue valiendo».
Para el examen
Si el recurso no ha cambiado: el servidor responde 304
Qué tiene ese 304: ninguna carga: va SIN cuerpo
Con qué se comprueba: ETag o Last-Modified