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}