Created
November 3, 2019 03:55
-
-
Save Karl-Han/1b393ad4a9b7e67e8de317287c0ef2de to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![cfg(feature="unstable")] | |
extern crate futures; | |
extern crate hyper; | |
use { | |
hyper::{ | |
// Miscellaneous types from Hyper for working with HTTP. | |
Body, Client, Request, Response, Server, Uri, | |
// This function turns a closure which returns a future into an | |
// implementation of the the Hyper `Service` trait, which is an | |
// asynchronous function from a generic `Request` to a `Response`. | |
service::service_fn, | |
// A function which runs a future to completion using the Hyper runtime. | |
rt::run, | |
}, | |
futures::{ | |
// Extension trait for futures 0.1 futures, adding the `.compat()` method | |
// which allows us to use `.await` on 0.1 futures. | |
compat::Future01CompatExt, | |
// Extension traits providing additional methods on futures. | |
// `FutureExt` adds methods that work for all futures, whereas | |
// `TryFutureExt` adds methods to futures that return `Result` types. | |
future::{FutureExt, TryFutureExt}, | |
}, | |
std::net::SocketAddr, | |
}; | |
async fn serve_req(_req: Request<Body>) -> Result<Response<Body>, hyper::Error> { | |
// Always return successfully with a response containing a body with | |
// a friendly greeting ;) | |
Ok(Response::new(Body::from("hello, world!"))) | |
} | |
async fn run_server(addr: SocketAddr) { | |
println!("Listening on http://{}", addr); | |
// Create a server bound on the provided address | |
let serve_future = Server::bind(&addr) | |
// Serve requests using our `async serve_req` function. | |
// `serve` takes a closure which returns a type implementing the | |
// `Service` trait. `service_fn` returns a value implementing the | |
// `Service` trait, and accepts a closure which goes from request | |
// to a future of the response. To use our `serve_req` function with | |
// Hyper, we have to box it and put it in a compatability | |
// wrapper to go from a futures 0.3 future (the kind returned by | |
// `async fn`) to a futures 0.1 future (the kind used by Hyper). | |
.serve(|| service_fn(|req| serve_req(req).boxed().compat())); | |
// Wait for the server to complete serving or exit with an error. | |
// If an error occurred, print it to stderr. | |
if let Err(e) = serve_future.compat().await { | |
eprintln!("server error: {}", e); | |
} | |
} | |
fn main() { | |
// Set the address to run our socket on. | |
let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); | |
// Call our `run_server` function, which returns a future. | |
// As with every `async fn`, for `run_server` to do anything, | |
// the returned future needs to be run. Additionally, | |
// we need to convert the returned future from a futures 0.3 future into a | |
// futures 0.1 future. | |
let futures_03_future = run_server(addr); | |
let futures_01_future = futures_03_future.unit_error().boxed().compat(); | |
// Finally, we can run the future to completion using the `run` function | |
// provided by Hyper. | |
run(futures_01_future); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment