HTTP Request usando C++ puro

Necesitaba realizar un POST sobre una página que estaba en un dominio de un servidor que utilizaba VirtualHost para tener configurados varios dominos sobre una misma ip.

Hasta acá parece simple para cualquier persona con cierto conocimiento de programación de hoy en día. De hecho con lenguajes como Java o .NET es casi trivial hacerlo.

Pero se me complicó un poco cuando en el requerimiento estaba que debía hacerse con C++ usando la mínima cantidad de dependencias (inclusive librerías externas).

Busqué en internet algún código que hiciera lo que necesitaba, que no tenga una licencia prohibitiva (costosa, inusable, o sencillamente demasiado compleja para resolver el problema en cuestión), y que sea simple y funcionara. Me costó, pero encontré una implementación que parecía cumplir con mis requisitos.

Pero cuando la fui a probar, no funcionaba. La página que debía acceder me decía forbidden. ¿Pero cómo era posible esto si cuando accedía con Firefox veía bien la página?

Entonces recurrí el viejo y querido telnet para ver que estaba pasando de la siguiente manera:

[email protected]:~$ telnet dominio-en-shared-hosting.com 80
Trying xx.xx.xx.xx...
Connected to dominio-en-shared-hosting.com.
Escape character is '^]'.
GET /

Y para mi sorpresa, lo que veía con telnet era el mismo forbidden.
Investigando un poco sobre el protocolo entendí lo que estaba sucediendo.

Para que los VirtualHost de apache funcionen correctamente, en la petición HTTP se tiene que especificar cual es el dominio al que se intenta acceder, si no se especifica se intenta acceder al default, que es el primero de los virtualhost definidos.

¿Pero como se especifica el dominio? Bueno, la forma más facil es escribir en lugar de GET / la url completa del recurso, por ejemplo GET http://dominio-en-shared-hosting.com/ de esta forma Apache puede diferenciar el VirtualHost al que se quiere acceder.

Otra forma, es especificando una versión del protocolo 1.0 o superior y agregando el header Host. Ya no sería un GET y nada más, sino que habria que escribir dos lineas.

GET / HTTP/1.0
Host: dominio-en-shared-hosting.com

Al usar esta forma, es necesario dejar un enter despues de ingresar la linea de Host (o si se quieren más headers, despues del último header) para que el servidor entienda cuando se dejó de escribir el request y procese la página.


Discussion Area - Leave a Comment