Skip to content

Commit e193e29

Browse files
authored
fix: return write-zero error when write return 0 (#93)
1 parent 66fb0ae commit e193e29

File tree

2 files changed

+73
-2
lines changed

2 files changed

+73
-2
lines changed

src/common/mod.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ where
130130

131131
while self.session.wants_write() {
132132
match self.write_io(cx) {
133+
Poll::Ready(Ok(0)) => return Poll::Ready(Err(io::ErrorKind::WriteZero.into())),
133134
Poll::Ready(Ok(n)) => {
134135
wrlen += n;
135136
need_flush = true;
@@ -322,14 +323,18 @@ where
322323
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<io::Result<()>> {
323324
self.session.writer().flush()?;
324325
while self.session.wants_write() {
325-
ready!(self.write_io(cx))?;
326+
if ready!(self.write_io(cx))? == 0 {
327+
return Poll::Ready(Err(io::ErrorKind::WriteZero.into()));
328+
}
326329
}
327330
Pin::new(&mut self.io).poll_flush(cx)
328331
}
329332

330333
fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
331334
while self.session.wants_write() {
332-
ready!(self.write_io(cx))?;
335+
if ready!(self.write_io(cx))? == 0 {
336+
return Poll::Ready(Err(io::ErrorKind::WriteZero.into()));
337+
}
333338
}
334339

335340
Poll::Ready(match ready!(Pin::new(&mut self.io).poll_shutdown(cx)) {

src/common/test_stream.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,36 @@ impl AsyncWrite for Expected {
122122
}
123123
}
124124

125+
struct Eof;
126+
127+
impl AsyncRead for Eof {
128+
fn poll_read(
129+
self: Pin<&mut Self>,
130+
_cx: &mut Context<'_>,
131+
_buf: &mut ReadBuf<'_>,
132+
) -> Poll<io::Result<()>> {
133+
Poll::Ready(Ok(()))
134+
}
135+
}
136+
137+
impl AsyncWrite for Eof {
138+
fn poll_write(
139+
self: Pin<&mut Self>,
140+
_cx: &mut Context<'_>,
141+
_buf: &[u8],
142+
) -> Poll<io::Result<usize>> {
143+
Poll::Ready(Ok(0))
144+
}
145+
146+
fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
147+
Poll::Ready(Ok(()))
148+
}
149+
150+
fn poll_shutdown(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
151+
Poll::Ready(Ok(()))
152+
}
153+
}
154+
125155
#[tokio::test]
126156
async fn stream_good() -> io::Result<()> {
127157
stream_good_impl(false).await
@@ -254,6 +284,23 @@ async fn stream_handshake_eof() -> io::Result<()> {
254284
Ok(()) as io::Result<()>
255285
}
256286

287+
#[tokio::test]
288+
async fn stream_handshake_write_eof() -> io::Result<()> {
289+
let (_, mut client) = make_pair();
290+
291+
let mut io = Eof;
292+
let mut stream = Stream::new(&mut io, &mut client);
293+
294+
let mut cx = Context::from_waker(noop_waker_ref());
295+
let r = stream.handshake(&mut cx);
296+
assert_eq!(
297+
r.map_err(|err| err.kind()),
298+
Poll::Ready(Err(io::ErrorKind::WriteZero))
299+
);
300+
301+
Ok(()) as io::Result<()>
302+
}
303+
257304
// see https://github.com/tokio-rs/tls/issues/77
258305
#[tokio::test]
259306
async fn stream_handshake_regression_issues_77() -> io::Result<()> {
@@ -291,6 +338,25 @@ async fn stream_eof() -> io::Result<()> {
291338
Ok(()) as io::Result<()>
292339
}
293340

341+
#[tokio::test]
342+
async fn stream_write_zero() -> io::Result<()> {
343+
let (server, mut client) = make_pair();
344+
let mut server = Connection::from(server);
345+
poll_fn(|cx| do_handshake(&mut client, &mut server, cx)).await?;
346+
347+
let mut io = Eof;
348+
let mut stream = Stream::new(&mut io, &mut client);
349+
350+
stream.write(b"1").await.unwrap();
351+
let result = stream.flush().await;
352+
assert_eq!(
353+
result.err().map(|e| e.kind()),
354+
Some(io::ErrorKind::WriteZero)
355+
);
356+
357+
Ok(()) as io::Result<()>
358+
}
359+
294360
fn make_pair() -> (ServerConnection, ClientConnection) {
295361
let (sconfig, cconfig) = utils::make_configs();
296362
let server = ServerConnection::new(Arc::new(sconfig)).unwrap();

0 commit comments

Comments
 (0)