|
@@ -1,20 +1,23 @@
|
|
|
extern crate futures;
|
|
|
-extern crate tokio_proto;
|
|
|
-extern crate tokio_service;
|
|
|
extern crate hyper;
|
|
|
+extern crate num_cpus;
|
|
|
#[macro_use]
|
|
|
extern crate serde_derive;
|
|
|
extern crate serde_json;
|
|
|
-extern crate num_cpus;
|
|
|
-extern crate mime;
|
|
|
+extern crate tokio;
|
|
|
+
|
|
|
+use std::env;
|
|
|
+use std::net::SocketAddr;
|
|
|
+use std::process;
|
|
|
+
|
|
|
+use futures::{future, Future, Stream};
|
|
|
|
|
|
-use tokio_proto::TcpServer;
|
|
|
-use futures::future;
|
|
|
use hyper::Method::Get;
|
|
|
use hyper::header::{ContentLength, ContentType, Server};
|
|
|
use hyper::StatusCode::NotFound;
|
|
|
use hyper::server::{Http, Service, Request, Response};
|
|
|
-use std::net::SocketAddr;
|
|
|
+
|
|
|
+use tokio::net::TcpListener;
|
|
|
|
|
|
static HELLOWORLD: &'static [u8] = b"Hello, world!";
|
|
|
|
|
@@ -36,7 +39,7 @@ impl Service for TechEmpower {
|
|
|
(&Get, "/plaintext") => {
|
|
|
Response::new()
|
|
|
.with_header(ContentLength(HELLOWORLD.len() as u64))
|
|
|
- .with_header(ContentType(mime::TEXT_PLAIN))
|
|
|
+ .with_header(ContentType::text())
|
|
|
.with_body(HELLOWORLD)
|
|
|
}
|
|
|
(&Get, "/json") => {
|
|
@@ -44,7 +47,7 @@ impl Service for TechEmpower {
|
|
|
let rep_body = serde_json::to_vec(&rep).unwrap();
|
|
|
Response::new()
|
|
|
.with_header(ContentLength(rep_body.len() as u64))
|
|
|
- .with_header(ContentType(mime::APPLICATION_JSON))
|
|
|
+ .with_header(ContentType::json())
|
|
|
.with_body(rep_body)
|
|
|
}
|
|
|
_ => Response::new().with_status(NotFound),
|
|
@@ -53,15 +56,52 @@ impl Service for TechEmpower {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+fn configure() -> Http {
|
|
|
+ let pipeline = {
|
|
|
+ let mut args = env::args();
|
|
|
+ args.next().expect("first arg is this binary");
|
|
|
+
|
|
|
+ args.next()
|
|
|
+ .map(|arg| {
|
|
|
+ if arg == "pipeline" {
|
|
|
+ true
|
|
|
+ } else {
|
|
|
+ eprintln!("unknown second argument: {:?}", arg);
|
|
|
+ process::exit(1);
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .unwrap_or(false)
|
|
|
+ };
|
|
|
+
|
|
|
+ // Set our hyper options
|
|
|
+ // (pipeline is desired for the plaintext route)
|
|
|
+ let mut http = Http::<hyper::Chunk>::new();
|
|
|
+ http.pipeline(pipeline);
|
|
|
+ http
|
|
|
+}
|
|
|
+
|
|
|
fn main() {
|
|
|
- let addr: SocketAddr = "0.0.0.0:8080".parse().unwrap();
|
|
|
- let mut http = Http::new();
|
|
|
- http.pipeline(true);
|
|
|
- let mut srv = TcpServer::new(http, addr);
|
|
|
- println!("Listening on http://{} using {} threads",
|
|
|
- addr,
|
|
|
- num_cpus::get());
|
|
|
-
|
|
|
- srv.threads(num_cpus::get());
|
|
|
- srv.serve(move || Ok(TechEmpower))
|
|
|
+ // Check for some runtime configuration
|
|
|
+ let http = configure();
|
|
|
+
|
|
|
+ // Bind to 0.0.0.0:8080
|
|
|
+ let addr = SocketAddr::from(([0, 0, 0, 0], 8080));
|
|
|
+ let tcp = TcpListener::bind(&addr)
|
|
|
+ .expect("couldn't bind to addr");
|
|
|
+
|
|
|
+ // For every accepted connection, spawn an HTTP task
|
|
|
+ let server = tcp.incoming()
|
|
|
+ .for_each(move |sock| {
|
|
|
+ let _ = sock.set_nodelay(true);
|
|
|
+ let conn = http.serve_connection(sock, TechEmpower)
|
|
|
+ .map_err(|e| eprintln!("connection error: {}", e));
|
|
|
+
|
|
|
+ tokio::spawn(conn);
|
|
|
+
|
|
|
+ Ok(())
|
|
|
+ })
|
|
|
+ .map_err(|e| eprintln!("accept error: {}", e));
|
|
|
+
|
|
|
+ println!("Listening on http://{}", addr);
|
|
|
+ tokio::run(server);
|
|
|
}
|