1pub use ::http::*;
4
5use core::{
6 borrow::{Borrow, BorrowMut},
7 convert::Infallible,
8 mem,
9 net::SocketAddr,
10 pin::Pin,
11 result::Result as StdResult,
12 str::FromStr,
13 task::{Context, Poll},
14};
15
16use pin_project_lite::pin_project;
17
18use crate::body::{Body, Frame, SizeHint};
19
20#[derive(Debug, Copy, Clone, PartialEq)]
22pub struct Protocol {
23 inner: _Protocol,
24}
25
26#[derive(Debug, Copy, Clone, PartialEq)]
27enum _Protocol {
28 WebSocket,
29 WebTransport,
30 ConnectIp,
31 ConnectUdp,
32 Unknown,
33}
34
35impl Protocol {
36 pub const WEB_SOCKET: Self = Self::new(_Protocol::WebSocket);
37 pub const WEB_TRANSPORT: Self = Self::new(_Protocol::WebTransport);
38 pub const CONNECT_IP: Self = Self::new(_Protocol::ConnectIp);
39 pub const CONNECT_UDP: Self = Self::new(_Protocol::ConnectUdp);
40
41 pub(crate) fn from_str(str: &str) -> Self {
42 let inner = match str {
43 "websocket" => _Protocol::WebSocket,
44 "webtransport" => _Protocol::WebTransport,
45 "connect-ip" => _Protocol::ConnectIp,
46 "connect-udp" => _Protocol::ConnectUdp,
47 _ => _Protocol::Unknown,
48 };
49
50 Self { inner }
51 }
52
53 pub fn as_str(&self) -> &'static str {
58 match self.inner {
59 _Protocol::WebSocket => "websocket",
60 _Protocol::WebTransport => "webtransport",
61 _Protocol::ConnectIp => "connect-ip",
62 _Protocol::ConnectUdp => "connect-udp",
63 _Protocol::Unknown => "",
64 }
65 }
66
67 const fn new(inner: _Protocol) -> Self {
68 Self { inner }
69 }
70}
71
72impl FromStr for Protocol {
73 type Err = Infallible;
74
75 fn from_str(s: &str) -> StdResult<Self, Self::Err> {
76 Ok(Self::from_str(s))
77 }
78}
79
80#[allow(clippy::declare_interior_mutable_const)]
82pub mod const_header_value {
83 use ::http::header::HeaderValue;
84
85 macro_rules! const_value {
86 ($(($ident: ident, $expr: expr)), *) => {
87 $(
88 pub const $ident: HeaderValue = HeaderValue::from_static($expr);
89 )*
90 }
91 }
92
93 const_value!(
94 (TEXT, "text/plain"),
95 (TEXT_UTF8, "text/plain; charset=utf-8"),
96 (JSON, "application/json"),
97 (APPLICATION_WWW_FORM_URLENCODED, "application/x-www-form-urlencoded"),
98 (TEXT_HTML_UTF8, "text/html; charset=utf-8"),
99 (GRPC, "application/grpc"),
100 (WEBSOCKET, "websocket")
101 );
102}
103
104#[allow(clippy::declare_interior_mutable_const)]
106pub mod const_header_name {
107 use ::http::header::HeaderName;
108
109 macro_rules! const_name {
110 ($(($ident: ident, $expr: expr)), *) => {
111 $(
112 pub const $ident: HeaderName = HeaderName::from_static($expr);
113 )*
114 }
115 }
116
117 const_name!(
118 (GRPC_STATUS, "grpc-status"),
119 (GRPC_MESSAGE, "grpc-message"),
120 (GRPC_ENCODING, "grpc-encoding"),
121 (GRPC_ACCEPT_ENCODING, "grpc-accept-encoding"),
122 (GRPC_TIMEOUT, "grpc-timeout")
123 );
124}
125
126pub trait IntoResponse<B, ResB> {
152 fn into_response(self, body: B) -> Response<ResB>;
153
154 fn as_response(&mut self, body: B) -> Response<ResB>
155 where
156 Self: Default,
157 {
158 mem::take(self).into_response(body)
159 }
160}
161
162impl<ReqB, B, ResB> IntoResponse<B, ResB> for Request<ReqB>
163where
164 B: Into<ResB>,
165{
166 fn into_response(self, body: B) -> Response<ResB> {
167 let (
168 request::Parts {
169 mut headers,
170 extensions,
171 version,
172 ..
173 },
174 _,
175 ) = self.into_parts();
176 headers.clear();
177
178 let mut res = Response::new(body.into());
179 *res.headers_mut() = headers;
180 *res.extensions_mut() = extensions;
181 *res.version_mut() = version;
182
183 res
184 }
185}
186
187#[cfg(feature = "router")]
188use super::util::service::router::Params;
189
190pin_project! {
191 #[derive(Debug)]
193 pub struct RequestExt<B> {
194 #[pin]
195 body: B,
196 ext: Extension,
200 }
201}
202
203impl<B> Clone for RequestExt<B>
204where
205 B: Clone,
206{
207 fn clone(&self) -> Self {
208 Self {
209 body: self.body.clone(),
210 ext: Extension(Box::new(_Extension::clone(&*self.ext.0))),
211 }
212 }
213}
214
215#[derive(Debug)]
218pub(crate) struct Extension(Box<_Extension>);
219
220impl Extension {
221 pub(crate) fn new(addr: SocketAddr) -> Self {
222 Self::with_protocol(addr, None)
223 }
224
225 pub(crate) fn with_protocol(addr: SocketAddr, protocol: Option<Protocol>) -> Self {
226 Self(Box::new(_Extension {
227 addr,
228 protocol,
229 #[cfg(feature = "router")]
230 params: Default::default(),
231 }))
232 }
233}
234
235#[derive(Clone, Debug)]
236struct _Extension {
237 addr: SocketAddr,
238 protocol: Option<Protocol>,
239 #[cfg(feature = "router")]
240 params: Params,
241}
242
243impl<B> RequestExt<B> {
244 pub(crate) fn from_parts(body: B, ext: Extension) -> Self {
245 Self { body, ext }
246 }
247
248 #[inline]
253 pub fn socket_addr(&self) -> &SocketAddr {
254 &self.ext.0.addr
255 }
256
257 #[inline]
259 pub fn socket_addr_mut(&mut self) -> &mut SocketAddr {
260 &mut self.ext.0.addr
261 }
262
263 pub fn protocol(&self) -> Option<Protocol> {
264 self.ext.0.protocol
265 }
266
267 #[inline]
269 pub fn map_body<F, B1>(self, func: F) -> RequestExt<B1>
270 where
271 F: FnOnce(B) -> B1,
272 {
273 RequestExt {
274 body: func(self.body),
275 ext: self.ext,
276 }
277 }
278
279 #[inline]
282 pub fn replace_body<B1>(self, body: B1) -> (RequestExt<B1>, B) {
283 let body_org = self.body;
284
285 (RequestExt { body, ext: self.ext }, body_org)
286 }
287}
288
289impl<B> Default for RequestExt<B>
290where
291 B: Default,
292{
293 fn default() -> Self {
294 Self::from_parts(B::default(), Extension::new(crate::unspecified_socket_addr()))
295 }
296}
297
298impl<B> Body for RequestExt<B>
299where
300 B: Body,
301{
302 type Data = B::Data;
303 type Error = B::Error;
304
305 #[inline]
306 fn poll_frame(
307 self: Pin<&mut Self>,
308 cx: &mut Context<'_>,
309 ) -> Poll<Option<StdResult<Frame<Self::Data>, Self::Error>>> {
310 self.project().body.poll_frame(cx)
311 }
312
313 #[inline]
314 fn is_end_stream(&self) -> bool {
315 self.body.is_end_stream()
316 }
317
318 #[inline]
319 fn size_hint(&self) -> SizeHint {
320 self.body.size_hint()
321 }
322}
323
324impl<B> Borrow<SocketAddr> for RequestExt<B> {
325 #[inline]
326 fn borrow(&self) -> &SocketAddr {
327 self.socket_addr()
328 }
329}
330
331#[cfg(feature = "router")]
332mod router {
333 use super::*;
334
335 impl<B> RequestExt<B> {
336 #[inline]
338 pub fn params(&self) -> &Params {
339 &self.ext.0.params
340 }
341
342 #[inline]
344 pub fn params_mut(&mut self) -> &mut Params {
345 &mut self.ext.0.params
346 }
347 }
348
349 impl<B> Borrow<Params> for RequestExt<B> {
350 #[inline]
351 fn borrow(&self) -> &Params {
352 self.params()
353 }
354 }
355
356 impl<B> BorrowMut<Params> for RequestExt<B> {
357 #[inline]
358 fn borrow_mut(&mut self) -> &mut Params {
359 self.params_mut()
360 }
361 }
362}
363
364pub trait BorrowReq<T> {
367 fn borrow(&self) -> &T;
368}
369
370pub trait BorrowReqMut<T> {
373 fn borrow_mut(&mut self) -> &mut T;
374}
375
376impl<Ext> BorrowReq<Uri> for Request<Ext> {
377 #[inline]
378 fn borrow(&self) -> &Uri {
379 self.uri()
380 }
381}
382
383impl<Ext> BorrowReq<Method> for Request<Ext> {
384 #[inline]
385 fn borrow(&self) -> &Method {
386 self.method()
387 }
388}
389
390impl<Ext> BorrowReq<HeaderMap> for Request<Ext> {
391 #[inline]
392 fn borrow(&self) -> &HeaderMap {
393 self.headers()
394 }
395}
396
397impl<Ext> BorrowReq<Extensions> for Request<Ext> {
398 #[inline]
399 fn borrow(&self) -> &Extensions {
400 self.extensions()
401 }
402}
403
404impl<Ext> BorrowReqMut<Extensions> for Request<Ext> {
405 #[inline]
406 fn borrow_mut(&mut self) -> &mut Extensions {
407 self.extensions_mut()
408 }
409}
410
411impl<T, B> BorrowReq<T> for Request<RequestExt<B>>
412where
413 RequestExt<B>: Borrow<T>,
414{
415 #[inline]
416 fn borrow(&self) -> &T {
417 self.body().borrow()
418 }
419}
420
421impl<T, B> BorrowReqMut<T> for Request<RequestExt<B>>
422where
423 RequestExt<B>: BorrowMut<T>,
424{
425 #[inline]
426 fn borrow_mut(&mut self) -> &mut T {
427 self.body_mut().borrow_mut()
428 }
429}