#![deny(
missing_docs,
single_use_lifetimes,
trivial_casts,
trivial_numeric_casts,
unsafe_code,
unstable_features,
unused_import_braces,
unused_qualifications,
unreachable_pub,
unused_results
)]
extern crate futures;
extern crate http;
extern crate hyper;
extern crate indexmap;
extern crate regex;
extern crate tokio_fs;
#[cfg(feature = "json")]
extern crate serde;
#[cfg(feature = "json")]
#[macro_use]
extern crate serde_derive;
#[cfg(feature = "json")]
extern crate serde_json;
#[cfg(feature = "html")]
extern crate tera;
use std::any::{Any, TypeId};
use std::borrow::Cow;
use std::error::Error;
use std::fs::File;
use std::io::prelude::*;
use std::sync::Arc;
use futures::{future, Future};
use http::{request, response};
use hyper::header::{self, HeaderMap, HeaderValue};
use hyper::service::{NewService, Service};
use hyper::{rt, Body, Method, Server, StatusCode, Uri, Version};
use indexmap::IndexMap;
use regex::Regex;
#[cfg(feature = "json")]
use serde::Serialize;
#[cfg(feature = "html")]
use tera::Tera;
pub struct Direkuta {
config: Arc<Config>,
state: Arc<State>,
middle: Arc<IndexMap<TypeId, Box<Middle + Send + Sync + 'static>>>,
routes: Arc<Router>,
}
impl Direkuta {
pub fn new() -> Self {
Direkuta::default()
}
pub fn config(c: impl Fn(&mut Config) + Send + Sync + 'static) -> Self {
let mut config = Config::new();
c(&mut config);
#[allow(unused_mut)]
let mut state = State::new();
#[cfg(feature = "html")]
state.set(match Tera::parse(&format!("{}/**/*", config.template_path)) {
Ok(t) => t,
Err(e) => {
println!("Parsing error(s): {}", e);
::std::process::exit(1);
}
});
Self {
config: Arc::new(config),
state: Arc::new(state),
middle: Arc::new(IndexMap::new()),
routes: Arc::new(Router::default()),
}
}
#[inline]
pub fn state<T: Any + Send + Sync + 'static>(mut self, state: T) -> Self {
Arc::get_mut(&mut self.state)
.expect("Cannot get_mut on state")
.set(state);
self
}
#[inline]
pub fn middle<T: Middle + Send + Sync + 'static>(mut self, middle: T) -> Self {
let _ = Arc::get_mut(&mut self.middle)
.expect("Cannot get_mut on middle")
.insert(TypeId::of::<T>(), Box::new(middle));
self
}
#[inline]
pub fn route(mut self, route: impl Fn(&mut Router) + Send + Sync + 'static) -> Self {
let mut route_builder = Router::new();
route(&mut route_builder);
self.routes = Arc::new(route_builder);
self
}
#[inline]
pub fn run(self, addr: &str) {
let address = addr.parse().expect("Address not a valid socket address");
let server = Server::bind(&address)
.serve(self)
.map_err(|e| eprintln!("server error: {}", e));
println!("Direkuta listening on http://{}", addr);
rt::run(server);
}
}
impl Default for Direkuta {
fn default() -> Self {
#[allow(unused_mut)]
let mut state = State::new();
#[cfg(feature = "html")]
state.set(match Tera::parse("templates/**/*") {
Ok(t) => t,
Err(e) => {
println!("Parsing error(s): {}", e);
::std::process::exit(1);
}
});
Self {
config: Arc::new(Config::new()),
state: Arc::new(state),
middle: Arc::new(IndexMap::new()),
routes: Arc::new(Router::default()),
}
}
}
impl NewService for Direkuta {
type ReqBody = Body;
type ResBody = Body;
type Error = DireError;
type InitError = DireError;
type Service = Direkuta;
type Future = Box<Future<Item = Self::Service, Error = Self::InitError> + Send>;
fn new_service(&self) -> Self::Future {
Box::new(future::ok(Self {
config: self.config.clone(),
state: self.state.clone(),
middle: self.middle.clone(),
routes: self.routes.clone(),
}))
}
}
impl Service for Direkuta {
type ReqBody = Body;
type ResBody = Body;
type Error = DireError;
type Future = Box<Future<Item = response::Response<Self::ResBody>, Error = Self::Error> + Send>;
fn call(&mut self, req: request::Request<Self::ReqBody>) -> Self::Future {
let path = req.uri().path().to_owned();
let (parts, body) = req.into_parts();
let mut req = Request::new(body, parts);
for (_, before) in self.middle.iter() {
before.run(&mut req);
}
match self.routes.recognize(&req.method(), &path) {
Ok((handler, cap)) => handler(req, self.state.clone(), cap),
Err(code) => Response::new().with_status(code.as_u16()).build(),
}
}
}
pub struct Config {
template_path: String,
static_path: String,
}
impl Config {
fn new() -> Self {
Self::default()
}
#[inline]
pub fn template_path(&mut self, path: impl Into<String>) {
self.template_path = path.into();
}
#[inline]
pub fn static_path(&mut self, path: impl Into<String>) {
self.static_path = path.into();
}
}
impl Default for Config {
fn default() -> Self {
Self {
template_path: "templates".to_string(),
static_path: "static".to_string(),
}
}
}
#[derive(Debug)]
pub enum DireError {
Hyper(hyper::Error),
Other(String),
StateNotFound,
}
impl std::fmt::Display for DireError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match *self {
DireError::Hyper(ref e) => write!(f, "(DireError [Hyper] {})", e),
DireError::Other(ref e) => write!(f, "(DireError [Other] {})", e),
DireError::StateNotFound => write!(f, "(DireError [State] Key Not Found)"),
}
}
}
impl Error for DireError {
fn description(&self) -> &str {
match *self {
DireError::Hyper(ref e) => e.description(),
DireError::Other(ref e) => e,
DireError::StateNotFound => "Key not found",
}
}
fn cause(&self) -> Option<&Error> {
match *self {
DireError::Hyper(ref e) => e.cause(),
_ => None,
}
}
}
impl From<hyper::Error> for DireError {
fn from(err: hyper::Error) -> DireError {
DireError::Hyper(err)
}
}
impl From<&'static str> for DireError {
fn from(err: &str) -> DireError {
DireError::Other(err.to_string())
}
}
impl From<String> for DireError {
fn from(err: String) -> DireError {
DireError::Other(err)
}
}
pub trait Middle {
fn run(&self, req: &mut Request);
}
pub struct Logger {}
impl Logger {
pub fn new() -> Self {
Logger::default()
}
}
impl Middle for Logger {
#[inline]
fn run(&self, req: &mut Request) {
println!("[{:>6}] `{}`", req.method().as_ref(), req.uri());
}
}
impl Default for Logger {
fn default() -> Logger {
Logger {}
}
}
pub struct State {
inner: IndexMap<TypeId, Box<Any + Send + Sync + 'static>>,
}
impl State {
pub fn new() -> Self {
State::default()
}
pub fn set<T: Any + Send + Sync + 'static>(&mut self, ctx: T) {
let _ = self.inner.insert(TypeId::of::<T>(), Box::new(ctx));
}
pub fn try_get<T: Any + Send + Sync + 'static>(&self) -> Option<&T> {
self.inner
.get(&TypeId::of::<T>())
.and_then(|b| b.downcast_ref::<T>())
}
pub fn get_err<T: Any + Send + Sync + 'static>(&self) -> Result<&T, DireError> {
match self.inner
.get(&TypeId::of::<T>())
.and_then(|b| b.downcast_ref::<T>()) {
Some(inner) => Ok(inner),
None => Err(DireError::StateNotFound)
}
}
pub fn get<T: Any + Send + Sync + 'static>(&self) -> &T {
self.try_get::<T>()
.unwrap_or_else(|| panic!("Key not found in state: {:?}", &TypeId::of::<T>()))
}
}
impl Default for State {
fn default() -> Self {
Self {
inner: IndexMap::new(),
}
}
}
enum Mode {
Id,
Regex,
Look,
}
pub struct Capture {
inner: IndexMap<String, String>,
}
impl Capture {
pub fn new() -> Self {
Capture::default()
}
#[inline]
pub fn set(&mut self, key: impl Into<String>, value: impl Into<String>) {
let _ = self.inner.insert(key.into(), value.into());
}
pub fn try_get(&self, key: impl Into<String>) -> Option<&str> {
match self.inner.get(&key.into()) {
Some(s) => Some(s.as_str()),
None => None,
}
}
pub fn get(&self, key: impl Into<String>) -> &str {
let key = key.into();
self.try_get(key.as_str())
.unwrap_or_else(|| panic!("Key not found in captures: {}", key))
}
pub fn try_get_parse<T: ::std::str::FromStr>(&self, key: &str) -> Option<T>
where
T::Err: ::std::fmt::Debug
{
match self.try_get(key) {
Some(s) => {
let c = s.parse::<T>()
.unwrap_or_else(|_| panic!("Error parsing key to type: {}", key));
Some(c)
},
None => None,
}
}
pub fn get_parse<T: ::std::str::FromStr>(&self, key: &str) -> T
where
T::Err: ::std::fmt::Debug
{
self.try_get_parse(key)
.unwrap_or_else(|| panic!("Key not found in captures: {}", key))
}
}
impl Default for Capture {
fn default() -> Capture {
Capture {
inner: IndexMap::new(),
}
}
}
type Handler =
Fn(Request, Arc<State>, Capture)
-> Box<dyn Future<Item = response::Response<Body>, Error = DireError> + Send + 'static>
+ Send
+ Sync
+ 'static;
struct Route {
handler: Box<Handler>,
ids: Vec<String>,
path: String,
pattern: Regex,
}
pub struct Router {
inner: IndexMap<Method, Vec<Route>>,
}
impl Router {
fn new() -> Router {
Router::default()
}
pub fn route(
&mut self,
method: Method,
path: impl Into<String>,
handler: impl Fn(Request, Arc<State>, Capture)
-> Box<dyn Future<Item = response::Response<Body>, Error = DireError> + Send + 'static>
+ Send
+ Sync
+ 'static,
) {
let path = path.into();
let reader = self.read(&path);
self.inner.entry(method).or_insert(Vec::new()).push(Route {
handler: Box::new(handler),
ids: reader.0,
path,
pattern: reader.1,
});
}
pub fn get(
&mut self,
path: impl Into<String>,
handler: impl Fn(Request, Arc<State>, Capture)
-> Box<dyn Future<Item = response::Response<Body>, Error = DireError> + Send + 'static>
+ Send
+ Sync
+ 'static,
) {
self.route(Method::GET, path, handler);
}
pub fn post(
&mut self,
path: impl Into<String>,
handler: impl Fn(Request, Arc<State>, Capture)
-> Box<dyn Future<Item = response::Response<Body>, Error = DireError> + Send + 'static>
+ Send
+ Sync
+ 'static,
) {
self.route(Method::POST, path, handler);
}
pub fn put(
&mut self,
path: impl Into<String>,
handler: impl Fn(Request, Arc<State>, Capture)
-> Box<dyn Future<Item = response::Response<Body>, Error = DireError> + Send + 'static>
+ Send
+ Sync
+ 'static,
) {
self.route(Method::PUT, path, handler);
}
pub fn delete(
&mut self,
path: impl Into<String>,
handler: impl Fn(Request, Arc<State>, Capture)
-> Box<dyn Future<Item = response::Response<Body>, Error = DireError> + Send + 'static>
+ Send
+ Sync
+ 'static,
) {
self.route(Method::DELETE, path, handler);
}
pub fn head(
&mut self,
path: impl Into<String>,
handler: impl Fn(Request, Arc<State>, Capture)
-> Box<dyn Future<Item = response::Response<Body>, Error = DireError> + Send + 'static>
+ Send
+ Sync
+ 'static,
) {
self.route(Method::HEAD, path, handler);
}
pub fn options(
&mut self,
path: impl Into<String>,
handler: impl Fn(Request, Arc<State>, Capture)
-> Box<dyn Future<Item = response::Response<Body>, Error = DireError> + Send + 'static>
+ Send
+ Sync
+ 'static,
) {
self.route(Method::OPTIONS, path, handler);
}
pub fn path(
&mut self,
path: impl Into<String>,
sub: impl Fn(&mut Router) + Send + Sync + 'static,
) {
let mut builder = Router::new();
sub(&mut builder);
let path = path.into();
for (method, routes) in builder.inner {
for route in routes {
let n_path = format!("{}{}", path, route.path);
let reader = self.read(&n_path);
self.inner
.entry(method.clone())
.or_insert(Vec::new())
.push(Route {
handler: route.handler,
ids: reader.0,
path: n_path,
pattern: reader.1,
});
}
}
}
#[inline]
fn recognize(&self, method: &Method, path: &str) -> Result<(&Handler, Capture), StatusCode> {
let routes = self.inner.get(method).ok_or(StatusCode::NOT_FOUND)?;
for route in routes.iter() {
if route.pattern.is_match(path) {
if let Some(map) = self.captures(&route, &route.pattern, path) {
return Ok((&*route.handler, map));
}
}
}
Err(StatusCode::NOT_FOUND)
}
#[inline]
fn captures(&self, route: &Route, re: &Regex, path: &str) -> Option<Capture> {
re.captures(path).map(|caps| {
let mut captures = Capture::new();
for (i, _) in caps.iter().enumerate() {
if i != 0 {
captures.set(
route.ids[i - 1].as_str(),
caps.get(i).unwrap().as_str(),
);
}
}
if cfg!(debug_assertions) {
captures.set("debug_pattern", re.as_str());
}
captures
})
}
#[inline]
fn read(&self, path: &str) -> (Vec<String>, Regex) {
let mut ids: Vec<String> = Vec::new();
let mut pattern = String::new();
let mut mode = Mode::Look;
let mut id = String::new();
for c in path.chars() {
match c {
'<' => mode = Mode::Id,
':' => {
mode = Mode::Regex;
ids.push(id.clone());
id.clear();
}
'>' => mode = Mode::Look,
_ => match mode {
Mode::Id => id.push(c),
Mode::Regex | Mode::Look => pattern.push(c),
},
}
}
(
ids,
match Regex::new(&self.normalize(&pattern)) {
Ok(r) => r,
Err(e) => {
eprintln!("Regex pattern error: {}", e);
::std::process::exit(1);
}
},
)
}
#[inline]
fn normalize(&self, pattern: &str) -> Cow<str> {
let pattern = pattern
.trim()
.trim_left_matches('^')
.trim_right_matches('$')
.trim_right_matches('/');
match pattern {
"" => "^/$".into(),
s => format!("^{}/?$", s).into(),
}
}
}
impl Default for Router {
fn default() -> Router {
Router {
inner: IndexMap::new(),
}
}
}
pub struct Response {
body: Body,
parts: response::Parts,
}
impl Response {
pub fn new() -> Self {
Response::default()
}
pub fn version(&self) -> Version {
self.parts.version
}
pub fn headers(&self) -> &HeaderMap<HeaderValue> {
&self.parts.headers
}
pub fn headers_mut(&mut self) -> &mut HeaderMap<HeaderValue> {
&mut self.parts.headers
}
pub fn set_headers(&mut self, headers: HeaderMap<HeaderValue>) {
self.parts.headers.extend(headers);
}
pub fn with_headers(mut self, headers: HeaderMap<HeaderValue>) -> Self {
self.parts.headers.extend(headers);
self
}
pub fn status(&self) -> StatusCode {
self.parts.status
}
pub fn status_mut(&mut self) -> &mut StatusCode {
&mut self.parts.status
}
pub fn set_status(&mut self, status: u16) {
self.parts.status =
StatusCode::from_u16(status).expect("Given status is not a valid status code");
}
pub fn with_status(mut self, status: u16) -> Self {
self.set_status(status);
self
}
pub fn body(self) -> Body {
self.body
}
pub fn body_mut(&mut self) -> &mut Body {
&mut self.body
}
pub fn set_body(&mut self, body: impl Into<String>) {
let body = body.into();
let _ = self.headers_mut().insert(
header::CONTENT_LENGTH,
HeaderValue::from_str(&body.len().to_string())
.expect("Given value for CONTENT_LENGTH is not valid"),
);
self.body = Body::from(body);
}
pub fn with_body(mut self, body: impl Into<String>) -> Self {
self.set_body(body);
self
}
pub fn redirect(&mut self, url: &'static str) {
self.set_status(301);
let _ = self
.headers_mut()
.insert(header::LOCATION, HeaderValue::from_static(url));
}
pub fn with_redirect(mut self, url: &'static str) -> Self {
self.redirect(url);
self
}
pub fn html(&mut self, html: impl Into<String>) {
let _ = self
.headers_mut()
.insert(header::CONTENT_TYPE, HeaderValue::from_static("text/html; charset=utf-8"));
self.set_body(html);
}
pub fn with_html(mut self, html: impl Into<String>) -> Self {
self.html(html);
self
}
pub fn css(&mut self, css: impl Fn(&mut CssBuilder)) {
let _ = self
.headers_mut()
.insert(header::CONTENT_TYPE, HeaderValue::from_static("text/css; charset=utf-8"));
let mut builder = CssBuilder::new();
css(&mut builder);
self.set_body(builder.get_body());
}
pub fn with_css(mut self, css: impl Fn(&mut CssBuilder)) -> Self {
self.css(css);
self
}
pub fn js(&mut self, js: impl Fn(&mut JsBuilder)) {
let _ = self.headers_mut().insert(
header::CONTENT_TYPE,
HeaderValue::from_static("application/javascript; charset=utf-8"),
);
let mut builder = JsBuilder::new();
js(&mut builder);
self.set_body(builder.get_body());
}
pub fn with_js(mut self, js: impl Fn(&mut JsBuilder)) -> Self {
self.js(js);
self
}
#[cfg(feature = "json")]
pub fn json<T: Serialize + Send + Sync>(&mut self, json: impl Fn(&mut JsonBuilder<T>)) {
let mut builder = JsonBuilder::new::<T>();
let _ = self.headers_mut().insert(
header::CONTENT_TYPE,
HeaderValue::from_static("application/json; charset=utf-8"),
);
json(&mut builder);
self.set_body(builder.get_body());
}
#[cfg(feature = "json")]
pub fn with_json<T: Serialize + Send + Sync>(
mut self,
json: impl Fn(&mut JsonBuilder<T>),
) -> Self {
self.json(json);
self
}
#[cfg(feature = "json")]
pub fn json_body<T: Serialize + Send + Sync>(&mut self, json: T) {
let mut builder = JsonBuilder::new::<T>();
let _ = self.headers_mut().insert(
header::CONTENT_TYPE,
HeaderValue::from_static("application/json; charset=utf-8"),
);
let _ = self.headers_mut().insert(
header::ACCESS_CONTROL_ALLOW_ORIGIN,
HeaderValue::from_static("*"),
);
builder.body(json);
self.set_body(builder.get_body());
}
pub fn into_hyper(self) -> response::Response<Body> {
response::Response::from_parts(self.parts, self.body)
}
pub fn build(
self,
) -> Box<Future<Item = response::Response<Body>, Error = DireError> + Send + 'static> {
Box::new(future::ok(self.into_hyper()))
}
}
impl Default for Response {
fn default() -> Response {
let (parts, body) = hyper::Response::new(Body::empty()).into_parts();
Response { body, parts }
}
}
pub struct CssBuilder {
inner: String,
}
impl CssBuilder {
fn new() -> CssBuilder {
CssBuilder::default()
}
fn get_body(&self) -> &str {
self.inner.as_str()
}
pub fn file(&mut self, mut file: File) {
match file.read_to_string(&mut self.inner) {
Ok(_) => {}
Err(_) => println!("Unable to write file contents"),
}
}
}
impl Default for CssBuilder {
fn default() -> CssBuilder {
CssBuilder {
inner: String::new(),
}
}
}
pub struct JsBuilder {
inner: String,
}
impl JsBuilder {
fn new() -> JsBuilder {
JsBuilder::default()
}
fn get_body(&self) -> &str {
self.inner.as_str()
}
pub fn file(&mut self, mut file: File) {
match file.read_to_string(&mut self.inner) {
Ok(_) => {}
Err(_) => println!("Unable to write file contents"),
}
}
}
impl Default for JsBuilder {
fn default() -> JsBuilder {
JsBuilder {
inner: String::new(),
}
}
}
#[cfg(feature = "json")]
pub struct JsonBuilder<T: Serialize + Send + Sync> {
wrapper: Wrapper<T>,
}
#[cfg(feature = "json")]
impl JsonBuilder<()> {
fn new<T: Serialize + Send + Sync>() -> JsonBuilder<T> {
JsonBuilder::default()
}
}
#[cfg(feature = "json")]
impl<T: Serialize + Send + Sync> JsonBuilder<T> {
pub fn body(&mut self, body: T) {
self.wrapper.set_result(body);
}
pub fn with_body(mut self, body: T) -> Self {
self.body(body);
self
}
pub fn error(&mut self, message: impl Into<String>) {
self.wrapper.add_message(message);
}
pub fn errors(&mut self, messages: Vec<impl Into<String>>) {
for message in messages {
self.wrapper.add_message(message);
}
}
pub fn code(&mut self, status: u16) {
self.wrapper.set_code(status);
}
pub fn with_code(mut self, status: u16) -> Self {
self.code(status);
self
}
pub fn status(&mut self, status: impl Into<String>) {
self.wrapper.set_status(status);
}
pub fn with_status(mut self, status: &str) -> Self {
self.status(status);
self
}
fn get_body(&self) -> String {
serde_json::to_string(&self.wrapper).expect("Can not transform struct into json")
}
}
#[cfg(feature = "json")]
impl<T: Serialize + Send + Sync> Default for JsonBuilder<T> {
fn default() -> JsonBuilder<T> {
Self {
wrapper: Wrapper::new(),
}
}
}
#[cfg(feature = "json")]
#[derive(Serialize)]
struct Wrapper<T: Serialize + Send + Sync> {
code: u16,
messages: Vec<String>,
result: Option<T>,
status: String,
}
#[cfg(feature = "json")]
impl<T: Serialize + Send + Sync> Wrapper<T> {
fn new() -> Wrapper<T> {
Wrapper::default()
}
fn add_message(&mut self, message: impl Into<String>) {
self.messages.push(message.into());
}
fn set_code(&mut self, code: u16) {
self.code = code;
}
fn set_status(&mut self, status: impl Into<String>) {
self.status = status.into();
}
fn set_result(&mut self, result: T) {
self.result = Some(result);
}
}
#[cfg(feature = "json")]
impl<T: Serialize + Send + Sync> Default for Wrapper<T> {
fn default() -> Wrapper<T> {
Self {
code: 200,
messages: Vec::new(),
result: None,
status: String::from("OK"),
}
}
}
pub struct Request {
body: Body,
parts: request::Parts,
}
impl Request {
fn new(body: Body, parts: request::Parts) -> Self {
Self { body, parts }
}
pub fn version(&self) -> Version {
self.parts.version
}
pub fn headers(&self) -> &HeaderMap<HeaderValue> {
&self.parts.headers
}
pub fn headers_mut(&mut self) -> &mut HeaderMap<HeaderValue> {
&mut self.parts.headers
}
pub fn parts(&self) -> &request::Parts {
&self.parts
}
pub fn method(&self) -> &Method {
&self.parts.method
}
pub fn uri(&self) -> &Uri {
&self.parts.uri
}
pub fn path(&self) -> &str {
self.parts.uri.path()
}
pub fn body(&self) -> &Body {
&self.body
}
pub fn into_body(self) -> Body {
self.body
}
}
#[macro_export]
macro_rules! headermap {
(@single $($x:tt)*) => (());
(@count $($rest:expr),*) => (<[()]>::len(&[$(headermap!(@single $rest)),*]));
($($key:expr => $value:expr,)+) => { headermap!($($key => $value),+) };
($($key:expr => $value:expr),*) => {
{
let _cap = headermap!(@count $($key),*);
let mut _map = ::direkuta::prelude::hyper::HeaderMap::with_capacity(_cap);
$(
let _ = _map.insert($key, ::direkuta::prelude::hyper::HeaderValue::from_str($value).unwrap());
)*
_map
}
};
}
pub mod prelude {
pub use super::{Capture, DireError, Direkuta, Logger, Middle, Request, Response, State};
pub mod builder {
pub use super::super::{Config, CssBuilder, JsBuilder, Router};
#[cfg(feature = "json")]
pub use super::super::JsonBuilder;
}
#[cfg(feature = "html")]
pub mod html {
pub use tera::{Context, Tera, Error as TeraError, ErrorKind as TeraErrorKind};
}
pub mod hyper {
pub use hyper::header::{self, HeaderMap, HeaderValue};
pub use hyper::{Body, Method};
}
#[cfg(feature = "runtime")]
pub mod rt {
use http::response::Response;
use hyper::Body;
use super::super::DireError;
pub type Res = Response<Body>;
pub type FutureResponse = Box<Future<Item = Res, Error = DireError> + Send + 'static>;
pub use futures::{future, Future, Stream};
}
}