diff --git a/src/main/filter_chunked.c b/src/main/filter_chunked.c index a15d849..e165788 100644 --- a/src/main/filter_chunked.c +++ b/src/main/filter_chunked.c @@ -69,7 +69,6 @@ gboolean li_filter_chunked_decode(liVRequest *vr, liChunkQueue *out, liChunkQueu li_chunk_parser_init(&ctx, in); li_chunk_parser_prepare(&ctx); - for (;;) { /* 0: start new chunklen, 1: reading chunklen, 2: found \r, 3: copying content, 4: found \r, * 10: wait for \r\n\r\n, 11: wait for \n\r\n, 12: wait for \r\n, 13: wait for \n, 14: eof, @@ -78,7 +77,6 @@ gboolean li_filter_chunked_decode(liVRequest *vr, liChunkQueue *out, liChunkQueu switch (state->parse_state) { case 0: state->cur_chunklen = -1; - li_chunk_parser_prepare(&ctx); state->parse_state = 1; break; case 1: @@ -117,10 +115,10 @@ gboolean li_filter_chunked_decode(liVRequest *vr, liChunkQueue *out, liChunkQueu li_chunk_parser_done(&ctx, 1); if (c == '\n') { li_chunkqueue_skip(in, ctx.bytes_in); - li_chunk_parser_reset(&ctx); p = NULL; if (state->cur_chunklen > 0) { state->parse_state = 3; } else { + li_chunk_parser_reset(&ctx); p = NULL; li_chunk_parser_prepare(&ctx); state->parse_state = 12; } @@ -133,6 +131,7 @@ gboolean li_filter_chunked_decode(liVRequest *vr, liChunkQueue *out, liChunkQueu state->cur_chunklen -= li_chunkqueue_steal_len(out, in, state->cur_chunklen); } if (state->cur_chunklen == 0) { + li_chunk_parser_reset(&ctx); p = NULL; li_chunk_parser_prepare(&ctx); read_char(c); li_chunk_parser_done(&ctx, 1); @@ -152,6 +151,7 @@ gboolean li_filter_chunked_decode(liVRequest *vr, liChunkQueue *out, liChunkQueu if (c == '\n') { li_chunkqueue_skip(in, ctx.bytes_in); li_chunk_parser_reset(&ctx); p = NULL; + li_chunk_parser_prepare(&ctx); state->parse_state = 0; } else { state->parse_state = 20; diff --git a/tests/t-mod-proxy.py b/tests/t-mod-proxy.py index 5285a4c..ab971a6 100644 --- a/tests/t-mod-proxy.py +++ b/tests/t-mod-proxy.py @@ -33,6 +33,15 @@ class HttpBackendHandler(socketserver.StreamRequestHandler): if reqline[1].startswith("/upgrade/custom"): self.wfile.write(b"HTTP/1.1 101 Switching Protocols\r\nConnection: Upgrade\r\nUpgrade: custom\r\n\r\nHello World!") return + if reqline[1].startswith("/chunked/delay"): + import time + self.wfile.write(b"HTTP/1.1 200 Ok\r\nTransfer-Encoding: chunked\r\n\r\n4\r\nHi") + time.sleep(0.1) + self.wfile.write(b"!\n") + time.sleep(0.1) + self.wfile.write(b"\r\n0\r\n\r\n") + continue + # send response resp_body = reqline[1].encode('utf-8') clen = "Content-Length: {}\r\n".format(len(resp_body)).encode('utf-8') @@ -112,6 +121,15 @@ class TestBackendUpgrade(CurlRequest): backend_proxy; """ +class TestBackendDelayedChunk(CurlRequest): + URL = "/chunked/delay" + EXPECT_RESPONSE_BODY = "Hi!\n" + EXPECT_RESPONSE_CODE = 200 + no_docroot = True + config = """ +backend_proxy; +""" + class Test(GroupTest): group = [ TestSimple, @@ -119,6 +137,7 @@ class Test(GroupTest): TestProxiedRewrittenDecodedURL, TestBackendForcedKeepalive, TestBackendUpgrade, + TestBackendDelayedChunk, ] def Prepare(self):