Skip to content

Commit 1f90cb9

Browse files
committed
Enforce maximum payload size
1 parent 577c1d7 commit 1f90cb9

File tree

8 files changed

+777
-18
lines changed

8 files changed

+777
-18
lines changed

PROTOCOL.md

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ All messages MUST have no control flags set (i.e., the `controlFlags` field is `
162162
- The payload MUST be `{ type: 'ACK' }`.
163163
- Because this is a control message that is not associated with a specific stream, you MUST NOT set `serviceName` or `procedureName` and `streamId` can be something arbitrary (e.g. `heartbeat`).
164164

165-
There are 4 error payloads that are defined in the protocol sent from server to client, these codes are reserved:
165+
There are 5 error payloads that are defined in the protocol sent from server to client, these codes are reserved:
166166

167167
```ts
168168
// When a client sends a malformed request. This can be
@@ -187,11 +187,22 @@ interface CancelError extends BaseError {
187187
message: string;
188188
}
189189

190+
// This occurrs when a client or server attempts to send a message that is
191+
// larger than the configurable max payload size.
192+
interface MaxPayloadSizeExceededError extends BaseError {
193+
code: 'MAX_PAYLOAD_SIZE_EXCEEDED';
194+
message: string;
195+
}
196+
190197
// This is sent when the server encounters an internal error
191198
// i.e. an invariant has been violated
192199
interface;
193200

194-
type ProtocolError = UncaughtError | InvalidRequestError | CancelError;
201+
type ProtocolError =
202+
| UncaughtError
203+
| InvalidRequestError
204+
| CancelError
205+
| MaxPayloadSizeExceededError;
195206
```
196207

197208
`ProtocolError`s, just like service-level errors, are wrapped with a `Result`, which is further wrapped with `TransportMessage` and MUST have a `StreamCancelBit` flag. Please note that these are separate from user-defined errors, which should be treated just like any response message.
@@ -672,3 +683,23 @@ This explicit ack serves three purposes:
672683
1. It keeps the connection alive by preventing the underlying transport from timing out.
673684
2. It allows the session to detect when the underlying transport has been lost, even in cases where the transport does not emit a close event.
674685
3. It provides an upper bound on how many messages the session buffers in the case of a reconnection (consider the case where an upload procedure is really long-lived and the server doesn't send any messages until the upload is finished. Without these explicit heartbeats, the client will buffer everything!).
686+
687+
#### Maximum payload size handling
688+
689+
It is desirable to set a maximum allowed payload size to prevent clients or servers from sending payloads that are too large for the underlying transport. Some transports may enforce a maximum payload size and close the connection if that is exceeded. This would cause the entire river session to become broken as this payload cannot be transmitted. It is better to catch this before sending the message on the transport and only fail the single procedure call that was attempting to send the large payload.
690+
691+
Payload size is calculated after encoding the message with the configured codec.
692+
693+
##### Client handling
694+
695+
###### Init Message
696+
697+
If the init message of a procedure exceeds the maximum payload size, the client must inject a `MAX_PAYLOAD_SIZE_EXCEEDED` error and fail the procedure. In this case no message is ever sent to the server and is handled entirely client-side.
698+
699+
###### Non-init message
700+
701+
If the client attempts to send a message after a procedure has been started which exceeds the maximum payload size. The client must throw an error inside the `write` call and inject a `MAX_PAYLOAD_SIZE_EXCEEDED` error in the procedure read stream. The client must also send a cancel request to the server so the server-side resources can be cleaned up.
702+
703+
##### Server handling
704+
705+
If the server attempts to send a message after a procedure has been started which exceeds the maximum payload size, the server must reply with a `MAX_PAYLOAD_SIZE_EXCEEDED` error and close down the procedure.

0 commit comments

Comments
 (0)