@@ -533,15 +533,6 @@ struct HttpParser {
533533 const char *querySeparatorPtr = (const char *) memchr (req->headers ->value .data (), ' ?' , req->headers ->value .length ());
534534 req->querySeparator = (unsigned int ) ((querySeparatorPtr ? querySeparatorPtr : req->headers ->value .data () + req->headers ->value .length ()) - req->headers ->value .data ());
535535
536- /* If returned socket is not what we put in we need
537- * to break here as we either have upgraded to
538- * WebSockets or otherwise closed the socket. */
539- void *returnedUser = requestHandler (user, req);
540- if (returnedUser != user) {
541- /* We are upgraded to WebSocket or otherwise broken */
542- return {consumedTotal, returnedUser};
543- }
544-
545536 /* The rules at play here according to RFC 9112 for requests are essentially:
546537 * If both content-length and transfer-encoding then invalid message; must break.
547538 * If has transfer-encoding then must be chunked regardless of value.
@@ -566,6 +557,28 @@ struct HttpParser {
566557 * This could be made stricter but makes no difference either way, unless forwarding the identical message as a proxy. */
567558
568559 remainingStreamingBytes = STATE_IS_CHUNKED;
560+ } else if (contentLengthString.length ()) {
561+ remainingStreamingBytes = toUnsignedInteger (contentLengthString);
562+ if (remainingStreamingBytes == UINT64_MAX) {
563+ /* Parser error */
564+ return {HTTP_ERROR_400_BAD_REQUEST, FULLPTR};
565+ }
566+ } else {
567+ /* No body (e.g. GET requests); set to 0 to match this assumption */
568+ remainingStreamingBytes = 0 ;
569+ }
570+
571+ /* If returned socket is not what we put in we need
572+ * to break here as we either have upgraded to
573+ * WebSockets or otherwise closed the socket. */
574+ void *returnedUser = requestHandler (user, req);
575+ if (returnedUser != user) {
576+ /* We are upgraded to WebSocket or otherwise broken */
577+ return {consumedTotal, returnedUser};
578+ }
579+
580+ /* Consume body data */
581+ if (transferEncodingString.length ()) {
569582 /* If consume minimally, we do not want to consume anything but we want to mark this as being chunked */
570583 if (!CONSUME_MINIMALLY) {
571584 /* Go ahead and parse it (todo: better heuristics for emitting FIN to the app level) */
@@ -582,12 +595,6 @@ struct HttpParser {
582595 consumedTotal += consumed;
583596 }
584597 } else if (contentLengthString.length ()) {
585- remainingStreamingBytes = toUnsignedInteger (contentLengthString);
586- if (remainingStreamingBytes == UINT64_MAX) {
587- /* Parser error */
588- return {HTTP_ERROR_400_BAD_REQUEST, FULLPTR};
589- }
590-
591598 if (!CONSUME_MINIMALLY) {
592599 unsigned int emittable = (unsigned int ) std::min<uint64_t >(remainingStreamingBytes, length);
593600 dataHandler (user, std::string_view (data, emittable), emittable == remainingStreamingBytes);
0 commit comments