Class: DEBUGGER__::UI_CDP::WebSocketClient

Inherits:
Object
  • Object
show all
Includes:
WebSocketUtils
Defined in:
lib/debug/server_cdp.rb

Instance Method Summary collapse

Methods included from WebSocketUtils

#show_protocol

Constructor Details

#initialize(s) ⇒ WebSocketClient

Returns a new instance of WebSocketClient.



287
288
289
# File 'lib/debug/server_cdp.rb', line 287

def initialize s
  @sock = s
end

Instance Method Details

#extract_dataObject



344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
# File 'lib/debug/server_cdp.rb', line 344

def extract_data
  first_group = @sock.getbyte
  fin = first_group & 0b10000000 != 128
  raise 'Unsupported' if fin
  opcode = first_group & 0b00001111
  raise "Unsupported: #{opcode}" unless opcode == 1

  second_group = @sock.getbyte
  mask = second_group & 0b10000000 == 128
  raise 'The server must not mask any frames' if mask
  payload_len = second_group & 0b01111111
  # TODO: Support other payload_lengths
  if payload_len == 126
    payload_len = @sock.read(2).unpack('n*')[0]
  end

  msg = @sock.read payload_len
  show_protocol :<, msg
  JSON.parse msg
end

#handshake(port, path) ⇒ Object



291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'lib/debug/server_cdp.rb', line 291

def handshake port, path
  key = SecureRandom.hex(11)
  req = "GET #{path} HTTP/1.1\r\nHost: 127.0.0.1:#{port}\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: #{key}==\r\n\r\n"
  show_protocol :>, req
  @sock.print req
  res = @sock.readpartial 4092
  show_protocol :<, res

  if res.match(/^Sec-WebSocket-Accept: (.*)\r\n/)
    correct_key = Digest::SHA1.base64digest "#{key}==258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
    raise "The Sec-WebSocket-Accept value: #{$1} is not valid" unless $1 == correct_key
  else
    raise "Unknown response: #{res}"
  end
end

#send(**msg) ⇒ Object



307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
# File 'lib/debug/server_cdp.rb', line 307

def send **msg
  msg = JSON.generate(msg)
  show_protocol :>, msg
  frame = Frame.new
  fin = 0b10000000
  opcode = 0b00000001
  frame.char fin + opcode

  mask = 0b10000000 # A client must mask all frames in a WebSocket Protocol.
  bytesize = msg.bytesize
  if bytesize < 126
    payload_len = bytesize
    frame.char mask + payload_len
  elsif bytesize < 2 ** 16
    payload_len = 0b01111110
    frame.char mask + payload_len
    frame.uint16 bytesize
  elsif bytesize < 2 ** 64
    payload_len = 0b01111111
    frame.char mask + payload_len
    frame.ulonglong bytesize
  else
    raise 'Bytesize is too big.'
  end

  masking_key = 4.times.map{
    key = rand(1..255)
    frame.char key
    key
  }
  msg.bytes.each_with_index do |b, i|
    frame.char(b ^ masking_key[i % 4])
  end

  @sock.print frame.b
end