blob: 3a7a99948e7b95b61d1f10f1dc98165a7316cbc3 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//! Handler implementations
use {
crate::Handler,
futures::{
future::{ready, BoxFuture},
prelude::*,
},
hyper::{Body, Request, Response, StatusCode},
std::path::PathBuf,
};
/// Returns a fixed response for any request (it doesn't match on any path)
#[derive(Default)]
pub struct StaticResponse {
status: StatusCode,
headers: Vec<(String, String)>,
body: Vec<u8>,
}
impl Handler for StaticResponse {
fn handles(&self, _: &Request<Body>) -> Option<BoxFuture<'_, Response<Body>>> {
let mut builder = Response::builder();
builder = builder.status(self.status);
for (key, value) in &self.headers {
builder = builder.header(key, value);
}
return builder.body(self.body.clone().into()).ok().map(|r| ready(r).boxed());
}
}
impl StaticResponse {
/// Create a new StaticResponse handler, which returns the given response body.
pub fn ok_body(body: impl Into<Vec<u8>>) -> Self {
StaticResponse { status: StatusCode::OK, headers: vec![], body: body.into() }
}
}
/// Handler wrapper that responds to the given request path using the given handler.
pub struct ForPath<H> {
path: PathBuf,
handler: H,
}
impl<H> ForPath<H> {
/// Create a new ForPath handler for the given path and composed Handler.
pub fn new(path: impl Into<PathBuf>, handler: H) -> Self {
Self { path: path.into(), handler }
}
}
impl<H> Handler for ForPath<H>
where
H: Handler,
{
fn handles(&self, request: &Request<Body>) -> Option<BoxFuture<'_, Response<Body>>> {
if self.path == PathBuf::from(request.uri().path()) {
self.handler.handles(request)
} else {
None
}
}
}