-
Notifications
You must be signed in to change notification settings - Fork 86
add server::AsyncAcceptor with take_io function #144
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
Conversation
This is a handle on a server-side connection before configuration is available. This is a replacement for `LazyConfigAcceptor` which has no way to retrieve the client IO stream after an error. `AsyncAcceptor` has a function `take_io` which can be used take back ownership of the client IO stream. An example of this is when a client tries to connect to an TLS socket expecting it to be plain text connection. In this case `take_io` can be used to send a 400 response, "The plain HTTP request was sent to HTTPS port", back to the client. The reason for a new struct is not break the API of `LazyConfigAcceptor`.
} | ||
/// Takes back the client connection. Will return `None` if called more than once or if the | ||
/// connection has been accepted. | ||
pub fn take_io(&mut self) -> Option<IO> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see why we can't add a take_io()
method to the LazyConfigAcceptor
? I don't think adding a new type is the right direction here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't know how to deal with fact that the new
function works like an async function. I guess I can add a take_io
method even so? I didn't try that (I'm a brand new rust programmer).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just gave it a go but the problem is that the acceptor.await
takes ownership of acceptor
so I can't call the take_io
method 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can try
tokio::pin!(acceptor);
let ret = futures::future::poll_fn(|cx| acceptor.as_mut().poll(cx)).await;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That worked! I didn't need to call poll_fn
let mut acceptor = LazyConfigAcceptor::new(rustls::server::Acceptor::default(), stream);
pin_mut!(acceptor);
match acceptor.as_mut().await {
...
Err(err) => {
if let Some(mut stream) = acceptor.take_io() {
stream
.write_all(
format!("HTTP/1.1 500 Internal Server Error\r\n\r\n\r\n{:?}\n", err) /* */
.as_bytes(),
)
.await
.unwrap();
}
}
}
I'll close this and make another PR.
This is a handle on a server-side connection before configuration is available. This is a replacement for
LazyConfigAcceptor
which has no way to retrieve the client IO stream after an error.AsyncAcceptor
has a functiontake_io
which can be used take back ownership of the client IO stream.An example of this is when a client tries to connect to an TLS socket expecting it to be plain text connection. In this case
take_io
can be used to send a 400 response, "The plain HTTP request was sent to HTTPS port", back to the client.The reason for a new struct is not break the API of
LazyConfigAcceptor
.