Skip to content

Commit 13c13c2

Browse files
committed
tlsuv: partial write should not cause an unexpected error
1 parent 034295b commit 13c13c2

File tree

3 files changed

+54
-9
lines changed

3 files changed

+54
-9
lines changed

src/tlsuv.c

+8-8
Original file line numberDiff line numberDiff line change
@@ -308,16 +308,16 @@ static void process_outbound(tlsuv_stream_t *clt) {
308308
if (ret > 0) {
309309
req->buf.base += ret;
310310
req->buf.len -= ret;
311-
}
312311

313-
// complete
314-
if (req->buf.len == 0) {
315-
clt->queue_len -= 1;
316-
TAILQ_REMOVE(&clt->queue, req, _next);
317-
if (req->wr->cb) {
318-
req->wr->cb(req->wr, 0);
312+
// complete
313+
if (req->buf.len == 0) {
314+
clt->queue_len -= 1;
315+
TAILQ_REMOVE(&clt->queue, req, _next);
316+
if (req->wr->cb) {
317+
req->wr->cb(req->wr, 0);
318+
}
319+
free(req);
319320
}
320-
free(req);
321321
continue;
322322
}
323323

tests/stream_tests.cpp

+41
Original file line numberDiff line numberDiff line change
@@ -382,4 +382,45 @@ TEST_CASE("read start/stop", "[stream]") {
382382

383383
start(loopTest.loop, steps);
384384
loopTest.run();
385+
}
386+
387+
static void wrt_cb(uv_write_t *wr, int status) {
388+
if (status != 0) {
389+
CHECK(status == UV_ECANCELED);
390+
}
391+
392+
free(wr->data);
393+
delete wr;
394+
}
395+
396+
// this test is designed to block echo server since it is not reading back
397+
// eventually echo server will block on write and stop reading
398+
// this will cause this stream to block writing
399+
// the write requests will get either success of cancellation at the end of the test
400+
TEST_CASE("large/partial writes", "[stream]") {
401+
tlsuv_stream_t s;
402+
UvLoopTest loopTest(3);
403+
uv_connect_t cr;
404+
cr.data = &s;
405+
406+
tlsuv_stream_init(loopTest.loop, &s, testServerTLS());
407+
408+
tlsuv_stream_connect(&cr, &s, "localhost", 7443, [](uv_connect_t *r, int status){
409+
REQUIRE(status == 0);
410+
411+
auto stream = (tlsuv_stream_t*) r->data;
412+
for (int i = 0; i < 20; i++) {
413+
auto w = new uv_write_t;
414+
auto buf = uv_buf_init((char*)malloc(1024 * 1024), 1024 * 1024);
415+
w->data = buf.base;
416+
tlsuv_stream_write(w, stream, &buf, wrt_cb);
417+
}
418+
});
419+
420+
loopTest.run();
421+
422+
// cleanup after timeout
423+
tlsuv_stream_close(&s, nullptr);
424+
loopTest.run();
425+
tlsuv_stream_free(&s);
385426
}

tests/test_server/test-server.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,12 @@ func runEchoServer(port int) chan error {
9090
}
9191

9292
go func() {
93+
defer func(clt net.Conn) {
94+
_ = clt.Close()
95+
}(clt)
96+
97+
buf := make([]byte, 1024)
9398
for {
94-
buf := make([]byte, 1024)
9599
n, err := clt.Read(buf)
96100
if err != nil {
97101
return

0 commit comments

Comments
 (0)