websocket-driver 0.3.1 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 826108e30bdbc4629bcd1ef1c6b8029f9e4fed1b
4
+ data.tar.gz: e117f305de4f1e50f7046e32605538cbbec763c7
5
+ SHA512:
6
+ metadata.gz: b0d72d49469e28e6245e3df38a4769b834fb83bc5b5185ee51a32b15178dcd4b247810a0c507b190eb6e0e6411e20a9a3ccd48c0b29ead666c83b3307160bfb4
7
+ data.tar.gz: 15dd9190ce6ba1d40961820951c4056f60602ddac2d7d5d1c97923584a416b49a0b62d968eed95cf5eb8de7715170f999d18afb93c0fa92fd749e0c210ee16f0
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ### 0.3.2 / 2013-12-29
2
+
3
+ * Expand `max_length` to cover sequences of continuation frames and `draft-{75,76}`
4
+ * Decrease default maximum frame buffer size to 64MB
5
+ * Stop parsing when the protocol enters a failure mode, to save CPU cycles
6
+
1
7
  ### 0.3.1 / 2013-12-03
2
8
 
3
9
  * Add a `max_length` option to limit allowed frame size
data/README.md CHANGED
@@ -213,7 +213,7 @@ The `options` argument is optional, and is a hash. It may contain the following
213
213
  keys:
214
214
 
215
215
  * `:max_length` - the maximum allowed size of incoming message frames, in bytes.
216
- The default value is `2^30 - 1`, or 1 byte short of 1GiB.
216
+ The default value is `2^26 - 1`, or 1 byte short of 64 MiB.
217
217
  * `:protocols` - an array of strings representing acceptable subprotocols for
218
218
  use over the socket. The driver will negotiate one of these to use via the
219
219
  `Sec-WebSocket-Protocol` header if supported by the other peer.
@@ -35,7 +35,8 @@ module WebSocket
35
35
  require root + '/utf8_match'
36
36
  end
37
37
 
38
- STATES = [:connecting, :open, :closing, :closed]
38
+ MAX_LENGTH = 0x3ffffff
39
+ STATES = [:connecting, :open, :closing, :closed]
39
40
 
40
41
  class ConnectEvent < Struct.new(nil) ; end
41
42
  class OpenEvent < Struct.new(nil) ; end
@@ -60,6 +61,7 @@ module WebSocket
60
61
 
61
62
  @socket = socket
62
63
  @options = options
64
+ @max_length = options[:max_length] || MAX_LENGTH
63
65
  @headers = Headers.new
64
66
  @queue = []
65
67
  @ready_state = 0
@@ -11,7 +11,15 @@ module WebSocket
11
11
  'hixie-75'
12
12
  end
13
13
 
14
+ def close(reason = nil, code = nil)
15
+ return false if @ready_state == 3
16
+ @ready_state = 3
17
+ emit(:close, CloseEvent.new(nil, nil))
18
+ true
19
+ end
20
+
14
21
  def parse(buffer)
22
+ return if @ready_state > 1
15
23
  buffer = buffer.bytes if buffer.respond_to?(:bytes)
16
24
 
17
25
  buffer.each do |data|
@@ -28,8 +36,7 @@ module WebSocket
28
36
  @length = value + 128 * @length
29
37
 
30
38
  if @closing and @length.zero?
31
- @ready_state = 3
32
- emit(:close, CloseEvent.new(nil, nil))
39
+ return close
33
40
  elsif (0x80 & data) != 0x80
34
41
  if @length.zero?
35
42
  @stage = 0
@@ -49,6 +56,7 @@ module WebSocket
49
56
  @stage = 0 if @skipped == @length
50
57
  else
51
58
  @buffer << data
59
+ return close if @buffer.size > @max_length
52
60
  end
53
61
  end
54
62
  end
@@ -32,8 +32,6 @@ module WebSocket
32
32
  FRAGMENTED_OPCODES = OPCODES.values_at(:continuation, :text, :binary)
33
33
  OPENING_OPCODES = OPCODES.values_at(:text, :binary)
34
34
 
35
- MAX_LENGTH = 0x3fffffff
36
-
37
35
  ERRORS = {
38
36
  :normal_closure => 1000,
39
37
  :going_away => 1001,
@@ -54,12 +52,11 @@ module WebSocket
54
52
  super
55
53
  reset
56
54
 
57
- @reader = StreamReader.new
58
- @stage = 0
59
- @masking = options[:masking]
60
- @protocols = options[:protocols] || []
61
- @protocols = @protocols.strip.split(/\s*,\s*/) if String === @protocols
62
- @max_length = options[:max_length] || MAX_LENGTH
55
+ @reader = StreamReader.new
56
+ @stage = 0
57
+ @masking = options[:masking]
58
+ @protocols = options[:protocols] || []
59
+ @protocols = @protocols.strip.split(/\s*,\s*/) if String === @protocols
63
60
 
64
61
  @require_masking = options[:require_masking]
65
62
  @ping_callbacks = {}
@@ -101,6 +98,9 @@ module WebSocket
101
98
  emit_frame
102
99
  @stage = 0
103
100
  end
101
+
102
+ else
103
+ buffer = nil
104
104
  end
105
105
  end
106
106
  end
@@ -222,6 +222,7 @@ module WebSocket
222
222
  def shutdown(code, reason)
223
223
  frame(reason, :close, code)
224
224
  @ready_state = 3
225
+ @stage = 5
225
226
  emit(:close, CloseEvent.new(code, reason))
226
227
  end
227
228
 
@@ -268,7 +269,8 @@ module WebSocket
268
269
 
269
270
  @length = (data & LENGTH)
270
271
 
271
- if @length <= 125
272
+ if @length >= 0 and @length <= 125
273
+ return unless check_frame_length
272
274
  @stage = @masked ? 3 : 4
273
275
  else
274
276
  @length_size = (@length == 126) ? 2 : 8
@@ -283,13 +285,20 @@ module WebSocket
283
285
  return fail(:protocol_error, "Received control frame having too long payload: #{@length}")
284
286
  end
285
287
 
286
- if @length > @max_length
287
- return fail(:too_large, 'WebSocket frame length too large')
288
- end
288
+ return unless check_frame_length
289
289
 
290
290
  @stage = @masked ? 3 : 4
291
291
  end
292
292
 
293
+ def check_frame_length
294
+ if @buffer.size + @length > @max_length
295
+ fail(:too_large, 'WebSocket frame length too large')
296
+ false
297
+ else
298
+ true
299
+ end
300
+ end
301
+
293
302
  def emit_frame
294
303
  payload = @masked ? Mask.mask(@payload, @mask) : @payload
295
304
 
metadata CHANGED
@@ -1,62 +1,55 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: websocket-driver
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
5
- prerelease:
4
+ version: 0.3.2
6
5
  platform: ruby
7
6
  authors:
8
7
  - James Coglan
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-12-03 00:00:00.000000000 Z
11
+ date: 2013-12-29 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: eventmachine
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - ">="
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
22
20
  type: :development
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - ">="
28
25
  - !ruby/object:Gem::Version
29
26
  version: '0'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: rake-compiler
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ~>
31
+ - - "~>"
36
32
  - !ruby/object:Gem::Version
37
33
  version: 0.8.0
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ~>
38
+ - - "~>"
44
39
  - !ruby/object:Gem::Version
45
40
  version: 0.8.0
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: rspec
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - ">="
52
46
  - !ruby/object:Gem::Version
53
47
  version: '0'
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ! '>='
52
+ - - ">="
60
53
  - !ruby/object:Gem::Version
61
54
  version: '0'
62
55
  description:
@@ -67,53 +60,52 @@ extensions:
67
60
  extra_rdoc_files:
68
61
  - README.md
69
62
  files:
70
- - README.md
71
63
  - CHANGELOG.md
72
- - ext/websocket_mask/websocket_mask.c
64
+ - README.md
65
+ - examples/tcp_server.rb
73
66
  - ext/websocket_mask/WebsocketMaskService.java
74
67
  - ext/websocket_mask/extconf.rb
75
- - examples/tcp_server.rb
76
- - lib/websocket/http/request.rb
77
- - lib/websocket/http/headers.rb
78
- - lib/websocket/http/response.rb
68
+ - ext/websocket_mask/websocket_mask.c
79
69
  - lib/websocket/driver.rb
80
- - lib/websocket/http.rb
81
- - lib/websocket/driver/hybi/stream_reader.rb
82
- - lib/websocket/driver/utf8_match.rb
83
- - lib/websocket/driver/headers.rb
84
- - lib/websocket/driver/hybi.rb
85
- - lib/websocket/driver/server.rb
86
70
  - lib/websocket/driver/client.rb
87
71
  - lib/websocket/driver/draft75.rb
88
- - lib/websocket/driver/event_emitter.rb
89
72
  - lib/websocket/driver/draft76.rb
73
+ - lib/websocket/driver/event_emitter.rb
74
+ - lib/websocket/driver/headers.rb
75
+ - lib/websocket/driver/hybi.rb
76
+ - lib/websocket/driver/hybi/stream_reader.rb
77
+ - lib/websocket/driver/server.rb
78
+ - lib/websocket/driver/utf8_match.rb
79
+ - lib/websocket/http.rb
80
+ - lib/websocket/http/headers.rb
81
+ - lib/websocket/http/request.rb
82
+ - lib/websocket/http/response.rb
90
83
  homepage: http://github.com/faye/websocket-driver-ruby
91
84
  licenses:
92
85
  - MIT
86
+ metadata: {}
93
87
  post_install_message:
94
88
  rdoc_options:
95
- - --main
89
+ - "--main"
96
90
  - README.md
97
- - --markup
91
+ - "--markup"
98
92
  - markdown
99
93
  require_paths:
100
94
  - lib
101
95
  required_ruby_version: !ruby/object:Gem::Requirement
102
- none: false
103
96
  requirements:
104
- - - ! '>='
97
+ - - ">="
105
98
  - !ruby/object:Gem::Version
106
99
  version: '0'
107
100
  required_rubygems_version: !ruby/object:Gem::Requirement
108
- none: false
109
101
  requirements:
110
- - - ! '>='
102
+ - - ">="
111
103
  - !ruby/object:Gem::Version
112
104
  version: '0'
113
105
  requirements: []
114
106
  rubyforge_project:
115
- rubygems_version: 1.8.23
107
+ rubygems_version: 2.2.0
116
108
  signing_key:
117
- specification_version: 3
109
+ specification_version: 4
118
110
  summary: WebSocket protocol handler with pluggable I/O
119
111
  test_files: []