Skip to main content

longbridge_httpcli/
client.rs

1use std::sync::Arc;
2
3use reqwest::{
4    Client, Method,
5    header::{HeaderMap, HeaderName, HeaderValue},
6};
7use serde::Deserialize;
8
9use crate::{HttpClientConfig, HttpClientError, HttpClientResult, Json, RequestBuilder};
10
11/// Longbridge HTTP client
12#[derive(Clone)]
13pub struct HttpClient {
14    pub(crate) http_cli: Client,
15    pub(crate) config: Arc<HttpClientConfig>,
16    pub(crate) default_headers: HeaderMap,
17}
18
19impl HttpClient {
20    /// Create a new `HttpClient`
21    pub fn new(config: HttpClientConfig) -> Self {
22        Self {
23            http_cli: Client::new(),
24            config: Arc::new(config),
25            default_headers: HeaderMap::new(),
26        }
27    }
28
29    /// Set the default header
30    pub fn header<K, V>(mut self, key: K, value: V) -> Self
31    where
32        K: TryInto<HeaderName>,
33        V: TryInto<HeaderValue>,
34    {
35        let key = key.try_into();
36        let value = value.try_into();
37        if let (Ok(key), Ok(value)) = (key, value) {
38            self.default_headers.insert(key, value);
39        }
40        self
41    }
42
43    /// Create a new request builder
44    #[inline]
45    pub fn request(
46        &self,
47        method: Method,
48        path: impl Into<String>,
49    ) -> RequestBuilder<'_, (), (), ()> {
50        RequestBuilder::new(self, method, path)
51    }
52
53    /// Get the socket OTP(One Time Password)
54    ///
55    /// Reference: <https://open.longbridge.com/en/docs/socket-token-api>
56    pub async fn get_otp(&self) -> HttpClientResult<String> {
57        #[derive(Debug, Deserialize)]
58        struct Response {
59            otp: String,
60            limit: i32,
61            online: i32,
62        }
63
64        let resp = self
65            .request(Method::GET, "/v1/socket/token")
66            .response::<Json<Response>>()
67            .send()
68            .await?
69            .0;
70        tracing::info!(limit = resp.limit, online = resp.online, "create otp");
71
72        if resp.online >= resp.limit {
73            return Err(HttpClientError::ConnectionLimitExceeded {
74                limit: resp.limit,
75                online: resp.online,
76            });
77        }
78
79        Ok(resp.otp)
80    }
81}