From b51a7c95144ff5ccc0f79d19f4dd4f57b0b9a317 Mon Sep 17 00:00:00 2001 From: JustAnotherArchivist Date: Wed, 3 May 2023 05:04:41 +0000 Subject: [PATCH] Fall back to response length when there is neither Content-Length nor Transfer-Encoding in an HTTP/1.1 response --- http-response-bodies.c | 58 +++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/http-response-bodies.c b/http-response-bodies.c index 9c22ae5..898d040 100644 --- a/http-response-bodies.c +++ b/http-response-bodies.c @@ -217,31 +217,41 @@ checkstate: } else { m0 = memcasemem(bufp, eoh - bufp, "\ntransfer-encoding:", 19); if (!m0 || m0 >= eoh) { - fprintf(stderr, "Error: Content-Length and Transfer-Encoding missing\n"); - return 1; - } - DEBUG_PRINTF("Found Transfer-Encoding header at %p (offset %zu)\n", (void*)(m0 + 1), m0 + 1 - bufp); - m1 = memmem(m0 + 1, eoh - (m0 + 1), "\n", 1); - if (!m1 || m1 >= eoh - 1) { - fprintf(stderr, "Error: CRLF after Transfer-Encoding missing\n"); - return 1; - } - m0 += 19; - if (*(m1 - 1) == '\r') --m1; - while (m0 < bufp + n && (*m0 == ' ' || *m0 == '\t')) ++m0; - if (memcmp(m0, "chunked", 7) != 0) { - fprintf(stderr, "Error: unsupported Transfer-Encoding\n"); - return 1; - } - m0 += 7; - while (m0 < bufp + n && (*m0 == ' ' || *m0 == '\t')) ++m0; - if (m0 != m1) { - fprintf(stderr, "Error: unsupported Transfer-Encoding\n"); - return 1; - } - DEBUG_PRINTF("Chunked transfer encoding\n"); + DEBUG_PRINTF("No Content-Length or Transfer-Encoding, falling back to response length\n"); + if (!have_response_length) { + fprintf(stderr, "Error: Content-Length and Transfer-Encoding missing and no response length from metadata line\n"); + return 1; + } + if (bufp + response_length < eoh) { + fprintf(stderr, "Error: end of headers occurs after alleged response length\n"); + return 1; + } + length = response_length - (eoh - bufp); + state = STATE_BODY; + } else { + DEBUG_PRINTF("Found Transfer-Encoding header at %p (offset %zu)\n", (void*)(m0 + 1), m0 + 1 - bufp); + m1 = memmem(m0 + 1, eoh - (m0 + 1), "\n", 1); + if (!m1 || m1 >= eoh - 1) { + fprintf(stderr, "Error: CRLF after Transfer-Encoding missing\n"); + return 1; + } + m0 += 19; + if (*(m1 - 1) == '\r') --m1; + while (m0 < bufp + n && (*m0 == ' ' || *m0 == '\t')) ++m0; + if (memcmp(m0, "chunked", 7) != 0) { + fprintf(stderr, "Error: unsupported Transfer-Encoding\n"); + return 1; + } + m0 += 7; + while (m0 < bufp + n && (*m0 == ' ' || *m0 == '\t')) ++m0; + if (m0 != m1) { + fprintf(stderr, "Error: unsupported Transfer-Encoding\n"); + return 1; + } + DEBUG_PRINTF("Chunked transfer encoding\n"); - state = STATE_CHUNK_LINE; + state = STATE_CHUNK_LINE; + } } if (html_fake_base) {