diff options
-rw-r--r-- | src/libwaitress/waitress.c | 8 | ||||
-rw-r--r-- | src/libwaitress/waitress.h | 1 |
2 files changed, 9 insertions, 0 deletions
diff --git a/src/libwaitress/waitress.c b/src/libwaitress/waitress.c index 3d01198..771c54f 100644 --- a/src/libwaitress/waitress.c +++ b/src/libwaitress/waitress.c @@ -703,6 +703,7 @@ static void WaitressHandleHeader (WaitressHandle_t *waith, const char * const ke if (strcaseeq (key, "Content-Length")) { waith->request.contentLength = atol (value); + waith->request.contentLengthKnown = true; } else if (strcaseeq (key, "Transfer-Encoding")) { if (strcaseeq (value, "chunked")) { waith->request.dataHandler = WaitressHandleChunked; @@ -1064,6 +1065,12 @@ static WaitressReturn_t WaitressReceiveResponse (WaitressHandle_t *waith) { /* go on */ break; } + if (waith->request.contentLengthKnown && + waith->request.contentReceived >= waith->request.contentLength) { + /* don’t call read() again if we know the body’s size and have all + * of it already */ + break; + } READ_RET (buf, WAITRESS_BUFFER_SIZE-1, &recvSize); } while (recvSize > 0); @@ -1083,6 +1090,7 @@ WaitressReturn_t WaitressFetchCall (WaitressHandle_t *waith) { waith->request.dataHandler = WaitressHandleIdentity; waith->request.read = WaitressOrdinaryRead; waith->request.write = WaitressOrdinaryWrite; + waith->request.contentLengthKnown = false; if (waith->url.tls) { gnutls_init (&waith->request.tlsSession, GNUTLS_CLIENT); diff --git a/src/libwaitress/waitress.h b/src/libwaitress/waitress.h index 9075047..bd80134 100644 --- a/src/libwaitress/waitress.h +++ b/src/libwaitress/waitress.h @@ -110,6 +110,7 @@ typedef struct { WaitressReturn_t readWriteRet; size_t contentLength, contentReceived, chunkSize; + bool contentLengthKnown; enum {CHUNKSIZE = 0, DATA = 1} chunkedState; char *buf; |