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) {