From a47ae80e69c00b09e260f141e340f88c13c7d958 Mon Sep 17 00:00:00 2001 From: Minh VU Date: Mon, 24 Feb 2025 15:58:57 +0100 Subject: [PATCH] Update readme il manque ex2 partie 2 --- README.md | 158 +++++++----------- images/p1_ex3_2clients.png | Bin 0 -> 29964 bytes .../java/fr/istic/pr/serveur/HTTPHandler.java | 27 ++- 3 files changed, 70 insertions(+), 115 deletions(-) create mode 100644 images/p1_ex3_2clients.png diff --git a/README.md b/README.md index 2ac5176..3d5ade3 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,15 @@ Le 4 février 2025 Nous nous sommes inspirés du cours pour implémenter le serveur écho. ### EXERCICE 2 : Test et capture -![Echo sur client utilisant ClientHandlerBytes](images/p1_ex2_bytes.png) - +Après lancé le serveur, on a ouvert un terminal cmd sur windows pour tester: +``` +ncat localhost 8080 +Hello World! +Hello World! +Je teste, je suis content, je dors +Je teste, je suis content, je dors +^C +``` Quand on voit le contenu du TCP, on voit tout le texte d'échange mais on voit qu'il y a un espace entre chaque 8 caractères quand on passe la taille du buffer. Et à la fin du caractère, nous pouvons voir le dernier caractère pour déterminer la fin du texte. ![Follow> TCP Stream](images/p1_ex2_wireshark.png) @@ -27,45 +34,69 @@ Dans le texte "Je teste, je suis content, je dors" nous avons 99 octets, dont 64 ### EXERCICE 3 : Version Multithreadée Dans cet exercice, on réussit à créer un multi thread pour 4 personnes seulement, on teste avec le 5ème et il ne peut pas être "echo" +On peut voir dans l'image qu'on a 2 clients demandent l'accès du serveur: +Paquet no.49 et 51 sont client 1 et paquet 324 et 326 sont client 2. +![Multi_threadée_2_clients](images/p1_ex3_2clients.png) ## Partie II: Implémentation d’un client HTTPping ### EXERCICE 1 : Analyse du protocole HTTP -``` -On vous demande de produire une capture de l’intéraction entre votre navigateur et le site http://example.com. - -Vous devrez utiliser “Follow TCP Stream” - -En vous aidant de la spécification ou de Wikipedia. - Coté requête : - -Quel est le rôle de la première ligne ? ( GET / HTTP/1.1 ): -Càd on a demandé les resources sur la racine de example.com avec la version HTTP 1.1 - -Décrivez le rôle des options : “Accept-Encoding:”, “Accept:” et “Connection: keep-alive” ? - -Accept-Encoding - -Coté serveur : - -Décrire la première ligne. A quoi sert le code de réponse ? -Trouvez un site dont la réponse est 404 ou 403. -En vous aidant de la spec décrivez les grandes étapes du protocole pour la récupération d’une page ? -Par la suite nous vous suggérons d’utiliser l’option “Connection: Close” dans les réponses. +1. Ex: La première ligne `GET / HTTP/1.1` est la ligne de requête avec structure: ``` +Méthode Lien Version_de_HTTP +``` + +2. Rôle des options: +- Accept-Encoding: L'encodage que le client peut comprendre +- Accept: Type de conetnu que le client peut accepter +- Connection: keep-alive: C'est une intruction qui permets de rester ouvert pour multiples requêtes/ réponses HTTP + +Cote serveur: +1. La première ligne est la ligne de status avec structure: +``` +Version_de_HTTP Code_de_status Message +``` +2. On ne peut pas trouver un siteweb qui retourne 404. On a testé avec nombreux de sitewebs et reçu 400 Bad Request. +Donc on a utiliser localhost de 3ème partie qui lance test.html et change à abc.html pour créer erreur 404 +``` +ncat localhost 8080 +GET /a.html HTTP/1.1 +HTTP/1.1 404 File Not Found +Content-Type: text/html +Connection: close +``` + +3. Les étapes du protocole pour la récupération d’une page: + - Le client demande la connexion + - Le client envoie les requêtes + - Serveur va vérifier et connecter + - Serveur verra s'il existe le web page + - Serveur renvoie le résultat et son contenu si c'est possible + - Fermeture la connexion + ### Exercice 2 : Récupération d’une page avec netcat ``` Pensez à faire un retour à la ligne. -example.com supporte-t-il le protocole HTTP/1.0 ? +example.com supporte-t-il le protocole HTTP/1.0 quel est l’encodage utilisé pour le type de retour ? que se passe-t-il si vous ajoutez “Accept-Encoding : gzip” ? ``` ### Exercice 3, Implémentation du HTTP ping ### Exercice 4 : Socket securisée -![Teste HTTPS avec ncat](images/p2_ex4_https.png) +On test avec google.fr et on a reçu ce résultat: +``` +ncat --ssl google.fr 443 +GET / HTTP/1.0 + +HTTP/1.0 200 OK +Date: Tue, 04 Feb 2025 22:57:57 GMT +Expires: -1 +Cache-Control: private, max-age=0 +Content-Type: text/html; charset=ISO-8859-1 +``` Ensuite, nous devons changer `GET / HTTP/1.1` en `GET / HTTP/1.0` pour détecter https, son port et créer SSLSocketFactory pour détecter le http sécurisé. On lance wireshark et obtient le message crypté. Malheureusement, je ne peux pas mettre le fichier pcapng car j'utilise l'adresse IP chez moi. @@ -78,78 +109,5 @@ Vérification de message encrypté: ![Message encrypté](images/p2_ex4_ecrypted.png) ## Partie III : Implémentation d’un serveur HTTP simple - -## Utilisation - -Pour utiliser ce tp vous devez : - -1. le forker via le lien fork ci-dessus. -2. Votre repository doit être **privé**. Vous devez le partager avec votre encadrant de TP. -3. vous obtiendrez un nouveau lien : par exemple git@gitlab.istic.univ-rennes1.fr:monpseudo/tp1.http.git -4. Dans le **workspace d'eclipse** faites `git clone git@gitlab.istic.univ-rennes1.fr:monpseudo/tp1.http.git` avec l'url précédente. -5. Ouvrez le workspace dans eclipse. -6. Utilisez Import> "Existing Maven Projects". -7. Selectionnez le projet et validez. - -Vous devriez avoir une version du projet dans votre propre compte gitlab. - -Vous pouvez le partager avec votre binome et l'encadrant de TP. - - -## Rapport - -J'ai fait ça avec Tuan Minh Vu. - -Votre rapport doit être écrit ici en markdown. - -Vous trouverez la syntaxe de markdown ici : https://docs.gitlab.com/ee/user/markdown.html - -Placez vos images dans le répertoire images si nécessaire. - - - -## Faire des diagrammes - -En particulier vous pouvez utiliser [mermaid](https://mermaidjs.github.io/) : - - - -```mermaid -sequenceDiagram - participant Alice - participant Bob - Alice->John: Hello John, how are you? - loop Healthcheck - John->John: Fight against hypochondria - end - Note right of John: Rational thoughts
prevail... - John-->Alice: Great! - John->Bob: How about you? - Bob-->John: Jolly good! -``` - -## Insérer du code - -Insérer du `code` : - -```java -public interface ClientHandler { - public void handle(); -} -``` - -et des résultats : - -```bash -[yo@capybara dkgr]$ nc google.fr 80 -PWET / -HTTP/1.0 400 Bad Request -Content-Type: text/html; charset=UTF-8 -Referrer-Policy: no-referrer -Content-Length: 1555 -Date: Mon, 21 Jan 2019 12:18:02 GMT - - - - -``` +Dans cette dernière partie, on a codé un serveur auquel on peut accéder depuis ncat et notre navigateur. On utilise PrintWriter pour envoyer les données au client. +Et on vérifie également auprès de Wireshark pour assurer que cela a fonctionné correctement. \ No newline at end of file diff --git a/images/p1_ex3_2clients.png b/images/p1_ex3_2clients.png new file mode 100644 index 0000000000000000000000000000000000000000..bd09331484c89c1de5cc3fbad3950666d6049542 GIT binary patch literal 29964 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 CY#B8G literal 0 HcmV?d00001 diff --git a/src/main/java/fr/istic/pr/serveur/HTTPHandler.java b/src/main/java/fr/istic/pr/serveur/HTTPHandler.java index 5b7891d..0d2d39b 100644 --- a/src/main/java/fr/istic/pr/serveur/HTTPHandler.java +++ b/src/main/java/fr/istic/pr/serveur/HTTPHandler.java @@ -15,12 +15,15 @@ public class HTTPHandler implements ClientHandler, Runnable { public void handle() { try { // Crée les print writer et buffered reader - PrintWriter out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream())); + PrintWriter out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()),true); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); // lit l'entête de la requête String[] premiere_ligne=in.readLine().split(" "); System.out.println(premiere_ligne.length); + if(premiere_ligne.length<2){ + doError(out); + } System.out.println(premiere_ligne[0] + " " + premiere_ligne[1]); // Appelle doGet si la méthode est une méthode GET. if (premiere_ligne[0].equals("GET")){ @@ -45,10 +48,11 @@ public class HTTPHandler implements ClientHandler, Runnable { // si le fichier existe : if (f.exists() && !f.isDirectory()) { - //Ecrit l'en-tête de réponse (Code, Content-type, Connexion, ...) out.println("HTTP/1.1 200 OK"); out.println("Content-Type: text/html"); + out.println("Connection: close"); + out.println(""); //Ecrit le contenu du fichier si il existe BufferedReader fin = new BufferedReader(new FileReader(f)); @@ -56,8 +60,9 @@ public class HTTPHandler implements ClientHandler, Runnable { while ((line = fin.readLine()) != null) { out.println(line); } - out.println("Connection: close"); - out.println(); + out.flush(); + out.close(); + fin.close(); }else{ // sinon // appelle la méthode send404. @@ -71,6 +76,7 @@ public class HTTPHandler implements ClientHandler, Runnable { out.println("Content-Type: text/html"); out.println("Connection: close"); out.println(""); + out.flush(); } public void doError(PrintWriter out) { @@ -79,20 +85,11 @@ public class HTTPHandler implements ClientHandler, Runnable { out.println("Content-Type: text/html"); out.println("Connection: close"); out.println(""); + out.flush(); } @Override public void run() { - try { - BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); - String message = in.readLine(); - System.out.println(message); - String[] a= message.split(" "); - if(a[0].equals("GET")) { - doGet("test.html",new PrintWriter(new OutputStreamWriter(socket.getOutputStream()))); - } - } catch (IOException e) { - throw new RuntimeException(e); - } + handle(); } }