mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-10-23 11:54:42 +00:00
Bound the size of an SSE event
The SSE client buffered a line, or the data of an event, with no limit of its own, and with payload_max_length(0) with none at all. Add CPPHTTPLIB_SSE_MAX_EVENT_LENGTH (16MB) and end the connection with ExceedMaxPayloadSize past it.
This commit is contained in:
1 parent
f5e11024da
commit
cadcc425b8
3 files changed
+44
No files matched your search
@@ -79,6 +79,8 @@ sse.set_max_reconnect_attempts(10);
|
|||||||
sse.set_headers({{"Authorization", "Bearer new_token"}});
|
sse.set_headers({{"Authorization", "Bearer new_token"}});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
An event, or a line still waiting for its end, longer than `CPPHTTPLIB_SSE_MAX_EVENT_LENGTH` (16MB by default, `0` for no limit) ends the connection with `Error::ExceedMaxPayloadSize`, and the client reconnects as usual.
|
||||||
|
|
||||||
#### Control
|
#### Control
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
|
|||||||
@@ -138,6 +138,10 @@
|
|||||||
#define CPPHTTPLIB_PAYLOAD_MAX_LENGTH (100 * 1024 * 1024) // 100MB
|
#define CPPHTTPLIB_PAYLOAD_MAX_LENGTH (100 * 1024 * 1024) // 100MB
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef CPPHTTPLIB_SSE_MAX_EVENT_LENGTH
|
||||||
|
#define CPPHTTPLIB_SSE_MAX_EVENT_LENGTH (16 * 1024 * 1024) // 16MB
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef CPPHTTPLIB_FORM_URL_ENCODED_PAYLOAD_MAX_LENGTH
|
#ifndef CPPHTTPLIB_FORM_URL_ENCODED_PAYLOAD_MAX_LENGTH
|
||||||
#define CPPHTTPLIB_FORM_URL_ENCODED_PAYLOAD_MAX_LENGTH 8192
|
#define CPPHTTPLIB_FORM_URL_ENCODED_PAYLOAD_MAX_LENGTH 8192
|
||||||
#endif
|
#endif
|
||||||
@@ -5084,6 +5088,15 @@ inline void SSEClient::run_event_loop() {
|
|||||||
|
|
||||||
// Keep unprocessed data in buffer
|
// Keep unprocessed data in buffer
|
||||||
buffer.erase(0, line_start);
|
buffer.erase(0, line_start);
|
||||||
|
|
||||||
|
// Neither an event nor a line still waiting for its end may grow
|
||||||
|
// without bound. 0 means no limit.
|
||||||
|
if (CPPHTTPLIB_SSE_MAX_EVENT_LENGTH > 0 &&
|
||||||
|
buffer.size() + current_msg.data.size() >
|
||||||
|
CPPHTTPLIB_SSE_MAX_EVENT_LENGTH) {
|
||||||
|
if (on_error_) { on_error_(Error::ExceedMaxPayloadSize); }
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connection ended
|
// Connection ended
|
||||||
|
|||||||
@@ -23809,6 +23809,35 @@ TEST_F(SSEIntegrationTest, SuccessfulConnection) {
|
|||||||
EXPECT_TRUE(message_received.load());
|
EXPECT_TRUE(message_received.load());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(SSEIntegrationTest, TooLongEventEndsTheConnection) {
|
||||||
|
// A data line that never ends.
|
||||||
|
server_->Get("/endless-line", [](const Request &, Response &res) {
|
||||||
|
res.set_chunked_content_provider(
|
||||||
|
"text/event-stream", [](size_t offset, DataSink &sink) {
|
||||||
|
if (offset == 0) { sink.write("data: ", 6); }
|
||||||
|
std::string chunk(64 * 1024, 'A');
|
||||||
|
return sink.write(chunk.data(), chunk.size());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
Client client("localhost", get_port());
|
||||||
|
// A stream that may run forever, so that only the event is bounded.
|
||||||
|
client.set_payload_max_length(0);
|
||||||
|
sse::SSEClient sse(client, "/endless-line");
|
||||||
|
std::atomic<bool> too_long{false};
|
||||||
|
sse.on_error([&](Error err) {
|
||||||
|
if (err == Error::ExceedMaxPayloadSize) { too_long = true; }
|
||||||
|
});
|
||||||
|
sse.set_max_reconnect_attempts(1);
|
||||||
|
sse.start_async();
|
||||||
|
|
||||||
|
for (int i = 0; i < 500 && !too_long; i++) {
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||||
|
}
|
||||||
|
sse.stop();
|
||||||
|
EXPECT_TRUE(too_long);
|
||||||
|
}
|
||||||
|
|
||||||
// Test: on_message callback
|
// Test: on_message callback
|
||||||
TEST_F(SSEIntegrationTest, OnMessageCallback) {
|
TEST_F(SSEIntegrationTest, OnMessageCallback) {
|
||||||
// Endpoint that sends multiple events then closes
|
// Endpoint that sends multiple events then closes
|
||||||
|
|||||||
Reference in new issue
Block a user