From 3f8e8476596ac11aba24a3bcc427107a56f9a2df Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sun, 22 Aug 2021 16:41:02 +0100 Subject: [PATCH] own http body type Signed-off-by: Ian Jackson --- Cargo.lock | 1 + Cargo.toml | 1 + server/suser.rs | 2 +- server/sweb.rs | 13 +++++++------ src/prelude.rs | 3 ++- src/queue.rs | 32 ++++++++++++++++++++++++++++++++ 6 files changed, 44 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9b65d3e..593f1e4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -431,6 +431,7 @@ dependencies = [ "memchr", "mime", "parking_lot", + "pin-project-lite", "regex", "sha2", "structopt", diff --git a/Cargo.toml b/Cargo.toml index b5f5c13..54575e5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,6 +41,7 @@ regex = "1.5" lazy_static = "1.4" log = "0.4" memchr = "2" +pin-project-lite = "0.2" sha2 = "0.9" structopt = "0.3" subtle = "2" diff --git a/server/suser.rs b/server/suser.rs index 69881e5..48c8be5 100644 --- a/server/suser.rs +++ b/server/suser.rs @@ -51,7 +51,7 @@ pub async fn run(global: Arc, } } { let response = WebResponse { - data: Ok(vec![ /* xxx */ ]), + data: Ok(default()), warnings: default(), }; diff --git a/server/sweb.rs b/server/sweb.rs index d4e825e..0176e46 100644 --- a/server/sweb.rs +++ b/server/sweb.rs @@ -30,15 +30,16 @@ pub struct WebResponse { pub data: Result, } -pub type WebResponseData = Vec; +pub type WebResponseData = FrameQueueBuf; +pub type WebResponseBody = BufBody; pub async fn handle( conn: Arc, global: Arc, req: hyper::Request -) -> Result, hyper::http::Error> { +) -> Result, hyper::http::Error> { if req.method() == Method::GET { - let mut resp = hyper::Response::new(hyper::Body::from("hippotat\r\n")); + let mut resp = hyper::Response::new(BufBody::display("hippotat\r\n")); resp.headers_mut().insert( "Content-Type", "text/plain; charset=US-ASCII".try_into().unwrap() @@ -149,7 +150,7 @@ pub async fn handle( //dbg!(DumpHex(hmac_got), hmac_ok, client_exists); if ! bool::from(hmac_ok & client_exists) { debug!("{} rejected client {}", &conn, &client_name); - let body = hyper::Body::from("Not authorised\r\n"); + let body = BufBody::display("Not authorised\r\n"); return Ok( hyper::Response::builder() .status(hyper::StatusCode::FORBIDDEN) @@ -208,7 +209,7 @@ pub async fn handle( &warnings.warnings); } - let data = hyper::Body::from(data); + let data = BufBody::new(data); Ok::<_,AE>( hyper::Response::builder() .header("Content-Type", r#"application/octet-stream"#) @@ -223,6 +224,6 @@ pub async fn handle( hyper::Response::builder() .status(hyper::StatusCode::BAD_REQUEST) .header("Content-Type", r#"text/plain; charset="utf-8""#) - .body(errmsg.into()) + .body(BufBody::display(errmsg)) }) } diff --git a/src/prelude.rs b/src/prelude.rs index 228509b..c7c53e1 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -29,7 +29,7 @@ pub use cervine::Cow as Cervine; pub use extend::ext; pub use fehler::{throw, throws}; pub use futures::{poll, future, FutureExt, StreamExt, TryStreamExt}; -pub use hyper::body::{Bytes, Buf}; +pub use hyper::body::{Bytes, Buf, HttpBody}; pub use hyper::{Method, Uri}; pub use hyper_tls::HttpsConnector; pub use ipnet::IpNet; @@ -38,6 +38,7 @@ pub use lazy_regex::{regex_captures, regex_is_match, regex_replace_all}; pub use lazy_static::lazy_static; pub use log::{trace, debug, info, warn, error}; pub use memchr::memmem; +pub use pin_project_lite::pin_project; pub use structopt::StructOpt; pub use subtle::ConstantTimeEq; pub use thiserror::Error; diff --git a/src/queue.rs b/src/queue.rs index 9deb48b..5e22de9 100644 --- a/src/queue.rs +++ b/src/queue.rs @@ -59,6 +59,7 @@ impl QueueBuf where E: AsRef<[u8]> { self.content += l; } pub fn is_empty(&self) -> bool { self.content == 0 } + pub fn len(&self) -> usize { self.content } } impl FrameQueueBuf { @@ -70,6 +71,7 @@ impl FrameQueueBuf { self.queue.push_(Cervine::Borrowed(&SLIP_END_SLICE)); } pub fn is_empty(&self) -> bool { self.queue.is_empty() } + pub fn len(&self) -> usize { self.queue.len() } } impl Extend for FrameQueueBuf where E: Into> { @@ -104,3 +106,33 @@ impl hyper::body::Buf for FrameQueueBuf { fn chunk(&self) -> &[u8] { self.queue.chunk() } fn advance(&mut self, cnt: usize) { self.queue.advance(cnt) } } + +pin_project!{ + pub struct BufBody { + body: Option, + } +} +impl BufBody { + pub fn new(body: B) -> Self { Self { body: Some(body ) } } +} +impl BufBody { + pub fn display(s: S) -> Self { + let s = s.to_string().into_bytes(); + let mut buf: FrameQueueBuf = default(); + buf.push(s); + Self::new(buf) + } +} + +impl HttpBody for BufBody { + type Error = Void; + type Data = B; + fn poll_data(self: Pin<&mut Self>, _: &mut std::task::Context<'_>) + -> Poll>> { + Poll::Ready(Ok(self.project().body.take()).transpose()) + } + fn poll_trailers(self: Pin<&mut Self>, _: &mut std::task::Context<'_>) + -> Poll>, Void>> { + Poll::Ready(Ok(None)) + } +} -- 2.30.2