diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..6bc2d83 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/README.md b/README.md index 349a6b7..2ac5176 100644 --- a/README.md +++ b/README.md @@ -6,21 +6,26 @@ Le 4 février 2025 ## Partie I: Le classique serveur Echo ### EXERCICE 1 : Version séquentielle + Nous nous sommes inspirés du cours pour implémenter le serveur écho. + ### EXERCICE 2 : Test et capture -![Echo sur client utilisant ClientHandlerBytes](fichier_pour_CR/p1_ex2_bytes.png) +![Echo sur client utilisant ClientHandlerBytes](images/p1_ex2_bytes.png) -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. +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](fichier_pour_CR/p1_ex2_wireshark.png) +![Follow> TCP Stream](images/p1_ex2_wireshark.png) -la taille des segments TCP est cohérente avec la taille du buffer. + +La taille des segments TCP est cohérente avec la taille du buffer. Dans "Bonjour tout le monde !" nous avons 13 octets (comptez le dernier caractère à la fin) de texte et 64 octets pour échanger des informations pour un total de 77 octets. Dans le texte "Je teste, je suis content, je dors" nous avons 99 octets, dont 64 octets pour le protocole d'échange et l'IP, et 35 pour le texte. -![Data cohérant](fichier_pour_CR/p1_ex2_je_teste.png) + +![Data cohérant](images/p1_ex2_je_teste.png) ### 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" ## Partie II: Implémentation d’un client HTTPping @@ -50,10 +55,27 @@ En vous aidant de la spec décrivez les grandes étapes du protocole pour la ré Par la suite nous vous suggérons d’utiliser l’option “Connection: Close” dans les réponses. ``` ### 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 ? +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) + +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. +J'ai mis toute la partie http en code commenté. + +![Verification HTTPS](images/p2_ex4_wireshark.png) + +Vérification de message encrypté: + +![Message encrypté](images/p2_ex4_ecrypted.png) ## Partie III : Implémentation d’un serveur HTTP simple diff --git a/fichier_pour_CR/p1_ex2_bytes.pcapng b/images/p1_ex2_bytes.pcapng similarity index 100% rename from fichier_pour_CR/p1_ex2_bytes.pcapng rename to images/p1_ex2_bytes.pcapng diff --git a/fichier_pour_CR/p1_ex2_bytes.png b/images/p1_ex2_bytes.png similarity index 100% rename from fichier_pour_CR/p1_ex2_bytes.png rename to images/p1_ex2_bytes.png diff --git a/fichier_pour_CR/p1_ex2_je_teste.png b/images/p1_ex2_je_teste.png similarity index 100% rename from fichier_pour_CR/p1_ex2_je_teste.png rename to images/p1_ex2_je_teste.png diff --git a/fichier_pour_CR/p1_ex2_wireshark.png b/images/p1_ex2_wireshark.png similarity index 100% rename from fichier_pour_CR/p1_ex2_wireshark.png rename to images/p1_ex2_wireshark.png diff --git a/fichier_pour_CR/p2_ex1_example.com.pcapng b/images/p2_ex1_example.com.pcapng similarity index 100% rename from fichier_pour_CR/p2_ex1_example.com.pcapng rename to images/p2_ex1_example.com.pcapng diff --git a/fichier_pour_CR/p2_ex1_example.com.png b/images/p2_ex1_example.com.png similarity index 100% rename from fichier_pour_CR/p2_ex1_example.com.png rename to images/p2_ex1_example.com.png diff --git a/images/p2_ex4_ecrypted.png b/images/p2_ex4_ecrypted.png new file mode 100644 index 0000000..373e1ca Binary files /dev/null and b/images/p2_ex4_ecrypted.png differ diff --git a/images/p2_ex4_https.png b/images/p2_ex4_https.png new file mode 100644 index 0000000..53b5dad Binary files /dev/null and b/images/p2_ex4_https.png differ diff --git a/images/p2_ex4_wireshark.png b/images/p2_ex4_wireshark.png new file mode 100644 index 0000000..e008b8e Binary files /dev/null and b/images/p2_ex4_wireshark.png differ diff --git a/src/main/java/fr/istic/pr/ping/HttpPing.java b/src/main/java/fr/istic/pr/ping/HttpPing.java index c4c9063..6c94691 100644 --- a/src/main/java/fr/istic/pr/ping/HttpPing.java +++ b/src/main/java/fr/istic/pr/ping/HttpPing.java @@ -1,5 +1,6 @@ package fr.istic.pr.ping; +import javax.net.ssl.SSLSocketFactory; import java.io.*; import java.net.Socket; import java.net.UnknownHostException; @@ -19,8 +20,8 @@ public class HttpPing { } public static void main(String[] args) throws UnknownHostException, IOException, InterruptedException { - System.out.println(ping("www.example.com", 80)); - + //System.out.println(ping("www.example.com", 80)); + System.out.println(ping("www.google.fr", 443)); } public static PingInfo ping(String host, int port) throws UnknownHostException, IOException, InterruptedException { @@ -28,13 +29,17 @@ public class HttpPing { long time = System.currentTimeMillis(); - Socket socket = new Socket(host, port); + //Socket socket = new Socket(host, port); + SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault(); + Socket socket = factory.createSocket(host, port); + // UTILISER PrintWriter et BufferedReader PrintWriter out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream())); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); /// Envoyer l'entête //https://stackoverflow.com/questions/9405620/send-http-header-for-identification - out.println("GET / HTTP/1.1"); + //out.println("GET / HTTP/1.1"); + out.println("GET / HTTP/1.0"); // Penser à préciser l'Host dans l'en-tête out.println("Host: " + host); // L'en-tête doit également contenir : @@ -46,7 +51,8 @@ public class HttpPing { String line; while ((line=in.readLine()) != null) { String[] ligne =line.split(" "); - if (ligne[0].equals("HTTP/1.1")){ + //if (ligne[0].equals("HTTP/1.1")){ + if (ligne[0].equals("HTTP/1.0")){ info.code=Integer.parseInt(ligne[1]); break; } diff --git a/src/main/java/fr/istic/pr/serveur/Affiche.java b/src/main/java/fr/istic/pr/serveur/Affiche.java new file mode 100644 index 0000000..bf67a45 --- /dev/null +++ b/src/main/java/fr/istic/pr/serveur/Affiche.java @@ -0,0 +1,22 @@ +package fr.istic.pr.serveur; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; + +public class Affiche { + public static void main(String[] args) throws IOException { + String path = "test.html"; + File f = new File("./www/" + path); + if (f.exists() && !f.isDirectory()) { + System.out.println(f.getAbsolutePath()); + System.out.println(f.exists()); + BufferedReader fin = new BufferedReader(new FileReader(f)); + String line = ""; + while ((line = fin.readLine()) != null) { + System.out.println(line); + } + } + } +} diff --git a/src/main/java/fr/istic/pr/serveur/HTTPHandler.java b/src/main/java/fr/istic/pr/serveur/HTTPHandler.java new file mode 100644 index 0000000..f1fcde3 --- /dev/null +++ b/src/main/java/fr/istic/pr/serveur/HTTPHandler.java @@ -0,0 +1,73 @@ +package fr.istic.pr.serveur; + +import java.io.*; +import java.net.Socket; + +public class HTTPHandler implements ClientHandler, Runnable { + + private Socket socket; + + public HTTPHandler(Socket socket) { + this.socket = socket; + } + + @Override + public void handle() { + try { + // Crée les print writer et buffered reader + PrintWriter out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream())); + BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); + + // lit l'entête de la requête + String premiere_ligne=in.readLine(); + //TODO + // Appelle doGet si la méthode est une méthode GET. + //TODO + }catch (IOException e) { + System.out.println(e.getMessage()); + } finally { + try{ + socket.close(); + }catch (IOException e) { + System.out.println(e.getMessage()); + } + } + } + + public void doGet(String pagepath, PrintWriter out) { + //Vérifie que le fichier existe + File f = new File("./www/" + pagepath); + // 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(); + }else{ + //Ecrit le contenu du fichier si il existe + // sinon + // appelle la méthode send404. + send404(out); + } + } + + public void send404(PrintWriter out) { + //Envoie une réponse 404 si le fichier n'existe pas. + out.println("HTTP/1.1 404 File Not Found"); + out.println("Content-Type: text/html"); + out.println("Connection: close"); + } + + public void doError(PrintWriter out) { + //Envoie une réponse avec le code 405 : Method Not Allowed + out.println("HTTP/1.1 405 Method Not Allowed"); + out.println("Content-Type: text/html"); + out.println("Connection: close"); + } + + @Override + public void run() { + this.handle(); + } +} diff --git a/src/main/java/fr/istic/pr/serveur/ServeurHTTP.java b/src/main/java/fr/istic/pr/serveur/ServeurHTTP.java new file mode 100644 index 0000000..65a513d --- /dev/null +++ b/src/main/java/fr/istic/pr/serveur/ServeurHTTP.java @@ -0,0 +1,5 @@ +package fr.istic.pr.serveur; + +public class ServeurHTTP { + //TODO +}