From 4564736fde067ab35c3227784aeb07eda3d52257 Mon Sep 17 00:00:00 2001 From: James Coglan Date: Mon, 6 Mar 2017 21:12:27 +0000 Subject: [PATCH] Bring close frame handling into line between parser implementations. --- .../com/jcoglan/websocket/Parser.java | 2 +- ext/websocket_driver/parser.c | 1 - lib/websocket/driver/hybi/parser.rb | 24 ++++++++++--------- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/ext/websocket_driver/com/jcoglan/websocket/Parser.java b/ext/websocket_driver/com/jcoglan/websocket/Parser.java index a7f7b5a..e986f6c 100644 --- a/ext/websocket_driver/com/jcoglan/websocket/Parser.java +++ b/ext/websocket_driver/com/jcoglan/websocket/Parser.java @@ -240,6 +240,7 @@ public class Parser { case OPCODE_CLOSE: if (frame.length == 0) { code = DEFAULT_ERROR_CODE; + reason = new byte[0]; } else if (frame.length >= 2) { code = bitshift(frame.payload[0], 8) | bitshift(frame.payload[1], 0); reason = Arrays.copyOfRange(frame.payload, 2, (int)frame.length); @@ -247,7 +248,6 @@ public class Parser { if (!validCloseCode(code)) { code = PROTOCOL_ERROR; - // TODO emit error on invalid code } observer.onClose(code, reason); break; diff --git a/ext/websocket_driver/parser.c b/ext/websocket_driver/parser.c index 4989b1e..db0b06b 100644 --- a/ext/websocket_driver/parser.c +++ b/ext/websocket_driver/parser.c @@ -291,7 +291,6 @@ void wsd_Parser_emit_frame(wsd_Parser *parser) if (!wsd_Parser_valid_close_code(code)) { code = WSD_PROTOCOL_ERROR; - // TODO emit error on invalid code } wsd_Observer_on_close(parser->observer, code, length, reason); break; diff --git a/lib/websocket/driver/hybi/parser.rb b/lib/websocket/driver/hybi/parser.rb index 20f2c1c..751db70 100644 --- a/lib/websocket/driver/hybi/parser.rb +++ b/lib/websocket/driver/hybi/parser.rb @@ -135,6 +135,9 @@ module WebSocket @frame = nil + code = 0 + reason = nil + case opcode when OPCODES[:continuation] then return parser_error(:protocol_error, 'Received unexpected continuation frame') unless @message @@ -145,21 +148,20 @@ module WebSocket @message << frame when OPCODES[:close] then - code = (bytesize >= 2) ? payload.unpack(PACK_FORMATS[2]).first : nil - reason = (bytesize > 2) ? Driver.encode(bytes[2..-1] || [], UNICODE) : nil + if frame.length == 0 + code = DEFAULT_ERROR_CODE + reason = '' + elsif frame.length >= 2 + code = payload.unpack(PACK_FORMATS[2]).first + reason = bytes[2..-1] + end - unless (bytesize == 0) or - (code && code >= MIN_RESERVED_ERROR && code <= MAX_RESERVED_ERROR) or - ERROR_CODES.include?(code) + unless ERROR_CODES.include?(code) or + (code >= MIN_RESERVED_ERROR and code <= MAX_RESERVED_ERROR) code = ERRORS[:protocol_error] end - if bytesize > 125 or (bytesize > 2 and reason.nil?) - code = ERRORS[:protocol_error] - # TODO emit error on invalid code - end - - @driver.__send__(:handle_close, code || DEFAULT_ERROR_CODE, reason || '') + @driver.__send__(:handle_close, code, reason || '') when OPCODES[:ping] then @driver.__send__(:handle_ping, payload)