Tabla de Contenidos

02 - Servidor HTTP

Servidor HTTP

HTTP es un protocolo de aplicación que funciona encima de TCP. Cuando escribimos un servidor HTTP, en el fondo estamos abriendo un socket TCP, recibiendo la petición y devolviendo una respuesta siguiendo el formato que dicta el protocolo HTTP.

En este caso, vamos a construir un servidor muy básico que:

Anatomía de una petición HTTP

Cuando un navegador solicita una página, envía algo parecido a:

GET / HTTP/1.1
Host: localhost:12345
User-Agent: Mozilla/5.0 ...
Accept: text/html
[... otras cabeceras ...]

Las cabeceras terminan con una línea vacía (\r\n).

Anatomía de una respuesta HTTP

El servidor debe responder con:

HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: [número de bytes del HTML]
Connection: close

<html><body><h1>Hola</h1></body></html>

Las cabeceras también terminan con una línea vacía antes del contenido.

Ciclo de vida clásico

Servidor

Cliente (navegador)

Ejemplo

HttpServer

package es.cesguiro.socket;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

public class HttpServer {

    private final int port = 12345;

    public void start() {
        System.out.println("Starting HTTP server on port " + port + "...");
        try {
            System.out.println("HTTP server started. Waiting for requests...");
            // Aceptamos UNA conexión de cliente y luego cerramos el servidor (Ejemplo simple)
            try(Socket socket = new ServerSocket(port).accept()) {
                System.out.println("Client connected: " + socket.getInetAddress());

                // Leer la solicitud HTTP del cliente
                BufferedReader in = new BufferedReader(
                        new InputStreamReader(socket.getInputStream())
                );
                String line;
                while ((line = in.readLine()) != null && !line.isEmpty()) {
                    System.out.println(line);
                }

                // HTML a devolver
                String htmlResponse = "<html><body><h1>Hello from HTTP Server!</h1></body></html>";
                byte[] content = htmlResponse.getBytes(StandardCharsets.UTF_8);

                // Cabeceras de respuesta HTTP
                String responseHeader = "HTTP/1.1 200 OK\r\n" +
                                  "Content-Type: text/html\r\n" +
                                  "Connection: close\r\n" +
                                  "\r\n";

                OutputStream out = socket.getOutputStream();
                out.write(responseHeader.getBytes(StandardCharsets.UTF_8));
                out.write(content);
                out.flush();
            } catch (IOException e) {
                System.err.println("Error handling client connection: " + e.getMessage());
            }
        } catch (Exception e) {
            System.err.println("Error starting HTTP server: " + e.getMessage());
            throw new RuntimeException("Failed to start HTTP server", e);
        }
    }
}

package es.cesguiro.socket;

public class Main {
    public static void main(String[] args) {
        HttpServer server = new HttpServer();
        server.start();
    }
}

Para probarlo, accede en tu navegador a http://localhost:12345 y debería ver el mensaje “Hello from HTTP Server!”