@@ -198,6 +198,8 @@ struct HttpParser {
198198 std::string fallback;
199199 /* This guy really has only 30 bits since we reserve two highest bits to chunked encoding parsing state */
200200 uint64_t remainingStreamingBytes = 0 ;
201+ /* Set before (and only before) each call to dataHandler; equals remainingStreamingBytes minus the emitted chunk */
202+ uint64_t remainingBodyLength = 0 ;
201203
202204 /* Returns UINT64_MAX on error. Maximum 999999999 is allowed. */
203205 static uint64_t toUnsignedInteger (std::string_view str) {
@@ -571,6 +573,7 @@ struct HttpParser {
571573 /* Go ahead and parse it (todo: better heuristics for emitting FIN to the app level) */
572574 std::string_view dataToConsume (data, length);
573575 for (auto chunk : uWS::ChunkIterator (&dataToConsume, &remainingStreamingBytes)) {
576+ remainingBodyLength = (chunk.length () == 0 ) ? 0 : STATE_IS_CHUNKED;
574577 dataHandler (user, chunk, chunk.length () == 0 );
575578 }
576579 if (isParsingInvalidChunkedEncoding (remainingStreamingBytes)) {
@@ -590,6 +593,7 @@ struct HttpParser {
590593
591594 if (!CONSUME_MINIMALLY) {
592595 unsigned int emittable = (unsigned int ) std::min<uint64_t >(remainingStreamingBytes, length);
596+ remainingBodyLength = remainingStreamingBytes - emittable;
593597 dataHandler (user, std::string_view (data, emittable), emittable == remainingStreamingBytes);
594598 remainingStreamingBytes -= emittable;
595599
@@ -599,6 +603,7 @@ struct HttpParser {
599603 }
600604 } else {
601605 /* If we came here without a body; emit an empty data chunk to signal no data */
606+ remainingBodyLength = 0 ;
602607 dataHandler (user, {}, true );
603608 }
604609
@@ -617,10 +622,10 @@ struct HttpParser {
617622public:
618623 /* Returns the remaining body length if set via content-length, UINT64_MAX if transfer-encoding is chunked, or 0 if no body */
619624 uint64_t maxRemainingBodyLength () {
620- if (isParsingChunkedEncoding (remainingStreamingBytes )) {
625+ if (isParsingChunkedEncoding (remainingBodyLength )) {
621626 return UINT64_MAX;
622627 }
623- return remainingStreamingBytes ;
628+ return remainingBodyLength ;
624629 }
625630
626631 std::pair<unsigned int , void *> consumePostPadded (char *data, unsigned int length, void *user, void *reserved, MoveOnlyFunction<void *(void *, HttpRequest *)> &&requestHandler, MoveOnlyFunction<void *(void *, std::string_view, bool )> &&dataHandler) {
@@ -635,6 +640,7 @@ struct HttpParser {
635640 if (isParsingChunkedEncoding (remainingStreamingBytes)) {
636641 std::string_view dataToConsume (data, length);
637642 for (auto chunk : uWS::ChunkIterator (&dataToConsume, &remainingStreamingBytes)) {
643+ remainingBodyLength = (chunk.length () == 0 ) ? 0 : STATE_IS_CHUNKED;
638644 dataHandler (user, chunk, chunk.length () == 0 );
639645 }
640646 if (isParsingInvalidChunkedEncoding (remainingStreamingBytes)) {
@@ -646,10 +652,12 @@ struct HttpParser {
646652 // this is exactly the same as below!
647653 // todo: refactor this
648654 if (remainingStreamingBytes >= length) {
655+ remainingBodyLength = remainingStreamingBytes - length;
649656 void *returnedUser = dataHandler (user, std::string_view (data, length), remainingStreamingBytes == length);
650657 remainingStreamingBytes -= length;
651658 return {0 , returnedUser};
652659 } else {
660+ remainingBodyLength = 0 ;
653661 void *returnedUser = dataHandler (user, std::string_view (data, remainingStreamingBytes), true );
654662
655663 data += (unsigned int ) remainingStreamingBytes;
@@ -692,6 +700,7 @@ struct HttpParser {
692700 if (isParsingChunkedEncoding (remainingStreamingBytes)) {
693701 std::string_view dataToConsume (data, length);
694702 for (auto chunk : uWS::ChunkIterator (&dataToConsume, &remainingStreamingBytes)) {
703+ remainingBodyLength = (chunk.length () == 0 ) ? 0 : STATE_IS_CHUNKED;
695704 dataHandler (user, chunk, chunk.length () == 0 );
696705 }
697706 if (isParsingInvalidChunkedEncoding (remainingStreamingBytes)) {
@@ -702,10 +711,12 @@ struct HttpParser {
702711 } else {
703712 // this is exactly the same as above!
704713 if (remainingStreamingBytes >= (unsigned int ) length) {
714+ remainingBodyLength = remainingStreamingBytes - length;
705715 void *returnedUser = dataHandler (user, std::string_view (data, length), remainingStreamingBytes == (unsigned int ) length);
706716 remainingStreamingBytes -= length;
707717 return {0 , returnedUser};
708718 } else {
719+ remainingBodyLength = 0 ;
709720 void *returnedUser = dataHandler (user, std::string_view (data, remainingStreamingBytes), true );
710721
711722 data += (unsigned int ) remainingStreamingBytes;
0 commit comments