Fix some issues with recv hanging (#109)

* Crash on concurrent reads
* Fix some issues with recv hanging
This commit is contained in:
Tanguy 2022-05-18 14:37:53 +02:00 committed by GitHub
parent 5311a6e0b8
commit edfbb169c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 12 additions and 3 deletions

View File

@ -205,6 +205,9 @@ proc decode*(
frame.length = finalLen frame.length = finalLen
if frame.length > WSMaxMessageSize:
raise newException(WSPayloadLengthError, "Frame too big: " & $frame.length)
# Do we need to apply mask? # Do we need to apply mask?
frame.mask = (b1 and 0x80) == 0x80 frame.mask = (b1 and 0x80) == 0x80
if masked == frame.mask: if masked == frame.mask:

View File

@ -312,6 +312,10 @@ proc recv*(
## Use this to stream data from frames ## Use this to stream data from frames
## ##
doAssert ws.reading == false, "Only one concurrent read allowed"
ws.reading = true
defer: ws.reading = false
var consumed = 0 var consumed = 0
var pbuffer = cast[ptr UncheckedArray[byte]](data) var pbuffer = cast[ptr UncheckedArray[byte]](data)
try: try:
@ -321,7 +325,8 @@ proc recv*(
while consumed < size: while consumed < size:
if isNil(ws.frame): if isNil(ws.frame):
trace "Empty frame, breaking" assert ws.readyState == ReadyState.Closed
trace "Closed connection, breaking"
break break
logScope: logScope:
@ -347,8 +352,8 @@ proc recv*(
trace "Reading bytes from frame stream", len trace "Reading bytes from frame stream", len
let read = await ws.frame.read(ws.stream.reader, addr pbuffer[consumed], len) let read = await ws.frame.read(ws.stream.reader, addr pbuffer[consumed], len)
if read <= 0: if read <= 0:
trace "Didn't read any bytes, breaking" trace "Didn't read any bytes, stopping"
break raise newException(WSClosedError, "WebSocket is closed!")
trace "Read data from frame", read trace "Read data from frame", read
consumed += read consumed += read

View File

@ -96,6 +96,7 @@ type
stream*: AsyncStream stream*: AsyncStream
frame*: Frame frame*: Frame
first*: bool first*: bool
reading*: bool
proto*: string proto*: string
Ext* = ref object of RootObj Ext* = ref object of RootObj