Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ chrono = { version = "0.4", default-features = false, features = ["clock", "std"
base64 = "0.22"
getrandom = "0.3"
unicode-general-category = "1.1"
reqwest = { version = "0.12", default-features = false, features = ["rustls-tls"] }
# rustls trusting the bundled roots and the platform's certificate store (spec/providers.md §2).
reqwest = { version = "0.12", default-features = false, features = [
"rustls-tls-webpki-roots",
"rustls-tls-native-roots",
] }
url = "2"
# init --template: the release's source archive (spec/service.md §2.1).
tar = { version = "0.4", default-features = false }
Expand Down
4 changes: 4 additions & 0 deletions crates/grida-fx-providers/src/transport/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
//! machine, not this one. Every other request is `https` to a remote host: through a proxy it
//! is tunnelled (`CONNECT`), so the proxy sees the host and port, and the request stays
//! encrypted end to end;
//! - **trust**: a server's certificate is accepted when it chains to the bundled Mozilla roots or
//! to a root the platform's certificate store trusts (the macOS keychain, the Windows store, the
//! system bundle elsewhere; `SSL_CERT_FILE` / `SSL_CERT_DIR`, when set, name it instead), read
//! when the clients are built;
//! - `redirect::Policy::none()`, no retries (reqwest's own retry of protocol NACKs is turned
//! off), `accept-encoding: identity` on every request (the adapter reads the entity as sent), a
//! connect timeout ([`HttpConfig::connect_timeout`], 30 s by default) inside the request's
Expand Down
5 changes: 3 additions & 2 deletions spec/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ Adapters are thin clients over one injected transport. The transport MUST make *
- `after_send`: anything else. A reset, a read timeout, a truncated body and a response over the cap all are `after_send`.
- A transport that cannot tell reports `after_send`.
8. **The network can be turned off.** With `GRIDA_FX_NETWORK=off`, a live invocation's transport refuses every exchange before it leaves (`not_sent`, refused). Tests of live paths use it; nothing is sent.
9. **Proxies never see a credential.** A request whose URL is plain `http`, or whose host is a loopback host (`localhost`, a loopback IP), goes straight to its host, whatever the environment's proxy settings say: a proxy would read a plain request, credential included, in clear text, and a loopback host is this machine, not the proxy's. Any other request is `https` to a remote host, and honours the proxy settings of the environment (`HTTPS_PROXY`, `ALL_PROXY`, `NO_PROXY`; `HTTP_PROXY` names a proxy for plain `http` only, so it never applies). Through a proxy it is tunnelled (`CONNECT`): the proxy sees the host and port, and the request stays encrypted to the provider. These variables are the transport's; they are not keys or endpoints (§3).
9. **Proxies never see a credential.** A request whose URL is plain `http`, or whose host is a loopback host (`localhost`, a loopback IP), goes straight to its host, whatever the environment's proxy settings say: a proxy would read a plain request, credential included, in clear text, and a loopback host is this machine, not the proxy's. Any other request is `https` to a remote host, and honours the proxy settings of the environment (`HTTPS_PROXY`, `ALL_PROXY`, `NO_PROXY`; `HTTP_PROXY` names a proxy for plain `http` only, so it never applies). Through a proxy it is tunnelled (`CONNECT`): the proxy sees the host and port, and the request stays encrypted to the provider, unless the platform trusts the proxy's own certificates (item 10). These variables are the transport's; they are not keys or endpoints (§3).
10. **Certificates chain to a trusted root.** A server's certificate is accepted when it chains to a well-known public root or to a root the platform's certificate store trusts, as the machine's other programs accept it. A proxy that presents certificates under a root the platform trusts can read a tunnelled request, credential included; which roots a machine trusts is its owner's choice, not the transport's.

The default transport is HTTP over rustls. Besides what the request sets, it sends `accept-encoding: identity`, `accept: */*` unless the request sets `accept`, and a `user-agent` on the provider and upload lanes. Tests use a replay transport that plays synthetic exchanges and asserts every request, or one that fails any send. The default transport MUST NOT be constructed in a test. A request, a response or a credential printed for debugging shows no URL path or query, no header value, no body and no key.
The default transport is HTTP over rustls, trusting the bundled Mozilla roots and the platform's certificate store (`SSL_CERT_FILE` / `SSL_CERT_DIR` in its place when set). Besides what the request sets, it sends `accept-encoding: identity`, `accept: */*` unless the request sets `accept`, and a `user-agent` on the provider and upload lanes. Tests use a replay transport that plays synthetic exchanges and asserts every request, or one that fails any send. The default transport MUST NOT be constructed in a test. A request, a response or a credential printed for debugging shows no URL path or query, no header value, no body and no key.

## 3. Keys and endpoints

Expand Down
Loading