2
0
Fork 0

[core] fix chunk decoding bug: reused stale context after forwarding chunk data

Change-Id: Ie37e3c2d605ae23dcb7a6b74ff6b5f0699074ac5
personal/stbuehler/wip
Stefan Bühler 2019-08-26 00:28:48 +02:00
parent 7078063491
commit afaf285bfb
2 changed files with 22 additions and 3 deletions

View File

@ -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;

View File

@ -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):