[][src]Trait http_tools::request::Filter

pub trait Filter<'a, R> {
    fn filter_header(self, key: &str, value: &str) -> Self;
fn filter_path(self, pattern: &str) -> Self;
fn filter_path_prefix(self, pattern: &str) -> Self;
fn filter_method(self, method: &str) -> Self;
fn filter_query(self, key: &str, value: &str) -> Self;
fn filter_scheme(self, scheme: &str) -> Self;
fn filter_custom(self, func: fn(_: &Request<R>) -> bool) -> Self; }

The filter trait allows for the easy filtering of requests. They can be chained together to create more complex filters.

Filters were designed to be used in making an http router, but can be used in many more ways. The trait always outputs an Option<&Request>. If the option is Some then the underlying filter applies to the request, if the request is None then request did not pass the filter. The filter trait is implemented on both a Request and an Option<&Request>

Syntax

use http_tools::request::{Filter, Extension};
 
// given an http::request::Request
request
    // Creates an Option<&Request>, each fiter returns Some(req) if it passes and None if it fails
    .filter()
    // match the path /item/{} where {} is a wild card
    .filter_path("/item/{}")
    // request has the method of type POST
    .filter_method("POST")
    // The header has the key content-type with a value of application/x-www-form-urlencoded
    .filter_header("content-type", "application/x-www-form-urlencoded")
    // The {} wild card can be used to filter headers aswell
    .filter_header("content-length", "{}")
    // The query has the key cool with the value rust
    .filter_query("cool", "rust")
    // the wild card {} can be used in queries, filters do not decode uri encodings
    .filter_query("also+cool", "{}")
    // custom filters can be applied, and will be given the request and return a bool
    .filter_custom(|req| req.extensions().get::<i32>().is_some())
    // The request has a scheme of https
    .filter_scheme("https")
    // filters simply return std Option where Some means pass and None means failed
    .and_then(|_request| Some("I passed the test!"));

Since all filters simply take a refrence to a Request and return an Option, the filters can be applied in a number of different ways. For example the below router ensures that the Request is authenticated before routing it.

use http_tools::request::{Extension, Filter};
 
// The following filter must pass for any of the other handlers to pass
let parent_filter = request.filter()
    .filter_header("Authorization", "type token");
 
// check to see if the request is equal, if so call the handler function
parent_filter
    .filter_path("/")
    .and_then(|req| some_handler(req));
 
// if the above function didn't match we check the next one and if this one
// matches then we call some other handler function
parent_filter
    .filter_path("/{}")
    .and_then(|req| some_other_handler(req));

If you only ever want 1 handler function to be applied, then it is more efficent to test each filter afterwards, and return the output

use http_tools::request::{Extension, Filter};
 
fn mux<R>(request : &Request<R>) -> Response<()> {
    // Check the first filter
    let filter = request.filter()
        .filter_method("GET")
        .filter_path("/");
    if let Some(req) = filter {
        return some_handler(req);
    }
     
    // check the second filter
    let filter = request.filter()
        .filter_method("GET")
        .filter_path("/{}");
    if let Some(req) = filter {
        return some_other_handler(req);
    }
 
    return Response::builder()
        .status(StatusCode::NOT_FOUND)
        .body(())
        .unwrap()
}

Required methods

fn filter_header(self, key: &str, value: &str) -> Self

Checks to see if the request has the specified key and value. The wildcard '{}' pattern can be used in either the key or the value string. The function returns Some(request) if the header with the key and value are found or None if they are absent.

Example

use http::request::Builder;
use http_tools::request::{Extension, Filter};
 
// Request Builder found in http crate
let request = Builder::new()
                .uri("https://www.rust-lang.org/")
                .header("key", "value")
                .body(()).unwrap();
 
// matches when the key is key and value is value
let filter = request.filter().filter_header("key", "value");
assert!(filter.is_some());
 
// matches when the key exists
let filter = request.filter().filter_header("key", "{}");
assert!(filter.is_some());

fn filter_path(self, pattern: &str) -> Self

Checks to see if the requests path matches the specified pattern. The wildcard '{}' pattern can be used can be used to match any text between foward slashes so '/{}' will match '/any' but not '/any/more'

Example

use http::request::Builder;
use http_tools::request::{Extension, Filter};
 
// Request Builder found in http crate
let request = Builder::new()
                    .uri("https://www.rust-lang.org/var/static")
                    .body(()).unwrap();
 
// this will match because the paths are exact
let filter = request.filter().filter_path("/var/static");
assert!(filter.is_some());
 
// this will match because the wildcard '{}' will match var
let filter = request.filter().filter_path("/{}/static");
assert!(filter.is_some());

fn filter_path_prefix(self, pattern: &str) -> Self

Checks to see if the requests path begins with the specified pattern. The wildcard '{}' pattern can be used to match any text between foward slashes.

Example

use http::request::Builder;
use http_tools::request::{Extension, Filter};
 
// Request Builder found in http crate
let request = Builder::new()
                    .uri("https://www.rust-lang.org/var/static")
                    .body(()).unwrap();
 
// this will match any path
let filter = request.filter().filter_path_prefix("/");
assert!(filter.is_some());
 
// this will match any path atleast 1 in size
let filter = request.filter().filter_path_prefix("/{}");
assert!(filter.is_some());
 
// this will match any path that starts with var
let filter = request.filter().filter_path_prefix("/var");
assert!(filter.is_some());
 
// Note: This will NOT pass as each subpath must be complete
let filter = request.filter().filter_path_prefix("/v"); // '/v' doesn't match '/var'
assert!(filter.is_none());

fn filter_method(self, method: &str) -> Self

Checks to see if the request has the inputed method.

Example

use http::request::Builder;
use http_tools::request::{Extension, Filter};
// Request Builder found in http crate
let request = Builder::new()
                    .uri("https://www.rust-lang.org/")
                    .method("GET")
                    .body(()).unwrap();
 
// this will match any path
let filter = request.filter().filter_method("GET");
assert!(filter.is_some());
 
// this will not 
let filter = request.filter().filter_method("POST");
assert!(filter.is_none());

fn filter_query(self, key: &str, value: &str) -> Self

Checks to see if the uri contains a query with the given key and value. The wildcard '{}' pattern can be used to match any key or value.

Example

use http::request::Builder;
use http_tools::request::{Extension, Filter};
// Request Builder found in http crate
let request = Builder::new()
                    .uri("https://www.rust-lang.org/?cool=rust&also+cool=go")
                    .body(()).unwrap();
 
// this will match as the value of cool is equal to rust
let filter = request.filter().filter_query("cool", "rust");
assert!(filter.is_some());
 
// this will match because the key of cool exists
let filter = request.filter().filter_query("cool", "{}");
assert!(filter.is_some());
 
// this will match because go is a value in the query
let filter = request.filter().filter_query("{}", "go");
assert!(filter.is_some());
 
// this will NOT match because filter_query does not decode it's arguments
let filter = request.filter().filter_query("also cool", "go");
assert!(filter.is_none());
// this will work
let filter = request.filter().filter_query("also+cool", "go");
assert!(filter.is_some());

fn filter_scheme(self, scheme: &str) -> Self

Checks to see if the request has given scheme

Example

use http::request::Builder;
use http_tools::request::{Extension, Filter};
// Request Builder found in http crate
let request = Builder::new()
                    .uri("https://www.rust-lang.org/")
                    .body(()).unwrap();
 
// this will match
let filter = request.filter().filter_scheme("https");
assert!(filter.is_some());
// this will not 
let filter = request.filter().filter_scheme("http");
assert!(filter.is_none());

fn filter_custom(self, func: fn(_: &Request<R>) -> bool) -> Self

filter_custom allows for a custom function filter. The filter will be given a &Request and will output a bool. if the bool is true, then function returns Some, if it is false then the function will return None

Example

use http::request::Builder;
use http_tools::request::{Extension, Filter};
// Request Builder found in http crate
let request = Builder::new()
                    .extension(-1i32)
                    .uri("https://www.rust-lang.org/")
                    .body(()).unwrap();
 
// this will match as the request has an extension of type i32
let filter = request.filter().filter_custom(|req| req.extensions().get::<i32>().is_some());
assert!(filter.is_some());
Loading content...

Implementations on Foreign Types

impl<'a, '_, R> Filter<'a, R> for Option<&'_ Request<R>>[src]

Loading content...

Implementors

Loading content...