From a08d53a7a038e2b836419659274dedd44870527b Mon Sep 17 00:00:00 2001 From: MeexReay Date: Mon, 17 Jun 2024 20:07:54 +0300 Subject: [PATCH] removed tokio and used std::thread --- Cargo.lock | 453 +++++++++++----------------------------------------- Cargo.toml | 2 +- src/lib.rs | 237 +++++++++++++++------------ src/main.rs | 29 ++-- 4 files changed, 239 insertions(+), 482 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4fe08d2..05a5d29 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,86 +2,109 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "addr2line" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - [[package]] name = "autocfg" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" -[[package]] -name = "backtrace" -version = "0.3.72" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17c6a35df3749d2e8bb1b7b21a976d82b15548788d2735b9d82f329268f71a11" -dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - -[[package]] -name = "bitflags" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" - -[[package]] -name = "bytes" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" - -[[package]] -name = "cc" -version = "1.0.98" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - [[package]] name = "ezhttp" version = "0.1.0" dependencies = [ + "futures", "serde_json", - "tokio", "urlencoding", ] [[package]] -name = "gimli" -version = "0.29.0" +name = "futures" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] [[package]] -name = "hermit-abi" -version = "0.3.9" +name = "futures-channel" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] [[package]] name = "itoa" @@ -89,89 +112,11 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" -[[package]] -name = "libc" -version = "0.2.155" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" - -[[package]] -name = "lock_api" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" -dependencies = [ - "autocfg", - "scopeguard", -] - [[package]] name = "memchr" -version = "2.7.2" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" - -[[package]] -name = "miniz_oxide" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" -dependencies = [ - "adler", -] - -[[package]] -name = "mio" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" -dependencies = [ - "libc", - "wasi", - "windows-sys 0.48.0", -] - -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "object" -version = "0.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8ec7ab813848ba4522158d5517a6093db1ded27575b070f4177b8d12b41db5e" -dependencies = [ - "memchr", -] - -[[package]] -name = "parking_lot" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets 0.52.5", -] +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "pin-project-lite" @@ -179,6 +124,12 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "proc-macro2" version = "1.0.85" @@ -197,33 +148,12 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "redox_syscall" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" -dependencies = [ - "bitflags", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - [[package]] name = "ryu" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - [[package]] name = "serde" version = "1.0.203" @@ -256,28 +186,12 @@ dependencies = [ ] [[package]] -name = "signal-hook-registry" -version = "1.4.2" +name = "slab" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ - "libc", -] - -[[package]] -name = "smallvec" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" - -[[package]] -name = "socket2" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" -dependencies = [ - "libc", - "windows-sys 0.52.0", + "autocfg", ] [[package]] @@ -291,36 +205,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "tokio" -version = "1.38.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" -dependencies = [ - "backtrace", - "bytes", - "libc", - "mio", - "num_cpus", - "parking_lot", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "tokio-macros", - "windows-sys 0.48.0", -] - -[[package]] -name = "tokio-macros" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "unicode-ident" version = "1.0.12" @@ -332,148 +216,3 @@ name = "urlencoding" version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.5", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - -[[package]] -name = "windows-targets" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" -dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", - "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" diff --git a/Cargo.toml b/Cargo.toml index dcb79ea..c750454 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,4 +12,4 @@ keywords = ["http", "server", "site"] [dependencies] urlencoding = "2.1.3" serde_json = "1.0" -tokio = { version = "1", features = ["full"] } +futures = "0.3.30" diff --git a/src/lib.rs b/src/lib.rs index a933061..23afc66 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,14 +1,16 @@ +use futures::executor::block_on; use serde_json::Value; +use std::io::{Read, Write}; +use std::time::Duration; use std::{ boxed::Box, error::Error, future::Future, net::{IpAddr, SocketAddr, ToSocketAddrs}, sync::Arc, + thread, }; -use tokio::io::{AsyncReadExt, AsyncWriteExt, BufReader}; -use tokio::{ - io::AsyncBufReadExt, +use std::{ net::{TcpListener, TcpStream}, sync::Mutex, }; @@ -170,29 +172,37 @@ impl std::fmt::Display for HttpError { impl Error for HttpError {} -async fn read_line(data: &mut BufReader<&mut TcpStream>) -> Result { - let mut buf = String::new(); - match data.read_line(&mut buf).await { - Ok(i) => { - if i == 0 { - Err(HttpError::ReadLineEof) - } else { - Ok(buf) - } +fn read_line(data: &mut TcpStream) -> Result { + let mut bytes = Vec::new(); + + for byte in data.bytes() { + let byte = match byte { + Ok(i) => i, + Err(_) => return Err(HttpError::ReadLineEof), + }; + + bytes.push(byte); + + if byte == 0x0A { + break; } + } + + match String::from_utf8(bytes) { + Ok(i) => Ok(i), Err(_) => Err(HttpError::ReadLineUnknown), } } -async fn read_line_crlf(data: &mut BufReader<&mut TcpStream>) -> Result { - match read_line(data).await { +fn read_line_crlf(data: &mut TcpStream) -> Result { + match read_line(data) { Ok(i) => Ok(i[..i.len() - 2].to_string()), Err(e) => Err(e), } } -async fn read_line_lf(data: &mut BufReader<&mut TcpStream>) -> Result { - match read_line(data).await { +fn read_line_lf(data: &mut TcpStream) -> Result { + match read_line(data) { Ok(i) => Ok(i[..i.len() - 1].to_string()), Err(e) => Err(e), } @@ -239,10 +249,7 @@ impl HttpRequest { } } - pub async fn read( - mut data: BufReader<&mut TcpStream>, - addr: &SocketAddr, - ) -> Result { + pub fn read(data: &mut TcpStream, addr: &SocketAddr) -> Result { let octets = match addr.ip() { IpAddr::V4(ip) => ip.octets(), _ => [127, 0, 0, 1], @@ -257,7 +264,7 @@ impl HttpRequest { + &octets[3].to_string(); let status = split( - match read_line_crlf(&mut data).await { + match read_line_crlf(data) { Ok(i) => i, Err(e) => return Err(e), }, @@ -274,7 +281,7 @@ impl HttpRequest { let mut headers = Headers::new(); loop { - let text = match read_line_crlf(&mut data).await { + let text = match read_line_crlf(data) { Ok(i) => i, Err(_) => return Err(HttpError::InvalidHeaders), }; @@ -325,7 +332,7 @@ impl HttpRequest { let mut buf: Vec = Vec::new(); buf.resize(content_size - reqdata.len(), 0); - match data.read_exact(&mut buf).await { + match data.read_exact(&mut buf) { Ok(i) => i, Err(_) => return Err(HttpError::InvalidContent), }; @@ -405,10 +412,8 @@ impl HttpRequest { }) } - pub async fn read_with_rrs( - mut data: BufReader<&mut TcpStream>, - ) -> Result { - let addr = match read_line_lf(&mut data).await { + pub fn read_with_rrs(data: &mut TcpStream) -> Result { + let addr = match read_line_lf(data) { Ok(i) => i, Err(e) => { return Err(e); @@ -417,7 +422,7 @@ impl HttpRequest { .to_socket_addrs() .unwrap() .collect::>()[0]; - HttpRequest::read(data, &addr).await + HttpRequest::read(data, &addr) } pub fn params_to_page(&mut self) { @@ -442,7 +447,7 @@ impl HttpRequest { self.page += query.as_str(); } - pub async fn write(self, data: &mut TcpStream) -> Result<(), HttpError> { + pub fn write(self, data: &mut TcpStream) -> Result<(), HttpError> { let mut head: String = String::new(); head.push_str(&self.method); head.push_str(" "); @@ -459,13 +464,13 @@ impl HttpRequest { head.push_str("\r\n"); - match data.write_all(head.as_bytes()).await { + match data.write_all(head.as_bytes()) { Ok(i) => i, Err(_) => return Err(HttpError::WriteHeadError), }; if !self.data.is_empty() { - match data.write_all(&self.data).await { + match data.write_all(&self.data) { Ok(i) => i, Err(_) => return Err(HttpError::WriteBodyError), }; @@ -506,10 +511,8 @@ impl HttpResponse { } } - pub async fn read(dread: &mut TcpStream) -> Result { - let mut data = BufReader::new(dread); - - let status = match read_line_crlf(&mut data).await { + pub fn read(data: &mut TcpStream) -> Result { + let status = match read_line_crlf(data) { Ok(i) => i, Err(e) => { return Err(e); @@ -524,7 +527,7 @@ impl HttpResponse { let mut headers = Headers::new(); loop { - let text = match read_line_crlf(&mut data).await { + let text = match read_line_crlf(data) { Ok(i) => i, Err(_) => return Err(HttpError::InvalidHeaders), }; @@ -553,7 +556,7 @@ impl HttpResponse { let mut buf: Vec = Vec::new(); buf.resize(content_size - reqdata.len(), 0); - match data.read_exact(&mut buf).await { + match data.read_exact(&mut buf) { Ok(i) => i, Err(_) => return Err(HttpError::InvalidContent), }; @@ -564,7 +567,7 @@ impl HttpResponse { loop { let mut buf: Vec = vec![0; 1024 * 32]; - let buf_len = match data.read(&mut buf).await { + let buf_len = match data.read(&mut buf) { Ok(i) => i, Err(_) => { break; @@ -588,7 +591,7 @@ impl HttpResponse { }) } - pub async fn write(self, data: &mut TcpStream) -> Result<(), &str> { + pub fn write(self, data: &mut TcpStream) -> Result<(), &str> { let mut head: String = String::new(); head.push_str("HTTP/1.1 "); head.push_str(&self.status_code); @@ -603,12 +606,12 @@ impl HttpResponse { head.push_str("\r\n"); - match data.write_all(head.as_bytes()).await { + match data.write_all(head.as_bytes()) { Ok(i) => i, Err(_) => return Err("write head error"), }; - match data.write_all(&self.data).await { + match data.write_all(&self.data) { Ok(i) => i, Err(_) => return Err("write body error"), }; @@ -618,7 +621,7 @@ impl HttpResponse { } pub trait HttpServer: Sync { - fn on_start(&mut self, host: &str, listener: &TcpListener) -> impl Future + Send; + fn on_start(&mut self, host: &str) -> impl Future + Send; fn on_close(&mut self) -> impl Future + Send; fn on_request( &mut self, @@ -626,96 +629,118 @@ pub trait HttpServer: Sync { ) -> impl Future> + Send; } -async fn handle_connection( - server: Arc>, - mut sock: TcpStream, -) { +fn start_server_with_handler( + server: S, + host: &str, + timeout: Option, + handler: F, +) -> Result<(), Box> +where + F: Fn(Arc>, TcpStream) -> (), + S: HttpServer + Send + 'static, + F: Send + 'static, +{ + let server = Arc::new(Mutex::new(server)); + let listener = TcpListener::bind(host)?; + + let host_clone = String::from(host).clone(); + let server_clone = server.clone(); + thread::spawn(move || block_on(server_clone.lock().unwrap().on_start(&host_clone))); + + loop { + let (sock, _) = match listener.accept() { + Ok(i) => i, + Err(_) => { + break; + } + }; + + sock.set_read_timeout(timeout).unwrap(); + sock.set_write_timeout(timeout).unwrap(); + + let now_server = Arc::clone(&server); + handler(now_server, sock); + } + + thread::spawn(move || block_on(server.lock().unwrap().on_close())); + + Ok(()) +} + +pub fn start_server( + server: impl HttpServer + Send + 'static, + host: &str, +) -> Result<(), Box> { + start_server_with_handler(server, host, None, move |server, sock| { + thread::spawn(move || handle_connection(server, sock)); + }) +} + +// http rrs support +pub fn start_server_rrs( + server: impl HttpServer + Send + 'static, + host: &str, +) -> Result<(), Box> { + start_server_with_handler(server, host, None, move |server, sock| { + thread::spawn(move || handle_connection_rrs(server, sock)); + }) +} + +pub fn start_server_timeout( + server: impl HttpServer + Send + 'static, + host: &str, + timeout: Duration, +) -> Result<(), Box> { + start_server_with_handler(server, host, Some(timeout), move |server, sock| { + thread::spawn(move || handle_connection(server, sock)); + }) +} + +// http rrs support +pub fn start_server_rrs_timeout( + server: impl HttpServer + Send + 'static, + host: &str, + timeout: Duration, +) -> Result<(), Box> { + start_server_with_handler(server, host, Some(timeout), move |server, sock| { + thread::spawn(move || handle_connection_rrs(server, sock)); + }) +} + +fn handle_connection(server: Arc>, mut sock: TcpStream) { let addr = sock.peer_addr().unwrap(); - let req = match HttpRequest::read(BufReader::new(&mut sock), &addr).await { + let req = match HttpRequest::read(&mut sock, &addr) { Ok(i) => i, Err(_) => { return; } }; - let resp = match server.lock().await.on_request(&req).await { + let resp = match block_on(server.lock().unwrap().on_request(&req)) { Some(i) => i, None => { return; } }; - resp.write(&mut sock).await.unwrap(); -} - -pub async fn start_server( - server: impl HttpServer + Send + 'static, - host: &str, -) -> Result<(), Box> { - let server = Arc::new(Mutex::new(server)); - let listener = TcpListener::bind(host).await?; - - server.lock().await.on_start(host, &listener).await; - - loop { - let (sock, _) = match listener.accept().await { - Ok(i) => i, - Err(_) => { - break; - } - }; - - let now_server = Arc::clone(&server); - tokio::spawn(handle_connection(now_server, sock)); - } - - server.lock().await.on_close().await; - - Ok(()) + resp.write(&mut sock).unwrap(); } // http rrs support -pub async fn start_server_rrs( - server: impl HttpServer + Send + 'static, - host: &str, -) -> Result<(), Box> { - let server = Arc::new(Mutex::new(server)); - let listener = TcpListener::bind(host).await?; - - server.lock().await.on_start(host, &listener).await; - - loop { - let (sock, _) = match listener.accept().await { - Ok(i) => i, - Err(_) => { - break; - } - }; - - let now_server = Arc::clone(&server); - tokio::spawn(handle_connection_rrs(now_server, sock)); - } - - server.lock().await.on_close().await; - - Ok(()) -} - -// http rrs support -async fn handle_connection_rrs( +fn handle_connection_rrs( server: Arc>, mut sock: TcpStream, ) { - let req = match HttpRequest::read_with_rrs(BufReader::new(&mut sock)).await { + let req = match HttpRequest::read_with_rrs(&mut sock) { Ok(i) => i, Err(_) => { return; } }; - let resp = match server.lock().await.on_request(&req).await { + let resp = match block_on(server.lock().unwrap().on_request(&req)) { Some(i) => i, None => { return; } }; - resp.write(&mut sock).await.unwrap(); + resp.write(&mut sock).unwrap(); } diff --git a/src/main.rs b/src/main.rs index b6a4c14..858871d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,7 @@ -use ezhttp::{Headers, HttpResponse, HttpRequest, HttpServer}; -use tokio::{runtime::Runtime, net::TcpListener}; +use ezhttp::{Headers, HttpRequest, HttpResponse, HttpServer}; struct EzSite { - index_page: String + index_page: String, } impl HttpServer for EzSite { @@ -10,21 +9,17 @@ impl HttpServer for EzSite { println!("{} > {} {}", req.addr, req.method, req.page); if req.page == "/" { - Some( - HttpResponse::from_str( - Headers::from(vec![ - ("Content-Type", "text/html") - ]), - "200 OK".to_string(), - &self.index_page - ) - ) + Some(HttpResponse::from_str( + Headers::from(vec![("Content-Type", "text/html")]), + "200 OK".to_string(), + &self.index_page, + )) } else { None // just shutdown socket } } - async fn on_start(&mut self, host: &str, _listener: &TcpListener) { + async fn on_start(&mut self, host: &str) { println!("Http server started on {}", host); } @@ -36,7 +31,7 @@ impl HttpServer for EzSite { impl EzSite { fn new(index_page: &str) -> Self { EzSite { - index_page: index_page.to_string() + index_page: index_page.to_string(), } } } @@ -45,7 +40,5 @@ fn main() { let site = EzSite::new("Hello World!"); let host = "localhost:8080"; - Runtime::new().unwrap().block_on(async move { - ezhttp::start_server(site, host).await.unwrap(); - }); -} \ No newline at end of file + ezhttp::start_server(site, host).unwrap(); +}