convex-rust 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +137 -2
- package/dist/cli/bin.d.ts +2 -0
- package/dist/cli/bin.js +200 -0
- package/dist/cli/build.d.ts +146 -0
- package/dist/cli/build.js +902 -0
- package/dist/cli/demangle.d.ts +7 -0
- package/dist/cli/demangle.js +328 -0
- package/dist/cli/diagnostics.d.ts +34 -0
- package/dist/cli/diagnostics.js +296 -0
- package/dist/cli/generate.d.ts +29 -0
- package/dist/cli/generate.js +82 -0
- package/dist/cli/manifest.d.ts +24 -0
- package/dist/cli/manifest.js +75 -0
- package/dist/cli/rustApi.d.ts +78 -0
- package/dist/cli/rustApi.js +609 -0
- package/dist/cli/scaffold.d.ts +22 -0
- package/dist/cli/scaffold.js +114 -0
- package/dist/cli/shim.d.ts +30 -0
- package/dist/cli/shim.js +140 -0
- package/dist/cli/size.d.ts +17 -0
- package/dist/cli/size.js +73 -0
- package/dist/cli/split.d.ts +20 -0
- package/dist/cli/split.js +140 -0
- package/dist/cli/symbols.d.ts +30 -0
- package/dist/cli/symbols.js +133 -0
- package/dist/cli/toolchain.d.ts +53 -0
- package/dist/cli/toolchain.js +167 -0
- package/dist/cli/validators.d.ts +6 -0
- package/dist/cli/validators.js +66 -0
- package/dist/cli/wasisdk.d.ts +82 -0
- package/dist/cli/wasisdk.js +220 -0
- package/dist/cli/wasmHints.d.ts +29 -0
- package/dist/cli/wasmHints.js +172 -0
- package/dist/runtime/base64.d.ts +4 -0
- package/dist/runtime/base64.js +77 -0
- package/dist/runtime/crypto.d.ts +7 -0
- package/dist/runtime/crypto.js +421 -0
- package/dist/runtime/fastjson.d.ts +3 -0
- package/dist/runtime/fastjson.js +170 -0
- package/dist/runtime/host.d.ts +73 -0
- package/dist/runtime/host.js +1230 -0
- package/dist/runtime/http.d.ts +40 -0
- package/dist/runtime/http.js +157 -0
- package/dist/runtime/index.d.ts +2 -0
- package/dist/runtime/index.js +1 -0
- package/dist/runtime/intl.d.ts +5 -0
- package/dist/runtime/intl.js +69 -0
- package/dist/runtime/tmpfs.d.ts +129 -0
- package/dist/runtime/tmpfs.js +624 -0
- package/dist/runtime/wasi.d.ts +33 -0
- package/dist/runtime/wasi.js +216 -0
- package/package.json +57 -4
- package/rust/convex_fn/Cargo.toml +32 -0
- package/rust/convex_fn/LICENSE +201 -0
- package/rust/convex_fn/build.rs +3 -0
- package/rust/convex_fn/src/args.rs +416 -0
- package/rust/convex_fn/src/crypto.rs +237 -0
- package/rust/convex_fn/src/ctx.rs +1044 -0
- package/rust/convex_fn/src/dns.rs +356 -0
- package/rust/convex_fn/src/error.rs +179 -0
- package/rust/convex_fn/src/executor.rs +577 -0
- package/rust/convex_fn/src/fanout.rs +106 -0
- package/rust/convex_fn/src/fs.rs +19 -0
- package/rust/convex_fn/src/function_ref.rs +219 -0
- package/rust/convex_fn/src/http.rs +441 -0
- package/rust/convex_fn/src/intl.rs +75 -0
- package/rust/convex_fn/src/lib.rs +242 -0
- package/rust/convex_fn/src/logging.rs +222 -0
- package/rust/convex_fn/src/native.rs +360 -0
- package/rust/convex_fn/src/net.rs +122 -0
- package/rust/convex_fn/src/sys.rs +178 -0
- package/rust/convex_fn/src/values.rs +121 -0
- package/rust/convex_fn/src/wire.rs +579 -0
- package/rust/convex_fn_macros/Cargo.toml +13 -0
- package/rust/convex_fn_macros/LICENSE +201 -0
- package/rust/convex_fn_macros/src/derive.rs +632 -0
- package/rust/convex_fn_macros/src/lib.rs +338 -0
- package/rust/convex_reqwest/Cargo.toml +69 -0
- package/rust/convex_reqwest/LICENSE +201 -0
- package/rust/convex_reqwest/src/blocking.rs +287 -0
- package/rust/convex_reqwest/src/body.rs +152 -0
- package/rust/convex_reqwest/src/client.rs +359 -0
- package/rust/convex_reqwest/src/config_types.rs +150 -0
- package/rust/convex_reqwest/src/error.rs +241 -0
- package/rust/convex_reqwest/src/into_url.rs +57 -0
- package/rust/convex_reqwest/src/lib.rs +42 -0
- package/rust/convex_reqwest/src/multipart.rs +140 -0
- package/rust/convex_reqwest/src/request.rs +358 -0
- package/rust/convex_reqwest/src/response.rs +310 -0
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
use std::{fmt, future::Future, net::SocketAddr, sync::Arc, time::Duration};
|
|
2
|
+
|
|
3
|
+
use convex_fn::{select, Ctx, Either, FetchRequest, Redirect};
|
|
4
|
+
use http::{
|
|
5
|
+
header::{HeaderMap, HeaderName, HeaderValue, USER_AGENT},
|
|
6
|
+
Method, StatusCode,
|
|
7
|
+
};
|
|
8
|
+
use url::Url;
|
|
9
|
+
|
|
10
|
+
use crate::{
|
|
11
|
+
body::Body,
|
|
12
|
+
error::{Error, Kind, Result},
|
|
13
|
+
into_url::IntoUrl,
|
|
14
|
+
redirect, tls, Proxy, Request, RequestBuilder, Response,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/// An asynchronous `Client` to make Requests with. Every request becomes a
|
|
18
|
+
/// Convex `Fetch` task, so egress policy, limits, metering and logs are the
|
|
19
|
+
/// host's, exactly as for `fetch` in a JS action.
|
|
20
|
+
#[derive(Clone)]
|
|
21
|
+
pub struct Client {
|
|
22
|
+
inner: Arc<Config>,
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
#[derive(Default)]
|
|
26
|
+
struct Config {
|
|
27
|
+
headers: HeaderMap,
|
|
28
|
+
timeout: Option<Duration>,
|
|
29
|
+
https_only: bool,
|
|
30
|
+
no_redirect: bool,
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
impl Default for Client {
|
|
34
|
+
fn default() -> Self {
|
|
35
|
+
Self::new()
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
impl Client {
|
|
40
|
+
/// Constructs a new `Client`.
|
|
41
|
+
pub fn new() -> Client {
|
|
42
|
+
Client {
|
|
43
|
+
inner: Arc::new(Config::default()),
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/// Creates a `ClientBuilder` to configure a `Client`.
|
|
48
|
+
pub fn builder() -> ClientBuilder {
|
|
49
|
+
ClientBuilder::new()
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
pub fn get<U: IntoUrl>(&self, url: U) -> RequestBuilder {
|
|
53
|
+
self.request(Method::GET, url)
|
|
54
|
+
}
|
|
55
|
+
pub fn post<U: IntoUrl>(&self, url: U) -> RequestBuilder {
|
|
56
|
+
self.request(Method::POST, url)
|
|
57
|
+
}
|
|
58
|
+
pub fn put<U: IntoUrl>(&self, url: U) -> RequestBuilder {
|
|
59
|
+
self.request(Method::PUT, url)
|
|
60
|
+
}
|
|
61
|
+
pub fn patch<U: IntoUrl>(&self, url: U) -> RequestBuilder {
|
|
62
|
+
self.request(Method::PATCH, url)
|
|
63
|
+
}
|
|
64
|
+
pub fn delete<U: IntoUrl>(&self, url: U) -> RequestBuilder {
|
|
65
|
+
self.request(Method::DELETE, url)
|
|
66
|
+
}
|
|
67
|
+
pub fn head<U: IntoUrl>(&self, url: U) -> RequestBuilder {
|
|
68
|
+
self.request(Method::HEAD, url)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/// Start building a `Request` with the `Method` and `Url`.
|
|
72
|
+
pub fn request<U: IntoUrl>(&self, method: Method, url: U) -> RequestBuilder {
|
|
73
|
+
let req = url.into_url().map(|url| Request::new(method, url));
|
|
74
|
+
RequestBuilder::new(self.clone(), req)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/// Executes a `Request`.
|
|
78
|
+
pub fn execute(&self, request: Request) -> impl Future<Output = Result<Response>> {
|
|
79
|
+
let this = self.clone();
|
|
80
|
+
async move { this.execute_inner(request).await }
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async fn execute_inner(&self, request: Request) -> Result<Response> {
|
|
84
|
+
let (method, url, mut headers, body, timeout) = request.into_parts();
|
|
85
|
+
if self.inner.https_only && url.scheme() != "https" {
|
|
86
|
+
return Err(Error::builder_msg("URL scheme is not allowed").with_url(url));
|
|
87
|
+
}
|
|
88
|
+
let timeout = timeout.or(self.inner.timeout);
|
|
89
|
+
for (k, v) in &self.inner.headers {
|
|
90
|
+
if !headers.contains_key(k) {
|
|
91
|
+
headers.append(k.clone(), v.clone());
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// An in-memory body is sent as is; a streaming one is uploaded chunk by chunk
|
|
95
|
+
// (`Ctx::fetch_upload`), so it never has to fit in memory.
|
|
96
|
+
let mut upload = None;
|
|
97
|
+
let body = match body.map(Body::into_source) {
|
|
98
|
+
Some(Ok(b)) => Some(b),
|
|
99
|
+
Some(Err(src)) => {
|
|
100
|
+
upload = Some(src);
|
|
101
|
+
None
|
|
102
|
+
}
|
|
103
|
+
None => None,
|
|
104
|
+
};
|
|
105
|
+
let mut fr = FetchRequest {
|
|
106
|
+
url: url.to_string(),
|
|
107
|
+
method: method.as_str().to_string(),
|
|
108
|
+
headers: headers
|
|
109
|
+
.iter()
|
|
110
|
+
.map(|(k, v)| (k.as_str().to_string(), latin1(v.as_bytes())))
|
|
111
|
+
.collect(),
|
|
112
|
+
body: body.map(|b| b.to_vec()),
|
|
113
|
+
redirect: if self.inner.no_redirect {
|
|
114
|
+
Redirect::Manual
|
|
115
|
+
} else {
|
|
116
|
+
Redirect::Follow
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
if matches!(method, Method::GET | Method::HEAD)
|
|
120
|
+
&& fr.body.as_ref().is_some_and(Vec::is_empty)
|
|
121
|
+
{
|
|
122
|
+
fr.body = None;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
let ctx = Ctx::default();
|
|
126
|
+
// Dropping `send` (the timeout below, or the caller dropping the request future)
|
|
127
|
+
// aborts the host fetch.
|
|
128
|
+
let send = async {
|
|
129
|
+
match upload {
|
|
130
|
+
Some(src) => ctx.fetch_stream_upload(fr, src).await,
|
|
131
|
+
None => ctx.fetch_stream(fr).await,
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
let stream = match timeout {
|
|
135
|
+
// The host `sleep` task, not a tokio timer: inside `block_on_direct` (a blocking client
|
|
136
|
+
// in an action) no tokio timer is ever driven. Dropping `send` cancels the fetch.
|
|
137
|
+
Some(t) => match select(send, ctx.sleep(millis(t))).await {
|
|
138
|
+
Either::Left(r) => r,
|
|
139
|
+
Either::Right(_) => return Err(Error::timeout(Kind::Request).with_url(url)),
|
|
140
|
+
},
|
|
141
|
+
None => send.await,
|
|
142
|
+
}
|
|
143
|
+
.map_err(|e| {
|
|
144
|
+
Error::request(crate::error::FetchFailed(e.to_string())).with_url(url.clone())
|
|
145
|
+
})?;
|
|
146
|
+
|
|
147
|
+
let status = StatusCode::from_u16(stream.status)
|
|
148
|
+
.map_err(|e| Error::request(e).with_url(url.clone()))?;
|
|
149
|
+
let mut resp_headers = HeaderMap::new();
|
|
150
|
+
for (k, v) in &stream.headers {
|
|
151
|
+
if let (Ok(k), Ok(v)) = (
|
|
152
|
+
HeaderName::from_bytes(k.as_bytes()),
|
|
153
|
+
header_value(v),
|
|
154
|
+
) {
|
|
155
|
+
resp_headers.append(k, v);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
let final_url = Url::parse(&stream.url).unwrap_or(url);
|
|
159
|
+
Ok(Response::from_fetch(
|
|
160
|
+
stream,
|
|
161
|
+
status,
|
|
162
|
+
resp_headers,
|
|
163
|
+
final_url,
|
|
164
|
+
timeout,
|
|
165
|
+
))
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
impl fmt::Debug for Client {
|
|
170
|
+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
171
|
+
f.debug_struct("Client").finish()
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/// A `ClientBuilder` can be used to create a `Client` with custom
|
|
176
|
+
/// configuration. Options with no equivalent for host-side fetch (TLS,
|
|
177
|
+
/// proxies, pooling, redirects, ...) are accepted and ignored.
|
|
178
|
+
#[must_use]
|
|
179
|
+
pub struct ClientBuilder {
|
|
180
|
+
config: Config,
|
|
181
|
+
error: Option<Error>,
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
impl Default for ClientBuilder {
|
|
185
|
+
fn default() -> Self {
|
|
186
|
+
Self::new()
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
macro_rules! ignored {
|
|
191
|
+
($($(#[$m:meta])* $name:ident($($arg:ident: $ty:ty),*);)*) => {
|
|
192
|
+
$(
|
|
193
|
+
$(#[$m])*
|
|
194
|
+
pub fn $name(self $(, $arg: $ty)*) -> ClientBuilder {
|
|
195
|
+
$(let _ = $arg;)*
|
|
196
|
+
self
|
|
197
|
+
}
|
|
198
|
+
)*
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
impl ClientBuilder {
|
|
203
|
+
pub fn new() -> ClientBuilder {
|
|
204
|
+
ClientBuilder {
|
|
205
|
+
config: Config::default(),
|
|
206
|
+
error: None,
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/// Returns a `Client` that uses this `ClientBuilder` configuration.
|
|
211
|
+
pub fn build(self) -> Result<Client> {
|
|
212
|
+
match self.error {
|
|
213
|
+
Some(e) => Err(e),
|
|
214
|
+
None => Ok(Client {
|
|
215
|
+
inner: Arc::new(self.config),
|
|
216
|
+
}),
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/// Sets the default headers for every request.
|
|
221
|
+
pub fn default_headers(mut self, headers: HeaderMap) -> ClientBuilder {
|
|
222
|
+
for (k, v) in headers.iter() {
|
|
223
|
+
self.config.headers.insert(k.clone(), v.clone());
|
|
224
|
+
}
|
|
225
|
+
self
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/// Sets the `User-Agent` header to be used by this client.
|
|
229
|
+
pub fn user_agent<V>(mut self, value: V) -> ClientBuilder
|
|
230
|
+
where
|
|
231
|
+
HeaderValue: TryFrom<V>,
|
|
232
|
+
<HeaderValue as TryFrom<V>>::Error: Into<http::Error>,
|
|
233
|
+
{
|
|
234
|
+
match HeaderValue::try_from(value) {
|
|
235
|
+
Ok(v) => {
|
|
236
|
+
self.config.headers.insert(USER_AGENT, v);
|
|
237
|
+
}
|
|
238
|
+
Err(e) => self.error = Some(Error::builder(e.into())),
|
|
239
|
+
}
|
|
240
|
+
self
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/// Enables a total request timeout.
|
|
244
|
+
pub fn timeout(mut self, timeout: Duration) -> ClientBuilder {
|
|
245
|
+
self.config.timeout = Some(timeout);
|
|
246
|
+
self
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/// Only use HTTPS URLs.
|
|
250
|
+
pub fn https_only(mut self, enabled: bool) -> ClientBuilder {
|
|
251
|
+
self.config.https_only = enabled;
|
|
252
|
+
self
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/// Sets the redirect policy. `Policy::none()` returns 3xx responses as
|
|
256
|
+
/// is; any other policy follows redirects (the host's limit applies).
|
|
257
|
+
pub fn redirect(mut self, policy: redirect::Policy) -> ClientBuilder {
|
|
258
|
+
self.config.no_redirect = policy.is_none();
|
|
259
|
+
self
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/// Add a proxy (accepted, ignored).
|
|
263
|
+
pub fn proxy(self, proxy: Proxy) -> ClientBuilder {
|
|
264
|
+
let _ = proxy;
|
|
265
|
+
self
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/// Add a root certificate (accepted, ignored).
|
|
269
|
+
pub fn add_root_certificate(self, cert: tls::Certificate) -> ClientBuilder {
|
|
270
|
+
let _ = cert;
|
|
271
|
+
self
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/// Sets the identity to be used for client certificate authentication (ignored).
|
|
275
|
+
pub fn identity(self, identity: tls::Identity) -> ClientBuilder {
|
|
276
|
+
let _ = identity;
|
|
277
|
+
self
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
ignored! {
|
|
281
|
+
connect_timeout(timeout: Duration);
|
|
282
|
+
read_timeout(timeout: Duration);
|
|
283
|
+
no_proxy();
|
|
284
|
+
pool_idle_timeout(val: impl Into<Option<Duration>>);
|
|
285
|
+
pool_max_idle_per_host(max: usize);
|
|
286
|
+
http1_only();
|
|
287
|
+
http1_title_case_headers();
|
|
288
|
+
http2_prior_knowledge();
|
|
289
|
+
http2_adaptive_window(enabled: bool);
|
|
290
|
+
http2_keep_alive_interval(interval: impl Into<Option<Duration>>);
|
|
291
|
+
http2_keep_alive_timeout(timeout: Duration);
|
|
292
|
+
http2_keep_alive_while_idle(enabled: bool);
|
|
293
|
+
tcp_nodelay(enabled: bool);
|
|
294
|
+
tcp_keepalive(val: impl Into<Option<Duration>>);
|
|
295
|
+
local_address(addr: impl Into<Option<std::net::IpAddr>>);
|
|
296
|
+
referer(enable: bool);
|
|
297
|
+
gzip(enable: bool);
|
|
298
|
+
brotli(enable: bool);
|
|
299
|
+
zstd(enable: bool);
|
|
300
|
+
deflate(enable: bool);
|
|
301
|
+
no_gzip();
|
|
302
|
+
no_brotli();
|
|
303
|
+
no_zstd();
|
|
304
|
+
no_deflate();
|
|
305
|
+
cookie_store(enable: bool);
|
|
306
|
+
hickory_dns(enable: bool);
|
|
307
|
+
trust_dns(enable: bool);
|
|
308
|
+
no_hickory_dns();
|
|
309
|
+
no_trust_dns();
|
|
310
|
+
danger_accept_invalid_certs(accept: bool);
|
|
311
|
+
danger_accept_invalid_hostnames(accept: bool);
|
|
312
|
+
tls_built_in_root_certs(enabled: bool);
|
|
313
|
+
tls_built_in_webpki_certs(enabled: bool);
|
|
314
|
+
tls_built_in_native_certs(enabled: bool);
|
|
315
|
+
tls_sni(enabled: bool);
|
|
316
|
+
min_tls_version(version: tls::Version);
|
|
317
|
+
max_tls_version(version: tls::Version);
|
|
318
|
+
use_native_tls();
|
|
319
|
+
use_rustls_tls();
|
|
320
|
+
tls_info(enabled: bool);
|
|
321
|
+
connection_verbose(enabled: bool);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/// Override DNS resolution for a domain (ignored).
|
|
325
|
+
pub fn resolve(self, domain: &str, addr: SocketAddr) -> ClientBuilder {
|
|
326
|
+
let _ = (domain, addr);
|
|
327
|
+
self
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
impl fmt::Debug for ClientBuilder {
|
|
332
|
+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
333
|
+
f.debug_struct("ClientBuilder").finish()
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/// A timeout as whole host-sleep milliseconds (rounded up, at least 1).
|
|
338
|
+
pub(crate) fn millis(d: Duration) -> u64 {
|
|
339
|
+
u64::try_from(d.as_nanos().div_ceil(1_000_000))
|
|
340
|
+
.unwrap_or(u64::MAX)
|
|
341
|
+
.max(1)
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/// A header value's bytes as the ByteString `fetch` takes (one char per byte), so values that
|
|
345
|
+
/// are not UTF-8 survive the round trip instead of being dropped.
|
|
346
|
+
fn latin1(b: &[u8]) -> String {
|
|
347
|
+
b.iter().map(|&c| c as char).collect()
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/// The inverse of [`latin1`] for response headers (fetch hands out ByteStrings); a value with
|
|
351
|
+
/// chars above U+00FF is taken as UTF-8.
|
|
352
|
+
fn header_value(s: &str) -> std::result::Result<HeaderValue, http::header::InvalidHeaderValue> {
|
|
353
|
+
if s.chars().all(|c| (c as u32) < 256) {
|
|
354
|
+
let bytes: Vec<u8> = s.chars().map(|c| c as u8).collect();
|
|
355
|
+
HeaderValue::from_bytes(&bytes)
|
|
356
|
+
} else {
|
|
357
|
+
HeaderValue::from_str(s)
|
|
358
|
+
}
|
|
359
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
//! Types for options that the Convex host owns (redirects, proxies, TLS).
|
|
2
|
+
//! They exist so vendor crates compile; they have no effect.
|
|
3
|
+
|
|
4
|
+
pub mod redirect {
|
|
5
|
+
use http::StatusCode;
|
|
6
|
+
use url::Url;
|
|
7
|
+
|
|
8
|
+
/// A type that controls the policy on how to handle the following of redirects.
|
|
9
|
+
pub struct Policy {
|
|
10
|
+
_max: Option<usize>,
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
impl Policy {
|
|
14
|
+
pub fn limited(max: usize) -> Self {
|
|
15
|
+
Policy { _max: Some(max) }
|
|
16
|
+
}
|
|
17
|
+
pub fn none() -> Self {
|
|
18
|
+
Policy { _max: Some(0) }
|
|
19
|
+
}
|
|
20
|
+
pub fn custom<T>(policy: T) -> Self
|
|
21
|
+
where
|
|
22
|
+
T: Fn(Attempt) -> Action + Send + Sync + 'static,
|
|
23
|
+
{
|
|
24
|
+
let _ = policy;
|
|
25
|
+
Policy { _max: None }
|
|
26
|
+
}
|
|
27
|
+
/// `Policy::none()`: the host returns 3xx responses as is. Any other
|
|
28
|
+
/// policy follows redirects (the host's limit is 20 hops).
|
|
29
|
+
pub(crate) fn is_none(&self) -> bool {
|
|
30
|
+
self._max == Some(0)
|
|
31
|
+
}
|
|
32
|
+
pub fn redirect(&self, attempt: Attempt) -> Action {
|
|
33
|
+
match self._max {
|
|
34
|
+
Some(m) if attempt.previous.len() >= m => attempt.stop(),
|
|
35
|
+
_ => attempt.follow(),
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
impl Default for Policy {
|
|
41
|
+
fn default() -> Policy {
|
|
42
|
+
Policy::limited(10)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/// A type that holds information on the next request and previous requests in a redirect chain.
|
|
47
|
+
#[derive(Debug)]
|
|
48
|
+
pub struct Attempt<'a> {
|
|
49
|
+
status: StatusCode,
|
|
50
|
+
next: &'a Url,
|
|
51
|
+
previous: &'a [Url],
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/// An action to perform when a redirect status code is found.
|
|
55
|
+
#[derive(Debug)]
|
|
56
|
+
pub struct Action {
|
|
57
|
+
_follow: bool,
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
impl<'a> Attempt<'a> {
|
|
61
|
+
pub fn status(&self) -> StatusCode {
|
|
62
|
+
self.status
|
|
63
|
+
}
|
|
64
|
+
pub fn url(&self) -> &Url {
|
|
65
|
+
self.next
|
|
66
|
+
}
|
|
67
|
+
pub fn previous(&self) -> &[Url] {
|
|
68
|
+
self.previous
|
|
69
|
+
}
|
|
70
|
+
pub fn follow(self) -> Action {
|
|
71
|
+
Action { _follow: true }
|
|
72
|
+
}
|
|
73
|
+
pub fn stop(self) -> Action {
|
|
74
|
+
Action { _follow: false }
|
|
75
|
+
}
|
|
76
|
+
pub fn error<E: Into<Box<dyn std::error::Error + Send + Sync>>>(self, error: E) -> Action {
|
|
77
|
+
let _ = error.into();
|
|
78
|
+
Action { _follow: false }
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
use crate::{error::Result, into_url::IntoUrl};
|
|
84
|
+
|
|
85
|
+
/// Configuration of a proxy (accepted, ignored).
|
|
86
|
+
#[derive(Debug, Clone)]
|
|
87
|
+
pub struct Proxy {
|
|
88
|
+
_p: (),
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
impl Proxy {
|
|
92
|
+
pub fn all<U: IntoUrl>(proxy_scheme: U) -> Result<Proxy> {
|
|
93
|
+
proxy_scheme.into_url().map(|_| Proxy { _p: () })
|
|
94
|
+
}
|
|
95
|
+
pub fn http<U: IntoUrl>(proxy_scheme: U) -> Result<Proxy> {
|
|
96
|
+
Self::all(proxy_scheme)
|
|
97
|
+
}
|
|
98
|
+
pub fn https<U: IntoUrl>(proxy_scheme: U) -> Result<Proxy> {
|
|
99
|
+
Self::all(proxy_scheme)
|
|
100
|
+
}
|
|
101
|
+
pub fn basic_auth(self, username: &str, password: &str) -> Proxy {
|
|
102
|
+
let _ = (username, password);
|
|
103
|
+
self
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
pub mod tls {
|
|
108
|
+
use crate::error::Result;
|
|
109
|
+
|
|
110
|
+
/// A TLS protocol version.
|
|
111
|
+
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
|
112
|
+
pub struct Version(u8);
|
|
113
|
+
|
|
114
|
+
impl Version {
|
|
115
|
+
pub const TLS_1_0: Version = Version(0);
|
|
116
|
+
pub const TLS_1_1: Version = Version(1);
|
|
117
|
+
pub const TLS_1_2: Version = Version(2);
|
|
118
|
+
pub const TLS_1_3: Version = Version(3);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/// A root certificate (accepted, ignored).
|
|
122
|
+
#[derive(Debug, Clone)]
|
|
123
|
+
pub struct Certificate {
|
|
124
|
+
_p: (),
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
impl Certificate {
|
|
128
|
+
pub fn from_der(der: &[u8]) -> Result<Certificate> {
|
|
129
|
+
let _ = der;
|
|
130
|
+
Ok(Certificate { _p: () })
|
|
131
|
+
}
|
|
132
|
+
pub fn from_pem(pem: &[u8]) -> Result<Certificate> {
|
|
133
|
+
let _ = pem;
|
|
134
|
+
Ok(Certificate { _p: () })
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/// A client identity (accepted, ignored).
|
|
139
|
+
#[derive(Debug, Clone)]
|
|
140
|
+
pub struct Identity {
|
|
141
|
+
_p: (),
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
impl Identity {
|
|
145
|
+
pub fn from_pem(buf: &[u8]) -> Result<Identity> {
|
|
146
|
+
let _ = buf;
|
|
147
|
+
Ok(Identity { _p: () })
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|