1 //! Http response
2 use std::cell::{Ref, RefMut};
3 use std::convert::TryFrom;
4 use std::future::Future;
5 use std::pin::Pin;
6 use std::task::{Context, Poll};
7 use std::{fmt, str};
8 
9 use bytes::{Bytes, BytesMut};
10 use futures_core::Stream;
11 use serde::Serialize;
12 use serde_json;
13 
14 use crate::body::{Body, BodyStream, MessageBody, ResponseBody};
15 use crate::cookie::{Cookie, CookieJar};
16 use crate::error::Error;
17 use crate::extensions::Extensions;
18 use crate::header::{Header, IntoHeaderValue};
19 use crate::http::header::{self, HeaderName, HeaderValue};
20 use crate::http::{Error as HttpError, HeaderMap, StatusCode};
21 use crate::message::{BoxedResponseHead, ConnectionType, ResponseHead};
22 
23 /// An HTTP Response
24 pub struct Response<B = Body> {
25     head: BoxedResponseHead,
26     body: ResponseBody<B>,
27     error: Option<Error>,
28 }
29 
30 impl Response<Body> {
31     /// Create http response builder with specific status.
32     #[inline]
build(status: StatusCode) -> ResponseBuilder33     pub fn build(status: StatusCode) -> ResponseBuilder {
34         ResponseBuilder::new(status)
35     }
36 
37     /// Create http response builder
38     #[inline]
build_from<T: Into<ResponseBuilder>>(source: T) -> ResponseBuilder39     pub fn build_from<T: Into<ResponseBuilder>>(source: T) -> ResponseBuilder {
40         source.into()
41     }
42 
43     /// Constructs a response
44     #[inline]
new(status: StatusCode) -> Response45     pub fn new(status: StatusCode) -> Response {
46         Response {
47             head: BoxedResponseHead::new(status),
48             body: ResponseBody::Body(Body::Empty),
49             error: None,
50         }
51     }
52 
53     /// Constructs an error response
54     #[inline]
from_error(error: Error) -> Response55     pub fn from_error(error: Error) -> Response {
56         let mut resp = error.as_response_error().error_response();
57         if resp.head.status == StatusCode::INTERNAL_SERVER_ERROR {
58             error!("Internal Server Error: {:?}", error);
59         }
60         resp.error = Some(error);
61         resp
62     }
63 
64     /// Convert response to response with body
into_body<B>(self) -> Response<B>65     pub fn into_body<B>(self) -> Response<B> {
66         let b = match self.body {
67             ResponseBody::Body(b) => b,
68             ResponseBody::Other(b) => b,
69         };
70         Response {
71             head: self.head,
72             error: self.error,
73             body: ResponseBody::Other(b),
74         }
75     }
76 }
77 
78 impl<B> Response<B> {
79     /// Constructs a response with body
80     #[inline]
with_body(status: StatusCode, body: B) -> Response<B>81     pub fn with_body(status: StatusCode, body: B) -> Response<B> {
82         Response {
83             head: BoxedResponseHead::new(status),
84             body: ResponseBody::Body(body),
85             error: None,
86         }
87     }
88 
89     #[inline]
90     /// Http message part of the response
head(&self) -> &ResponseHead91     pub fn head(&self) -> &ResponseHead {
92         &*self.head
93     }
94 
95     #[inline]
96     /// Mutable reference to a http message part of the response
head_mut(&mut self) -> &mut ResponseHead97     pub fn head_mut(&mut self) -> &mut ResponseHead {
98         &mut *self.head
99     }
100 
101     /// The source `error` for this response
102     #[inline]
error(&self) -> Option<&Error>103     pub fn error(&self) -> Option<&Error> {
104         self.error.as_ref()
105     }
106 
107     /// Get the response status code
108     #[inline]
status(&self) -> StatusCode109     pub fn status(&self) -> StatusCode {
110         self.head.status
111     }
112 
113     /// Set the `StatusCode` for this response
114     #[inline]
status_mut(&mut self) -> &mut StatusCode115     pub fn status_mut(&mut self) -> &mut StatusCode {
116         &mut self.head.status
117     }
118 
119     /// Get the headers from the response
120     #[inline]
headers(&self) -> &HeaderMap121     pub fn headers(&self) -> &HeaderMap {
122         &self.head.headers
123     }
124 
125     /// Get a mutable reference to the headers
126     #[inline]
headers_mut(&mut self) -> &mut HeaderMap127     pub fn headers_mut(&mut self) -> &mut HeaderMap {
128         &mut self.head.headers
129     }
130 
131     /// Get an iterator for the cookies set by this response
132     #[inline]
cookies(&self) -> CookieIter<'_>133     pub fn cookies(&self) -> CookieIter<'_> {
134         CookieIter {
135             iter: self.head.headers.get_all(header::SET_COOKIE),
136         }
137     }
138 
139     /// Add a cookie to this response
140     #[inline]
add_cookie(&mut self, cookie: &Cookie<'_>) -> Result<(), HttpError>141     pub fn add_cookie(&mut self, cookie: &Cookie<'_>) -> Result<(), HttpError> {
142         let h = &mut self.head.headers;
143         HeaderValue::from_str(&cookie.to_string())
144             .map(|c| {
145                 h.append(header::SET_COOKIE, c);
146             })
147             .map_err(|e| e.into())
148     }
149 
150     /// Remove all cookies with the given name from this response. Returns
151     /// the number of cookies removed.
152     #[inline]
del_cookie(&mut self, name: &str) -> usize153     pub fn del_cookie(&mut self, name: &str) -> usize {
154         let h = &mut self.head.headers;
155         let vals: Vec<HeaderValue> = h
156             .get_all(header::SET_COOKIE)
157             .map(|v| v.to_owned())
158             .collect();
159         h.remove(header::SET_COOKIE);
160 
161         let mut count: usize = 0;
162         for v in vals {
163             if let Ok(s) = v.to_str() {
164                 if let Ok(c) = Cookie::parse_encoded(s) {
165                     if c.name() == name {
166                         count += 1;
167                         continue;
168                     }
169                 }
170             }
171             h.append(header::SET_COOKIE, v);
172         }
173         count
174     }
175 
176     /// Connection upgrade status
177     #[inline]
upgrade(&self) -> bool178     pub fn upgrade(&self) -> bool {
179         self.head.upgrade()
180     }
181 
182     /// Keep-alive status for this connection
keep_alive(&self) -> bool183     pub fn keep_alive(&self) -> bool {
184         self.head.keep_alive()
185     }
186 
187     /// Responses extensions
188     #[inline]
extensions(&self) -> Ref<'_, Extensions>189     pub fn extensions(&self) -> Ref<'_, Extensions> {
190         self.head.extensions.borrow()
191     }
192 
193     /// Mutable reference to a the response's extensions
194     #[inline]
extensions_mut(&mut self) -> RefMut<'_, Extensions>195     pub fn extensions_mut(&mut self) -> RefMut<'_, Extensions> {
196         self.head.extensions.borrow_mut()
197     }
198 
199     /// Get body of this response
200     #[inline]
body(&self) -> &ResponseBody<B>201     pub fn body(&self) -> &ResponseBody<B> {
202         &self.body
203     }
204 
205     /// Set a body
set_body<B2>(self, body: B2) -> Response<B2>206     pub fn set_body<B2>(self, body: B2) -> Response<B2> {
207         Response {
208             head: self.head,
209             body: ResponseBody::Body(body),
210             error: None,
211         }
212     }
213 
214     /// Split response and body
into_parts(self) -> (Response<()>, ResponseBody<B>)215     pub fn into_parts(self) -> (Response<()>, ResponseBody<B>) {
216         (
217             Response {
218                 head: self.head,
219                 body: ResponseBody::Body(()),
220                 error: self.error,
221             },
222             self.body,
223         )
224     }
225 
226     /// Drop request's body
drop_body(self) -> Response<()>227     pub fn drop_body(self) -> Response<()> {
228         Response {
229             head: self.head,
230             body: ResponseBody::Body(()),
231             error: None,
232         }
233     }
234 
235     /// Set a body and return previous body value
replace_body<B2>(self, body: B2) -> (Response<B2>, ResponseBody<B>)236     pub(crate) fn replace_body<B2>(self, body: B2) -> (Response<B2>, ResponseBody<B>) {
237         (
238             Response {
239                 head: self.head,
240                 body: ResponseBody::Body(body),
241                 error: self.error,
242             },
243             self.body,
244         )
245     }
246 
247     /// Set a body and return previous body value
map_body<F, B2>(mut self, f: F) -> Response<B2> where F: FnOnce(&mut ResponseHead, ResponseBody<B>) -> ResponseBody<B2>,248     pub fn map_body<F, B2>(mut self, f: F) -> Response<B2>
249     where
250         F: FnOnce(&mut ResponseHead, ResponseBody<B>) -> ResponseBody<B2>,
251     {
252         let body = f(&mut self.head, self.body);
253 
254         Response {
255             body,
256             head: self.head,
257             error: self.error,
258         }
259     }
260 
261     /// Extract response body
take_body(&mut self) -> ResponseBody<B>262     pub fn take_body(&mut self) -> ResponseBody<B> {
263         self.body.take_body()
264     }
265 }
266 
267 impl<B: MessageBody> fmt::Debug for Response<B> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result268     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
269         let res = writeln!(
270             f,
271             "\nResponse {:?} {}{}",
272             self.head.version,
273             self.head.status,
274             self.head.reason.unwrap_or(""),
275         );
276         let _ = writeln!(f, "  headers:");
277         for (key, val) in self.head.headers.iter() {
278             let _ = writeln!(f, "    {:?}: {:?}", key, val);
279         }
280         let _ = writeln!(f, "  body: {:?}", self.body.size());
281         res
282     }
283 }
284 
285 impl Future for Response {
286     type Output = Result<Response, Error>;
287 
poll(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output>288     fn poll(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> {
289         Poll::Ready(Ok(Response {
290             head: self.head.take(),
291             body: self.body.take_body(),
292             error: self.error.take(),
293         }))
294     }
295 }
296 
297 pub struct CookieIter<'a> {
298     iter: header::GetAll<'a>,
299 }
300 
301 impl<'a> Iterator for CookieIter<'a> {
302     type Item = Cookie<'a>;
303 
304     #[inline]
next(&mut self) -> Option<Cookie<'a>>305     fn next(&mut self) -> Option<Cookie<'a>> {
306         for v in self.iter.by_ref() {
307             if let Ok(c) = Cookie::parse_encoded(v.to_str().ok()?) {
308                 return Some(c);
309             }
310         }
311         None
312     }
313 }
314 
315 /// An HTTP response builder
316 ///
317 /// This type can be used to construct an instance of `Response` through a
318 /// builder-like pattern.
319 pub struct ResponseBuilder {
320     head: Option<BoxedResponseHead>,
321     err: Option<HttpError>,
322     cookies: Option<CookieJar>,
323 }
324 
325 impl ResponseBuilder {
326     #[inline]
327     /// Create response builder
new(status: StatusCode) -> Self328     pub fn new(status: StatusCode) -> Self {
329         ResponseBuilder {
330             head: Some(BoxedResponseHead::new(status)),
331             err: None,
332             cookies: None,
333         }
334     }
335 
336     /// Set HTTP status code of this response.
337     #[inline]
status(&mut self, status: StatusCode) -> &mut Self338     pub fn status(&mut self, status: StatusCode) -> &mut Self {
339         if let Some(parts) = parts(&mut self.head, &self.err) {
340             parts.status = status;
341         }
342         self
343     }
344 
345     /// Set a header.
346     ///
347     /// ```rust
348     /// use actix_http::{http, Request, Response, Result};
349     ///
350     /// fn index(req: Request) -> Result<Response> {
351     ///     Ok(Response::Ok()
352     ///         .set(http::header::IfModifiedSince(
353     ///             "Sun, 07 Nov 1994 08:48:37 GMT".parse()?,
354     ///         ))
355     ///         .finish())
356     /// }
357     /// ```
358     #[doc(hidden)]
set<H: Header>(&mut self, hdr: H) -> &mut Self359     pub fn set<H: Header>(&mut self, hdr: H) -> &mut Self {
360         if let Some(parts) = parts(&mut self.head, &self.err) {
361             match hdr.try_into() {
362                 Ok(value) => {
363                     parts.headers.append(H::name(), value);
364                 }
365                 Err(e) => self.err = Some(e.into()),
366             }
367         }
368         self
369     }
370 
371     /// Append a header to existing headers.
372     ///
373     /// ```rust
374     /// use actix_http::{http, Request, Response};
375     ///
376     /// fn index(req: Request) -> Response {
377     ///     Response::Ok()
378     ///         .header("X-TEST", "value")
379     ///         .header(http::header::CONTENT_TYPE, "application/json")
380     ///         .finish()
381     /// }
382     /// ```
header<K, V>(&mut self, key: K, value: V) -> &mut Self where HeaderName: TryFrom<K>, <HeaderName as TryFrom<K>>::Error: Into<HttpError>, V: IntoHeaderValue,383     pub fn header<K, V>(&mut self, key: K, value: V) -> &mut Self
384     where
385         HeaderName: TryFrom<K>,
386         <HeaderName as TryFrom<K>>::Error: Into<HttpError>,
387         V: IntoHeaderValue,
388     {
389         if let Some(parts) = parts(&mut self.head, &self.err) {
390             match HeaderName::try_from(key) {
391                 Ok(key) => match value.try_into() {
392                     Ok(value) => {
393                         parts.headers.append(key, value);
394                     }
395                     Err(e) => self.err = Some(e.into()),
396                 },
397                 Err(e) => self.err = Some(e.into()),
398             };
399         }
400         self
401     }
402 
403     /// Set a header.
404     ///
405     /// ```rust
406     /// use actix_http::{http, Request, Response};
407     ///
408     /// fn index(req: Request) -> Response {
409     ///     Response::Ok()
410     ///         .set_header("X-TEST", "value")
411     ///         .set_header(http::header::CONTENT_TYPE, "application/json")
412     ///         .finish()
413     /// }
414     /// ```
set_header<K, V>(&mut self, key: K, value: V) -> &mut Self where HeaderName: TryFrom<K>, <HeaderName as TryFrom<K>>::Error: Into<HttpError>, V: IntoHeaderValue,415     pub fn set_header<K, V>(&mut self, key: K, value: V) -> &mut Self
416     where
417         HeaderName: TryFrom<K>,
418         <HeaderName as TryFrom<K>>::Error: Into<HttpError>,
419         V: IntoHeaderValue,
420     {
421         if let Some(parts) = parts(&mut self.head, &self.err) {
422             match HeaderName::try_from(key) {
423                 Ok(key) => match value.try_into() {
424                     Ok(value) => {
425                         parts.headers.insert(key, value);
426                     }
427                     Err(e) => self.err = Some(e.into()),
428                 },
429                 Err(e) => self.err = Some(e.into()),
430             };
431         }
432         self
433     }
434 
435     /// Set the custom reason for the response.
436     #[inline]
reason(&mut self, reason: &'static str) -> &mut Self437     pub fn reason(&mut self, reason: &'static str) -> &mut Self {
438         if let Some(parts) = parts(&mut self.head, &self.err) {
439             parts.reason = Some(reason);
440         }
441         self
442     }
443 
444     /// Set connection type to KeepAlive
445     #[inline]
keep_alive(&mut self) -> &mut Self446     pub fn keep_alive(&mut self) -> &mut Self {
447         if let Some(parts) = parts(&mut self.head, &self.err) {
448             parts.set_connection_type(ConnectionType::KeepAlive);
449         }
450         self
451     }
452 
453     /// Set connection type to Upgrade
454     #[inline]
upgrade<V>(&mut self, value: V) -> &mut Self where V: IntoHeaderValue,455     pub fn upgrade<V>(&mut self, value: V) -> &mut Self
456     where
457         V: IntoHeaderValue,
458     {
459         if let Some(parts) = parts(&mut self.head, &self.err) {
460             parts.set_connection_type(ConnectionType::Upgrade);
461         }
462         self.set_header(header::UPGRADE, value)
463     }
464 
465     /// Force close connection, even if it is marked as keep-alive
466     #[inline]
force_close(&mut self) -> &mut Self467     pub fn force_close(&mut self) -> &mut Self {
468         if let Some(parts) = parts(&mut self.head, &self.err) {
469             parts.set_connection_type(ConnectionType::Close);
470         }
471         self
472     }
473 
474     /// Disable chunked transfer encoding for HTTP/1.1 streaming responses.
475     #[inline]
no_chunking(&mut self) -> &mut Self476     pub fn no_chunking(&mut self) -> &mut Self {
477         if let Some(parts) = parts(&mut self.head, &self.err) {
478             parts.no_chunking(true);
479         }
480         self
481     }
482 
483     /// Set response content type
484     #[inline]
content_type<V>(&mut self, value: V) -> &mut Self where HeaderValue: TryFrom<V>, <HeaderValue as TryFrom<V>>::Error: Into<HttpError>,485     pub fn content_type<V>(&mut self, value: V) -> &mut Self
486     where
487         HeaderValue: TryFrom<V>,
488         <HeaderValue as TryFrom<V>>::Error: Into<HttpError>,
489     {
490         if let Some(parts) = parts(&mut self.head, &self.err) {
491             match HeaderValue::try_from(value) {
492                 Ok(value) => {
493                     parts.headers.insert(header::CONTENT_TYPE, value);
494                 }
495                 Err(e) => self.err = Some(e.into()),
496             };
497         }
498         self
499     }
500 
501     /// Set content length
502     #[inline]
content_length(&mut self, len: u64) -> &mut Self503     pub fn content_length(&mut self, len: u64) -> &mut Self {
504         self.header(header::CONTENT_LENGTH, len)
505     }
506 
507     /// Set a cookie
508     ///
509     /// ```rust
510     /// use actix_http::{http, Request, Response};
511     ///
512     /// fn index(req: Request) -> Response {
513     ///     Response::Ok()
514     ///         .cookie(
515     ///             http::Cookie::build("name", "value")
516     ///                 .domain("www.rust-lang.org")
517     ///                 .path("/")
518     ///                 .secure(true)
519     ///                 .http_only(true)
520     ///                 .finish(),
521     ///         )
522     ///         .finish()
523     /// }
524     /// ```
cookie<'c>(&mut self, cookie: Cookie<'c>) -> &mut Self525     pub fn cookie<'c>(&mut self, cookie: Cookie<'c>) -> &mut Self {
526         if self.cookies.is_none() {
527             let mut jar = CookieJar::new();
528             jar.add(cookie.into_owned());
529             self.cookies = Some(jar)
530         } else {
531             self.cookies.as_mut().unwrap().add(cookie.into_owned());
532         }
533         self
534     }
535 
536     /// Remove cookie
537     ///
538     /// ```rust
539     /// use actix_http::{http, Request, Response, HttpMessage};
540     ///
541     /// fn index(req: Request) -> Response {
542     ///     let mut builder = Response::Ok();
543     ///
544     ///     if let Some(ref cookie) = req.cookie("name") {
545     ///         builder.del_cookie(cookie);
546     ///     }
547     ///
548     ///     builder.finish()
549     /// }
550     /// ```
del_cookie<'a>(&mut self, cookie: &Cookie<'a>) -> &mut Self551     pub fn del_cookie<'a>(&mut self, cookie: &Cookie<'a>) -> &mut Self {
552         if self.cookies.is_none() {
553             self.cookies = Some(CookieJar::new())
554         }
555         let jar = self.cookies.as_mut().unwrap();
556         let cookie = cookie.clone().into_owned();
557         jar.add_original(cookie.clone());
558         jar.remove(cookie);
559         self
560     }
561 
562     /// This method calls provided closure with builder reference if value is
563     /// true.
if_true<F>(&mut self, value: bool, f: F) -> &mut Self where F: FnOnce(&mut ResponseBuilder),564     pub fn if_true<F>(&mut self, value: bool, f: F) -> &mut Self
565     where
566         F: FnOnce(&mut ResponseBuilder),
567     {
568         if value {
569             f(self);
570         }
571         self
572     }
573 
574     /// This method calls provided closure with builder reference if value is
575     /// Some.
if_some<T, F>(&mut self, value: Option<T>, f: F) -> &mut Self where F: FnOnce(T, &mut ResponseBuilder),576     pub fn if_some<T, F>(&mut self, value: Option<T>, f: F) -> &mut Self
577     where
578         F: FnOnce(T, &mut ResponseBuilder),
579     {
580         if let Some(val) = value {
581             f(val, self);
582         }
583         self
584     }
585 
586     /// Responses extensions
587     #[inline]
extensions(&self) -> Ref<'_, Extensions>588     pub fn extensions(&self) -> Ref<'_, Extensions> {
589         let head = self.head.as_ref().expect("cannot reuse response builder");
590         head.extensions.borrow()
591     }
592 
593     /// Mutable reference to a the response's extensions
594     #[inline]
extensions_mut(&mut self) -> RefMut<'_, Extensions>595     pub fn extensions_mut(&mut self) -> RefMut<'_, Extensions> {
596         let head = self.head.as_ref().expect("cannot reuse response builder");
597         head.extensions.borrow_mut()
598     }
599 
600     #[inline]
601     /// Set a body and generate `Response`.
602     ///
603     /// `ResponseBuilder` can not be used after this call.
body<B: Into<Body>>(&mut self, body: B) -> Response604     pub fn body<B: Into<Body>>(&mut self, body: B) -> Response {
605         self.message_body(body.into())
606     }
607 
608     /// Set a body and generate `Response`.
609     ///
610     /// `ResponseBuilder` can not be used after this call.
message_body<B>(&mut self, body: B) -> Response<B>611     pub fn message_body<B>(&mut self, body: B) -> Response<B> {
612         if let Some(e) = self.err.take() {
613             return Response::from(Error::from(e)).into_body();
614         }
615 
616         let mut response = self.head.take().expect("cannot reuse response builder");
617 
618         if let Some(ref jar) = self.cookies {
619             for cookie in jar.delta() {
620                 match HeaderValue::from_str(&cookie.to_string()) {
621                     Ok(val) => response.headers.append(header::SET_COOKIE, val),
622                     Err(e) => return Response::from(Error::from(e)).into_body(),
623                 };
624             }
625         }
626 
627         Response {
628             head: response,
629             body: ResponseBody::Body(body),
630             error: None,
631         }
632     }
633 
634     #[inline]
635     /// Set a streaming body and generate `Response`.
636     ///
637     /// `ResponseBuilder` can not be used after this call.
streaming<S, E>(&mut self, stream: S) -> Response where S: Stream<Item = Result<Bytes, E>> + 'static, E: Into<Error> + 'static,638     pub fn streaming<S, E>(&mut self, stream: S) -> Response
639     where
640         S: Stream<Item = Result<Bytes, E>> + 'static,
641         E: Into<Error> + 'static,
642     {
643         self.body(Body::from_message(BodyStream::new(stream)))
644     }
645 
646     #[inline]
647     /// Set a json body and generate `Response`
648     ///
649     /// `ResponseBuilder` can not be used after this call.
json<T: Serialize>(&mut self, value: T) -> Response650     pub fn json<T: Serialize>(&mut self, value: T) -> Response {
651         self.json2(&value)
652     }
653 
654     /// Set a json body and generate `Response`
655     ///
656     /// `ResponseBuilder` can not be used after this call.
json2<T: Serialize>(&mut self, value: &T) -> Response657     pub fn json2<T: Serialize>(&mut self, value: &T) -> Response {
658         match serde_json::to_string(value) {
659             Ok(body) => {
660                 let contains = if let Some(parts) = parts(&mut self.head, &self.err) {
661                     parts.headers.contains_key(header::CONTENT_TYPE)
662                 } else {
663                     true
664                 };
665                 if !contains {
666                     self.header(header::CONTENT_TYPE, "application/json");
667                 }
668 
669                 self.body(Body::from(body))
670             }
671             Err(e) => Error::from(e).into(),
672         }
673     }
674 
675     #[inline]
676     /// Set an empty body and generate `Response`
677     ///
678     /// `ResponseBuilder` can not be used after this call.
finish(&mut self) -> Response679     pub fn finish(&mut self) -> Response {
680         self.body(Body::Empty)
681     }
682 
683     /// This method construct new `ResponseBuilder`
take(&mut self) -> ResponseBuilder684     pub fn take(&mut self) -> ResponseBuilder {
685         ResponseBuilder {
686             head: self.head.take(),
687             err: self.err.take(),
688             cookies: self.cookies.take(),
689         }
690     }
691 }
692 
693 #[inline]
parts<'a>( parts: &'a mut Option<BoxedResponseHead>, err: &Option<HttpError>, ) -> Option<&'a mut ResponseHead>694 fn parts<'a>(
695     parts: &'a mut Option<BoxedResponseHead>,
696     err: &Option<HttpError>,
697 ) -> Option<&'a mut ResponseHead> {
698     if err.is_some() {
699         return None;
700     }
701     parts.as_mut().map(|r| &mut **r)
702 }
703 
704 /// Convert `Response` to a `ResponseBuilder`. Body get dropped.
705 impl<B> From<Response<B>> for ResponseBuilder {
from(res: Response<B>) -> ResponseBuilder706     fn from(res: Response<B>) -> ResponseBuilder {
707         // If this response has cookies, load them into a jar
708         let mut jar: Option<CookieJar> = None;
709         for c in res.cookies() {
710             if let Some(ref mut j) = jar {
711                 j.add_original(c.into_owned());
712             } else {
713                 let mut j = CookieJar::new();
714                 j.add_original(c.into_owned());
715                 jar = Some(j);
716             }
717         }
718 
719         ResponseBuilder {
720             head: Some(res.head),
721             err: None,
722             cookies: jar,
723         }
724     }
725 }
726 
727 /// Convert `ResponseHead` to a `ResponseBuilder`
728 impl<'a> From<&'a ResponseHead> for ResponseBuilder {
from(head: &'a ResponseHead) -> ResponseBuilder729     fn from(head: &'a ResponseHead) -> ResponseBuilder {
730         // If this response has cookies, load them into a jar
731         let mut jar: Option<CookieJar> = None;
732 
733         let cookies = CookieIter {
734             iter: head.headers.get_all(header::SET_COOKIE),
735         };
736         for c in cookies {
737             if let Some(ref mut j) = jar {
738                 j.add_original(c.into_owned());
739             } else {
740                 let mut j = CookieJar::new();
741                 j.add_original(c.into_owned());
742                 jar = Some(j);
743             }
744         }
745 
746         let mut msg = BoxedResponseHead::new(head.status);
747         msg.version = head.version;
748         msg.reason = head.reason;
749         for (k, v) in &head.headers {
750             msg.headers.append(k.clone(), v.clone());
751         }
752         msg.no_chunking(!head.chunked());
753 
754         ResponseBuilder {
755             head: Some(msg),
756             err: None,
757             cookies: jar,
758         }
759     }
760 }
761 
762 impl Future for ResponseBuilder {
763     type Output = Result<Response, Error>;
764 
poll(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output>765     fn poll(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> {
766         Poll::Ready(Ok(self.finish()))
767     }
768 }
769 
770 impl fmt::Debug for ResponseBuilder {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result771     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
772         let head = self.head.as_ref().unwrap();
773 
774         let res = writeln!(
775             f,
776             "\nResponseBuilder {:?} {}{}",
777             head.version,
778             head.status,
779             head.reason.unwrap_or(""),
780         );
781         let _ = writeln!(f, "  headers:");
782         for (key, val) in head.headers.iter() {
783             let _ = writeln!(f, "    {:?}: {:?}", key, val);
784         }
785         res
786     }
787 }
788 
789 /// Helper converters
790 impl<I: Into<Response>, E: Into<Error>> From<Result<I, E>> for Response {
from(res: Result<I, E>) -> Self791     fn from(res: Result<I, E>) -> Self {
792         match res {
793             Ok(val) => val.into(),
794             Err(err) => err.into().into(),
795         }
796     }
797 }
798 
799 impl From<ResponseBuilder> for Response {
from(mut builder: ResponseBuilder) -> Self800     fn from(mut builder: ResponseBuilder) -> Self {
801         builder.finish()
802     }
803 }
804 
805 impl From<&'static str> for Response {
from(val: &'static str) -> Self806     fn from(val: &'static str) -> Self {
807         Response::Ok()
808             .content_type("text/plain; charset=utf-8")
809             .body(val)
810     }
811 }
812 
813 impl From<&'static [u8]> for Response {
from(val: &'static [u8]) -> Self814     fn from(val: &'static [u8]) -> Self {
815         Response::Ok()
816             .content_type("application/octet-stream")
817             .body(val)
818     }
819 }
820 
821 impl From<String> for Response {
from(val: String) -> Self822     fn from(val: String) -> Self {
823         Response::Ok()
824             .content_type("text/plain; charset=utf-8")
825             .body(val)
826     }
827 }
828 
829 impl<'a> From<&'a String> for Response {
from(val: &'a String) -> Self830     fn from(val: &'a String) -> Self {
831         Response::Ok()
832             .content_type("text/plain; charset=utf-8")
833             .body(val)
834     }
835 }
836 
837 impl From<Bytes> for Response {
from(val: Bytes) -> Self838     fn from(val: Bytes) -> Self {
839         Response::Ok()
840             .content_type("application/octet-stream")
841             .body(val)
842     }
843 }
844 
845 impl From<BytesMut> for Response {
from(val: BytesMut) -> Self846     fn from(val: BytesMut) -> Self {
847         Response::Ok()
848             .content_type("application/octet-stream")
849             .body(val)
850     }
851 }
852 
853 #[cfg(test)]
854 mod tests {
855     use super::*;
856     use crate::body::Body;
857     use crate::http::header::{HeaderValue, CONTENT_TYPE, COOKIE, SET_COOKIE};
858 
859     #[test]
test_debug()860     fn test_debug() {
861         let resp = Response::Ok()
862             .header(COOKIE, HeaderValue::from_static("cookie1=value1; "))
863             .header(COOKIE, HeaderValue::from_static("cookie2=value2; "))
864             .finish();
865         let dbg = format!("{:?}", resp);
866         assert!(dbg.contains("Response"));
867     }
868 
869     #[test]
test_response_cookies()870     fn test_response_cookies() {
871         use crate::httpmessage::HttpMessage;
872 
873         let req = crate::test::TestRequest::default()
874             .header(COOKIE, "cookie1=value1")
875             .header(COOKIE, "cookie2=value2")
876             .finish();
877         let cookies = req.cookies().unwrap();
878 
879         let resp = Response::Ok()
880             .cookie(
881                 crate::http::Cookie::build("name", "value")
882                     .domain("www.rust-lang.org")
883                     .path("/test")
884                     .http_only(true)
885                     .max_age_time(time::Duration::days(1))
886                     .finish(),
887             )
888             .del_cookie(&cookies[1])
889             .finish();
890 
891         let mut val: Vec<_> = resp
892             .headers()
893             .get_all(SET_COOKIE)
894             .map(|v| v.to_str().unwrap().to_owned())
895             .collect();
896         val.sort();
897         assert!(val[0].starts_with("cookie1=; Max-Age=0;"));
898         assert_eq!(
899             val[1],
900             "name=value; HttpOnly; Path=/test; Domain=www.rust-lang.org; Max-Age=86400"
901         );
902     }
903 
904     #[test]
test_update_response_cookies()905     fn test_update_response_cookies() {
906         let mut r = Response::Ok()
907             .cookie(crate::http::Cookie::new("original", "val100"))
908             .finish();
909 
910         r.add_cookie(&crate::http::Cookie::new("cookie2", "val200"))
911             .unwrap();
912         r.add_cookie(&crate::http::Cookie::new("cookie2", "val250"))
913             .unwrap();
914         r.add_cookie(&crate::http::Cookie::new("cookie3", "val300"))
915             .unwrap();
916 
917         assert_eq!(r.cookies().count(), 4);
918         r.del_cookie("cookie2");
919 
920         let mut iter = r.cookies();
921         let v = iter.next().unwrap();
922         assert_eq!((v.name(), v.value()), ("cookie3", "val300"));
923         let v = iter.next().unwrap();
924         assert_eq!((v.name(), v.value()), ("original", "val100"));
925     }
926 
927     #[test]
test_basic_builder()928     fn test_basic_builder() {
929         let resp = Response::Ok().header("X-TEST", "value").finish();
930         assert_eq!(resp.status(), StatusCode::OK);
931     }
932 
933     #[test]
test_upgrade()934     fn test_upgrade() {
935         let resp = Response::build(StatusCode::OK)
936             .upgrade("websocket")
937             .finish();
938         assert!(resp.upgrade());
939         assert_eq!(
940             resp.headers().get(header::UPGRADE).unwrap(),
941             HeaderValue::from_static("websocket")
942         );
943     }
944 
945     #[test]
test_force_close()946     fn test_force_close() {
947         let resp = Response::build(StatusCode::OK).force_close().finish();
948         assert!(!resp.keep_alive())
949     }
950 
951     #[test]
test_content_type()952     fn test_content_type() {
953         let resp = Response::build(StatusCode::OK)
954             .content_type("text/plain")
955             .body(Body::Empty);
956         assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "text/plain")
957     }
958 
959     #[test]
test_json()960     fn test_json() {
961         let resp = Response::build(StatusCode::OK).json(vec!["v1", "v2", "v3"]);
962         let ct = resp.headers().get(CONTENT_TYPE).unwrap();
963         assert_eq!(ct, HeaderValue::from_static("application/json"));
964         assert_eq!(resp.body().get_ref(), b"[\"v1\",\"v2\",\"v3\"]");
965     }
966 
967     #[test]
test_json_ct()968     fn test_json_ct() {
969         let resp = Response::build(StatusCode::OK)
970             .header(CONTENT_TYPE, "text/json")
971             .json(vec!["v1", "v2", "v3"]);
972         let ct = resp.headers().get(CONTENT_TYPE).unwrap();
973         assert_eq!(ct, HeaderValue::from_static("text/json"));
974         assert_eq!(resp.body().get_ref(), b"[\"v1\",\"v2\",\"v3\"]");
975     }
976 
977     #[test]
test_json2()978     fn test_json2() {
979         let resp = Response::build(StatusCode::OK).json2(&vec!["v1", "v2", "v3"]);
980         let ct = resp.headers().get(CONTENT_TYPE).unwrap();
981         assert_eq!(ct, HeaderValue::from_static("application/json"));
982         assert_eq!(resp.body().get_ref(), b"[\"v1\",\"v2\",\"v3\"]");
983     }
984 
985     #[test]
test_json2_ct()986     fn test_json2_ct() {
987         let resp = Response::build(StatusCode::OK)
988             .header(CONTENT_TYPE, "text/json")
989             .json2(&vec!["v1", "v2", "v3"]);
990         let ct = resp.headers().get(CONTENT_TYPE).unwrap();
991         assert_eq!(ct, HeaderValue::from_static("text/json"));
992         assert_eq!(resp.body().get_ref(), b"[\"v1\",\"v2\",\"v3\"]");
993     }
994 
995     #[test]
test_serde_json_in_body()996     fn test_serde_json_in_body() {
997         use serde_json::json;
998         let resp =
999             Response::build(StatusCode::OK).body(json!({"test-key":"test-value"}));
1000         assert_eq!(resp.body().get_ref(), br#"{"test-key":"test-value"}"#);
1001     }
1002 
1003     #[test]
test_into_response()1004     fn test_into_response() {
1005         let resp: Response = "test".into();
1006         assert_eq!(resp.status(), StatusCode::OK);
1007         assert_eq!(
1008             resp.headers().get(CONTENT_TYPE).unwrap(),
1009             HeaderValue::from_static("text/plain; charset=utf-8")
1010         );
1011         assert_eq!(resp.status(), StatusCode::OK);
1012         assert_eq!(resp.body().get_ref(), b"test");
1013 
1014         let resp: Response = b"test".as_ref().into();
1015         assert_eq!(resp.status(), StatusCode::OK);
1016         assert_eq!(
1017             resp.headers().get(CONTENT_TYPE).unwrap(),
1018             HeaderValue::from_static("application/octet-stream")
1019         );
1020         assert_eq!(resp.status(), StatusCode::OK);
1021         assert_eq!(resp.body().get_ref(), b"test");
1022 
1023         let resp: Response = "test".to_owned().into();
1024         assert_eq!(resp.status(), StatusCode::OK);
1025         assert_eq!(
1026             resp.headers().get(CONTENT_TYPE).unwrap(),
1027             HeaderValue::from_static("text/plain; charset=utf-8")
1028         );
1029         assert_eq!(resp.status(), StatusCode::OK);
1030         assert_eq!(resp.body().get_ref(), b"test");
1031 
1032         let resp: Response = (&"test".to_owned()).into();
1033         assert_eq!(resp.status(), StatusCode::OK);
1034         assert_eq!(
1035             resp.headers().get(CONTENT_TYPE).unwrap(),
1036             HeaderValue::from_static("text/plain; charset=utf-8")
1037         );
1038         assert_eq!(resp.status(), StatusCode::OK);
1039         assert_eq!(resp.body().get_ref(), b"test");
1040 
1041         let b = Bytes::from_static(b"test");
1042         let resp: Response = b.into();
1043         assert_eq!(resp.status(), StatusCode::OK);
1044         assert_eq!(
1045             resp.headers().get(CONTENT_TYPE).unwrap(),
1046             HeaderValue::from_static("application/octet-stream")
1047         );
1048         assert_eq!(resp.status(), StatusCode::OK);
1049         assert_eq!(resp.body().get_ref(), b"test");
1050 
1051         let b = Bytes::from_static(b"test");
1052         let resp: Response = b.into();
1053         assert_eq!(resp.status(), StatusCode::OK);
1054         assert_eq!(
1055             resp.headers().get(CONTENT_TYPE).unwrap(),
1056             HeaderValue::from_static("application/octet-stream")
1057         );
1058         assert_eq!(resp.status(), StatusCode::OK);
1059         assert_eq!(resp.body().get_ref(), b"test");
1060 
1061         let b = BytesMut::from("test");
1062         let resp: Response = b.into();
1063         assert_eq!(resp.status(), StatusCode::OK);
1064         assert_eq!(
1065             resp.headers().get(CONTENT_TYPE).unwrap(),
1066             HeaderValue::from_static("application/octet-stream")
1067         );
1068 
1069         assert_eq!(resp.status(), StatusCode::OK);
1070         assert_eq!(resp.body().get_ref(), b"test");
1071     }
1072 
1073     #[test]
test_into_builder()1074     fn test_into_builder() {
1075         let mut resp: Response = "test".into();
1076         assert_eq!(resp.status(), StatusCode::OK);
1077 
1078         resp.add_cookie(&crate::http::Cookie::new("cookie1", "val100"))
1079             .unwrap();
1080 
1081         let mut builder: ResponseBuilder = resp.into();
1082         let resp = builder.status(StatusCode::BAD_REQUEST).finish();
1083         assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
1084 
1085         let cookie = resp.cookies().next().unwrap();
1086         assert_eq!((cookie.name(), cookie.value()), ("cookie1", "val100"));
1087     }
1088 }
1089