[rb] fix silent hang on oversized WebSocket frames#17655
Conversation
websocket-ruby drops frames larger than WebSocket.max_frame_size (20MB default) and keeps returning nil, so the listener spun forever and the process appeared to hang (e.g. large CDP data: URL payloads under request interception). Raise the limit to 100MB for our connections (lazily, and only when the user has not already set a larger value, so non-DevTools users and custom configs are unaffected), and surface an undecodable frame as a logged error that stops the listener instead of hanging silently. Fixes SeleniumHQ#17264
Review Summary by QodoFix silent hang on oversized WebSocket frames
WalkthroughsDescription• Raise WebSocket frame size limit to 100MB for DevTools connections • Surface dropped frames as logged errors instead of silent hangs • Add frame error detection to stop listener gracefully • Include unit tests for frame size and error handling Diagramflowchart LR
A["WebSocket Frame Received"] --> B["Check Frame Size"]
B --> C{"Exceeds Limit?"}
C -->|No| D["Process Frame"]
C -->|Yes| E["frame_dropped? Detects Error"]
E --> F["Log Error Message"]
F --> G["Stop Listener Gracefully"]
D --> H["Continue Processing"]
File Changes1. rb/lib/selenium/webdriver/common/websocket_connection.rb
|
Code Review by Qodo
1.
|
|
Code review by qodo was updated up to the latest commit 510ee4e |
💥 What does this PR do?
The Ruby devtools/bidi websocket listener can hang when it gets a frame bigger than WebSocket.max_frame_size (websocket-ruby defaults to 20MB).
Websocket-ruby raises TooLong internally but rescues it unless you set should_raise, so incoming_frame.next just returns nil, the oversized bytes stay buffered, and the loop spins forever at ~100% cpu.
builds on #17286, thanks @Chandan25sharma. left the track_cancelled part out, that's separate.
🔧 Implementation Notes
the bump happens in WebSocketConnection#initialize, not at load time, and only when the current limit is lower, so non-devtools users or anyone who already set a bigger value aren't affected. websocket-ruby only
exposes max_frame_size globally so there's no per-instance option. didn't touch should_raise, detection uses the per-instance incoming_frame.error? instead.
🤖 AI assistance
🔄 Types of changes