Skip to content

Commit 691f069

Browse files
authored
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
1 parent cf8b8ce commit 691f069

File tree

1 file changed

+13
-6
lines changed

1 file changed

+13
-6
lines changed

websock/session.nim

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,10 @@ proc handleClose*(
249249
if ws.readyState != ReadyState.Closing:
250250
ws.readyState = ReadyState.Closing
251251
trace "Sending close", code = ord(code), reason
252-
await ws.send(prepareCloseBody(code, reason), Opcode.Close)
252+
try:
253+
await ws.send(prepareCloseBody(code, reason), Opcode.Close).wait(5.seconds)
254+
except CatchableError as exc:
255+
trace "Failed to send Close opcode", err=exc.msg
253256

254257
ws.readyState = ReadyState.Closed
255258

@@ -502,18 +505,22 @@ proc close*(
502505
if ws.readyState != ReadyState.Open:
503506
return
504507

505-
try:
506-
ws.readyState = ReadyState.Closing
508+
proc gentleCloser(ws: WSSession, closeBody: seq[byte]) {.async.} =
507509
await ws.send(
508-
prepareCloseBody(code, reason),
510+
closeBody,
509511
opcode = Opcode.Close)
510512

511513
# read frames until closed
512514
try:
513515
while ws.readyState != ReadyState.Closed:
514516
discard await ws.readFrame()
515517
except CatchableError as exc:
516-
ws.readyState = ReadyState.Closed
517-
await ws.stream.closeWait()
518+
discard # most likely EOF
519+
try:
520+
ws.readyState = ReadyState.Closing
521+
await gentleCloser(ws, prepareCloseBody(code, reason)).wait(10.seconds)
518522
except CatchableError as exc:
519523
trace "Exception closing", exc = exc.msg
524+
finally:
525+
await ws.stream.closeWait()
526+
ws.readyState = ReadyState.Closed

0 commit comments

Comments
 (0)