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
//! HTTP server and client surface for Camber.
//!
//! This module is the main entrypoint for building services: routing,
//! middleware, request and response types, server startup, proxying, and a
//! small built-in HTTP client all live here.
//!
//! # Start With a Router
//!
//! ```rust,no_run
//! use camber::RuntimeError;
//! use camber::http::{self, Response, Router};
//!
//! fn main() -> Result<(), RuntimeError> {
//! let mut router = Router::new();
//! router.get("/hello", |_req| async {
//! Response::text(200, "Hello, world!")
//! });
//! http::serve("0.0.0.0:8080", router)
//! }
//! ```
//!
//! Use [`self::serve`] for the normal blocking server case. Use the `serve_async*`
//! or `serve_background*` variants when you need explicit handle management
//! inside an existing runtime scope.
//!
//! # Core Types
//!
//! - [`self::Router`]: register routes, middleware, SSE, streams, proxy routes, and
//! feature-gated WebSocket or gRPC handlers
//! - [`self::Request`]: inspect params, query strings, headers, cookies, form data,
//! multipart bodies, and raw bytes
//! - [`self::Response`]: build text, JSON, bytes, headers, and cookies
//! - [`self::IntoResponse`]: handler return conversion for `Response` and
//! `Result<Response, RuntimeError>`
//! - [`self::DisconnectSignal`] and [`self::DisconnectCause`]: observe one
//! response's lifetime through
//! [`Request::on_disconnect`](self::Request::on_disconnect) — it resolves
//! once, to the peer going away, this stream being reset, the server
//! shutting down, or the response finishing
//!
//! # Two Query Views
//!
//! [`Request::query`](self::Request::query) and
//! [`Request::query_all`](self::Request::query_all) look values up by decoded
//! key. [`Request::query_pairs`](self::Request::query_pairs) iterates every
//! decoded pair in the order the peer sent it, duplicates and blank keys
//! included. [`Request::raw_query`](self::Request::raw_query) returns the query
//! exactly as it arrived, without the leading `?`.
//!
//! A request target with no `?` has no raw query. One that ends in `?` has an
//! empty one. Both yield zero decoded pairs, so `raw_query` is what separates
//! them. An empty lookup name stays absent from `query` and `query_all` even
//! though `query_pairs` exposes blank keys.
//!
//! Decoding is permissive and never fails. A valid `%HH` escape decodes one
//! byte, `+` and `%20` both decode to a space, a malformed escape stays
//! literal, and invalid UTF-8 becomes the replacement character. No pair is
//! rejected or dropped. Read `raw_query` and apply your own policy when a
//! signature check or a strict decoder needs the accepted bytes.
//!
//! The URI owns the raw query, so `raw_query` borrows it and allocates nothing.
//! The first decoded accessor parses the whole query once into a cache the
//! request owns; every later call borrows from that one sequence.
//!
//! # HTTP Client
//!
//! For one-off calls, use the free functions like [`self::get`], [`self::post`],
//! [`self::put`], and [`self::delete`]. For custom timeouts or retries, start
//! with [`self::client`]:
//!
//! ```rust,no_run
//! use camber::RuntimeError;
//! use camber::http;
//! use std::time::Duration;
//!
//! async fn fetch() -> Result<(), RuntimeError> {
//! let client = http::client()
//! .connect_timeout(Duration::from_secs(5))
//! .read_timeout(Duration::from_secs(10))
//! .retries(3)
//! .backoff(Duration::from_millis(100));
//!
//! let response = client.get("https://example.com/health").await?;
//! let _status = response.status();
//! Ok(())
//! }
//! ```
//!
//! # Middleware and Handler Shape
//!
//! Handlers receive `&Request` and return an async block. Middleware receives
//! `&Request` and a [`self::Next`] handle.
//!
//! If you need request data after an `.await`, move owned values into the
//! future first instead of borrowing from `req` across the await boundary.
//!
//! # Related Modules
//!
//! - [`self::cors`]: CORS helpers
//! - [`self::compression`]: response compression helpers
//! - [`self::rate_limit`]: request rate limiting middleware
//! - [`self::validate`]: request validation middleware
//! - [`self::mock`]: HTTP client interception for tests
//! - `otel`: OpenTelemetry propagation and spans when the feature is enabled
/// Response compression helpers.
/// CORS middleware builders and helpers.
/// HTTP client mocking for tests.
/// OpenTelemetry request propagation and tracing hooks.
/// Rate limiting middleware.
/// Request validation middleware.
pub use proxy_forward;
pub use ;
pub use ;
pub use ;
pub use ;
pub use HostRouter;
pub use ;
pub use Next;
pub use ;
pub use ;
pub use ;
pub use GrpcRouter;
pub use Router;
pub use ;
pub use SseWriter;
pub use serve_file;
pub use ;
pub use ;
pub use ;
pub use ;