ruflet_server 0.0.3 → 0.0.5
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/wire_codec.rb +11 -0
- data/lib/ruflet/server.rb +102 -6
- 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: 2c35513240e60fcb581c31fd046248670f30e035c6c775d6308e55b573cad7f4
|
|
4
|
+
data.tar.gz: ae14a3359d2f0ef9d07f46c01a48387993c1aaa85f7432a5c36a98a09f37d752
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: af605adfe624b0bd74c0ce6e81a50c962829ac4a145e32e83ea50418798b9d4488dec2961bb4e41d67a8a4d5f28b9f6fd09d287aafc966c09753b6816ada476b
|
|
7
|
+
data.tar.gz: cf036c4fc05472ad511ab5a576cf6057a1f5b08d3c40958a8ce3a244228ab440fee99af2cf30964b06793f4e87f382b20c84f9a480876d6b50bcdf0dc8e51a64
|
|
@@ -132,6 +132,12 @@ module Ruflet
|
|
|
132
132
|
when 0xdd then read_array(reader, reader.read_u32)
|
|
133
133
|
when 0xde then read_map(reader, reader.read_u16)
|
|
134
134
|
when 0xdf then read_map(reader, reader.read_u32)
|
|
135
|
+
when 0xc7
|
|
136
|
+
read_ext(reader, reader.read_u8)
|
|
137
|
+
when 0xc8
|
|
138
|
+
read_ext(reader, reader.read_u16)
|
|
139
|
+
when 0xc9
|
|
140
|
+
read_ext(reader, reader.read_u32)
|
|
135
141
|
else
|
|
136
142
|
if (marker & 0xf0) == 0x90
|
|
137
143
|
read_array(reader, marker & 0x0f)
|
|
@@ -157,6 +163,11 @@ module Ruflet
|
|
|
157
163
|
end
|
|
158
164
|
out
|
|
159
165
|
end
|
|
166
|
+
|
|
167
|
+
def read_ext(reader, size)
|
|
168
|
+
reader.read_i8 # type (ignored)
|
|
169
|
+
reader.read_exact(size)
|
|
170
|
+
end
|
|
160
171
|
end
|
|
161
172
|
|
|
162
173
|
class ByteReader
|
data/lib/ruflet/server.rb
CHANGED
|
@@ -61,7 +61,9 @@ module Ruflet
|
|
|
61
61
|
begin
|
|
62
62
|
@server_socket = TCPServer.new(@host, candidate)
|
|
63
63
|
@port = candidate
|
|
64
|
-
|
|
64
|
+
if @port != requested && ENV["RUFLET_SUPPRESS_SERVER_BANNER"] != "1"
|
|
65
|
+
warn "Requested port #{requested} is busy; bound to #{@port}"
|
|
66
|
+
end
|
|
65
67
|
return
|
|
66
68
|
rescue Errno::EADDRINUSE
|
|
67
69
|
candidate += 1
|
|
@@ -157,11 +159,13 @@ module Ruflet
|
|
|
157
159
|
ws = nil
|
|
158
160
|
begin
|
|
159
161
|
path, headers = read_http_upgrade_request(socket)
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
162
|
+
if websocket_upgrade_request?(path, headers)
|
|
163
|
+
send_handshake_response(socket, headers["sec-websocket-key"])
|
|
164
|
+
ws = Ruflet::WebSocketConnection.new(socket)
|
|
165
|
+
run_connection(ws)
|
|
166
|
+
else
|
|
167
|
+
handle_http_request(socket, path)
|
|
168
|
+
end
|
|
165
169
|
rescue StandardError => e
|
|
166
170
|
warn "server error: #{e.class}: #{e.message}"
|
|
167
171
|
warn e.backtrace.join("\n") if e.backtrace
|
|
@@ -221,6 +225,91 @@ module Ruflet
|
|
|
221
225
|
true
|
|
222
226
|
end
|
|
223
227
|
|
|
228
|
+
def handle_http_request(socket, path)
|
|
229
|
+
case path
|
|
230
|
+
when "/health"
|
|
231
|
+
write_http_response(socket, 200, "text/plain", "ok")
|
|
232
|
+
when "/"
|
|
233
|
+
write_http_response(socket, 200, "text/plain", "ruflet server")
|
|
234
|
+
else
|
|
235
|
+
if path.start_with?("/assets/")
|
|
236
|
+
serve_asset(socket, path)
|
|
237
|
+
else
|
|
238
|
+
write_http_response(socket, 404, "text/plain", "not found")
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
rescue StandardError => e
|
|
242
|
+
warn "http error: #{e.class}: #{e.message}"
|
|
243
|
+
write_http_response(socket, 500, "text/plain", "server error")
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def serve_asset(socket, path)
|
|
247
|
+
asset_path = resolve_asset_path(path)
|
|
248
|
+
unless asset_path
|
|
249
|
+
write_http_response(socket, 404, "text/plain", "not found")
|
|
250
|
+
return
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
content = File.binread(asset_path)
|
|
254
|
+
write_http_response(socket, 200, content_type_for(asset_path), content, binary: true)
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
def resolve_asset_path(path)
|
|
258
|
+
root = assets_root
|
|
259
|
+
return nil unless root
|
|
260
|
+
|
|
261
|
+
root = File.expand_path(root)
|
|
262
|
+
relative = path.sub(%r{\A/assets/}, "")
|
|
263
|
+
full = File.expand_path(File.join(root, relative))
|
|
264
|
+
return nil unless full.start_with?(root + File::SEPARATOR) || full == root
|
|
265
|
+
return nil unless File.file?(full)
|
|
266
|
+
|
|
267
|
+
full
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
def assets_root
|
|
271
|
+
root = ENV["RUFLET_ASSETS_DIR"].to_s
|
|
272
|
+
return root unless root.empty?
|
|
273
|
+
|
|
274
|
+
default_root = File.join(Dir.pwd, "assets")
|
|
275
|
+
File.directory?(default_root) ? default_root : nil
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
def content_type_for(path)
|
|
279
|
+
case File.extname(path).downcase
|
|
280
|
+
when ".png"
|
|
281
|
+
"image/png"
|
|
282
|
+
when ".jpg", ".jpeg"
|
|
283
|
+
"image/jpeg"
|
|
284
|
+
when ".gif"
|
|
285
|
+
"image/gif"
|
|
286
|
+
when ".webp"
|
|
287
|
+
"image/webp"
|
|
288
|
+
when ".svg"
|
|
289
|
+
"image/svg+xml"
|
|
290
|
+
else
|
|
291
|
+
"application/octet-stream"
|
|
292
|
+
end
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
def write_http_response(socket, status, content_type, body, binary: false)
|
|
296
|
+
reason = {
|
|
297
|
+
200 => "OK",
|
|
298
|
+
404 => "Not Found",
|
|
299
|
+
500 => "Internal Server Error"
|
|
300
|
+
}[status] || "OK"
|
|
301
|
+
|
|
302
|
+
body_str = binary ? body : body.to_s
|
|
303
|
+
length = body_str.bytesize
|
|
304
|
+
|
|
305
|
+
socket.write("HTTP/1.1 #{status} #{reason}\r\n")
|
|
306
|
+
socket.write("Content-Type: #{content_type}\r\n")
|
|
307
|
+
socket.write("Content-Length: #{length}\r\n")
|
|
308
|
+
socket.write("Connection: close\r\n")
|
|
309
|
+
socket.write("\r\n")
|
|
310
|
+
socket.write(body_str)
|
|
311
|
+
end
|
|
312
|
+
|
|
224
313
|
def send_handshake_response(socket, key)
|
|
225
314
|
accept = [Digest::SHA1.digest("#{key}#{WEBSOCKET_GUID}")].pack("m0")
|
|
226
315
|
|
|
@@ -268,6 +357,8 @@ module Ruflet
|
|
|
268
357
|
on_control_event(ws, payload)
|
|
269
358
|
when Protocol::ACTIONS[:update_control], Protocol::ACTIONS[:update_control_props]
|
|
270
359
|
on_update_control(ws, payload)
|
|
360
|
+
when Protocol::ACTIONS[:invoke_control_method]
|
|
361
|
+
on_invoke_control_method(ws, payload)
|
|
271
362
|
else
|
|
272
363
|
raise "Unknown action: #{action.inspect}"
|
|
273
364
|
end
|
|
@@ -347,6 +438,11 @@ module Ruflet
|
|
|
347
438
|
raise
|
|
348
439
|
end
|
|
349
440
|
|
|
441
|
+
def on_invoke_control_method(_ws, _payload)
|
|
442
|
+
# Client response to invoke_control_method; no server-side handling yet.
|
|
443
|
+
nil
|
|
444
|
+
end
|
|
445
|
+
|
|
350
446
|
def on_control_event(ws, payload)
|
|
351
447
|
event = Protocol.normalize_control_event_payload(payload)
|
|
352
448
|
page = fetch_page(ws)
|
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.5
|
|
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.5
|
|
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.5
|
|
26
26
|
description: Ruflet WebSocket server runtime compatible with Flet protocol.
|
|
27
27
|
email:
|
|
28
28
|
- adammusa2222@gmail.com
|