Skip to content

Commit e42d69f

Browse files
committed
Remove maxRemainingBodyLength(), add onDataV2
1 parent 2d18f69 commit e42d69f

File tree

4 files changed

+28
-24
lines changed

4 files changed

+28
-24
lines changed

src/HttpContext.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -230,12 +230,12 @@ struct HttpContext {
230230
/* Continue parsing */
231231
return s;
232232

233-
}, [httpResponseData](void *user, std::string_view data, bool fin) -> void * {
233+
}, [httpResponseData](void *user, std::string_view data, uint64_t maxRemainingBodyLength) -> void * {
234234
/* We always get an empty chunk even if there is no data */
235235
if (httpResponseData->inStream) {
236236

237237
/* Todo: can this handle timeout for non-post as well? */
238-
if (fin) {
238+
if (maxRemainingBodyLength == 0) {
239239
/* If we just got the last chunk (or empty chunk), disable timeout */
240240
us_socket_timeout(SSL, (struct us_socket_t *) user, 0);
241241
} else {
@@ -249,7 +249,7 @@ struct HttpContext {
249249
}
250250

251251
/* We might respond in the handler, so do not change timeout after this */
252-
httpResponseData->inStream(data, fin);
252+
httpResponseData->inStream(data, maxRemainingBodyLength);
253253

254254
/* Was the socket closed? */
255255
if (us_socket_is_closed(SSL, (struct us_socket_t *) user)) {
@@ -263,7 +263,7 @@ struct HttpContext {
263263

264264
/* If we were given the last data chunk, reset data handler to ensure following
265265
* requests on the same socket won't trigger any previously registered behavior */
266-
if (fin) {
266+
if (maxRemainingBodyLength == 0) {
267267
httpResponseData->inStream = nullptr;
268268
}
269269
}

src/HttpParser.h

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ struct HttpParser {
474474
* or [consumed, nullptr] for "break; I am closed or upgraded to websocket"
475475
* or [whatever, fullptr] for "break and close me, I am a parser error!" */
476476
template <int CONSUME_MINIMALLY>
477-
std::pair<unsigned int, void *> fenceAndConsumePostPadded(char *data, unsigned int length, void *user, void *reserved, HttpRequest *req, MoveOnlyFunction<void *(void *, HttpRequest *)> &requestHandler, MoveOnlyFunction<void *(void *, std::string_view, bool)> &dataHandler) {
477+
std::pair<unsigned int, void *> fenceAndConsumePostPadded(char *data, unsigned int length, void *user, void *reserved, HttpRequest *req, MoveOnlyFunction<void *(void *, HttpRequest *)> &requestHandler, MoveOnlyFunction<void *(void *, std::string_view, uint64_t)> &dataHandler) {
478478

479479
/* How much data we CONSUMED (to throw away) */
480480
unsigned int consumedTotal = 0;
@@ -571,7 +571,7 @@ struct HttpParser {
571571
/* Go ahead and parse it (todo: better heuristics for emitting FIN to the app level) */
572572
std::string_view dataToConsume(data, length);
573573
for (auto chunk : uWS::ChunkIterator(&dataToConsume, &remainingStreamingBytes)) {
574-
dataHandler(user, chunk, chunk.length() == 0);
574+
dataHandler(user, chunk, chunk.length() ? UINT64_MAX : 0);
575575
}
576576
if (isParsingInvalidChunkedEncoding(remainingStreamingBytes)) {
577577
return {HTTP_ERROR_400_BAD_REQUEST, FULLPTR};
@@ -590,7 +590,7 @@ struct HttpParser {
590590

591591
if (!CONSUME_MINIMALLY) {
592592
unsigned int emittable = (unsigned int) std::min<uint64_t>(remainingStreamingBytes, length);
593-
dataHandler(user, std::string_view(data, emittable), emittable == remainingStreamingBytes);
593+
dataHandler(user, std::string_view(data, emittable), remainingStreamingBytes - emittable);
594594
remainingStreamingBytes -= emittable;
595595

596596
data += emittable;
@@ -599,7 +599,7 @@ struct HttpParser {
599599
}
600600
} else {
601601
/* If we came here without a body; emit an empty data chunk to signal no data */
602-
dataHandler(user, {}, true);
602+
dataHandler(user, {}, 0);
603603
}
604604

605605
/* Consume minimally should break as easrly as possible */
@@ -615,15 +615,7 @@ struct HttpParser {
615615
}
616616

617617
public:
618-
/* Returns the remaining body length if set via content-length, UINT64_MAX if transfer-encoding is chunked, or 0 if no body */
619-
uint64_t maxRemainingBodyLength() {
620-
if (isParsingChunkedEncoding(remainingStreamingBytes)) {
621-
return UINT64_MAX;
622-
}
623-
return remainingStreamingBytes;
624-
}
625-
626-
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) {
618+
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, uint64_t)> &&dataHandler) {
627619

628620
/* This resets BloomFilter by construction, but later we also reset it again.
629621
* Optimize this to skip resetting twice (req could be made global) */
@@ -635,7 +627,8 @@ struct HttpParser {
635627
if (isParsingChunkedEncoding(remainingStreamingBytes)) {
636628
std::string_view dataToConsume(data, length);
637629
for (auto chunk : uWS::ChunkIterator(&dataToConsume, &remainingStreamingBytes)) {
638-
dataHandler(user, chunk, chunk.length() == 0);
630+
/* If we got the zero size chunk, maxRemainingBodyLength is 0, else it is practically infinity */
631+
dataHandler(user, chunk, chunk.length() ? UINT64_MAX : 0);
639632
}
640633
if (isParsingInvalidChunkedEncoding(remainingStreamingBytes)) {
641634
return {HTTP_ERROR_400_BAD_REQUEST, FULLPTR};
@@ -646,11 +639,11 @@ struct HttpParser {
646639
// this is exactly the same as below!
647640
// todo: refactor this
648641
if (remainingStreamingBytes >= length) {
649-
void *returnedUser = dataHandler(user, std::string_view(data, length), remainingStreamingBytes == length);
642+
void *returnedUser = dataHandler(user, std::string_view(data, length), remainingStreamingBytes - length);
650643
remainingStreamingBytes -= length;
651644
return {0, returnedUser};
652645
} else {
653-
void *returnedUser = dataHandler(user, std::string_view(data, remainingStreamingBytes), true);
646+
void *returnedUser = dataHandler(user, std::string_view(data, remainingStreamingBytes), 0);
654647

655648
data += (unsigned int) remainingStreamingBytes;
656649
length -= (unsigned int) remainingStreamingBytes;
@@ -692,7 +685,7 @@ struct HttpParser {
692685
if (isParsingChunkedEncoding(remainingStreamingBytes)) {
693686
std::string_view dataToConsume(data, length);
694687
for (auto chunk : uWS::ChunkIterator(&dataToConsume, &remainingStreamingBytes)) {
695-
dataHandler(user, chunk, chunk.length() == 0);
688+
dataHandler(user, chunk, chunk.length() ? UINT64_MAX : 0);
696689
}
697690
if (isParsingInvalidChunkedEncoding(remainingStreamingBytes)) {
698691
return {HTTP_ERROR_400_BAD_REQUEST, FULLPTR};
@@ -702,11 +695,11 @@ struct HttpParser {
702695
} else {
703696
// this is exactly the same as above!
704697
if (remainingStreamingBytes >= (unsigned int) length) {
705-
void *returnedUser = dataHandler(user, std::string_view(data, length), remainingStreamingBytes == (unsigned int) length);
698+
void *returnedUser = dataHandler(user, std::string_view(data, length), remainingStreamingBytes - (unsigned int) length);
706699
remainingStreamingBytes -= length;
707700
return {0, returnedUser};
708701
} else {
709-
void *returnedUser = dataHandler(user, std::string_view(data, remainingStreamingBytes), true);
702+
void *returnedUser = dataHandler(user, std::string_view(data, remainingStreamingBytes), 0);
710703

711704
data += (unsigned int) remainingStreamingBytes;
712705
length -= (unsigned int) remainingStreamingBytes;

src/HttpResponse.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,17 @@ struct HttpResponse : public AsyncSocket<SSL> {
581581

582582
/* Attach a read handler for data sent. Will be called with FIN set true if last segment. */
583583
void onData(MoveOnlyFunction<void(std::string_view, bool)> &&handler) {
584+
if (handler) {
585+
onDataV2([handler = std::move(handler)](std::string_view chunk, uint64_t maxRemainingBodyLength) mutable {
586+
handler(chunk, maxRemainingBodyLength == 0);
587+
});
588+
} else {
589+
onDataV2(nullptr);
590+
}
591+
}
592+
593+
/* Attach a read handler for data sent. Will be called with maxRemainingBodyLength. maxRemainingBodyLength == 0 is the same as isLast. */
594+
void onDataV2(MoveOnlyFunction<void(std::string_view, uint64_t)> &&handler) {
584595
HttpResponseData<SSL> *data = getHttpResponseData();
585596
data->inStream = std::move(handler);
586597

src/HttpResponseData.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ struct HttpResponseData : AsyncSocketData<SSL>, HttpParser {
7575
/* Per socket event handlers */
7676
MoveOnlyFunction<bool(uintmax_t)> onWritable;
7777
MoveOnlyFunction<void()> onAborted;
78-
MoveOnlyFunction<void(std::string_view, bool)> inStream; // onData
78+
MoveOnlyFunction<void(std::string_view, uint64_t)> inStream; // onData
7979
/* Outgoing offset */
8080
uintmax_t offset = 0;
8181

0 commit comments

Comments
 (0)