ruma_client/
http_client.rs1use std::{future::Future, pin::Pin};
5
6use bytes::BufMut;
7use ruma::{
8 api::{OutgoingRequest, SendAccessToken, SupportedVersions},
9 UserId,
10};
11
12use crate::{add_user_id_to_query, ResponseError, ResponseResult};
13
14#[cfg(feature = "hyper")]
15mod hyper;
16#[cfg(feature = "reqwest")]
17mod reqwest;
18
19#[cfg(feature = "hyper")]
20pub use self::hyper::Hyper;
21#[cfg(feature = "hyper-native-tls")]
22pub use self::hyper::HyperNativeTls;
23#[cfg(feature = "hyper-rustls")]
24pub use self::hyper::HyperRustls;
25#[cfg(feature = "reqwest")]
26pub use self::reqwest::Reqwest;
27
28pub trait HttpClient: Sync {
30 type RequestBody: Default + BufMut + Send;
32
33 type ResponseBody: AsRef<[u8]>;
35
36 type Error: Send + Unpin;
38
39 fn send_http_request(
41 &self,
42 req: http::Request<Self::RequestBody>,
43 ) -> impl Future<Output = Result<http::Response<Self::ResponseBody>, Self::Error>> + Send;
44}
45
46pub trait DefaultConstructibleHttpClient: HttpClient {
48 fn default() -> Self;
50}
51
52pub trait HttpClientExt: HttpClient {
57 fn send_matrix_request<'a, R: OutgoingRequest + 'a>(
60 &'a self,
61 homeserver_url: &str,
62 access_token: SendAccessToken<'_>,
63 for_versions: &SupportedVersions,
64 request: R,
65 ) -> Pin<Box<dyn Future<Output = ResponseResult<Self, R>> + 'a + Send>> {
66 self.send_customized_matrix_request(
67 homeserver_url,
68 access_token,
69 for_versions,
70 request,
71 |_| Ok(()),
72 )
73 }
74
75 fn send_customized_matrix_request<'a, R, F>(
79 &'a self,
80 homeserver_url: &str,
81 access_token: SendAccessToken<'_>,
82 for_versions: &SupportedVersions,
83 request: R,
84 customize: F,
85 ) -> Pin<Box<dyn Future<Output = ResponseResult<Self, R>> + 'a + Send>>
86 where
87 R: OutgoingRequest + 'a,
88 F: FnOnce(&mut http::Request<Self::RequestBody>) -> Result<(), ResponseError<Self, R>> + 'a,
89 {
90 Box::pin(crate::send_customized_request(
91 self,
92 homeserver_url,
93 access_token,
94 for_versions,
95 request,
96 customize,
97 ))
98 }
99
100 fn send_matrix_request_as<'a, R: OutgoingRequest + 'a>(
106 &'a self,
107 homeserver_url: &str,
108 access_token: SendAccessToken<'_>,
109 for_versions: &SupportedVersions,
110 user_id: &'a UserId,
111 request: R,
112 ) -> Pin<Box<dyn Future<Output = ResponseResult<Self, R>> + 'a>> {
113 self.send_customized_matrix_request(
114 homeserver_url,
115 access_token,
116 for_versions,
117 request,
118 add_user_id_to_query::<Self, R>(user_id),
119 )
120 }
121}
122
123impl<T: HttpClient> HttpClientExt for T {}
124
125#[doc(hidden)]
126#[derive(Debug)]
127#[allow(clippy::exhaustive_structs)]
128pub struct Dummy;
129
130impl HttpClient for Dummy {
131 type RequestBody = Vec<u8>;
132 type ResponseBody = Vec<u8>;
133 type Error = ();
134
135 #[allow(clippy::diverging_sub_expression)]
136 async fn send_http_request(
137 &self,
138 _req: http::Request<Self::RequestBody>,
139 ) -> Result<http::Response<Self::ResponseBody>, Self::Error> {
140 unimplemented!("this client only exists to allow doctests to compile")
141 }
142}
143
144impl DefaultConstructibleHttpClient for Dummy {
145 fn default() -> Self {
146 Dummy
147 }
148}