1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
use serde::Deserialize;
use url::Url;
mod clients;
pub mod types;
pub use clients::*;
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error("error making request request")]
RequestError(#[from] reqwest::Error),
#[error("error")]
Ngrok(NgrokError),
#[error("unknown error returned: {0}")]
UnknownError(String),
}
#[derive(Debug, Deserialize)]
pub struct NgrokError {
pub error_code: String,
pub msg: String,
}
#[derive(Clone, Debug)]
pub struct ClientConfig {
pub api_key: String,
pub api_url: Option<Url>,
}
#[derive(Clone, Debug)]
pub struct Client {
conf: ClientConfig,
c: reqwest::Client,
}
impl Client {
pub fn new(conf: ClientConfig) -> Self {
Client {
c: reqwest::Client::new(),
conf,
}
}
pub(crate) async fn make_request<T, R>(
&self,
path: &str,
method: reqwest::Method,
req: Option<T>,
) -> Result<R, Error>
where
T: serde::Serialize,
R: serde::de::DeserializeOwned + Default,
{
let api_url = self
.conf
.api_url
.clone()
.unwrap_or_else(|| "https://api.ngrok.com".parse::<Url>().unwrap());
let mut builder = self
.c
.request(method.clone(), api_url.join(path).unwrap())
.bearer_auth(&self.conf.api_key)
.header("Ngrok-Version", "2");
if let Some(r) = req {
builder = match method {
reqwest::Method::GET => builder.query(&r),
_ => builder.json(&r),
};
}
let resp = builder.send().await?;
match resp.status() {
reqwest::StatusCode::NO_CONTENT => return Ok(Default::default()),
s if s.is_success() => {
return resp.json().await.map_err(|e| e.into());
}
_ => {}
}
let resp_bytes = resp.bytes().await?;
if let Ok(e) = serde_json::from_slice(&resp_bytes) {
return Err(Error::Ngrok(e));
}
Err(Error::UnknownError(
String::from_utf8_lossy(&resp_bytes).into(),
))
}
pub(crate) async fn get_by_uri<R>(&self, uri: &str) -> Result<R, Error>
where
R: serde::de::DeserializeOwned,
{
let builder = self
.c
.request(reqwest::Method::GET, uri)
.bearer_auth(&self.conf.api_key)
.header("Ngrok-Version", "2");
let resp = builder.send().await?;
if resp.status().is_success() {
return resp.json().await.map_err(|e| e.into());
}
let resp_bytes = resp.bytes().await?;
if let Ok(e) = serde_json::from_slice(&resp_bytes) {
return Err(Error::Ngrok(e));
}
Err(Error::UnknownError(
String::from_utf8_lossy(&resp_bytes).into(),
))
}
}