| 1 | //! HTTP response types. |
| 2 | //! |
| 3 | //! This module contains structs related to HTTP responses, notably the |
| 4 | //! `Response` type itself as well as a builder to create responses. Typically |
| 5 | //! you'll import the `http::Response` type rather than reaching into this |
| 6 | //! module itself. |
| 7 | //! |
| 8 | //! # Examples |
| 9 | //! |
| 10 | //! Creating a `Response` to return |
| 11 | //! |
| 12 | //! ``` |
| 13 | //! use http::{Request, Response, StatusCode}; |
| 14 | //! |
| 15 | //! fn respond_to(req: Request<()>) -> http::Result<Response<()>> { |
| 16 | //! let mut builder = Response::builder() |
| 17 | //! .header("Foo" , "Bar" ) |
| 18 | //! .status(StatusCode::OK); |
| 19 | //! |
| 20 | //! if req.headers().contains_key("Another-Header" ) { |
| 21 | //! builder = builder.header("Another-Header" , "Ack" ); |
| 22 | //! } |
| 23 | //! |
| 24 | //! builder.body(()) |
| 25 | //! } |
| 26 | //! ``` |
| 27 | //! |
| 28 | //! A simple 404 handler |
| 29 | //! |
| 30 | //! ``` |
| 31 | //! use http::{Request, Response, StatusCode}; |
| 32 | //! |
| 33 | //! fn not_found(_req: Request<()>) -> http::Result<Response<()>> { |
| 34 | //! Response::builder() |
| 35 | //! .status(StatusCode::NOT_FOUND) |
| 36 | //! .body(()) |
| 37 | //! } |
| 38 | //! ``` |
| 39 | //! |
| 40 | //! Or otherwise inspecting the result of a request: |
| 41 | //! |
| 42 | //! ```no_run |
| 43 | //! use http::{Request, Response}; |
| 44 | //! |
| 45 | //! fn get(url: &str) -> http::Result<Response<()>> { |
| 46 | //! // ... |
| 47 | //! # panic!() |
| 48 | //! } |
| 49 | //! |
| 50 | //! let response = get("https://www.rust-lang.org/" ).unwrap(); |
| 51 | //! |
| 52 | //! if !response.status().is_success() { |
| 53 | //! panic!("failed to get a successful response status!" ); |
| 54 | //! } |
| 55 | //! |
| 56 | //! if let Some(date) = response.headers().get("Date" ) { |
| 57 | //! // we've got a `Date` header! |
| 58 | //! } |
| 59 | //! |
| 60 | //! let body = response.body(); |
| 61 | //! // ... |
| 62 | //! ``` |
| 63 | |
| 64 | use std::any::Any; |
| 65 | use std::convert::TryFrom; |
| 66 | use std::fmt; |
| 67 | |
| 68 | use crate::header::{HeaderMap, HeaderName, HeaderValue}; |
| 69 | use crate::status::StatusCode; |
| 70 | use crate::version::Version; |
| 71 | use crate::{Extensions, Result}; |
| 72 | |
| 73 | /// Represents an HTTP response |
| 74 | /// |
| 75 | /// An HTTP response consists of a head and a potentially optional body. The body |
| 76 | /// component is generic, enabling arbitrary types to represent the HTTP body. |
| 77 | /// For example, the body could be `Vec<u8>`, a `Stream` of byte chunks, or a |
| 78 | /// value that has been deserialized. |
| 79 | /// |
| 80 | /// Typically you'll work with responses on the client side as the result of |
| 81 | /// sending a `Request` and on the server you'll be generating a `Response` to |
| 82 | /// send back to the client. |
| 83 | /// |
| 84 | /// # Examples |
| 85 | /// |
| 86 | /// Creating a `Response` to return |
| 87 | /// |
| 88 | /// ``` |
| 89 | /// use http::{Request, Response, StatusCode}; |
| 90 | /// |
| 91 | /// fn respond_to(req: Request<()>) -> http::Result<Response<()>> { |
| 92 | /// let mut builder = Response::builder() |
| 93 | /// .header("Foo" , "Bar" ) |
| 94 | /// .status(StatusCode::OK); |
| 95 | /// |
| 96 | /// if req.headers().contains_key("Another-Header" ) { |
| 97 | /// builder = builder.header("Another-Header" , "Ack" ); |
| 98 | /// } |
| 99 | /// |
| 100 | /// builder.body(()) |
| 101 | /// } |
| 102 | /// ``` |
| 103 | /// |
| 104 | /// A simple 404 handler |
| 105 | /// |
| 106 | /// ``` |
| 107 | /// use http::{Request, Response, StatusCode}; |
| 108 | /// |
| 109 | /// fn not_found(_req: Request<()>) -> http::Result<Response<()>> { |
| 110 | /// Response::builder() |
| 111 | /// .status(StatusCode::NOT_FOUND) |
| 112 | /// .body(()) |
| 113 | /// } |
| 114 | /// ``` |
| 115 | /// |
| 116 | /// Or otherwise inspecting the result of a request: |
| 117 | /// |
| 118 | /// ```no_run |
| 119 | /// use http::{Request, Response}; |
| 120 | /// |
| 121 | /// fn get(url: &str) -> http::Result<Response<()>> { |
| 122 | /// // ... |
| 123 | /// # panic!() |
| 124 | /// } |
| 125 | /// |
| 126 | /// let response = get("https://www.rust-lang.org/" ).unwrap(); |
| 127 | /// |
| 128 | /// if !response.status().is_success() { |
| 129 | /// panic!("failed to get a successful response status!" ); |
| 130 | /// } |
| 131 | /// |
| 132 | /// if let Some(date) = response.headers().get("Date" ) { |
| 133 | /// // we've got a `Date` header! |
| 134 | /// } |
| 135 | /// |
| 136 | /// let body = response.body(); |
| 137 | /// // ... |
| 138 | /// ``` |
| 139 | /// |
| 140 | /// Deserialize a response of bytes via json: |
| 141 | /// |
| 142 | /// ``` |
| 143 | /// # extern crate serde; |
| 144 | /// # extern crate serde_json; |
| 145 | /// # extern crate http; |
| 146 | /// use http::Response; |
| 147 | /// use serde::de; |
| 148 | /// |
| 149 | /// fn deserialize<T>(res: Response<Vec<u8>>) -> serde_json::Result<Response<T>> |
| 150 | /// where for<'de> T: de::Deserialize<'de>, |
| 151 | /// { |
| 152 | /// let (parts, body) = res.into_parts(); |
| 153 | /// let body = serde_json::from_slice(&body)?; |
| 154 | /// Ok(Response::from_parts(parts, body)) |
| 155 | /// } |
| 156 | /// # |
| 157 | /// # fn main() {} |
| 158 | /// ``` |
| 159 | /// |
| 160 | /// Or alternatively, serialize the body of a response to json |
| 161 | /// |
| 162 | /// ``` |
| 163 | /// # extern crate serde; |
| 164 | /// # extern crate serde_json; |
| 165 | /// # extern crate http; |
| 166 | /// use http::Response; |
| 167 | /// use serde::ser; |
| 168 | /// |
| 169 | /// fn serialize<T>(res: Response<T>) -> serde_json::Result<Response<Vec<u8>>> |
| 170 | /// where T: ser::Serialize, |
| 171 | /// { |
| 172 | /// let (parts, body) = res.into_parts(); |
| 173 | /// let body = serde_json::to_vec(&body)?; |
| 174 | /// Ok(Response::from_parts(parts, body)) |
| 175 | /// } |
| 176 | /// # |
| 177 | /// # fn main() {} |
| 178 | /// ``` |
| 179 | pub struct Response<T> { |
| 180 | head: Parts, |
| 181 | body: T, |
| 182 | } |
| 183 | |
| 184 | /// Component parts of an HTTP `Response` |
| 185 | /// |
| 186 | /// The HTTP response head consists of a status, version, and a set of |
| 187 | /// header fields. |
| 188 | pub struct Parts { |
| 189 | /// The response's status |
| 190 | pub status: StatusCode, |
| 191 | |
| 192 | /// The response's version |
| 193 | pub version: Version, |
| 194 | |
| 195 | /// The response's headers |
| 196 | pub headers: HeaderMap<HeaderValue>, |
| 197 | |
| 198 | /// The response's extensions |
| 199 | pub extensions: Extensions, |
| 200 | |
| 201 | _priv: (), |
| 202 | } |
| 203 | |
| 204 | /// An HTTP response builder |
| 205 | /// |
| 206 | /// This type can be used to construct an instance of `Response` through a |
| 207 | /// builder-like pattern. |
| 208 | #[derive(Debug)] |
| 209 | pub struct Builder { |
| 210 | inner: Result<Parts>, |
| 211 | } |
| 212 | |
| 213 | impl Response<()> { |
| 214 | /// Creates a new builder-style object to manufacture a `Response` |
| 215 | /// |
| 216 | /// This method returns an instance of `Builder` which can be used to |
| 217 | /// create a `Response`. |
| 218 | /// |
| 219 | /// # Examples |
| 220 | /// |
| 221 | /// ``` |
| 222 | /// # use http::*; |
| 223 | /// let response = Response::builder() |
| 224 | /// .status(200) |
| 225 | /// .header("X-Custom-Foo" , "Bar" ) |
| 226 | /// .body(()) |
| 227 | /// .unwrap(); |
| 228 | /// ``` |
| 229 | #[inline ] |
| 230 | pub fn builder() -> Builder { |
| 231 | Builder::new() |
| 232 | } |
| 233 | } |
| 234 | |
| 235 | impl<T> Response<T> { |
| 236 | /// Creates a new blank `Response` with the body |
| 237 | /// |
| 238 | /// The component ports of this response will be set to their default, e.g. |
| 239 | /// the ok status, no headers, etc. |
| 240 | /// |
| 241 | /// # Examples |
| 242 | /// |
| 243 | /// ``` |
| 244 | /// # use http::*; |
| 245 | /// let response = Response::new("hello world" ); |
| 246 | /// |
| 247 | /// assert_eq!(response.status(), StatusCode::OK); |
| 248 | /// assert_eq!(*response.body(), "hello world" ); |
| 249 | /// ``` |
| 250 | #[inline ] |
| 251 | pub fn new(body: T) -> Response<T> { |
| 252 | Response { |
| 253 | head: Parts::new(), |
| 254 | body: body, |
| 255 | } |
| 256 | } |
| 257 | |
| 258 | /// Creates a new `Response` with the given head and body |
| 259 | /// |
| 260 | /// # Examples |
| 261 | /// |
| 262 | /// ``` |
| 263 | /// # use http::*; |
| 264 | /// let response = Response::new("hello world" ); |
| 265 | /// let (mut parts, body) = response.into_parts(); |
| 266 | /// |
| 267 | /// parts.status = StatusCode::BAD_REQUEST; |
| 268 | /// let response = Response::from_parts(parts, body); |
| 269 | /// |
| 270 | /// assert_eq!(response.status(), StatusCode::BAD_REQUEST); |
| 271 | /// assert_eq!(*response.body(), "hello world" ); |
| 272 | /// ``` |
| 273 | #[inline ] |
| 274 | pub fn from_parts(parts: Parts, body: T) -> Response<T> { |
| 275 | Response { |
| 276 | head: parts, |
| 277 | body: body, |
| 278 | } |
| 279 | } |
| 280 | |
| 281 | /// Returns the `StatusCode`. |
| 282 | /// |
| 283 | /// # Examples |
| 284 | /// |
| 285 | /// ``` |
| 286 | /// # use http::*; |
| 287 | /// let response: Response<()> = Response::default(); |
| 288 | /// assert_eq!(response.status(), StatusCode::OK); |
| 289 | /// ``` |
| 290 | #[inline ] |
| 291 | pub fn status(&self) -> StatusCode { |
| 292 | self.head.status |
| 293 | } |
| 294 | |
| 295 | /// Returns a mutable reference to the associated `StatusCode`. |
| 296 | /// |
| 297 | /// # Examples |
| 298 | /// |
| 299 | /// ``` |
| 300 | /// # use http::*; |
| 301 | /// let mut response: Response<()> = Response::default(); |
| 302 | /// *response.status_mut() = StatusCode::CREATED; |
| 303 | /// assert_eq!(response.status(), StatusCode::CREATED); |
| 304 | /// ``` |
| 305 | #[inline ] |
| 306 | pub fn status_mut(&mut self) -> &mut StatusCode { |
| 307 | &mut self.head.status |
| 308 | } |
| 309 | |
| 310 | /// Returns a reference to the associated version. |
| 311 | /// |
| 312 | /// # Examples |
| 313 | /// |
| 314 | /// ``` |
| 315 | /// # use http::*; |
| 316 | /// let response: Response<()> = Response::default(); |
| 317 | /// assert_eq!(response.version(), Version::HTTP_11); |
| 318 | /// ``` |
| 319 | #[inline ] |
| 320 | pub fn version(&self) -> Version { |
| 321 | self.head.version |
| 322 | } |
| 323 | |
| 324 | /// Returns a mutable reference to the associated version. |
| 325 | /// |
| 326 | /// # Examples |
| 327 | /// |
| 328 | /// ``` |
| 329 | /// # use http::*; |
| 330 | /// let mut response: Response<()> = Response::default(); |
| 331 | /// *response.version_mut() = Version::HTTP_2; |
| 332 | /// assert_eq!(response.version(), Version::HTTP_2); |
| 333 | /// ``` |
| 334 | #[inline ] |
| 335 | pub fn version_mut(&mut self) -> &mut Version { |
| 336 | &mut self.head.version |
| 337 | } |
| 338 | |
| 339 | /// Returns a reference to the associated header field map. |
| 340 | /// |
| 341 | /// # Examples |
| 342 | /// |
| 343 | /// ``` |
| 344 | /// # use http::*; |
| 345 | /// let response: Response<()> = Response::default(); |
| 346 | /// assert!(response.headers().is_empty()); |
| 347 | /// ``` |
| 348 | #[inline ] |
| 349 | pub fn headers(&self) -> &HeaderMap<HeaderValue> { |
| 350 | &self.head.headers |
| 351 | } |
| 352 | |
| 353 | /// Returns a mutable reference to the associated header field map. |
| 354 | /// |
| 355 | /// # Examples |
| 356 | /// |
| 357 | /// ``` |
| 358 | /// # use http::*; |
| 359 | /// # use http::header::*; |
| 360 | /// let mut response: Response<()> = Response::default(); |
| 361 | /// response.headers_mut().insert(HOST, HeaderValue::from_static("world" )); |
| 362 | /// assert!(!response.headers().is_empty()); |
| 363 | /// ``` |
| 364 | #[inline ] |
| 365 | pub fn headers_mut(&mut self) -> &mut HeaderMap<HeaderValue> { |
| 366 | &mut self.head.headers |
| 367 | } |
| 368 | |
| 369 | /// Returns a reference to the associated extensions. |
| 370 | /// |
| 371 | /// # Examples |
| 372 | /// |
| 373 | /// ``` |
| 374 | /// # use http::*; |
| 375 | /// let response: Response<()> = Response::default(); |
| 376 | /// assert!(response.extensions().get::<i32>().is_none()); |
| 377 | /// ``` |
| 378 | #[inline ] |
| 379 | pub fn extensions(&self) -> &Extensions { |
| 380 | &self.head.extensions |
| 381 | } |
| 382 | |
| 383 | /// Returns a mutable reference to the associated extensions. |
| 384 | /// |
| 385 | /// # Examples |
| 386 | /// |
| 387 | /// ``` |
| 388 | /// # use http::*; |
| 389 | /// # use http::header::*; |
| 390 | /// let mut response: Response<()> = Response::default(); |
| 391 | /// response.extensions_mut().insert("hello" ); |
| 392 | /// assert_eq!(response.extensions().get(), Some(&"hello" )); |
| 393 | /// ``` |
| 394 | #[inline ] |
| 395 | pub fn extensions_mut(&mut self) -> &mut Extensions { |
| 396 | &mut self.head.extensions |
| 397 | } |
| 398 | |
| 399 | /// Returns a reference to the associated HTTP body. |
| 400 | /// |
| 401 | /// # Examples |
| 402 | /// |
| 403 | /// ``` |
| 404 | /// # use http::*; |
| 405 | /// let response: Response<String> = Response::default(); |
| 406 | /// assert!(response.body().is_empty()); |
| 407 | /// ``` |
| 408 | #[inline ] |
| 409 | pub fn body(&self) -> &T { |
| 410 | &self.body |
| 411 | } |
| 412 | |
| 413 | /// Returns a mutable reference to the associated HTTP body. |
| 414 | /// |
| 415 | /// # Examples |
| 416 | /// |
| 417 | /// ``` |
| 418 | /// # use http::*; |
| 419 | /// let mut response: Response<String> = Response::default(); |
| 420 | /// response.body_mut().push_str("hello world" ); |
| 421 | /// assert!(!response.body().is_empty()); |
| 422 | /// ``` |
| 423 | #[inline ] |
| 424 | pub fn body_mut(&mut self) -> &mut T { |
| 425 | &mut self.body |
| 426 | } |
| 427 | |
| 428 | /// Consumes the response, returning just the body. |
| 429 | /// |
| 430 | /// # Examples |
| 431 | /// |
| 432 | /// ``` |
| 433 | /// # use http::Response; |
| 434 | /// let response = Response::new(10); |
| 435 | /// let body = response.into_body(); |
| 436 | /// assert_eq!(body, 10); |
| 437 | /// ``` |
| 438 | #[inline ] |
| 439 | pub fn into_body(self) -> T { |
| 440 | self.body |
| 441 | } |
| 442 | |
| 443 | /// Consumes the response returning the head and body parts. |
| 444 | /// |
| 445 | /// # Examples |
| 446 | /// |
| 447 | /// ``` |
| 448 | /// # use http::*; |
| 449 | /// let response: Response<()> = Response::default(); |
| 450 | /// let (parts, body) = response.into_parts(); |
| 451 | /// assert_eq!(parts.status, StatusCode::OK); |
| 452 | /// ``` |
| 453 | #[inline ] |
| 454 | pub fn into_parts(self) -> (Parts, T) { |
| 455 | (self.head, self.body) |
| 456 | } |
| 457 | |
| 458 | /// Consumes the response returning a new response with body mapped to the |
| 459 | /// return type of the passed in function. |
| 460 | /// |
| 461 | /// # Examples |
| 462 | /// |
| 463 | /// ``` |
| 464 | /// # use http::*; |
| 465 | /// let response = Response::builder().body("some string" ).unwrap(); |
| 466 | /// let mapped_response: Response<&[u8]> = response.map(|b| { |
| 467 | /// assert_eq!(b, "some string" ); |
| 468 | /// b.as_bytes() |
| 469 | /// }); |
| 470 | /// assert_eq!(mapped_response.body(), &"some string" .as_bytes()); |
| 471 | /// ``` |
| 472 | #[inline ] |
| 473 | pub fn map<F, U>(self, f: F) -> Response<U> |
| 474 | where |
| 475 | F: FnOnce(T) -> U, |
| 476 | { |
| 477 | Response { |
| 478 | body: f(self.body), |
| 479 | head: self.head, |
| 480 | } |
| 481 | } |
| 482 | } |
| 483 | |
| 484 | impl<T: Default> Default for Response<T> { |
| 485 | #[inline ] |
| 486 | fn default() -> Response<T> { |
| 487 | Response::new(T::default()) |
| 488 | } |
| 489 | } |
| 490 | |
| 491 | impl<T: fmt::Debug> fmt::Debug for Response<T> { |
| 492 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 493 | f.debug_struct("Response" ) |
| 494 | .field("status" , &self.status()) |
| 495 | .field("version" , &self.version()) |
| 496 | .field("headers" , self.headers()) |
| 497 | // omits Extensions because not useful |
| 498 | .field("body" , self.body()) |
| 499 | .finish() |
| 500 | } |
| 501 | } |
| 502 | |
| 503 | impl Parts { |
| 504 | /// Creates a new default instance of `Parts` |
| 505 | fn new() -> Parts { |
| 506 | Parts { |
| 507 | status: StatusCode::default(), |
| 508 | version: Version::default(), |
| 509 | headers: HeaderMap::default(), |
| 510 | extensions: Extensions::default(), |
| 511 | _priv: (), |
| 512 | } |
| 513 | } |
| 514 | } |
| 515 | |
| 516 | impl fmt::Debug for Parts { |
| 517 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 518 | f.debug_struct("Parts" ) |
| 519 | .field("status" , &self.status) |
| 520 | .field("version" , &self.version) |
| 521 | .field("headers" , &self.headers) |
| 522 | // omits Extensions because not useful |
| 523 | // omits _priv because not useful |
| 524 | .finish() |
| 525 | } |
| 526 | } |
| 527 | |
| 528 | impl Builder { |
| 529 | /// Creates a new default instance of `Builder` to construct either a |
| 530 | /// `Head` or a `Response`. |
| 531 | /// |
| 532 | /// # Examples |
| 533 | /// |
| 534 | /// ``` |
| 535 | /// # use http::*; |
| 536 | /// |
| 537 | /// let response = response::Builder::new() |
| 538 | /// .status(200) |
| 539 | /// .body(()) |
| 540 | /// .unwrap(); |
| 541 | /// ``` |
| 542 | #[inline ] |
| 543 | pub fn new() -> Builder { |
| 544 | Builder::default() |
| 545 | } |
| 546 | |
| 547 | /// Set the HTTP status for this response. |
| 548 | /// |
| 549 | /// By default this is `200`. |
| 550 | /// |
| 551 | /// # Examples |
| 552 | /// |
| 553 | /// ``` |
| 554 | /// # use http::*; |
| 555 | /// |
| 556 | /// let response = Response::builder() |
| 557 | /// .status(200) |
| 558 | /// .body(()) |
| 559 | /// .unwrap(); |
| 560 | /// ``` |
| 561 | pub fn status<T>(self, status: T) -> Builder |
| 562 | where |
| 563 | StatusCode: TryFrom<T>, |
| 564 | <StatusCode as TryFrom<T>>::Error: Into<crate::Error>, |
| 565 | { |
| 566 | self.and_then(move |mut head| { |
| 567 | head.status = TryFrom::try_from(status).map_err(Into::into)?; |
| 568 | Ok(head) |
| 569 | }) |
| 570 | } |
| 571 | |
| 572 | /// Set the HTTP version for this response. |
| 573 | /// |
| 574 | /// By default this is HTTP/1.1 |
| 575 | /// |
| 576 | /// # Examples |
| 577 | /// |
| 578 | /// ``` |
| 579 | /// # use http::*; |
| 580 | /// |
| 581 | /// let response = Response::builder() |
| 582 | /// .version(Version::HTTP_2) |
| 583 | /// .body(()) |
| 584 | /// .unwrap(); |
| 585 | /// ``` |
| 586 | pub fn version(self, version: Version) -> Builder { |
| 587 | self.and_then(move |mut head| { |
| 588 | head.version = version; |
| 589 | Ok(head) |
| 590 | }) |
| 591 | } |
| 592 | |
| 593 | /// Appends a header to this response builder. |
| 594 | /// |
| 595 | /// This function will append the provided key/value as a header to the |
| 596 | /// internal `HeaderMap` being constructed. Essentially this is equivalent |
| 597 | /// to calling `HeaderMap::append`. |
| 598 | /// |
| 599 | /// # Examples |
| 600 | /// |
| 601 | /// ``` |
| 602 | /// # use http::*; |
| 603 | /// # use http::header::HeaderValue; |
| 604 | /// |
| 605 | /// let response = Response::builder() |
| 606 | /// .header("Content-Type" , "text/html" ) |
| 607 | /// .header("X-Custom-Foo" , "bar" ) |
| 608 | /// .header("content-length" , 0) |
| 609 | /// .body(()) |
| 610 | /// .unwrap(); |
| 611 | /// ``` |
| 612 | pub fn header<K, V>(self, key: K, value: V) -> Builder |
| 613 | where |
| 614 | HeaderName: TryFrom<K>, |
| 615 | <HeaderName as TryFrom<K>>::Error: Into<crate::Error>, |
| 616 | HeaderValue: TryFrom<V>, |
| 617 | <HeaderValue as TryFrom<V>>::Error: Into<crate::Error>, |
| 618 | { |
| 619 | self.and_then(move |mut head| { |
| 620 | let name = <HeaderName as TryFrom<K>>::try_from(key).map_err(Into::into)?; |
| 621 | let value = <HeaderValue as TryFrom<V>>::try_from(value).map_err(Into::into)?; |
| 622 | head.headers.append(name, value); |
| 623 | Ok(head) |
| 624 | }) |
| 625 | } |
| 626 | |
| 627 | /// Get header on this response builder. |
| 628 | /// |
| 629 | /// When builder has error returns None. |
| 630 | /// |
| 631 | /// # Example |
| 632 | /// |
| 633 | /// ``` |
| 634 | /// # use http::Response; |
| 635 | /// # use http::header::HeaderValue; |
| 636 | /// let res = Response::builder() |
| 637 | /// .header("Accept" , "text/html" ) |
| 638 | /// .header("X-Custom-Foo" , "bar" ); |
| 639 | /// let headers = res.headers_ref().unwrap(); |
| 640 | /// assert_eq!( headers["Accept" ], "text/html" ); |
| 641 | /// assert_eq!( headers["X-Custom-Foo" ], "bar" ); |
| 642 | /// ``` |
| 643 | pub fn headers_ref(&self) -> Option<&HeaderMap<HeaderValue>> { |
| 644 | self.inner.as_ref().ok().map(|h| &h.headers) |
| 645 | } |
| 646 | |
| 647 | /// Get header on this response builder. |
| 648 | /// when builder has error returns None |
| 649 | /// |
| 650 | /// # Example |
| 651 | /// |
| 652 | /// ``` |
| 653 | /// # use http::*; |
| 654 | /// # use http::header::HeaderValue; |
| 655 | /// # use http::response::Builder; |
| 656 | /// let mut res = Response::builder(); |
| 657 | /// { |
| 658 | /// let headers = res.headers_mut().unwrap(); |
| 659 | /// headers.insert("Accept" , HeaderValue::from_static("text/html" )); |
| 660 | /// headers.insert("X-Custom-Foo" , HeaderValue::from_static("bar" )); |
| 661 | /// } |
| 662 | /// let headers = res.headers_ref().unwrap(); |
| 663 | /// assert_eq!( headers["Accept" ], "text/html" ); |
| 664 | /// assert_eq!( headers["X-Custom-Foo" ], "bar" ); |
| 665 | /// ``` |
| 666 | pub fn headers_mut(&mut self) -> Option<&mut HeaderMap<HeaderValue>> { |
| 667 | self.inner.as_mut().ok().map(|h| &mut h.headers) |
| 668 | } |
| 669 | |
| 670 | /// Adds an extension to this builder |
| 671 | /// |
| 672 | /// # Examples |
| 673 | /// |
| 674 | /// ``` |
| 675 | /// # use http::*; |
| 676 | /// |
| 677 | /// let response = Response::builder() |
| 678 | /// .extension("My Extension" ) |
| 679 | /// .body(()) |
| 680 | /// .unwrap(); |
| 681 | /// |
| 682 | /// assert_eq!(response.extensions().get::<&'static str>(), |
| 683 | /// Some(&"My Extension" )); |
| 684 | /// ``` |
| 685 | pub fn extension<T>(self, extension: T) -> Builder |
| 686 | where |
| 687 | T: Any + Send + Sync + 'static, |
| 688 | { |
| 689 | self.and_then(move |mut head| { |
| 690 | head.extensions.insert(extension); |
| 691 | Ok(head) |
| 692 | }) |
| 693 | } |
| 694 | |
| 695 | /// Get a reference to the extensions for this response builder. |
| 696 | /// |
| 697 | /// If the builder has an error, this returns `None`. |
| 698 | /// |
| 699 | /// # Example |
| 700 | /// |
| 701 | /// ``` |
| 702 | /// # use http::Response; |
| 703 | /// let res = Response::builder().extension("My Extension" ).extension(5u32); |
| 704 | /// let extensions = res.extensions_ref().unwrap(); |
| 705 | /// assert_eq!(extensions.get::<&'static str>(), Some(&"My Extension" )); |
| 706 | /// assert_eq!(extensions.get::<u32>(), Some(&5u32)); |
| 707 | /// ``` |
| 708 | pub fn extensions_ref(&self) -> Option<&Extensions> { |
| 709 | self.inner.as_ref().ok().map(|h| &h.extensions) |
| 710 | } |
| 711 | |
| 712 | /// Get a mutable reference to the extensions for this response builder. |
| 713 | /// |
| 714 | /// If the builder has an error, this returns `None`. |
| 715 | /// |
| 716 | /// # Example |
| 717 | /// |
| 718 | /// ``` |
| 719 | /// # use http::Response; |
| 720 | /// let mut res = Response::builder().extension("My Extension" ); |
| 721 | /// let mut extensions = res.extensions_mut().unwrap(); |
| 722 | /// assert_eq!(extensions.get::<&'static str>(), Some(&"My Extension" )); |
| 723 | /// extensions.insert(5u32); |
| 724 | /// assert_eq!(extensions.get::<u32>(), Some(&5u32)); |
| 725 | /// ``` |
| 726 | pub fn extensions_mut(&mut self) -> Option<&mut Extensions> { |
| 727 | self.inner.as_mut().ok().map(|h| &mut h.extensions) |
| 728 | } |
| 729 | |
| 730 | /// "Consumes" this builder, using the provided `body` to return a |
| 731 | /// constructed `Response`. |
| 732 | /// |
| 733 | /// # Errors |
| 734 | /// |
| 735 | /// This function may return an error if any previously configured argument |
| 736 | /// failed to parse or get converted to the internal representation. For |
| 737 | /// example if an invalid `head` was specified via `header("Foo", |
| 738 | /// "Bar\r\n")` the error will be returned when this function is called |
| 739 | /// rather than when `header` was called. |
| 740 | /// |
| 741 | /// # Examples |
| 742 | /// |
| 743 | /// ``` |
| 744 | /// # use http::*; |
| 745 | /// |
| 746 | /// let response = Response::builder() |
| 747 | /// .body(()) |
| 748 | /// .unwrap(); |
| 749 | /// ``` |
| 750 | pub fn body<T>(self, body: T) -> Result<Response<T>> { |
| 751 | self.inner.map(move |head| { |
| 752 | Response { |
| 753 | head, |
| 754 | body, |
| 755 | } |
| 756 | }) |
| 757 | } |
| 758 | |
| 759 | // private |
| 760 | |
| 761 | fn and_then<F>(self, func: F) -> Self |
| 762 | where |
| 763 | F: FnOnce(Parts) -> Result<Parts> |
| 764 | { |
| 765 | Builder { |
| 766 | inner: self.inner.and_then(func), |
| 767 | } |
| 768 | } |
| 769 | } |
| 770 | |
| 771 | impl Default for Builder { |
| 772 | #[inline ] |
| 773 | fn default() -> Builder { |
| 774 | Builder { |
| 775 | inner: Ok(Parts::new()), |
| 776 | } |
| 777 | } |
| 778 | } |
| 779 | |
| 780 | #[cfg (test)] |
| 781 | mod tests { |
| 782 | use super::*; |
| 783 | |
| 784 | #[test] |
| 785 | fn it_can_map_a_body_from_one_type_to_another() { |
| 786 | let response = Response::builder().body("some string" ).unwrap(); |
| 787 | let mapped_response = response.map(|s| { |
| 788 | assert_eq!(s, "some string" ); |
| 789 | 123u32 |
| 790 | }); |
| 791 | assert_eq!(mapped_response.body(), &123u32); |
| 792 | } |
| 793 | } |
| 794 | |