-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WebSocket#close accepts code and reason arguments #7483
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -53,7 +53,7 @@ class HTTP::WebSocket | |
def on_binary(&@on_binary : Bytes ->) | ||
end | ||
|
||
def on_close(&@on_close : String ->) | ||
def on_close(&@on_close : Int16?, String? ->) | ||
end | ||
|
||
protected def check_open | ||
|
@@ -90,18 +90,26 @@ class HTTP::WebSocket | |
end | ||
end | ||
|
||
def close(message = nil) | ||
# Closes the websocket. | ||
def close | ||
return if closed? | ||
@closed = true | ||
@ws.close(message) | ||
@ws.close | ||
end | ||
|
||
# Closes the websocket with *code* and *reason*. | ||
def close(code : Int16, reason : String? = nil) | ||
return if closed? | ||
@closed = true | ||
@ws.close(code, reason) | ||
end | ||
|
||
def run | ||
loop do | ||
begin | ||
info = @ws.receive(@buffer) | ||
rescue IO::EOFError | ||
@on_close.try &.call("") | ||
@on_close.try &.call(nil, nil) | ||
vladfaust marked this conversation as resolved.
Show resolved
Hide resolved
|
||
break | ||
end | ||
|
||
|
@@ -135,9 +143,16 @@ class HTTP::WebSocket | |
when Protocol::Opcode::CLOSE | ||
@current_message.write @buffer[0, info.size] | ||
if info.final | ||
message = @current_message.to_s | ||
@on_close.try &.call(message) | ||
close(message) unless closed? | ||
begin | ||
code = @current_message.read_bytes(Int16, IO::ByteFormat::NetworkEndian) | ||
reason = @current_message.gets_to_end | ||
@on_close.try &.call(code, reason) | ||
rescue IO::EOFError | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't this be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Makes sense There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🏓 |
||
@on_close.try &.call(nil, nil) | ||
vladfaust marked this conversation as resolved.
Show resolved
Hide resolved
|
||
ensure | ||
close unless closed? | ||
end | ||
|
||
@current_message.clear | ||
break | ||
end | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -229,12 +229,15 @@ class HTTP::WebSocket::Protocol | |
end | ||
end | ||
|
||
def close(message = nil) | ||
if message | ||
send(message.to_slice, Opcode::CLOSE) | ||
else | ||
send(Bytes.empty, Opcode::CLOSE) | ||
end | ||
def close | ||
send(Bytes.empty, Opcode::CLOSE) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Edit: On second thought, maybe disregard. There is the reserved 1005 close code which is not explicitly sent, but is implicitly received when a client sends a close frame with no body. 🤷♂️ |
||
end | ||
|
||
def close(code : Int16, reason : String? = nil) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto |
||
slice = Bytes.new(sizeof(Int16) + (reason ? reason.bytesize : 0)) | ||
IO::ByteFormat::NetworkEndian.encode(code, slice) | ||
reason.to_slice.copy_to(slice + sizeof(Int16)) if reason | ||
send(slice, Opcode::CLOSE) | ||
end | ||
|
||
def self.new(host : String, path : String, port = nil, tls = false, headers = HTTP::Headers.new) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, shouldn't
code
beUInt16
everywhere?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Sija see in the discussion above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't find it, which discussion?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Sija See:
#7483 (comment)
#7483 (comment)