Skip to main content

ntex_h2/client/
mod.rs

1//! Http2 client
2use std::io;
3
4use ntex_error::{ErrorDiagnostic, ResultType};
5use ntex_net::connect::ConnectError;
6use ntex_util::channel::Canceled;
7
8mod connector;
9mod pool;
10mod simple;
11mod stream;
12
13use crate::{error::ConnectionError, error::OperationError, frame};
14
15pub use self::connector::Connector;
16pub use self::pool::{Client, ClientBuilder};
17pub use self::simple::SimpleClient;
18pub use self::stream::{RecvStream, SendStream};
19
20/// Errors which can occur when attempting to handle http2 client connection.
21#[derive(thiserror::Error, Debug)]
22pub enum ClientError {
23    /// Protocol error
24    #[error("Protocol error")]
25    Protocol(#[source] ConnectionError),
26    /// Operation error
27    #[error("Operation error")]
28    Operation(
29        #[from]
30        #[source]
31        OperationError,
32    ),
33    /// Http/2 frame codec error
34    #[error("Http/2 codec error: {0}")]
35    Frame(#[from] frame::FrameError),
36    /// Handshake timeout
37    #[error("Handshake timeout")]
38    HandshakeTimeout,
39    /// Connect error
40    #[error("Connect error")]
41    Connect(
42        #[from]
43        #[source]
44        ConnectError,
45    ),
46    /// Peer disconnected
47    #[error("Peer disconnected")]
48    Disconnected(
49        #[from]
50        #[source]
51        io::Error,
52    ),
53}
54
55impl From<ConnectionError> for ClientError {
56    fn from(err: ConnectionError) -> Self {
57        Self::Protocol(err)
58    }
59}
60
61impl From<Canceled> for ClientError {
62    fn from(err: Canceled) -> Self {
63        Self::Disconnected(io::Error::other(err))
64    }
65}
66
67impl Clone for ClientError {
68    fn clone(&self) -> Self {
69        match self {
70            Self::Protocol(err) => Self::Protocol(err.clone()),
71            Self::Operation(err) => Self::Operation(err.clone()),
72            Self::Frame(err) => Self::Frame(*err),
73            Self::HandshakeTimeout => Self::HandshakeTimeout,
74            Self::Connect(err) => Self::Connect(err.clone()),
75            Self::Disconnected(err) => {
76                Self::Disconnected(io::Error::new(err.kind(), format!("{err}")))
77            }
78        }
79    }
80}
81
82impl ErrorDiagnostic for ClientError {
83    fn typ(&self) -> ResultType {
84        ResultType::ServiceError
85    }
86
87    fn signature(&self) -> &'static str {
88        match self {
89            ClientError::Protocol(err) => err.signature(),
90            ClientError::Operation(err) => err.signature(),
91            ClientError::Connect(err) => err.signature(),
92            ClientError::Disconnected(err) => err.signature(),
93            ClientError::Frame(_) => "h2-client-Frame",
94            ClientError::HandshakeTimeout => "h2-client-HandshakeTimeout",
95        }
96    }
97}
98
99#[cfg(feature = "unstable")]
100pub trait Observer {
101    /// New request is prepared
102    fn on_request(&mut self, id: frame::StreamId, headers: &mut frame::Headers);
103
104    /// Bytes has been written to memory
105    fn on_request_sent(&mut self, id: frame::StreamId);
106
107    /// Payload data has been written to memory
108    fn on_request_payload(&mut self, id: frame::StreamId, data: &frame::Data);
109
110    /// Response is received
111    fn on_response(&mut self, id: frame::StreamId, headers: &mut frame::Headers);
112
113    /// Payload data has been received
114    fn on_response_payload(&mut self, id: frame::StreamId, data: &frame::Data);
115}