hyper_simple_server/
extensions.rs1
2
3use crate::prelude::*;
4
5
6
7
8#[ cfg (feature = "hss-extensions") ]
9pub trait RequestExt <B>
10 where
11 B : BodyTrait,
12{
13 fn is_get (&self) -> bool;
14 fn is_head (&self) -> bool;
15 fn is_put (&self) -> bool;
16 fn is_post (&self) -> bool;
17 fn is_delete (&self) -> bool;
18 fn is_patch (&self) -> bool;
19 fn is_options (&self) -> bool;
20
21 fn uri_path (&self) -> &str;
22 fn uri_query (&self) -> Option<&str>;
23
24 fn header (&self, _name : impl AsHeaderName) -> Option<&HeaderValue>;
25 fn header_all (&self, _name : impl AsHeaderName) -> http::header::GetAll<'_, HeaderValue>;
26
27 fn header_str (&self, _name : impl AsHeaderName) -> Option<&str> {
28 self.header (_name) .and_then (|_value| _value.to_str () .ok ())
29 }
30
31 fn header_host (&self) -> Option<&str> {
32 self.header_str (consts::HOST)
33 }
34}
35
36
37#[ cfg (feature = "hss-extensions") ]
38impl <B> RequestExt<B> for Request<B>
39 where
40 B : BodyTrait,
41{
42 fn is_get (&self) -> bool {
43 self.method () == Method::GET
44 }
45 fn is_head (&self) -> bool {
46 self.method () == Method::HEAD
47 }
48 fn is_put (&self) -> bool {
49 self.method () == Method::PUT
50 }
51 fn is_post (&self) -> bool {
52 self.method () == Method::POST
53 }
54 fn is_delete (&self) -> bool {
55 self.method () == Method::DELETE
56 }
57 fn is_patch (&self) -> bool {
58 self.method () == Method::PATCH
59 }
60 fn is_options (&self) -> bool {
61 self.method () == Method::OPTIONS
62 }
63
64 fn uri_path (&self) -> &str {
65 self.uri () .path ()
66 }
67
68 fn uri_query (&self) -> Option<&str> {
69 self.uri () .query ()
70 }
71
72 fn header (&self, _name : impl AsHeaderName) -> Option<&HeaderValue> {
73 self.headers () .get (_name)
74 }
75
76 fn header_all (&self, _name : impl AsHeaderName) -> http::header::GetAll<'_, HeaderValue> {
77 self.headers () .get_all (_name)
78 }
79}
80
81
82
83
84#[ cfg (feature = "hss-extensions") ]
85pub trait ResponseExt <B>
86 where
87 B : BodyTrait,
88{
89 fn status (&self) -> StatusCode;
90 fn set_status (&mut self, _status : StatusCode) -> &mut Self;
91
92 fn get_header (&self, _name : impl AsHeaderName) -> Option<&HeaderValue>;
93 fn set_header (&mut self, _name : impl IntoHeaderName, _value : impl Into<HeaderValue>) -> &mut Self;
94 fn add_header (&mut self, _name : impl IntoHeaderName, _value : impl Into<HeaderValue>) -> &mut Self;
95
96 fn set_body (&mut self, _body : impl Into<B>) -> &mut Self;
97
98 fn set_status_200 (&mut self) -> &mut Self {
99 self.set_status (consts::OK)
100 }
101
102 fn set_content_type (&mut self, _content_type : impl Into<HeaderValue>) -> &mut Self {
103 self.set_header (consts::CONTENT_TYPE, _content_type)
104 }
105
106 fn set_header_str_static (&mut self, _name : impl IntoHeaderName, _value : &'static str) -> &mut Self {
107 self.set_header (_name, HeaderValue::from_static (_value))
108 }
109
110 fn set_header_string (&mut self, _name : impl IntoHeaderName, _value : String) -> &mut Self {
111 self.set_header (_name, HeaderValue::try_from (_value) .or_panic (0x627a7cff))
112 }
113
114 fn add_header_str_static (&mut self, _name : impl IntoHeaderName, _value : &'static str) -> &mut Self {
115 self.add_header (_name, HeaderValue::from_static (_value))
116 }
117
118 fn add_header_string (&mut self, _name : impl IntoHeaderName, _value : String) -> &mut Self {
119 self.add_header (_name, HeaderValue::try_from (_value) .or_panic (0x1ac00c46))
120 }
121
122 fn content_type (&self) -> Option<ContentType> {
123 if let Some (_content_type) = self.get_header (consts::CONTENT_TYPE) {
124 if let Ok (_content_type) = _content_type.to_str () {
125 ContentType::from_str (_content_type)
126 } else {
127 None
128 }
129 } else {
130 None
131 }
132 }
133
134 fn content_type_or_unknown (&self) -> ContentType {
135 self.content_type () .unwrap_or (ContentType::Unknown)
136 }
137}
138
139
140#[ cfg (feature = "hss-extensions") ]
141impl <B> ResponseExt<B> for Response<B>
142 where
143 B : BodyTrait,
144{
145 fn status (&self) -> StatusCode {
146 self.status ()
147 }
148
149 fn set_status (&mut self, _status : StatusCode) -> &mut Self {
150 *self.status_mut () = _status;
151 self
152 }
153
154 fn get_header (&self, _name : impl AsHeaderName) -> Option<&HeaderValue> {
155 self.headers () .get (_name)
156 }
157
158 fn set_header (&mut self, _name : impl IntoHeaderName, _value : impl Into<HeaderValue>) -> &mut Self {
159 self.headers_mut () .insert (_name, _value.into ());
160 self
161 }
162
163 fn add_header (&mut self, _name : impl IntoHeaderName, _value : impl Into<HeaderValue>) -> &mut Self {
164 self.headers_mut () .append (_name, _value.into ());
165 self
166 }
167
168 fn set_body (&mut self, _body : impl Into<B>) -> &mut Self {
169 *self.body_mut () = _body.into ();
170 self
171 }
172}
173
174
175
176
177#[ cfg (feature = "hss-extensions") ]
178pub trait ResponseExtBuild <B>
179 where
180 B : BodyTrait,
181 Self : Sized,
182 Self : ResponseExt<B>,
183{
184 fn new_with_status_and_body (_status : StatusCode, _body : impl Into<B>, _content_type : Option<impl Into<HeaderValue>>) -> Self;
185
186 fn new_empty () -> Self where B : Default {
187 let _content_type : Option<ContentType> = None;
188 Self::new_with_status_and_body (consts::OK, B::default (), _content_type)
189 }
190
191 fn new_with_status (_status : StatusCode) -> Self where B : Default {
192 let _content_type : Option<ContentType> = None;
193 Self::new_with_status_and_body (_status, B::default (), _content_type)
194 }
195
196 fn new_201 () -> Self where B : Default {
197 Self::new_with_status (consts::CREATED)
198 }
199
200 fn new_200_with_body (_body : impl Into<B>, _content_type : Option<impl Into<HeaderValue>>) -> Self {
201 Self::new_with_status_and_body (consts::OK, _body, _content_type)
202 }
203
204 fn new_200_with_text (_body : impl Into<B>) -> Self {
205 Self::new_200_with_body (_body, Some (ContentType::Text))
206 }
207
208 fn new_200_with_html (_body : impl Into<B>) -> Self {
209 Self::new_200_with_body (_body, Some (ContentType::Html))
210 }
211
212 fn new_200 () -> Self where B : From<&'static str> {
213 Self::new_with_status_and_body (consts::OK, "OK\n", Some (ContentType::Text))
214 }
215
216 fn new_301 (_location : impl Into<HeaderValue>) -> Self where B : Default {
217 Self::new_redirect_with_code (consts::MOVED_PERMANENTLY, _location)
218 }
219
220 fn new_302 (_location : impl Into<HeaderValue>) -> Self where B : Default {
221 Self::new_redirect_with_code (consts::FOUND, _location)
222 }
223
224 fn new_303 (_location : impl Into<HeaderValue>) -> Self where B : Default {
225 Self::new_redirect_with_code (consts::SEE_OTHER, _location)
226 }
227
228 fn new_307 (_location : impl Into<HeaderValue>) -> Self where B : Default {
229 Self::new_redirect_with_code (consts::TEMPORARY_REDIRECT, _location)
230 }
231
232 fn new_308 (_location : impl Into<HeaderValue>) -> Self where B : Default {
233 Self::new_redirect_with_code (consts::PERMANENT_REDIRECT, _location)
234 }
235
236 fn new_301_str_static (_location : &'static str) -> Self where B : Default {
237 Self::new_301 (HeaderValue::from_static (_location))
238 }
239
240 fn new_302_str_static (_location : &'static str) -> Self where B : Default {
241 Self::new_302 (HeaderValue::from_static (_location))
242 }
243
244 fn new_303_str_static (_location : &'static str) -> Self where B : Default {
245 Self::new_303 (HeaderValue::from_static (_location))
246 }
247
248 fn new_307_str_static (_location : &'static str) -> Self where B : Default {
249 Self::new_307 (HeaderValue::from_static (_location))
250 }
251
252 fn new_308_str_static (_location : &'static str) -> Self where B : Default {
253 Self::new_308 (HeaderValue::from_static (_location))
254 }
255
256 fn new_301_string (_location : String) -> Self where B : Default {
257 Self::new_301 (HeaderValue::try_from (_location) .or_panic (0x15f9b93c))
258 }
259
260 fn new_302_string (_location : String) -> Self where B : Default {
261 Self::new_302 (HeaderValue::try_from (_location) .or_panic (0x0a94e02d))
262 }
263
264 fn new_303_string (_location : String) -> Self where B : Default {
265 Self::new_303 (HeaderValue::try_from (_location) .or_panic (0xa87f95a7))
266 }
267
268 fn new_307_string (_location : String) -> Self where B : Default {
269 Self::new_307 (HeaderValue::try_from (_location) .or_panic (0xd0e3f0f9))
270 }
271
272 fn new_308_string (_location : String) -> Self where B : Default {
273 Self::new_308 (HeaderValue::try_from (_location) .or_panic (0x69839071))
274 }
275
276 fn new_redirect_with_code (_status : StatusCode, _location : impl Into<HeaderValue>) -> Self where B : Default {
277 let mut _response = Self::new_with_status (_status);
278 _response.set_header (consts::LOCATION, _location);
279 _response
280 }
281
282 fn new_404 () -> Self where B : From<&'static str> {
283 Self::new_with_status_and_body (consts::NOT_FOUND, "404\n", Some (ContentType::Text))
284 }
285
286 fn new_method_not_allowed () -> Self where B : From<&'static str> {
287 Self::new_with_status_and_body (consts::METHOD_NOT_ALLOWED, "method-not-allowed\n", Some (ContentType::Text))
288 }
289
290 fn ok <E> (self) -> Result<Self, E> {
291 Ok (self)
292 }
293
294 fn ok_0 (self) -> Result<Self, ServerError> {
295 Ok (self)
296 }
297
298 fn ready <E> (self) -> future::Ready<Result<Self, E>> {
299 future::ready (Ok (self))
300 }
301
302 fn ready_0 (self) -> future::Ready<Result<Self, ServerError>> {
303 future::ready (Ok (self))
304 }
305}
306
307
308#[ cfg (feature = "hss-extensions") ]
309impl ResponseExtBuild<Body> for Response<Body> {
310
311 fn new_with_status_and_body (_status : StatusCode, _body : impl Into<Body>, _content_type : Option<impl Into<HeaderValue>>) -> Self {
312 let mut _response = Response::new (_body.into ());
313 _response.set_status (_status);
314 if let Some (_content_type) = _content_type {
315 _response.set_content_type (_content_type);
316 }
317 _response
318 }
319}
320
321
322
323
324#[ cfg (feature = "hss-extensions") ]
325#[ cfg (feature = "tokio--rt") ]
326pub trait BodyExt {
327
328 fn consume_into_vec (&mut self, _buffer : &mut Vec<u8>, _runtime : Option<&Runtime>) -> ServerResult;
329
330 fn consume_to_vec (&mut self, _runtime : Option<&Runtime>) -> ServerResult<Vec<u8>> {
331 let mut _buffer = Vec::new ();
332 self.consume_into_vec (&mut _buffer, _runtime) ?;
333 Ok (_buffer)
334 }
335}
336
337
338#[ cfg (feature = "hss-extensions") ]
339#[ cfg (feature = "tokio--rt") ]
340impl <B> BodyExt for B
341 where
342 B : BodyTrait<Data = Bytes> + Send + Sync + 'static + Unpin,
343 B::Error : Error + Send + Sync + 'static,
344{
345 fn consume_into_vec (&mut self, _buffer : &mut Vec<u8>, _runtime : Option<&Runtime>) -> ServerResult {
346
347 _buffer.reserve (BodyTrait::size_hint (self) .lower () as usize);
348
349 let _runtime_0 = if _runtime.is_none () {
350 Some (tokio::RuntimeBuilder::new_current_thread () .build () .or_wrap (0x6d0d289e) ?)
351 } else {
352 None
353 };
354
355 let _runtime = _runtime.or (_runtime_0.as_ref ()) .infallible (0x022bb6d6);
356
357 loop {
358 let _next = _runtime.block_on (self.data ());
359 let _next = if let Some (_next) = _next {
360 _next
361 } else {
362 break;
363 };
364 let mut _data = _next.or_wrap (0x401ac565) ?;
365 while _data.remaining () > 0 {
366 let _chunk = _data.chunk ();
367 _buffer.extend (_chunk);
368 let _chunk_size = _chunk.len ();
369 _data.advance (_chunk_size);
370 }
371 }
372
373 Ok (())
374 }
375}
376