Update http deps
This commit is contained in:
@@ -1,18 +1,22 @@
|
||||
pub use hyper_util;
|
||||
|
||||
pub use http_body_util;
|
||||
pub use http_body_util::Full;
|
||||
pub use hyper_util;
|
||||
|
||||
use bytes::BufMut;
|
||||
use bytes::Bytes;
|
||||
use bytes::BytesMut;
|
||||
use err::PublicError;
|
||||
use futures_util::pin_mut;
|
||||
use futures_util::Stream;
|
||||
use futures_util::StreamExt;
|
||||
use futures_util::TryStreamExt;
|
||||
use http::header;
|
||||
use http::Request;
|
||||
use http::Response;
|
||||
use http::StatusCode;
|
||||
use http_body::Frame;
|
||||
use http_body_util::combinators::BoxBody;
|
||||
use http_body_util::BodyExt;
|
||||
use hyper::body::Body;
|
||||
use hyper::body::Incoming;
|
||||
use hyper::client::conn::http2::SendRequest;
|
||||
use hyper::Method;
|
||||
use netpod::log::*;
|
||||
@@ -21,18 +25,150 @@ use netpod::ChannelConfigQuery;
|
||||
use netpod::ChannelConfigResponse;
|
||||
use netpod::NodeConfigCached;
|
||||
use netpod::APP_JSON;
|
||||
use serde::Serialize;
|
||||
use std::fmt;
|
||||
use std::pin::Pin;
|
||||
use std::task::Context;
|
||||
use std::task::Poll;
|
||||
use tokio::io;
|
||||
use tokio::io::AsyncRead;
|
||||
use tokio::io::ReadBuf;
|
||||
use tokio::net::TcpStream;
|
||||
use url::Url;
|
||||
|
||||
pub type BodyBox = BoxBody<Bytes, BodyError>;
|
||||
pub type RespBox = Response<BodyBox>;
|
||||
pub type Requ = Request<Incoming>;
|
||||
pub type RespFull = Response<Full<Bytes>>;
|
||||
|
||||
// TODO rename: too similar.
|
||||
pub type StreamBody = http_body_util::StreamBody<Pin<Box<dyn Stream<Item = Result<Frame<Bytes>, BodyError>> + Send>>>;
|
||||
pub type StreamResponse = Response<StreamBody>;
|
||||
|
||||
fn _assert1() {
|
||||
let body: Full<Bytes> = todoval();
|
||||
let _: &dyn Body<Data = _, Error = _> = &body;
|
||||
}
|
||||
|
||||
fn _assert2() {
|
||||
let stream: Pin<Box<dyn futures_util::Stream<Item = Result<Frame<Bytes>, BodyError>>>> = todoval();
|
||||
let body = http_body_util::StreamBody::new(stream);
|
||||
let _: &dyn Body<Data = _, Error = _> = &body;
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
fn todoval<T>() -> T {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn body_empty() -> StreamBody {
|
||||
// Full::new(Bytes::new()).map_err(Into::into).boxed()
|
||||
let fr = Frame::data(Bytes::new());
|
||||
let stream = futures_util::stream::iter([Ok(fr)]);
|
||||
http_body_util::StreamBody::new(Box::pin(stream))
|
||||
}
|
||||
|
||||
pub fn body_string<S: ToString>(body: S) -> StreamBody {
|
||||
// Full::new(Bytes::from(body.to_string())).map_err(Into::into).boxed()
|
||||
let fr = Frame::data(Bytes::from(body.to_string()));
|
||||
let stream = futures_util::stream::iter([Ok(fr)]);
|
||||
http_body_util::StreamBody::new(Box::pin(stream))
|
||||
}
|
||||
|
||||
pub fn body_bytes<D: Into<Bytes>>(body: D) -> StreamBody {
|
||||
let fr = Frame::data(body.into());
|
||||
let stream = futures_util::stream::iter([Ok(fr)]);
|
||||
http_body_util::StreamBody::new(Box::pin(stream))
|
||||
}
|
||||
|
||||
pub trait IntoBody {
|
||||
fn into_body(self) -> StreamBody;
|
||||
}
|
||||
|
||||
pub struct StringBody {
|
||||
body: String,
|
||||
}
|
||||
|
||||
impl<S: ToString> From<S> for StringBody {
|
||||
fn from(value: S) -> Self {
|
||||
Self {
|
||||
body: value.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoBody for StringBody {
|
||||
fn into_body(self) -> StreamBody {
|
||||
let fr = Frame::data(Bytes::from(self.body.as_bytes().to_vec()));
|
||||
let stream = futures_util::stream::iter([Ok(fr)]);
|
||||
http_body_util::StreamBody::new(Box::pin(stream))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ToJsonBody {
|
||||
body: Vec<u8>,
|
||||
}
|
||||
|
||||
impl<S: Serialize> From<&S> for ToJsonBody {
|
||||
fn from(value: &S) -> Self {
|
||||
Self {
|
||||
body: serde_json::to_vec(value).unwrap_or(Vec::new()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoBody for ToJsonBody {
|
||||
fn into_body(self) -> StreamBody {
|
||||
let fr = Frame::data(Bytes::from(self.body));
|
||||
let stream = futures_util::stream::iter([Ok(fr)]);
|
||||
http_body_util::StreamBody::new(Box::pin(stream))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn body_stream<S, I, E>(stream: S) -> StreamBody
|
||||
where
|
||||
S: Stream<Item = Result<I, E>> + Send + 'static,
|
||||
I: Into<Bytes>,
|
||||
E: fmt::Display,
|
||||
{
|
||||
let stream = stream.map(|x| match x {
|
||||
Ok(x) => Ok(Frame::data(x.into())),
|
||||
Err(_e) => Err(BodyError::Bad),
|
||||
});
|
||||
StreamBody::new(Box::pin(stream))
|
||||
}
|
||||
|
||||
pub struct StreamIncoming {
|
||||
inp: http_body_util::BodyStream<Incoming>,
|
||||
}
|
||||
|
||||
impl StreamIncoming {
|
||||
pub fn new(inp: Incoming) -> Self {
|
||||
Self {
|
||||
inp: http_body_util::BodyStream::new(inp),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Stream for StreamIncoming {
|
||||
type Item = Result<Bytes, BodyError>;
|
||||
|
||||
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
|
||||
use Poll::*;
|
||||
match self.inp.poll_next_unpin(cx) {
|
||||
Ready(Some(Ok(x))) => {
|
||||
if x.is_data() {
|
||||
Ready(Some(Ok(x.into_data().unwrap())))
|
||||
} else {
|
||||
Ready(Some(Ok(Bytes::new())))
|
||||
}
|
||||
}
|
||||
Ready(Some(Err(e))) => {
|
||||
error!("{e}");
|
||||
Ready(Some(Err(BodyError::Bad)))
|
||||
}
|
||||
Ready(None) => Ready(None),
|
||||
Pending => Pending,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum BodyError {
|
||||
@@ -62,19 +198,19 @@ pub enum Error {
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for Error {
|
||||
fn from(value: std::io::Error) -> Self {
|
||||
fn from(_: std::io::Error) -> Self {
|
||||
Self::IO
|
||||
}
|
||||
}
|
||||
|
||||
impl From<http::Error> for Error {
|
||||
fn from(value: http::Error) -> Self {
|
||||
fn from(_: http::Error) -> Self {
|
||||
Self::Http
|
||||
}
|
||||
}
|
||||
|
||||
impl From<hyper::Error> for Error {
|
||||
fn from(value: hyper::Error) -> Self {
|
||||
fn from(_: hyper::Error) -> Self {
|
||||
Self::Http
|
||||
}
|
||||
}
|
||||
@@ -102,13 +238,11 @@ pub async fn http_get(url: Url, accept: &str) -> Result<HttpResponse, Error> {
|
||||
.uri(url.to_string())
|
||||
.header(header::HOST, url.host_str().ok_or_else(|| Error::BadUrl)?)
|
||||
.header(header::ACCEPT, accept)
|
||||
.body(Full::new(Bytes::new()))?;
|
||||
.body(body_empty())?;
|
||||
let mut send_req = connect_client(req.uri()).await?;
|
||||
let res = send_req.send_request(req).await?;
|
||||
let (head, mut body) = res.into_parts();
|
||||
debug!("http_get head {head:?}");
|
||||
use bytes::BufMut;
|
||||
use http_body_util::BodyExt;
|
||||
let mut buf = BytesMut::new();
|
||||
while let Some(x) = body.frame().await {
|
||||
match x {
|
||||
@@ -128,14 +262,13 @@ pub async fn http_get(url: Url, accept: &str) -> Result<HttpResponse, Error> {
|
||||
}
|
||||
|
||||
pub async fn http_post(url: Url, accept: &str, body: String) -> Result<Bytes, Error> {
|
||||
let body = Bytes::from(body.as_bytes().to_vec());
|
||||
let req = Request::builder()
|
||||
.method(http::Method::POST)
|
||||
.uri(url.to_string())
|
||||
.header(header::HOST, url.host_str().ok_or_else(|| Error::BadUrl)?)
|
||||
.header(header::CONTENT_TYPE, APP_JSON)
|
||||
.header(header::ACCEPT, accept)
|
||||
.body(Full::new(body))?;
|
||||
.body(body_string(body))?;
|
||||
let mut send_req = connect_client(req.uri()).await?;
|
||||
let res = send_req.send_request(req).await?;
|
||||
if res.status() != StatusCode::OK {
|
||||
@@ -143,12 +276,12 @@ pub async fn http_post(url: Url, accept: &str, body: String) -> Result<Bytes, Er
|
||||
let (_head, body) = res.into_parts();
|
||||
let buf = read_body_bytes(body).await?;
|
||||
let s = String::from_utf8_lossy(&buf);
|
||||
error!("{s}");
|
||||
// TODO return error
|
||||
return Err(Error::Http);
|
||||
}
|
||||
let (head, mut body) = res.into_parts();
|
||||
debug!("http_get head {head:?}");
|
||||
use bytes::BufMut;
|
||||
use http_body_util::BodyExt;
|
||||
let mut buf = BytesMut::new();
|
||||
while let Some(x) = body.frame().await {
|
||||
match x {
|
||||
@@ -164,7 +297,7 @@ pub async fn http_post(url: Url, accept: &str, body: String) -> Result<Bytes, Er
|
||||
Ok(buf)
|
||||
}
|
||||
|
||||
pub async fn connect_client(uri: &http::Uri) -> Result<SendRequest<Full<Bytes>>, Error> {
|
||||
pub async fn connect_client(uri: &http::Uri) -> Result<SendRequest<StreamBody>, Error> {
|
||||
let host = uri.host().ok_or_else(|| Error::BadUrl)?;
|
||||
let port = uri.port_u16().ok_or_else(|| Error::BadUrl)?;
|
||||
let stream = TcpStream::connect(format!("{host}:{port}")).await?;
|
||||
@@ -178,8 +311,6 @@ pub async fn connect_client(uri: &http::Uri) -> Result<SendRequest<Full<Bytes>>,
|
||||
}
|
||||
|
||||
pub async fn read_body_bytes(mut body: hyper::body::Incoming) -> Result<Bytes, Error> {
|
||||
use bytes::BufMut;
|
||||
use http_body_util::BodyExt;
|
||||
let mut buf = BytesMut::new();
|
||||
while let Some(x) = body.frame().await {
|
||||
match x {
|
||||
|
||||
Reference in New Issue
Block a user