[][src]Trait hyperdrive::Guard

pub trait Guard: Sized {
    type Context: RequestContext;
    type Result: IntoFuture<Item = Self, Error = BoxedError>;
    fn from_request(
        request: &Arc<Request<()>>,
        context: &Self::Context
    ) -> Self::Result; }

A request guard that checks a condition or extracts data out of an incoming request.

For example, this could be used to extract an Authorization header and verify user credentials, or to look up a session token in a database.

A Guard can not access the request body. If you need to do that, implement FromBody instead.

Examples

Define a guard that ensures that required request headers are present:

struct MustFrobnicate;

impl Guard for MustFrobnicate {
    type Context = NoContext;
    type Result = Result<Self, BoxedError>;

    fn from_request(request: &Arc<http::Request<()>>, context: &Self::Context) -> Self::Result {
        if request.headers().contains_key("X-Frobnicate") {
            Ok(MustFrobnicate)
        } else {
            let msg = "request did not contain mandatory `X-Frobnicate` header";
            Err(String::from(msg).into())
        }
    }
}

Use server settings stored in a RequestContext to exclude certain user agents:

#[derive(RequestContext)]
struct ForbiddenAgents {
    agents: Vec<String>,
}

struct RejectForbiddenAgents;

impl Guard for RejectForbiddenAgents {
    type Context = ForbiddenAgents;
    type Result = Result<Self, BoxedError>;

    fn from_request(request: &Arc<http::Request<()>>, context: &Self::Context) -> Self::Result {
        let agent = request.headers().get("User-Agent")
            .ok_or_else(|| String::from("No User-Agent header"))?;

        if context.agents.iter().any(|f| f == agent) {
            Err(String::from("This User-Agent is forbidden!").into())
        } else {
            Ok(RejectForbiddenAgents)
        }
    }
}

Associated Types

type Context: RequestContext

A context parameter passed to Guard::from_request.

This can be used to pass application-specific data like a database connection or server configuration (eg. for limiting the maximum HTTP request size) around.

If no context is needed, this should be set to NoContext.

type Result: IntoFuture<Item = Self, Error = BoxedError>

The result returned by Guard::from_request.

Because impl Trait cannot be used inside traits (and named existential types aren't stable), the type here might not be nameable. In that case, you can set it to DefaultFuture<Self, Error> and box the returned future.

If your guard doesn't need to return a future (eg. because it's just a parsing step), you can set this to Result<Self, BoxedError> and immediately return the result of the conversion.

Loading content...

Required methods

fn from_request(
    request: &Arc<Request<()>>,
    context: &Self::Context
) -> Self::Result

Create an instance of this type from HTTP request data, asynchronously.

This can inspect HTTP headers and other data provided by http::Request, but can not access the body of the request. If access to the body is needed, FromBody must be implemented instead.

Implementations of this function must not block, since this function is always run on a futures executor. If you need to perform blocking I/O or long-running computations, you can call tokio_threadpool::blocking.

Parameters

  • request: An HTTP request (without body) from the http crate.
  • context: User-defined context needed by the guard.
Loading content...

Implementors

Loading content...