diff --git a/FRENCH/examples-sources/09_01_sync_tcp_server/404.html b/FRENCH/examples-sources/09_01_sync_tcp_server/404.html new file mode 100644 index 00000000..88d8e915 --- /dev/null +++ b/FRENCH/examples-sources/09_01_sync_tcp_server/404.html @@ -0,0 +1,11 @@ + + +
+ +Sorry, I don't know what you're asking for.
+ + diff --git a/FRENCH/examples-sources/09_01_sync_tcp_server/Cargo.toml b/FRENCH/examples-sources/09_01_sync_tcp_server/Cargo.toml new file mode 100644 index 00000000..3048a1e7 --- /dev/null +++ b/FRENCH/examples-sources/09_01_sync_tcp_server/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "sync_tcp_server" +version = "0.1.0" +authors = ["Your NameHi from Rust
+ + diff --git a/FRENCH/examples-sources/09_01_sync_tcp_server/src/main.rs b/FRENCH/examples-sources/09_01_sync_tcp_server/src/main.rs new file mode 100644 index 00000000..3f62eb47 --- /dev/null +++ b/FRENCH/examples-sources/09_01_sync_tcp_server/src/main.rs @@ -0,0 +1,39 @@ +use std::fs; +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; + +fn main() { + // Listen for incoming TCP connections on localhost port 7878 + let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); + + // Block forever, handling each request that arrives at this IP address + for stream in listener.incoming() { + let stream = stream.unwrap(); + + handle_connection(stream); + } +} + +fn handle_connection(mut stream: TcpStream) { + // Read the first 1024 bytes of data from the stream + let mut buffer = [0; 1024]; + stream.read(&mut buffer).unwrap(); + + let get = b"GET / HTTP/1.1\r\n"; + + // Respond with greetings or a 404, + // depending on the data in the request + let (status_line, filename) = if buffer.starts_with(get) { + ("HTTP/1.1 200 OK\r\n\r\n", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND\r\n\r\n", "404.html") + }; + let contents = fs::read_to_string(filename).unwrap(); + + // Write response back to the stream, + // and flush the stream to ensure the response is sent back to the client + let response = format!("{status_line}{contents}"); + stream.write_all(response.as_bytes()).unwrap(); + stream.flush().unwrap(); +} diff --git a/FRENCH/examples-sources/Cargo.toml b/FRENCH/examples-sources/Cargo.toml index 38cf9482..950d252f 100644 --- a/FRENCH/examples-sources/Cargo.toml +++ b/FRENCH/examples-sources/Cargo.toml @@ -1,3 +1,4 @@ [workspace] members = [ + "09_01_sync_tcp_server", ] diff --git a/FRENCH/examples/09_01_sync_tcp_server/404.html b/FRENCH/examples/09_01_sync_tcp_server/404.html new file mode 100644 index 00000000..19994bda --- /dev/null +++ b/FRENCH/examples/09_01_sync_tcp_server/404.html @@ -0,0 +1,11 @@ + + + + +Désolé, je ne connaît pas ce que vous demandez.
+ + diff --git a/FRENCH/examples/09_01_sync_tcp_server/Cargo.toml b/FRENCH/examples/09_01_sync_tcp_server/Cargo.toml new file mode 100644 index 00000000..3048a1e7 --- /dev/null +++ b/FRENCH/examples/09_01_sync_tcp_server/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "sync_tcp_server" +version = "0.1.0" +authors = ["Your NameBonjour de la part de Rust
+ + diff --git a/FRENCH/examples/09_01_sync_tcp_server/src/main.rs b/FRENCH/examples/09_01_sync_tcp_server/src/main.rs new file mode 100644 index 00000000..4092c5e9 --- /dev/null +++ b/FRENCH/examples/09_01_sync_tcp_server/src/main.rs @@ -0,0 +1,40 @@ +use std::fs; +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; + +fn main() { + // Ecoute les connexions TCP entrantes sur localhost, port 7878. + let ecouteur = TcpListener::bind("127.0.0.1:7878").unwrap(); + + // Bloque pour toujours, gérant chaque requête qui arrive + // sur cette adresse IP. + for flux in ecouteur.incoming() { + let flux = flux.unwrap(); + + gestion_connexion(flux); + } +} + +fn gestion_connexion(mut flux: TcpStream) { + // Lit les 1024 premiers octets de données présents dans le flux + let mut tampon = [0; 1024]; + flux.read(&mut tampon).unwrap(); + + let get = b"GET / HTTP/1.1\r\n"; + + // Répond avec l'accueil ou une erreur 404, + // en fonction des données présentes dans la requête + let (ligne_statut, nom_fichier) = if tampon.starts_with(get) { + ("HTTP/1.1 200 OK\r\n\r\n", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND\r\n\r\n", "404.html") + }; + let contenu = fs::read_to_string(nom_fichier).unwrap(); + + // Ecrit la réponse dans le flux, et purge le flux pour s'assurer + // que la réponse est bien renvoyée au client + let reponse = format!("{ligne_statut}{contenu}"); + flux.write_all(reponse.as_bytes()).unwrap(); + flux.flush().unwrap(); +} diff --git a/FRENCH/examples/Cargo.toml b/FRENCH/examples/Cargo.toml index 38cf9482..950d252f 100644 --- a/FRENCH/examples/Cargo.toml +++ b/FRENCH/examples/Cargo.toml @@ -1,3 +1,4 @@ [workspace] members = [ + "09_01_sync_tcp_server", ] diff --git a/FRENCH/src/09_example/00_intro.md b/FRENCH/src/09_example/00_intro.md new file mode 100644 index 00000000..27593241 --- /dev/null +++ b/FRENCH/src/09_example/00_intro.md @@ -0,0 +1,66 @@ + + +# Projet final : construire un serveur web concurrent avec le Rust asynchrone + +Dans ce chapitre, nous allons utiliser le Rust asynchrone pour modifier le +[serveur web mono-processus](https://jimskapt.github.io/rust-book-fr/ch20-00-final-project-a-web-server.html) +du livre sur Rust, afin qu'il serve les requêtes de manière concurrente. + +## Résumé + +Voici ce à quoi ressemblera le code à la fin de cette leçon. + + + +`src/main.rs` : + +```rust +{{#include ../../examples/09_01_sync_tcp_server/src/main.rs}} +``` + + + +`hello.html` : + +```html +{{#include ../../examples/09_01_sync_tcp_server/hello.html}} +``` + + + +`404.html` : + +```html +{{#include ../../examples/09_01_sync_tcp_server/404.html}} +``` + + + +Si vous exécutez le serveur avec `cargo run` et visitez `127.0.0.1:7878` dans +votre navigateur, vous allez être accueilli par un message chaleureux de +Ferris ! diff --git a/FRENCH/src/SUMMARY.md b/FRENCH/src/SUMMARY.md index beeca743..7115b1e4 100644 --- a/FRENCH/src/SUMMARY.md +++ b/FRENCH/src/SUMMARY.md @@ -1,3 +1,5 @@ # Table des matières +- [Projet final : Serveur HTTP](09_example/00_intro.md) + [Traduction des termes](translation-terms.md)