websocket 1.2.4 → 1.2.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.codeclimate.yml +16 -0
- data/.rubocop.yml +18 -3
- data/.travis.yml +6 -8
- data/CHANGELOG.md +4 -0
- data/Gemfile +10 -0
- data/README.md +2 -2
- data/Rakefile +1 -1
- data/lib/websocket.rb +1 -0
- data/lib/websocket/frame/base.rb +1 -7
- data/lib/websocket/frame/handler/base.rb +2 -2
- data/lib/websocket/frame/handler/handler03.rb +2 -1
- data/lib/websocket/frame/handler/handler75.rb +1 -1
- data/lib/websocket/handshake/base.rb +1 -7
- data/lib/websocket/handshake/handler/client.rb +9 -0
- data/lib/websocket/handshake/handler/client04.rb +6 -7
- data/lib/websocket/handshake/handler/client75.rb +6 -7
- data/lib/websocket/handshake/handler/client76.rb +2 -7
- data/lib/websocket/handshake/handler/server75.rb +13 -5
- data/lib/websocket/handshake/handler/server76.rb +9 -17
- data/lib/websocket/handshake/server.rb +1 -1
- data/lib/websocket/nice_inspect.rb +10 -0
- data/lib/websocket/version.rb +1 -1
- data/spec/frame/incoming_03_spec.rb +3 -2
- data/spec/frame/incoming_04_spec.rb +3 -2
- data/spec/frame/incoming_05_spec.rb +3 -2
- data/spec/frame/incoming_07_spec.rb +3 -2
- data/spec/frame/incoming_75_spec.rb +3 -2
- data/spec/frame/incoming_common_spec.rb +17 -8
- data/spec/frame/masking_spec.rb +2 -1
- data/spec/frame/outgoing_03_spec.rb +2 -1
- data/spec/frame/outgoing_04_spec.rb +2 -1
- data/spec/frame/outgoing_05_spec.rb +2 -1
- data/spec/frame/outgoing_07_spec.rb +2 -1
- data/spec/frame/outgoing_75_spec.rb +2 -1
- data/spec/frame/outgoing_common_spec.rb +10 -4
- data/spec/handshake/client_04_spec.rb +3 -3
- data/spec/handshake/client_11_spec.rb +2 -2
- data/spec/handshake/client_75_spec.rb +1 -1
- data/spec/handshake/client_76_spec.rb +3 -3
- data/spec/handshake/server_04_spec.rb +2 -2
- data/spec/handshake/server_76_spec.rb +8 -8
- data/spec/spec_helper.rb +0 -2
- data/spec/support/all_client_drafts.rb +21 -21
- data/spec/support/all_server_drafts.rb +19 -16
- data/spec/support/incoming_frames.rb +29 -12
- data/spec/support/outgoing_frames.rb +28 -8
- data/websocket.gemspec +2 -4
- metadata +7 -61
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d1beb710905d152c983423d7119156b054b515c3
|
4
|
+
data.tar.gz: e74c5149d1ff19ff7b5ed25a499c0d2b2d3bef4b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2ec8c925807edd84216c70bfdc7947f9d24c5f37d9ca4eb11274f8f32d99bd0e405b7fe3ad405d1ad835318a18ef9aaf0256bf4d0996ef6bedbdf89455b2b6e0
|
7
|
+
data.tar.gz: 8a64ac2c2bb7da84c15afe43df803abc14d90a6d7e65d358f7a52b909c663a2fab1641c14e0d2666ed5d712f2e6c0bae97dd1ce31818fd48dbde77184bf7e855
|
data/.codeclimate.yml
ADDED
data/.rubocop.yml
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
+
require: rubocop-rspec
|
2
|
+
|
1
3
|
AllCops:
|
2
4
|
DisplayCopNames: true
|
5
|
+
TargetRubyVersion: 2.1
|
3
6
|
|
4
7
|
# Target: 15
|
5
8
|
Metrics/AbcSize:
|
@@ -37,8 +40,20 @@ Metrics/PerceivedComplexity:
|
|
37
40
|
- lib/websocket/frame/handler/handler75.rb
|
38
41
|
- spec/support/handshake_requests.rb
|
39
42
|
|
40
|
-
|
43
|
+
RSpec/DescribeClass:
|
44
|
+
Enabled: false
|
45
|
+
|
46
|
+
RSpec/ExampleLength:
|
47
|
+
Enabled: false
|
48
|
+
|
49
|
+
RSpec/InstanceVariable:
|
41
50
|
Enabled: false
|
42
51
|
|
43
|
-
|
44
|
-
|
52
|
+
RSpec/MultipleExpectations:
|
53
|
+
Enabled: false
|
54
|
+
|
55
|
+
RSpec/NamedSubject:
|
56
|
+
Enabled: false
|
57
|
+
|
58
|
+
Style/Documentation:
|
59
|
+
Enabled: false
|
data/.travis.yml
CHANGED
@@ -1,23 +1,21 @@
|
|
1
|
+
dist: trusty
|
1
2
|
language: ruby
|
2
3
|
script: "bundle exec rake"
|
3
4
|
rvm:
|
4
|
-
- 1.9.3
|
5
|
-
- 2.0
|
6
5
|
- 2.1
|
7
6
|
- 2.2
|
8
7
|
- 2.3
|
8
|
+
- 2.4
|
9
9
|
- ruby-head
|
10
|
-
- jruby
|
10
|
+
- jruby-9.1.9.0 # https://github.com/travis-ci/travis-ci/issues/8446
|
11
11
|
- jruby-head
|
12
|
-
- rbx
|
13
|
-
- rbx-head
|
12
|
+
- rbx-3
|
14
13
|
|
15
14
|
matrix:
|
16
15
|
allow_failures:
|
17
16
|
- rvm: ruby-head
|
18
17
|
- rvm: jruby-head
|
19
|
-
- rvm: rbx
|
20
|
-
- rvm: rbx-head
|
18
|
+
- rvm: rbx-3
|
21
19
|
|
22
20
|
before_install:
|
23
|
-
- gem
|
21
|
+
- gem update bundler
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
@@ -1,3 +1,13 @@
|
|
1
1
|
source 'http://rubygems.org'
|
2
2
|
|
3
|
+
group :development do
|
4
|
+
gem 'rake'
|
5
|
+
gem 'rspec', '~> 3.0'
|
6
|
+
|
7
|
+
# Use same version as Code Climate for consistency with CI
|
8
|
+
# https://github.com/codeclimate/codeclimate-rubocop/blob/master/Gemfile.lock
|
9
|
+
gem 'rubocop', '0.46.0', require: false
|
10
|
+
gem 'rubocop-rspec', '1.8.0', require: false
|
11
|
+
end
|
12
|
+
|
3
13
|
gemspec
|
data/README.md
CHANGED
@@ -4,8 +4,8 @@ Universal Ruby library to handle WebSocket protocol. It focuses on providing abs
|
|
4
4
|
|
5
5
|
[![Gem Version](https://badge.fury.io/rb/websocket.svg)](http://badge.fury.io/rb/websocket)
|
6
6
|
[![Gem Downloads](https://img.shields.io/gem/dt/websocket.svg?maxAge=2592000)](https://rubygems.org/gems/websocket)
|
7
|
-
[![Travis CI](https://travis-ci.org/imanel/websocket-ruby.
|
8
|
-
[![Code Climate](https://codeclimate.com/github/imanel/websocket-ruby.
|
7
|
+
[![Travis CI](https://travis-ci.org/imanel/websocket-ruby.svg)](http://travis-ci.org/imanel/websocket-ruby)
|
8
|
+
[![Code Climate](https://codeclimate.com/github/imanel/websocket-ruby.svg)](https://codeclimate.com/github/imanel/websocket-ruby)
|
9
9
|
|
10
10
|
**Autobahn tests:** [server](http://imanel.github.com/websocket-ruby/autobahn/server/), [client](http://imanel.github.com/websocket-ruby/autobahn/client/)
|
11
11
|
|
data/Rakefile
CHANGED
data/lib/websocket.rb
CHANGED
@@ -12,6 +12,7 @@ module WebSocket
|
|
12
12
|
autoload :ExceptionHandler, "#{ROOT}/websocket/exception_handler"
|
13
13
|
autoload :Frame, "#{ROOT}/websocket/frame"
|
14
14
|
autoload :Handshake, "#{ROOT}/websocket/handshake"
|
15
|
+
autoload :NiceInspect, "#{ROOT}/websocket/nice_inspect"
|
15
16
|
|
16
17
|
# Limit of frame size payload in bytes
|
17
18
|
def self.max_frame_size
|
data/lib/websocket/frame/base.rb
CHANGED
@@ -3,6 +3,7 @@ module WebSocket
|
|
3
3
|
# @abstract Subclass and override to implement custom frames
|
4
4
|
class Base
|
5
5
|
include ExceptionHandler
|
6
|
+
include NiceInspect
|
6
7
|
|
7
8
|
attr_reader :type, :version, :error
|
8
9
|
attr_accessor :data, :code
|
@@ -39,13 +40,6 @@ module WebSocket
|
|
39
40
|
raise NotImplementedError
|
40
41
|
end
|
41
42
|
|
42
|
-
# Recreate inspect as #to_s was overwritten
|
43
|
-
def inspect
|
44
|
-
vars = instance_variables.map { |v| "#{v}=#{instance_variable_get(v).inspect}" }.join(', ')
|
45
|
-
insp = Kernel.format("#{self.class}:0x%08x", __id__)
|
46
|
-
"<#{insp} #{vars}>"
|
47
|
-
end
|
48
|
-
|
49
43
|
private
|
50
44
|
|
51
45
|
# Include set of methods for selected protocol version
|
@@ -24,14 +24,14 @@ module WebSocket
|
|
24
24
|
# @param [Symbol] frame_type Frame type
|
25
25
|
# @return [Boolean] True if given frame type is control frame
|
26
26
|
def control_frame?(frame_type)
|
27
|
-
|
27
|
+
!%i(text binary continuation).include?(frame_type)
|
28
28
|
end
|
29
29
|
|
30
30
|
# Check if frame is one of data frames
|
31
31
|
# @param [Symbol] frame_type Frame type
|
32
32
|
# @return [Boolean] True if given frame type is data frame
|
33
33
|
def data_frame?(frame_type)
|
34
|
-
|
34
|
+
%i(text binary).include?(frame_type)
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# encoding: binary
|
2
|
+
|
2
3
|
require 'securerandom'
|
3
4
|
|
4
5
|
module WebSocket
|
@@ -20,7 +21,7 @@ module WebSocket
|
|
20
21
|
|
21
22
|
# @see WebSocket::Frame::Base#supported_frames
|
22
23
|
def supported_frames
|
23
|
-
|
24
|
+
%i(text binary close ping pong)
|
24
25
|
end
|
25
26
|
|
26
27
|
# @see WebSocket::Frame::Handler::Base#encode_frame
|
@@ -3,6 +3,7 @@ module WebSocket
|
|
3
3
|
# @abstract Subclass and override to implement custom handshakes
|
4
4
|
class Base
|
5
5
|
include ExceptionHandler
|
6
|
+
include NiceInspect
|
6
7
|
|
7
8
|
attr_reader :host, :port, :path, :query,
|
8
9
|
:state, :version, :secure,
|
@@ -32,13 +33,6 @@ module WebSocket
|
|
32
33
|
end
|
33
34
|
rescue_method :to_s, return: ''
|
34
35
|
|
35
|
-
# Recreate inspect as #to_s was overwritten
|
36
|
-
def inspect
|
37
|
-
vars = instance_variables.map { |v| "#{v}=#{instance_variable_get(v).inspect}" }.join(', ')
|
38
|
-
insp = Kernel.format("#{self.class}:0x%08x", __id__)
|
39
|
-
"<#{insp} #{vars}>"
|
40
|
-
end
|
41
|
-
|
42
36
|
# Is parsing of data finished?
|
43
37
|
# @return [Boolena] True if request was completely parsed or error occured. False otherwise
|
44
38
|
def finished?
|
@@ -15,6 +15,15 @@ module WebSocket
|
|
15
15
|
def handshake_keys
|
16
16
|
super + @handshake.headers.to_a
|
17
17
|
end
|
18
|
+
|
19
|
+
# Verify if received header matches with one of the sent ones
|
20
|
+
# @return [Boolean] True if matching. False otherwise(appropriate error is set)
|
21
|
+
def verify_protocol
|
22
|
+
return true if supported_protocols.empty?
|
23
|
+
protos = provided_protocols & supported_protocols
|
24
|
+
raise WebSocket::Error::Handshake::UnsupportedProtocol if protos.empty?
|
25
|
+
true
|
26
|
+
end
|
18
27
|
end
|
19
28
|
end
|
20
29
|
end
|
@@ -48,13 +48,12 @@ module WebSocket
|
|
48
48
|
true
|
49
49
|
end
|
50
50
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
true
|
51
|
+
def supported_protocols
|
52
|
+
@handshake.protocols
|
53
|
+
end
|
54
|
+
|
55
|
+
def provided_protocols
|
56
|
+
@handshake.headers['sec-websocket-protocol'].to_s.split(/ *, */)
|
58
57
|
end
|
59
58
|
end
|
60
59
|
end
|
@@ -24,13 +24,12 @@ module WebSocket
|
|
24
24
|
keys
|
25
25
|
end
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
true
|
27
|
+
def supported_protocols
|
28
|
+
Array(@handshake.protocols.first)
|
29
|
+
end
|
30
|
+
|
31
|
+
def provided_protocols
|
32
|
+
Array(@handshake.headers['websocket-protocol'].to_s.strip)
|
34
33
|
end
|
35
34
|
end
|
36
35
|
end
|
@@ -94,13 +94,8 @@ module WebSocket
|
|
94
94
|
[rand(0x100000000)].pack('N') + [rand(0x100000000)].pack('N')
|
95
95
|
end
|
96
96
|
|
97
|
-
|
98
|
-
|
99
|
-
def verify_protocol
|
100
|
-
return true if @handshake.protocols.empty?
|
101
|
-
invalid = @handshake.headers['sec-websocket-protocol'].strip != @handshake.protocols.first
|
102
|
-
raise WebSocket::Error::Handshake::UnsupportedProtocol if invalid
|
103
|
-
true
|
97
|
+
def provided_protocols
|
98
|
+
Array(@handshake.headers['sec-websocket-protocol'].to_s.strip)
|
104
99
|
end
|
105
100
|
end
|
106
101
|
end
|
@@ -4,6 +4,14 @@ module WebSocket
|
|
4
4
|
class Server75 < Server
|
5
5
|
private
|
6
6
|
|
7
|
+
def headers
|
8
|
+
{
|
9
|
+
origin: 'WebSocket-Origin',
|
10
|
+
location: 'WebSocket-Location',
|
11
|
+
protocol: 'WebSocket-Protocol'
|
12
|
+
}.freeze
|
13
|
+
end
|
14
|
+
|
7
15
|
# @see WebSocket::Handshake::Handler::Base#header_line
|
8
16
|
def header_line
|
9
17
|
'HTTP/1.1 101 Web Socket Protocol Handshake'
|
@@ -14,15 +22,15 @@ module WebSocket
|
|
14
22
|
[
|
15
23
|
%w(Upgrade WebSocket),
|
16
24
|
%w(Connection Upgrade),
|
17
|
-
[
|
18
|
-
[
|
25
|
+
[headers[:origin], @handshake.headers['origin']],
|
26
|
+
[headers[:location], @handshake.uri]
|
19
27
|
] + protocol
|
20
28
|
end
|
21
29
|
|
22
30
|
def protocol
|
23
|
-
return [] unless @handshake.headers.key?(
|
24
|
-
proto = @handshake.headers[
|
25
|
-
[[
|
31
|
+
return [] unless @handshake.headers.key?(headers[:protocol].downcase)
|
32
|
+
proto = @handshake.headers[headers[:protocol].downcase]
|
33
|
+
[[headers[:protocol], @handshake.protocols.include?(proto) ? proto : nil]]
|
26
34
|
end
|
27
35
|
end
|
28
36
|
end
|
@@ -3,7 +3,7 @@ require 'digest/md5'
|
|
3
3
|
module WebSocket
|
4
4
|
module Handshake
|
5
5
|
module Handler
|
6
|
-
class Server76 <
|
6
|
+
class Server76 < Server75
|
7
7
|
# @see WebSocket::Handshake::Base#valid?
|
8
8
|
def valid?
|
9
9
|
super && !finishing_line.nil?
|
@@ -11,6 +11,14 @@ module WebSocket
|
|
11
11
|
|
12
12
|
private
|
13
13
|
|
14
|
+
def headers
|
15
|
+
{
|
16
|
+
origin: 'Sec-WebSocket-Origin',
|
17
|
+
location: 'Sec-WebSocket-Location',
|
18
|
+
protocol: 'Sec-WebSocket-Protocol'
|
19
|
+
}.freeze
|
20
|
+
end
|
21
|
+
|
14
22
|
# @see WebSocket::Handshake::Base#reserved_leftover_lines
|
15
23
|
def reserved_leftover_lines
|
16
24
|
1
|
@@ -21,16 +29,6 @@ module WebSocket
|
|
21
29
|
'HTTP/1.1 101 WebSocket Protocol Handshake'
|
22
30
|
end
|
23
31
|
|
24
|
-
# @see WebSocket::Handshake::Handler::Base#handshake_keys
|
25
|
-
def handshake_keys
|
26
|
-
[
|
27
|
-
%w(Upgrade WebSocket),
|
28
|
-
%w(Connection Upgrade),
|
29
|
-
['Sec-WebSocket-Origin', @handshake.headers['origin']],
|
30
|
-
['Sec-WebSocket-Location', @handshake.uri]
|
31
|
-
] + protocol
|
32
|
-
end
|
33
|
-
|
34
32
|
# @see WebSocket::Handshake::Handler::Base#finishing_line
|
35
33
|
def finishing_line
|
36
34
|
@finishing_line ||= challenge_response
|
@@ -69,12 +67,6 @@ module WebSocket
|
|
69
67
|
|
70
68
|
quotient
|
71
69
|
end
|
72
|
-
|
73
|
-
def protocol
|
74
|
-
return [] unless @handshake.headers.key?('sec-websocket-protocol')
|
75
|
-
proto = @handshake.headers['sec-websocket-protocol']
|
76
|
-
[['Sec-WebSocket-Protocol', @handshake.protocols.include?(proto) ? proto : nil]]
|
77
|
-
end
|
78
70
|
end
|
79
71
|
end
|
80
72
|
end
|
@@ -71,7 +71,7 @@ module WebSocket
|
|
71
71
|
# @example
|
72
72
|
# @handshake.from_rack(env)
|
73
73
|
def from_rack(env)
|
74
|
-
@headers = env.select { |key, _value| key.start_with? 'HTTP_' }.each_with_object({}) do |tuple, memo|
|
74
|
+
@headers = env.select { |key, _value| key.to_s.start_with? 'HTTP_' }.each_with_object({}) do |tuple, memo|
|
75
75
|
key, value = tuple
|
76
76
|
memo[key.gsub(/\AHTTP_/, '').tr('_', '-').downcase] = value
|
77
77
|
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module WebSocket
|
2
|
+
module NiceInspect
|
3
|
+
# Recreate inspect as #to_s will be overwritten
|
4
|
+
def inspect
|
5
|
+
vars = instance_variables.map { |v| "#{v}=#{instance_variable_get(v).inspect}" }.join(', ')
|
6
|
+
insp = Kernel.format("#{self.class}:0x%08x", __id__)
|
7
|
+
"<#{insp} #{vars}>"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
data/lib/websocket/version.rb
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
# encoding: binary
|
2
|
+
|
2
3
|
require 'spec_helper'
|
3
4
|
|
4
5
|
RSpec.describe 'Incoming frame draft 03' do
|
6
|
+
subject { frame }
|
5
7
|
let(:version) { 3 }
|
6
8
|
let(:frame) { WebSocket::Frame::Incoming.new(version: version, data: encoded_text) }
|
7
9
|
let(:encoded_text) { nil }
|
8
10
|
let(:decoded_text) { nil }
|
9
11
|
let(:frame_type) { nil }
|
10
12
|
let(:error) { nil }
|
11
|
-
subject { frame }
|
12
13
|
|
13
14
|
it_should_behave_like 'valid_incoming_frame'
|
14
15
|
|
@@ -54,7 +55,7 @@ RSpec.describe 'Incoming frame draft 03' do
|
|
54
55
|
|
55
56
|
context 'should properly decode text frame in between of continuation' do
|
56
57
|
let(:encoded_text) { "\x84\x03Hel\x03\x03abc\x00\x02lo" }
|
57
|
-
let(:frame_type) {
|
58
|
+
let(:frame_type) { %i(pong text) }
|
58
59
|
let(:decoded_text) { %w(abc Hello) }
|
59
60
|
|
60
61
|
it_should_behave_like 'valid_incoming_frame'
|