ruflet_server 0.0.7 → 0.0.8
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 +4 -4
- data/lib/ruflet/server/web_socket_connection.rb +20 -2
- data/lib/ruflet/server/wire_codec.rb +17 -0
- data/lib/ruflet/server.rb +31 -3
- data/lib/ruflet/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f0ec355d06e9fb730a851fa6b085bc97b74bd1231aa682bfc03a93ed3078f762
|
|
4
|
+
data.tar.gz: 2c3af4192affd015f59bfc0a49dc4fe3af264f1da38f5914c78af3d8602ace57
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 250363621bf1bfaefb04a2a2a89f30336590272250239c21061d96c60cac1ae5464f5a5442a42fab0f415bea3085a5921be8bb073e59d7d968b5bc537635eac9
|
|
7
|
+
data.tar.gz: 14d25116e02035b24646f73577aa3780b5f990473191725636324d26c53cccd3a65da53d84db3d2534a4a60450aac5ce7c79799f70b44703db271819c8f8f687
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
module Ruflet
|
|
4
4
|
class WebSocketConnection
|
|
5
|
+
# Ruflet control messages are small; anything much larger is invalid or hostile.
|
|
6
|
+
MAX_FRAME_PAYLOAD_BYTES = 16 * 1024 * 1024
|
|
7
|
+
|
|
5
8
|
def initialize(socket)
|
|
6
9
|
@socket = socket
|
|
7
10
|
@write_mutex = Mutex.new
|
|
@@ -70,10 +73,20 @@ module Ruflet
|
|
|
70
73
|
masked = (b2 & 0x80) != 0
|
|
71
74
|
payload_len = b2 & 0x7f
|
|
72
75
|
|
|
73
|
-
|
|
74
|
-
|
|
76
|
+
if payload_len == 126
|
|
77
|
+
ext = read_exact(2)
|
|
78
|
+
return nil if ext.nil?
|
|
79
|
+
payload_len = ext.unpack1("n")
|
|
80
|
+
elsif payload_len == 127
|
|
81
|
+
ext = read_exact(8)
|
|
82
|
+
return nil if ext.nil?
|
|
83
|
+
payload_len = ext.unpack1("Q>")
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
return nil if payload_len.negative? || payload_len > MAX_FRAME_PAYLOAD_BYTES
|
|
75
87
|
|
|
76
88
|
masking_key = masked ? read_exact(4) : nil
|
|
89
|
+
return nil if masked && masking_key.nil?
|
|
77
90
|
payload = payload_len.zero? ? "".b : read_exact(payload_len)
|
|
78
91
|
return nil if payload.nil?
|
|
79
92
|
|
|
@@ -112,6 +125,9 @@ module Ruflet
|
|
|
112
125
|
end
|
|
113
126
|
|
|
114
127
|
def read_exact(length)
|
|
128
|
+
return nil unless length.is_a?(Integer)
|
|
129
|
+
return nil if length.negative? || length > MAX_FRAME_PAYLOAD_BYTES
|
|
130
|
+
|
|
115
131
|
chunk = +""
|
|
116
132
|
chunk.force_encoding(Encoding::BINARY)
|
|
117
133
|
|
|
@@ -123,6 +139,8 @@ module Ruflet
|
|
|
123
139
|
end
|
|
124
140
|
|
|
125
141
|
chunk
|
|
142
|
+
rescue IOError, SystemCallError
|
|
143
|
+
nil
|
|
126
144
|
end
|
|
127
145
|
end
|
|
128
146
|
end
|
|
@@ -128,10 +128,23 @@ module Ruflet
|
|
|
128
128
|
when 0xd9 then reader.read_string(reader.read_u8)
|
|
129
129
|
when 0xda then reader.read_string(reader.read_u16)
|
|
130
130
|
when 0xdb then reader.read_string(reader.read_u32)
|
|
131
|
+
when 0xc4 then reader.read_binary(reader.read_u8)
|
|
132
|
+
when 0xc5 then reader.read_binary(reader.read_u16)
|
|
133
|
+
when 0xc6 then reader.read_binary(reader.read_u32)
|
|
131
134
|
when 0xdc then read_array(reader, reader.read_u16)
|
|
132
135
|
when 0xdd then read_array(reader, reader.read_u32)
|
|
133
136
|
when 0xde then read_map(reader, reader.read_u16)
|
|
134
137
|
when 0xdf then read_map(reader, reader.read_u32)
|
|
138
|
+
when 0xd4
|
|
139
|
+
read_ext(reader, 1)
|
|
140
|
+
when 0xd5
|
|
141
|
+
read_ext(reader, 2)
|
|
142
|
+
when 0xd6
|
|
143
|
+
read_ext(reader, 4)
|
|
144
|
+
when 0xd7
|
|
145
|
+
read_ext(reader, 8)
|
|
146
|
+
when 0xd8
|
|
147
|
+
read_ext(reader, 16)
|
|
135
148
|
when 0xc7
|
|
136
149
|
read_ext(reader, reader.read_u8)
|
|
137
150
|
when 0xc8
|
|
@@ -231,6 +244,10 @@ module Ruflet
|
|
|
231
244
|
def read_string(size)
|
|
232
245
|
read_exact(size).force_encoding("UTF-8")
|
|
233
246
|
end
|
|
247
|
+
|
|
248
|
+
def read_binary(size)
|
|
249
|
+
read_exact(size)
|
|
250
|
+
end
|
|
234
251
|
end
|
|
235
252
|
end
|
|
236
253
|
end
|
data/lib/ruflet/server.rb
CHANGED
|
@@ -186,6 +186,8 @@ module Ruflet
|
|
|
186
186
|
ws = nil
|
|
187
187
|
begin
|
|
188
188
|
path, headers = read_http_upgrade_request(socket)
|
|
189
|
+
return if path.nil?
|
|
190
|
+
|
|
189
191
|
if websocket_upgrade_request?(path, headers)
|
|
190
192
|
send_handshake_response(socket, headers["sec-websocket-key"])
|
|
191
193
|
ws = Ruflet::WebSocketConnection.new(socket)
|
|
@@ -194,6 +196,8 @@ module Ruflet
|
|
|
194
196
|
handle_http_request(socket, path)
|
|
195
197
|
end
|
|
196
198
|
rescue StandardError => e
|
|
199
|
+
return if disconnect_error?(e)
|
|
200
|
+
|
|
197
201
|
warn "server error: #{e.class}: #{e.message}"
|
|
198
202
|
warn e.backtrace.join("\n") if e.backtrace
|
|
199
203
|
send_message(ws, Protocol::ACTIONS[:session_crashed], { "message" => e.message.to_s.dup.force_encoding("UTF-8") }) if ws
|
|
@@ -209,6 +213,8 @@ module Ruflet
|
|
|
209
213
|
handle_message(ws, raw)
|
|
210
214
|
end
|
|
211
215
|
rescue StandardError => e
|
|
216
|
+
return if disconnect_error?(e)
|
|
217
|
+
|
|
212
218
|
warn "server error: #{e.class}: #{e.message}"
|
|
213
219
|
warn e.backtrace.join("\n") if e.backtrace
|
|
214
220
|
send_message(ws, Protocol::ACTIONS[:session_crashed], { "message" => e.message.to_s.dup.force_encoding("UTF-8") })
|
|
@@ -224,10 +230,12 @@ module Ruflet
|
|
|
224
230
|
|
|
225
231
|
def read_http_upgrade_request(socket)
|
|
226
232
|
request_line = socket.gets("\r\n")
|
|
227
|
-
|
|
233
|
+
return [nil, {}] if request_line.nil?
|
|
234
|
+
return [nil, {}] unless request_line.include?(" ")
|
|
228
235
|
|
|
229
236
|
method, path, _version = request_line.strip.split(" ", 3)
|
|
230
|
-
|
|
237
|
+
return [nil, {}] unless method == "GET"
|
|
238
|
+
return [nil, {}] if path.to_s.empty?
|
|
231
239
|
|
|
232
240
|
headers = {}
|
|
233
241
|
loop do
|
|
@@ -509,10 +517,30 @@ module Ruflet
|
|
|
509
517
|
end
|
|
510
518
|
|
|
511
519
|
def send_message(ws, action, payload)
|
|
520
|
+
return if ws.nil? || ws.closed?
|
|
521
|
+
|
|
512
522
|
message = [action, payload]
|
|
513
523
|
ws.send_binary(Ruflet::WireCodec.pack(message))
|
|
514
524
|
rescue StandardError => e
|
|
515
|
-
|
|
525
|
+
unless disconnect_error?(e)
|
|
526
|
+
warn "send error: #{e.class}: #{e.message}"
|
|
527
|
+
end
|
|
528
|
+
remove_session(ws)
|
|
529
|
+
unregister_connection(ws)
|
|
530
|
+
ws&.close
|
|
531
|
+
end
|
|
532
|
+
|
|
533
|
+
def disconnect_error?(error)
|
|
534
|
+
return true if error.is_a?(IOError)
|
|
535
|
+
return true if error.is_a?(Errno::EPIPE)
|
|
536
|
+
return true if error.is_a?(Errno::ECONNRESET)
|
|
537
|
+
return true if error.is_a?(Errno::ECONNABORTED)
|
|
538
|
+
return true if error.is_a?(Errno::ENOTCONN)
|
|
539
|
+
return true if error.is_a?(Errno::ESHUTDOWN)
|
|
540
|
+
return true if error.is_a?(Errno::EBADF)
|
|
541
|
+
return true if error.is_a?(Errno::EINVAL)
|
|
542
|
+
|
|
543
|
+
false
|
|
516
544
|
end
|
|
517
545
|
|
|
518
546
|
def pseudo_uuid
|
data/lib/ruflet/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ruflet_server
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- AdamMusa
|
|
@@ -15,14 +15,14 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - '='
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 0.0.
|
|
18
|
+
version: 0.0.8
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - '='
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: 0.0.
|
|
25
|
+
version: 0.0.8
|
|
26
26
|
description: Ruflet WebSocket server runtime compatible with Flet protocol.
|
|
27
27
|
email:
|
|
28
28
|
- adammusa2222@gmail.com
|