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