Fix closing hangs (#131)

A peer can make us wait forever when closing a connection.
This PR instead tries to be nice and wait for him, but kills the connection after a while
This commit is contained in:
Tanguy 2022-11-22 10:45:38 +01:00 committed by GitHub
parent cf8b8ce235
commit 691f069b20
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -249,7 +249,10 @@ proc handleClose*(
if ws.readyState != ReadyState.Closing:
ws.readyState = ReadyState.Closing
trace "Sending close", code = ord(code), reason
await ws.send(prepareCloseBody(code, reason), Opcode.Close)
try:
await ws.send(prepareCloseBody(code, reason), Opcode.Close).wait(5.seconds)
except CatchableError as exc:
trace "Failed to send Close opcode", err=exc.msg
ws.readyState = ReadyState.Closed
@ -502,10 +505,9 @@ proc close*(
if ws.readyState != ReadyState.Open:
return
try:
ws.readyState = ReadyState.Closing
proc gentleCloser(ws: WSSession, closeBody: seq[byte]) {.async.} =
await ws.send(
prepareCloseBody(code, reason),
closeBody,
opcode = Opcode.Close)
# read frames until closed
@ -513,7 +515,12 @@ proc close*(
while ws.readyState != ReadyState.Closed:
discard await ws.readFrame()
except CatchableError as exc:
ws.readyState = ReadyState.Closed
await ws.stream.closeWait()
discard # most likely EOF
try:
ws.readyState = ReadyState.Closing
await gentleCloser(ws, prepareCloseBody(code, reason)).wait(10.seconds)
except CatchableError as exc:
trace "Exception closing", exc = exc.msg
finally:
await ws.stream.closeWait()
ws.readyState = ReadyState.Closed