sábado, 1 de marzo de 2014

miniServidor Web en Windows

Mirando un poco cómo hacer una pequeña aplicación en lenguaje C para probar Sockets y comunicar programas a través de TCP/IP, encontré que el compilador LCC-Win trae una biblioteca llamada netutils.h dejando el asunto fácil y muy interesante.

Adaptando un poco el ejemplo de la aplicación servidor que trae la documentación, decidí dar un repaso al protocolo HTTP y crear un pequeño servidor Web.

El funcionamiento de este miniServidor Web sería muy sencillo y no cumpliría mucho con el estándar, pero para ver cómo funciona por dentro está bien. Lo que hace es lo siguiente:

  • Leer un archivo HTML dado como parámetro.
  • Iniciar una sesión de conexión a un Socket en la IP 127.0.01 en el puerto 10000.
  • Esperar una conexión de un navegador web.
  • Cuando reciba una conexión, visualiza la información recibida (las cabeceras HTTP del navegador).
  • Preparar las cabeceras HTTP de respuesta.
  • Leer el archivo HTML dado y agregarlo a las cabeceras anteriores.
  • Enviar la respuesta al navegador (cabeceras HTTP y el HTML).
  • Visualizar los datos enviados.

El código fuente sería el siguiente (servidor.c):

#include <stdio .h>
#include "netutils.h"

int main(int argc,char *argv[])
{
  while (1)
  {
    FILE* pf;
    if ((pf = fopen(argv[1],"rt")) == NULL)
    {
      puts("Error abriendo html.");
      return 1;
    }
    
    Session session; 
    char buf[8192];
    memset(&session,0,sizeof(session));
    session.port = 10000;
    session.Host = "127.0.0.1";
    
    if (ServerConnect(&session)){ return 0; }

    printf("Conectado...\n");
    memset(buf,0,sizeof(buf));
    
    if (Receive(&session,sizeof(buf)-1,buf)){ return 0; }
    
    printf("Datos recibidos:\n\n %s\n",buf);

    char texto[1000000] = "HTTP/1.1 200 OK\nContent-Type: text/html\n\n";

    int c, i = strlen(texto);

    while ( (c=getc(pf) ) != EOF){ texto[i] = c; i++; }
    texto[i] = '\0';

    fclose(pf);    
    
    if (Send(&session,strlen(texto),texto)){ return 0; }

    printf("Datos enviados:\n\n %s\n", texto);

    CloseSession(&session);

    printf("\nConexion cerrada.\n");
  }
}

Una vez creado servidor.c, en la misma carpeta creamos el archivo HTML que queremos publicar en nuestro miniServidorWeb (holamundo.html), cuyo código sería el siguiente:

<html>
<head>
  <title>Titulo>/title>
</head>
<body>
  <p><h1>Hola Mundo</h1></p>
</body>
</html>

Asumiendo que  LCC-Win está instalado en c:\lcc y que tenemos la ruta de los binarios del compilador (c:\lcc\bin) incluida en la variable PATH del sistema, ya podemos compilar y enlazar:

    lcc servidor.c
    lcclnk servidor.obj c:\lcc\lib\netutils.lib

Con esto tendremos el ejecutable servidor.exe creado, que es nuestro miniServidor Web. Lo ejecutamos dándole como parámetro el nombre del archivo HTML a publicar:

    servidor.exe holamundo.html

Y el miniServidor Web quedará a la escucha en el puerto 10000 de la IP 127.0.0.1, datos proporcionados en el código fuente. Ahora le toca al cliente, vamos al navegador Web y tecleamos la URL:

    http://127.0.0.1:10000

Con esto el navegador Web conecta con la IP indicada en el puerto 10000 y recupera nuestro HTML.

Mientras, en la ventana donde ejecutamos el miniServidor Web aparecerán los datos recibidos y los enviados en cada sesión HTTP.

Y ahí lo tienes, el servidor Web más pequeño del mundo.