Name Description Size
error.rs 1829
filter
filters
generic.rs 5434
lib.rs # warp warp is a super-easy, composable, web server framework for warp speeds. Thanks to its [`Filter`][Filter] system, warp provides these out of the box: - Path routing and parameter extraction - Header requirements and extraction - Query string deserialization - JSON and Form bodies - Multipart form data - Static Files and Directories - Websockets - Access logging - Etc Since it builds on top of [hyper](https://hyper.rs), you automatically get: - HTTP/1 - HTTP/2 - Asynchronous - One of the fastest HTTP implementations - Tested and **correct** ## Filters The main concept in warp is the [`Filter`][Filter], which allows composition to describe various endpoints in your web service. Besides this powerful trait, warp comes with several built in [filters](filters/index.html), which can be combined for your specific needs. As a small example, consider an endpoint that has path and header requirements: ``` use warp::Filter; let hi = warp::path("hello") .and(warp::path::param()) .and(warp::header("user-agent")) .map(|param: String, agent: String| { format!("Hello {}, whose agent is {}", param, agent) }); ``` This example composes several [`Filter`s][Filter] together using `and`: - A path prefix of "hello" - A path parameter of a `String` - The `user-agent` header parsed as a `String` These specific filters will [`reject`][reject] requests that don't match their requirements. This ends up matching requests like: ```notrust GET /hello/sean HTTP/1.1 Host: hyper.rs User-Agent: reqwest/v0.8.6 ``` And it returns a response similar to this: ```notrust HTTP/1.1 200 OK Content-Length: 41 Date: ... Hello sean, whose agent is reqwest/v0.8.6 ``` Take a look at the full list of [`filters`](filters/index.html) to see what you can build. ## Testing Testing your web services easily is extremely important, and warp provides a [`test`](mod@self::test) module to help send mocked requests through your service. [Filter]: trait.Filter.html [reject]: reject/index.html 4432
redirect.rs Redirect requests to a new location. The types in this module are helpers that implement [`Reply`], and easy to use in order to setup redirects. 5601
reject.rs Rejections Part of the power of the [`Filter`](../trait.Filter.html) system is being able to reject a request from a filter chain. This allows for filters to be combined with `or`, so that if one side of the chain finds that a request doesn't fulfill its requirements, the other side can try to process the request. Many of the built-in [`filters`](../filters) will automatically reject the request with an appropriate rejection. However, you can also build new custom [`Filter`](../trait.Filter.html)s and still want other routes to be matchable in the case a predicate doesn't hold. As a request is processed by a Filter chain, the rejections are accumulated into a list contained by the [`Rejection`](struct.Rejection.html) type. Rejections from filters can be handled using [`Filter::recover`](../trait.Filter.html#method.recover). This is a convenient way to map rejections into a [`Reply`](../reply/trait.Reply.html). For a more complete example see the [Rejection Example](https://github.com/seanmonstar/warp/blob/master/examples/rejections.rs) from the repository. # Example ``` use warp::{reply, Reply, Filter, reject, Rejection, http::StatusCode}; #[derive(Debug)] struct InvalidParameter; impl reject::Reject for InvalidParameter {} // Custom rejection handler that maps rejections into responses. async fn handle_rejection(err: Rejection) -> Result<impl Reply, std::convert::Infallible> { if err.is_not_found() { Ok(reply::with_status("NOT_FOUND", StatusCode::NOT_FOUND)) } else if let Some(e) = err.find::<InvalidParameter>() { Ok(reply::with_status("BAD_REQUEST", StatusCode::BAD_REQUEST)) } else { eprintln!("unhandled rejection: {:?}", err); Ok(reply::with_status("INTERNAL_SERVER_ERROR", StatusCode::INTERNAL_SERVER_ERROR)) } } // Filter on `/:id`, but reject with InvalidParameter if the `id` is `0`. // Recover from this rejection using a custom rejection handler. let route = warp::path::param() .and_then(|id: u32| async move { if id == 0 { Err(warp::reject::custom(InvalidParameter)) } else { Ok("id is valid") } }) .recover(handle_rejection); ``` 25669
reply.rs Reply to requests. A [`Reply`](./trait.Reply.html) is a type that can be converted into an HTTP response to be sent to the client. These are typically the successful counterpart to a [rejection](../reject). The functions in this module are helpers for quickly creating a reply. Besides them, you can return a type that implements [`Reply`](./trait.Reply.html). This could be any of the following: - [`http::Response<impl Into<hyper::Body>>`](https://docs.rs/http) - `String` - `&'static str` - `http::StatusCode` # Example ``` use warp::{Filter, http::Response}; // Returns an empty `200 OK` response. let empty_200 = warp::any().map(warp::reply); // Returns a `200 OK` response with custom header and body. let custom = warp::any().map(|| { Response::builder() .header("my-custom-header", "some-value") .body("and a custom body") }); // GET requests return the empty 200, POST return the custom. let routes = warp::get().and(empty_200) .or(warp::post().and(custom)); ``` 14213
route.rs 3275
server.rs 19996
service.rs Convert `Filter`s into `Service`s 80
test.rs Test utilities to test your filters. [`Filter`](../trait.Filter.html)s can be easily tested without starting up an HTTP server, by making use of the [`RequestBuilder`](./struct.RequestBuilder.html) in this module. # Testing Filters It's easy to test filters, especially if smaller filters are used to build up your full set. Consider these example filters: ``` use warp::Filter; fn sum() -> impl Filter<Extract = (u32,), Error = warp::Rejection> + Copy { warp::path::param() .and(warp::path::param()) .map(|x: u32, y: u32| { x + y }) } fn math() -> impl Filter<Extract = (String,), Error = warp::Rejection> + Copy { warp::post() .and(sum()) .map(|z: u32| { format!("Sum = {}", z) }) } ``` We can test some requests against the `sum` filter like this: ``` # use warp::Filter; #[tokio::test] async fn test_sum() { # let sum = || warp::any().map(|| 3); let filter = sum(); // Execute `sum` and get the `Extract` back. let value = warp::test::request() .path("/1/2") .filter(&filter) .await .unwrap(); assert_eq!(value, 3); // Or simply test if a request matches (doesn't reject). assert!( warp::test::request() .path("/1/-5") .matches(&filter) .await ); } ``` If the filter returns something that implements `Reply`, and thus can be turned into a response sent back to the client, we can test what exact response is returned. The `math` filter uses the `sum` filter, but returns a `String` that can be turned into a response. ``` # use warp::Filter; #[test] fn test_math() { # let math = || warp::any().map(warp::reply); let filter = math(); let res = warp::test::request() .path("/1/2") .reply(&filter); assert_eq!(res.status(), 405, "GET is not allowed"); let res = warp::test::request() .method("POST") .path("/1/2") .reply(&filter); assert_eq!(res.status(), 200); assert_eq!(res.body(), "Sum is 3"); } ``` 21224
tls.rs 13586
transport.rs 1421