Ok, using args and all
This commit is contained in:
		
							
								
								
									
										261
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										261
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @ -45,12 +45,55 @@ dependencies = [ | |||||||
|  "generic-array", |  "generic-array", | ||||||
| ] | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "cc" | ||||||
|  | version = "1.0.78" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "cfg-if" | name = "cfg-if" | ||||||
| version = "1.0.0" | version = "1.0.0" | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
| checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "clap" | ||||||
|  | version = "4.0.32" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "a7db700bc935f9e43e88d00b0850dae18a63773cfbec6d8e070fccf7fef89a39" | ||||||
|  | dependencies = [ | ||||||
|  |  "bitflags", | ||||||
|  |  "clap_derive", | ||||||
|  |  "clap_lex", | ||||||
|  |  "is-terminal", | ||||||
|  |  "once_cell", | ||||||
|  |  "strsim", | ||||||
|  |  "termcolor", | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "clap_derive" | ||||||
|  | version = "4.0.21" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014" | ||||||
|  | dependencies = [ | ||||||
|  |  "heck", | ||||||
|  |  "proc-macro-error", | ||||||
|  |  "proc-macro2", | ||||||
|  |  "quote", | ||||||
|  |  "syn", | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "clap_lex" | ||||||
|  | version = "0.3.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" | ||||||
|  | dependencies = [ | ||||||
|  |  "os_str_bytes", | ||||||
|  | ] | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "config" | name = "config" | ||||||
| version = "0.13.3" | version = "0.13.3" | ||||||
| @ -105,6 +148,27 @@ version = "0.3.0" | |||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
| checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257" | checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257" | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "errno" | ||||||
|  | version = "0.2.8" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" | ||||||
|  | dependencies = [ | ||||||
|  |  "errno-dragonfly", | ||||||
|  |  "libc", | ||||||
|  |  "winapi", | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "errno-dragonfly" | ||||||
|  | version = "0.1.2" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" | ||||||
|  | dependencies = [ | ||||||
|  |  "cc", | ||||||
|  |  "libc", | ||||||
|  | ] | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "generic-array" | name = "generic-array" | ||||||
| version = "0.14.6" | version = "0.14.6" | ||||||
| @ -136,10 +200,40 @@ dependencies = [ | |||||||
| ] | ] | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "hello" | name = "heck" | ||||||
| version = "0.1.0" | version = "0.4.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "hermit-abi" | ||||||
|  | version = "0.2.6" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" | ||||||
| dependencies = [ | dependencies = [ | ||||||
|  "config", |  "libc", | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "io-lifetimes" | ||||||
|  | version = "1.0.3" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c" | ||||||
|  | dependencies = [ | ||||||
|  |  "libc", | ||||||
|  |  "windows-sys", | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "is-terminal" | ||||||
|  | version = "0.4.2" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189" | ||||||
|  | dependencies = [ | ||||||
|  |  "hermit-abi", | ||||||
|  |  "io-lifetimes", | ||||||
|  |  "rustix", | ||||||
|  |  "windows-sys", | ||||||
| ] | ] | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| @ -177,6 +271,12 @@ version = "0.5.6" | |||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
| checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" | checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "linux-raw-sys" | ||||||
|  | version = "0.1.4" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "memchr" | name = "memchr" | ||||||
| version = "2.5.0" | version = "2.5.0" | ||||||
| @ -215,6 +315,12 @@ dependencies = [ | |||||||
|  "hashbrown", |  "hashbrown", | ||||||
| ] | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "os_str_bytes" | ||||||
|  | version = "6.4.1" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "pathdiff" | name = "pathdiff" | ||||||
| version = "0.2.1" | version = "0.2.1" | ||||||
| @ -265,6 +371,30 @@ dependencies = [ | |||||||
|  "sha1", |  "sha1", | ||||||
| ] | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "proc-macro-error" | ||||||
|  | version = "1.0.4" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" | ||||||
|  | dependencies = [ | ||||||
|  |  "proc-macro-error-attr", | ||||||
|  |  "proc-macro2", | ||||||
|  |  "quote", | ||||||
|  |  "syn", | ||||||
|  |  "version_check", | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "proc-macro-error-attr" | ||||||
|  | version = "1.0.4" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" | ||||||
|  | dependencies = [ | ||||||
|  |  "proc-macro2", | ||||||
|  |  "quote", | ||||||
|  |  "version_check", | ||||||
|  | ] | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "proc-macro2" | name = "proc-macro2" | ||||||
| version = "1.0.49" | version = "1.0.49" | ||||||
| @ -304,6 +434,20 @@ dependencies = [ | |||||||
|  "ordered-multimap", |  "ordered-multimap", | ||||||
| ] | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "rustix" | ||||||
|  | version = "0.36.6" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "4feacf7db682c6c329c4ede12649cd36ecab0f3be5b7d74e6a20304725db4549" | ||||||
|  | dependencies = [ | ||||||
|  |  "bitflags", | ||||||
|  |  "errno", | ||||||
|  |  "io-lifetimes", | ||||||
|  |  "libc", | ||||||
|  |  "linux-raw-sys", | ||||||
|  |  "windows-sys", | ||||||
|  | ] | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "ryu" | name = "ryu" | ||||||
| version = "1.0.12" | version = "1.0.12" | ||||||
| @ -352,6 +496,20 @@ dependencies = [ | |||||||
|  "digest", |  "digest", | ||||||
| ] | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "ssw" | ||||||
|  | version = "0.1.0" | ||||||
|  | dependencies = [ | ||||||
|  |  "clap", | ||||||
|  |  "config", | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "strsim" | ||||||
|  | version = "0.10.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "syn" | name = "syn" | ||||||
| version = "1.0.107" | version = "1.0.107" | ||||||
| @ -363,6 +521,15 @@ dependencies = [ | |||||||
|  "unicode-ident", |  "unicode-ident", | ||||||
| ] | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "termcolor" | ||||||
|  | version = "1.1.3" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" | ||||||
|  | dependencies = [ | ||||||
|  |  "winapi-util", | ||||||
|  | ] | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "thiserror" | name = "thiserror" | ||||||
| version = "1.0.38" | version = "1.0.38" | ||||||
| @ -422,6 +589,94 @@ version = "0.11.0+wasi-snapshot-preview1" | |||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
| checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "winapi" | ||||||
|  | version = "0.3.9" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" | ||||||
|  | dependencies = [ | ||||||
|  |  "winapi-i686-pc-windows-gnu", | ||||||
|  |  "winapi-x86_64-pc-windows-gnu", | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "winapi-i686-pc-windows-gnu" | ||||||
|  | version = "0.4.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "winapi-util" | ||||||
|  | version = "0.1.5" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" | ||||||
|  | dependencies = [ | ||||||
|  |  "winapi", | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "winapi-x86_64-pc-windows-gnu" | ||||||
|  | version = "0.4.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "windows-sys" | ||||||
|  | version = "0.42.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" | ||||||
|  | dependencies = [ | ||||||
|  |  "windows_aarch64_gnullvm", | ||||||
|  |  "windows_aarch64_msvc", | ||||||
|  |  "windows_i686_gnu", | ||||||
|  |  "windows_i686_msvc", | ||||||
|  |  "windows_x86_64_gnu", | ||||||
|  |  "windows_x86_64_gnullvm", | ||||||
|  |  "windows_x86_64_msvc", | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "windows_aarch64_gnullvm" | ||||||
|  | version = "0.42.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "windows_aarch64_msvc" | ||||||
|  | version = "0.42.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "windows_i686_gnu" | ||||||
|  | version = "0.42.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "windows_i686_msvc" | ||||||
|  | version = "0.42.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "windows_x86_64_gnu" | ||||||
|  | version = "0.42.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "windows_x86_64_gnullvm" | ||||||
|  | version = "0.42.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "windows_x86_64_msvc" | ||||||
|  | version = "0.42.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "yaml-rust" | name = "yaml-rust" | ||||||
| version = "0.4.5" | version = "0.4.5" | ||||||
|  | |||||||
| @ -1,9 +1,16 @@ | |||||||
| [package] | [package] | ||||||
| name = "hello" | name = "ssw" | ||||||
| version = "0.1.0" | version = "0.1.0" | ||||||
| edition = "2021" | edition = "2021" | ||||||
|  | description = "A pretty basic web server, derived from the final chapter of the Rust book." | ||||||
|  |  | ||||||
| # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||||||
|  | [profile.release] | ||||||
|  | opt-level = 3 | ||||||
|  | strip = true | ||||||
|  | lto = true | ||||||
|  | codegen-units = 1 | ||||||
|  |  | ||||||
| [dependencies] | [dependencies] | ||||||
|  | clap = { version = "4.0.32", features = ["derive"] } | ||||||
| config = "0.13.3" | config = "0.13.3" | ||||||
|  | |||||||
| @ -4,5 +4,7 @@ This is a simple web server expanding on the example given in the Rust book. At | |||||||
|  |  | ||||||
| TODO: | TODO: | ||||||
| * Also answer css requests, pictures, etc => OK | * Also answer css requests, pictures, etc => OK | ||||||
| * Fully integrate the config path => More or less | * Fully integrate the config path => Ok | ||||||
| * Gather info about the client (IP, User-Agent, etc) to do funny stuff with it | * Gather info about the client (IP, User-Agent, etc) to do funny stuff with it => Just printing client's adress for now | ||||||
|  | * Use arguments => Done, clap is very very nice ! | ||||||
|  | * Not satisfied with the way root_folder is handled, being passed on from one function to another. | ||||||
|  | |||||||
| @ -71,12 +71,12 @@ struct Worker { | |||||||
|  |  | ||||||
| impl Worker { | impl Worker { | ||||||
|     fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Job>>>) -> Worker { |     fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Job>>>) -> Worker { | ||||||
|  |         println!("Worker {id} online"); | ||||||
|         let thread = thread::spawn(move || loop { |         let thread = thread::spawn(move || loop { | ||||||
|             let message = receiver.lock().expect("Lock's been poisoned, another thread panicked").recv(); |             let message = receiver.lock().expect("Lock's been poisoned, another thread panicked").recv(); | ||||||
|  |  | ||||||
|             match message { |             match message { | ||||||
|                 Ok(job) => { |                 Ok(job) => { | ||||||
|                     println!("Worker {id} got a job; executing !"); |  | ||||||
|                     job(); |                     job(); | ||||||
|                 } |                 } | ||||||
|                 Err(_) => { |                 Err(_) => { | ||||||
|  | |||||||
							
								
								
									
										130
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										130
									
								
								src/main.rs
									
									
									
									
									
								
							| @ -1,4 +1,4 @@ | |||||||
| use hello::{ | use ssw::{ | ||||||
|     ThreadPool, |     ThreadPool, | ||||||
| }; | }; | ||||||
| use std::{ | use std::{ | ||||||
| @ -6,26 +6,40 @@ use std::{ | |||||||
|     io::{prelude::*, BufReader}, |     io::{prelude::*, BufReader}, | ||||||
|     net::{TcpListener, TcpStream}, |     net::{TcpListener, TcpStream}, | ||||||
|     collections::HashMap, |     collections::HashMap, | ||||||
|  |     fmt, | ||||||
|  |     thread, | ||||||
|  |     env, | ||||||
| }; | }; | ||||||
| use config::Config; | use config::Config; | ||||||
|  | use clap::Parser; | ||||||
|  |  | ||||||
| //CONSTS | #[derive(Parser, Debug)] | ||||||
| static ROOT_FOLDER: &str = "./html"; | //#[command(author, version, about, long_about = None)] | ||||||
| static CONF_FILE: &str = "websrv_conf"; | #[command(name = "ssw")] | ||||||
|  | #[command(author = None)] | ||||||
|  | #[command(about = "A simple web server. Pass a configuration file with -c.")] | ||||||
|  | struct Args { | ||||||
|  |     #[arg(short, long)] | ||||||
|  |     conf_file: String, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | ///Stores the configuration | ||||||
|  | struct WebsrvConfig { | ||||||
|  |     nbr_of_threads: usize, | ||||||
|  |     bind_addr: String, | ||||||
|  |     root_folder: String, | ||||||
|  | } | ||||||
|  |  | ||||||
| fn main() { | impl WebsrvConfig { | ||||||
|     //building config |     ///Loads the config from a config file | ||||||
|  |     ///No need to put the file extension (eg. .toml) | ||||||
|  |     fn from_file(filename: &str) -> WebsrvConfig { | ||||||
|         let cfg = Config::builder() |         let cfg = Config::builder() | ||||||
|         .add_source(config::File::with_name(CONF_FILE)) |            .add_source(config::File::with_name(filename)) | ||||||
|            .build() |            .build() | ||||||
|            .unwrap(); |            .unwrap(); | ||||||
|  |  | ||||||
|         let cfg = cfg.try_deserialize::<HashMap<String, String>>().expect("Could not deserialize configuration"); |         let cfg = cfg.try_deserialize::<HashMap<String, String>>().expect("Could not deserialize configuration"); | ||||||
|     println!("Starting with configuration: "); |  | ||||||
|     for conf in &cfg { |  | ||||||
|         println!("{:?}", conf); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|         let nbr_of_threads: usize = cfg |         let nbr_of_threads: usize = cfg | ||||||
|             .get("threads") |             .get("threads") | ||||||
| @ -33,34 +47,74 @@ fn main() { | |||||||
|             .parse() |             .parse() | ||||||
|             .unwrap(); |             .unwrap(); | ||||||
|  |  | ||||||
|  |  | ||||||
|         let default_bind_addr = String::from("0.0.0.0:7878"); |         let default_bind_addr = String::from("0.0.0.0:7878"); | ||||||
|         let bind_addr = cfg |         let bind_addr = cfg | ||||||
|             .get("bind_addr") |             .get("bind_addr") | ||||||
|             .unwrap_or(&default_bind_addr) |             .unwrap_or(&default_bind_addr) | ||||||
|             .to_string(); |             .to_string(); | ||||||
|  |  | ||||||
|     let listener = TcpListener::bind(bind_addr).unwrap(); |         let default_root_folder = String::from("./html"); | ||||||
|  |         let root_folder = cfg | ||||||
|  |             .get("root_folder") | ||||||
|  |             .unwrap_or(&default_root_folder) | ||||||
|  |             .to_string(); | ||||||
|  |  | ||||||
|     let pool = ThreadPool::new(nbr_of_threads); |         let ret_value = WebsrvConfig { | ||||||
|  |             nbr_of_threads: nbr_of_threads, | ||||||
|  |             bind_addr: bind_addr, | ||||||
|  |             root_folder: root_folder, | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         return ret_value; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl fmt::Display for WebsrvConfig { | ||||||
|  |     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||||||
|  |         write!(f, "Number_of_threads : {}, bind_addr : {}, root_folder : {}", | ||||||
|  |                self.nbr_of_threads, | ||||||
|  |                self.bind_addr, | ||||||
|  |                self.root_folder) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | fn run_server(conf_path: &str) { | ||||||
|  |     //Getting config | ||||||
|  |     let cfg = WebsrvConfig::from_file(conf_path); | ||||||
|  |  | ||||||
|  |     println!("==== Squi's Tiny Web Server ===="); | ||||||
|  |     println!("Starting with configuration: "); | ||||||
|  |     println!("{}", cfg); | ||||||
|  |  | ||||||
|  |      | ||||||
|  |     //Got the config, start listening | ||||||
|  |     let listener = TcpListener::bind(cfg.bind_addr).unwrap(); | ||||||
|  |  | ||||||
|  |     let pool = ThreadPool::new(cfg.nbr_of_threads); | ||||||
|  |  | ||||||
|     for stream in listener.incoming() { |     for stream in listener.incoming() { | ||||||
|         let stream = stream.unwrap(); |         let stream = stream.unwrap(); | ||||||
|  |         let peer_addr = stream.peer_addr().unwrap(); | ||||||
|  |         println!("INFO : Got a connection from {:?}", peer_addr); | ||||||
|  |  | ||||||
|  |         let root_f = cfg.root_folder.clone(); | ||||||
|  |  | ||||||
|         pool.execute(move || { |         pool.execute(move || { | ||||||
|            handle_connection(stream); |            handle_connection(stream, root_f.as_str()); | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     println!("Shutting down."); |     println!("Shutting down."); | ||||||
| } | } | ||||||
|  |  | ||||||
| fn search_page(page: &String) -> Option<Vec<u8>> { | fn search_page(page: &String, root_folder: &str) -> Option<Vec<u8>> { | ||||||
|     println!("Looking for {page} in {ROOT_FOLDER}"); |  | ||||||
|     //regular page |     //regular page | ||||||
|     if !page.contains('.') { |     if !page.contains('.') { | ||||||
|         let possible_pagenames = vec![format!("{page}.html"), format!("{page}.htm")]; |         let possible_pagenames = vec![format!("{page}.html"), format!("{page}.htm")]; | ||||||
|         for p in possible_pagenames { |         for p in possible_pagenames { | ||||||
|             match fs::read(format!("{ROOT_FOLDER}/{p}")) { |             match fs::read(format!("{root_folder}/{p}")) { | ||||||
|                 Ok(c) => return Some(c), |                 Ok(c) => return Some(c), | ||||||
|                 Err(_) => (), |                 Err(_) => (), | ||||||
|             } |             } | ||||||
| @ -68,7 +122,7 @@ fn search_page(page: &String) -> Option<Vec<u8>> { | |||||||
|         return None; |         return None; | ||||||
|     //css, jpg, etc |     //css, jpg, etc | ||||||
|     } else { |     } else { | ||||||
|         match fs::read(format!("{ROOT_FOLDER}/{page}")) { |         match fs::read(format!("{root_folder}/{page}")) { | ||||||
|             Ok(c) => return Some(c), |             Ok(c) => return Some(c), | ||||||
|             Err(_) => return None, |             Err(_) => return None, | ||||||
|         }; |         }; | ||||||
| @ -77,7 +131,7 @@ fn search_page(page: &String) -> Option<Vec<u8>> { | |||||||
|          |          | ||||||
| ///Analyze the request and answer it | ///Analyze the request and answer it | ||||||
| ///Returns the complete answer, as a vector of bytes | ///Returns the complete answer, as a vector of bytes | ||||||
| fn analyze_request_line(line: Vec<&str>) -> Vec<u8> { | fn analyze_request_line(line: Vec<&str>, root_folder: &str) -> Vec<u8> { | ||||||
|     let _req = String::from(line[0]); |     let _req = String::from(line[0]); | ||||||
|     let mut page = String::from(line[1]); |     let mut page = String::from(line[1]); | ||||||
|     let proto = String::from(line[2]); |     let proto = String::from(line[2]); | ||||||
| @ -90,7 +144,7 @@ fn analyze_request_line(line: Vec<&str>) -> Vec<u8> { | |||||||
|         page = String::from("index"); |         page = String::from("index"); | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     let mut content = match search_page(&page) { |     let mut content = match search_page(&page, root_folder) { | ||||||
|         Some(c) => { |         Some(c) => { | ||||||
|             *&mut ret_code = "200 OK"; |             *&mut ret_code = "200 OK"; | ||||||
|             c |             c | ||||||
| @ -112,9 +166,7 @@ fn analyze_request_line(line: Vec<&str>) -> Vec<u8> { | |||||||
|             let returned_line = returned_line.as_bytes().to_vec(); |             let returned_line = returned_line.as_bytes().to_vec(); | ||||||
|             return returned_line; |             return returned_line; | ||||||
|         }, |         }, | ||||||
|         Err(_e) => { |         Err(_) => (), | ||||||
|             println!("Got {_e} since we are sending a picture"); |  | ||||||
|         }, |  | ||||||
|     }; |     }; | ||||||
|      |      | ||||||
|     let img_format = if page.ends_with(".jpg") || page.ends_with(".jpeg") { |     let img_format = if page.ends_with(".jpg") || page.ends_with(".jpeg") { | ||||||
| @ -132,28 +184,44 @@ fn analyze_request_line(line: Vec<&str>) -> Vec<u8> { | |||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| fn handle_connection(mut stream: TcpStream) { | fn handle_connection(mut stream: TcpStream, root_folder: &str) { | ||||||
|     let buf_reader = BufReader::new(&mut stream); |     let buf_reader = BufReader::new(&mut stream); | ||||||
|     //for i in buf_reader.lines() { |  | ||||||
|     //    println!("{:?}", i); |  | ||||||
|     //} |  | ||||||
|     let mut req_lines = buf_reader.lines(); |     let mut req_lines = buf_reader.lines(); | ||||||
|     let request = match req_lines.next() { |     let request = match req_lines.next() { | ||||||
|         Some(c) => c, |         Some(c) => c, | ||||||
|         None => Ok(String::from("RIEN")), |         None => Ok(String::from("No request")), | ||||||
|     }; |     }; | ||||||
|     let request = request.unwrap(); |     let request = request.unwrap(); | ||||||
|     println!("!!{:?}", request); |     println!("INFO: Received request {:?}", request); | ||||||
|     //Some(Ok("GET /crabe HTTP/1.1")) |     //Some(Ok("GET /crabe HTTP/1.1")) | ||||||
|  |  | ||||||
|  |  | ||||||
|     if &request != "RIEN" { |     if &request != "No request" { | ||||||
|         let request_analyze: Vec<&str> = request.split_whitespace().collect(); |         let request_analyze: Vec<&str> = request.split_whitespace().collect(); | ||||||
|         let ret_line = analyze_request_line(request_analyze); |         let ret_line = analyze_request_line(request_analyze, root_folder); | ||||||
|  |  | ||||||
|         let payload: &[u8] = &ret_line;  |         let payload: &[u8] = &ret_line;  | ||||||
|         stream.write_all(payload).unwrap(); |         stream.write_all(payload).unwrap(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | fn get_args() -> Vec<String> { | ||||||
|  |     let args: Vec<String> = env::args().collect(); | ||||||
|  |     return args; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fn main() { | ||||||
|  |     let args = Args::parse(); | ||||||
|  |     println!("Hello {}!", args.conf_file); | ||||||
|  |     dbg!(args); | ||||||
|  |  | ||||||
|  |     thread::spawn(|| { | ||||||
|  |         run_server("websrv_conf"); | ||||||
|  |     }); | ||||||
|  |     loop { | ||||||
|  |         continue | ||||||
|  |     }; | ||||||
|  |      | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user