class WebSocket::Driver::Draft76

Constants

BODY_SIZE

Public Class Methods

new(socket, options = {}) click to toggle source
Calls superclass method WebSocket::Driver::Draft75.new
# File lib/websocket/driver/draft76.rb, line 7
def initialize(socket, options = {})
  super
  input  = @socket.env['rack.input']
  @stage = -1
  @body  = input ? input.read.bytes.to_a : []
end

Public Instance Methods

close(reason = nil, code = nil) click to toggle source
# File lib/websocket/driver/draft76.rb, line 24
def close(reason = nil, code = nil)
  return false if @ready_state == 3
  @socket.write(Driver.encode("\xFF\x00", :binary))
  @ready_state = 3
  emit(:close, CloseEvent.new(nil, nil))
  true
end
start() click to toggle source
Calls superclass method WebSocket::Driver#start
# File lib/websocket/driver/draft76.rb, line 18
def start
  return false unless super
  send_handshake_body
  true
end
version() click to toggle source
# File lib/websocket/driver/draft76.rb, line 14
def version
  'hixie-76'
end

Private Instance Methods

big_endian(number) click to toggle source
# File lib/websocket/driver/draft76.rb, line 87
def big_endian(number)
  string = ''
  [24, 16, 8, 0].each do |offset|
    string << (number >> offset & 0xFF).chr
  end
  string
end
handshake_response() click to toggle source
# File lib/websocket/driver/draft76.rb, line 34
def handshake_response
  upgrade =  "HTTP/1.1 101 WebSocket Protocol Handshake\r\n"
  upgrade << "Upgrade: WebSocket\r\n"
  upgrade << "Connection: Upgrade\r\n"
  upgrade << "Sec-WebSocket-Origin: #{@socket.env['HTTP_ORIGIN']}\r\n"
  upgrade << "Sec-WebSocket-Location: #{@socket.url}\r\n"
  upgrade << @headers.to_s
  upgrade << "\r\n"
  upgrade
end
handshake_signature() click to toggle source
# File lib/websocket/driver/draft76.rb, line 45
def handshake_signature
  return nil unless @body.size >= BODY_SIZE

  head = @body[0...BODY_SIZE].pack('C*')
  head.force_encoding('ASCII-8BIT') if head.respond_to?(:force_encoding)

  env = @socket.env

  key1   = env['HTTP_SEC_WEBSOCKET_KEY1']
  value1 = number_from_key(key1) / spaces_in_key(key1)

  key2   = env['HTTP_SEC_WEBSOCKET_KEY2']
  value2 = number_from_key(key2) / spaces_in_key(key2)

  Digest::MD5.digest(big_endian(value1) +
                     big_endian(value2) +
                     head)
end
number_from_key(key) click to toggle source
# File lib/websocket/driver/draft76.rb, line 79
def number_from_key(key)
  key.scan(/[0-9]/).join('').to_i(10)
end
parse_leading_byte(data) click to toggle source
# File lib/websocket/driver/draft76.rb, line 72
def parse_leading_byte(data)
  return super unless data == 0xFF
  @closing = true
  @length = 0
  @stage = 1
end
send_handshake_body() click to toggle source
# File lib/websocket/driver/draft76.rb, line 64
def send_handshake_body
  return unless signature = handshake_signature
  @socket.write(Driver.encode(signature, :binary))
  @stage = 0
  open
  parse(@body[BODY_SIZE..-1]) if @body.size > BODY_SIZE
end
spaces_in_key(key) click to toggle source
# File lib/websocket/driver/draft76.rb, line 83
def spaces_in_key(key)
  key.scan(/ /).size
end