gproxy_channel_api/
transport.rs1use bytes::Bytes;
4
5#[derive(Debug, Clone, Copy, Default)]
21pub struct TransportOptions {
22 pub total_timeout: Option<std::time::Duration>,
23 pub max_redirects: Option<usize>,
24 pub http_version: Option<http::Version>,
25 pub omit_body: bool,
26}
27
28pub trait ByteStreamDecoder: Send {
30 fn push(&mut self, chunk: &[u8]) -> Result<Vec<u8>, ClientError>;
32
33 fn finish(&mut self) -> Result<Vec<u8>, ClientError>;
35}
36
37#[derive(Debug, thiserror::Error)]
39pub enum ClientError {
40 #[error("upstream transport error: {0}")]
41 Transport(String),
42 #[error("upstream client config error: {0}")]
45 Config(String),
46 #[error("upstream stream decode failed: {0}")]
48 Decode(String),
49}
50
51#[cfg(not(target_arch = "wasm32"))]
54pub type RespStream =
55 std::pin::Pin<Box<dyn futures_core::Stream<Item = Result<Bytes, ClientError>> + Send>>;
56#[cfg(target_arch = "wasm32")]
57pub type RespStream =
58 std::pin::Pin<Box<dyn futures_core::Stream<Item = Result<Bytes, ClientError>>>>;
59
60#[cfg(not(target_arch = "wasm32"))]
62#[derive(Debug)]
63pub enum ConduitFrame {
64 Text(String),
65 Binary(Bytes),
66 Close,
67}
68
69#[cfg(not(target_arch = "wasm32"))]
71#[async_trait::async_trait]
72pub trait ConduitSocket: Send {
73 async fn send_text(&mut self, text: String) -> Result<(), ClientError>;
74 async fn send_binary(&mut self, _bytes: Bytes) -> Result<(), ClientError> {
75 Err(ClientError::Config(
76 "binary upstream websocket frames not supported by this client".into(),
77 ))
78 }
79 async fn recv_text(&mut self) -> Option<Result<String, ClientError>>;
80 async fn recv_frame(&mut self) -> Option<Result<ConduitFrame, ClientError>> {
81 self.recv_text()
82 .await
83 .map(|result| result.map(ConduitFrame::Text))
84 }
85 async fn close(&mut self) -> Result<(), ClientError> {
86 Ok(())
87 }
88}
89
90#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
94#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))]
95pub trait UpstreamClient: Send + Sync {
96 async fn send(&self, req: http::Request<Bytes>) -> Result<http::Response<Bytes>, ClientError>;
97
98 async fn send_websocket(
99 &self,
100 _req: http::Request<Bytes>,
101 ) -> Result<http::Response<Bytes>, ClientError> {
102 Err(ClientError::Config(
103 "upstream websocket not supported by this client".into(),
104 ))
105 }
106
107 async fn send_streaming(
108 &self,
109 req: http::Request<Bytes>,
110 ) -> Result<(http::StatusCode, http::HeaderMap, RespStream), ClientError> {
111 let resp = self.send(req).await?;
112 let (parts, body) = resp.into_parts();
113 let once = futures_util::stream::once(async move { Ok::<Bytes, ClientError>(body) });
114 Ok((parts.status, parts.headers, Box::pin(once)))
115 }
116
117 #[cfg(not(target_arch = "wasm32"))]
118 async fn open_websocket(
119 &self,
120 _req: http::Request<Bytes>,
121 ) -> Result<Box<dyn ConduitSocket>, ClientError> {
122 Err(ClientError::Config(
123 "upstream websocket not supported by this client".into(),
124 ))
125 }
126}