diff --git a/src/body.rs b/src/body.rs index 9966213..4e84305 100644 --- a/src/body.rs +++ b/src/body.rs @@ -1,12 +1,12 @@ +use http_1::HeaderMap; +use http_body_1::Frame; +use pin_project_lite::pin_project; +use std::str::FromStr; use std::{ pin::Pin, task::{Context, Poll}, }; -use http_1::HeaderMap; -use http_body_1::Frame; -use pin_project_lite::pin_project; - // --- http-body 0.4 to http-body 1.0 --- pin_project! { @@ -48,7 +48,9 @@ where } match self.as_mut().project().body.poll_trailers(cx) { - Poll::Ready(Ok(Some(trailers))) => Poll::Ready(Some(Ok(Frame::trailers(http02_headermap_to_http1(trailers))))), + Poll::Ready(Ok(Some(trailers))) => Poll::Ready(Some(Ok(Frame::trailers( + http02_headermap_to_http1(trailers), + )))), Poll::Ready(Ok(None)) => Poll::Ready(None), Poll::Ready(Err(err)) => Poll::Ready(Some(Err(err))), Poll::Pending => Poll::Pending, @@ -143,7 +145,9 @@ where match ready!(this.body.poll_frame(cx)) { Some(Ok(frame)) => match frame.into_trailers() { - Ok(trailers) => break Poll::Ready(Ok(Some(http1_headermap_to_http02(trailers)))), + Ok(trailers) => { + break Poll::Ready(Ok(Some(http1_headermap_to_http02(trailers)))) + } // we might get a trailers frame on next poll // so loop and try again Err(_frame) => {} @@ -171,41 +175,109 @@ where } fn http1_headermap_to_http02(h: http_1::HeaderMap) -> http_02::HeaderMap { - unsafe { - std::mem::transmute::(h) + let mut hm = http_02::HeaderMap::new(); + for (k, v) in h { + hm.insert( + http_02::HeaderName::from_str(k.unwrap().as_str()).unwrap(), + http_02::HeaderValue::from_bytes(v.as_ref()).unwrap(), + ); } + hm } fn http02_headermap_to_http1(h: http_02::HeaderMap) -> http_1::HeaderMap { - unsafe { - std::mem::transmute::(h) + let mut hm = http_1::HeaderMap::new(); + for (k, v) in h { + hm.insert( + http_1::HeaderName::from_str(k.unwrap().as_str()).unwrap(), + http_1::HeaderValue::from_bytes(v.as_ref()).unwrap(), + ); } + hm } pub fn http1_request_to_http02(r: http_1::Request) -> http_02::Request { let (head, body) = r.into_parts(); - unsafe { - http_02::Request::from_parts(std::mem::transmute::<_, http_02::request::Parts>(head), body) + let mut build = http_02::request::Builder::new() + .method(head.method.as_str()) + .uri(format!("{}", head.uri)) + .version(match head.version { + http_1::version::Version::HTTP_09 => http_02::version::Version::HTTP_09, + http_1::version::Version::HTTP_10 => http_02::version::Version::HTTP_10, + http_1::version::Version::HTTP_11 => http_02::version::Version::HTTP_11, + http_1::version::Version::HTTP_2 => http_02::version::Version::HTTP_2, + http_1::version::Version::HTTP_3 => http_02::version::Version::HTTP_3, + _ => panic!("unknown version"), + }); + for (k, v) in head.headers { + build = build.header(k.unwrap().as_str(), v.as_ref()) } + // for v in head.extension { + // build = build.extension(v) + // } + build.body(body).unwrap() } pub fn http1_response_to_http02(r: http_1::Response) -> http_02::Response { let (head, body) = r.into_parts(); - unsafe { - http_02::Response::from_parts(std::mem::transmute::<_, http_02::response::Parts>(head), body) + let mut build = http_02::response::Builder::new() + .status(head.status.as_u16()) + .version(match head.version { + http_1::version::Version::HTTP_09 => http_02::version::Version::HTTP_09, + http_1::version::Version::HTTP_10 => http_02::version::Version::HTTP_10, + http_1::version::Version::HTTP_11 => http_02::version::Version::HTTP_11, + http_1::version::Version::HTTP_2 => http_02::version::Version::HTTP_2, + http_1::version::Version::HTTP_3 => http_02::version::Version::HTTP_3, + _ => panic!("unknown version"), + }); + for (k, v) in head.headers { + build = build.header(k.unwrap().as_str(), v.as_ref()) } + // for v in head.extension { + // build = build.extension(v) + // } + build.body(body).unwrap() } pub fn http02_request_to_http1(r: http_02::Request) -> http_1::Request { let (head, body) = r.into_parts(); - unsafe { - http_1::Request::from_parts(std::mem::transmute::<_, http_1::request::Parts>(head), body) + let mut build = http_1::request::Builder::new() + .method(head.method.as_str()) + .uri(format!("{}", head.uri)) + .version(match head.version { + http_02::version::Version::HTTP_09 => http_1::version::Version::HTTP_09, + http_02::version::Version::HTTP_10 => http_1::version::Version::HTTP_10, + http_02::version::Version::HTTP_11 => http_1::version::Version::HTTP_11, + http_02::version::Version::HTTP_2 => http_1::version::Version::HTTP_2, + http_02::version::Version::HTTP_3 => http_1::version::Version::HTTP_3, + _ => panic!("unknown version"), + }); + for (k, v) in head.headers { + build = build.header(k.unwrap().as_str(), v.as_ref()) } + // for v in head.extension { + // build = build.extension(v) + // } + build.body(body).unwrap() } pub fn http02_response_to_http1(r: http_02::Response) -> http_1::Response { let (head, body) = r.into_parts(); - unsafe { - http_1::Response::from_parts(std::mem::transmute::<_, http_1::response::Parts>(head), body) + let mut build = http_1::response::Builder::new() + .status(head.status.as_u16()) + .version(match head.version { + http_02::version::Version::HTTP_09 => http_1::version::Version::HTTP_09, + http_02::version::Version::HTTP_10 => http_1::version::Version::HTTP_10, + http_02::version::Version::HTTP_11 => http_1::version::Version::HTTP_11, + http_02::version::Version::HTTP_2 => http_1::version::Version::HTTP_2, + http_02::version::Version::HTTP_3 => http_1::version::Version::HTTP_3, + _ => panic!("unknown version"), + }); + for (k, v) in head.headers { + build = build.header(k.unwrap().as_str(), v.as_ref()) } -} \ No newline at end of file + // for v in head.extension { + // build = build.extension(v) + // } + build.body(body).unwrap() +} diff --git a/src/lib.rs b/src/lib.rs index 483ca3d..d3c8502 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -138,9 +138,9 @@ cfg_service! { mod body; -pub use body::{HttpBody04ToHttpBody1, HttpBody1ToHttpBody04}; -pub use body::{http1_request_to_http02, http1_response_to_http02}; pub use body::{http02_request_to_http1, http02_response_to_http1}; +pub use body::{http1_request_to_http02, http1_response_to_http02}; +pub use body::{HttpBody04ToHttpBody1, HttpBody1ToHttpBody04}; #[cfg(test)] mod tests;