rocket/response/
response.rs

1use std::{fmt, str};
2use std::borrow::Cow;
3use std::collections::HashMap;
4use std::pin::Pin;
5
6use tokio::io::{AsyncRead, AsyncSeek};
7
8use crate::http::{Header, HeaderMap, Status, ContentType, Cookie};
9use crate::http::uncased::{Uncased, AsUncased};
10use crate::data::IoHandler;
11use crate::response::Body;
12
13/// Builder for the [`Response`] type.
14///
15/// Building a [`Response`] can be a low-level ordeal; this structure presents a
16/// higher-level API that simplifies building `Response`s.
17///
18/// # Usage
19///
20/// `Builder` follows the builder pattern and is usually obtained by calling
21/// [`Response::build()`] on `Response`. Almost all methods take the current
22/// builder as a mutable reference and return the same mutable reference with
23/// field(s) modified in the `Response` being built. These method calls can be
24/// chained: `build.a().b()`.
25///
26/// To finish building and retrieve the built `Response`, use the
27/// [`finalize()`](#method.finalize) or [`ok()`](#method.ok) methods.
28///
29/// ## Headers
30///
31/// When building a `Response`, headers can either be _replaced_ or _adjoined_;
32/// the default behavior (using `header(..)`) is to _replace_. When a header is
33/// _replaced_, any existing values for headers with the same name are removed,
34/// and the new value is set. If no header exists, the header is simply added.
35/// On the other hand, when a header is _adjoined_, all existing values will
36/// remain, and the `value` of the adjoined header will be added to the set of
37/// existing values, if any. Adjoining maintains order: headers adjoined first
38/// will appear first in the `Response`.
39///
40/// ## Joining and Merging
41///
42/// It is often necessary to combine multiple `Response`s in some way. The
43/// [merge](#method.merge) and [join](#method.join) methods facilitate this. The
44/// `merge` method replaces all of the fields in `self` with those present in
45/// `other`. The `join` method sets any fields not set in `self` to the value in
46/// `other`. See their documentation for more details.
47/// ## Example
48///
49/// The following example builds a `Response` with:
50///
51///   * **Status**: `418 I'm a teapot`
52///   * **Content-Type** header: `text/plain; charset=utf-8`
53///   * **X-Teapot-Make** header: `Rocket`
54///   * **X-Teapot-Model** headers: `Utopia`, `Series 1`
55///   * **Body**: fixed-size string `"Brewing the best coffee!"`
56///
57/// ```rust
58/// use std::io::Cursor;
59/// use rocket::response::Response;
60/// use rocket::http::{Status, ContentType};
61///
62/// let body = "Brewing the best coffee!";
63/// let response = Response::build()
64///     .status(Status::ImATeapot)
65///     .header(ContentType::Plain)
66///     .raw_header("X-Teapot-Make", "Rocket")
67///     .raw_header("X-Teapot-Model", "Utopia")
68///     .raw_header_adjoin("X-Teapot-Model", "Series 1")
69///     .sized_body(body.len(), Cursor::new(body))
70///     .finalize();
71/// ```
72pub struct Builder<'r> {
73    response: Response<'r>,
74}
75
76impl<'r> Builder<'r> {
77    /// Creates a new `Builder` that will build on top of the `base`
78    /// `Response`.
79    ///
80    /// # Example
81    ///
82    /// ```rust
83    /// use rocket::response::{Builder, Response};
84    ///
85    /// # #[allow(unused_variables)]
86    /// let builder = Builder::new(Response::new());
87    /// ```
88    #[inline(always)]
89    pub fn new(base: Response<'r>) -> Builder<'r> {
90        Builder {
91            response: base,
92        }
93    }
94
95    /// Sets the status of the `Response` being built to `status`.
96    ///
97    /// # Example
98    ///
99    /// ```rust
100    /// use rocket::Response;
101    /// use rocket::http::Status;
102    ///
103    /// let response = Response::build()
104    ///     .status(Status::NotFound)
105    ///     .finalize();
106    /// ```
107    #[inline(always)]
108    pub fn status(&mut self, status: Status) -> &mut Builder<'r> {
109        self.response.set_status(status);
110        self
111    }
112
113    /// Adds `header` to the `Response`, replacing any header with the same name
114    /// that already exists in the response. If multiple headers with
115    /// the same name exist, they are all removed, and only the new header and
116    /// value will remain.
117    ///
118    /// The type of `header` can be any type that implements `Into<Header>`.
119    /// This includes `Header` itself, [`ContentType`](crate::http::ContentType) and
120    /// [hyper::header types](crate::http::hyper::header).
121    ///
122    /// # Example
123    ///
124    /// ```rust
125    /// use rocket::Response;
126    /// use rocket::http::ContentType;
127    ///
128    /// let response = Response::build()
129    ///     .header(ContentType::JSON)
130    ///     .header(ContentType::HTML)
131    ///     .finalize();
132    ///
133    /// assert_eq!(response.headers().get("Content-Type").count(), 1);
134    /// ```
135    #[inline(always)]
136    pub fn header<'h: 'r, H>(&mut self, header: H) -> &mut Builder<'r>
137        where H: Into<Header<'h>>
138    {
139        self.response.set_header(header);
140        self
141    }
142
143    /// Adds `header` to the `Response` by adjoining the header with any
144    /// existing headers with the same name that already exist in the
145    /// `Response`. This allows for multiple headers with the same name and
146    /// potentially different values to be present in the `Response`.
147    ///
148    /// The type of `header` can be any type that implements `Into<Header>`.
149    /// This includes `Header` itself, [`ContentType`](crate::http::ContentType) and
150    /// [hyper::header types](crate::http::hyper::header).
151    ///
152    /// # Example
153    ///
154    /// ```rust
155    /// use rocket::Response;
156    /// use rocket::http::Header;
157    /// use rocket::http::hyper::header::ACCEPT;
158    ///
159    /// let response = Response::build()
160    ///     .header_adjoin(Header::new(ACCEPT.as_str(), "application/json"))
161    ///     .header_adjoin(Header::new(ACCEPT.as_str(), "text/plain"))
162    ///     .finalize();
163    ///
164    /// assert_eq!(response.headers().get("Accept").count(), 2);
165    /// ```
166    #[inline(always)]
167    pub fn header_adjoin<'h: 'r, H>(&mut self, header: H) -> &mut Builder<'r>
168        where H: Into<Header<'h>>
169    {
170        self.response.adjoin_header(header);
171        self
172    }
173
174    /// Adds a custom header to the `Response` with the given name and value,
175    /// replacing any header with the same name that already exists in the
176    /// response. If multiple headers with the same name exist, they are all
177    /// removed, and only the new header and value will remain.
178    ///
179    /// # Example
180    ///
181    /// ```rust
182    /// use rocket::Response;
183    ///
184    /// let response = Response::build()
185    ///     .raw_header("X-Custom", "first")
186    ///     .raw_header("X-Custom", "second")
187    ///     .finalize();
188    ///
189    /// assert_eq!(response.headers().get("X-Custom").count(), 1);
190    /// ```
191    #[inline(always)]
192    pub fn raw_header<'a, 'b, N, V>(&mut self, name: N, value: V) -> &mut Builder<'r>
193        where N: Into<Cow<'a, str>>, V: Into<Cow<'b, str>>, 'a: 'r, 'b: 'r
194    {
195        self.response.set_raw_header(name, value);
196        self
197    }
198
199    /// Adds custom header to the `Response` with the given name and value,
200    /// adjoining the header with any existing headers with the same name that
201    /// already exist in the `Response`. This allows for multiple headers with
202    /// the same name and potentially different values to be present in the
203    /// `Response`.
204    ///
205    /// # Example
206    ///
207    /// ```rust
208    /// use rocket::Response;
209    ///
210    /// let response = Response::build()
211    ///     .raw_header_adjoin("X-Custom", "first")
212    ///     .raw_header_adjoin("X-Custom", "second")
213    ///     .finalize();
214    ///
215    /// assert_eq!(response.headers().get("X-Custom").count(), 2);
216    /// ```
217    #[inline(always)]
218    pub fn raw_header_adjoin<'a, 'b, N, V>(&mut self, name: N, value: V) -> &mut Builder<'r>
219        where N: Into<Cow<'a, str>>, V: Into<Cow<'b, str>>, 'a: 'r, 'b: 'r
220    {
221        self.response.adjoin_raw_header(name, value);
222        self
223    }
224
225    /// Sets the body of the `Response` to be the fixed-sized `body` with size
226    /// `size`, which may be `None`. If `size` is `None`, the body's size will
227    /// be computed with calls to `seek` when the response is written out.
228    ///
229    /// # Example
230    ///
231    /// ```rust
232    /// use std::io::Cursor;
233    /// use rocket::Response;
234    ///
235    /// let body = "Hello, world!";
236    /// let response = Response::build()
237    ///     .sized_body(body.len(), Cursor::new(body))
238    ///     .finalize();
239    /// ```
240    pub fn sized_body<B, S>(&mut self, size: S, body: B) -> &mut Builder<'r>
241        where B: AsyncRead + AsyncSeek + Send + 'r,
242              S: Into<Option<usize>>
243    {
244        self.response.set_sized_body(size, body);
245        self
246    }
247
248    /// Sets the body of the `Response` to be the streamed `body`.
249    ///
250    /// # Example
251    ///
252    /// ```rust
253    /// use std::io::Cursor;
254    /// use rocket::Response;
255    ///
256    /// let response = Response::build()
257    ///     .streamed_body(Cursor::new("Hello, world!"))
258    ///     .finalize();
259    /// ```
260    #[inline(always)]
261    pub fn streamed_body<B>(&mut self, body: B) -> &mut Builder<'r>
262        where B: AsyncRead + Send + 'r
263    {
264        self.response.set_streamed_body(body);
265        self
266    }
267
268    /// Registers `handler` as the I/O handler for upgrade protocol `protocol`.
269    ///
270    /// This is equivalent to [`Response::add_upgrade()`].
271    ///
272    /// **NOTE**: Responses registering I/O handlers for upgraded protocols
273    /// **should not** set the response status to `101 Switching Protocols`, nor set the
274    /// `Connection` or `Upgrade` headers. Rocket automatically sets these
275    /// headers as needed. See [`Response`#upgrading] for details.
276    ///
277    /// # Example
278    ///
279    /// ```rust
280    /// use std::pin::Pin;
281    ///
282    /// use rocket::Response;
283    /// use rocket::data::{IoHandler, IoStream};
284    /// use rocket::tokio::io;
285    ///
286    /// struct EchoHandler;
287    ///
288    /// #[rocket::async_trait]
289    /// impl IoHandler for EchoHandler {
290    ///     async fn io(self: Pin<Box<Self>>, io: IoStream) -> io::Result<()> {
291    ///         let (mut reader, mut writer) = io::split(io);
292    ///         io::copy(&mut reader, &mut writer).await?;
293    ///         Ok(())
294    ///     }
295    /// }
296    ///
297    /// let response = Response::build()
298    ///     .upgrade("raw-echo", EchoHandler)
299    ///     .streamed_body(std::io::Cursor::new("We didn't upgrade!"))
300    ///     .finalize();
301    /// ```
302    #[inline(always)]
303    pub fn upgrade<P, H>(&mut self, protocol: P, handler: H) -> &mut Builder<'r>
304        where P: Into<Uncased<'r>>, H: IoHandler + 'r
305    {
306        self.response.add_upgrade(protocol.into(), handler);
307        self
308    }
309
310    /// Sets the max chunk size of a body, if any, to `size`.
311    ///
312    /// See [`Response::set_max_chunk_size()`] for notes.
313    ///
314    /// # Example
315    ///
316    /// ```rust
317    /// use std::io::Cursor;
318    /// use rocket::Response;
319    ///
320    /// let response = Response::build()
321    ///     .streamed_body(Cursor::new("Hello, world!"))
322    ///     .max_chunk_size(3072)
323    ///     .finalize();
324    /// ```
325    #[inline(always)]
326    pub fn max_chunk_size(&mut self, size: usize) -> &mut Builder<'r> {
327        self.response.set_max_chunk_size(size);
328        self
329    }
330
331    /// Merges the `other` `Response` into `self` by setting any fields in
332    /// `self` to the corresponding value in `other` if they are set in `other`.
333    /// Fields in `self` are unchanged if they are not set in `other`. If a
334    /// header is set in both `self` and `other`, the values in `other` are
335    /// kept. Headers set only in `self` remain.
336    ///
337    /// # Example
338    ///
339    /// ```rust
340    /// use rocket::Response;
341    /// use rocket::http::{Status, ContentType};
342    ///
343    /// let base = Response::build()
344    ///     .status(Status::NotFound)
345    ///     .header(ContentType::HTML)
346    ///     .raw_header("X-Custom", "value 1")
347    ///     .finalize();
348    ///
349    /// let response = Response::build()
350    ///     .status(Status::ImATeapot)
351    ///     .raw_header("X-Custom", "value 2")
352    ///     .raw_header_adjoin("X-Custom", "value 3")
353    ///     .merge(base)
354    ///     .finalize();
355    ///
356    /// assert_eq!(response.status(), Status::NotFound);
357    ///
358    /// let ctype: Vec<_> = response.headers().get("Content-Type").collect();
359    /// assert_eq!(ctype, vec![ContentType::HTML.to_string()]);
360    ///
361    /// let custom_values: Vec<_> = response.headers().get("X-Custom").collect();
362    /// assert_eq!(custom_values, vec!["value 1"]);
363    /// ```
364    #[inline(always)]
365    pub fn merge(&mut self, other: Response<'r>) -> &mut Builder<'r> {
366        self.response.merge(other);
367        self
368    }
369
370    /// Joins the `other` `Response` into `self` by setting any fields in `self`
371    /// to the corresponding value in `other` if they are set in `self`. Fields
372    /// in `self` are unchanged if they are already set. If a header is set in
373    /// both `self` and `other`, the values are adjoined, with the values in
374    /// `self` coming first. Headers only in `self` or `other` are set in
375    /// `self`.
376    ///
377    /// # Example
378    ///
379    /// ```rust
380    /// use rocket::Response;
381    /// use rocket::http::{Status, ContentType};
382    ///
383    /// let other = Response::build()
384    ///     .status(Status::NotFound)
385    ///     .header(ContentType::HTML)
386    ///     .raw_header("X-Custom", "value 1")
387    ///     .finalize();
388    ///
389    /// let response = Response::build()
390    ///     .status(Status::ImATeapot)
391    ///     .raw_header("X-Custom", "value 2")
392    ///     .raw_header_adjoin("X-Custom", "value 3")
393    ///     .join(other)
394    ///     .finalize();
395    ///
396    /// assert_eq!(response.status(), Status::ImATeapot);
397    ///
398    /// let ctype: Vec<_> = response.headers().get("Content-Type").collect();
399    /// assert_eq!(ctype, vec![ContentType::HTML.to_string()]);
400    ///
401    /// let custom_values: Vec<_> = response.headers().get("X-Custom").collect();
402    /// assert_eq!(custom_values, vec!["value 2", "value 3", "value 1"]);
403    /// ```
404    #[inline(always)]
405    pub fn join(&mut self, other: Response<'r>) -> &mut Builder<'r> {
406        self.response.join(other);
407        self
408    }
409
410    /// Return the `Response` structure that was being built by this builder.
411    /// After calling this method, `self` is cleared and must be rebuilt as if
412    /// from `new()`.
413    ///
414    /// # Example
415    ///
416    /// ```rust
417    /// use std::io::Cursor;
418    ///
419    /// use rocket::Response;
420    /// use rocket::http::Status;
421    ///
422    /// let body = "Brewing the best coffee!";
423    /// let response = Response::build()
424    ///     .status(Status::ImATeapot)
425    ///     .sized_body(body.len(), Cursor::new(body))
426    ///     .raw_header("X-Custom", "value 2")
427    ///     .finalize();
428    /// ```
429    pub fn finalize(&mut self) -> Response<'r> {
430        std::mem::replace(&mut self.response, Response::new())
431    }
432
433    /// Retrieve the built `Response` wrapped in `Ok`. After calling this
434    /// method, `self` is cleared and must be rebuilt as if from `new()`.
435    ///
436    /// # Example
437    ///
438    /// ```rust
439    /// use rocket::Response;
440    ///
441    /// let response: Result<Response, ()> = Response::build()
442    ///     // build the response
443    ///     .ok();
444    ///
445    /// assert!(response.is_ok());
446    /// ```
447    #[inline(always)]
448    pub fn ok<E>(&mut self) -> Result<Response<'r>, E> {
449        Ok(self.finalize())
450    }
451}
452
453/// A response, as returned by types implementing
454/// [`Responder`](crate::response::Responder).
455///
456/// See [`Builder`] for docs on how a `Response` is typically created and the
457/// [module docs](crate::response) for notes on composing responses
458///
459/// ## Upgrading
460///
461/// A response may optionally register [`IoHandler`]s for upgraded requests via
462/// [`Response::add_upgrade()`] or the corresponding builder method
463/// [`Builder::upgrade()`]. If the incoming request 1) requests an upgrade via a
464/// `Connection: Upgrade` header _and_ 2) includes a protocol in its `Upgrade`
465/// header that is registered by the returned `Response`, the connection will be
466/// upgraded. An upgrade response is sent to the client, and the registered
467/// `IoHandler` for the client's preferred protocol is invoked with an
468/// [`IoStream`](crate::data::IoStream) representing a raw byte stream to the
469/// client. Note that protocol names are treated case-insensitively during
470/// matching.
471///
472/// If a connection is upgraded, Rocket automatically set the following in the
473/// upgrade response:
474///   * The response status to `101 Switching Protocols`.
475///   * The `Connection: Upgrade` header.
476///   * The `Upgrade` header's value to the selected protocol.
477///
478/// As such, a response **should never** set a `101` status nor the `Connection`
479/// or `Upgrade` headers: Rocket handles this automatically. Instead, it should
480/// set a status and headers to use in case the connection is not upgraded,
481/// either due to an error or because the client did not request an upgrade.
482///
483/// If a connection _is not_ upgraded due to an error, even though there was a
484/// matching, registered protocol, the `IoHandler` is not invoked, and the
485/// original response is sent to the client without alteration.
486#[derive(Default)]
487pub struct Response<'r> {
488    status: Option<Status>,
489    headers: HeaderMap<'r>,
490    body: Body<'r>,
491    upgrade: HashMap<Uncased<'r>, Pin<Box<dyn IoHandler + 'r>>>,
492}
493
494impl<'r> Response<'r> {
495    /// Creates a new, empty `Response` without a status, body, or headers.
496    /// Because all HTTP responses must have a status, if a default `Response`
497    /// is written to the client without a status, the status defaults to `200
498    /// Ok`.
499    ///
500    /// # Example
501    ///
502    /// ```rust
503    /// use rocket::Response;
504    /// use rocket::http::Status;
505    ///
506    /// let mut response = Response::new();
507    ///
508    /// assert_eq!(response.status(), Status::Ok);
509    /// assert_eq!(response.headers().len(), 0);
510    /// assert!(response.body().is_none());
511    /// ```
512    #[inline(always)]
513    pub fn new() -> Response<'r> {
514        Response::default()
515    }
516
517    /// Returns a `Builder` with a base of `Response::new()`.
518    ///
519    /// # Example
520    ///
521    /// ```rust
522    /// use rocket::Response;
523    ///
524    /// # #[allow(unused_variables)]
525    /// let builder = Response::build();
526    /// ```
527    #[inline(always)]
528    pub fn build() -> Builder<'r> {
529        Response::build_from(Response::new())
530    }
531
532    /// Returns a `Builder` with a base of `other`.
533    ///
534    /// # Example
535    ///
536    /// ```rust
537    /// # #![allow(unused_variables)]
538    /// use rocket::Response;
539    ///
540    /// let other = Response::new();
541    /// let builder = Response::build_from(other);
542    /// ```
543    #[inline(always)]
544    pub fn build_from(other: Response<'r>) -> Builder<'r> {
545        Builder::new(other)
546    }
547
548    /// Returns the status of `self`.
549    ///
550    /// # Example
551    ///
552    /// ```rust
553    /// use rocket::Response;
554    /// use rocket::http::Status;
555    ///
556    /// let mut response = Response::new();
557    /// assert_eq!(response.status(), Status::Ok);
558    ///
559    /// response.set_status(Status::NotFound);
560    /// assert_eq!(response.status(), Status::NotFound);
561    /// ```
562    #[inline(always)]
563    pub fn status(&self) -> Status {
564        self.status.unwrap_or(Status::Ok)
565    }
566
567    /// Sets the status of `self` to `status`.
568    ///
569    /// # Example
570    ///
571    /// ```rust
572    /// use rocket::Response;
573    /// use rocket::http::Status;
574    ///
575    /// let mut response = Response::new();
576    /// response.set_status(Status::ImATeapot);
577    /// assert_eq!(response.status(), Status::ImATeapot);
578    /// ```
579    #[inline(always)]
580    pub fn set_status(&mut self, status: Status) {
581        self.status = Some(status);
582    }
583
584    /// Returns the Content-Type header of `self`. If the header is not present
585    /// or is malformed, returns `None`.
586    ///
587    /// # Example
588    ///
589    /// ```rust
590    /// use rocket::Response;
591    /// use rocket::http::ContentType;
592    ///
593    /// let mut response = Response::new();
594    /// response.set_header(ContentType::HTML);
595    /// assert_eq!(response.content_type(), Some(ContentType::HTML));
596    /// ```
597    #[inline(always)]
598    pub fn content_type(&self) -> Option<ContentType> {
599        self.headers().get_one("Content-Type").and_then(|v| v.parse().ok())
600    }
601
602    /// Returns an iterator over the cookies in `self` as identified by the
603    /// `Set-Cookie` header. Malformed cookies are skipped.
604    ///
605    /// # Example
606    ///
607    /// ```rust
608    /// use rocket::Response;
609    /// use rocket::http::Cookie;
610    ///
611    /// let mut response = Response::new();
612    /// response.set_header(Cookie::new("hello", "world!"));
613    /// let cookies: Vec<_> = response.cookies().collect();
614    /// assert_eq!(cookies, vec![Cookie::new("hello", "world!")]);
615    /// ```
616    pub fn cookies(&self) -> impl Iterator<Item = Cookie<'_>> {
617        self.headers()
618            .get("Set-Cookie")
619            .filter_map(|header| Cookie::parse_encoded(header).ok())
620    }
621
622    /// Returns a [`HeaderMap`] of all of the headers in `self`.
623    ///
624    /// # Example
625    ///
626    /// ```rust
627    /// use rocket::Response;
628    /// use rocket::http::Header;
629    ///
630    /// let mut response = Response::new();
631    /// response.adjoin_raw_header("X-Custom", "1");
632    /// response.adjoin_raw_header("X-Custom", "2");
633    ///
634    /// let mut custom_headers = response.headers().iter();
635    /// assert_eq!(custom_headers.next(), Some(Header::new("X-Custom", "1")));
636    /// assert_eq!(custom_headers.next(), Some(Header::new("X-Custom", "2")));
637    /// assert_eq!(custom_headers.next(), None);
638    /// ```
639    #[inline(always)]
640    pub fn headers(&self) -> &HeaderMap<'r> {
641        &self.headers
642    }
643
644    /// Sets the header `header` in `self`. Any existing headers with the name
645    /// `header.name` will be lost, and only `header` will remain. The type of
646    /// `header` can be any type that implements `Into<Header>`. This includes
647    /// `Header` itself, [`ContentType`](crate::http::ContentType) and
648    /// [`hyper::header` types](crate::http::hyper::header).
649    ///
650    /// # Example
651    ///
652    /// ```rust
653    /// use rocket::Response;
654    /// use rocket::http::ContentType;
655    ///
656    /// let mut response = Response::new();
657    ///
658    /// response.set_header(ContentType::HTML);
659    /// assert_eq!(response.headers().iter().next(), Some(ContentType::HTML.into()));
660    /// assert_eq!(response.headers().len(), 1);
661    ///
662    /// response.set_header(ContentType::JSON);
663    /// assert_eq!(response.headers().iter().next(), Some(ContentType::JSON.into()));
664    /// assert_eq!(response.headers().len(), 1);
665    /// ```
666    #[inline(always)]
667    pub fn set_header<'h: 'r, H: Into<Header<'h>>>(&mut self, header: H) -> bool {
668        self.headers.replace(header)
669    }
670
671    /// Sets the custom header with name `name` and value `value` in `self`. Any
672    /// existing headers with the same `name` will be lost, and the new custom
673    /// header will remain. This method should be used sparingly; prefer to use
674    /// [set_header](#method.set_header) instead.
675    ///
676    /// # Example
677    ///
678    /// ```rust
679    /// use rocket::Response;
680    /// use rocket::http::Header;
681    ///
682    /// let mut response = Response::new();
683    ///
684    /// response.set_raw_header("X-Custom", "1");
685    /// assert_eq!(response.headers().get_one("X-Custom"), Some("1"));
686    /// assert_eq!(response.headers().len(), 1);
687    ///
688    /// response.set_raw_header("X-Custom", "2");
689    /// assert_eq!(response.headers().get_one("X-Custom"), Some("2"));
690    /// assert_eq!(response.headers().len(), 1);
691    /// ```
692    #[inline(always)]
693    pub fn set_raw_header<'a: 'r, 'b: 'r, N, V>(&mut self, name: N, value: V) -> bool
694        where N: Into<Cow<'a, str>>, V: Into<Cow<'b, str>>
695    {
696        self.set_header(Header::new(name, value))
697    }
698
699    /// Adds the header `header` to `self`. If `self` contains headers with the
700    /// name `header.name`, another header with the same name and value
701    /// `header.value` is added. The type of `header` can be any type that
702    /// implements `Into<Header>`. This includes `Header` itself,
703    /// [`ContentType`](crate::http::ContentType) and [`hyper::header`
704    /// types](crate::http::hyper::header).
705    ///
706    /// # Example
707    ///
708    /// ```rust
709    /// use rocket::Response;
710    /// use rocket::http::Header;
711    /// use rocket::http::hyper::header::ACCEPT;
712    ///
713    /// let mut response = Response::new();
714    /// response.adjoin_header(Header::new(ACCEPT.as_str(), "application/json"));
715    /// response.adjoin_header(Header::new(ACCEPT.as_str(), "text/plain"));
716    ///
717    /// let mut accept_headers = response.headers().iter();
718    /// assert_eq!(accept_headers.next(), Some(Header::new(ACCEPT.as_str(), "application/json")));
719    /// assert_eq!(accept_headers.next(), Some(Header::new(ACCEPT.as_str(), "text/plain")));
720    /// assert_eq!(accept_headers.next(), None);
721    /// ```
722    #[inline(always)]
723    pub fn adjoin_header<'h: 'r, H: Into<Header<'h>>>(&mut self, header: H) {
724        self.headers.add(header)
725    }
726
727    /// Adds a custom header with name `name` and value `value` to `self`. If
728    /// `self` already contains headers with the name `name`, another header
729    /// with the same `name` and `value` is added. The type of `header` can be
730    /// any type implements `Into<Header>`. This includes `Header` itself,
731    /// [`ContentType`](crate::http::ContentType) and [`hyper::header`
732    /// types](crate::http::hyper::header).
733    ///
734    /// # Example
735    ///
736    /// ```rust
737    /// use rocket::Response;
738    /// use rocket::http::Header;
739    ///
740    /// let mut response = Response::new();
741    /// response.adjoin_raw_header("X-Custom", "one");
742    /// response.adjoin_raw_header("X-Custom", "two");
743    ///
744    /// let mut custom_headers = response.headers().iter();
745    /// assert_eq!(custom_headers.next(), Some(Header::new("X-Custom", "one")));
746    /// assert_eq!(custom_headers.next(), Some(Header::new("X-Custom", "two")));
747    /// assert_eq!(custom_headers.next(), None);
748    /// ```
749    #[inline(always)]
750    pub fn adjoin_raw_header<'a: 'r, 'b: 'r, N, V>(&mut self, name: N, value: V)
751        where N: Into<Cow<'a, str>>, V: Into<Cow<'b, str>>
752    {
753        self.adjoin_header(Header::new(name, value));
754    }
755
756    /// Removes all headers with the name `name`.
757    ///
758    /// # Example
759    ///
760    /// ```rust
761    /// use rocket::Response;
762    ///
763    /// let mut response = Response::new();
764    ///
765    /// response.adjoin_raw_header("X-Custom", "one");
766    /// response.adjoin_raw_header("X-Custom", "two");
767    /// response.adjoin_raw_header("X-Other", "hi");
768    /// assert_eq!(response.headers().len(), 3);
769    ///
770    /// response.remove_header("X-Custom");
771    /// assert_eq!(response.headers().len(), 1);
772    /// ```
773    #[inline(always)]
774    pub fn remove_header(&mut self, name: &str) {
775        self.headers.remove(name);
776    }
777
778    /// Returns an immutable borrow of the body of `self`, if there is one.
779    ///
780    /// # Example
781    ///
782    /// ```rust
783    /// use std::io::Cursor;
784    /// use rocket::Response;
785    ///
786    /// # rocket::async_test(async {
787    /// let mut response = Response::new();
788    /// assert!(response.body().is_none());
789    ///
790    /// let string = "Hello, world!";
791    /// response.set_sized_body(string.len(), Cursor::new(string));
792    /// assert!(response.body().is_some());
793    /// # })
794    /// ```
795    #[inline(always)]
796    pub fn body(&self) -> &Body<'r> {
797        &self.body
798    }
799
800    /// Returns `Ok(Some(_))` if `self` contains a suitable handler for any of
801    /// the comma-separated protocols any of the strings in `I`. Returns
802    /// `Ok(None)` if `self` doesn't support any kind of upgrade. Returns
803    /// `Err(_)` if `protocols` is non-empty but no match was found in `self`.
804    pub(crate) fn take_upgrade<I: Iterator<Item = &'r str>>(
805        &mut self,
806        protocols: I
807    ) -> Result<Option<(Uncased<'r>, Pin<Box<dyn IoHandler + 'r>>)>, ()> {
808        if self.upgrade.is_empty() {
809            return Ok(None);
810        }
811
812        let mut protocols = protocols.peekable();
813        let have_protocols = protocols.peek().is_some();
814        let found = protocols
815            .flat_map(|v| v.split(',').map(str::trim))
816            .find_map(|p| self.upgrade.remove_entry(p.as_uncased()));
817
818        match found {
819            Some(handler) => Ok(Some(handler)),
820            None if have_protocols => Err(()),
821            None => Ok(None)
822        }
823    }
824
825    /// Returns the [`IoHandler`] for the protocol `proto`.
826    ///
827    /// Returns `Some` if such a handler was registered via
828    /// [`Response::add_upgrade()`] or the corresponding builder method
829    /// [`upgrade()`](Builder::upgrade()). Otherwise returns `None`.
830    ///
831    /// ```rust
832    /// use std::pin::Pin;
833    ///
834    /// use rocket::Response;
835    /// use rocket::data::{IoHandler, IoStream};
836    /// use rocket::tokio::io;
837    ///
838    /// struct EchoHandler;
839    ///
840    /// #[rocket::async_trait]
841    /// impl IoHandler for EchoHandler {
842    ///     async fn io(self: Pin<Box<Self>>, io: IoStream) -> io::Result<()> {
843    ///         let (mut reader, mut writer) = io::split(io);
844    ///         io::copy(&mut reader, &mut writer).await?;
845    ///         Ok(())
846    ///     }
847    /// }
848    ///
849    /// # rocket::async_test(async {
850    /// let mut response = Response::new();
851    /// assert!(response.upgrade("raw-echo").is_none());
852    ///
853    /// response.add_upgrade("raw-echo", EchoHandler);
854    /// assert!(response.upgrade("raw-echo").is_some());
855    /// # })
856    /// ```
857    pub fn upgrade(&mut self, proto: &str) -> Option<Pin<&mut (dyn IoHandler + 'r)>> {
858        self.upgrade.get_mut(proto.as_uncased()).map(|h| h.as_mut())
859    }
860
861    /// Returns a mutable borrow of the body of `self`, if there is one. A
862    /// mutable borrow allows for reading the body.
863    ///
864    /// # Example
865    ///
866    /// ```rust
867    /// use std::io::Cursor;
868    /// use rocket::Response;
869    ///
870    /// # rocket::async_test(async {
871    /// let mut response = Response::new();
872    /// assert!(response.body().is_none());
873    ///
874    /// let string = "Hello, world!";
875    /// response.set_sized_body(string.len(), Cursor::new(string));
876    /// let string = response.body_mut().to_string().await;
877    /// assert_eq!(string.unwrap(), "Hello, world!");
878    /// # })
879    /// ```
880    #[inline(always)]
881    pub fn body_mut(&mut self) -> &mut Body<'r> {
882        &mut self.body
883    }
884
885    // Makes the `AsyncRead`er in the body empty but leaves the size of the body
886    // if it exists. Meant to be used during HEAD handling.
887    #[inline(always)]
888    pub(crate) fn strip_body(&mut self) {
889        self.body.strip();
890    }
891
892    /// Sets the body of `self` to be the fixed-sized `body` with size
893    /// `size`, which may be `None`. If `size` is `None`, the body's size will
894    /// be computing with calls to `seek` just before being written out in a
895    /// response.
896    ///
897    /// # Example
898    ///
899    /// ```rust
900    /// use std::io;
901    /// use rocket::Response;
902    ///
903    /// # let o: io::Result<()> = rocket::async_test(async {
904    /// let string = "Hello, world!";
905    ///
906    /// let mut response = Response::new();
907    /// response.set_sized_body(string.len(), io::Cursor::new(string));
908    /// assert_eq!(response.body_mut().to_string().await?, "Hello, world!");
909    /// # Ok(())
910    /// # });
911    /// # assert!(o.is_ok());
912    /// ```
913    pub fn set_sized_body<B, S>(&mut self, size: S, body: B)
914        where B: AsyncRead + AsyncSeek + Send + 'r,
915              S: Into<Option<usize>>
916    {
917        self.body = Body::with_sized(body, size.into());
918    }
919
920    /// Sets the body of `self` to `body`, which will be streamed.
921    ///
922    /// The max chunk size is configured via [`Response::set_max_chunk_size()`]
923    /// and defaults to [`Body::DEFAULT_MAX_CHUNK`].
924    ///
925    /// # Example
926    ///
927    /// ```rust
928    /// # use std::io;
929    /// use tokio::io::{repeat, AsyncReadExt};
930    /// use rocket::Response;
931    ///
932    /// # let o: io::Result<()> = rocket::async_test(async {
933    /// let mut response = Response::new();
934    /// response.set_streamed_body(repeat(97).take(5));
935    /// assert_eq!(response.body_mut().to_string().await?, "aaaaa");
936    /// # Ok(())
937    /// # });
938    /// # assert!(o.is_ok());
939    /// ```
940    #[inline(always)]
941    pub fn set_streamed_body<B>(&mut self, body: B)
942        where B: AsyncRead + Send + 'r
943    {
944        self.body = Body::with_unsized(body);
945    }
946
947    /// Registers `handler` as the I/O handler for upgrade protocol `protocol`.
948    ///
949    /// Responses registering I/O handlers for upgraded protocols **should not**
950    /// set the response status to `101`, nor set the `Connection` or `Upgrade`
951    /// headers. Rocket automatically sets these headers as needed. See
952    /// [`Response`#upgrading] for details.
953    ///
954    /// If a handler was previously registered for `protocol`, this `handler`
955    /// replaces it. If the connection is upgraded to `protocol`, the last
956    /// `handler` registered for the protocol is used to handle the connection.
957    /// See [`IoHandler`] for details on implementing an I/O handler. For
958    /// details on connection upgrading, see [`Response`#upgrading].
959    ///
960    /// [`Response`#upgrading]: Response#upgrading
961    ///
962    /// # Example
963    ///
964    /// ```rust
965    /// use std::pin::Pin;
966    ///
967    /// use rocket::Response;
968    /// use rocket::data::{IoHandler, IoStream};
969    /// use rocket::tokio::io;
970    ///
971    /// struct EchoHandler;
972    ///
973    /// #[rocket::async_trait]
974    /// impl IoHandler for EchoHandler {
975    ///     async fn io(self: Pin<Box<Self>>, io: IoStream) -> io::Result<()> {
976    ///         let (mut reader, mut writer) = io::split(io);
977    ///         io::copy(&mut reader, &mut writer).await?;
978    ///         Ok(())
979    ///     }
980    /// }
981    ///
982    /// # rocket::async_test(async {
983    /// let mut response = Response::new();
984    /// assert!(response.upgrade("raw-echo").is_none());
985    ///
986    /// response.add_upgrade("raw-echo", EchoHandler);
987    /// assert!(response.upgrade("raw-echo").is_some());
988    /// # })
989    /// ```
990    pub fn add_upgrade<N, H>(&mut self, protocol: N, handler: H)
991        where N: Into<Uncased<'r>>, H: IoHandler + 'r
992    {
993        self.upgrade.insert(protocol.into(), Box::pin(handler));
994    }
995
996    /// Sets the body's maximum chunk size to `size` bytes.
997    ///
998    /// The default max chunk size is [`Body::DEFAULT_MAX_CHUNK`]. The max chunk
999    /// size is a property of the body and is thus reset whenever a body is set
1000    /// via [`Response::set_streamed_body()`], [`Response::set_sized_body()`],
1001    /// or the corresponding builder methods.
1002    ///
1003    /// This setting does not typically need to be changed. Configuring a high
1004    /// value can result in high memory usage. Similarly, configuring a low
1005    /// value can result in excessive network writes. When unsure, leave the
1006    /// value unchanged.
1007    ///
1008    /// # Example
1009    ///
1010    /// ```rust
1011    /// use tokio::io::{repeat, AsyncReadExt};
1012    /// use rocket::Response;
1013    ///
1014    /// # let o: Option<()> = rocket::async_test(async {
1015    /// let mut response = Response::new();
1016    /// response.set_streamed_body(repeat(97).take(5));
1017    /// response.set_max_chunk_size(3072);
1018    /// # Some(())
1019    /// # });
1020    /// # assert!(o.is_some());
1021    #[inline(always)]
1022    pub fn set_max_chunk_size(&mut self, size: usize) {
1023        self.body_mut().set_max_chunk_size(size);
1024    }
1025
1026    /// Replaces this response's status and body with that of `other`, if they
1027    /// exist in `other`. Any headers that exist in `other` replace the ones in
1028    /// `self`. Any in `self` that aren't in `other` remain in `self`.
1029    ///
1030    /// # Example
1031    ///
1032    /// ```rust
1033    /// use rocket::Response;
1034    /// use rocket::http::{Status, ContentType};
1035    ///
1036    /// let base = Response::build()
1037    ///     .status(Status::NotFound)
1038    ///     .header(ContentType::HTML)
1039    ///     .raw_header("X-Custom", "value 1")
1040    ///     .finalize();
1041    ///
1042    /// let response = Response::build()
1043    ///     .status(Status::ImATeapot)
1044    ///     .raw_header("X-Custom", "value 2")
1045    ///     .raw_header_adjoin("X-Custom", "value 3")
1046    ///     .merge(base)
1047    ///     .finalize();
1048    ///
1049    /// assert_eq!(response.status(), Status::NotFound);
1050    ///
1051    /// let ctype: Vec<_> = response.headers().get("Content-Type").collect();
1052    /// assert_eq!(ctype, vec![ContentType::HTML.to_string()]);
1053    ///
1054    /// let custom_values: Vec<_> = response.headers().get("X-Custom").collect();
1055    /// assert_eq!(custom_values, vec!["value 1"]);
1056    /// ```
1057    pub fn merge(&mut self, other: Response<'r>) {
1058        if let Some(status) = other.status {
1059            self.status = Some(status);
1060        }
1061
1062        if other.body().is_some() {
1063            self.body = other.body;
1064        }
1065
1066        for (name, values) in other.headers.into_iter_raw() {
1067            self.headers.replace_all(name.into_cow(), values);
1068        }
1069    }
1070
1071    /// Sets `self`'s status and body to that of `other` if they are not already
1072    /// set in `self`. Any headers present in both `other` and `self` are
1073    /// adjoined.
1074    ///
1075    /// # Example
1076    ///
1077    /// ```rust
1078    /// use rocket::Response;
1079    /// use rocket::http::{Status, ContentType};
1080    ///
1081    /// let other = Response::build()
1082    ///     .status(Status::NotFound)
1083    ///     .header(ContentType::HTML)
1084    ///     .raw_header("X-Custom", "value 1")
1085    ///     .finalize();
1086    ///
1087    /// let response = Response::build()
1088    ///     .status(Status::ImATeapot)
1089    ///     .raw_header("X-Custom", "value 2")
1090    ///     .raw_header_adjoin("X-Custom", "value 3")
1091    ///     .join(other)
1092    ///     .finalize();
1093    ///
1094    /// assert_eq!(response.status(), Status::ImATeapot);
1095    ///
1096    /// let ctype: Vec<_> = response.headers().get("Content-Type").collect();
1097    /// assert_eq!(ctype, vec![ContentType::HTML.to_string()]);
1098    ///
1099    /// let custom_values: Vec<_> = response.headers().get("X-Custom").collect();
1100    /// assert_eq!(custom_values, vec!["value 2", "value 3", "value 1"]);
1101    /// ```
1102    pub fn join(&mut self, other: Response<'r>) {
1103        if self.status.is_none() {
1104            self.status = other.status;
1105        }
1106
1107        if self.body.is_none() {
1108            self.body = other.body;
1109        }
1110
1111        for (name, mut values) in other.headers.into_iter_raw() {
1112            self.headers.add_all(name.into_cow(), &mut values);
1113        }
1114    }
1115}
1116
1117impl fmt::Debug for Response<'_> {
1118    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1119        writeln!(f, "{}", self.status())?;
1120
1121        for header in self.headers().iter() {
1122            writeln!(f, "{}", header)?;
1123        }
1124
1125        self.body.fmt(f)
1126    }
1127}