@@ -386,6 +386,14 @@ defmodule ThousandIsland.Handler do
386
386
{ :stop , reason , { socket , state } }
387
387
end
388
388
389
+ def handle_info ( { msg , _raw_socket , _data } , _state ) when msg in [ :tcp , :ssl ] do
390
+ raise """
391
+ The callback's `state` doesn't match the expected `{socket, state}` form.
392
+ Please ensure that you are returning a `{socket, state}` tuple from any
393
+ `GenServer.handle_*` callbacks you have implemented
394
+ """
395
+ end
396
+
389
397
def handle_info ( :timeout , { % ThousandIsland.Socket { } = socket , state } ) do
390
398
{ :stop , { :shutdown , :timeout } , { socket , state } }
391
399
end
@@ -395,65 +403,64 @@ defmodule ThousandIsland.Handler do
395
403
# This ensures that the `c:terminate/2` calls below are able to properly
396
404
# close down the process
397
405
@ impl GenServer
398
- def handle_continue ( :handle_connection , { socket , state } ) do
406
+ def handle_continue ( :handle_connection , { % ThousandIsland.Socket { } = socket , state } ) do
399
407
__MODULE__ . handle_connection ( socket , state )
400
408
|> handle_continuation ( socket )
401
409
end
402
410
403
- @ impl GenServer
404
- def terminate ( reason , state )
405
-
406
- # This clause could happen if we are shut down before we have had a chance to fully set up
407
- # the handler process. In this case we would have never called any of the `Handler`
408
- # callbacks so the connection hasn't started yet from the perspective of the user
409
- # See https://github.com/mtrudel/bandit/issues/54 for details
410
- def terminate ( _reason , { nil , _state } ) do
411
- :ok
412
- end
413
-
414
411
# Called if the remote end closed the connection before we could initialize it
412
+ @ impl GenServer
415
413
def terminate ( { :shutdown , { :premature_conn_closing , _reason } } , { _raw_socket , _state } ) do
416
414
:ok
417
415
end
418
416
419
417
# Called by GenServer if we hit our read_timeout. Socket is still open
420
- def terminate ( { :shutdown , :timeout } , { socket , state } ) do
418
+ def terminate ( { :shutdown , :timeout } , { % ThousandIsland.Socket { } = socket , state } ) do
421
419
__MODULE__ . handle_timeout ( socket , state )
422
420
do_socket_close ( socket , :timeout )
423
421
end
424
422
425
423
# Called if we're being shutdown in an orderly manner. Socket is still open
426
- def terminate ( :shutdown , { socket , state } ) do
424
+ def terminate ( :shutdown , { % ThousandIsland.Socket { } = socket , state } ) do
427
425
__MODULE__ . handle_shutdown ( socket , state )
428
426
do_socket_close ( socket , :shutdown )
429
427
end
430
428
431
429
# Called if the socket encountered an error during handshaking
432
- def terminate ( { :shutdown , { :handshake , reason } } , { socket , state } ) do
430
+ def terminate ( { :shutdown , { :handshake , reason } } , { % ThousandIsland.Socket { } = socket , state } ) do
433
431
__MODULE__ . handle_error ( reason , socket , state )
434
432
do_socket_close ( socket , reason )
435
433
end
436
434
437
435
# Called if the socket encountered an error and we are configured to shutdown silently.
438
436
# Socket is closed
439
- def terminate ( { :shutdown , { :silent_termination , reason } } , { socket , state } ) do
437
+ def terminate (
438
+ { :shutdown , { :silent_termination , reason } } ,
439
+ { % ThousandIsland.Socket { } = socket , state }
440
+ ) do
440
441
__MODULE__ . handle_error ( reason , socket , state )
441
442
do_socket_close ( socket , reason )
442
443
end
443
444
444
445
# Called if the remote end shut down the connection, or if the local end closed the
445
446
# connection by returning a `{:close,...}` tuple (in which case the socket will be open)
446
- def terminate ( { :shutdown , reason } , { socket , state } ) do
447
+ def terminate ( { :shutdown , reason } , { % ThousandIsland.Socket { } = socket , state } ) do
447
448
__MODULE__ . handle_close ( socket , state )
448
449
do_socket_close ( socket , reason )
449
450
end
450
451
451
452
# Called if the socket encountered an error. Socket is closed
452
- def terminate ( reason , { socket , state } ) do
453
+ def terminate ( reason , { % ThousandIsland.Socket { } = socket , state } ) do
453
454
__MODULE__ . handle_error ( reason , socket , state )
454
455
do_socket_close ( socket , reason )
455
456
end
456
457
458
+ # This clause could happen if we do not have a socket defined in state (either because the
459
+ # process crashed before setting it up, or because the user sent an invalid state)
460
+ def terminate ( _reason , _state ) do
461
+ :ok
462
+ end
463
+
457
464
@ spec do_socket_close (
458
465
ThousandIsland.Socket . t ( ) ,
459
466
reason :: :shutdown | :local_closed | term ( )
0 commit comments