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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d1274808d06afdf7dcc85a83667fdc9f5933ea3ee875a3b7e511062cc62e9aa7
4
- data.tar.gz: 883096dfec88b4bbbe11f964cfe430f418bb1b8827c81a063677882ac1b4d595
3
+ metadata.gz: 2c35513240e60fcb581c31fd046248670f30e035c6c775d6308e55b573cad7f4
4
+ data.tar.gz: ae14a3359d2f0ef9d07f46c01a48387993c1aaa85f7432a5c36a98a09f37d752
5
5
  SHA512:
6
- metadata.gz: a5511a185183913576248cda98b30d3e3a2ad1e81aff6491720b6c9d92c612ea7167a4e06d001aec31beae22df21f9fb3ef502275a1db447e23dca799258d374
7
- data.tar.gz: a35ab333a4b059adf63d5727c93a388499bd00bec390b2f8e5f402b1d90ea59b364f1ef6e5ed38cb81ed072bc3f31b2706efc14f5f3163759de3988b226a812e
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
- warn "Requested port #{requested} is busy; bound to #{@port}" if @port != requested
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
- return unless websocket_upgrade_request?(path, headers)
161
-
162
- send_handshake_response(socket, headers["sec-websocket-key"])
163
- ws = Ruflet::WebSocketConnection.new(socket)
164
- run_connection(ws)
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)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ruflet
4
- VERSION = "0.0.3" unless const_defined?(:VERSION)
4
+ VERSION = "0.0.5" unless const_defined?(:VERSION)
5
5
  end
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.3
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.3
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.3
25
+ version: 0.0.5
26
26
  description: Ruflet WebSocket server runtime compatible with Flet protocol.
27
27
  email:
28
28
  - adammusa2222@gmail.com