Aller au contenu

Serveur HTTP

Objectif

Développer un serveur HTTP simple en Java capable de servir des fichiers HTML, CSS et JavaScript. Le serveur doit gérer les requêtes GET et retourner les réponses appropriées. Un journal en JSON doit également être produit sur le serveur pour stocker les requêtes.

Spécification de la requête GET

Une requête GET HTTP suit le format suivant :

GET /chemin/fichier.html HTTP/1.1
Host: localhost:8080
Connection: close

Éléments importants :

  • La première ligne contient la méthode (GET), le chemin de la ressource et la version HTTP
  • L'en-tête Host est obligatoire pour HTTP/1.1
  • Les en-têtes se terminent par une ligne vide
  • Le navigateur utilise le chemin pour localiser la ressource sur le serveur

Spécification des réponses

Réponse 200 OK

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 1234
Connection: close

<contenu du fichier>

Éléments importants :

  • La ligne de statut indique le succès avec le code 200
  • L'en-tête Content-Type doit correspondre au type de fichier :
    • text/html pour les fichiers .html
    • text/css pour les fichiers .css
    • application/javascript pour les fichiers .js
  • L'en-tête Content-Length indique la taille du contenu en octets
  • Une ligne vide sépare les en-têtes du contenu
  • Le navigateur utilise Content-Type pour interpréter correctement le fichier

Réponse 404 Not Found

HTTP/1.1 404 Not Found
Content-Type: text/html
Content-Length: 45
Connection: close

<html><body>404 - Fichier non trouvé</body></html>

Éléments importants :

  • Le code 404 indique que la ressource demandée n'existe pas
  • Retourner une page HTML simple pour informer l'utilisateur
  • Respecter le même format d'en-têtes que la réponse 200
  • Pensez à une façon pour transformer la requête format texte en objets. Par exemple, l'entête pourrait être intégré dans un HashMap<String, String> afin d'être plus facilement consultable.

Instructions de laboratoire

Étape 1 : Créer la structure du projet

Organisez votre projet avec un dossier public contenant vos ressources web :

src/
    main/
        java/
            Main.java
            HttpServer.java
public/
    index.html
    styles.css
    script.js

Étape 2 : Implémenter le serveur

  1. Créez une classe HttpServer qui écoute sur le port 8080
  2. Utilisez un ServerSocket pour accepter les connexions entrantes
  3. Parsez la première ligne de la requête pour extraire le chemin demandé
  4. Recherchez le fichier correspondant dans le dossier public
    • La classe Files intégrée à Java contient tout le nécessaire pour la gestion des fichiers
  5. Lire les entêtes et les stocker - elles pourraient être utiles plus tard

Étape 3 : Gérer les réponses

  1. Lisez le fichier demandé et détermine son type MIME (Entête Content-Type)
  2. Construisez l'en-tête HTTP avec le statut approprié
  3. Écrivez l'en-tête suivi du contenu du fichier
  4. Fermez la connexion après l'envoi

Étape 4 : Tester le serveur

  1. Démarrez le serveur
  2. Ouvrez un navigateur et accédez à http://localhost:8080/index.html
  3. Testez l'accès aux fichiers CSS et JavaScript et que leur résultat fonctionne comme prévu
  4. Testez une URL invalide pour vérifier la réponse 404

Étape 5 : Journaux JSON

Enregistrez toutes les requêtes dans un fichier JSON. Dans ce fichier, vous devriez avoir :

  • La date et l'heure
  • L'adresse IP d'où provient la requête
  • Le verbe (GET, POST, etc.)
  • Le chemin demandé (/, /index.html, etc.)
  • La requête URL (queryString, tout ce qui se trouve après le ? dans le chemin)
  • Le nom de domaine demandé (entête Host)

Voici un exemple de journal :

[
    {
        "Date": "2026-03-18 13:02:00",
        "IP": "127.0.0.1",
        "Verbe": "GET",
        "Chemin": "/index.html",
        "QueryString": "?recherche=salut",
        "Domaine": "localhost"
    },
    {
        "Date": "2026-03-18 13:02:05",
        "IP": "127.0.0.1",
        "Verbe": "GET",
        "Chemin": "/script.js",
        "QueryString": "",
        "Domaine": "localhost"
    }
]

Améliorations

Lorsque tout est fonctionnel pour les requêtes de base, voici les améliorations supplémentaires que vous pouvez apporter :

  • Créer une classe RequeteHTTP et lui envoyer la requête texte dans son constructeur. Cette classe transforme le contenu texte en objet facile d'accès. Par exemple, requeteHttp.getFichier() retournerait /index.html, tandis que requeteHttp.getEntete("Host") retournerait localhost:8000, et ainsi de suite.
  • Envoyer le fichier index.html par défaut lorsque le chemin est /
  • Permettre d'offrir des images en plus du texte
    • Au lieu d'un PrintWriter, il vous faudra utiliser un BufferedOutputStream
  • Permettre d'écrire un fichier lorsqu'une requête POST est faite vers un chemin
    • Par exemple, une requête POST vers /page.html écrira le contenu spécifié dans le fichier /page.html
  • Implanter de l'authentification de base pour les chemins /admin qui demandera un nom d'utilisateur et un mot de passe au navigateur. Regardez pour l'entête Authorization: Basic ..., l'encodage Base64 et son implémentation côté serveur et côté client.