ruflet_server 0.0.7 → 0.0.9

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: 34a06b652824d1837a37bc693722bcaeea85ff0ce8be5e3ec6bd71a3535ea520
4
- data.tar.gz: 8430980c8a035a0a5b9bb7c844469473018b1f51a8385207a1dca0902686a1da
3
+ metadata.gz: 89a4205a1319e0a391d06cd12012c51c57db414a4cc025b99a56304f25fa4c04
4
+ data.tar.gz: 65fe06aca8676dfc1411a3953276b44387ac3e3ae562e93a19757be0d72b6d82
5
5
  SHA512:
6
- metadata.gz: 0b2d54fa5da1a3c653364d90fa40ae856504565ff98959b7bce46e696e4ae5997d8f46e356c64b6f850a2cefc587bb8ab11f56cd2b357015a93b1e089e9723ae
7
- data.tar.gz: 64298fa102ecdcdb25c5829998f839511a1f22f78cda4608b5257a849a16d63bcb78b6efbb552e087587972316ecf2a6c525b1b75bfb2c9634cd4e4099936eb7
6
+ metadata.gz: 9c0c67700b28c5a95734fcfd4cb0c572214e5f9f71f3fe3d0d7c13546411f1cf4cf09f6ea460dad08b970f731865c4efd0f4d2427c22513aaa14e94d8dbfa86a
7
+ data.tar.gz: 41fed410cdafc664fe6d5c50f6261d78bbe08bf7148322f9011a437f078f78e1abf5f008aebd35fb7637b61e869832e7daf9694b8f3026a11e557da4a599b07f
@@ -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
- payload_len = read_exact(2).unpack1("n") if payload_len == 126
74
- payload_len = read_exact(8).unpack1("Q>") if payload_len == 127
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
@@ -4,7 +4,7 @@ require "digest/sha1"
4
4
  require "socket"
5
5
  require "thread"
6
6
 
7
- require "ruflet"
7
+ require "ruflet_core"
8
8
  require_relative "server/wire_codec"
9
9
  require_relative "server/web_socket_connection"
10
10
 
@@ -170,6 +170,8 @@ module Ruflet
170
170
  rescue IOError, Errno::EBADF
171
171
  nil
172
172
  rescue StandardError => e
173
+ return nil unless @running && @server_socket
174
+
173
175
  warn "accept error: #{e.class}: #{e.message}"
174
176
  warn e.backtrace.join("\n") if e.backtrace
175
177
  nil
@@ -186,6 +188,8 @@ module Ruflet
186
188
  ws = nil
187
189
  begin
188
190
  path, headers = read_http_upgrade_request(socket)
191
+ return if path.nil?
192
+
189
193
  if websocket_upgrade_request?(path, headers)
190
194
  send_handshake_response(socket, headers["sec-websocket-key"])
191
195
  ws = Ruflet::WebSocketConnection.new(socket)
@@ -194,6 +198,8 @@ module Ruflet
194
198
  handle_http_request(socket, path)
195
199
  end
196
200
  rescue StandardError => e
201
+ return if disconnect_error?(e)
202
+
197
203
  warn "server error: #{e.class}: #{e.message}"
198
204
  warn e.backtrace.join("\n") if e.backtrace
199
205
  send_message(ws, Protocol::ACTIONS[:session_crashed], { "message" => e.message.to_s.dup.force_encoding("UTF-8") }) if ws
@@ -209,6 +215,8 @@ module Ruflet
209
215
  handle_message(ws, raw)
210
216
  end
211
217
  rescue StandardError => e
218
+ return if disconnect_error?(e)
219
+
212
220
  warn "server error: #{e.class}: #{e.message}"
213
221
  warn e.backtrace.join("\n") if e.backtrace
214
222
  send_message(ws, Protocol::ACTIONS[:session_crashed], { "message" => e.message.to_s.dup.force_encoding("UTF-8") })
@@ -224,10 +232,12 @@ module Ruflet
224
232
 
225
233
  def read_http_upgrade_request(socket)
226
234
  request_line = socket.gets("\r\n")
227
- raise "Invalid HTTP request" if request_line.nil?
235
+ return [nil, {}] if request_line.nil?
236
+ return [nil, {}] unless request_line.include?(" ")
228
237
 
229
238
  method, path, _version = request_line.strip.split(" ", 3)
230
- raise "Unsupported HTTP method: #{method}" unless method == "GET"
239
+ return [nil, {}] unless method == "GET"
240
+ return [nil, {}] if path.to_s.empty?
231
241
 
232
242
  headers = {}
233
243
  loop do
@@ -509,10 +519,30 @@ module Ruflet
509
519
  end
510
520
 
511
521
  def send_message(ws, action, payload)
522
+ return if ws.nil? || ws.closed?
523
+
512
524
  message = [action, payload]
513
525
  ws.send_binary(Ruflet::WireCodec.pack(message))
514
526
  rescue StandardError => e
515
- warn "send error: #{e.class}: #{e.message}"
527
+ unless disconnect_error?(e)
528
+ warn "send error: #{e.class}: #{e.message}"
529
+ end
530
+ remove_session(ws)
531
+ unregister_connection(ws)
532
+ ws&.close
533
+ end
534
+
535
+ def disconnect_error?(error)
536
+ return true if error.is_a?(IOError)
537
+ return true if error.is_a?(Errno::EPIPE)
538
+ return true if error.is_a?(Errno::ECONNRESET)
539
+ return true if error.is_a?(Errno::ECONNABORTED)
540
+ return true if error.is_a?(Errno::ENOTCONN)
541
+ return true if error.is_a?(Errno::ESHUTDOWN)
542
+ return true if error.is_a?(Errno::EBADF)
543
+ return true if error.is_a?(Errno::EINVAL)
544
+
545
+ false
516
546
  end
517
547
 
518
548
  def pseudo_uuid
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ruflet
4
- VERSION = "0.0.7" unless const_defined?(:VERSION)
4
+ VERSION = "0.0.9" unless const_defined?(:VERSION)
5
5
  end
data/lib/ruflet_server.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "ruflet"
3
+ require "ruflet_core"
4
4
  require_relative "ruflet/server"
5
5
 
6
6
  module Ruflet
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.7
4
+ version: 0.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - AdamMusa
@@ -10,19 +10,19 @@ cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
- name: ruflet
13
+ name: ruflet_core
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
16
  - - '='
17
17
  - !ruby/object:Gem::Version
18
- version: 0.0.7
18
+ version: 0.0.9
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.7
25
+ version: 0.0.9
26
26
  description: Ruflet WebSocket server runtime compatible with Flet protocol.
27
27
  email:
28
28
  - adammusa2222@gmail.com