1use std::io::Cursor;
2use std::sync::Arc;
3use std::fs::File;
4use std::net::SocketAddr;
5use futures::{Poll, Async};
6use futures::future::{self, Future};
7use hyper::body::Payload;
8use hyper::{self, StatusCode, Request, Response, Server};
9use hyper::service::{NewService, Service};
10use hyper::server::conn::AddrIncoming;
11use hyper::header::{CONTENT_TYPE, CONTENT_LENGTH, CACHE_CONTROL, EXPIRES, PRAGMA, ACCESS_CONTROL_ALLOW_ORIGIN};
12use http::response::Builder;
13use memmap::Mmap;
14use mime_guess::Mime;
15
16pub enum BodyContents {
17 Owned( Vec< u8 > ),
18 Mmap( Mmap )
19}
20
21impl AsRef< [u8] > for BodyContents {
22 fn as_ref( &self ) -> &[u8] {
23 match *self {
24 BodyContents::Owned( ref buffer ) => &buffer,
25 BodyContents::Mmap( ref map ) => &map
26 }
27 }
28}
29
30pub struct Body( Option< Cursor< BodyContents > > );
31
32impl Payload for Body {
33 type Data = Cursor< BodyContents >;
34 type Error = hyper::Error;
35
36 fn poll_data(&mut self) -> Poll< Option< Self::Data >, Self::Error > {
37 Ok( Async::Ready( self.0.take() ) )
38 }
39}
40
41impl From< Vec< u8 > > for Body {
42 fn from( buffer: Vec< u8 > ) -> Self {
43 Body( Some( Cursor::new( BodyContents::Owned( buffer ) ) ) )
44 }
45}
46
47impl From< Mmap > for Body {
48 fn from( map: Mmap ) -> Self {
49 Body( Some( Cursor::new( BodyContents::Mmap( map ) ) ) )
50 }
51}
52
53pub type ResponseFuture = Box< Future< Item = Response< Body >, Error = hyper::Error > + Send >;
54pub type FnHandler = Box< Fn( Request< hyper::Body > ) -> ResponseFuture + Send + Sync >;
55pub type ServiceFuture = Box< Future< Item = SimpleService, Error = hyper::Error > + Send >;
56
57pub struct SimpleService {
58 handler: Arc< FnHandler >
59}
60
61impl Service for SimpleService {
62 type ReqBody = hyper::Body;
63 type ResBody = Body;
64 type Error = hyper::Error;
65
66 type Future = ResponseFuture;
67
68 fn call( &mut self, request: Request< hyper::Body > ) -> ResponseFuture {
69 ( *self.handler )( request )
70 }
71}
72
73pub struct NewSimpleService {
74 handler: Arc< FnHandler >
75}
76
77impl NewService for NewSimpleService {
78 type ReqBody = hyper::Body;
79 type ResBody = Body;
80 type Error = hyper::Error;
81
82 type Service = SimpleService;
83 type Future = ServiceFuture;
84 type InitError = hyper::Error;
85
86 fn new_service( &self ) -> Self::Future {
87 Box::new( future::ok( SimpleService {
88 handler: self.handler.clone()
89 } ) )
90 }
91}
92
93pub struct SimpleServer {
94 server: Server< AddrIncoming, NewSimpleService >
95}
96
97impl SimpleServer {
98 pub fn new< F >( address: &SocketAddr, handler: F ) -> Self
99 where
100 F: Send + Sync + 'static + Fn( Request< hyper::Body > ) -> ResponseFuture
101 {
102 let server = Server::bind( address )
103 .serve( NewSimpleService {
104 handler: Arc::new( Box::new( handler ) )
105 } );
106 SimpleServer { server }
107 }
108
109 pub fn server_addr( &self ) -> SocketAddr {
110 self.server.local_addr()
111 }
112
113 pub fn run( self ) {
114 hyper::rt::run(self.server.map_err(|e| {
115 eprintln!("server error: {}", e);
116 }));
117 }
118}
119
120fn add_headers( builder: &mut Builder ) {
121 builder.header( CACHE_CONTROL, "no-cache" );
122 builder.header( CACHE_CONTROL, "no-store" );
123 builder.header( CACHE_CONTROL, "must-revalidate" );
124 builder.header( EXPIRES, "0" );
125 builder.header( PRAGMA, "no-cache" );
126 builder.header( ACCESS_CONTROL_ALLOW_ORIGIN, "*" );
127}
128
129pub fn response_from_file( mime_type: &Mime, fp: File ) -> ResponseFuture {
130 if let Ok( metadata ) = fp.metadata() {
131 if metadata.len() == 0 {
132 return response_from_data( mime_type, Vec::new() );
134 }
135 }
136
137 let map = match unsafe { Mmap::map( &fp ) } {
138 Ok( map ) => map,
139 Err( error ) => {
140 warn!( "Mmap failed: {}", error );
141 let status = StatusCode::INTERNAL_SERVER_ERROR;
142 let message = format!( "{}\n\n{}", status, error ).into_bytes();
143 let mut response = sync_response_from_data(
144 &"text/plain".parse().unwrap(),
145 message );
146 *response.status_mut() = status;
147 return Box::new( future::ok( response ) );
148 }
149 };
150
151 let length = map.len();
152 let body: Body = map.into();
153 let mut response = Response::builder();
154 add_headers( &mut response );
155 response.header( CONTENT_TYPE, mime_type.to_string() );
156 response.header( CONTENT_LENGTH, length );
157
158 Box::new( future::ok( response.body( body ).unwrap() ) )
159}
160
161fn sync_response_from_data( mime_type: &Mime, data: Vec< u8 > ) -> Response< Body > {
162 let length = data.len();
163 let body: Body = data.into();
164 let mut response = Response::builder();
165 add_headers( &mut response );
166 response.header( CONTENT_TYPE, mime_type.to_string());
167 response.header( CONTENT_LENGTH, length );
168 response.body( body ).unwrap()
169}
170
171pub fn response_from_data( mime_type: &Mime, data: Vec< u8 > ) -> ResponseFuture {
172 Box::new( future::ok( sync_response_from_data( mime_type, data ) ) )
173}
174
175pub fn response_from_status( status: StatusCode ) -> ResponseFuture {
176 let mut response = sync_response_from_data(
177 &"text/plain".parse().unwrap(),
178 format!( "{}", status ).into_bytes() );
179 *response.status_mut() = status;
180 Box::new( future::ok( response ) )
181}