commit rubygem-websocket-driver for openSUSE:Factory
Hello community, here is the log from the commit of package rubygem-websocket-driver for openSUSE:Factory checked in at 2019-06-30 10:22:27 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/rubygem-websocket-driver (Old) and /work/SRC/openSUSE:Factory/.rubygem-websocket-driver.new.4615 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "rubygem-websocket-driver" Sun Jun 30 10:22:27 2019 rev:4 rq:712552 version:0.7.1 Changes: -------- --- /work/SRC/openSUSE:Factory/rubygem-websocket-driver/rubygem-websocket-driver.changes 2017-10-06 11:03:17.662759033 +0200 +++ /work/SRC/openSUSE:Factory/.rubygem-websocket-driver.new.4615/rubygem-websocket-driver.changes 2019-06-30 10:22:32.631717373 +0200 @@ -1,0 +2,14 @@ +Sat Jun 29 22:12:11 UTC 2019 - Manuel Schnitzer <mschnitzer@suse.com> + +- updated to version 0.7.1 + + * Catch any exceptions produced while generating a handshake + response and send a `400 Bad Request` response to the client + * Pick the RFC-6455 protocol version if the request contains any + of the headers + used by that version + * Handle errors encountered while handling malformed draft-76 + requests + * Change license from MIT to Apache 2.0 + +------------------------------------------------------------------- Old: ---- websocket-driver-0.7.0.gem New: ---- websocket-driver-0.7.1.gem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ rubygem-websocket-driver.spec ++++++ --- /var/tmp/diff_new_pack.4x83iC/_old 2019-06-30 10:22:33.191718243 +0200 +++ /var/tmp/diff_new_pack.4x83iC/_new 2019-06-30 10:22:33.191718243 +0200 @@ -1,7 +1,7 @@ # # spec file for package rubygem-websocket-driver # -# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -12,7 +12,7 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# Please submit bugfixes or comments via https://bugs.opensuse.org/ # @@ -24,7 +24,7 @@ # Name: rubygem-websocket-driver -Version: 0.7.0 +Version: 0.7.1 Release: 0 %define mod_name websocket-driver %define mod_full_name %{mod_name}-%{version} @@ -37,7 +37,7 @@ Source: https://rubygems.org/gems/%{mod_full_name}.gem Source1: gem2rpm.yml Summary: WebSocket protocol handler with pluggable I/O -License: MIT +License: Apache-2.0 Group: Development/Languages/Ruby %description ++++++ websocket-driver-0.7.0.gem -> websocket-driver-0.7.1.gem ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/CHANGELOG.md new/CHANGELOG.md --- old/CHANGELOG.md 2017-09-11 23:16:18.000000000 +0200 +++ new/CHANGELOG.md 2019-06-10 13:40:12.000000000 +0200 @@ -1,127 +1,136 @@ +### 0.7.1 / 2019-06-10 + +- Catch any exceptions produced while generating a handshake response and send a + `400 Bad Request` response to the client +- Pick the RFC-6455 protocol version if the request contains any of the headers + used by that version +- Handle errors encountered while handling malformed draft-76 requests + ### 0.7.0 / 2017-09-11 -* Add `ping` and `pong` to the set of events users can listen to +- Add `ping` and `pong` to the set of events users can listen to ### 0.6.5 / 2017-01-22 -* Provide a pure-Ruby fallback for the native unmasking code +- Provide a pure-Ruby fallback for the native unmasking code ### 0.6.4 / 2016-05-20 -* Amend warnings issued when running with -W2 -* Make sure message strings passed in by the app are transcoded to UTF-8 -* Copy strings if necessary for frozen-string compatibility +- Amend warnings issued when running with -W2 +- Make sure message strings passed in by the app are transcoded to UTF-8 +- Copy strings if necessary for frozen-string compatibility ### 0.6.3 / 2015-11-06 -* Reject draft-76 handshakes if their Sec-WebSocket-Key headers are invalid -* Throw a more helpful error if a client is created with an invalid URL +- Reject draft-76 handshakes if their Sec-WebSocket-Key headers are invalid +- Throw a more helpful error if a client is created with an invalid URL ### 0.6.2 / 2015-07-18 -* When the peer sends a close frame with no error code, emit 1000 +- When the peer sends a close frame with no error code, emit 1000 ### 0.6.1 / 2015-07-13 -* Fix how events are stored in `EventEmitter` to fix a backward-compatibility +- Fix how events are stored in `EventEmitter` to fix a backward-compatibility violation introduced in the last release -* Use the `Array#pack` and `String#unpack` methods for reading/writing numbers +- Use the `Array#pack` and `String#unpack` methods for reading/writing numbers to buffers rather than including duplicate logic for this ### 0.6.0 / 2015-07-08 -* Use `SecureRandom` to generate the `Sec-WebSocket-Key` header -* Allow the parser to recover cleanly if event listeners raise an error -* Let the `on()` method take a lambda as a positional argument rather than a block -* Add a `pong` method for sending unsolicited pong frames +- Use `SecureRandom` to generate the `Sec-WebSocket-Key` header +- Allow the parser to recover cleanly if event listeners raise an error +- Let the `on()` method take a lambda as a positional argument rather than a + block +- Add a `pong` method for sending unsolicited pong frames ### 0.5.4 / 2015-03-29 -* Don't emit extra close frames if we receive a close frame after we already +- Don't emit extra close frames if we receive a close frame after we already sent one -* Fail the connection when the driver receives an invalid +- Fail the connection when the driver receives an invalid `Sec-WebSocket-Extensions` header ### 0.5.3 / 2015-02-22 -* Don't treat incoming data as WebSocket frames if a client driver is closed +- Don't treat incoming data as WebSocket frames if a client driver is closed before receiving the server handshake ### 0.5.2 / 2015-02-19 -* Don't emit multiple `error` events +- Don't emit multiple `error` events ### 0.5.1 / 2014-12-18 -* Don't allow drivers to be created with unrecognized options +- Don't allow drivers to be created with unrecognized options ### 0.5.0 / 2014-12-13 -* Support protocol extensions via the websocket-extensions module +- Support protocol extensions via the websocket-extensions module ### 0.4.0 / 2014-11-08 -* Support connection via HTTP proxies using `CONNECT` +- Support connection via HTTP proxies using `CONNECT` ### 0.3.5 / 2014-10-04 -* Fix bug where the `Server` driver doesn't pass `ping` callbacks to its +- Fix bug where the `Server` driver doesn't pass `ping` callbacks to its delegate -* Fix an arity error when calling `fail_request` -* Allow `close` to be called before `start` to close the driver +- Fix an arity error when calling `fail_request` +- Allow `close` to be called before `start` to close the driver ### 0.3.4 / 2014-07-06 -* Don't hold references to frame buffers after a message has been emitted -* Make sure that `protocol` and `version` are exposed properly by the TCP driver -* Correct HTTP header parsing based on RFC 7230; header names cannot contain +- Don't hold references to frame buffers after a message has been emitted +- Make sure that `protocol` and `version` are exposed properly by the TCP driver +- Correct HTTP header parsing based on RFC 7230; header names cannot contain backslashes ### 0.3.3 / 2014-04-24 -* Fix problems with loading C and Java native extension code -* Correct the acceptable characters used in the HTTP parser -* Correct the draft-76 status line reason phrase +- Fix problems with loading C and Java native extension code +- Correct the acceptable characters used in the HTTP parser +- Correct the draft-76 status line reason phrase ### 0.3.2 / 2013-12-29 -* Expand `max_length` to cover sequences of continuation frames and +- Expand `max_length` to cover sequences of continuation frames and `draft-{75,76}` -* Decrease default maximum frame buffer size to 64MB -* Stop parsing when the protocol enters a failure mode, to save CPU cycles +- Decrease default maximum frame buffer size to 64MB +- Stop parsing when the protocol enters a failure mode, to save CPU cycles ### 0.3.1 / 2013-12-03 -* Add a `max_length` option to limit allowed frame size +- Add a `max_length` option to limit allowed frame size ### 0.3.0 / 2013-09-09 -* Support client URLs with Basic Auth credentials +- Support client URLs with Basic Auth credentials ### 0.2.3 / 2013-08-04 -* Fix bug in EventEmitter#emit when listeners are removed +- Fix bug in EventEmitter#emit when listeners are removed ### 0.2.2 / 2013-08-04 -* Fix bug in EventEmitter#listener_count for unregistered events +- Fix bug in EventEmitter#listener_count for unregistered events ### 0.2.1 / 2013-07-05 -* Queue sent messages if the client has not begun trying to connect -* Encode all strings sent to I/O as `ASCII-8BIT` +- Queue sent messages if the client has not begun trying to connect +- Encode all strings sent to I/O as `ASCII-8BIT` ### 0.2.0 / 2013-05-12 -* Add API for setting and reading headers -* Add Driver.server() method for getting a driver for TCP servers +- Add API for setting and reading headers +- Add Driver.server() method for getting a driver for TCP servers ### 0.1.0 / 2013-05-04 -* First stable release +- First stable release ### 0.0.0 / 2013-04-22 -* First release -* Proof of concept for people to try out -* Might be unstable +- First release +- Proof of concept for people to try out +- Might be unstable diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/LICENSE.md new/LICENSE.md --- old/LICENSE.md 2017-09-11 23:16:18.000000000 +0200 +++ new/LICENSE.md 2019-06-10 13:40:12.000000000 +0200 @@ -1,20 +1,12 @@ -# The MIT License +Copyright 2010-2019 James Coglan -Copyright (c) 2010-2017 James Coglan +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the 'Software'), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: + http://www.apache.org/licenses/LICENSE-2.0 -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +Unless required by applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/README.md new/README.md --- old/README.md 2017-09-11 23:16:18.000000000 +0200 +++ new/README.md 2019-06-10 13:40:12.000000000 +0200 @@ -10,21 +10,21 @@ Due to this design, you get a lot of things for free. In particular, if you hook this module up to some I/O object, it will do all of this for you: -* Select the correct server-side driver to talk to the client -* Generate and send both server- and client-side handshakes -* Recognize when the handshake phase completes and the WS protocol begins -* Negotiate subprotocol selection based on `Sec-WebSocket-Protocol` -* Negotiate and use extensions via the +- Select the correct server-side driver to talk to the client +- Generate and send both server- and client-side handshakes +- Recognize when the handshake phase completes and the WS protocol begins +- Negotiate subprotocol selection based on `Sec-WebSocket-Protocol` +- Negotiate and use extensions via the [websocket-extensions](https://github.com/faye/websocket-extensions-ruby) module -* Buffer sent messages until the handshake process is finished -* Deal with proxies that defer delivery of the draft-76 handshake body -* Notify you when the socket is open and closed and when messages arrive -* Recombine fragmented messages -* Dispatch text, binary, ping, pong and close frames -* Manage the socket-closing handshake process -* Automatically reply to ping frames with a matching pong -* Apply masking to messages sent by the client +- Buffer sent messages until the handshake process is finished +- Deal with proxies that defer delivery of the draft-76 handshake body +- Notify you when the socket is open and closed and when messages arrive +- Recombine fragmented messages +- Dispatch text, binary, ping, pong and close frames +- Manage the socket-closing handshake process +- Automatically reply to ping frames with a matching pong +- Apply masking to messages sent by the client This library was originally extracted from the [Faye](http://faye.jcoglan.com) project but now aims to provide simple WebSocket support for any Ruby server or @@ -43,12 +43,12 @@ To build either a server-side or client-side socket, the only requirement is that you supply a `socket` object with these methods: -* `socket.url` - returns the full URL of the socket as a string. -* `socket.write(string)` - writes the given string to a TCP stream. +- `socket.url` - returns the full URL of the socket as a string. +- `socket.write(string)` - writes the given string to a TCP stream. Server-side sockets require one additional method: -* `socket.env` - returns a Rack-style env hash that will contain some of the +- `socket.env` - returns a Rack-style env hash that will contain some of the following fields. Their values are strings containing the value of the named header, unless stated otherwise. * `HTTP_CONNECTION` @@ -193,8 +193,8 @@ Client drivers have two additional methods for reading the HTTP data that was sent back by the server: -* `driver.status` - the integer value of the HTTP status code -* `driver.headers` - a hash-like object containing the response headers +- `driver.status` - the integer value of the HTTP status code +- `driver.headers` - a hash-like object containing the response headers ### HTTP Proxies @@ -261,9 +261,9 @@ The `options` argument is optional, and is a hash. It may contain the following keys: -* `:max_length` - the maximum allowed size of incoming message frames, in bytes. +- `:max_length` - the maximum allowed size of incoming message frames, in bytes. The default value is `2^26 - 1`, or 1 byte short of 64 MiB. -* `:protocols` - an array of strings representing acceptable subprotocols for +- `:protocols` - an array of strings representing acceptable subprotocols for use over the socket. The driver will negotiate one of these to use via the `Sec-WebSocket-Protocol` header if supported by the other peer. Binary files old/checksums.yaml.gz and new/checksums.yaml.gz differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ext/websocket-driver/WebsocketMaskService.java new/ext/websocket-driver/WebsocketMaskService.java --- old/ext/websocket-driver/WebsocketMaskService.java 2017-09-11 23:16:18.000000000 +0200 +++ new/ext/websocket-driver/WebsocketMaskService.java 2019-06-10 13:40:12.000000000 +0200 @@ -1,8 +1,6 @@ package com.jcoglan.websocket; -import java.lang.Long; import java.io.IOException; - import org.jruby.Ruby; import org.jruby.RubyClass; import org.jruby.RubyModule; @@ -15,41 +13,45 @@ import org.jruby.runtime.load.BasicLibraryService; public class WebsocketMaskService implements BasicLibraryService { - private Ruby runtime; + private Ruby runtime; + + public boolean basicLoad(Ruby runtime) throws IOException { + this.runtime = runtime; + + RubyModule websocket = runtime.defineModule("WebSocket"); + RubyClass webSocketMask = websocket.defineClassUnder("Mask", runtime.getObject(), getAllocator()); + + webSocketMask.defineAnnotatedMethods(WebsocketMask.class); + return true; + } - public boolean basicLoad(Ruby runtime) throws IOException { - this.runtime = runtime; - RubyModule websocket = runtime.defineModule("WebSocket"); - - RubyClass webSocketMask = websocket.defineClassUnder("Mask", runtime.getObject(), new ObjectAllocator() { - public IRubyObject allocate(Ruby runtime, RubyClass rubyClass) { - return new WebsocketMask(runtime, rubyClass); - } - }); - - webSocketMask.defineAnnotatedMethods(WebsocketMask.class); - return true; - } - - public class WebsocketMask extends RubyObject { - public WebsocketMask(final Ruby runtime, RubyClass rubyClass) { - super(runtime, rubyClass); + ObjectAllocator getAllocator() { + return new ObjectAllocator() { + public IRubyObject allocate(Ruby runtime, RubyClass rubyClass) { + return new WebsocketMask(runtime, rubyClass); + } + }; } - @JRubyMethod - public IRubyObject mask(ThreadContext context, IRubyObject payload, IRubyObject mask) { - if (mask.isNil()) return payload; - - byte[] payload_a = ((RubyString)payload).getBytes(); - byte[] mask_a = ((RubyString)mask).getBytes(); - int i, n = payload_a.length; - - if (n == 0) return payload; - - for (i = 0; i < n; i++) { - payload_a[i] ^= mask_a[i % 4]; - } - return RubyString.newStringNoCopy(runtime, payload_a); + public class WebsocketMask extends RubyObject { + public WebsocketMask(final Ruby runtime, RubyClass rubyClass) { + super(runtime, rubyClass); + } + + @JRubyMethod + public IRubyObject mask(ThreadContext context, IRubyObject payload, IRubyObject mask) { + if (mask.isNil()) return payload; + + byte[] payload_a = ((RubyString)payload).getBytes(); + byte[] mask_a = ((RubyString)mask).getBytes(); + int i, n = payload_a.length; + + if (n == 0) return payload; + + for (i = 0; i < n; i++) { + payload_a[i] ^= mask_a[i % 4]; + } + return RubyString.newStringNoCopy(runtime, payload_a); + } } - } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ext/websocket-driver/websocket_mask.c new/ext/websocket-driver/websocket_mask.c --- old/ext/websocket-driver/websocket_mask.c 2017-09-11 23:16:18.000000000 +0200 +++ new/ext/websocket-driver/websocket_mask.c 2019-06-10 13:40:12.000000000 +0200 @@ -1,41 +1,32 @@ #include <ruby.h> -VALUE WebSocket = Qnil; -VALUE WebSocketMask = Qnil; - -void Init_websocket_mask(); -VALUE method_websocket_mask(VALUE self, VALUE payload, VALUE mask); - -void -Init_websocket_mask() +VALUE method_websocket_mask(VALUE self, VALUE payload, VALUE mask) { - WebSocket = rb_define_module("WebSocket"); - WebSocketMask = rb_define_module_under(WebSocket, "Mask"); - rb_define_singleton_method(WebSocketMask, "mask", method_websocket_mask, 2); + char *payload_s, *mask_s, *unmasked_s; + long i, n; + VALUE unmasked; + + if (mask == Qnil || RSTRING_LEN(mask) != 4) { + return payload; + } + + payload_s = RSTRING_PTR(payload); + mask_s = RSTRING_PTR(mask); + n = RSTRING_LEN(payload); + + unmasked = rb_str_new(0, n); + unmasked_s = RSTRING_PTR(unmasked); + + for (i = 0; i < n; i++) { + unmasked_s[i] = payload_s[i] ^ mask_s[i % 4]; + } + return unmasked; } -VALUE -method_websocket_mask(VALUE self, - VALUE payload, - VALUE mask) +void Init_websocket_mask() { - char *payload_s, *mask_s, *unmasked_s; - long i, n; - VALUE unmasked; - - if (mask == Qnil || RSTRING_LEN(mask) != 4) { - return payload; - } - - payload_s = RSTRING_PTR(payload); - mask_s = RSTRING_PTR(mask); - n = RSTRING_LEN(payload); - - unmasked = rb_str_new(0, n); - unmasked_s = RSTRING_PTR(unmasked); - - for (i = 0; i < n; i++) { - unmasked_s[i] = payload_s[i] ^ mask_s[i % 4]; - } - return unmasked; + VALUE WebSocket = rb_define_module("WebSocket"); + VALUE Mask = rb_define_module_under(WebSocket, "Mask"); + + rb_define_singleton_method(Mask, "mask", method_websocket_mask, 2); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/websocket/driver/client.rb new/lib/websocket/driver/client.rb --- old/lib/websocket/driver/client.rb 2017-09-11 23:16:18.000000000 +0200 +++ new/lib/websocket/driver/client.rb 2019-06-10 13:40:12.000000000 +0200 @@ -31,7 +31,7 @@ @headers['Upgrade'] = 'websocket' @headers['Connection'] = 'Upgrade' @headers['Sec-WebSocket-Key'] = @key - @headers['Sec-WebSocket-Version'] = '13' + @headers['Sec-WebSocket-Version'] = VERSION if @protocols.size > 0 @headers['Sec-WebSocket-Protocol'] = @protocols * ', ' @@ -44,7 +44,7 @@ end def version - 'hybi-13' + "hybi-#{VERSION}" end def proxy(origin, options = {}) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/websocket/driver/draft76.rb new/lib/websocket/driver/draft76.rb --- old/lib/websocket/driver/draft76.rb 2017-09-11 23:16:18.000000000 +0200 +++ new/lib/websocket/driver/draft76.rb 2019-06-10 13:40:12.000000000 +0200 @@ -29,7 +29,7 @@ def close(reason = nil, code = nil) return false if @ready_state == 3 - @socket.write([0xFF, 0x00].pack('C*')) + @socket.write([0xFF, 0x00].pack('C*')) if @ready_state == 1 @ready_state = 3 emit(:close, CloseEvent.new(nil, nil)) true @@ -39,19 +39,20 @@ def handshake_response env = @socket.env - key1 = env['HTTP_SEC_WEBSOCKET_KEY1'] + key2 = env['HTTP_SEC_WEBSOCKET_KEY2'] + + raise ProtocolError.new('Missing required header: Sec-WebSocket-Key1') unless key1 + raise ProtocolError.new('Missing required header: Sec-WebSocket-Key2') unless key2 + number1 = number_from_key(key1) spaces1 = spaces_in_key(key1) - key2 = env['HTTP_SEC_WEBSOCKET_KEY2'] number2 = number_from_key(key2) spaces2 = spaces_in_key(key2) if number1 % spaces1 != 0 or number2 % spaces2 != 0 - emit(:error, ProtocolError.new('Client sent invalid Sec-WebSocket-Key headers')) - close - return nil + raise ProtocolError.new('Client sent invalid Sec-WebSocket-Key headers') end @key_values = [number1 / spaces1, number2 / spaces2] @@ -84,7 +85,8 @@ end def number_from_key(key) - key.scan(/[0-9]/).join('').to_i(10) + number = key.scan(/[0-9]/).join('') + number == '' ? Float::NAN : number.to_i(10) end def spaces_in_key(key) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/websocket/driver/hybi.rb new/lib/websocket/driver/hybi.rb --- old/lib/websocket/driver/hybi.rb 2017-09-11 23:16:18.000000000 +0200 +++ new/lib/websocket/driver/hybi.rb 2019-06-10 13:40:12.000000000 +0200 @@ -11,7 +11,8 @@ Base64.strict_encode64(Digest::SHA1.digest(key + GUID)) end - GUID = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11' + VERSION = '13' + GUID = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11' BYTE = 0b11111111 FIN = MASK = 0b10000000 @@ -68,22 +69,16 @@ return unless @socket.respond_to?(:env) - sec_key = @socket.env['HTTP_SEC_WEBSOCKET_KEY'] - protos = @socket.env['HTTP_SEC_WEBSOCKET_PROTOCOL'] - - @headers['Upgrade'] = 'websocket' - @headers['Connection'] = 'Upgrade' - @headers['Sec-WebSocket-Accept'] = Hybi.generate_accept(sec_key) - if protos = @socket.env['HTTP_SEC_WEBSOCKET_PROTOCOL'] protos = protos.split(/ *, */) if String === protos @protocol = protos.find { |p| @protocols.include?(p) } - @headers['Sec-WebSocket-Protocol'] = @protocol if @protocol + else + @protocol = nil end end def version - "hybi-#{@socket.env['HTTP_SEC_WEBSOCKET_VERSION']}" + "hybi-#{VERSION}" end def add_extension(extension) @@ -229,13 +224,24 @@ end def handshake_response - begin - extensions = @extensions.generate_response(@socket.env['HTTP_SEC_WEBSOCKET_EXTENSIONS']) - rescue => error - fail(:protocol_error, error.message) - return nil + sec_key = @socket.env['HTTP_SEC_WEBSOCKET_KEY'] + version = @socket.env['HTTP_SEC_WEBSOCKET_VERSION'] + + unless version == VERSION + raise ProtocolError.new("Unsupported WebSocket version: #{VERSION}") + end + + unless sec_key + raise ProtocolError.new('Missing handshake request header: Sec-WebSocket-Key') end + @headers['Upgrade'] = 'websocket' + @headers['Connection'] = 'Upgrade' + @headers['Sec-WebSocket-Accept'] = Hybi.generate_accept(sec_key) + + @headers['Sec-WebSocket-Protocol'] = @protocol if @protocol + + extensions = @extensions.generate_response(@socket.env['HTTP_SEC_WEBSOCKET_EXTENSIONS']) @headers['Sec-WebSocket-Extensions'] = extensions if extensions start = 'HTTP/1.1 101 Switching Protocols' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/websocket/driver.rb new/lib/websocket/driver.rb --- old/lib/websocket/driver.rb 2017-09-11 23:16:18.000000000 +0200 +++ new/lib/websocket/driver.rb 2019-06-10 13:40:12.000000000 +0200 @@ -101,8 +101,17 @@ def start return false unless @ready_state == 0 - response = handshake_response - return false unless response + + unless Driver.websocket?(@socket.env) + return fail_handshake(ProtocolError.new('Not a WebSocket request')) + end + + begin + response = handshake_response + rescue => error + return fail_handshake(error) + end + @socket.write(response) open unless @stage == -1 true @@ -134,6 +143,24 @@ private + def fail_handshake(error) + headers = Headers.new + headers['Content-Type'] = 'text/plain' + headers['Content-Length'] = error.message.bytesize + + headers = ['HTTP/1.1 400 Bad Request', headers.to_s, error.message] + @socket.write(headers.join("\r\n")) + fail(:protocol_error, error.message) + + false + end + + def fail(type, message) + @ready_state = 2 + emit(:error, ProtocolError.new(message)) + close + end + def open @ready_state = 1 @queue.each { |message| frame(*message) } @@ -155,10 +182,15 @@ end def self.rack(socket, options = {}) - env = socket.env - if env['HTTP_SEC_WEBSOCKET_VERSION'] + env = socket.env + version = env['HTTP_SEC_WEBSOCKET_VERSION'] + key = env['HTTP_SEC_WEBSOCKET_KEY'] + key1 = env['HTTP_SEC_WEBSOCKET_KEY1'] + key2 = env['HTTP_SEC_WEBSOCKET_KEY2'] + + if version or key Hybi.new(socket, options.merge(:require_masking => true)) - elsif env['HTTP_SEC_WEBSOCKET_KEY1'] + elsif key1 or key2 Draft76.new(socket, options) else Draft75.new(socket, options) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/metadata new/metadata --- old/metadata 2017-09-11 23:16:18.000000000 +0200 +++ new/metadata 2019-06-10 13:40:12.000000000 +0200 @@ -1,14 +1,14 @@ --- !ruby/object:Gem::Specification name: websocket-driver version: !ruby/object:Gem::Version - version: 0.7.0 + version: 0.7.1 platform: ruby authors: - James Coglan autorequire: bindir: bin cert_chain: [] -date: 2017-09-11 00:00:00.000000000 Z +date: 2019-06-10 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: websocket-extensions @@ -56,16 +56,16 @@ name: rake-compiler requirement: !ruby/object:Gem::Requirement requirements: - - - "~>" + - - ">=" - !ruby/object:Gem::Version - version: 0.8.0 + version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - - "~>" + - - ">=" - !ruby/object:Gem::Version - version: 0.8.0 + version: '0' - !ruby/object:Gem::Dependency name: rspec requirement: !ruby/object:Gem::Requirement @@ -114,7 +114,7 @@ - lib/websocket/websocket_mask.rb homepage: https://github.com/faye/websocket-driver-ruby licenses: -- MIT +- Apache-2.0 metadata: {} post_install_message: rdoc_options: @@ -135,8 +135,7 @@ - !ruby/object:Gem::Version version: '0' requirements: [] -rubyforge_project: -rubygems_version: 2.6.11 +rubygems_version: 3.0.3 signing_key: specification_version: 4 summary: WebSocket protocol handler with pluggable I/O
participants (1)
-
root