macro_rules! proto_err {
(conn: $($msg:tt)+) => {
log::debug!("connection error PROTOCOL_ERROR -- {};", format_args!($($msg)+))
};
(stream: $($msg:tt)+) => {
log::debug!("stream error PROTOCOL_ERROR -- {};", format_args!($($msg)+))
};
}
macro_rules! ready {
($e:expr) => {
match $e {
::std::task::Poll::Ready(r) => r,
::std::task::Poll::Pending => return ::std::task::Poll::Pending,
}
};
}
mod codec;
mod error;
mod hpack;
mod proto;
mod frame;
mod share;
pub mod client;
pub mod server;
pub use self::error::{Error, Reason};
pub use self::share::{FlowControl, Ping, PingPong, Pong, RecvStream, SendStream, StreamId};
pub use self::codec::{Codec, RecvError, SendError, UserError};
use std::task::{Context, Poll};
trait PollExt<T, E> {
fn map_ok_<U, F>(self, f: F) -> Poll<Option<Result<U, E>>>
where
F: FnOnce(T) -> U;
fn map_err_<U, F>(self, f: F) -> Poll<Option<Result<T, U>>>
where
F: FnOnce(E) -> U;
}
impl<T, E> PollExt<T, E> for Poll<Option<Result<T, E>>> {
fn map_ok_<U, F>(self, f: F) -> Poll<Option<Result<U, E>>>
where
F: FnOnce(T) -> U,
{
match self {
Poll::Ready(Some(Ok(t))) => Poll::Ready(Some(Ok(f(t)))),
Poll::Ready(Some(Err(e))) => Poll::Ready(Some(Err(e))),
Poll::Ready(None) => Poll::Ready(None),
Poll::Pending => Poll::Pending,
}
}
fn map_err_<U, F>(self, f: F) -> Poll<Option<Result<T, U>>>
where
F: FnOnce(E) -> U,
{
match self {
Poll::Ready(Some(Ok(t))) => Poll::Ready(Some(Ok(t))),
Poll::Ready(Some(Err(e))) => Poll::Ready(Some(Err(f(e)))),
Poll::Ready(None) => Poll::Ready(None),
Poll::Pending => Poll::Pending,
}
}
}
mod dispatcher;
mod service;
pub use self::dispatcher::Dispatcher;
pub use self::service::H2Service;
use std::pin::Pin;
use bytes::Bytes;
use futures_core::Stream;
use crate::http::error::PayloadError;
pub struct Payload {
pl: RecvStream,
}
impl Payload {
pub(crate) fn new(pl: RecvStream) -> Self {
Self { pl }
}
}
impl Stream for Payload {
type Item = Result<Bytes, PayloadError>;
fn poll_next(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Option<Self::Item>> {
let this = self.get_mut();
match Pin::new(&mut this.pl).poll_data(cx) {
Poll::Ready(Some(Ok(chunk))) => {
let len = chunk.len();
if let Err(err) = this.pl.flow_control().release_capacity(len) {
Poll::Ready(Some(Err(err.into())))
} else {
Poll::Ready(Some(Ok(chunk)))
}
}
Poll::Ready(Some(Err(err))) => Poll::Ready(Some(Err(err.into()))),
Poll::Pending => Poll::Pending,
Poll::Ready(None) => Poll::Ready(None),
}
}
}