rfc-ws-client 1.0.1 → 1.1.0
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 +7 -0
- data/lib/rfc-ws-client.rb +92 -80
- data/lib/rfc-ws-client/version.rb +1 -1
- metadata +7 -9
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 98e21be6e84c991f51c14e5e98857eec559bec5e
|
4
|
+
data.tar.gz: 3d84f5d37b93a1b2761c09a787f194063c9d6baa
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d8e5966a84bca782a7e8d31a9fb8e456131247883ccaa10693589b807891e3b3e3821cb1a01cde72f12d34d49ab7902103ab425ba1713f4a27f982f42c1dea6f
|
7
|
+
data.tar.gz: 7b1fa847326b0c87a216c3a55d7f6c3877a848d91ab7791452a745fa2ea76ced24a8e0f0a2203c06c8c97ecd34894157876fe96046b0b5d9372186c985b75a16
|
data/lib/rfc-ws-client.rb
CHANGED
@@ -69,105 +69,117 @@ module RfcWebSocket
|
|
69
69
|
raise WebSocketError.new("sec-websocket-accept missing") unless accept
|
70
70
|
expected_accept = Digest::SHA1.base64digest(request_key + WEB_SOCKET_GUID)
|
71
71
|
raise WebSocketError.new("sec-websocket-accept is invalid, actual: #{accept}, expected: #{expected_accept}") unless accept == expected_accept
|
72
|
+
rescue WebSocketError
|
73
|
+
raise
|
74
|
+
rescue => e
|
75
|
+
raise WebSocketError(e.to_s)
|
72
76
|
end
|
73
77
|
|
74
78
|
def send_message(message, opts = {binary: false})
|
75
79
|
write(encode(message, opts[:binary] ? OPCODE_BINARY : OPCODE_TEXT))
|
80
|
+
rescue WebSocketError
|
81
|
+
raise
|
82
|
+
rescue => e
|
83
|
+
raise WebSocketError(e.to_s)
|
76
84
|
end
|
77
85
|
|
78
86
|
def receive
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
87
|
+
buffer = ""
|
88
|
+
fragmented = nil
|
89
|
+
# Loop until something returns
|
90
|
+
while true
|
91
|
+
b1, b2 = read(2).unpack("CC")
|
92
|
+
# first byte
|
93
|
+
fin = (b1 & 0x80) != 0
|
94
|
+
raise WebSocketError.new("reserved bits must be 0") if (b1 & 0b01110000) != 0
|
95
|
+
opcode = b1 & 0x0f
|
96
|
+
# second byte
|
97
|
+
mask = (b2 & 0x80) != 0
|
98
|
+
# we're a client
|
99
|
+
raise WebSocketError.new("server->client must not be masked!") if mask
|
100
|
+
length = b2 & 0x7f
|
101
|
+
if opcode > 7
|
102
|
+
raise WebSocketError.new("control frame cannot be fragmented") unless fin
|
103
|
+
raise WebSocketError.new("control frame is too large: #{length}") if length > 125
|
104
|
+
raise WebSocketError.new("unexpected reserved opcode: #{opcode}") if opcode > 0xA
|
105
|
+
raise WebSocketError.new("close frame with payload length 1") if length == 1 and opcode == OPCODE_CLOSE
|
106
|
+
elsif opcode != OPCODE_CONTINUATION && opcode != OPCODE_TEXT && opcode != OPCODE_BINARY
|
107
|
+
raise WebSocketError.new("unexpected reserved opcode: #{opcode}")
|
108
|
+
end
|
109
|
+
# extended payload length
|
110
|
+
if length == 126
|
111
|
+
length = read(2).unpack("n")[0]
|
112
|
+
elsif length == 127
|
113
|
+
high, low = *read(8).unpack("NN")
|
114
|
+
length = high * (2 ** 32) + low
|
115
|
+
end
|
116
|
+
# payload
|
117
|
+
payload = read(length)
|
118
|
+
case opcode
|
119
|
+
when OPCODE_CONTINUATION
|
120
|
+
raise WebSocketError.new("no frame to continue") unless fragmented
|
121
|
+
if fragmented == :binary
|
122
|
+
buffer << payload
|
123
|
+
else
|
124
|
+
buffer << payload.force_encoding("UTF-8")
|
108
125
|
end
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
raise WebSocketError.new("no frame to continue") unless fragmented
|
114
|
-
if fragmented == :binary
|
115
|
-
buffer << payload
|
116
|
-
else
|
117
|
-
buffer << payload.force_encoding("UTF-8")
|
118
|
-
end
|
119
|
-
if fin
|
120
|
-
raise WebSocketError.new("invalid utf8", 1007) if fragmented == :text and !valid_utf8?(buffer)
|
121
|
-
return buffer, fragmented == :binary
|
122
|
-
else
|
123
|
-
next
|
124
|
-
end
|
125
|
-
when OPCODE_TEXT
|
126
|
-
raise WebSocketError.new("unexpected opcode in continuation mode") if fragmented
|
127
|
-
if !fin
|
128
|
-
fragmented = :text
|
129
|
-
buffer << payload.force_encoding("UTF-8")
|
130
|
-
next
|
131
|
-
else
|
132
|
-
raise WebSocketError.new("invalid utf8", 1007) unless valid_utf8?(payload)
|
133
|
-
return payload, false
|
134
|
-
end
|
135
|
-
when OPCODE_BINARY
|
136
|
-
raise WebSocketError.new("unexpected opcode in continuation mode") if fragmented
|
137
|
-
if !fin
|
138
|
-
fragmented = :binary
|
139
|
-
buffer << payload
|
140
|
-
else
|
141
|
-
return payload, true
|
142
|
-
end
|
143
|
-
when OPCODE_CLOSE
|
144
|
-
code, explain = payload.unpack("nA*")
|
145
|
-
if explain && !valid_utf8?(explain)
|
146
|
-
close(1007)
|
147
|
-
else
|
148
|
-
close(response_close_code(code))
|
149
|
-
end
|
150
|
-
return nil, nil
|
151
|
-
when OPCODE_PING
|
152
|
-
write(encode(payload, OPCODE_PONG))
|
126
|
+
if fin
|
127
|
+
raise WebSocketError.new("invalid utf8", 1007) if fragmented == :text and !valid_utf8?(buffer)
|
128
|
+
return buffer, fragmented == :binary
|
129
|
+
else
|
153
130
|
next
|
154
|
-
|
131
|
+
end
|
132
|
+
when OPCODE_TEXT
|
133
|
+
raise WebSocketError.new("unexpected opcode in continuation mode") if fragmented
|
134
|
+
if !fin
|
135
|
+
fragmented = :text
|
136
|
+
buffer << payload.force_encoding("UTF-8")
|
155
137
|
next
|
156
138
|
else
|
157
|
-
raise WebSocketError.new("
|
139
|
+
raise WebSocketError.new("invalid utf8", 1007) unless valid_utf8?(payload)
|
140
|
+
return payload, false
|
141
|
+
end
|
142
|
+
when OPCODE_BINARY
|
143
|
+
raise WebSocketError.new("unexpected opcode in continuation mode") if fragmented
|
144
|
+
if !fin
|
145
|
+
fragmented = :binary
|
146
|
+
buffer << payload
|
147
|
+
else
|
148
|
+
return payload, true
|
149
|
+
end
|
150
|
+
when OPCODE_CLOSE
|
151
|
+
code, explain = payload.unpack("nA*")
|
152
|
+
if explain && !valid_utf8?(explain)
|
153
|
+
close(1007)
|
154
|
+
else
|
155
|
+
close(response_close_code(code))
|
158
156
|
end
|
157
|
+
return nil, nil
|
158
|
+
when OPCODE_PING
|
159
|
+
write(encode(payload, OPCODE_PONG))
|
160
|
+
next
|
161
|
+
when OPCODE_PONG
|
162
|
+
next
|
163
|
+
else
|
164
|
+
raise WebSocketError.new("received unknown opcode: #{opcode}")
|
159
165
|
end
|
160
|
-
rescue EOFError
|
161
|
-
return nil, nil
|
162
|
-
rescue WebSocketError => e
|
163
|
-
close(e.code)
|
164
|
-
raise e
|
165
166
|
end
|
167
|
+
rescue EOFError
|
168
|
+
return nil, nil
|
169
|
+
rescue WebSocketError => e
|
170
|
+
close(e.code)
|
171
|
+
raise e
|
172
|
+
rescue => e
|
173
|
+
raise WebSocketError(e.to_s)
|
166
174
|
end
|
167
175
|
|
168
176
|
def close(code = 1000, msg = nil)
|
169
177
|
write(encode [code ? code : 1000, msg].pack("nA*"), OPCODE_CLOSE)
|
170
178
|
@socket.close
|
179
|
+
rescue WebSocketError
|
180
|
+
raise
|
181
|
+
rescue => e
|
182
|
+
raise WebSocketError(e.to_s)
|
171
183
|
end
|
172
184
|
|
173
185
|
private
|
metadata
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rfc-ws-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
5
|
-
prerelease:
|
4
|
+
version: 1.1.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Lucas Clemente
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2013-04-08 00:00:00.000000000 Z
|
13
12
|
dependencies: []
|
14
13
|
description:
|
15
14
|
email:
|
@@ -29,26 +28,25 @@ files:
|
|
29
28
|
- rfc-ws-client.gemspec
|
30
29
|
homepage: https://github.com/lucas-clemente/rfc-ws-client
|
31
30
|
licenses: []
|
31
|
+
metadata: {}
|
32
32
|
post_install_message:
|
33
33
|
rdoc_options: []
|
34
34
|
require_paths:
|
35
35
|
- lib
|
36
36
|
required_ruby_version: !ruby/object:Gem::Requirement
|
37
|
-
none: false
|
38
37
|
requirements:
|
39
|
-
- -
|
38
|
+
- - '>='
|
40
39
|
- !ruby/object:Gem::Version
|
41
40
|
version: '0'
|
42
41
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
43
|
-
none: false
|
44
42
|
requirements:
|
45
|
-
- -
|
43
|
+
- - '>='
|
46
44
|
- !ruby/object:Gem::Version
|
47
45
|
version: '0'
|
48
46
|
requirements: []
|
49
47
|
rubyforge_project:
|
50
|
-
rubygems_version:
|
48
|
+
rubygems_version: 2.0.3
|
51
49
|
signing_key:
|
52
|
-
specification_version:
|
50
|
+
specification_version: 4
|
53
51
|
summary: A simple WebSocket client in ruby
|
54
52
|
test_files: []
|