websocket 1.2.2 → 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +37 -0
  3. data/.travis.yml +2 -0
  4. data/CHANGELOG.md +5 -0
  5. data/Gemfile +1 -1
  6. data/Rakefile +3 -3
  7. data/lib/websocket.rb +2 -3
  8. data/lib/websocket/error.rb +57 -25
  9. data/lib/websocket/exception_handler.rb +2 -14
  10. data/lib/websocket/frame.rb +0 -2
  11. data/lib/websocket/frame/base.rb +12 -13
  12. data/lib/websocket/frame/data.rb +1 -3
  13. data/lib/websocket/frame/handler.rb +0 -2
  14. data/lib/websocket/frame/handler/base.rb +2 -4
  15. data/lib/websocket/frame/handler/handler03.rb +149 -112
  16. data/lib/websocket/frame/handler/handler04.rb +3 -3
  17. data/lib/websocket/frame/handler/handler05.rb +3 -3
  18. data/lib/websocket/frame/handler/handler07.rb +8 -10
  19. data/lib/websocket/frame/handler/handler75.rb +10 -12
  20. data/lib/websocket/frame/incoming.rb +0 -2
  21. data/lib/websocket/frame/incoming/client.rb +0 -2
  22. data/lib/websocket/frame/incoming/server.rb +0 -2
  23. data/lib/websocket/frame/outgoing.rb +1 -3
  24. data/lib/websocket/frame/outgoing/client.rb +0 -2
  25. data/lib/websocket/frame/outgoing/server.rb +0 -2
  26. data/lib/websocket/handshake.rb +0 -2
  27. data/lib/websocket/handshake/base.rb +10 -9
  28. data/lib/websocket/handshake/client.rb +22 -35
  29. data/lib/websocket/handshake/handler.rb +0 -2
  30. data/lib/websocket/handshake/handler/base.rb +0 -2
  31. data/lib/websocket/handshake/handler/client.rb +0 -2
  32. data/lib/websocket/handshake/handler/client01.rb +0 -2
  33. data/lib/websocket/handshake/handler/client04.rb +3 -5
  34. data/lib/websocket/handshake/handler/client11.rb +0 -2
  35. data/lib/websocket/handshake/handler/client75.rb +2 -4
  36. data/lib/websocket/handshake/handler/client76.rb +6 -8
  37. data/lib/websocket/handshake/handler/server.rb +0 -1
  38. data/lib/websocket/handshake/handler/server04.rb +3 -5
  39. data/lib/websocket/handshake/handler/server75.rb +2 -4
  40. data/lib/websocket/handshake/handler/server76.rb +7 -9
  41. data/lib/websocket/handshake/server.rb +19 -24
  42. data/lib/websocket/version.rb +1 -1
  43. data/spec/frame/incoming_03_spec.rb +1 -2
  44. data/spec/frame/incoming_04_spec.rb +1 -2
  45. data/spec/frame/incoming_05_spec.rb +1 -2
  46. data/spec/frame/incoming_07_spec.rb +1 -2
  47. data/spec/frame/incoming_75_spec.rb +1 -2
  48. data/spec/support/all_client_drafts.rb +1 -1
  49. data/spec/support/all_server_drafts.rb +7 -10
  50. data/spec/support/frames_base.rb +0 -2
  51. data/spec/support/handshake_requests.rb +4 -4
  52. data/spec/support/outgoing_frames.rb +0 -1
  53. data/spec/support/overwrites.rb +0 -2
  54. data/websocket.gemspec +10 -10
  55. metadata +4 -3
@@ -3,7 +3,6 @@ module WebSocket
3
3
  module Handler
4
4
  # This class and it's descendants are included in client or server handshake in order to extend basic functionality
5
5
  class Base
6
-
7
6
  def initialize(handshake)
8
7
  @handshake = handshake
9
8
  end
@@ -42,7 +41,6 @@ module WebSocket
42
41
  def finishing_line
43
42
  ''
44
43
  end
45
-
46
44
  end
47
45
  end
48
46
  end
@@ -2,7 +2,6 @@ module WebSocket
2
2
  module Handshake
3
3
  module Handler
4
4
  class Client < Base
5
-
6
5
  private
7
6
 
8
7
  # @see WebSocket::Handshake::Handler::Base#header_line
@@ -16,7 +15,6 @@ module WebSocket
16
15
  def handshake_keys
17
16
  super + @handshake.headers.to_a
18
17
  end
19
-
20
18
  end
21
19
  end
22
20
  end
@@ -4,7 +4,6 @@ module WebSocket
4
4
  module Handshake
5
5
  module Handler
6
6
  class Client01 < Client76
7
-
8
7
  private
9
8
 
10
9
  # @see WebSocket::Handshake::Handler::Base#handshake_keys
@@ -13,7 +12,6 @@ module WebSocket
13
12
  keys << ['Sec-WebSocket-Draft', @handshake.version]
14
13
  keys
15
14
  end
16
-
17
15
  end
18
16
  end
19
17
  end
@@ -5,7 +5,6 @@ module WebSocket
5
5
  module Handshake
6
6
  module Handler
7
7
  class Client04 < Client
8
-
9
8
  # @see WebSocket::Handshake::Base#valid?
10
9
  def valid?
11
10
  super && verify_accept
@@ -16,8 +15,8 @@ module WebSocket
16
15
  # @see WebSocket::Handshake::Handler::Base#handshake_keys
17
16
  def handshake_keys
18
17
  keys = [
19
- ['Upgrade', 'websocket'],
20
- ['Connection', 'Upgrade']
18
+ %w(Upgrade websocket),
19
+ %w(Connection Upgrade)
21
20
  ]
22
21
  host = @handshake.host
23
22
  host += ":#{@handshake.port}" if @handshake.port
@@ -44,10 +43,9 @@ module WebSocket
44
43
  # Verify if received header Sec-WebSocket-Accept matches generated one.
45
44
  # @return [Boolean] True if accept is matching. False otherwise(appropriate error is set)
46
45
  def verify_accept
47
- raise WebSocket::Error::Handshake::InvalidAuthentication unless @handshake.headers['sec-websocket-accept'] == accept
46
+ fail WebSocket::Error::Handshake::InvalidAuthentication unless @handshake.headers['sec-websocket-accept'] == accept
48
47
  true
49
48
  end
50
-
51
49
  end
52
50
  end
53
51
  end
@@ -2,7 +2,6 @@ module WebSocket
2
2
  module Handshake
3
3
  module Handler
4
4
  class Client11 < Client04
5
-
6
5
  private
7
6
 
8
7
  # @see WebSocket::Handshake::Handler::Base#handshake_keys
@@ -15,7 +14,6 @@ module WebSocket
15
14
  end
16
15
  end
17
16
  end
18
-
19
17
  end
20
18
  end
21
19
  end
@@ -2,14 +2,13 @@ module WebSocket
2
2
  module Handshake
3
3
  module Handler
4
4
  class Client75 < Client
5
-
6
5
  private
7
6
 
8
7
  # @see WebSocket::Handshake::Handler::Base#handshake_keys
9
8
  def handshake_keys
10
9
  keys = [
11
- ['Upgrade', 'WebSocket'],
12
- ['Connection', 'Upgrade']
10
+ %w(Upgrade WebSocket),
11
+ %w(Connection Upgrade)
13
12
  ]
14
13
  host = @handshake.host
15
14
  host += ":#{@handshake.port}" if @handshake.port
@@ -18,7 +17,6 @@ module WebSocket
18
17
  keys += super
19
18
  keys
20
19
  end
21
-
22
20
  end
23
21
  end
24
22
  end
@@ -4,7 +4,6 @@ module WebSocket
4
4
  module Handshake
5
5
  module Handler
6
6
  class Client76 < Client75
7
-
8
7
  # @see WebSocket::Handshake::Base#valid?
9
8
  def valid?
10
9
  super && verify_challenge
@@ -57,17 +56,17 @@ module WebSocket
57
56
  [@key2_number].pack('N*') +
58
57
  key3
59
58
 
60
- @challenge = Digest::MD5.digest(sum)
59
+ @challenge = Digest::MD5.digest(sum).strip
61
60
  end
62
61
 
63
62
  # Verify if challenge sent by server match generated one
64
63
  # @return [Boolena] True if challenge matches, false otherwise(sets appropriate error)
65
64
  def verify_challenge
66
- raise WebSocket::Error::Handshake::InvalidAuthentication unless @handshake.leftovers == challenge
65
+ fail WebSocket::Error::Handshake::InvalidAuthentication unless @handshake.leftovers == challenge
67
66
  true
68
67
  end
69
68
 
70
- NOISE_CHARS = ("\x21".."\x2f").to_a() + ("\x3a".."\x7e").to_a()
69
+ NOISE_CHARS = ("\x21".."\x2f").to_a + ("\x3a".."\x7e").to_a
71
70
 
72
71
  # Generate Sec-WebSocket-Key1 and Sec-WebSocket-Key2
73
72
  # @param [String] name of key. Will be used to set number variable needed later. Valid values: key1, key2
@@ -78,23 +77,22 @@ module WebSocket
78
77
  number = rand(max + 1)
79
78
  instance_variable_set("@#{key}_number", number)
80
79
  key = (number * spaces).to_s
81
- (1 + rand(12)).times() do
80
+ (1 + rand(12)).times do
82
81
  char = NOISE_CHARS[rand(NOISE_CHARS.size)]
83
82
  pos = rand(key.size + 1)
84
83
  key[pos...pos] = char
85
84
  end
86
- spaces.times() do
85
+ spaces.times do
87
86
  pos = 1 + rand(key.size - 1)
88
87
  key[pos...pos] = ' '
89
88
  end
90
- return key
89
+ key
91
90
  end
92
91
 
93
92
  # Generate third key
94
93
  def generate_key3
95
94
  [rand(0x100000000)].pack('N') + [rand(0x100000000)].pack('N')
96
95
  end
97
-
98
96
  end
99
97
  end
100
98
  end
@@ -2,7 +2,6 @@ module WebSocket
2
2
  module Handshake
3
3
  module Handler
4
4
  class Server < Base
5
-
6
5
  end
7
6
  end
8
7
  end
@@ -5,7 +5,6 @@ module WebSocket
5
5
  module Handshake
6
6
  module Handler
7
7
  class Server04 < Server
8
-
9
8
  # @see WebSocket::Handshake::Base#valid?
10
9
  def valid?
11
10
  super && verify_key
@@ -21,8 +20,8 @@ module WebSocket
21
20
  # @see WebSocket::Handshake::Handler::Base#handshake_keys
22
21
  def handshake_keys
23
22
  [
24
- ['Upgrade', 'websocket'],
25
- ['Connection', 'Upgrade'],
23
+ %w(Upgrade websocket),
24
+ %w(Connection Upgrade),
26
25
  ['Sec-WebSocket-Accept', signature]
27
26
  ]
28
27
  end
@@ -36,14 +35,13 @@ module WebSocket
36
35
  end
37
36
 
38
37
  def verify_key
39
- raise WebSocket::Error::Handshake::InvalidAuthentication unless key
38
+ fail WebSocket::Error::Handshake::InvalidAuthentication unless key
40
39
  true
41
40
  end
42
41
 
43
42
  def key
44
43
  @handshake.headers['sec-websocket-key']
45
44
  end
46
-
47
45
  end
48
46
  end
49
47
  end
@@ -2,7 +2,6 @@ module WebSocket
2
2
  module Handshake
3
3
  module Handler
4
4
  class Server75 < Server
5
-
6
5
  private
7
6
 
8
7
  # @see WebSocket::Handshake::Handler::Base#header_line
@@ -13,13 +12,12 @@ module WebSocket
13
12
  # @see WebSocket::Handshake::Handler::Base#handshake_keys
14
13
  def handshake_keys
15
14
  [
16
- ['Upgrade', 'WebSocket'],
17
- ['Connection', 'Upgrade'],
15
+ %w(Upgrade WebSocket),
16
+ %w(Connection Upgrade),
18
17
  ['WebSocket-Origin', @handshake.headers['origin']],
19
18
  ['WebSocket-Location', @handshake.uri]
20
19
  ]
21
20
  end
22
-
23
21
  end
24
22
  end
25
23
  end
@@ -4,10 +4,9 @@ module WebSocket
4
4
  module Handshake
5
5
  module Handler
6
6
  class Server76 < Server
7
-
8
7
  # @see WebSocket::Handshake::Base#valid?
9
8
  def valid?
10
- super && !!finishing_line
9
+ super && !finishing_line.nil?
11
10
  end
12
11
 
13
12
  private
@@ -25,8 +24,8 @@ module WebSocket
25
24
  # @see WebSocket::Handshake::Handler::Base#handshake_keys
26
25
  def handshake_keys
27
26
  [
28
- ['Upgrade', 'WebSocket'],
29
- ['Connection', 'Upgrade'],
27
+ %w(Upgrade WebSocket),
28
+ %w(Connection Upgrade),
30
29
  ['Sec-WebSocket-Origin', @handshake.headers['origin']],
31
30
  ['Sec-WebSocket-Location', @handshake.uri]
32
31
  ]
@@ -61,18 +60,17 @@ module WebSocket
61
60
 
62
61
  spaces = string.scan(/ /).size
63
62
  # As per 5.2.5, abort the connection if spaces are zero.
64
- raise WebSocket::Error::Handshake::InvalidAuthentication if spaces == 0
63
+ fail WebSocket::Error::Handshake::InvalidAuthentication if spaces == 0
65
64
 
66
65
  # As per 5.2.6, abort if numbers is not an integral multiple of spaces
67
- raise WebSocket::Error::Handshake::InvalidAuthentication if numbers % spaces != 0
66
+ fail WebSocket::Error::Handshake::InvalidAuthentication if numbers % spaces != 0
68
67
 
69
68
  quotient = numbers / spaces
70
69
 
71
- raise WebSocket::Error::Handshake::InvalidAuthentication if quotient > 2**32 - 1
70
+ fail WebSocket::Error::Handshake::InvalidAuthentication if quotient > 2**32 - 1
72
71
 
73
- return quotient
72
+ quotient
74
73
  end
75
-
76
74
  end
77
75
  end
78
76
  end
@@ -30,7 +30,6 @@ module WebSocket
30
30
  # # Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
31
31
  #
32
32
  class Server < Base
33
-
34
33
  # Initialize new WebSocket Server
35
34
  #
36
35
  # @param [Hash] args Arguments for server
@@ -41,7 +40,7 @@ module WebSocket
41
40
  # Websocket::Handshake::Server.new(secure: true)
42
41
  def initialize(args = {})
43
42
  super
44
- @secure = !!args[:secure]
43
+ @secure ||= false
45
44
  end
46
45
 
47
46
  # Add text of request from Client. This method will parse content immediately and update version, state and error(if neccessary)
@@ -60,7 +59,7 @@ module WebSocket
60
59
  #
61
60
  # EOF
62
61
  def <<(data)
63
- @data << data
62
+ super
64
63
  set_version if parse_data
65
64
  end
66
65
  rescue_method :<<
@@ -71,12 +70,9 @@ module WebSocket
71
70
  # @example
72
71
  # @handshake.from_rack(env)
73
72
  def from_rack(env)
74
- @headers = env.select do |key, value|
75
- key =~ /\AHTTP_/
76
- end.reduce({}) do |memo, tuple|
73
+ @headers = env.select { |key, _value| key =~ /\AHTTP_/ }.each_with_object({}) do |tuple, memo|
77
74
  key, value = tuple
78
- memo[key.gsub(/\AHTTP_/, '').gsub('_', '-').downcase] = value
79
- memo
75
+ memo[key.gsub(/\AHTTP_/, '').tr('_', '-').downcase] = value
80
76
  end
81
77
 
82
78
  @path = env['REQUEST_PATH']
@@ -90,13 +86,13 @@ module WebSocket
90
86
  # Better safe than sorry...
91
87
  if @version == 76
92
88
  input = env['rack.input']
93
- @leftovers = if input.respond_to?(:readpartial)
94
- input.readpartial
95
- elsif input.respond_to?(:read)
96
- input.read
97
- else
98
- input.to_s
99
- end
89
+ @leftovers = if input.respond_to?(:readpartial)
90
+ input.readpartial
91
+ elsif input.respond_to?(:read)
92
+ input.read
93
+ else
94
+ input.to_s
95
+ end
100
96
  end
101
97
 
102
98
  @state = :finished
@@ -154,28 +150,27 @@ module WebSocket
154
150
  # @return [Boolean] false if protocol number is unknown, otherwise true
155
151
  def include_version
156
152
  @handler = case @version
157
- when 75 then Handler::Server75.new(self)
158
- when 76, 0..3 then Handler::Server76.new(self)
159
- when 4..17 then Handler::Server04.new(self)
160
- else raise WebSocket::Error::Handshake::UnknownVersion
161
- end
153
+ when 75 then Handler::Server75.new(self)
154
+ when 76, 0..3 then Handler::Server76.new(self)
155
+ when 4..17 then Handler::Server04.new(self)
156
+ else fail WebSocket::Error::Handshake::UnknownVersion
157
+ end
162
158
  end
163
159
 
164
- PATH = /^(\w+) (\/[^\s]*) HTTP\/1\.1$/
160
+ PATH = %r{^(\w+) (\/[^\s]*) HTTP\/1\.1$}
165
161
 
166
162
  # Parse first line of Client response.
167
163
  # @param [String] line Line to parse
168
164
  # @return [Boolean] True if parsed correctly. False otherwise
169
165
  def parse_first_line(line)
170
166
  line_parts = line.match(PATH)
171
- raise WebSocket::Error::Handshake::InvalidHeader unless line_parts
167
+ fail WebSocket::Error::Handshake::InvalidHeader unless line_parts
172
168
  method = line_parts[1].strip
173
- raise WebSocket::Error::Handshake::GetRequestRequired unless method == 'GET'
169
+ fail WebSocket::Error::Handshake::GetRequestRequired unless method == 'GET'
174
170
 
175
171
  resource_name = line_parts[2].strip
176
172
  @path, @query = resource_name.split('?', 2)
177
173
  end
178
-
179
174
  end
180
175
  end
181
176
  end
@@ -1,3 +1,3 @@
1
1
  module WebSocket
2
- VERSION = '1.2.2'
2
+ VERSION = '1.2.3'
3
3
  end
@@ -55,7 +55,7 @@ RSpec.describe 'Incoming frame draft 03' do
55
55
  context 'should properly decode text frame in between of continuation' do
56
56
  let(:encoded_text) { "\x84\x03Hel\x03\x03abc\x00\x02lo" }
57
57
  let(:frame_type) { [:pong, :text] }
58
- let(:decoded_text) { ['abc', 'Hello'] }
58
+ let(:decoded_text) { %w(abc Hello) }
59
59
 
60
60
  it_should_behave_like 'valid_incoming_frame'
61
61
  end
@@ -114,5 +114,4 @@ RSpec.describe 'Incoming frame draft 03' do
114
114
 
115
115
  it_should_behave_like 'valid_incoming_frame'
116
116
  end
117
-
118
117
  end
@@ -55,7 +55,7 @@ RSpec.describe 'Incoming frame draft 04' do
55
55
  context 'should properly decode text frame in between of continuation' do
56
56
  let(:encoded_text) { "\x04\x03Hel\x83\x03abc\x80\x02lo" }
57
57
  let(:frame_type) { [:pong, :text] }
58
- let(:decoded_text) { ['abc', 'Hello'] }
58
+ let(:decoded_text) { %w(abc Hello) }
59
59
 
60
60
  it_should_behave_like 'valid_incoming_frame'
61
61
  end
@@ -114,5 +114,4 @@ RSpec.describe 'Incoming frame draft 04' do
114
114
 
115
115
  it_should_behave_like 'valid_incoming_frame'
116
116
  end
117
-
118
117
  end
@@ -71,7 +71,7 @@ RSpec.describe 'Incoming frame draft 05' do
71
71
  context 'should properly decode text frame in between of continuation' do
72
72
  let(:encoded_text) { "\x04\x03Hel\x83\x03abc\x80\x02lo" }
73
73
  let(:frame_type) { [:pong, :text] }
74
- let(:decoded_text) { ['abc', 'Hello'] }
74
+ let(:decoded_text) { %w(abc Hello) }
75
75
 
76
76
  it_should_behave_like 'valid_incoming_frame'
77
77
  end
@@ -130,5 +130,4 @@ RSpec.describe 'Incoming frame draft 05' do
130
130
 
131
131
  it_should_behave_like 'valid_incoming_frame'
132
132
  end
133
-
134
133
  end
@@ -88,7 +88,7 @@ RSpec.describe 'Incoming frame draft 07' do
88
88
  context 'should properly decode text frame in between of continuation' do
89
89
  let(:encoded_text) { "\x01\x03Hel\x8a\x03abc\x80\x02lo" }
90
90
  let(:frame_type) { [:pong, :text] }
91
- let(:decoded_text) { ['abc', 'Hello'] }
91
+ let(:decoded_text) { %w(abc Hello) }
92
92
 
93
93
  it_should_behave_like 'valid_incoming_frame'
94
94
  end
@@ -147,5 +147,4 @@ RSpec.describe 'Incoming frame draft 07' do
147
147
 
148
148
  it_should_behave_like 'valid_incoming_frame'
149
149
  end
150
-
151
150
  end