Skip to content

fix: limit the size of an event read by EventStreamReader - #1604

Merged
jlouvel merged 2 commits into
3.0from
fix/sse-reader-event-limit
Nov 2, 2026
Merged

jlouvel merged 2 commits into
3.0from
fix/sse-reader-event-limit

Conversation

@jlouvel

@jlouvel jlouvel commented Oct 30, 2026

Copy link
Copy Markdown
Collaborator

Fixes #1597.

Summary

EventStreamReader read lines with BufferedReader.readLine() and appended data: and comment lines until a blank line, so a server could make a client buffer an unbounded line or event in memory.

  • Lines are now read with a bounded reader that keeps the CRLF, LF and CR handling of readLine(). As before, a CR returns the line at once and a following LF is skipped on the next read, so a live stream doesn't block on a trailing CR.
  • The characters of an event's lines, without line terminators, count toward a maximum event size: 1 Mi characters by default, set with setMaxEventSize(int). DEFAULT_MAX_EVENT_SIZE is public.
  • When the limit is exceeded, readEvent() throws an IOException and closes the reader, rather than truncating the event. Later reads return null.

The limit counts all the lines of an event (field names included), not only the data and comment text, which keeps the check simple and strict.

Testing

New cases in EventStreamTestCase:

  • an event exactly at the limit is accepted;
  • an oversized line fails and stops the reader;
  • an event that exceeds the limit across several lines fails;
  • the setter rejects non-positive values;
  • CR line endings return an event without reading past the available input.

EventStreamTestCase and EventStreamConnectorTestCase pass locally (15 tests). The full core suite was not run locally, because the machine was short of memory; CI runs it.

🤖 Generated with Claude Code

@jlouvel jlouvel self-assigned this Oct 31, 2026
@jlouvel
jlouvel requested a balanced review from Copilot October 31, 2026 07:20

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The size limit incorrectly counts an initial BOM, and a close failure can hide the exception explaining why the event was rejected.

2 open issues
What changed in this PR

This PR addresses #1597 by bounding the memory used by EventStreamReader when reading Server-Sent Events.

Changes:

  • Adds a configurable event-size limit, defaulting to 1 Mi characters, with bounded line reading.
  • Rejects oversized events with an IOException and closes the reader while preserving CRLF, LF, and CR handling.
  • Adds boundary and rejection tests and documents the behavior in the changelog.
File Description
org.restlet/​src/​test/​java/​org/​restlet/​representation/​EventStreamTestCase.java Tests size limits, invalid configuration, and nonblocking CR handling.
org.restlet/​src/​main/​java/​org/​restlet/​representation/​EventStreamReader.java Adds bounded reads and configurable event-size enforcement.
changes.md Records the new limit and oversized-event behavior.

Review effort: Balanced

@jlouvel
jlouvel force-pushed the fix/sse-reader-event-limit branch 2 times, most recently from 2e6877e to 8a06cec Compare November 1, 2026 21:29
jlouvel and others added 2 commits November 1, 2026 21:07
EventStreamReader read lines with BufferedReader.readLine() and appended
data and comment lines until a blank line, so a server could make a
client buffer an unbounded line or event in memory.

Lines are now read with a bounded reader that keeps the CRLF, LF and CR
handling, and the characters of an event's lines are counted. Beyond
the maximum event size (1 Mi characters by default, setMaxEventSize),
readEvent() throws an IOException and closes the reader.

Fixes #1597.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Signed-off-by: Jerome Louvel <[email protected]>
…size failure

The optional byte order mark at the start of the stream was counted in the
size of the first event before being removed, so an event of exactly the
maximum size was rejected. It is now skipped while reading the first line.

When closing the reader failed after an event exceeded the maximum size,
the close failure replaced the size failure. The size failure is now
thrown, with the close failure suppressed.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@jlouvel
jlouvel force-pushed the fix/sse-reader-event-limit branch from 3c6b0f1 to ea3cbb5 Compare November 2, 2026 02:07
@sonarqubecloud

sonarqubecloud Bot commented Nov 2, 2026

Copy link
Copy Markdown

@jlouvel
jlouvel merged commit d3fe990 into 3.0 Nov 2, 2026
3 checks passed
@jlouvel
jlouvel deleted the fix/sse-reader-event-limit branch November 2, 2026 02:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants