websocket-driver 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
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: []