Skip to content

Commit fc77758

Browse files
penalosaRamIdeas
andauthored
Add a compat flag for increasing the WS message size limit (#2164)
* Add a compat flag for increasing the WS message size limit * Move compat flag to end of list * Reverse negation * Update messaging * move maxMessageSize and reading feature flag into startReadLoop * use constant kj::WebSocket::SUGGESTED_MAX_MESSAGE_SIZE --------- Co-authored-by: Rahul Sethi <[email protected]>
1 parent ce15e0b commit fc77758

File tree

3 files changed

+20
-4
lines changed

3 files changed

+20
-4
lines changed

src/workerd/api/web-socket.c++

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -476,14 +476,19 @@ WebSocket::Accepted::~Accepted() noexcept(false) {
476476
}
477477

478478
void WebSocket::startReadLoop(jsg::Lock& js, kj::Maybe<kj::Own<InputGate::CriticalSection>> cs) {
479+
size_t maxMessageSize = kj::WebSocket::SUGGESTED_MAX_MESSAGE_SIZE;
480+
if (FeatureFlags::get(js).getIncreaseWebsocketMessageSize()) {
481+
maxMessageSize = 128u << 20;
482+
}
483+
479484
// If the kj::WebSocket happens to be an AbortableWebSocket (see util/abortable.h), then
480485
// calling readLoop here could throw synchronously if the canceler has already been tripped.
481486
// Using kj::evalNow() here let's us capture that and handle correctly.
482487
//
483488
// We catch exceptions and return Maybe<Exception> instead since we want to handle the exceptions
484489
// in awaitIo() below, but we don't want the KJ exception converted to JavaScript before we can
485490
// examine it.
486-
kj::Promise<kj::Maybe<kj::Exception>> promise = readLoop(kj::mv(cs));
491+
kj::Promise<kj::Maybe<kj::Exception>> promise = readLoop(kj::mv(cs), maxMessageSize);
487492

488493
auto& context = IoContext::current();
489494

@@ -942,14 +947,15 @@ kj::Array<kj::StringPtr> WebSocket::getHibernatableTags() {
942947
}
943948

944949
kj::Promise<kj::Maybe<kj::Exception>> WebSocket::readLoop(
945-
kj::Maybe<kj::Own<InputGate::CriticalSection>> cs) {
950+
kj::Maybe<kj::Own<InputGate::CriticalSection>> cs,
951+
size_t maxMessageSize) {
946952
try {
947953
// Note that we'll throw if the websocket has enabled hibernation.
948954
auto& ws = *KJ_REQUIRE_NONNULL(
949955
KJ_ASSERT_NONNULL(farNative->state.tryGet<Accepted>()).ws.getIfNotHibernatable());
950956
auto& context = IoContext::current();
951957
while (true) {
952-
auto message = co_await ws.receive();
958+
auto message = co_await ws.receive(maxMessageSize);
953959

954960
auto size = countBytesFromMessage(message);
955961
KJ_IF_SOME(o, observer) {

src/workerd/api/web-socket.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,9 @@ class WebSocket: public EventTarget {
445445
// `close()`, thereby preventing calls to `send()` even after we wake from hibernation.
446446
bool closedOutgoingForHib = false;
447447

448+
// Maximum allowed size for WebSocket messages
449+
inline static const size_t SUGGESTED_MAX_MESSAGE_SIZE = 1u << 20;
450+
448451
// Maximum size of a WebSocket attachment.
449452
inline static const size_t MAX_ATTACHMENT_SIZE = 1024 * 2;
450453

@@ -648,7 +651,7 @@ class WebSocket: public EventTarget {
648651
IoContext& context, OutgoingMessagesMap& outgoingMessages, kj::WebSocket& ws, Native& native,
649652
AutoResponse& autoResponse, kj::Maybe<kj::Own<WebSocketObserver>>& observer);
650653

651-
kj::Promise<kj::Maybe<kj::Exception>> readLoop(kj::Maybe<kj::Own<InputGate::CriticalSection>> cs);
654+
kj::Promise<kj::Maybe<kj::Exception>> readLoop(kj::Maybe<kj::Own<InputGate::CriticalSection>> cs, size_t maxMessageSize);
652655

653656
void reportError(jsg::Lock& js, kj::Exception&& e);
654657
void reportError(jsg::Lock& js, jsg::JsRef<jsg::JsValue> err);

src/workerd/io/compatibility-date.capnp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,4 +523,11 @@ struct CompatibilityFlags @0x8f8c1b68151b6cef {
523523
# Enables fetching hosts with a custom port from workers.
524524
# For orange clouded sites only standard ports are allowed (https://developers.cloudflare.com/fundamentals/reference/network-ports/#network-ports-compatible-with-cloudflares-proxy).
525525
# For grey clouded sites all ports are allowed.
526+
527+
increaseWebsocketMessageSize @56 :Bool
528+
$compatEnableFlag("increase_websocket_message_size")
529+
$experimental;
530+
# For local development purposes only, increase the message size limit to 128MB.
531+
# This is not expected ever to be made available in production, as large messages are inefficient.
532+
526533
}

0 commit comments

Comments
 (0)