async-std
async-std copied to clipboard
Hyper not responding on async-std 1.7.0
Hey,
I have been using hyper.rs with async-std as a compat layer. However, ever since 1.7.0 released, I've not been able to get hyper.rs to run with async-std at all. I have tried to build a minimal reproducible example and have the following:
main.rs
mod async_compat;
use async_compat::HyperStream;
use async_std::net::TcpListener;
use hyper::{
service::{make_service_fn, service_fn},
Body, Error as HyperError, Request as HyperRequest, Response as HyperResponse, Server,
};
use std::net::SocketAddr;
#[async_std::main]
pub async fn main() {
let bind_addr = SocketAddr::from(([127, 0, 0, 1], 3000));
async move {
let service = make_service_fn(|_: &HyperStream| {
async move {
Ok::<_, HyperError>(service_fn(move |_: HyperRequest<Body>| {
async move {
let hyper_response = HyperResponse::builder();
Ok::<HyperResponse<Body>, HyperError>(
hyper_response
.status(200)
.body(Body::from("Hello world"))
.unwrap(),
)
}
}))
}
});
let tcp_listener = TcpListener::bind(&bind_addr).await.unwrap();
Server::builder(async_compat::HyperListener(tcp_listener))
.executor(async_compat::HyperExecutor)
.serve(service)
.await
.unwrap();
}
.await
}
async_compat.rs
use std::{
pin::Pin,
task::{Context, Poll},
};
use async_std::{
io,
net::{TcpListener, TcpStream},
prelude::*,
task,
};
use hyper::server::accept::Accept;
#[derive(Clone)]
pub struct HyperExecutor;
impl<F> hyper::rt::Executor<F> for HyperExecutor
where
F: Future + Send + 'static,
F::Output: Send + 'static,
{
fn execute(&self, fut: F) {
task::spawn(fut);
}
}
pub struct HyperListener(pub TcpListener);
impl Accept for HyperListener {
type Conn = HyperStream;
type Error = io::Error;
#[allow(unused_mut)]
fn poll_accept(
mut self: Pin<&mut Self>,
cx: &mut Context,
) -> Poll<Option<Result<Self::Conn, Self::Error>>> {
let stream = task::ready!(Pin::new(&mut self.0.incoming()).poll_next(cx)).unwrap()?;
Poll::Ready(Some(Ok(HyperStream(stream))))
}
}
pub struct HyperStream(pub TcpStream);
impl tokio::io::AsyncRead for HyperStream {
fn poll_read(
mut self: Pin<&mut Self>,
cx: &mut Context,
buf: &mut [u8],
) -> Poll<io::Result<usize>> {
Pin::new(&mut self.0).poll_read(cx, buf)
}
}
impl tokio::io::AsyncWrite for HyperStream {
fn poll_write(
mut self: Pin<&mut Self>,
cx: &mut Context,
buf: &[u8],
) -> Poll<io::Result<usize>> {
Pin::new(&mut self.0).poll_write(cx, buf)
}
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<io::Result<()>> {
Pin::new(&mut self.0).poll_flush(cx)
}
fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<io::Result<()>> {
Pin::new(&mut self.0).poll_close(cx)
}
}
Cargo.toml
[package]
authors = ["Rakshith Ravi"]
edition = "2018"
name = "hyper-test"
version = "0.1.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
async-std = {version = "1.7.0", features = ["attributes"]}
futures = "0.3.8"
hyper = "0.13.9"
tokio = {version = "0.2.22", default-features = false}
When I visit http://localhost:3000 with this code, I get no response. The browser keeps loading forever and no response is sent whatsoever. Any help would be appreciated.
Probably you need to enable the tokio02 feature of async-std.
Tried that. That doesn't seem to fix it either.