don't throw eof error to keep consistency (#79)
This commit is contained in:
parent
5aae337945
commit
56855b7166
@ -119,9 +119,9 @@ where
|
|||||||
|
|
||||||
Poll::Ready(Ok(()))
|
Poll::Ready(Ok(()))
|
||||||
}
|
}
|
||||||
Poll::Ready(Err(ref e)) if e.kind() == io::ErrorKind::ConnectionAborted => {
|
Poll::Ready(Err(err)) if err.kind() == io::ErrorKind::ConnectionAborted => {
|
||||||
this.state.shutdown_read();
|
this.state.shutdown_read();
|
||||||
Poll::Ready(Ok(()))
|
Poll::Ready(Err(err))
|
||||||
}
|
}
|
||||||
output => output,
|
output => output,
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,6 @@ pub struct Stream<'a, IO, C> {
|
|||||||
pub io: &'a mut IO,
|
pub io: &'a mut IO,
|
||||||
pub session: &'a mut C,
|
pub session: &'a mut C,
|
||||||
pub eof: bool,
|
pub eof: bool,
|
||||||
pub unexpected_eof: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, IO: AsyncRead + AsyncWrite + Unpin, C, SD> Stream<'a, IO, C>
|
impl<'a, IO: AsyncRead + AsyncWrite + Unpin, C, SD> Stream<'a, IO, C>
|
||||||
@ -77,7 +76,6 @@ where
|
|||||||
// The state so far is only used to detect EOF, so either Stream
|
// The state so far is only used to detect EOF, so either Stream
|
||||||
// or EarlyData state should both be all right.
|
// or EarlyData state should both be all right.
|
||||||
eof: false,
|
eof: false,
|
||||||
unexpected_eof: false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,16 +236,12 @@ where
|
|||||||
cx: &mut Context<'_>,
|
cx: &mut Context<'_>,
|
||||||
buf: &mut ReadBuf<'_>,
|
buf: &mut ReadBuf<'_>,
|
||||||
) -> Poll<io::Result<()>> {
|
) -> Poll<io::Result<()>> {
|
||||||
let prev = buf.remaining();
|
|
||||||
|
|
||||||
while buf.remaining() != 0 {
|
|
||||||
let mut io_pending = false;
|
let mut io_pending = false;
|
||||||
|
|
||||||
// read a packet
|
// read a packet
|
||||||
while !self.eof && self.session.wants_read() {
|
while !self.eof && self.session.wants_read() {
|
||||||
match self.read_io(cx) {
|
match self.read_io(cx) {
|
||||||
Poll::Ready(Ok(0)) => {
|
Poll::Ready(Ok(0)) => {
|
||||||
self.eof = true;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Poll::Ready(Ok(_)) => (),
|
Poll::Ready(Ok(_)) => (),
|
||||||
@ -259,49 +253,36 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return match self.session.reader().read(buf.initialize_unfilled()) {
|
match self.session.reader().read(buf.initialize_unfilled()) {
|
||||||
// If Rustls returns `Ok(0)` (while `buf` is non-empty), the peer closed the
|
// If Rustls returns `Ok(0)` (while `buf` is non-empty), the peer closed the
|
||||||
// connection with a `CloseNotify` message and no more data will be forthcoming.
|
// connection with a `CloseNotify` message and no more data will be forthcoming.
|
||||||
Ok(0) => break,
|
//
|
||||||
|
|
||||||
// Rustls yielded more data: advance the buffer, then see if more data is coming.
|
// Rustls yielded more data: advance the buffer, then see if more data is coming.
|
||||||
|
//
|
||||||
|
// We don't need to modify `self.eof` here, because it is only a temporary mark.
|
||||||
|
// rustls will only return 0 if is has received `CloseNotify`,
|
||||||
|
// in which case no additional processing is required.
|
||||||
Ok(n) => {
|
Ok(n) => {
|
||||||
buf.advance(n);
|
buf.advance(n);
|
||||||
|
Poll::Ready(Ok(()))
|
||||||
if self.eof || io_pending {
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rustls doesn't have more data to yield, but it believes the connection is open.
|
// Rustls doesn't have more data to yield, but it believes the connection is open.
|
||||||
Err(ref err) if err.kind() == io::ErrorKind::WouldBlock => {
|
Err(ref err) if err.kind() == io::ErrorKind::WouldBlock => {
|
||||||
if prev == buf.remaining() && io_pending {
|
if !io_pending {
|
||||||
|
// If `wants_read()` is satisfied, rustls will not return `WouldBlock`.
|
||||||
|
// but if it does, we can try again.
|
||||||
|
//
|
||||||
|
// If the rustls state is abnormal, it may cause a cyclic wakeup.
|
||||||
|
// but tokio's cooperative budget will prevent infinite wakeup.
|
||||||
|
cx.waker().wake_by_ref();
|
||||||
|
}
|
||||||
|
|
||||||
Poll::Pending
|
Poll::Pending
|
||||||
} else if self.eof || io_pending {
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(err) if err.kind() == io::ErrorKind::UnexpectedEof => {
|
|
||||||
self.eof = true;
|
|
||||||
self.unexpected_eof = true;
|
|
||||||
if prev == buf.remaining() {
|
|
||||||
Poll::Ready(Err(err))
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This should be unreachable.
|
|
||||||
Err(err) => Poll::Ready(Err(err)),
|
Err(err) => Poll::Ready(Err(err)),
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Poll::Ready(Ok(()))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,8 +127,10 @@ async fn stream_good() -> io::Result<()> {
|
|||||||
let (server, mut client) = make_pair();
|
let (server, mut client) = make_pair();
|
||||||
let mut server = Connection::from(server);
|
let mut server = Connection::from(server);
|
||||||
poll_fn(|cx| do_handshake(&mut client, &mut server, cx)).await?;
|
poll_fn(|cx| do_handshake(&mut client, &mut server, cx)).await?;
|
||||||
|
|
||||||
io::copy(&mut Cursor::new(FILE), &mut server.writer())?;
|
io::copy(&mut Cursor::new(FILE), &mut server.writer())?;
|
||||||
server.send_close_notify();
|
server.send_close_notify();
|
||||||
|
|
||||||
let mut server = Connection::from(server);
|
let mut server = Connection::from(server);
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -138,8 +140,10 @@ async fn stream_good() -> io::Result<()> {
|
|||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
dbg!(stream.read_to_end(&mut buf).await)?;
|
dbg!(stream.read_to_end(&mut buf).await)?;
|
||||||
assert_eq!(buf, FILE);
|
assert_eq!(buf, FILE);
|
||||||
|
|
||||||
dbg!(stream.write_all(b"Hello World!").await)?;
|
dbg!(stream.write_all(b"Hello World!").await)?;
|
||||||
stream.session.send_close_notify();
|
stream.session.send_close_notify();
|
||||||
|
|
||||||
dbg!(stream.shutdown().await)?;
|
dbg!(stream.shutdown().await)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,8 +245,8 @@ async fn stream_eof() -> io::Result<()> {
|
|||||||
let mut server = Connection::from(server);
|
let mut server = Connection::from(server);
|
||||||
poll_fn(|cx| do_handshake(&mut client, &mut server, cx)).await?;
|
poll_fn(|cx| do_handshake(&mut client, &mut server, cx)).await?;
|
||||||
|
|
||||||
let mut good = Good(&mut server);
|
let mut bad = Expected(Cursor::new(Vec::new()));
|
||||||
let mut stream = Stream::new(&mut good, &mut client).set_eof(true);
|
let mut stream = Stream::new(&mut bad, &mut client);
|
||||||
|
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
let result = stream.read_to_end(&mut buf).await;
|
let result = stream.read_to_end(&mut buf).await;
|
||||||
|
@ -77,12 +77,11 @@ where
|
|||||||
|
|
||||||
Poll::Ready(Ok(()))
|
Poll::Ready(Ok(()))
|
||||||
}
|
}
|
||||||
Poll::Ready(Err(ref err)) if err.kind() == io::ErrorKind::ConnectionAborted => {
|
Poll::Ready(Err(err)) if err.kind() == io::ErrorKind::UnexpectedEof => {
|
||||||
this.state.shutdown_read();
|
this.state.shutdown_read();
|
||||||
Poll::Ready(Ok(()))
|
Poll::Ready(Err(err))
|
||||||
}
|
}
|
||||||
Poll::Ready(Err(e)) => Poll::Ready(Err(e)),
|
output => output,
|
||||||
Poll::Pending => Poll::Pending,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TlsState::ReadShutdown | TlsState::FullyShutdown => Poll::Ready(Ok(())),
|
TlsState::ReadShutdown | TlsState::FullyShutdown => Poll::Ready(Ok(())),
|
||||||
|
Loading…
Reference in New Issue
Block a user