websocket-driver 0.3.3 → 0.3.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -1
- data/README.md +0 -1
- data/examples/tcp_server.rb +0 -1
- data/ext/websocket-driver/WebsocketMaskService.java +4 -0
- data/ext/websocket-driver/extconf.rb +0 -1
- data/ext/websocket-driver/websocket_mask.c +4 -1
- data/lib/websocket/driver.rb +0 -2
- data/lib/websocket/driver/client.rb +0 -1
- data/lib/websocket/driver/draft75.rb +0 -1
- data/lib/websocket/driver/draft76.rb +0 -1
- data/lib/websocket/driver/event_emitter.rb +0 -1
- data/lib/websocket/driver/headers.rb +0 -1
- data/lib/websocket/driver/hybi.rb +26 -29
- data/lib/websocket/driver/hybi/stream_reader.rb +0 -1
- data/lib/websocket/driver/server.rb +6 -1
- data/lib/websocket/driver/utf8_match.rb +0 -1
- data/lib/websocket/http.rb +0 -1
- data/lib/websocket/http/headers.rb +28 -2
- data/lib/websocket/http/request.rb +0 -1
- data/lib/websocket/http/response.rb +0 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 547ad558c91b225fb330155dfda3c4b80fce0ffe
|
4
|
+
data.tar.gz: 87efd4c7a99f2a765badd12237966e6c000e7581
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1dc8274a20b011cb8caf5d5acb8b96a0c0e4312c1e1f7f722de8304124b7249b97eee978e84f110ac4d6988bfcb098709e4430d890f9dc442f809806d0a0a034
|
7
|
+
data.tar.gz: c4780127df20fbb47c9c3c5fedbc33df99fbed323a1b52cf5b4d1dd0e5a812e0fcd11515dcacd6494214759c035a01e657029cbbfac5bd20d98e2138573f9e04
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
### 0.3.4 / 2014-07-06
|
2
|
+
|
3
|
+
* Don't hold references to frame buffers after a message has been emitted
|
4
|
+
* Make sure that `protocol` and `version` are exposed properly by the TCP driver
|
5
|
+
* Correct HTTP header parsing based on RFC 7230; header names cannot contain backslashes
|
6
|
+
|
1
7
|
### 0.3.3 / 2014-04-24
|
2
8
|
|
3
9
|
* Fix problems with loading C and Java native extension code
|
@@ -45,4 +51,3 @@
|
|
45
51
|
* First release
|
46
52
|
* Proof of concept for people to try out
|
47
53
|
* Might be unstable
|
48
|
-
|
data/README.md
CHANGED
data/examples/tcp_server.rb
CHANGED
@@ -39,6 +39,10 @@ public class WebsocketMaskService implements BasicLibraryService {
|
|
39
39
|
|
40
40
|
@JRubyMethod
|
41
41
|
public IRubyObject mask(ThreadContext context, IRubyObject payload, IRubyObject mask) {
|
42
|
+
if (mask.isNil() || ((RubyArray)mask).getLength() == 0) {
|
43
|
+
return payload;
|
44
|
+
}
|
45
|
+
|
42
46
|
int n = ((RubyArray)payload).getLength(), i;
|
43
47
|
long p, m;
|
44
48
|
RubyArray unmasked = RubyArray.newArray(runtime, n);
|
@@ -13,6 +13,10 @@ void Init_websocket_mask() {
|
|
13
13
|
}
|
14
14
|
|
15
15
|
VALUE method_websocket_mask(VALUE self, VALUE payload, VALUE mask) {
|
16
|
+
if (mask == Qnil || RARRAY_LEN(mask) == 0) {
|
17
|
+
return payload;
|
18
|
+
}
|
19
|
+
|
16
20
|
int n = RARRAY_LEN(payload), i, p, m;
|
17
21
|
VALUE unmasked = rb_ary_new2(n);
|
18
22
|
|
@@ -30,4 +34,3 @@ VALUE method_websocket_mask(VALUE self, VALUE payload, VALUE mask) {
|
|
30
34
|
}
|
31
35
|
return unmasked;
|
32
36
|
}
|
33
|
-
|
data/lib/websocket/driver.rb
CHANGED
@@ -170,7 +170,6 @@ module WebSocket
|
|
170
170
|
end
|
171
171
|
|
172
172
|
def self.websocket?(env)
|
173
|
-
return false unless env['REQUEST_METHOD'] == 'GET'
|
174
173
|
connection = env['HTTP_CONNECTION'] || ''
|
175
174
|
upgrade = env['HTTP_UPGRADE'] || ''
|
176
175
|
|
@@ -181,4 +180,3 @@ module WebSocket
|
|
181
180
|
|
182
181
|
end
|
183
182
|
end
|
184
|
-
|
@@ -52,14 +52,20 @@ module WebSocket
|
|
52
52
|
super
|
53
53
|
reset
|
54
54
|
|
55
|
-
@reader
|
56
|
-
@stage
|
57
|
-
@masking
|
58
|
-
@protocols
|
59
|
-
@protocols
|
60
|
-
|
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
|
61
60
|
@require_masking = options[:require_masking]
|
62
61
|
@ping_callbacks = {}
|
62
|
+
|
63
|
+
return unless @socket.respond_to?(:env)
|
64
|
+
|
65
|
+
if protos = @socket.env['HTTP_SEC_WEBSOCKET_PROTOCOL']
|
66
|
+
protos = protos.split(/\s*,\s*/) if String === protos
|
67
|
+
@protocol = protos.find { |p| @protocols.include?(p) }
|
68
|
+
end
|
63
69
|
end
|
64
70
|
|
65
71
|
def version
|
@@ -95,7 +101,7 @@ module WebSocket
|
|
95
101
|
buffer = @reader.read(@length)
|
96
102
|
if buffer
|
97
103
|
@payload = buffer
|
98
|
-
emit_frame
|
104
|
+
emit_frame(buffer)
|
99
105
|
@stage = 0
|
100
106
|
end
|
101
107
|
|
@@ -195,25 +201,15 @@ module WebSocket
|
|
195
201
|
sec_key = @socket.env['HTTP_SEC_WEBSOCKET_KEY']
|
196
202
|
return '' unless String === sec_key
|
197
203
|
|
198
|
-
accept = Hybi.generate_accept(sec_key)
|
199
|
-
protos = @socket.env['HTTP_SEC_WEBSOCKET_PROTOCOL']
|
200
|
-
supported = @protocols
|
201
|
-
proto = nil
|
202
|
-
|
203
204
|
headers = [
|
204
205
|
"HTTP/1.1 101 Switching Protocols",
|
205
206
|
"Upgrade: websocket",
|
206
207
|
"Connection: Upgrade",
|
207
|
-
"Sec-WebSocket-Accept: #{
|
208
|
+
"Sec-WebSocket-Accept: #{Hybi.generate_accept(sec_key)}"
|
208
209
|
]
|
209
210
|
|
210
|
-
if
|
211
|
-
|
212
|
-
proto = protos.find { |p| supported.include?(p) }
|
213
|
-
if proto
|
214
|
-
@protocol = proto
|
215
|
-
headers << "Sec-WebSocket-Protocol: #{proto}"
|
216
|
-
end
|
211
|
+
if @protocol
|
212
|
+
headers << "Sec-WebSocket-Protocol: #{@protocol}"
|
217
213
|
end
|
218
214
|
|
219
215
|
(headers + [@headers.to_s, '']).join("\r\n")
|
@@ -243,8 +239,6 @@ module WebSocket
|
|
243
239
|
|
244
240
|
@final = (data & FIN) == FIN
|
245
241
|
@opcode = (data & OPCODE)
|
246
|
-
@mask = []
|
247
|
-
@payload = []
|
248
242
|
|
249
243
|
unless OPCODES.values.include?(@opcode)
|
250
244
|
return fail(:protocol_error, "Unrecognized frame opcode: #{@opcode}")
|
@@ -299,14 +293,18 @@ module WebSocket
|
|
299
293
|
end
|
300
294
|
end
|
301
295
|
|
302
|
-
def emit_frame
|
303
|
-
payload
|
296
|
+
def emit_frame(buffer)
|
297
|
+
payload = Mask.mask(buffer, @mask)
|
298
|
+
is_final = @final
|
299
|
+
opcode = @opcode
|
304
300
|
|
305
|
-
|
301
|
+
@final = @opcode = @length = @length_size = @masked = @mask = nil
|
302
|
+
|
303
|
+
case opcode
|
306
304
|
when OPCODES[:continuation] then
|
307
305
|
return fail(:protocol_error, 'Received unexpected continuation frame') unless @mode
|
308
306
|
@buffer.concat(payload)
|
309
|
-
if
|
307
|
+
if is_final
|
310
308
|
message = @buffer
|
311
309
|
message = Driver.encode(message, :utf8) if @mode == :text
|
312
310
|
reset
|
@@ -318,7 +316,7 @@ module WebSocket
|
|
318
316
|
end
|
319
317
|
|
320
318
|
when OPCODES[:text] then
|
321
|
-
if
|
319
|
+
if is_final
|
322
320
|
message = Driver.encode(payload, :utf8)
|
323
321
|
if message
|
324
322
|
emit(:message, MessageEvent.new(message))
|
@@ -331,7 +329,7 @@ module WebSocket
|
|
331
329
|
end
|
332
330
|
|
333
331
|
when OPCODES[:binary] then
|
334
|
-
if
|
332
|
+
if is_final
|
335
333
|
emit(:message, MessageEvent.new(payload))
|
336
334
|
else
|
337
335
|
@mode = :binary
|
@@ -383,4 +381,3 @@ module WebSocket
|
|
383
381
|
|
384
382
|
end
|
385
383
|
end
|
386
|
-
|
@@ -33,6 +33,12 @@ module WebSocket
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
+
%w[protocol version].each do |method|
|
37
|
+
define_method(method) do
|
38
|
+
@delegate && @delegate.__send__(method)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
36
42
|
def parse(buffer)
|
37
43
|
return @delegate.parse(buffer) if @delegate
|
38
44
|
|
@@ -70,4 +76,3 @@ module WebSocket
|
|
70
76
|
|
71
77
|
end
|
72
78
|
end
|
73
|
-
|
data/lib/websocket/http.rb
CHANGED
@@ -6,7 +6,34 @@ module WebSocket
|
|
6
6
|
CR = 0x0D
|
7
7
|
LF = 0x0A
|
8
8
|
|
9
|
-
|
9
|
+
# RFC 2616 grammar rules:
|
10
|
+
#
|
11
|
+
# CHAR = <any US-ASCII character (octets 0 - 127)>
|
12
|
+
#
|
13
|
+
# CTL = <any US-ASCII control character
|
14
|
+
# (octets 0 - 31) and DEL (127)>
|
15
|
+
#
|
16
|
+
# SP = <US-ASCII SP, space (32)>
|
17
|
+
#
|
18
|
+
# HT = <US-ASCII HT, horizontal-tab (9)>
|
19
|
+
#
|
20
|
+
# token = 1*<any CHAR except CTLs or separators>
|
21
|
+
#
|
22
|
+
# separators = "(" | ")" | "<" | ">" | "@"
|
23
|
+
# | "," | ";" | ":" | "\" | <">
|
24
|
+
# | "/" | "[" | "]" | "?" | "="
|
25
|
+
# | "{" | "}" | SP | HT
|
26
|
+
#
|
27
|
+
# Or, as redefined in RFC 7230:
|
28
|
+
#
|
29
|
+
# token = 1*tchar
|
30
|
+
#
|
31
|
+
# tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*"
|
32
|
+
# / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
|
33
|
+
# / DIGIT / ALPHA
|
34
|
+
# ; any VCHAR, except delimiters
|
35
|
+
|
36
|
+
HEADER_LINE = /^([!#\$%&'\*\+\-\.\^_`\|~0-9a-z]+):\s*([\x20-\x7e]*?)\s*$/i
|
10
37
|
|
11
38
|
attr_reader :headers
|
12
39
|
|
@@ -74,4 +101,3 @@ module WebSocket
|
|
74
101
|
|
75
102
|
end
|
76
103
|
end
|
77
|
-
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: websocket-driver
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Coglan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-07-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: eventmachine
|
@@ -105,7 +105,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
105
105
|
version: '0'
|
106
106
|
requirements: []
|
107
107
|
rubyforge_project:
|
108
|
-
rubygems_version: 2.2.
|
108
|
+
rubygems_version: 2.2.2
|
109
109
|
signing_key:
|
110
110
|
specification_version: 4
|
111
111
|
summary: WebSocket protocol handler with pluggable I/O
|