From bbfef6daef00049dae56934c7fd3c262ce57ff3f Mon Sep 17 00:00:00 2001 From: MeexReay Date: Sun, 1 Dec 2024 00:42:48 +0300 Subject: [PATCH] sendable --- Cargo.lock | 147 +++++++++++++++++++---------------- Cargo.toml | 3 +- src/ezhttp/body.rs | 8 +- src/ezhttp/client/mod.rs | 2 +- src/ezhttp/headers.rs | 22 +++--- src/ezhttp/mod.rs | 8 +- src/ezhttp/request.rs | 42 +++++----- src/ezhttp/response.rs | 40 +++++----- src/ezhttp/server/handler.rs | 2 + src/ezhttp/server/mod.rs | 4 +- 10 files changed, 156 insertions(+), 122 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c168cb1..51b8878 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,38 +4,49 @@ version = 3 [[package]] name = "addr2line" -version = "0.22.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "async-trait" +version = "0.1.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "backtrace" -version = "0.3.73" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-targets", ] [[package]] @@ -58,15 +69,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" [[package]] name = "cc" -version = "1.1.14" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d2eb3cd3d1bf4529e31c215ee6f93ec5a3d536d9f578f93d9d33ee19562932" +checksum = "f34d93e62b03caf570cccc334cbc6c2fceca82f39211051345108adcba3eebdc" dependencies = [ "shlex", ] @@ -102,6 +113,7 @@ checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" name = "ezhttp" version = "0.2.0" dependencies = [ + "async-trait", "base64", "lazy_static", "mime_guess", @@ -134,9 +146,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "futures" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -149,9 +161,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -159,15 +171,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -176,15 +188,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", @@ -193,21 +205,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", @@ -234,9 +246,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.29.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "hermit-abi" @@ -246,9 +258,9 @@ checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "lazy_static" @@ -258,9 +270,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.155" +version = "0.2.167" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" [[package]] name = "lock_api" @@ -296,20 +308,19 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.7.4" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ - "adler", + "adler2", ] [[package]] name = "mio" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ - "hermit-abi", "libc", "wasi", "windows-sys", @@ -327,9 +338,9 @@ dependencies = [ [[package]] name = "object" -version = "0.36.3" +version = "0.36.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "memchr", ] @@ -403,9 +414,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" [[package]] name = "pin-utils" @@ -430,18 +441,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.85" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -478,9 +489,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.3" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ "bitflags", ] @@ -518,18 +529,18 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.203" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", @@ -580,9 +591,9 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" dependencies = [ "libc", "windows-sys", @@ -590,9 +601,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.66" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", @@ -601,18 +612,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.65" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.65" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", @@ -698,9 +709,9 @@ checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "urlencoding" diff --git a/Cargo.toml b/Cargo.toml index aab8575..4f20760 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,4 +22,5 @@ mime_guess = "2.0.5" openssl = "0.10.68" tokio-openssl = "0.6.5" tokio-socks = "0.5.2" -base64 = "0.22.1" \ No newline at end of file +base64 = "0.22.1" +async-trait = "0.1.83" \ No newline at end of file diff --git a/src/ezhttp/body.rs b/src/ezhttp/body.rs index f2e454c..bed0569 100644 --- a/src/ezhttp/body.rs +++ b/src/ezhttp/body.rs @@ -1,11 +1,12 @@ use std::{collections::HashMap, path::PathBuf}; +use async_trait::async_trait; use serde_json::Value; use tokio::{fs, io::{AsyncReadExt, AsyncWriteExt}}; use crate::ezhttp::{split_bytes, split_bytes_once}; -use super::{read_line_crlf, headers::Headers, error::HttpError}; +use super::{error::HttpError, headers::Headers, read_line_crlf, Sendable}; #[derive(Debug, Clone)] pub struct Body { @@ -146,8 +147,11 @@ impl Body { Ok(Body::from_bytes(&reqdata)) } +} - pub async fn send(&self, stream: &mut (impl AsyncWriteExt + Unpin)) -> Result<(), HttpError> { +#[async_trait] +impl Sendable for Body { + async fn send(&self, stream: &mut (impl AsyncWriteExt + Unpin + Send)) -> Result<(), HttpError> { stream.write_all(&self.as_bytes()).await.map_err(|_| HttpError::WriteHeadError) } } diff --git a/src/ezhttp/client/mod.rs b/src/ezhttp/client/mod.rs index b8debec..a723180 100644 --- a/src/ezhttp/client/mod.rs +++ b/src/ezhttp/client/mod.rs @@ -6,7 +6,7 @@ use tokio::{io::{AsyncReadExt, AsyncWriteExt}, net::TcpStream}; use tokio_openssl::SslStream; use tokio_socks::tcp::{Socks4Stream, Socks5Stream}; -use super::{error::HttpError, gen_multipart_boundary, headers::Headers, prelude::HttpResponse, request::HttpRequest}; +use super::{error::HttpError, gen_multipart_boundary, headers::Headers, prelude::HttpResponse, request::HttpRequest, Sendable}; use base64::prelude::BASE64_STANDARD; diff --git a/src/ezhttp/headers.rs b/src/ezhttp/headers.rs index 80d2935..3ea3f7e 100644 --- a/src/ezhttp/headers.rs +++ b/src/ezhttp/headers.rs @@ -3,9 +3,10 @@ use std::{ fmt::{Debug, Display}, }; +use async_trait::async_trait; use tokio::io::{AsyncReadExt, AsyncWriteExt}; -use super::{read_line_crlf, error::HttpError}; +use super::{error::HttpError, read_line_crlf, Sendable}; /// Http headers #[derive(Clone, Debug)] @@ -111,8 +112,17 @@ impl Headers { Ok(headers) } +} - pub async fn send(&self, stream: &mut (impl AsyncWriteExt + Unpin)) -> Result<(), HttpError> { +impl Display for Headers { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + Debug::fmt(self, f) + } +} + +#[async_trait] +impl Sendable for Headers { + async fn send(&self, stream: &mut (impl AsyncWriteExt + Unpin + Send)) -> Result<(), HttpError> { let mut head = String::new(); for (k, v) in self.entries() { head.push_str(&k); @@ -122,10 +132,4 @@ impl Headers { } stream.write_all(head.as_bytes()).await.map_err(|_| HttpError::WriteHeadError) } -} - -impl Display for Headers { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - Debug::fmt(self, f) - } -} +} \ No newline at end of file diff --git a/src/ezhttp/mod.rs b/src/ezhttp/mod.rs index fbe39c3..0a9f2b3 100644 --- a/src/ezhttp/mod.rs +++ b/src/ezhttp/mod.rs @@ -21,8 +21,9 @@ pub mod prelude { use error::HttpError; use rand::Rng; -use tokio::{io::AsyncReadExt, net::TcpStream}; +use tokio::{io::{AsyncReadExt, AsyncWriteExt}, net::TcpStream}; use tokio_io_timeout::TimeoutStream; +use async_trait::async_trait; const CHARS: &str = "qwertyuiopasdfghjklzxcvbnm0123456789QWERTYUIOPASDFGHJKLZXCVBNM'()+_,-./:=?"; @@ -106,4 +107,9 @@ async fn read_line_crlf(data: &mut (impl AsyncReadExt + Unpin)) -> Result Result<(), HttpError>; +} + pub type Stream = TimeoutStream; \ No newline at end of file diff --git a/src/ezhttp/request.rs b/src/ezhttp/request.rs index 597fa9b..fc2dca7 100644 --- a/src/ezhttp/request.rs +++ b/src/ezhttp/request.rs @@ -1,8 +1,9 @@ -use super::{body::{Body, Part}, client::RequestBuilder, gen_multipart_boundary, headers::Headers, read_line_crlf, HttpError}; +use super::{body::{Body, Part}, client::RequestBuilder, gen_multipart_boundary, headers::Headers, read_line_crlf, HttpError, Sendable}; use std::{ collections::HashMap, fmt::{Debug, Display}, net::SocketAddr, str::FromStr }; +use async_trait::async_trait; use tokio::io::{AsyncReadExt, AsyncWriteExt}; #[derive(Clone, Debug)] @@ -172,25 +173,6 @@ impl HttpRequest { )) } - /// Write http request to stream - pub async fn send(&self, stream: &mut (impl AsyncWriteExt + Unpin)) -> Result<(), HttpError> { - let mut head: String = String::new(); - head.push_str(&self.method); - head.push_str(" "); - head.push_str(&self.url.to_path_string()); - head.push_str(" HTTP/1.1"); - head.push_str("\r\n"); - stream.write_all(head.as_bytes()).await.map_err(|_| HttpError::WriteHeadError)?; - - self.headers.send(stream).await?; - - stream.write_all(b"\r\n").await.map_err(|_| HttpError::WriteBodyError)?; - - self.body.send(stream).await?; - - Ok(()) - } - pub fn get_multipart(&self) -> Option> { let boundary = self.headers.get("content-type")? .split(";") @@ -212,4 +194,24 @@ impl HttpRequest { } } +#[async_trait] +impl Sendable for HttpRequest { + /// Write http request to stream + async fn send(&self, stream: &mut (impl AsyncWriteExt + Unpin + Send)) -> Result<(), HttpError> { + let mut head: String = String::new(); + head.push_str(&self.method); + head.push_str(" "); + head.push_str(&self.url.to_path_string()); + head.push_str(" HTTP/1.1"); + head.push_str("\r\n"); + stream.write_all(head.as_bytes()).await.map_err(|_| HttpError::WriteHeadError)?; + self.headers.send(stream).await?; + + stream.write_all(b"\r\n").await.map_err(|_| HttpError::WriteBodyError)?; + + self.body.send(stream).await?; + + Ok(()) + } +} \ No newline at end of file diff --git a/src/ezhttp/response.rs b/src/ezhttp/response.rs index 3ba1d99..d60815f 100644 --- a/src/ezhttp/response.rs +++ b/src/ezhttp/response.rs @@ -1,5 +1,6 @@ -use super::{body::{Body, Part}, gen_multipart_boundary, read_line_crlf, headers::Headers, HttpError}; +use super::{body::{Body, Part}, gen_multipart_boundary, headers::Headers, read_line_crlf, HttpError, Sendable}; +use async_trait::async_trait; use tokio::io::{AsyncReadExt, AsyncWriteExt}; use std::fmt::{Debug, Display}; @@ -47,23 +48,6 @@ impl HttpResponse { Ok(HttpResponse::new(status_code, headers, body)) } - /// Write http response to stream - pub async fn send(self, stream: &mut (impl AsyncWriteExt + Unpin)) -> Result<(), HttpError> { - let mut head: String = String::new(); - head.push_str("HTTP/1.1 "); - head.push_str(&self.status_code); - head.push_str("\r\n"); - stream.write_all(head.as_bytes()).await.map_err(|_| HttpError::WriteHeadError)?; - - self.headers.send(stream).await?; - - stream.write_all(b"\r\n").await.map_err(|_| HttpError::WriteBodyError)?; - - self.body.send(stream).await?; - - Ok(()) - } - pub fn get_multipart(&self) -> Option> { let boundary = self.headers.get("content-type")? .split(";") @@ -88,3 +72,23 @@ impl Default for HttpResponse { Self::new("200 OK", Headers::new(), Body::default()) } } + +#[async_trait] +impl Sendable for HttpResponse { + /// Write http response to stream + async fn send(&self, stream: &mut (impl AsyncWriteExt + Unpin + Send)) -> Result<(), HttpError> { + let mut head: String = String::new(); + head.push_str("HTTP/1.1 "); + head.push_str(&self.status_code); + head.push_str("\r\n"); + stream.write_all(head.as_bytes()).await.map_err(|_| HttpError::WriteHeadError)?; + + self.headers.send(stream).await?; + + stream.write_all(b"\r\n").await.map_err(|_| HttpError::WriteBodyError)?; + + self.body.send(stream).await?; + + Ok(()) + } +} diff --git a/src/ezhttp/server/handler.rs b/src/ezhttp/server/handler.rs index 71672a0..9084b29 100644 --- a/src/ezhttp/server/handler.rs +++ b/src/ezhttp/server/handler.rs @@ -1,3 +1,5 @@ +use crate::Sendable; + use super::{ HttpServer, super::{ diff --git a/src/ezhttp/server/mod.rs b/src/ezhttp/server/mod.rs index 59e840d..2bdca92 100644 --- a/src/ezhttp/server/mod.rs +++ b/src/ezhttp/server/mod.rs @@ -16,7 +16,7 @@ use crate::pin_handler; use super::error::HttpError; use super::request::HttpRequest; -use super::response::HttpResponse; +use super::Sendable; pub mod handler; pub mod starter; @@ -30,7 +30,7 @@ pub trait HttpServer { fn on_request( &self, req: &HttpRequest, - ) -> impl Future> + Send; + ) -> impl Future> + Send; fn on_error( &self, _: HttpError