libwebsocket 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.5 / 2012-07-27
4
+
5
+ - Fixed problem caused by invalid draft 10 support
6
+
3
7
  ## 0.1.4 / 2012-07-13
4
8
 
5
9
  - New gemspec and bundler files
data/README.md CHANGED
@@ -82,7 +82,8 @@ examples directory in the repository.
82
82
 
83
83
  Copyright (C) 2012, Bernard Potocki.
84
84
 
85
- Based on protocol-websocket perl distribution by Viacheslav Tykhanovskyi.
85
+ 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:
86
86
 
87
- This program is free software, you can redistribute it and/or modify it under
88
- the MIT License.
87
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
88
+
89
+ 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.
@@ -2,7 +2,6 @@
2
2
  # not provide a WebSocket server or client, but is made for using in http servers
3
3
  # or clients to provide WebSocket support.
4
4
  module LibWebSocket
5
- class Error < RuntimeError; end # Universal LibWebSocket error class
6
5
 
7
6
  autoload :Cookie, "#{File.dirname(__FILE__)}/libwebsocket/cookie"
8
7
  autoload :Frame, "#{File.dirname(__FILE__)}/libwebsocket/frame"
@@ -1,5 +1,3 @@
1
- # -*- encoding: binary -*-
2
-
3
1
  module LibWebSocket
4
2
  # Construct or parse a WebSocket frame.
5
3
  #
@@ -7,50 +5,22 @@ module LibWebSocket
7
5
  #
8
6
  # # Create frame
9
7
  # frame = LibWebSocket::Frame.new('123')
10
- # frame.to_bytes
8
+ # frame.to_s # \x00123\xff
11
9
  #
12
10
  # # Parse frames
13
11
  # frame = LibWebSocket::Frame.new
14
- # frame.append(...)
15
- # frame.next # get next message
16
- # frame.next # get another next message
12
+ # frame.append("123\x00foo\xff56\x00bar\xff789")
13
+ # frame.next # => foo
14
+ # frame.next # => bar
17
15
  class Frame
18
16
 
19
- autoload :Error, "#{File.dirname(__FILE__)}/frame/error"
20
-
21
- MAX_RAND_INT = 2 ** 32
22
- TYPES = {
23
- :text => 0x01,
24
- :binary => 0x02,
25
- :ping => 0x09,
26
- :pong => 0x0a,
27
- :close => 0x08
28
- }
29
-
30
- attr_accessor :buffer, :version, :max_fragments_amount, :max_payload_size, :fin, :rsv, :opcode, :masked
31
-
32
- # Create a new Frame instance. Automatically detect if the passed data is a string or bytes.
33
- # Options can be buffer or hash with options:
34
- # :buffer - content of buffer
35
- # :type - frame type(allowed values: text, binary, ping, pong, close)
36
- # :version - protocol version(see readme for supported versions)
37
- # :max_fragments_amount - max number of message parts per single frame
38
- # :max_payload_size - max bytesize of single message
39
- # @example
40
- # LibWebSocket::Frame->new('data')
41
- # LibWebSocket::Frame->new(:buffer => 'data', :type => 'close')
42
- def initialize(options = '')
43
- if options.is_a?(Hash)
44
- options.each {|k,v| instance_variable_set("@#{k}",v) }
45
- else
46
- @buffer = options
47
- end
17
+ def initialize(buffer = nil)
18
+ @buffer = buffer || ''
19
+ end
48
20
 
49
- @buffer ||= ''
50
- @version ||= 'draft-ietf-hybi-10'
51
- @fragments = []
52
- @max_fragments_amount ||= 128
53
- @max_payload_size ||= 65536
21
+ # Create new frame without modification of current
22
+ def new(buffer = nil)
23
+ self.class.new(buffer)
54
24
  end
55
25
 
56
26
  # Append a frame chunk.
@@ -60,134 +30,37 @@ module LibWebSocket
60
30
  def append(string = nil)
61
31
  return unless string.is_a?(String)
62
32
 
63
- string.force_encoding("ASCII-8BIT") if string.respond_to?(:force_encoding)
33
+ @buffer += string
64
34
 
65
- self.buffer += string
66
35
  return self
67
36
  end
68
37
 
69
38
  # Return the next frame.
70
39
  # @example
71
- # frame.append(...)
72
- # frame.next; # next message
40
+ # frame.append("\x00foo")
41
+ # frame.append("\xff\x00bar\xff")
42
+ #
43
+ # frame.next; # => foo
44
+ # frame.next; # => bar
73
45
  def next
74
- bytes = self.next_bytes
75
- return unless bytes
46
+ return unless @buffer.slice!(/^[^\x00]*\x00(.*?)\xff/m)
76
47
 
77
- bytes.force_encoding('UTF-8') if bytes.respond_to?(:force_encoding)
78
- return bytes
79
- end
48
+ string = $1
49
+ string.force_encoding('UTF-8') if string.respond_to?(:force_encoding)
80
50
 
81
- def opcode
82
- @opcode || 1
51
+ return string
83
52
  end
84
53
 
85
- def ping?; opcode == TYPES[:ping]; end # Check if frame is a ping request.
86
- def pong?; opcode == TYPES[:pong]; end # Check if frame is a pong response.
87
- def close?; opcode == TYPES[:close]; end # Check if frame is of close type.
88
- def text?; opcode == TYPES[:text]; end # Check if frame is of text type.
89
- def binary?; opcode == TYPES[:binary]; end # Check if frame is of binary type.
90
-
91
- # Return the next message as a UTF-8 encoded string.
92
- def next_bytes
93
- if ['draft-hixie-75', 'draft-ietf-hybi-00'].include? self.version
94
- if self.buffer.slice!(/\A\xff\x00/m)
95
- self.opcode = TYPES[:close]
96
- return ''
97
- end
98
-
99
- return unless self.buffer.slice!(/^[^\x00]*\x00(.*?)\xff/m)
100
- return $1
101
- end
102
-
103
- return unless self.buffer.length >= 2
104
-
105
- while self.buffer.length > 0
106
- hdr = self.buffer[0..0]
107
- bits = hdr.unpack("B*").first.split(//)
108
-
109
- self.fin = bits[0]
110
- self.rsv = bits[1..3]
111
- opcode = hdr.unpack('C').first & 0b00001111
112
- offset = 1 # FIN,RSV[1-3],OPCODE
113
-
114
- payload_len = buffer[1..1].unpack('C').first
115
- self.masked = (payload_len & 0b10000000) >> 7
116
- offset += 1 # + MASKED,PAYLOAD_LEN
117
-
118
- payload_len = payload_len & 0b01111111
119
- if payload_len == 126
120
- return unless self.buffer.length >= offset + 2
121
-
122
- payload_len = self.buffer[offset..offset+2].unpack('n').first
123
- offset += 2
124
- elsif payload_len > 126
125
- return unless self.buffer.length >= offset + 4
126
- bits = self.buffer[offset..offset+7].unpack('B*').first
127
- bits.gsub!(/^./,'0') # Most significant bit must be 0.
128
- bits = bits[32..-1] # No idea how to unpack 64-bit unsigned integer with big-endian byte order
129
- payload_len = Array(bits).pack("B*").unpack("N").first
130
- offset += 8
131
- end
132
-
133
- if payload_len > self.max_payload_size
134
- self.buffer = ''
135
- raise Error::MessageTooBig.new("Payload is too big. Deny big message (#{payload_len}) or increase max_payload_size (#{self.max_payload_size})")
136
- end
137
-
138
- mask = ''
139
- if self.masked == 1
140
- return unless self.buffer.length >= offset + 4
141
-
142
- mask = self.buffer[offset..offset+4]
143
- offset += 4
144
- end
145
-
146
- return if self.buffer.length < offset + payload_len
147
-
148
- payload = self.buffer[offset..offset+payload_len-1]
149
- payload = self.mask(payload, mask) if self.masked == 1
150
-
151
- self.buffer[0..offset+payload_len-1] = ''
152
-
153
- # Inject control frame
154
- if !@fragments.empty? && (opcode & 0b1000 != 0)
155
- self.opcode = opcode
156
- return payload
157
- end
158
-
159
- if self.fin != '0'
160
- if @fragments.empty?
161
- self.opcode = opcode
162
- else
163
- self.opcode = @fragments.shift
164
- end
165
-
166
- payload = (@fragments + Array(payload)).join
167
- @fragments = []
168
- return payload
169
- else
170
- # Remember first fragment opcode
171
- @fragments.push(opcode) if @fragments.empty?
172
-
173
- @fragments.push(payload)
174
- raise Error::PolicyViolation.new("Too many fragments") if @fragments.size > self.max_fragments_amount
175
- end
176
- end
177
-
178
- return
179
- end
54
+ # Construct a WebSocket frame.
55
+ # @example
56
+ # frame = LibWebSocket::Frame.new('foo')
57
+ # frame.to_s # => \x00foo\xff
58
+ def to_s
59
+ ary = ["\x00", @buffer.dup, "\xff"]
180
60
 
181
- protected
61
+ ary.collect{ |s| s.force_encoding('UTF-8') if s.respond_to?(:force_encoding) }
182
62
 
183
- def mask(payload, mask)
184
- mask = mask.bytes.to_a
185
- payload = payload.bytes.to_a
186
- payload.each_with_index do |p, i|
187
- j = i % 4
188
- payload[i] = p ^ mask[j]
189
- end
190
- return payload.collect(&:chr).join
63
+ return ary.join
191
64
  end
192
65
 
193
66
  end
@@ -126,9 +126,7 @@ module LibWebSocket
126
126
  def append(data)
127
127
  return if self.error
128
128
 
129
- data = data.encode("ASCII-8BIT") if data.respond_to?(:encode)
130
-
131
- @buffer << data
129
+ @buffer += data
132
130
 
133
131
  if @buffer.length > @max_message_size
134
132
  self.error = 'Message is too long'
@@ -1,3 +1,3 @@
1
1
  module LibWebSocket
2
- VERSION = '0.1.4'
2
+ VERSION = '0.1.5'
3
3
  end
@@ -1,10 +1,9 @@
1
- # -*- encoding: binary -*-
2
1
  require 'test_helper'
3
2
 
4
3
  class TestFrame < Test::Unit::TestCase
5
4
 
6
- def test_append_ietf_hybi_00
7
- f = LibWebSocket::Frame.new(:version => 'draft-ietf-hybi-00')
5
+ def test_append
6
+ f = LibWebSocket::Frame.new
8
7
 
9
8
  f.append
10
9
  assert_nil f.next
@@ -22,11 +21,6 @@ class TestFrame < Test::Unit::TestCase
22
21
  f.append("\xff")
23
22
  assert_equal '', f.next
24
23
 
25
- f.append("\xff")
26
- f.append("\x00")
27
- assert_equal '', f.next
28
- assert f.close?
29
-
30
24
  f.append("\x00")
31
25
  assert_nil f.next
32
26
  f.append("foo")
@@ -44,28 +38,28 @@ class TestFrame < Test::Unit::TestCase
44
38
  assert_nil f.next
45
39
 
46
40
  # We append bytes, but read characters
47
- msg = '☺'
41
+ msg = "\342\230\272"
48
42
  f.append("\x00" + msg + "\xff")
49
43
  msg.force_encoding('UTF-8') if msg.respond_to?(:force_encoding)
50
44
  assert_equal msg, f.next
51
45
  end
52
46
 
53
- def test_new_ietf_hybi_00
54
- # f = LibWebSocket::Frame.new(:version => 'draft-ietf-hybi-00')
55
- # msg = "\x00\xff"
56
- # msg.force_encoding('UTF-8') if msg.respond_to?(:force_encoding)
57
- # assert_equal msg, f.to_s
58
- #
59
- # f = LibWebSocket::Frame.new('123')
60
- # msg = "\x00123\xff"
61
- # msg.force_encoding('UTF-8') if msg.respond_to?(:force_encoding)
62
- # assert_equal msg, f.to_s
63
- #
64
- # # We pass characters, but send bytes
65
- # f = LibWebSocket::Frame.new("\342\230\272")
66
- # msg = "\x00\342\230\272\xff"
67
- # msg.force_encoding('UTF-8') if msg.respond_to?(:force_encoding)
68
- # assert_equal msg, f.to_s
47
+ def test_new
48
+ f = LibWebSocket::Frame.new
49
+ msg = "\x00\xff"
50
+ msg.force_encoding('UTF-8') if msg.respond_to?(:force_encoding)
51
+ assert_equal msg, f.to_s
52
+
53
+ f = LibWebSocket::Frame.new('123')
54
+ msg = "\x00123\xff"
55
+ msg.force_encoding('UTF-8') if msg.respond_to?(:force_encoding)
56
+ assert_equal msg, f.to_s
57
+
58
+ # We pass characters, but send bytes
59
+ f = LibWebSocket::Frame.new("\342\230\272")
60
+ msg = "\x00\342\230\272\xff"
61
+ msg.force_encoding('UTF-8') if msg.respond_to?(:force_encoding)
62
+ assert_equal msg, f.to_s
69
63
  end
70
64
 
71
65
  end
metadata CHANGED
@@ -1,55 +1,60 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: libwebsocket
3
- version: !ruby/object:Gem::Version
4
- version: 0.1.4
3
+ version: !ruby/object:Gem::Version
4
+ hash: 17
5
5
  prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 5
10
+ version: 0.1.5
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Bernard Potocki
9
14
  autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
- date: 2012-07-13 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
17
+
18
+ date: 2012-07-27 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
15
21
  name: addressable
16
- requirement: !ruby/object:Gem::Requirement
17
- none: false
18
- requirements:
19
- - - ! '>='
20
- - !ruby/object:Gem::Version
21
- version: '0'
22
- type: :runtime
23
22
  prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
23
+ requirement: &id001 !ruby/object:Gem::Requirement
25
24
  none: false
26
- requirements:
27
- - - ! '>='
28
- - !ruby/object:Gem::Version
29
- version: '0'
30
- - !ruby/object:Gem::Dependency
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 0
31
+ version: "0"
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
31
35
  name: rake
32
- requirement: !ruby/object:Gem::Requirement
33
- none: false
34
- requirements:
35
- - - ! '>='
36
- - !ruby/object:Gem::Version
37
- version: '0'
38
- type: :development
39
36
  prerelease: false
40
- version_requirements: !ruby/object:Gem::Requirement
37
+ requirement: &id002 !ruby/object:Gem::Requirement
41
38
  none: false
42
- requirements:
43
- - - ! '>='
44
- - !ruby/object:Gem::Version
45
- version: '0'
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ hash: 3
43
+ segments:
44
+ - 0
45
+ version: "0"
46
+ type: :development
47
+ version_requirements: *id002
46
48
  description: Universal Ruby library to handle WebSocket protocol
47
- email:
49
+ email:
48
50
  - bernard.potocki@imanel.org
49
51
  executables: []
52
+
50
53
  extensions: []
54
+
51
55
  extra_rdoc_files: []
52
- files:
56
+
57
+ files:
53
58
  - .gitignore
54
59
  - .travis.yml
55
60
  - CHANGELOG.md
@@ -64,7 +69,6 @@ files:
64
69
  - lib/libwebsocket/cookie/request.rb
65
70
  - lib/libwebsocket/cookie/response.rb
66
71
  - lib/libwebsocket/frame.rb
67
- - lib/libwebsocket/frame/error.rb
68
72
  - lib/libwebsocket/message.rb
69
73
  - lib/libwebsocket/opening_handshake.rb
70
74
  - lib/libwebsocket/opening_handshake/client.rb
@@ -77,11 +81,10 @@ files:
77
81
  - libwebsocket.gemspec
78
82
  - test/libwebsocket/cookie/request.rb
79
83
  - test/libwebsocket/cookie/response.rb
80
- - test/libwebsocket/draft-ietf-hybi-00/test_frame.rb
81
- - test/libwebsocket/draft-ietf-hybi-10/test_frame.rb
82
- - test/libwebsocket/handshake/test_client.rb
83
- - test/libwebsocket/handshake/test_server.rb
84
+ - test/libwebsocket/opening_handshake/test_client.rb
85
+ - test/libwebsocket/opening_handshake/test_server.rb
84
86
  - test/libwebsocket/test_cookie.rb
87
+ - test/libwebsocket/test_frame.rb
85
88
  - test/libwebsocket/test_message.rb
86
89
  - test/libwebsocket/test_request_75.rb
87
90
  - test/libwebsocket/test_request_76.rb
@@ -93,42 +96,44 @@ files:
93
96
  - test/test_helper.rb
94
97
  homepage: http://github.com/imanel/libwebsocket
95
98
  licenses: []
99
+
96
100
  post_install_message:
97
101
  rdoc_options: []
98
- require_paths:
102
+
103
+ require_paths:
99
104
  - lib
100
- required_ruby_version: !ruby/object:Gem::Requirement
105
+ required_ruby_version: !ruby/object:Gem::Requirement
101
106
  none: false
102
- requirements:
103
- - - ! '>='
104
- - !ruby/object:Gem::Version
105
- version: '0'
106
- segments:
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ hash: 3
111
+ segments:
107
112
  - 0
108
- hash: -2462651630557065482
109
- required_rubygems_version: !ruby/object:Gem::Requirement
113
+ version: "0"
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
115
  none: false
111
- requirements:
112
- - - ! '>='
113
- - !ruby/object:Gem::Version
114
- version: '0'
115
- segments:
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ hash: 3
120
+ segments:
116
121
  - 0
117
- hash: -2462651630557065482
122
+ version: "0"
118
123
  requirements: []
124
+
119
125
  rubyforge_project:
120
126
  rubygems_version: 1.8.24
121
127
  signing_key:
122
128
  specification_version: 3
123
129
  summary: Universal Ruby library to handle WebSocket protocol
124
- test_files:
130
+ test_files:
125
131
  - test/libwebsocket/cookie/request.rb
126
132
  - test/libwebsocket/cookie/response.rb
127
- - test/libwebsocket/draft-ietf-hybi-00/test_frame.rb
128
- - test/libwebsocket/draft-ietf-hybi-10/test_frame.rb
129
- - test/libwebsocket/handshake/test_client.rb
130
- - test/libwebsocket/handshake/test_server.rb
133
+ - test/libwebsocket/opening_handshake/test_client.rb
134
+ - test/libwebsocket/opening_handshake/test_server.rb
131
135
  - test/libwebsocket/test_cookie.rb
136
+ - test/libwebsocket/test_frame.rb
132
137
  - test/libwebsocket/test_message.rb
133
138
  - test/libwebsocket/test_request_75.rb
134
139
  - test/libwebsocket/test_request_76.rb
@@ -138,3 +143,4 @@ test_files:
138
143
  - test/libwebsocket/test_response_common.rb
139
144
  - test/libwebsocket/test_url.rb
140
145
  - test/test_helper.rb
146
+ has_rdoc:
@@ -1,99 +0,0 @@
1
- module LibWebSocket
2
- class Frame
3
-
4
- # Generic close error command for frame. Should not be called directly - use one of subclasses.
5
- # This should be catched and responded to according to clean_close? and status.
6
- class Error < LibWebSocket::Error
7
-
8
- # Should close frame be sent before closing?
9
- # If so then status code should be used to build it.
10
- def clean_close?
11
- true
12
- end
13
-
14
- # Status code for closing frame.
15
- def status_code
16
- 500 # This should not be called directly
17
- end
18
-
19
- # 1000 indicates a normal closure, meaning whatever purpose the
20
- # connection was established for has been fulfilled.
21
- class NormalClosure < Error
22
- def status_code; 1000; end
23
- end
24
-
25
- # 1001 indicates that an endpoint is "going away", such as a server
26
- # going down, or a browser having navigated away from a page.
27
- class GoingAway < Error
28
- def status_code; 1001; end
29
- end
30
-
31
- # 1002 indicates that an endpoint is terminating the connection due
32
- # to a protocol error.
33
- class ProtocolError < Error
34
- def status_code; 1002; end
35
- end
36
-
37
- # 1003 indicates that an endpoint is terminating the connection
38
- # because it has received a type of data it cannot accept (e.g. an
39
- # endpoint that understands only text data MAY send this if it
40
- # receives a binary message).
41
- class UnsupportedData < Error
42
- def status_code; 1003; end
43
- end
44
-
45
- # 1005 is a reserved value and MUST NOT be set as a status code in a
46
- # Close control frame by an endpoint. It is designated for use in
47
- # applications expecting a status code to indicate that no status
48
- # code was actually present.
49
- class NoStatusRcvd < Error
50
- def status_code; 1005; end
51
- end
52
-
53
- # 1006 is a reserved value and MUST NOT be set as a status code in a
54
- # Close control frame by an endpoint. It is designated for use in
55
- # applications expecting a status code to indicate that the
56
- # connection was closed abnormally, e.g. without sending or
57
- # receiving a Close control frame.
58
- class AbnormalClosure < Error
59
- def status_code; 1006; end
60
- end
61
-
62
- # 1007 indicates that an endpoint is terminating the connection
63
- # because it has received data within a message that was not
64
- # consistent with the type of the message (e.g., non-UTF-8 [RFC3629]
65
- # data within a text message).
66
- class InvalidFramePayloadData < Error
67
- def status_code; 1007; end
68
- end
69
-
70
- # 1008 indicates that an endpoint is terminating the connection
71
- # because it has received a message that violates its policy. This
72
- # is a generic status code that can be returned when there is no
73
- # other more suitable status code (e.g. 1003 or 1009), or if there
74
- # is a need to hide specific details about the policy.
75
- class PolicyViolation < Error
76
- def status_code; 1008; end
77
- end
78
-
79
- # 1009 indicates that an endpoint is terminating the connection
80
- # because it has received a message which is too big for it to
81
- # process.
82
- class MessageTooBig < Error
83
- def status_code; 1009; end
84
- end
85
-
86
- # 1010 indicates that an endpoint (client) is terminating the
87
- # connection because it has expected the server to negotiate one or
88
- # more extension, but the server didn't return them in the response
89
- # message of the WebSocket handshake. The list of extensions which
90
- # are needed SHOULD appear in the /reason/ part of the Close frame.
91
- # Note that this status code is not used by the server, because it
92
- # can fail the WebSocket handshake instead.
93
- class MandatoryExtension < Error
94
- def status_code; 1010; end
95
- end
96
-
97
- end
98
- end
99
- end
@@ -1,84 +0,0 @@
1
- # -*- encoding: binary -*-
2
- require 'test_helper'
3
-
4
- class TestFrame < Test::Unit::TestCase
5
-
6
- def test_append_ietf_hybi_10
7
- f = LibWebSocket::Frame.new(:version => 'draft-ietf-hybi-10')
8
-
9
- f.append
10
- assert_nil f.next
11
- f.append('')
12
- assert_nil f.next
13
-
14
- # Not masked
15
- f.append ["810548656c6c6f"].pack('H*')
16
- assert_equal 'Hello', f.next_bytes
17
- assert_equal 1, f.opcode
18
- assert f.text?
19
-
20
- # Multi
21
- f.append(["810548656c6c6f"].pack('H*') + ["810548656c6c6f"].pack('H*'))
22
- assert_equal 'Hello', f.next_bytes
23
- assert_equal 'Hello', f.next_bytes
24
-
25
- # Masked
26
- f.append ["818537fa213d7f9f4d5158"].pack('H*')
27
- assert_equal 'Hello', f.next_bytes
28
- assert_equal 1, f.opcode
29
-
30
- # Fragments
31
- f.append ["010348656c"].pack("H*")
32
- assert_nil f.next_bytes
33
- f.append ["80026c6f"].pack("H*")
34
- assert_equal 'Hello', f.next_bytes
35
- assert_equal 1, f.opcode
36
-
37
- # Multi fragments
38
- f.append(["010348656c"].pack('H*') + ["80026c6f"].pack('H*'))
39
- assert_equal 'Hello', f.next_bytes
40
- assert_equal 1, f.opcode
41
-
42
- # Injected control frame (1 fragment, ping, 2 fragment)
43
- f.append ["010348656c"].pack('H*')
44
- f.append ["890548656c6c6f"].pack('H*')
45
- f.append ["80026c6f"].pack('H*')
46
- assert_equal 'Hello', f.next_bytes
47
- assert_equal 9, f.opcode
48
- assert_equal 'Hello', f.next_bytes
49
- assert_equal 1, f.opcode
50
-
51
- # Too many fragments
52
- 130.times { f.append(["010348656c"].pack('H*')) }
53
- assert_raise(LibWebSocket::Frame::Error::PolicyViolation) { f.next_bytes }
54
-
55
- # Ping request
56
- f = LibWebSocket::Frame.new(:version => 'draft-ietf-hybi-10')
57
- f.append ["890548656c6c6f"].pack('H*')
58
- assert_equal 'Hello', f.next_bytes
59
- assert_equal 9, f.opcode
60
- assert f.ping?
61
-
62
- # Ping response
63
- f.append ["8a0548656c6c6f"].pack('H*')
64
- assert_equal 'Hello', f.next_bytes
65
- assert_equal 10, f.opcode
66
- assert f.pong?
67
-
68
- # 256 bytes
69
- f.append ["827E0100" + '05' * 256].pack('H*')
70
- assert_equal 256, f.next_bytes.length
71
- assert_equal 2, f.opcode
72
- assert f.binary?
73
-
74
- # 64KiB
75
- f.append ["827F0000000000010000" + '05' * 65536].pack('H*')
76
- assert_equal 65536, f.next_bytes.length
77
- assert_equal 2, f.opcode
78
-
79
- # Too big frame
80
- f.append ["827F0000000000100000" + '05' * (65536 + 1)].pack('H*')
81
- assert_raise(LibWebSocket::Frame::Error::MessageTooBig) { f.next_bytes }
82
- end
83
-
84
- end