diff --git a/http-response-bodies.c b/http-response-bodies.c index f7184eb..9c22ae5 100644 --- a/http-response-bodies.c +++ b/http-response-bodies.c @@ -158,12 +158,21 @@ checkstate: } if (memcmp(bufp, "HTTP/1.1 ", 9) == 0 || memcmp(bufp, "HTTP/1.0 ", 9) == 0) { // Got some headers; find transfer encoding, content length, and end of headers - eoh = memmem(bufp, n, "\r\n\r\n", 4); + m0 = memmem(bufp, n, "\r\n\r\n", 4); + m1 = memmem(bufp, n, "\n\n", 2); + if (m0 && m1) { + eoh = (m0 < m1 ? m0 + 4 : m1 + 2); + } else if (m0) { + eoh = m0 + 4; + } else if (m1) { + eoh = m1 + 2; + } else { + eoh = NULL; + } if (!eoh) { fprintf(stderr, "Error: end of headers not found\n"); return 1; } - eoh += 4; DEBUG_PRINTF("Response body begins at %p (offset %zu)\n", (void*)eoh, eoh - bufp); if (memcmp(bufp, "HTTP/1.0 ", 9) == 0) { @@ -174,14 +183,15 @@ checkstate: } length = response_length - (eoh - bufp); state = STATE_BODY; - } else if ((m0 = memcasemem(bufp, eoh - bufp, "\r\ncontent-length:", 17)) && m0 < eoh) { + } else if ((m0 = memcasemem(bufp, eoh - bufp, "\ncontent-length:", 16)) && m0 < eoh) { DEBUG_PRINTF("Found Content-Length header at %p (offset %zu)\n", (void*)(m0 + 2), m0 + 2 - bufp); - m1 = memmem(m0 + 1, eoh - (m0 + 1), "\r\n", 2); + m1 = memmem(m0 + 1, eoh - (m0 + 1), "\n", 1); if (!m1) { fprintf(stderr, "Error: CRLF after Content-Length missing\n"); return 1; } - m0 += 17; + if (*(m1 - 1) == '\r') --m1; + m0 += 16; while (m0 < bufp + n && (*m0 == ' ' || *m0 == '\t')) ++m0; if (sscanf(m0, "%zu%ln", &length, &nscan) <= 0) { fprintf(stderr, "Error: invalid Content-Length\n"); @@ -205,18 +215,19 @@ checkstate: state = STATE_BODY; } else { - m0 = memcasemem(bufp, eoh - bufp, "\r\ntransfer-encoding:", 20); + 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 + 2), m0 + 2 - bufp); - m1 = memmem(m0 + 1, eoh - (m0 + 1), "\r\n", 2); - if (!m1 || m1 >= eoh - 2) { + 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 += 20; + 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"); @@ -234,15 +245,15 @@ checkstate: } if (html_fake_base) { - m0 = memcasemem(bufp, eoh - bufp, "\r\ncontent-type:", 15); + m0 = memcasemem(bufp, eoh - bufp, "\ncontent-type:", 14); if (m0 && m0 < eoh) { - DEBUG_PRINTF("Found Content-Type header at %p (offset %zu)\n", (void*)(m0 + 2), m0 + 2 - bufp); - m1 = memmem(m0 + 1, eoh - (m0 + 1), "\r\n", 2); + DEBUG_PRINTF("Found Content-Type header at %p (offset %zu)\n", (void*)(m0 + 1), m0 + 1 - bufp); + m1 = memmem(m0 + 1, eoh - (m0 + 1), "\n", 1); if (!m1) { fprintf(stderr, "Error: CRLF after Content-Type missing\n"); return 1; } - m0 += 15; + m0 += 14; while (m0 < bufp + n && (*m0 == ' ' || *m0 == '\t')) ++m0; if (memcmp(m0, "text/html", 9) == 0) { DEBUG_PRINTF("Is HTML response, inserting fake base tag\n");