| 1 | //! HTTP request types. |
| 2 | //! |
| 3 | //! This module contains structs related to HTTP requests, notably the |
| 4 | //! `Request` type itself as well as a builder to create requests. Typically |
| 5 | //! you'll import the `http::Request` type rather than reaching into this |
| 6 | //! module itself. |
| 7 | //! |
| 8 | //! # Examples |
| 9 | //! |
| 10 | //! Creating a `Request` to send |
| 11 | //! |
| 12 | //! ```no_run |
| 13 | //! use http::{Request, Response}; |
| 14 | //! |
| 15 | //! let mut request = Request::builder() |
| 16 | //! .uri("https://www.rust-lang.org/" ) |
| 17 | //! .header("User-Agent" , "my-awesome-agent/1.0" ); |
| 18 | //! |
| 19 | //! if needs_awesome_header() { |
| 20 | //! request = request.header("Awesome" , "yes" ); |
| 21 | //! } |
| 22 | //! |
| 23 | //! let response = send(request.body(()).unwrap()); |
| 24 | //! |
| 25 | //! # fn needs_awesome_header() -> bool { |
| 26 | //! # true |
| 27 | //! # } |
| 28 | //! # |
| 29 | //! fn send(req: Request<()>) -> Response<()> { |
| 30 | //! // ... |
| 31 | //! # panic!() |
| 32 | //! } |
| 33 | //! ``` |
| 34 | //! |
| 35 | //! Inspecting a request to see what was sent. |
| 36 | //! |
| 37 | //! ``` |
| 38 | //! use http::{Request, Response, StatusCode}; |
| 39 | //! |
| 40 | //! fn respond_to(req: Request<()>) -> http::Result<Response<()>> { |
| 41 | //! if req.uri() != "/awesome-url" { |
| 42 | //! return Response::builder() |
| 43 | //! .status(StatusCode::NOT_FOUND) |
| 44 | //! .body(()) |
| 45 | //! } |
| 46 | //! |
| 47 | //! let has_awesome_header = req.headers().contains_key("Awesome" ); |
| 48 | //! let body = req.body(); |
| 49 | //! |
| 50 | //! // ... |
| 51 | //! # panic!() |
| 52 | //! } |
| 53 | //! ``` |
| 54 | |
| 55 | use std::any::Any; |
| 56 | use std::convert::{TryFrom}; |
| 57 | use std::fmt; |
| 58 | |
| 59 | use crate::header::{HeaderMap, HeaderName, HeaderValue}; |
| 60 | use crate::method::Method; |
| 61 | use crate::version::Version; |
| 62 | use crate::{Extensions, Result, Uri}; |
| 63 | |
| 64 | /// Represents an HTTP request. |
| 65 | /// |
| 66 | /// An HTTP request consists of a head and a potentially optional body. The body |
| 67 | /// component is generic, enabling arbitrary types to represent the HTTP body. |
| 68 | /// For example, the body could be `Vec<u8>`, a `Stream` of byte chunks, or a |
| 69 | /// value that has been deserialized. |
| 70 | /// |
| 71 | /// # Examples |
| 72 | /// |
| 73 | /// Creating a `Request` to send |
| 74 | /// |
| 75 | /// ```no_run |
| 76 | /// use http::{Request, Response}; |
| 77 | /// |
| 78 | /// let mut request = Request::builder() |
| 79 | /// .uri("https://www.rust-lang.org/" ) |
| 80 | /// .header("User-Agent" , "my-awesome-agent/1.0" ); |
| 81 | /// |
| 82 | /// if needs_awesome_header() { |
| 83 | /// request = request.header("Awesome" , "yes" ); |
| 84 | /// } |
| 85 | /// |
| 86 | /// let response = send(request.body(()).unwrap()); |
| 87 | /// |
| 88 | /// # fn needs_awesome_header() -> bool { |
| 89 | /// # true |
| 90 | /// # } |
| 91 | /// # |
| 92 | /// fn send(req: Request<()>) -> Response<()> { |
| 93 | /// // ... |
| 94 | /// # panic!() |
| 95 | /// } |
| 96 | /// ``` |
| 97 | /// |
| 98 | /// Inspecting a request to see what was sent. |
| 99 | /// |
| 100 | /// ``` |
| 101 | /// use http::{Request, Response, StatusCode}; |
| 102 | /// |
| 103 | /// fn respond_to(req: Request<()>) -> http::Result<Response<()>> { |
| 104 | /// if req.uri() != "/awesome-url" { |
| 105 | /// return Response::builder() |
| 106 | /// .status(StatusCode::NOT_FOUND) |
| 107 | /// .body(()) |
| 108 | /// } |
| 109 | /// |
| 110 | /// let has_awesome_header = req.headers().contains_key("Awesome" ); |
| 111 | /// let body = req.body(); |
| 112 | /// |
| 113 | /// // ... |
| 114 | /// # panic!() |
| 115 | /// } |
| 116 | /// ``` |
| 117 | /// |
| 118 | /// Deserialize a request of bytes via json: |
| 119 | /// |
| 120 | /// ``` |
| 121 | /// # extern crate serde; |
| 122 | /// # extern crate serde_json; |
| 123 | /// # extern crate http; |
| 124 | /// use http::Request; |
| 125 | /// use serde::de; |
| 126 | /// |
| 127 | /// fn deserialize<T>(req: Request<Vec<u8>>) -> serde_json::Result<Request<T>> |
| 128 | /// where for<'de> T: de::Deserialize<'de>, |
| 129 | /// { |
| 130 | /// let (parts, body) = req.into_parts(); |
| 131 | /// let body = serde_json::from_slice(&body)?; |
| 132 | /// Ok(Request::from_parts(parts, body)) |
| 133 | /// } |
| 134 | /// # |
| 135 | /// # fn main() {} |
| 136 | /// ``` |
| 137 | /// |
| 138 | /// Or alternatively, serialize the body of a request to json |
| 139 | /// |
| 140 | /// ``` |
| 141 | /// # extern crate serde; |
| 142 | /// # extern crate serde_json; |
| 143 | /// # extern crate http; |
| 144 | /// use http::Request; |
| 145 | /// use serde::ser; |
| 146 | /// |
| 147 | /// fn serialize<T>(req: Request<T>) -> serde_json::Result<Request<Vec<u8>>> |
| 148 | /// where T: ser::Serialize, |
| 149 | /// { |
| 150 | /// let (parts, body) = req.into_parts(); |
| 151 | /// let body = serde_json::to_vec(&body)?; |
| 152 | /// Ok(Request::from_parts(parts, body)) |
| 153 | /// } |
| 154 | /// # |
| 155 | /// # fn main() {} |
| 156 | /// ``` |
| 157 | pub struct Request<T> { |
| 158 | head: Parts, |
| 159 | body: T, |
| 160 | } |
| 161 | |
| 162 | /// Component parts of an HTTP `Request` |
| 163 | /// |
| 164 | /// The HTTP request head consists of a method, uri, version, and a set of |
| 165 | /// header fields. |
| 166 | pub struct Parts { |
| 167 | /// The request's method |
| 168 | pub method: Method, |
| 169 | |
| 170 | /// The request's URI |
| 171 | pub uri: Uri, |
| 172 | |
| 173 | /// The request's version |
| 174 | pub version: Version, |
| 175 | |
| 176 | /// The request's headers |
| 177 | pub headers: HeaderMap<HeaderValue>, |
| 178 | |
| 179 | /// The request's extensions |
| 180 | pub extensions: Extensions, |
| 181 | |
| 182 | _priv: (), |
| 183 | } |
| 184 | |
| 185 | /// An HTTP request builder |
| 186 | /// |
| 187 | /// This type can be used to construct an instance or `Request` |
| 188 | /// through a builder-like pattern. |
| 189 | #[derive(Debug)] |
| 190 | pub struct Builder { |
| 191 | inner: Result<Parts>, |
| 192 | } |
| 193 | |
| 194 | impl Request<()> { |
| 195 | /// Creates a new builder-style object to manufacture a `Request` |
| 196 | /// |
| 197 | /// This method returns an instance of `Builder` which can be used to |
| 198 | /// create a `Request`. |
| 199 | /// |
| 200 | /// # Examples |
| 201 | /// |
| 202 | /// ``` |
| 203 | /// # use http::*; |
| 204 | /// let request = Request::builder() |
| 205 | /// .method("GET" ) |
| 206 | /// .uri("https://www.rust-lang.org/" ) |
| 207 | /// .header("X-Custom-Foo" , "Bar" ) |
| 208 | /// .body(()) |
| 209 | /// .unwrap(); |
| 210 | /// ``` |
| 211 | #[inline ] |
| 212 | pub fn builder() -> Builder { |
| 213 | Builder::new() |
| 214 | } |
| 215 | |
| 216 | /// Creates a new `Builder` initialized with a GET method and the given URI. |
| 217 | /// |
| 218 | /// This method returns an instance of `Builder` which can be used to |
| 219 | /// create a `Request`. |
| 220 | /// |
| 221 | /// # Example |
| 222 | /// |
| 223 | /// ``` |
| 224 | /// # use http::*; |
| 225 | /// |
| 226 | /// let request = Request::get("https://www.rust-lang.org/" ) |
| 227 | /// .body(()) |
| 228 | /// .unwrap(); |
| 229 | /// ``` |
| 230 | pub fn get<T>(uri: T) -> Builder |
| 231 | where |
| 232 | Uri: TryFrom<T>, |
| 233 | <Uri as TryFrom<T>>::Error: Into<crate::Error>, |
| 234 | |
| 235 | { |
| 236 | Builder::new().method(Method::GET).uri(uri) |
| 237 | } |
| 238 | |
| 239 | /// Creates a new `Builder` initialized with a PUT method and the given URI. |
| 240 | /// |
| 241 | /// This method returns an instance of `Builder` which can be used to |
| 242 | /// create a `Request`. |
| 243 | /// |
| 244 | /// # Example |
| 245 | /// |
| 246 | /// ``` |
| 247 | /// # use http::*; |
| 248 | /// |
| 249 | /// let request = Request::put("https://www.rust-lang.org/" ) |
| 250 | /// .body(()) |
| 251 | /// .unwrap(); |
| 252 | /// ``` |
| 253 | pub fn put<T>(uri: T) -> Builder |
| 254 | where |
| 255 | Uri: TryFrom<T>, |
| 256 | <Uri as TryFrom<T>>::Error: Into<crate::Error>, |
| 257 | |
| 258 | { |
| 259 | Builder::new().method(Method::PUT).uri(uri) |
| 260 | } |
| 261 | |
| 262 | /// Creates a new `Builder` initialized with a POST method and the given URI. |
| 263 | /// |
| 264 | /// This method returns an instance of `Builder` which can be used to |
| 265 | /// create a `Request`. |
| 266 | /// |
| 267 | /// # Example |
| 268 | /// |
| 269 | /// ``` |
| 270 | /// # use http::*; |
| 271 | /// |
| 272 | /// let request = Request::post("https://www.rust-lang.org/" ) |
| 273 | /// .body(()) |
| 274 | /// .unwrap(); |
| 275 | /// ``` |
| 276 | pub fn post<T>(uri: T) -> Builder |
| 277 | where |
| 278 | Uri: TryFrom<T>, |
| 279 | <Uri as TryFrom<T>>::Error: Into<crate::Error>, |
| 280 | |
| 281 | { |
| 282 | Builder::new().method(Method::POST).uri(uri) |
| 283 | } |
| 284 | |
| 285 | /// Creates a new `Builder` initialized with a DELETE method and the given URI. |
| 286 | /// |
| 287 | /// This method returns an instance of `Builder` which can be used to |
| 288 | /// create a `Request`. |
| 289 | /// |
| 290 | /// # Example |
| 291 | /// |
| 292 | /// ``` |
| 293 | /// # use http::*; |
| 294 | /// |
| 295 | /// let request = Request::delete("https://www.rust-lang.org/" ) |
| 296 | /// .body(()) |
| 297 | /// .unwrap(); |
| 298 | /// ``` |
| 299 | pub fn delete<T>(uri: T) -> Builder |
| 300 | where |
| 301 | Uri: TryFrom<T>, |
| 302 | <Uri as TryFrom<T>>::Error: Into<crate::Error>, |
| 303 | |
| 304 | { |
| 305 | Builder::new().method(Method::DELETE).uri(uri) |
| 306 | } |
| 307 | |
| 308 | /// Creates a new `Builder` initialized with an OPTIONS method and the given URI. |
| 309 | /// |
| 310 | /// This method returns an instance of `Builder` which can be used to |
| 311 | /// create a `Request`. |
| 312 | /// |
| 313 | /// # Example |
| 314 | /// |
| 315 | /// ``` |
| 316 | /// # use http::*; |
| 317 | /// |
| 318 | /// let request = Request::options("https://www.rust-lang.org/" ) |
| 319 | /// .body(()) |
| 320 | /// .unwrap(); |
| 321 | /// # assert_eq!(*request.method(), Method::OPTIONS); |
| 322 | /// ``` |
| 323 | pub fn options<T>(uri: T) -> Builder |
| 324 | where |
| 325 | Uri: TryFrom<T>, |
| 326 | <Uri as TryFrom<T>>::Error: Into<crate::Error>, |
| 327 | |
| 328 | { |
| 329 | Builder::new().method(Method::OPTIONS).uri(uri) |
| 330 | } |
| 331 | |
| 332 | /// Creates a new `Builder` initialized with a HEAD method and the given URI. |
| 333 | /// |
| 334 | /// This method returns an instance of `Builder` which can be used to |
| 335 | /// create a `Request`. |
| 336 | /// |
| 337 | /// # Example |
| 338 | /// |
| 339 | /// ``` |
| 340 | /// # use http::*; |
| 341 | /// |
| 342 | /// let request = Request::head("https://www.rust-lang.org/" ) |
| 343 | /// .body(()) |
| 344 | /// .unwrap(); |
| 345 | /// ``` |
| 346 | pub fn head<T>(uri: T) -> Builder |
| 347 | where |
| 348 | Uri: TryFrom<T>, |
| 349 | <Uri as TryFrom<T>>::Error: Into<crate::Error>, |
| 350 | |
| 351 | { |
| 352 | Builder::new().method(Method::HEAD).uri(uri) |
| 353 | } |
| 354 | |
| 355 | /// Creates a new `Builder` initialized with a CONNECT method and the given URI. |
| 356 | /// |
| 357 | /// This method returns an instance of `Builder` which can be used to |
| 358 | /// create a `Request`. |
| 359 | /// |
| 360 | /// # Example |
| 361 | /// |
| 362 | /// ``` |
| 363 | /// # use http::*; |
| 364 | /// |
| 365 | /// let request = Request::connect("https://www.rust-lang.org/" ) |
| 366 | /// .body(()) |
| 367 | /// .unwrap(); |
| 368 | /// ``` |
| 369 | pub fn connect<T>(uri: T) -> Builder |
| 370 | where |
| 371 | Uri: TryFrom<T>, |
| 372 | <Uri as TryFrom<T>>::Error: Into<crate::Error>, |
| 373 | |
| 374 | { |
| 375 | Builder::new().method(Method::CONNECT).uri(uri) |
| 376 | } |
| 377 | |
| 378 | /// Creates a new `Builder` initialized with a PATCH method and the given URI. |
| 379 | /// |
| 380 | /// This method returns an instance of `Builder` which can be used to |
| 381 | /// create a `Request`. |
| 382 | /// |
| 383 | /// # Example |
| 384 | /// |
| 385 | /// ``` |
| 386 | /// # use http::*; |
| 387 | /// |
| 388 | /// let request = Request::patch("https://www.rust-lang.org/" ) |
| 389 | /// .body(()) |
| 390 | /// .unwrap(); |
| 391 | /// ``` |
| 392 | pub fn patch<T>(uri: T) -> Builder |
| 393 | where |
| 394 | Uri: TryFrom<T>, |
| 395 | <Uri as TryFrom<T>>::Error: Into<crate::Error>, |
| 396 | { |
| 397 | Builder::new().method(Method::PATCH).uri(uri) |
| 398 | } |
| 399 | |
| 400 | /// Creates a new `Builder` initialized with a TRACE method and the given URI. |
| 401 | /// |
| 402 | /// This method returns an instance of `Builder` which can be used to |
| 403 | /// create a `Request`. |
| 404 | /// |
| 405 | /// # Example |
| 406 | /// |
| 407 | /// ``` |
| 408 | /// # use http::*; |
| 409 | /// |
| 410 | /// let request = Request::trace("https://www.rust-lang.org/" ) |
| 411 | /// .body(()) |
| 412 | /// .unwrap(); |
| 413 | /// ``` |
| 414 | pub fn trace<T>(uri: T) -> Builder |
| 415 | where |
| 416 | Uri: TryFrom<T>, |
| 417 | <Uri as TryFrom<T>>::Error: Into<crate::Error>, |
| 418 | { |
| 419 | Builder::new().method(Method::TRACE).uri(uri) |
| 420 | } |
| 421 | } |
| 422 | |
| 423 | impl<T> Request<T> { |
| 424 | /// Creates a new blank `Request` with the body |
| 425 | /// |
| 426 | /// The component parts of this request will be set to their default, e.g. |
| 427 | /// the GET method, no headers, etc. |
| 428 | /// |
| 429 | /// # Examples |
| 430 | /// |
| 431 | /// ``` |
| 432 | /// # use http::*; |
| 433 | /// let request = Request::new("hello world" ); |
| 434 | /// |
| 435 | /// assert_eq!(*request.method(), Method::GET); |
| 436 | /// assert_eq!(*request.body(), "hello world" ); |
| 437 | /// ``` |
| 438 | #[inline ] |
| 439 | pub fn new(body: T) -> Request<T> { |
| 440 | Request { |
| 441 | head: Parts::new(), |
| 442 | body: body, |
| 443 | } |
| 444 | } |
| 445 | |
| 446 | /// Creates a new `Request` with the given components parts and body. |
| 447 | /// |
| 448 | /// # Examples |
| 449 | /// |
| 450 | /// ``` |
| 451 | /// # use http::*; |
| 452 | /// let request = Request::new("hello world" ); |
| 453 | /// let (mut parts, body) = request.into_parts(); |
| 454 | /// parts.method = Method::POST; |
| 455 | /// |
| 456 | /// let request = Request::from_parts(parts, body); |
| 457 | /// ``` |
| 458 | #[inline ] |
| 459 | pub fn from_parts(parts: Parts, body: T) -> Request<T> { |
| 460 | Request { |
| 461 | head: parts, |
| 462 | body: body, |
| 463 | } |
| 464 | } |
| 465 | |
| 466 | /// Returns a reference to the associated HTTP method. |
| 467 | /// |
| 468 | /// # Examples |
| 469 | /// |
| 470 | /// ``` |
| 471 | /// # use http::*; |
| 472 | /// let request: Request<()> = Request::default(); |
| 473 | /// assert_eq!(*request.method(), Method::GET); |
| 474 | /// ``` |
| 475 | #[inline ] |
| 476 | pub fn method(&self) -> &Method { |
| 477 | &self.head.method |
| 478 | } |
| 479 | |
| 480 | /// Returns a mutable reference to the associated HTTP method. |
| 481 | /// |
| 482 | /// # Examples |
| 483 | /// |
| 484 | /// ``` |
| 485 | /// # use http::*; |
| 486 | /// let mut request: Request<()> = Request::default(); |
| 487 | /// *request.method_mut() = Method::PUT; |
| 488 | /// assert_eq!(*request.method(), Method::PUT); |
| 489 | /// ``` |
| 490 | #[inline ] |
| 491 | pub fn method_mut(&mut self) -> &mut Method { |
| 492 | &mut self.head.method |
| 493 | } |
| 494 | |
| 495 | /// Returns a reference to the associated URI. |
| 496 | /// |
| 497 | /// # Examples |
| 498 | /// |
| 499 | /// ``` |
| 500 | /// # use http::*; |
| 501 | /// let request: Request<()> = Request::default(); |
| 502 | /// assert_eq!(*request.uri(), *"/" ); |
| 503 | /// ``` |
| 504 | #[inline ] |
| 505 | pub fn uri(&self) -> &Uri { |
| 506 | &self.head.uri |
| 507 | } |
| 508 | |
| 509 | /// Returns a mutable reference to the associated URI. |
| 510 | /// |
| 511 | /// # Examples |
| 512 | /// |
| 513 | /// ``` |
| 514 | /// # use http::*; |
| 515 | /// let mut request: Request<()> = Request::default(); |
| 516 | /// *request.uri_mut() = "/hello" .parse().unwrap(); |
| 517 | /// assert_eq!(*request.uri(), *"/hello" ); |
| 518 | /// ``` |
| 519 | #[inline ] |
| 520 | pub fn uri_mut(&mut self) -> &mut Uri { |
| 521 | &mut self.head.uri |
| 522 | } |
| 523 | |
| 524 | /// Returns the associated version. |
| 525 | /// |
| 526 | /// # Examples |
| 527 | /// |
| 528 | /// ``` |
| 529 | /// # use http::*; |
| 530 | /// let request: Request<()> = Request::default(); |
| 531 | /// assert_eq!(request.version(), Version::HTTP_11); |
| 532 | /// ``` |
| 533 | #[inline ] |
| 534 | pub fn version(&self) -> Version { |
| 535 | self.head.version |
| 536 | } |
| 537 | |
| 538 | /// Returns a mutable reference to the associated version. |
| 539 | /// |
| 540 | /// # Examples |
| 541 | /// |
| 542 | /// ``` |
| 543 | /// # use http::*; |
| 544 | /// let mut request: Request<()> = Request::default(); |
| 545 | /// *request.version_mut() = Version::HTTP_2; |
| 546 | /// assert_eq!(request.version(), Version::HTTP_2); |
| 547 | /// ``` |
| 548 | #[inline ] |
| 549 | pub fn version_mut(&mut self) -> &mut Version { |
| 550 | &mut self.head.version |
| 551 | } |
| 552 | |
| 553 | /// Returns a reference to the associated header field map. |
| 554 | /// |
| 555 | /// # Examples |
| 556 | /// |
| 557 | /// ``` |
| 558 | /// # use http::*; |
| 559 | /// let request: Request<()> = Request::default(); |
| 560 | /// assert!(request.headers().is_empty()); |
| 561 | /// ``` |
| 562 | #[inline ] |
| 563 | pub fn headers(&self) -> &HeaderMap<HeaderValue> { |
| 564 | &self.head.headers |
| 565 | } |
| 566 | |
| 567 | /// Returns a mutable reference to the associated header field map. |
| 568 | /// |
| 569 | /// # Examples |
| 570 | /// |
| 571 | /// ``` |
| 572 | /// # use http::*; |
| 573 | /// # use http::header::*; |
| 574 | /// let mut request: Request<()> = Request::default(); |
| 575 | /// request.headers_mut().insert(HOST, HeaderValue::from_static("world" )); |
| 576 | /// assert!(!request.headers().is_empty()); |
| 577 | /// ``` |
| 578 | #[inline ] |
| 579 | pub fn headers_mut(&mut self) -> &mut HeaderMap<HeaderValue> { |
| 580 | &mut self.head.headers |
| 581 | } |
| 582 | |
| 583 | /// Returns a reference to the associated extensions. |
| 584 | /// |
| 585 | /// # Examples |
| 586 | /// |
| 587 | /// ``` |
| 588 | /// # use http::*; |
| 589 | /// let request: Request<()> = Request::default(); |
| 590 | /// assert!(request.extensions().get::<i32>().is_none()); |
| 591 | /// ``` |
| 592 | #[inline ] |
| 593 | pub fn extensions(&self) -> &Extensions { |
| 594 | &self.head.extensions |
| 595 | } |
| 596 | |
| 597 | /// Returns a mutable reference to the associated extensions. |
| 598 | /// |
| 599 | /// # Examples |
| 600 | /// |
| 601 | /// ``` |
| 602 | /// # use http::*; |
| 603 | /// # use http::header::*; |
| 604 | /// let mut request: Request<()> = Request::default(); |
| 605 | /// request.extensions_mut().insert("hello" ); |
| 606 | /// assert_eq!(request.extensions().get(), Some(&"hello" )); |
| 607 | /// ``` |
| 608 | #[inline ] |
| 609 | pub fn extensions_mut(&mut self) -> &mut Extensions { |
| 610 | &mut self.head.extensions |
| 611 | } |
| 612 | |
| 613 | /// Returns a reference to the associated HTTP body. |
| 614 | /// |
| 615 | /// # Examples |
| 616 | /// |
| 617 | /// ``` |
| 618 | /// # use http::*; |
| 619 | /// let request: Request<String> = Request::default(); |
| 620 | /// assert!(request.body().is_empty()); |
| 621 | /// ``` |
| 622 | #[inline ] |
| 623 | pub fn body(&self) -> &T { |
| 624 | &self.body |
| 625 | } |
| 626 | |
| 627 | /// Returns a mutable reference to the associated HTTP body. |
| 628 | /// |
| 629 | /// # Examples |
| 630 | /// |
| 631 | /// ``` |
| 632 | /// # use http::*; |
| 633 | /// let mut request: Request<String> = Request::default(); |
| 634 | /// request.body_mut().push_str("hello world" ); |
| 635 | /// assert!(!request.body().is_empty()); |
| 636 | /// ``` |
| 637 | #[inline ] |
| 638 | pub fn body_mut(&mut self) -> &mut T { |
| 639 | &mut self.body |
| 640 | } |
| 641 | |
| 642 | /// Consumes the request, returning just the body. |
| 643 | /// |
| 644 | /// # Examples |
| 645 | /// |
| 646 | /// ``` |
| 647 | /// # use http::Request; |
| 648 | /// let request = Request::new(10); |
| 649 | /// let body = request.into_body(); |
| 650 | /// assert_eq!(body, 10); |
| 651 | /// ``` |
| 652 | #[inline ] |
| 653 | pub fn into_body(self) -> T { |
| 654 | self.body |
| 655 | } |
| 656 | |
| 657 | /// Consumes the request returning the head and body parts. |
| 658 | /// |
| 659 | /// # Examples |
| 660 | /// |
| 661 | /// ``` |
| 662 | /// # use http::*; |
| 663 | /// let request = Request::new(()); |
| 664 | /// let (parts, body) = request.into_parts(); |
| 665 | /// assert_eq!(parts.method, Method::GET); |
| 666 | /// ``` |
| 667 | #[inline ] |
| 668 | pub fn into_parts(self) -> (Parts, T) { |
| 669 | (self.head, self.body) |
| 670 | } |
| 671 | |
| 672 | /// Consumes the request returning a new request with body mapped to the |
| 673 | /// return type of the passed in function. |
| 674 | /// |
| 675 | /// # Examples |
| 676 | /// |
| 677 | /// ``` |
| 678 | /// # use http::*; |
| 679 | /// let request = Request::builder().body("some string" ).unwrap(); |
| 680 | /// let mapped_request: Request<&[u8]> = request.map(|b| { |
| 681 | /// assert_eq!(b, "some string" ); |
| 682 | /// b.as_bytes() |
| 683 | /// }); |
| 684 | /// assert_eq!(mapped_request.body(), &"some string" .as_bytes()); |
| 685 | /// ``` |
| 686 | #[inline ] |
| 687 | pub fn map<F, U>(self, f: F) -> Request<U> |
| 688 | where |
| 689 | F: FnOnce(T) -> U, |
| 690 | { |
| 691 | Request { |
| 692 | body: f(self.body), |
| 693 | head: self.head, |
| 694 | } |
| 695 | } |
| 696 | } |
| 697 | |
| 698 | impl<T: Default> Default for Request<T> { |
| 699 | fn default() -> Request<T> { |
| 700 | Request::new(T::default()) |
| 701 | } |
| 702 | } |
| 703 | |
| 704 | impl<T: fmt::Debug> fmt::Debug for Request<T> { |
| 705 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 706 | f.debug_struct("Request" ) |
| 707 | .field("method" , self.method()) |
| 708 | .field("uri" , self.uri()) |
| 709 | .field("version" , &self.version()) |
| 710 | .field("headers" , self.headers()) |
| 711 | // omits Extensions because not useful |
| 712 | .field("body" , self.body()) |
| 713 | .finish() |
| 714 | } |
| 715 | } |
| 716 | |
| 717 | impl Parts { |
| 718 | /// Creates a new default instance of `Parts` |
| 719 | fn new() -> Parts { |
| 720 | Parts { |
| 721 | method: Method::default(), |
| 722 | uri: Uri::default(), |
| 723 | version: Version::default(), |
| 724 | headers: HeaderMap::default(), |
| 725 | extensions: Extensions::default(), |
| 726 | _priv: (), |
| 727 | } |
| 728 | } |
| 729 | } |
| 730 | |
| 731 | impl fmt::Debug for Parts { |
| 732 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 733 | f.debug_struct("Parts" ) |
| 734 | .field("method" , &self.method) |
| 735 | .field("uri" , &self.uri) |
| 736 | .field("version" , &self.version) |
| 737 | .field("headers" , &self.headers) |
| 738 | // omits Extensions because not useful |
| 739 | // omits _priv because not useful |
| 740 | .finish() |
| 741 | } |
| 742 | } |
| 743 | |
| 744 | impl Builder { |
| 745 | /// Creates a new default instance of `Builder` to construct a `Request`. |
| 746 | /// |
| 747 | /// # Examples |
| 748 | /// |
| 749 | /// ``` |
| 750 | /// # use http::*; |
| 751 | /// |
| 752 | /// let req = request::Builder::new() |
| 753 | /// .method("POST" ) |
| 754 | /// .body(()) |
| 755 | /// .unwrap(); |
| 756 | /// ``` |
| 757 | #[inline ] |
| 758 | pub fn new() -> Builder { |
| 759 | Builder::default() |
| 760 | } |
| 761 | |
| 762 | /// Set the HTTP method for this request. |
| 763 | /// |
| 764 | /// By default this is `GET`. |
| 765 | /// |
| 766 | /// # Examples |
| 767 | /// |
| 768 | /// ``` |
| 769 | /// # use http::*; |
| 770 | /// |
| 771 | /// let req = Request::builder() |
| 772 | /// .method("POST" ) |
| 773 | /// .body(()) |
| 774 | /// .unwrap(); |
| 775 | /// ``` |
| 776 | pub fn method<T>(self, method: T) -> Builder |
| 777 | where |
| 778 | Method: TryFrom<T>, |
| 779 | <Method as TryFrom<T>>::Error: Into<crate::Error>, |
| 780 | { |
| 781 | self.and_then(move |mut head| { |
| 782 | let method = TryFrom::try_from(method).map_err(Into::into)?; |
| 783 | head.method = method; |
| 784 | Ok(head) |
| 785 | }) |
| 786 | } |
| 787 | |
| 788 | /// Get the HTTP Method for this request. |
| 789 | /// |
| 790 | /// By default this is `GET`. If builder has error, returns None. |
| 791 | /// |
| 792 | /// # Examples |
| 793 | /// |
| 794 | /// ``` |
| 795 | /// # use http::*; |
| 796 | /// |
| 797 | /// let mut req = Request::builder(); |
| 798 | /// assert_eq!(req.method_ref(),Some(&Method::GET)); |
| 799 | /// |
| 800 | /// req = req.method("POST" ); |
| 801 | /// assert_eq!(req.method_ref(),Some(&Method::POST)); |
| 802 | /// ``` |
| 803 | pub fn method_ref(&self) -> Option<&Method> { |
| 804 | self.inner.as_ref().ok().map(|h| &h.method) |
| 805 | } |
| 806 | |
| 807 | /// Set the URI for this request. |
| 808 | /// |
| 809 | /// By default this is `/`. |
| 810 | /// |
| 811 | /// # Examples |
| 812 | /// |
| 813 | /// ``` |
| 814 | /// # use http::*; |
| 815 | /// |
| 816 | /// let req = Request::builder() |
| 817 | /// .uri("https://www.rust-lang.org/" ) |
| 818 | /// .body(()) |
| 819 | /// .unwrap(); |
| 820 | /// ``` |
| 821 | pub fn uri<T>(self, uri: T) -> Builder |
| 822 | where |
| 823 | Uri: TryFrom<T>, |
| 824 | <Uri as TryFrom<T>>::Error: Into<crate::Error>, |
| 825 | { |
| 826 | self.and_then(move |mut head| { |
| 827 | head.uri = TryFrom::try_from(uri).map_err(Into::into)?; |
| 828 | Ok(head) |
| 829 | }) |
| 830 | } |
| 831 | |
| 832 | /// Get the URI for this request |
| 833 | /// |
| 834 | /// By default this is `/`. |
| 835 | /// |
| 836 | /// # Examples |
| 837 | /// |
| 838 | /// ``` |
| 839 | /// # use http::*; |
| 840 | /// |
| 841 | /// let mut req = Request::builder(); |
| 842 | /// assert_eq!(req.uri_ref().unwrap(), "/" ); |
| 843 | /// |
| 844 | /// req = req.uri("https://www.rust-lang.org/" ); |
| 845 | /// assert_eq!(req.uri_ref().unwrap(), "https://www.rust-lang.org/" ); |
| 846 | /// ``` |
| 847 | pub fn uri_ref(&self) -> Option<&Uri> { |
| 848 | self.inner.as_ref().ok().map(|h| &h.uri) |
| 849 | } |
| 850 | |
| 851 | /// Set the HTTP version for this request. |
| 852 | /// |
| 853 | /// By default this is HTTP/1.1 |
| 854 | /// |
| 855 | /// # Examples |
| 856 | /// |
| 857 | /// ``` |
| 858 | /// # use http::*; |
| 859 | /// |
| 860 | /// let req = Request::builder() |
| 861 | /// .version(Version::HTTP_2) |
| 862 | /// .body(()) |
| 863 | /// .unwrap(); |
| 864 | /// ``` |
| 865 | pub fn version(self, version: Version) -> Builder { |
| 866 | self.and_then(move |mut head| { |
| 867 | head.version = version; |
| 868 | Ok(head) |
| 869 | }) |
| 870 | } |
| 871 | |
| 872 | /// Get the HTTP version for this request |
| 873 | /// |
| 874 | /// By default this is HTTP/1.1. |
| 875 | /// |
| 876 | /// # Examples |
| 877 | /// |
| 878 | /// ``` |
| 879 | /// # use http::*; |
| 880 | /// |
| 881 | /// let mut req = Request::builder(); |
| 882 | /// assert_eq!(req.version_ref().unwrap(), &Version::HTTP_11 ); |
| 883 | /// |
| 884 | /// req = req.version(Version::HTTP_2); |
| 885 | /// assert_eq!(req.version_ref().unwrap(), &Version::HTTP_2 ); |
| 886 | /// ``` |
| 887 | pub fn version_ref(&self) -> Option<&Version> { |
| 888 | self.inner.as_ref().ok().map(|h| &h.version) |
| 889 | } |
| 890 | |
| 891 | /// Appends a header to this request builder. |
| 892 | /// |
| 893 | /// This function will append the provided key/value as a header to the |
| 894 | /// internal `HeaderMap` being constructed. Essentially this is equivalent |
| 895 | /// to calling `HeaderMap::append`. |
| 896 | /// |
| 897 | /// # Examples |
| 898 | /// |
| 899 | /// ``` |
| 900 | /// # use http::*; |
| 901 | /// # use http::header::HeaderValue; |
| 902 | /// |
| 903 | /// let req = Request::builder() |
| 904 | /// .header("Accept" , "text/html" ) |
| 905 | /// .header("X-Custom-Foo" , "bar" ) |
| 906 | /// .body(()) |
| 907 | /// .unwrap(); |
| 908 | /// ``` |
| 909 | pub fn header<K, V>(self, key: K, value: V) -> Builder |
| 910 | where |
| 911 | HeaderName: TryFrom<K>, |
| 912 | <HeaderName as TryFrom<K>>::Error: Into<crate::Error>, |
| 913 | HeaderValue: TryFrom<V>, |
| 914 | <HeaderValue as TryFrom<V>>::Error: Into<crate::Error>, |
| 915 | { |
| 916 | self.and_then(move |mut head| { |
| 917 | let name = <HeaderName as TryFrom<K>>::try_from(key).map_err(Into::into)?; |
| 918 | let value = <HeaderValue as TryFrom<V>>::try_from(value).map_err(Into::into)?; |
| 919 | head.headers.append(name, value); |
| 920 | Ok(head) |
| 921 | }) |
| 922 | } |
| 923 | |
| 924 | /// Get header on this request builder. |
| 925 | /// when builder has error returns None |
| 926 | /// |
| 927 | /// # Example |
| 928 | /// |
| 929 | /// ``` |
| 930 | /// # use http::Request; |
| 931 | /// let req = Request::builder() |
| 932 | /// .header("Accept" , "text/html" ) |
| 933 | /// .header("X-Custom-Foo" , "bar" ); |
| 934 | /// let headers = req.headers_ref().unwrap(); |
| 935 | /// assert_eq!( headers["Accept" ], "text/html" ); |
| 936 | /// assert_eq!( headers["X-Custom-Foo" ], "bar" ); |
| 937 | /// ``` |
| 938 | pub fn headers_ref(&self) -> Option<&HeaderMap<HeaderValue>> { |
| 939 | self.inner.as_ref().ok().map(|h| &h.headers) |
| 940 | } |
| 941 | |
| 942 | /// Get headers on this request builder. |
| 943 | /// |
| 944 | /// When builder has error returns None. |
| 945 | /// |
| 946 | /// # Example |
| 947 | /// |
| 948 | /// ``` |
| 949 | /// # use http::{header::HeaderValue, Request}; |
| 950 | /// let mut req = Request::builder(); |
| 951 | /// { |
| 952 | /// let headers = req.headers_mut().unwrap(); |
| 953 | /// headers.insert("Accept" , HeaderValue::from_static("text/html" )); |
| 954 | /// headers.insert("X-Custom-Foo" , HeaderValue::from_static("bar" )); |
| 955 | /// } |
| 956 | /// let headers = req.headers_ref().unwrap(); |
| 957 | /// assert_eq!( headers["Accept" ], "text/html" ); |
| 958 | /// assert_eq!( headers["X-Custom-Foo" ], "bar" ); |
| 959 | /// ``` |
| 960 | pub fn headers_mut(&mut self) -> Option<&mut HeaderMap<HeaderValue>> { |
| 961 | self.inner.as_mut().ok().map(|h| &mut h.headers) |
| 962 | } |
| 963 | |
| 964 | /// Adds an extension to this builder |
| 965 | /// |
| 966 | /// # Examples |
| 967 | /// |
| 968 | /// ``` |
| 969 | /// # use http::*; |
| 970 | /// |
| 971 | /// let req = Request::builder() |
| 972 | /// .extension("My Extension" ) |
| 973 | /// .body(()) |
| 974 | /// .unwrap(); |
| 975 | /// |
| 976 | /// assert_eq!(req.extensions().get::<&'static str>(), |
| 977 | /// Some(&"My Extension" )); |
| 978 | /// ``` |
| 979 | pub fn extension<T>(self, extension: T) -> Builder |
| 980 | where |
| 981 | T: Any + Send + Sync + 'static, |
| 982 | { |
| 983 | self.and_then(move |mut head| { |
| 984 | head.extensions.insert(extension); |
| 985 | Ok(head) |
| 986 | }) |
| 987 | } |
| 988 | |
| 989 | /// Get a reference to the extensions for this request builder. |
| 990 | /// |
| 991 | /// If the builder has an error, this returns `None`. |
| 992 | /// |
| 993 | /// # Example |
| 994 | /// |
| 995 | /// ``` |
| 996 | /// # use http::Request; |
| 997 | /// let req = Request::builder().extension("My Extension" ).extension(5u32); |
| 998 | /// let extensions = req.extensions_ref().unwrap(); |
| 999 | /// assert_eq!(extensions.get::<&'static str>(), Some(&"My Extension" )); |
| 1000 | /// assert_eq!(extensions.get::<u32>(), Some(&5u32)); |
| 1001 | /// ``` |
| 1002 | pub fn extensions_ref(&self) -> Option<&Extensions> { |
| 1003 | self.inner.as_ref().ok().map(|h| &h.extensions) |
| 1004 | } |
| 1005 | |
| 1006 | /// Get a mutable reference to the extensions for this request builder. |
| 1007 | /// |
| 1008 | /// If the builder has an error, this returns `None`. |
| 1009 | /// |
| 1010 | /// # Example |
| 1011 | /// |
| 1012 | /// ``` |
| 1013 | /// # use http::Request; |
| 1014 | /// let mut req = Request::builder().extension("My Extension" ); |
| 1015 | /// let mut extensions = req.extensions_mut().unwrap(); |
| 1016 | /// assert_eq!(extensions.get::<&'static str>(), Some(&"My Extension" )); |
| 1017 | /// extensions.insert(5u32); |
| 1018 | /// assert_eq!(extensions.get::<u32>(), Some(&5u32)); |
| 1019 | /// ``` |
| 1020 | pub fn extensions_mut(&mut self) -> Option<&mut Extensions> { |
| 1021 | self.inner.as_mut().ok().map(|h| &mut h.extensions) |
| 1022 | } |
| 1023 | |
| 1024 | /// "Consumes" this builder, using the provided `body` to return a |
| 1025 | /// constructed `Request`. |
| 1026 | /// |
| 1027 | /// # Errors |
| 1028 | /// |
| 1029 | /// This function may return an error if any previously configured argument |
| 1030 | /// failed to parse or get converted to the internal representation. For |
| 1031 | /// example if an invalid `head` was specified via `header("Foo", |
| 1032 | /// "Bar\r\n")` the error will be returned when this function is called |
| 1033 | /// rather than when `header` was called. |
| 1034 | /// |
| 1035 | /// # Examples |
| 1036 | /// |
| 1037 | /// ``` |
| 1038 | /// # use http::*; |
| 1039 | /// |
| 1040 | /// let request = Request::builder() |
| 1041 | /// .body(()) |
| 1042 | /// .unwrap(); |
| 1043 | /// ``` |
| 1044 | pub fn body<T>(self, body: T) -> Result<Request<T>> { |
| 1045 | self.inner.map(move |head| { |
| 1046 | Request { |
| 1047 | head, |
| 1048 | body, |
| 1049 | } |
| 1050 | }) |
| 1051 | } |
| 1052 | |
| 1053 | // private |
| 1054 | |
| 1055 | fn and_then<F>(self, func: F) -> Self |
| 1056 | where |
| 1057 | F: FnOnce(Parts) -> Result<Parts> |
| 1058 | { |
| 1059 | Builder { |
| 1060 | inner: self.inner.and_then(func), |
| 1061 | } |
| 1062 | } |
| 1063 | } |
| 1064 | |
| 1065 | impl Default for Builder { |
| 1066 | #[inline ] |
| 1067 | fn default() -> Builder { |
| 1068 | Builder { |
| 1069 | inner: Ok(Parts::new()), |
| 1070 | } |
| 1071 | } |
| 1072 | } |
| 1073 | |
| 1074 | #[cfg (test)] |
| 1075 | mod tests { |
| 1076 | use super::*; |
| 1077 | |
| 1078 | #[test] |
| 1079 | fn it_can_map_a_body_from_one_type_to_another() { |
| 1080 | let request = Request::builder().body("some string" ).unwrap(); |
| 1081 | let mapped_request = request.map(|s| { |
| 1082 | assert_eq!(s, "some string" ); |
| 1083 | 123u32 |
| 1084 | }); |
| 1085 | assert_eq!(mapped_request.body(), &123u32); |
| 1086 | } |
| 1087 | } |
| 1088 | |