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
use fmt;
use Future;
use Pin;
use ;
use ;
use ;
use BoxBody;
use ;
use crateServeError;
use crateState;
/// An error that can occur while streaming a response body.
///
/// This error type wraps any error that might occur during the actual transmission
/// of the response body to the client (e.g., I/O errors from a file being streamed).
/// If the body stream yields an error after headers have already been sent to the client,
/// that error will cause the connection to be aborted — it cannot be converted back to
/// an HTTP error response.
/// The response body type used by all handlers.
///
/// The error type is `BodyError`, which can represent errors that occur during body
/// streaming (e.g., disk I/O failures while reading a large file). These errors will
/// abort the connection rather than being converted to an HTTP error response.
pub type ResponseBody = ;
/// Create a response body from raw bytes.
///
/// Since the bytes come from an infallible source (an in-memory `Full`), the body
/// stream can never actually fail. The error type is converted from `Infallible` to
/// `BodyError` to satisfy the `ResponseBody` type.
/// The upgraded connection handed to an [`OnUpgrade`] callback.
///
/// Wrapped so it implements tokio's `AsyncRead`/`AsyncWrite`, which is what a protocol
/// crate wants; the raw `hyper::upgrade::Upgraded` is reachable through it if needed.
pub type UpgradedIo = TokioIo;
/// Take over a connection once the response has been written.
///
/// Attach one to a `101 Switching Protocols` response and the server hands you the raw
/// stream after the response goes out. Everything past that point speaks whatever protocol
/// you like — this crate stops interpreting the bytes.
///
/// The callback runs **inside the connection's own task**, which is deliberate and is the
/// reason this type exists rather than callers using `hyper::upgrade::on` directly. That
/// task holds the connection's semaphore permit and is the one shutdown aborts, so an
/// upgraded connection still counts against [`RouteBuilder::with_max_connections`] and is
/// still ended by the shutdown drain. Servicing the stream from a detached `tokio::spawn`
/// — the usual hyper pattern — escapes both.
///
/// Requires [`RouteBuilder::with_upgrades`]; without it the response is sent and the
/// callback never runs.
///
/// ```no_run
/// # use hyper::{Response, StatusCode};
/// # use mini_serve::{OnUpgrade, ResponseBody, ServeError};
/// # fn example() -> Result<Response<ResponseBody>, ServeError> {
/// let mut response = Response::builder()
/// .status(StatusCode::SWITCHING_PROTOCOLS)
/// .body(mini_serve::body(hyper::body::Bytes::new()))
/// .unwrap();
/// response.extensions_mut().insert(OnUpgrade::new(|_io| async move {
/// // speak your protocol here
/// }));
/// Ok(response)
/// # }
/// ```
///
/// The callback is held behind `Arc<Mutex<Option<..>>>` rather than directly, because
/// `http::Extensions` requires `Clone + Send + Sync` and a `FnOnce` is none of those. The
/// `Option` is what makes it callable once: the connection takes it, leaving `None`.
/// The boxed callback inside an [`OnUpgrade`]. Named because the nested type is otherwise
/// unreadable at every use site.
type UpgradeCallback =
;
;
/// A request handler that processes an HTTP request and returns a response or error.
///
/// Handlers receive the full request (method, path, headers, body) and the app state,
/// and return either a response or a `ServeError` (which is converted to an HTTP error response).
pub type Handler<S> = ;
/// Wrap an async function to create a handler.
///
/// # Example
///
/// ```ignore
/// use mini_serve::handler;
/// use hyper::StatusCode;
/// use hyper::body::Bytes;
///
/// let h = handler(|req, state| async move {
/// Ok::<_, mini_serve::ServeError>(
/// mini_serve::json(StatusCode::OK, &serde_json::json!({"status": "ok"}))
/// )
/// });
/// ```
/// A middleware transforms a `Handler` into a new `Handler`, typically by
/// running logic before and/or after calling the inner handler — or by
/// short-circuiting and never calling it at all (e.g. to block a request).
///
/// Registered on a [`crate::RouteBuilder`] via `.wrap()`, and applied to every
/// route registered after that call.
pub type Middleware<S> = ;