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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
[]
= "structured-proxy"
= "Universal gRPC→REST transcoding proxy — config-driven, works with any gRPC service"
= "8.1.3"
= "2021"
# The oldest toolchain the crate builds on: the `msrv` CI job pins it, so
# raising it is a deliberate change.
= "1.99"
= ["Dmitry Prudnikov <mail@polaz.com>"]
= "Apache-2.0"
= "https://github.com/structured-world/structured-proxy"
= "https://github.com/structured-world/structured-proxy"
= "https://docs.rs/structured-proxy"
= "README.md"
= ["grpc", "rest", "proxy", "transcoding", "protobuf"]
= ["network-programming", "web-programming::http-server"]
# docs.rs builds with the `redis` feature on top of the defaults so the
# Redis-backed rate-limit store (and its intra-doc links) are documented.
[]
= ["redis"]
[]
= "structured_proxy"
= "src/lib.rs"
# The standalone proxy: `cargo install structured-proxy --features cli`. Behind
# the `cli` feature, so a crate that depends on the library compiles none of
# its dependencies.
[[]]
= "structured-proxy"
= "src/main.rs"
= ["cli"]
# Its crate name is the library's; the library's rustdoc is the one to keep.
= false
[]
# HTTP framework of the proxy's routes; `serve` runs connections on hyper-util.
= { = "0.8", = ["macros"] }
# `util`: the guarded gRPC and fallback paths are boxed services.
= { = "0.5", = ["util"] }
= { = "0.7", = ["trace"] }
# Foundational HTTP types, used directly by the framework-agnostic embedding
# hooks (src/hooks.rs) so an embedder never names `axum`. Already in the tree
# transitively via both axum and tonic; pinned here to make the public API deps
# explicit.
= "1"
= "1"
# The body bound of an upstream's responses and of requests `ProxyService`
# accepts; already in the tree through hyper, axum and tonic.
= "1"
# The response futures of `ProxyService`, named without boxing each one.
= "0.2"
# `serve_with`'s connections: HTTP/1.1 and HTTP/2 on one port, over TCP or
# TLS. Already in the tree through axum and tonic.
= { = "0.1", = ["server-auto", "server-graceful", "service", "tokio"] }
# The executor HTTP/2 connections spawn their stream tasks on: a
# `TaskTracker` a shutdown waits on, and a `CancellationToken` that ends
# them (0.7.16: `run_until_cancelled` checks the token first). Both already
# in the tree through hyper-util and tonic.
= "1"
= { = "0.7.16", = ["rt"] }
# The router axum matches paths with: a transcoded template is checked with it
# before axum registers it, where a path it rejects would panic. Already in the
# tree through axum, which pins the version this resolves to.
= "0.8"
# The hash of the routing maps a request is looked up in. Their keys are the
# paths and segments the proxy binds, fixed at startup, so a request can only
# look up, never fill a map with colliding keys: no randomized hash is needed,
# and FxHash looks up short strings faster than SipHash.
= "2"
# Decodes the path parameters of a custom verb bound on another route the
# request matches, as axum decodes its own; already in the tree through axum.
= "2"
# gRPC client (to upstream service). `tls-connect-info` gives a rustls server
# stream the connection record (client certificates) a tonic handler reads, so
# an in-process upstream behind the proxy gets it; tonic exports the type only
# with its TLS backends, so it is named through that stream (`tokio-rustls`,
# the same crate tonic uses). Neither links a crypto provider.
= { = "0.14", = ["tls-connect-info"] }
= { = "0.26", = false }
= "0.14"
# `grpc_web.translate`: gRPC-Web to gRPC for an upstream that speaks only gRPC.
= "0.14"
# Canonical google.rpc.Status / error_details descriptors (FILE_DESCRIPTOR_SET)
# and the Status message used to decode `grpc-status-details-bin`, so REST error
# bodies can render typed details even when the product descriptors do not
# import google/rpc/*.
= "0.14"
= "0.14"
# Async runtime
= { = "1", = ["full"] }
# Serialization
= { = "1", = ["derive"] }
= "1"
# The config file and the sections an embedder hands over as YAML. Safe Rust;
# deserialization only.
= { = "1.3", = false, = ["deserialize"] }
# The key path (`runtime.worker_threads`) a config error names; already in the
# tree through axum.
= "0.1"
# Streaming (server-streaming RPC handler)
= "0.3"
# Protobuf reflection (REST↔gRPC transcoding)
= { = "0.16", = ["serde"] }
# Logging
= "0.1"
# Error handling
= "2"
= "1"
# Metrics
= "0.14"
# Rate limiting (Shield middleware)
= "6"
= "0.1"
= "2"
# Optional shared rate-limit store for multi-instance deployments.
= { = "1.2", = ["tokio-comp", "connection-manager"], = true }
# Auth (JWT validation, route policies).
# Optional: it backs the BUILT-IN verifier only. A consumer that injects its own
# `hooks::TokenVerifier` builds with `default-features = false` and links no JWT
# crypto at all. Crypto backend is selected via this crate's `rust_crypto` /
# `aws_lc_rs` features (see [features] below); `use_pem` is always required for
# PEM key parsing and is therefore enabled unconditionally.
= { = "11", = false, = [
"use_pem",
], = true }
# Outbound HTTPS (JWKS fetches, the rate-limit service). reqwest 0.13's `rustls`
# feature hardwires the aws-lc-rs provider (C FFI), so `rustls-no-provider`
# builds rustls without one; src/tls.rs hands reqwest a fully preconfigured
# ClientConfig with the Mozilla roots from webpki-roots. Bundling the roots
# keeps the binary self-contained, so it works on musl / scratch / distroless
# images with no system CA bundle. The crypto provider follows the crypto
# backend features below: none is linked without one, and the process-wide
# rustls provider the embedder installs is used instead.
= { = "0.13", = false, = ["rustls-no-provider", "json"] }
= { = "0.23", = false, = ["std", "tls12"] }
# The pure-Rust provider of the `rust_crypto` backend. `0.0.2-alpha` still
# names its `rustls-webpki` 0.102 dependency, which carries four CRL /
# name-constraint advisories; the provider only reads algorithm identifier
# constants from it, while certificates are verified by rustls' own (patched)
# webpki. See deny.toml.
= { = "0.0.2-alpha", = true }
= "1"
= "0.4"
= "0.23"
= "0.11"
= "2"
= "0.4"
# Envoy ext_authz `Authorization/Check` messages (External AuthZ).
= "0.7"
# The binary's command line and log output (the `cli` feature).
= { = "4", = ["derive"], = true }
= { = "0.3", = ["env-filter", "json"], = true }
[]
= ["rust_crypto"]
# The built-in JWT verifier (config-driven keys: PEM file or JWKS endpoint),
# implemented with `jsonwebtoken`. Implied by both crypto backends below, so it
# is never enabled on its own. With neither backend the crate links no JWT
# crypto: `auth.mode: "jwt"` then requires a verifier injected through
# `ProxyServer::with_token_verifier`.
= ["dep:jsonwebtoken"]
# Crypto backend for the BUILT-IN verifier and the outbound TLS client.
# Additive, like every Cargo feature: with both on, jsonwebtoken cannot infer a
# provider, so the built-in verifier installs `aws_lc_rs` (constant-time,
# advisory-free) for the process, and TLS uses aws-lc too. They no longer
# decide for the whole dependency graph: a consumer that cannot accept this
# crate's choice supplies its own verifier (see `builtin_jwt`) and installs its
# own rustls provider. With neither, the crate links no crypto backend at all.
#
# `rust_crypto` (default): pure-Rust RustCrypto backend. Pulls in `rsa`, which
# carries RUSTSEC-2023-0071 (Marvin Attack). Not exploitable on our verify-only
# path (public key, no private-key ops); see deny.toml / issue #48.
= ["builtin_jwt", "jsonwebtoken/rust_crypto", "dep:rustls-rustcrypto"]
# `aws_lc_rs`: constant-time / FIPS-capable backend via aws-lc (C FFI),
# advisory-free. Opt-in for consumers that allow FFI; enable with
# `default-features = false, features = ["aws_lc_rs"]`.
= ["builtin_jwt", "jsonwebtoken/aws_lc_rs", "rustls/aws_lc_rs"]
# Shared Redis-backed rate-limit store for multi-instance deployments.
= ["dep:redis"]
# The `structured-proxy` binary. Off by default: the library links none of its
# dependencies unless asked. It carries `redis`, so `cargo install
# structured-proxy --features cli` builds what the release packages ship.
= ["dep:clap", "dep:tracing-subscriber", "redis"]
[]
# `test-util`: deadline tests run on a paused clock instead of waiting.
= { = "1", = ["macros", "rt-multi-thread", "test-util"] }
= { = "0.5", = ["util", "limit"] }
# An embedder's own CORS around the proxy (tests/edge.rs).
= { = "0.7", = ["cors"] }
= "0.1"
# `hyper::upgrade::on`: a fallback that upgrades its connection (src/serve/tests.rs).
= "1"
# A raw HTTP/2 client that sees the GOAWAY of a graceful shutdown
# (tests/shutdown.rs); already in the tree through hyper.
= "0.4"
# Trailer frames for the hand-written upstream response in
# tests/upstream_controls.rs (tonic's server API cannot set success trailers).
= "1"
# The local HTTPS server the outbound TLS client is tested against
# (src/tls/tests.rs), and the provider it runs on in every build. Default
# features would pull in aws-lc.
= { = "0.26", = false, = ["tls12"] }
= "0.0.2-alpha"
# benches/jwt_verify.rs. Plots and rayon are left out: numbers are enough.
= { = "0.8", = false, = ["async_tokio", "cargo_bench_support"] }
# The embedding-hooks integration test (tests/hooks.rs) writes hook impls using
# only these (the same crates a real embedder uses — none is an HTTP framework)
# and drives the resulting router via axum + tower for assertions.
= { = "0.8", = ["macros"] }
= "1"
= "1"
= "0.1"
= "3"
= "0.10"
= "0.4"
= "0.1"
# Compiles the in-memory test protos (google.api.http routes) of the
# error-details integration test without a protoc binary.
= "0.10"
# Runs the built binary, so it needs the binary built.
[[]]
= "cli"
= ["cli"]
# The built-in verifier's cost with and without the claims cache.
[[]]
= "jwt_verify"
= false
= ["builtin_jwt"]
# Building a gRPC request message from path, query and body.
[[]]
= "transcode_request"
= false