class WebSocketRb::Service::ReadFrameService

Public Class Methods

new(conn) click to toggle source
# File lib/web_socket_rb/service/read_frame_service.rb, line 7
def initialize(conn)
  @conn  = conn
  @frame = WebSocketRb::Wrapper::FrameBase.new
end

Public Instance Methods

run() click to toggle source

Read socket and return new frame

# File lib/web_socket_rb/service/read_frame_service.rb, line 13
def run
  # 1st byte
  read_fin_rsv_opcode
  # 2nd byte
  read_mask_payload_len
  # Optionally: 3rd - 10th byte
  read_ext_payload_len
  # Optionally: Masking-key
  read_masking_key
  # Payload data
  read_payload_data
  # Return frame
  @frame
rescue Error
  nil
end

Private Instance Methods

log_readed_data() click to toggle source
# File lib/web_socket_rb/service/read_frame_service.rb, line 79
def log_readed_data
  [:fin, :rsv1, :rsv2, :rsv3, :opcode, :mask, :payload_len, :masking_key, :payload_data].each do |var|
    App.logger.info('Frame structure') { "#{var}: #{send(var)}" }
  end
end
read_ext_payload_len() click to toggle source
# File lib/web_socket_rb/service/read_frame_service.rb, line 51
def read_ext_payload_len
  if @frame.payload_len == 126
    bytes = @conn.read(2)
    raise Error if bytes.nil?
    @frame.payload_len = bytes.unpack('S')
  elsif @frame.payload_len == 127
    bytes = @conn.read(8)
    raise Error if bytes.nil?
    @frame.payload_len = bytes.unpack('Q')
  end
end
read_fin_rsv_opcode() click to toggle source
# File lib/web_socket_rb/service/read_frame_service.rb, line 32
def read_fin_rsv_opcode
  byte = @conn.read(1)
  raise Error if byte.nil?
  byte          = byte.unpack('C*').first
  @frame.fin    = byte & '10000000'.to_i(2) > 0
  @frame.rsv1   = byte & '01000000'.to_i(2) > 0
  @frame.rsv2   = byte & '00100000'.to_i(2) > 0
  @frame.rsv3   = byte & '00010000'.to_i(2) > 0
  @frame.opcode = byte & '00001111'.to_i(2)
end
read_mask_payload_len() click to toggle source
# File lib/web_socket_rb/service/read_frame_service.rb, line 43
def read_mask_payload_len
  byte = @conn.read(1)
  raise Error if byte.nil?
  byte               = byte.unpack('C*').first
  @frame.mask        = byte & '10000000'.to_i(2) > 0
  @frame.payload_len = (byte & '01111111'.to_i(2)).to_i
end
read_masking_key() click to toggle source
# File lib/web_socket_rb/service/read_frame_service.rb, line 63
def read_masking_key
  if @frame.mask
    bytes = @conn.read(4)
    raise Error if bytes.nil?
    @frame.masking_key = bytes.unpack('C*')
  end
end
read_payload_data() click to toggle source
# File lib/web_socket_rb/service/read_frame_service.rb, line 71
def read_payload_data
  @frame.payload_data = @conn.read(@frame.payload_len)
  raise Error if @frame.payload_data.nil? && @frame.payload_len > 0
  @frame.payload_data = @frame.payload_data.unpack('C*').each_slice(4).map do |slice|
    slice.zip(@frame.masking_key).map { |a, b| a ^ b }
  end.flatten.pack('C*') if @frame.mask
end