async-std icon indicating copy to clipboard operation
async-std copied to clipboard

Hyper not responding on async-std 1.7.0

Open rakshith-ravi opened this issue 5 years ago • 2 comments

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.

rakshith-ravi avatar Nov 16 '20 06:11 rakshith-ravi

Probably you need to enable the tokio02 feature of async-std.

taiki-e avatar Nov 18 '20 16:11 taiki-e

Tried that. That doesn't seem to fix it either.

rakshith-ravi avatar Nov 19 '20 06:11 rakshith-ravi