A. Protocolo HTTP y Aplicaciones Web

 

A.1. Protocolos y servicios de Internet

A.1.1. Protocolo TCP/IP

Internet se construye sobre el protocolo de transmisión TCP (Transmision Control Protocol), y sobre un sistema de identificación de computadores que la forman basado en el protocolo IP:

La comunicación con TCP/IP se realiza mediante sockets, conexiones entre un computador y otro a través de la que se envían datos. Puede haber más de un socket entre dos mismos ordenadores, con lo que para distinguirlos se emplea un identificador, llamado puerto

A.1.2. Otros protocolos y servicios

Se han desarrollado una serie de servicios y protocolos basados en TCP/IP y en la arquitectura cliente/servidor, donde una máquina (cliente) solicita peticiones de servicio a otra en la que suelen estar los datos y programas de aplicación (servidor). Algunos de los servicios y protocolos desarrollados son:

Para identificar los recursos de Internet se introdujeron  las URL (Uniform Resource Locator), un esquema de nomenclatura de recursos basado en especificar el protocolo utilizado, el servidor y el recurso al que se accede:

Protocolo Servidor [:Puerto] Fichero

El protocolo depende del servicio al que se quiera acceder, y el fichero es la ruta del recurso, en el espacio de direcciones del servidor. Los protocolos de esta nomenclatura corresponden con algunos de los servicios mencionados:

Ejemplos de URL serían:

http://www.ua.es/index.htm
ftp://ftp.dccia.ua.es/pub/winzip.exe
mailto:pepe@yahoo.com

Los navegadores son clientes que permiten utilizar la mayoría de los protocolos anteriores. Traducen las URL en peticiones al servicio correspondiente.

 

A.2. El protocolo HTTP

El protocolo HTTP especifica el modo de comunicación entre una máquina cliente y una máquina servidor, de modo que el cliente solicita un documento del espacio de direcciones del servidor, y éste se lo sirve.

HTTP es un protocolo que no tiene estado: un cliente realiza una petición al servidor, que contesta y la transacción acaba, con lo que en la siguiente petición que pueda realizar el mismo cliente se deben proporcionar de nuevo todos los datos necesarios para que el servidor sirva correctamente la nueva petición, no habiendo ninguna relación entre las peticiones.

A.2.1. Peticiones del cliente

En el protocolo HTTP el cliente realiza una petición que se descompone en:

Comando    URI    Protocolo

Por ejemplo:

GET   /index.html  HTTP/1.1
Clave: Valor

Por ejemplo:

Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible;MSIE5.0;Windows 98)

Tras las cabeceras, el cliente envía una línea en blanco (\r\n\r\n) para indicar el final de la sección de cabeceras.

METODO GET

El comando GET permitía al principio solicitar al servidor un documento estático, existente en su espacio de direcciones. Luego se vio que esto no era suficiente, y se introdujo la posibilidad de solicitar búsquedas al servidor, de forma que el documento no tuviera que ser necesariamente estático, sino que la búsqueda estuviera condicionada por unos determinados parámetros. Así, el comando GET tiene la forma:

GET   direccion ? parametros   version HTTP

Por ejemplo:

GET   /cgi-bin/pagina.cgi?IDIOMA=C&MODELO=a+b  HTTP/1.1

Los parámetros se indican con pares nombre=valor, separados por '&', y reciben el nombre de datos de formulario. El URI no puede contener espacios ni algunos caracteres, por lo que se utilizan códigos especiales, como el '+' para indicar espacio en blanco, u otros códigos %XX para representar otros caracteres. Uno de los trabajos más duros de los programas CGI es procesar esta cadena de parámetros para extraer la información necesaria.

OTROS METODOS

En la versión 1.1 de HTTP se definen otros métodos además de GET:

GET Y POST

Los dos métodos más comúnmente usados son GET y POST. Veremos las diferencias entre uno y otro con un ejemplo:

GET  /dir/cargaPagina.php?id=21&nombre=Pepe  HTTP/1.1
<cabeceras>
POST  /dir/cargaPagina.php  HTTP/1.1
<cabeceras>

id=21&nombre=Pepe
Vemos que los parámetros se pasan en el cuerpo de la petición, fuera de la línea del comando.

Comúnmente existen 3 formas de enviar una petición GET:

http://www.xx.com/pag.html?id=123&nombre=pepe
<a href="http://www.xx.com/pag.html?id=123&nombre=pepe">
Pulsa Aqui
</a>
<html>
<body>
<form action="http://www.xx.com/pag.html"> 
	<input type="text" name="id" value="123"> 
	<input type="text" name="nombre" value="pepe"> 
	<input type="submit" value="Enviar"> 
</form> 
</body> 
</html> 

Para enviar una petición POST, normalmente se utiliza un formulario con METHOD=POST:

<html>
<body>
<form action="http://www.xx.com/pag.html" METHOD=POST> 
	<input type="text" name="id" value="123"> 
	<input type="text" name="nombre" value="pepe"> 
	<input type="submit" value="Enviar"> 
</form> 
</body> 
</html> 

A.2.2. Respuestas del servidor

Las respuestas del servidor también tienen tres partes:

HTTP/1.0  200  OK

A.2.3. Cabeceras

Vamos a poder implementar programas que lean las cabeceras que envía un cliente (un navegador, por ejemplo) y que modifiquen el documento servido en función de dichas cabeceras (por ejemplo, enviar una página en función del idioma que se especifique). Por otra parte, podremos utilizar las cabeceras que envíe el servidor como respuesta para obligar al navegador a hacer determinadas acciones, como saltar a otra URL.

Veremos a continuación las cabeceras más comunes tanto en las peticiones de los clientes como en las respuestas de los servidores. La RFC donde se especifican estas cabeceras es la 2616.

CABECERAS DE PETICION (HTTP/1.1)

NOMBRE DESCRIPCIÓN
Accept Tipos MIME que puede manejar el cliente
Accept-Charset Conjunto de caracteres que el cliente puede manejar
Accept-Encoding Define si el navegador puede aceptar datos codificados
Accept-Language Idiomas aceptados
Authorization Para identificarse cuando se accede a páginas protegidas
Cache-Control Opciones relacionadas con el servidor proxy. Esta cabecera se llamaba Pragma en HTTP 1.0
Connection Define si el cliente es capaz de realizar conexiones persistentes (keep-alive, valor por defecto), o no (close). Nueva en HTTP 1.1
Content-Length Longitud de los datos enviados. Aplicable a peticiones POST
Content-Type Tipo MIME de los datos enviados. Aplicable a peticiones POST
Cookie Para las cookies que se manejen
From Dirección de correo electrónico responsable de la petición
Host Unica cabecera requerida por HTTP 1.1. Indica el host y el puerto tal y como se especifica en la URL original.
If-Modified-Since El cliente sólo desea el documento si ha sido modificado después de la fecha indicada en esta cabecera.
Referer URL origen de la petición. Si estamos en la página 1 y pinchamos en un enlace a la página 2, la URL de la página 1 se incluye en esta cabecera cuando se realiza la petición de la página 2.
User-Agent Cliente que está realizando la petición (normalmente muestra datos del navegador, como nombre, etc).

CABECERAS DE RESPUESTA

NOMBRE DESCRIPCIÓN
Allow Métodos disponibles (GET, POST, etc) a los que puede responder el recurso que se está solicitando
Cache-Control Dice al cliente en qué circunstancias puede hacer una caché del documento que está sirviendo:
  • public: el documento puede almacenarse en una caché
  • private: el documento es para un solo usuario y sólo puede almacenarse en una caché privada (no compartida)
  • no-cache: el documento nunca debe ser almacenado en caché
  • no-store: el documento no debe almacenarse en caché ni almacenarse localmente de forma temporal en el disco duro
  • must-revalidate: el cliente debe revalidar la copia del documento con el servidor original, no con servidores proxy intermedios, cada vez que se use
  • max-age=xxx: el documento debe considerarse caducado después de xxx segundos.

Esta cabecera se llamaba Pragma en HTTP 1.0

Content-Encoding Tipo de compresión (gzip, etc) en que se devuelve el documento solicitado
Content-Language Idioma en que está escrito el documento. En la RFC 1766 están los idiomas disponibles
Content-Length Número de bytes de la respuesta
Content-MD5 Una forma de fijar el checksum (verificación de integridad) del documento enviado
Content-Type Tipo MIME de la respuesta
Date Hora y fecha, en formato GMT, en que la respuesta ha sido generada
Expires Hora y fecha, en formato GMT, en que la respuesta debe considerarse caducada
Last-Modified Fecha en que el documento servido se modificó por última vez. Con esto, el documento se sirve sólo si su Last-Modified es mayor que la fecha indicada en el If-Modified-Since de la cabecera del cliente.
Location Indica la nueva URL donde encontrar el documento. Debe usarse con un código de estado de tipo 300. El navegador se redirigirá automáticamente a la dirección indicada en esta cabecera.
Refresh Indica al cliente que debe recargar la página después de los segundos especificados. También puede indicarse la dirección de la página a cargar después de los segundos indicados:
Refresh: 5; URL=http://www.unapagina.com
Set-Cookie Especifica una cookie asociada a la página
WWW-Authenticate tipo de autorización y dominio que debería indicar el cliente en su cabecera Authorization.

Para colocar estas cabeceras en un documento se tienen varios métodos, dependiendo de cómo estemos tratando las páginas (mediante servlets, HTML, etc). Por ejemplo, con HTML podemos enviar cabeceras mediante etiquetas META en la cabecera (<HEAD>) de la página HTML:

<META HTTP-EQUIV="Cabecera" CONTENT="Valor">

Por ejemplo:

<META HTTP-EQUIV="Location" CONTENT="http://www.unapagina.com">

A.2.4. Códigos de estado HTTP

El código de estado que un servidor devuelve a un cliente en una petición indica el resultado de dicha petición. Se tiene una descripción completa de los mismos en el RFC 2616. Están agrupados en 5 categorías:

200 OK Todo está bien
204 No Content No hay documento nuevo
301 Moved Permanently El documento está en otro lugar, indicado en la cabecera Location
302 Found Como el anterior, pero la nueva URL es temporal, no permanente.
304 Not Modified El documento pedido no ha sufrido cambios con respecto al actual (para cabeceras If-Modified-Since)
400 Bad Request Mala sintaxis en la petición
401 Unauthorized El cliente no tiene permiso para acceder a la página. Se debería devolver una cabecera WWW-Authenticate para que el usuario introduzca login y password
403 Forbidden El recurso no está disponible
404 Not Found No se pudo encontrar el recurso
408 Request Timeout El cliente tarda demasiado en enviar la petición
500 Internal Server Error Error en el servidor
501 Not Implemented El servidor no soporta la petición realizada
504 Gateway Timeout Usado por servidores que actúan como proxies o gateways, indica que el servidor no obtuvo una respuesta a tiempo de un servidor remoto

A.2.5. Cookies

Las cookies son un mecanismo general mediante el que los programas de un servidor web pueden almacenar información en la parte del cliente de la conexión. Es una forma de añadir estado a las conexiones HTTP, aunque el manejo de cookies no es parte del protocolo HTTP, pero es soportado por la mayoría de los clientes.

Las cookies son objetos de tipo:

nombre = valor

donde se asigna un valor determinado (una cadena de texto) a una variable del nombre indicado. Dicho objeto es almacenado y recordado por el servidor web y el navegador durante un período de tiempo (indicado como un parámetro interno de la propia cookie). Así, se puede tener una lista de cookies con distintas variables y distintos valores, para almacenar información relevante para cada usuario (se tienen listas de cookies independientes para cada usuario).

El funcionamiento es: el servidor, con la cabecera Set-Cookie, envía al cliente información de estado que éste almacenará. Entre la información se encuentra la descripción de los rangos de URLs para los que este estado es válido, de forma que para cualquier petición HTTP a alguna de esas URLs el cliente incluirá esa información de estado, utilizando la cabecera Cookie.

La sintaxis de la cabecera Set-Cookie es:

Set-Cookie: CLAVE1=VALOR1;...;CLAVEN=VALORN [OPCIONES]

donde OPCIONES es una lista opcional con cualquiera de estos atributos:

expires=FECHA;path=PATH;domain=DOMINIO;secure
expires=Wed, 09-Nov-1999 23:12:40 GMT

Por otra parte, cuando el cliente solicita una URL que empareja con el dominio y path de alguna cookie, envía la cabecera:

Cookie: CLAVE1=VALOR1;CLAVE2=VALOR2;...;CLAVEN=VALORN

El número máximo de cookies que está garantizado que acepte cualquier navegador es de 300, con un máximo de 20 por cada servidor o dominio. El tamaño máximo de una cookie es de 4096 bytes.

A.2.6. Algunas definiciones

RFC: los documentos RFC (Request For Comment) forman un conjunto de notas acerca de Internet. Tratan sobre diferentes aspectos de la comunicación entre computadores. Podemos encontrar información sobre todos los RFC en http://www.rfc-editor.org. Si conocemos el número de RFC, normalmente podemos encontrar el documento en http://www.rfc-editor.org/rfc/rfcXXXX.txt (sindo XXXX el número de RFC).

MIME: MIME (Multipurpose Internet Mail Extensions) es un estándar oficial de Internet que indica cómo se deben formatear los mensajes para que puedan intercambiarse entre diferentes sistemas de correo electrónico. Permite incluir cualquier tipo de dato (texto, audio, video, imágenes, etc). Las RFC que definen los tipos MIME son la 2045, 2046, 2047, 2048 y 2049. Algunos tipos comunes son:

GMT: el formato de fecha y hora GMT tiene la siguiente estructura:

Wdy, DD Mon YYYY HH:MM:SS GMT

donde:

Esta representación está basada en las RFC 822, 1036 y 1123

 

A.3. Autentificaciones

Veremos ahora algunos mecanismos que pueden emplearse con HTTP para autentificar (validar) al usuario que intenta acceder a un determinado recurso.

A.3.1. Autentificaciones elementales

El protocolo HTTP incorpora un mecanismo de autentificación básico (basic) basado en cabeceras de autentificación para solicitar datos del usuario (el servidor) y para enviar los datos del usuario (el cliente), de forma que comprobando la exactitud de los datos se permitirá o no al usuario acceder a los recursos. Esta autentificación no proporciona confidencialidad ni integridad, sólo se emplea una codificación Base64.

Una variante de esto es la autentificación digest, donde, en lugar de transmitir el password por la red, se emplea un password codificado. Dicha codificación se realiza tomando el login, password, URI, método HTTP y un valor generado aleatoriamente, y todo ello se combina utilizando el método de encriptado MD5, muy seguro. De este modo, ambas partes de la comunicación conocen el password, y a partir de él pueden comprobar si los datos enviados son correctos. Sin embargo, algunos servidores no soportan este tipo de autentificación.

A.3.2. Certificados digitales y SSL

Las aplicaciones reales pueden requerir un nivel de seguridad mayor que el proporcionado por las autentificaciones basic o digest. También pueden requerir confidencialidad e integridad aseguradas. Todo esto se consigue mediante los certificados digitales.

A.3.2.1. Criptografía de clave pública

La clave de los certificados digitales reside en la criptografía de clave pública, mediante la cual cada participante en el proceso tiene dos claves, que le permiten encriptar y desencriptar la información. Una es la clave pública, que se distribuye libremente. La otra es la clave privada, que se mantiene secreta. Este par de claves es asimétrico, es decir, una clave sirve para desencriptar algo codificado con la otra. Por ejemplo, supongamos que A quiere enviar datos encriptados a B. Para ello, hay dos posibilidades:

El encriptado con clave pública se basa normalmente en el algoritmo RSA, que emplea números primos grandes para obtener un par de claves asimétricas. Las claves pueden darse con varias longitudes; así, son comunes claves de 1024 o 2048 bits. 

A.3.2.2. Certificados digitales

Lógicamente, no es práctico teclear las claves del sistema de clave pública, pues son muy largas. Lo que se hace en su lugar es almacenar estas claves en disco en forma de certificados digitales. Estos certificados pueden cargarse por muchas aplicaciones (servidores web, navegadores, gestores de correo, etc).

Notar que con este sistema se garantiza la confidencialidad (porque los datos van encriptados), y la integridad (porque si los datos se desencriptan bien, indica que son correctos). Sin embargo, no proporciona autentificación (B no sabe que los datos se los ha enviado A), a menos que A utilice su clave privada para encriptar los datos, y luego B utilice la clave pública de A para desencriptarlos. Así, B descodifica primero el mensaje con su clave privada, y luego con la pública de A. Si el proceso tiene éxito, los datos se sabe que han sido enviados por A, porque sólo A conoce su clave privada.

A.3.2.3. SSL

SSL (Secure Socket Layer) es una capa situada entre el protocolo a nivel de aplicación (HTTP, en este caso) y el protocolo a nivel de transporte (TCP/IP). Se encarga de gestionar la seguridad mediante criptografía de clave pública que encripta la comunicación entre cliente y servidor. La versión 2.0 de SSL (la primera mundialmente aceptada), proporciona autentificación en la parte del servidor, confidencialidad e integridad. Funciona como sigue:

SSL 3.0 proporciona también soporte para certificados y autentificación del cliente. Funcionan de la misma forma que los explicados para el servidor, pero residiendo en el cliente.

 

A.4. Aplicaciones Web

Hemos visto el protocolo HTTP, pero no cómo utilizarlo para implementar una aplicación.

A.4.1. Aplicaciones en el lado del servidor

En el lado del servidor, tenemos que conseguir que nuestro servidor HTTP sea capaz de ejecutar programas de aplicación que recojan los parámetros de peticiones del cliente, los procesen y devuelvan al servidor un documento que éste pasará a su vez al cliente.

Así, para el cliente el servidor no habrá hecho nada distinto a lo estipulado en el protocolo HTTP, pero el servidor podrá valerse de herramientas externas para procesar y servir la petición solicitada, pudiendo así no limitarse a servir páginas estáticas, sino utilizar otras aplicaciones (servlets, JSP, PHP, etc) para servir documentos con contenido dinámico.

Los programas de aplicación son típicamente programas que realizan consultas a bases de datos, procesan la información resultante y devuelven la salida al servidor, entre otras tareas.

A.4.2. Aplicaciones en el lado del cliente

Se tienen muchas tecnologías relacionadas con extensiones del lado del cliente (entendiendo cliente como un navegador que interpreta código HTML). El código HTML es un código estático que sólo permite formatear la apariencia de una página y definir enlaces a otras páginas o URLs. Esto no es suficiente si queremos que el navegador realice funciones más complicadas: validar entradas de formularios, mostrar la evolución del precio de unas acciones, etc.

Para ampliar las funcionalidades del navegador (respetando el protocolo HTTP), se utilizan tecnologías como JavaScript, Applets, Flash, etc. Estas se basan en hacer que el navegador ejecute código que le pasa el servidor, bien embebido en documentos HTML (como es el caso de JavaScript), o bien mediante ficheros compilados multiplataforma (como es el caso de los Applets Java o los ficheros Flash).

 

A.5. Ejemplos

Como ejercicio acerca del protocolo HTTP, practicaremos con unos comandos HTTP y veremos la forma de trabajar del protocolo. Nos vamos a basar para ello en algunas herramientas:

A.5.1. Ejemplo de cliente y servidor HTTP

En este ZIP tenéis disponible un ejemplo de funcionamiento de cliente y servidor HTTP. El ZIP tiene 4 clases Java:

Para probar esta utilidad, primero debemos colocarnos en el directorio donde están, y compilarlas. Luego las probamos siguiendo los pasos:

1. El servidor

Para ejecutar el servidor, escribimos:

java ServidorHTTP

Aparecerá una ventana como la siguiente:

Figura 1. Ejemplo de aplicación servidor HTTP

En el cuadro superior indicamos el puerto por el que escuchará las peticiones de los clientes. Luego, pulsando en Esperar Petición se quedará a la espera de que algún cliente el envíe alguna petición

2. El cliente

Para ejecutar el cliente, escribimos:

java ClienteHTTP

Aparecerá una ventana como la siguiente:

Figura 2. Ejemplo de aplicación cliente HTTP

En los cuadros superiores indicamos la dirección del servidor al que nos conectamos (127.0.0.1, por ejemplo), y el puerto por el que dicho servidor está esperando peticiones (por defecto es el 80). Pulsando el botón de Conectar nos conectaremos con el servidor.

En el cuadro de petición del cliente escribimos el comando HTTP que le queremos enviar al servidor. Por ejemplo:

GET / HTTP/1.1
Host:127.0.0.1
<2 veces Intro para el salto de linea tras las cabeceras>

Luego, pulsando en Enviar se quedará a la espera de que el servidor le envíe la respuesta.

3. Ultimos pasos

Tras enviar el cliente la petición, en el cuadro Petición del cliente del programa servidor nos aparecerá esa misma petición.

Ahora, el servidor debe responder. Para ello, en el cuadro Respuesta del servidor (dentro de la aplicación servidor) escribimos algo como:

HTTP/1.1 200 OK
<2 veces Intro para el salto de linea tras las cabeceras>

Pulsando el botón de Enviar en el servidor se enviará esta respuesta, que aparecerá en el cuadro Respuesta del servidor de la aplicación cliente.

4. Conexión con un servidor real

Podemos utilizar la aplicación cliente para conectar con un servidor real y ver lo que devuelve. Para ello, por ejemplo ponemos como host:

www.ua.es

Luego le damos al botón de Conectar, y en el cuadro de Petición del cliente escribimos:

GET / HTTP/1.1
Host:www.ua.es
<2 veces Intro para el salto de linea tras las cabeceras>

Y el servidor nos devolverá algo como:

HTTP/1.1 200 OK
Age:965
Date: Thu,24 Oct 2002 20:52:13 GMT
Content-Length:2657
Content-Type=text/html
...

<!DOCTYPE...>
...

A.5.2. Otra utilidad: WebClient

En este ZIP tenéis otra utilidad para poder probar el protocolo HTTP. Se trata de la herramienta WebClient, desarrollada por el autor del libro Core Servlets And JavaServer Pages, para probar sus ejemplos. Es un fichero JAR que simula un cliente HTTP (el servidor al que conectar será cualquier servidor que se tenga disponible: el de nuestra máquina, o uno remoto).

Se ejecuta con:

java -jar WebClient.jar

Aparece luego una ventana como esta:

Figura 3. WebClient

En ella pondremos:

GET / HTTP/1.1
Host:www.ua.es

Tras enviar los datos de la petición, nos aparece abajo la respuesta del servidor (la misma que con la aplicación anterior):

HTTP/1.1 200 OK
Age:965
Date: Thu,24 Oct 2002 20:52:13 GMT
Content-Length:2657
Content-Type=text/html
...

<!DOCTYPE...>
...

A.5.3. Clientes más sofisticados: navegadores

El funcionamiento visto con los ejemplos de clientes HTTP anteriores es el mismo que el que emplean los navegadores, sólo que ellos permiten configurar las cabeceras de otra forma, y no presentan la respuesta del servidor como texto plano, sino que dan formato al documento enviado.