longbridge_httpcli/
client.rs1use std::sync::Arc;
2
3use longbridge_geo::DcRegion;
4use reqwest::{
5 Client, Method,
6 header::{HeaderMap, HeaderName, HeaderValue},
7};
8use serde::Deserialize;
9
10use crate::{
11 AuthConfig, HttpClientConfig, HttpClientError, HttpClientResult, Json, RequestBuilder,
12};
13
14#[derive(Clone)]
16pub struct HttpClient {
17 pub(crate) http_cli: Client,
18 pub(crate) config: Arc<HttpClientConfig>,
19 pub(crate) default_headers: HeaderMap,
20}
21
22impl HttpClient {
23 pub fn new(config: HttpClientConfig) -> Self {
25 Self {
26 http_cli: Client::new(),
27 config: Arc::new(config),
28 default_headers: HeaderMap::new(),
29 }
30 }
31
32 pub fn header<K, V>(mut self, key: K, value: V) -> Self
34 where
35 K: TryInto<HeaderName>,
36 V: TryInto<HeaderValue>,
37 {
38 let key = key.try_into();
39 let value = value.try_into();
40 if let (Ok(key), Ok(value)) = (key, value) {
41 self.default_headers.insert(key, value);
42 }
43 self
44 }
45
46 pub async fn dc_region(&self) -> DcRegion {
50 match &self.config.auth {
51 AuthConfig::ApiKey {
52 app_key,
53 app_secret,
54 access_token,
55 } => DcRegion::from_credentials(&[app_key, access_token, app_secret]),
56 AuthConfig::OAuth(oauth) => oauth
57 .access_token()
58 .await
59 .map(|token| DcRegion::from_credential(&token))
60 .unwrap_or(DcRegion::Ap),
61 }
62 }
63
64 #[inline]
66 pub fn request(
67 &self,
68 method: Method,
69 path: impl Into<String>,
70 ) -> RequestBuilder<'_, (), (), ()> {
71 RequestBuilder::new(self, method, path)
72 }
73
74 pub async fn get_otp(&self) -> HttpClientResult<String> {
78 #[derive(Debug, Deserialize)]
79 struct Response {
80 otp: String,
81 limit: i32,
82 online: i32,
83 }
84
85 let resp = self
86 .request(Method::GET, "/v1/socket/token")
87 .response::<Json<Response>>()
88 .send()
89 .await?
90 .0;
91 tracing::info!(limit = resp.limit, online = resp.online, "create otp");
92
93 if resp.online >= resp.limit {
94 return Err(HttpClientError::ConnectionLimitExceeded {
95 limit: resp.limit,
96 online: resp.online,
97 });
98 }
99
100 Ok(resp.otp)
101 }
102}