srs_client/http_api.rs
1//! [HTTP API] definitions of [SRS].
2//!
3//! [SRS]: https://ossrs.io/
4//! [1]: https://ossrs.io/lts/en-us/docs/v5/doc/http-api
5#![allow(unused_imports)]
6
7mod client;
8mod common;
9mod error;
10mod feature;
11mod meminfos;
12mod response;
13mod rusages;
14mod self_proc_stats;
15mod stream;
16mod summary;
17mod system_proc_stats;
18mod vhost;
19
20pub use error::SrsClientError;
21pub use response::{SrsClientResp, SrsClientRespData};
22pub use stream::Stream;
23
24use reqwest::{Client, Response as ReqwestResponse};
25use url::Url;
26
27/// Client for performing requests to [HTTP API][1] of spawned [SRS].
28///
29/// [SRS]: https://ossrs.io/
30/// [1]: https://ossrs.io/lts/en-us/docs/v5/doc/http-api
31#[derive(Clone, Debug)]
32pub struct SrsClient {
33 http_client: Client,
34 base_url: Url,
35}
36
37impl SrsClient {
38 /// Build [`SrsClient`] for future call to [HTTP API][1] API of spawned [SRS]. .
39 ///
40 /// # Errors
41 ///
42 /// If incorrect `base_url` passed
43 ///
44 /// [SRS]: https://ossrs.io/
45 /// [1]: https://ossrs.io/lts/en-us/docs/v5/doc/http-api
46 pub fn build<S: Into<String>>(base_url: S) -> Result<Self, SrsClientError> {
47 let base_url = Url::parse(&base_url.into())
48 .and_then(|url| url.join("/api/v1/"))
49 .map_err(SrsClientError::IncorrectBaseUrl)?;
50 tracing::debug!("base_url: {base_url}");
51 Ok(Self {
52 http_client: Client::new(),
53 base_url,
54 })
55 }
56
57 async fn get(&self, url: &str) -> Result<ReqwestResponse, SrsClientError> {
58 self.http_client
59 .get(
60 self.base_url
61 .join(url)
62 .map_err(SrsClientError::IncorrectApiUrl)?,
63 )
64 .send()
65 .await
66 .map_err(SrsClientError::RequestFailed)
67 }
68
69 async fn delete(&self, url: &str) -> Result<ReqwestResponse, SrsClientError> {
70 self.http_client
71 .delete(
72 self.base_url
73 .join(url)
74 .map_err(SrsClientError::IncorrectApiUrl)?,
75 )
76 .send()
77 .await
78 .map_err(SrsClientError::RequestFailed)
79 }
80
81 async fn process_resp(&self, resp: ReqwestResponse) -> Result<SrsClientResp, SrsClientError> {
82 if !resp.status().is_success() {
83 return Err(SrsClientError::BadStatus(resp.status()));
84 }
85 // tracing::debug!(url = resp.url().to_string(), "processing request");
86 tracing::debug!("processing request to: {}", resp.url());
87 let resp = resp
88 .json::<SrsClientResp>()
89 .await
90 .map_err(SrsClientError::DeserializeError)?;
91 Ok(resp)
92 }
93
94 /// [Kicks off][1] a client connected to [SRS] server by its `id`.
95 ///
96 /// # Errors
97 ///
98 /// If API request cannot be performed, or fails. See [`SrsClientError`](enum@SrsClientError)
99 /// for details.
100 ///
101 /// [SRS]: https://ossrs.io/
102 /// [1]: https://ossrs.io/lts/en-us/docs/v5/doc/http-api#kickoff-client
103 pub async fn kickoff_client<T: Into<String>>(
104 self,
105 id: T,
106 ) -> Result<SrsClientResp, SrsClientError> {
107 let resp = self.delete(&format!("clients/{}/", id.into())).await?;
108 self.process_resp(resp).await
109 }
110
111 /// Retrieves the server version.
112 ///
113 /// # Errors
114 ///
115 /// If API request cannot be performed, or fails. See [`SrsClientError`](enum@SrsClientError)
116 /// for details.
117 pub async fn get_version(self) -> Result<SrsClientResp, SrsClientError> {
118 let resp = self.get("versions").await?;
119 self.process_resp(resp).await
120 }
121
122 /// Manages all vhosts or a specified vhost.
123 ///
124 /// # Errors
125 ///
126 /// If API request cannot be performed, or fails. See [`SrsClientError`](enum@SrsClientError)
127 /// for details.
128 pub async fn get_vhosts(self) -> Result<SrsClientResp, SrsClientError> {
129 let resp = self.get("vhosts").await?;
130 self.process_resp(resp).await
131 }
132
133 /// Manages all streams or a specified stream.
134 ///
135 /// # Errors
136 ///
137 /// If API request cannot be performed, or fails. See [`SrsClientError`](enum@SrsClientError)
138 /// for details.
139 pub async fn get_streams(self) -> Result<SrsClientResp, SrsClientError> {
140 let resp = self.get("streams").await?;
141 self.process_resp(resp).await
142 }
143
144 /// Retrieves all streams as a typed list.
145 ///
146 /// # Errors
147 ///
148 /// If API request cannot be performed, or fails. See [`SrsClientError`](enum@SrsClientError)
149 /// for details.
150 pub async fn get_stream_list(self) -> Result<Vec<Stream>, SrsClientError> {
151 let response = self.get_streams().await?;
152 match response.data {
153 SrsClientRespData::Streams { streams } => Ok(streams),
154 _ => Ok(Vec::new()),
155 }
156 }
157
158 /// Manages all clients or a specified client, default query top 10 clients.
159 ///
160 /// # Errors
161 ///
162 /// If API request cannot be performed, or fails. See [`SrsClientError`](enum@SrsClientError)
163 /// for details.
164 pub async fn get_clients(self) -> Result<SrsClientResp, SrsClientError> {
165 let resp = self.get("clients").await?;
166 self.process_resp(resp).await
167 }
168
169 /// Retrieves the supported features of SRS.
170 ///
171 /// # Errors
172 ///
173 /// If API request cannot be performed, or fails. See [`SrsClientError`](enum@SrsClientError)
174 /// for details.
175 pub async fn get_features(self) -> Result<SrsClientResp, SrsClientError> {
176 let resp = self.get("features").await?;
177 self.process_resp(resp).await
178 }
179
180 /// Retrieves the rusage of SRS.
181 ///
182 /// # Errors
183 ///
184 /// If API request cannot be performed, or fails. See [`SrsClientError`](enum@SrsClientError)
185 /// for details.
186 pub async fn get_rusages(self) -> Result<SrsClientResp, SrsClientError> {
187 let resp = self.get("rusages").await?;
188 self.process_resp(resp).await
189 }
190
191 /// Retrieves the self process stats.
192 ///
193 /// # Errors
194 ///
195 /// If API request cannot be performed, or fails. See [`SrsClientError`](enum@SrsClientError)
196 /// for details.
197 pub async fn get_self_proc_stats(self) -> Result<SrsClientResp, SrsClientError> {
198 let resp = self.get("self_proc_stats").await?;
199 self.process_resp(resp).await
200 }
201
202 /// Retrieves the system process stats.
203 ///
204 /// # Errors
205 ///
206 /// If API request cannot be performed, or fails. See [`SrsClientError`](enum@SrsClientError)
207 /// for details.
208 pub async fn get_system_proc_stats(self) -> Result<SrsClientResp, SrsClientError> {
209 let resp = self.get("system_proc_stats").await?;
210 self.process_resp(resp).await
211 }
212
213 /// Retrieves the meminfo of system.
214 ///
215 /// # Errors
216 ///
217 /// If API request cannot be performed, or fails. See [`SrsClientError`](enum@SrsClientError)
218 /// for details.
219 pub async fn get_meminfos(self) -> Result<SrsClientResp, SrsClientError> {
220 let resp = self.get("meminfos").await?;
221 self.process_resp(resp).await
222 }
223}