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