hyper v0.13.0
I am implementing an HTTP server by following examples
pub fn start(port : u16,
cipher_key : &str,
upstream_tx : UnboundedSender<InternalMessage>){
let addr = ([0, 0, 0, 0], port).into();
let server = Server::bind(&addr).http1_only(true).serve(MakeSvc{
srv : Arc::new(StreamingServer::new(cipher_key, upstream_tx)),
});
tokio::spawn(async move {
server.await.expect("hyper.server fault error");
});
}
pub struct MakeSvc {
srv : Arc<StreamingServer>
}
impl<T> Service<T> for MakeSvc {
type Response = Svc;
type Error = std::io::Error;
type Future = future::Ready<Result<Self::Response, Self::Error>>;
fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
Ok(()).into()
}
fn call(&mut self, _: T) -> Self::Future {
future::ok(Svc{
srv : self.srv.clone(),
})
}
}
pub struct Svc {
srv : Arc<StreamingServer>
}
impl Service<Request<Body>> for Svc {
type Response = Response<Body>;
type Error = hyper::Error;
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>>>>;
fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
Ok(()).into()
}
fn call(&mut self, req: Request<Body>) -> Self::Future {
let path : &str = req.uri().path();
let len : usize = PATH_PREFIX.len() as usize;
if req.method() == Method::PUT && path.starts_with(PATH_PREFIX) && path.len() > len {
let key = &path[len..].to_string();
let ar = req.into_body()
.map_err(|e| Error::new(ErrorKind::Other, format!("{:?}", e)) )
.into_async_read();
let srv = self.srv.clone();
let fut = async move {
srv.handle_client_request(key, ar).await;
let rsp = Response::builder();
let body = Body::from(Vec::new());
let rsp = rsp.status(200).body(body).unwrap();
Ok(rsp)
};
return Box::pin(fut)
}
let rsp = Response::builder();
let body = Body::from(Vec::new());
let rsp = rsp.status(404).body(body).unwrap();
let fut = async {
Ok(rsp)
};
Box::pin(fut)
}
}
It seems I encounter thread-safety issue with Future, have no idea how to solve. Can any body help? Thank you in advance.
| let server = Server::bind(&addr).http1_only(true).serve(MakeSvc{
| ^^^^^ `(dyn core::future::future::Future<Output = std::result::Result<http::response::Response<hyper::body::body::Body>, hyper::error::Error>> + 'static)` cannot be sent between threads safely
|
= help: the trait `std::marker::Send` is not implemented for `(dyn core::future::future::Future<Output = std::result::Result<http::response::Response<hyper::body::body::Body>, hyper::error::Error>> + 'static)`
= note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<(dyn core::future::future::Future<Output = std::result::Result<http::response::Response<hyper::body::body::Body>, hyper::error::Error>> + 'static)>`
= note: required because it appears within the type `std::boxed::Box<(dyn core::future::future::Future<Output = std::result::Result<http::response::Response<hyper::body::body::Body>, hyper::error::Error>> + 'static)>`
= note: required because it appears within the type `std::pin::Pin<std::boxed::Box<(dyn core::future::future::Future<Output = std::result::Result<http::response::Response<hyper::body::body::Body>, hyper::error::Error>> + 'static)>>`
= note: required because it appears within the type `hyper::proto::h2::server::H2StreamState<std::pin::Pin<std::boxed::Box<(dyn core::future::future::Future<Output = std::result::Result<http::response::Response<hyper::body::body::Body>, hyper::error::Error>> + 'static)>>, hyper::body::body::Body>`
= note: required because it appears within the type `hyper::proto::h2::server::H2Stream<std::pin::Pin<std::boxed::Box<(dyn core::future::future::Future<Output = std::result::Result<http::response::Response<hyper::body::body::Body>, hyper::error::Error>> + 'static)>>, hyper::body::body::Body>`
= note: required because of the requirements on the impl of `hyper::common::exec::H2Exec<std::pin::Pin<std::boxed::Box<(dyn core::future::future::Future<Output = std::result::Result<http::response::Response<hyper::body::body::Body>, hyper::error::Error>> + 'static)>>, hyper::body::body::Body>` for `hyper::common::exec::Exec`