-
-
Notifications
You must be signed in to change notification settings - Fork 25
/
doc_server.rs
59 lines (53 loc) · 1.8 KB
/
doc_server.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
// This example serves the docs from `target/doc/`.
//
// Run `cargo doc && cargo run --example doc_server`, then
// point your browser to http://localhost:3000/
use std::io::Error as IoError;
use std::net::SocketAddr;
use std::path::Path;
use http::response::Builder as ResponseBuilder;
use http::{header, StatusCode};
use hyper::service::service_fn;
use hyper::{Request, Response};
use hyper_staticfile::{Body, Static};
use hyper_util::rt::TokioIo;
use tokio::net::TcpListener;
async fn handle_request<B>(req: Request<B>, static_: Static) -> Result<Response<Body>, IoError> {
if req.uri().path() == "/" {
let res = ResponseBuilder::new()
.status(StatusCode::MOVED_PERMANENTLY)
.header(header::LOCATION, "/hyper_staticfile/")
.body(Body::Empty)
.expect("unable to build response");
Ok(res)
} else {
static_.clone().serve(req).await
}
}
#[tokio::main]
async fn main() {
let static_ = Static::new(Path::new("target/doc/"));
let addr: SocketAddr = ([127, 0, 0, 1], 3000).into();
let listener = TcpListener::bind(addr)
.await
.expect("Failed to create TCP listener");
eprintln!("Doc server running on http://{}/", addr);
loop {
let (stream, _) = listener
.accept()
.await
.expect("Failed to accept TCP connection");
let static_ = static_.clone();
tokio::spawn(async move {
if let Err(err) = hyper::server::conn::http1::Builder::new()
.serve_connection(
TokioIo::new(stream),
service_fn(move |req| handle_request(req, static_.clone())),
)
.await
{
eprintln!("Error serving connection: {:?}", err);
}
});
}
}