Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create an SSL example with tokio-tls #1942

Closed
trezm opened this issue Sep 15, 2019 · 6 comments
Closed

Create an SSL example with tokio-tls #1942

trezm opened this issue Sep 15, 2019 · 6 comments

Comments

@trezm
Copy link

trezm commented Sep 15, 2019

I'm attempting to get a version of a hyper server running with TLS off of the master branch (i.e. with async/await.) This is proving harder than expected, and I'd love for there to be an updated example of a hyper server using the tls acceptor.

I'd be happy to update the code myself, but don't quite see how it fits in to an example like this. Where can I add in a a TcpStream -> TlsStream portion?

@trezm
Copy link
Author

trezm commented Sep 16, 2019

So, was hacking on this a little more and now have this:

      let listener = TcpListener::bind(&addr).await.unwrap();
      let mut incoming = listener.incoming();
      let server = Builder
          ::new(incoming.filter_map(|socket| {
            async {
              let stream: TcpStream = socket.unwrap();

              Some(
                Ok::<_, hyper::Error>(
                  _arc_acceptor.clone().accept(stream).await.unwrap()
                )
              )
            }
          }), Http::new())
          .serve(service);

      server.await?;

but am getting a few errors that I'm confused about:

    |
104 |           .serve(service);
    |            ^^^^^ the trait `tokio_io::async_read::AsyncRead` is not implemented for `tokio_tls::TlsStream<tokio_net::tcp::stream::TcpStream>`
    |
106 |       server.await?;
    |       ^^^^^^^^^^^^ the trait `tokio_io::async_read::AsyncRead` is not implemented for `tokio_tls::TlsStream<tokio_net::tcp::stream::TcpStream>`
    |
    = note: required because of the requirements on the impl of `std::future::Future` for `hyper::server::Server<futures_util::stream::filter_map::FilterMap<tokio_net::tcp::incoming::Incoming, impl std::future::Future, [closure@/Users/pete/dev/thruster/thruster-server/src/ssl_hyper_server.rs:93:37: 103:12 _arc_acceptor:_]>, hyper::service::make_service::MakeServiceFn<[closure@/Users/pete/dev/thruster/thruster-server/src/ssl_hyper_server.rs:75:37: 88:8 arc_app:_]>>`
    = note: required by `std::future::poll_with_tls_context`

All of those errors apply to both AsyncRead and AsyncWrite (so that's half of them above.) I'm confused though, as both TcpStream and TlsStream implement both of those traits (as long as the TlsStream's generic implements those traits as well, which it should since its generic is TcpStream.)

On a little further thought -- I have to use tokio master in order to get this change, I wonder if it's because hyper isn't using the same?

@seanmonstar
Copy link
Member

Whenever I see those errors, my first guess is that the Cargo.lock will show multiple version of tokio in the tree. That'd explain why the traits don't match.

@trezm
Copy link
Author

trezm commented Sep 17, 2019 via email

@trezm
Copy link
Author

trezm commented Sep 26, 2019

After upgrading to the most recent versions of tokio and hyper, I believe I have a working solution! That being said, after about 10 minutes, the server no longer accepts connections and has very similar symptoms to #950.

Still not sure what's going on here, but I'll keep digging in.

Here is the relevant code snippet I'm using for SSL:

      let tls_acceptor =
        tokio_tls::TlsAcceptor::from(
          native_tls::TlsAcceptor::builder(cert)
            .build()
            .expect("Could not create TLS acceptor.")
          );
      let _arc_acceptor = Arc::new(tls_acceptor);
      let listener = TcpListener::bind(&addr).await.unwrap();
      let incoming = listener.incoming();
      let server = Builder
          ::new(hyper::server::accept::from_stream(incoming.filter_map(|socket| {
            async {
              match socket {
                Ok(stream) => {
                  match _arc_acceptor.clone().accept(stream).await {
                    Ok(val) => Some(Ok::<_, hyper::Error>(val)),
                    Err(e) => {
                      println!("TLS error: {}", e);
                      None
                    }
                  }
                },
                Err(e) => {
                  println!("TCP socket error: {}", e);
                  None
                }
              }
            }
          })), Http::new())
          .serve(service);

      server.await?;

@trezm
Copy link
Author

trezm commented Sep 26, 2019

A little more color to this -- it seems to only have the hang problem when run in my kubernetes setup. I'll do a little more digging to see if it's a docker thing or an architecture thing (kubernetes is running on an arm64v7 cluster.)

@seanmonstar
Copy link
Member

Glad you were able to get it working!

trezm added a commit to trezm/hyper that referenced this issue Oct 22, 2019
Adds an example using hyper + ssl for a server.

Should resolve the closed issue hyperium#1942
trezm added a commit to trezm/hyper that referenced this issue Nov 14, 2019
Adds an example using hyper + ssl for a server.

Should resolve the closed issue hyperium#1942
trezm added a commit to trezm/hyper that referenced this issue Nov 14, 2019
Adds an example using hyper + ssl for a server.

Should resolve the closed issue hyperium#1942
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants