Skip to content

H2Upgraded::poll_write returns Ok(0) while tokio-rustls assumes Ok(0) is 'successful' #3801

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

Closed
hatoo opened this issue Nov 30, 2024 · 4 comments
Labels
C-bug Category: bug. Something is wrong. This is bad!

Comments

@hatoo
Copy link
Contributor

hatoo commented Nov 30, 2024

Version
List the version(s) of hyper, and any relevant hyper dependency (such as h2 if this is related to HTTP/2).
hyper: commit 12717d1

Platform
The output of uname -a (UNIX), or version and 32 or 64-bit (Windows)

WSL2 Ubuntu on Windows 11

❯ uname -a
Linux WindowsNVMe 5.15.167.4-microsoft-standard-WSL2 #1 SMP Tue Nov 5 00:21:55 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux

Description

When we wrap tokio-rustls around HTTP2 Upgraded stream, tokio-rustls will infinite loop because Upgraded stream returns Ok(0) on poll_write when shutdown. relevant issue rustls/tokio-rustls#92

hyper/src/proto/h2/mod.rs

Lines 329 to 337 in 12717d1

let cnt = match ready!(self.send_stream.poll_capacity(cx)) {
None => Some(0),
Some(Ok(cnt)) => self
.send_stream
.write(&buf[..cnt], false)
.ok()
.map(|()| cnt),
Some(Err(_)) => None,
};

I've found that when I replace None => Some(0), to None => None, it works fine.

Honestly, I don't know the issue should be resolved in either hyper or tokio-rustls. But this issue is important when I implement HTTP2 proxy.

@hatoo hatoo added the C-bug Category: bug. Something is wrong. This is bad! label Nov 30, 2024
@seanmonstar
Copy link
Member

tokio-rustls will infinite loop because Upgraded stream returns Ok(0) on poll_write when shutdown.

What do you mean? As opposed to what?

@hatoo
Copy link
Contributor Author

hatoo commented Dec 2, 2024

https://github.com/rustls/tokio-rustls/blob/66fb0ae98fbc9e71d5aa855d45e88ca8d53f95f3/src/common/mod.rs#L330-L334

tokio-rustls writes the remaining data on poll_shutdown and because H2Upgraded::poll_write always returns Ok(0) on the write (perhaps because the stream is already closed by the other side), tokio-rustls goes an infinite loop.

@seanmonstar
Copy link
Member

Oh OK. That's a bug in tokio-rustls, then. Returning Ok(0) is the normal way for IO resources to indicate no more bytes are allowed (see https://doc.rust-lang.org/std/io/trait.Write.html#tymethod.write).

@hatoo
Copy link
Contributor Author

hatoo commented Dec 4, 2024

Fixed in tokio-rustls side rustls/tokio-rustls#93

@hatoo hatoo closed this as completed Dec 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: bug. Something is wrong. This is bad!
Projects
None yet
Development

No branches or pull requests

2 participants