rocket/local/asynchronous/
request.rs
1use std::fmt;
2
3use crate::{Request, Data};
4use crate::http::{Status, Method};
5use crate::http::uri::Origin;
6
7use super::{Client, LocalResponse};
8
9pub struct LocalRequest<'c> {
34 pub(in super) client: &'c Client,
35 pub(in super) request: Request<'c>,
36 data: Vec<u8>,
37 uri: Result<Origin<'c>, Origin<'static>>,
39}
40
41impl<'c> LocalRequest<'c> {
42 pub(crate) fn new<'u: 'c, U>(client: &'c Client, method: Method, uri: U) -> Self
43 where U: TryInto<Origin<'u>> + fmt::Display
44 {
45 let uri_str = uri.to_string();
47 let try_origin = uri.try_into().map_err(|_| Origin::path_only(uri_str));
48
49 let origin = try_origin.clone().unwrap_or_else(|bad| bad);
51 let mut request = Request::new(client.rocket(), method, origin);
52
53 if client.tracked {
55 client._with_raw_cookies(|jar| {
56 for cookie in jar.iter() {
57 request.cookies_mut().add_original(cookie.clone());
58 }
59 })
60 }
61
62 LocalRequest { client, request, uri: try_origin, data: vec![] }
63 }
64
65 pub(crate) fn _request(&self) -> &Request<'c> {
66 &self.request
67 }
68
69 pub(crate) fn _request_mut(&mut self) -> &mut Request<'c> {
70 &mut self.request
71 }
72
73 pub(crate) fn _body_mut(&mut self) -> &mut Vec<u8> {
74 &mut self.data
75 }
76
77 async fn _dispatch(mut self) -> LocalResponse<'c> {
79 let rocket = self.client.rocket();
83 if let Err(ref invalid) = self.uri {
84 if self.inner().uri() == invalid {
87 error!("invalid request URI: {:?}", invalid.path());
88 return LocalResponse::new(self.request, move |req| {
89 rocket.handle_error(Status::BadRequest, req)
90 }).await
91 }
92 }
93
94 let mut data = Data::local(self.data);
96 let token = rocket.preprocess_request(&mut self.request, &mut data).await;
97 let response = LocalResponse::new(self.request, move |req| {
98 rocket.dispatch(token, req, data)
99 }).await;
100
101 if self.client.tracked {
104 self.client._with_raw_cookies_mut(|jar| {
105 let current_time = time::OffsetDateTime::now_utc();
106 for cookie in response.cookies().iter() {
107 if let Some(expires) = cookie.expires_datetime() {
108 if expires <= current_time {
109 jar.force_remove(cookie.name());
110 continue;
111 }
112 }
113
114 jar.add_original(cookie.clone());
115 }
116 })
117 }
118
119 response
120 }
121
122 pub_request_impl!("# use rocket::local::asynchronous::Client;\n\
123 use rocket::local::asynchronous::LocalRequest;" async await);
124}
125
126impl<'c> Clone for LocalRequest<'c> {
127 fn clone(&self) -> Self {
128 LocalRequest {
129 client: self.client,
130 request: self.request.clone(),
131 data: self.data.clone(),
132 uri: self.uri.clone(),
133 }
134 }
135}
136
137impl std::fmt::Debug for LocalRequest<'_> {
138 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
139 self._request().fmt(f)
140 }
141}
142
143impl<'c> std::ops::Deref for LocalRequest<'c> {
144 type Target = Request<'c>;
145
146 fn deref(&self) -> &Self::Target {
147 self.inner()
148 }
149}
150
151impl<'c> std::ops::DerefMut for LocalRequest<'c> {
152 fn deref_mut(&mut self) -> &mut Self::Target {
153 self.inner_mut()
154 }
155}