Tabla de Contenidos

02 - Servidor HTTP sobre sockets

HTTP es un protocolo de aplicación sobre TCP: el cliente envía una petición con formato definido y el servidor responde con una respuesta también con formato definido. Como el formato es texto, un servidor HTTP puede construirse con los sockets del tema anterior.

1. Formato de una petición

GET /books/42 HTTP/1.1
Host: localhost:8080
Accept: application/json

2. Formato de una respuesta

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 39

{"id":42,"title":"Código limpio"}

Código Significado
200 OK
201 Recurso creado
400 Petición mal formada
404 No encontrado
500 Error del servidor

3. Servidor mínimo

public class HttpServer {
    public static void main(String[] args) throws IOException {
        try (ServerSocket serverSocket = new ServerSocket(8080)) {
            while (true) {
                try (Socket socket = serverSocket.accept()) {
                    handle(socket);
                }
            }
        }
    }

    private static void handle(Socket socket) throws IOException {
        BufferedReader in = new BufferedReader(
                new InputStreamReader(socket.getInputStream()));
        PrintWriter out = new PrintWriter(socket.getOutputStream());

        String requestLine = in.readLine();          // GET /books/42 HTTP/1.1
        String route = requestLine.split(" ")[1];
        readHeaders(in);                             // hasta la línea vacía

        String body = "{\"message\":\"Hello from " + route + "\"}";
        out.print("HTTP/1.1 200 OK\r\n");
        out.print("Content-Type: application/json\r\n");
        out.print("Content-Length: " + body.getBytes().length + "\r\n");
        out.print("\r\n");
        out.print(body);
        out.flush();
    }

    private static void readHeaders(BufferedReader in) throws IOException {
        String line;
        while ((line = in.readLine()) != null && !line.isEmpty()) {
            // procesar cada cabecera si hace falta
        }
    }
}

Con un navegador o curl contra http://localhost:8080/books/42 se obtiene la respuesta JSON.

4. Lo que falta

Necesidad Solución que llega después
Atender varias peticiones a la vez Hilos (tema siguiente)
Parsear rutas, parámetros y cuerpos completos Servlets y Tomcat
Devolver archivos, páginas, errores estándar El contenedor lo resuelve
Este servidor cumple el protocolo, pero es secuencial: una sola petición a la vez. Es la motivación exacta de por qué los servidores reales usan un pool de hilos.