# 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'] || StringIO.new('')).read
      input  = input.dup if input.frozen?
      @stage = -1
      @body  = input.force_encoding(Encoding::BINARY)

      @headers.clear
      @headers['Upgrade'] = 'WebSocket'
      @headers['Connection'] = 'Upgrade'
      @headers['Sec-WebSocket-Origin'] = @socket.env['HTTP_ORIGIN']
      @headers['Sec-WebSocket-Location'] = @socket.url
    end

### Public Instance Methods

close(reason = nil, code = nil) click to toggle source

    # File lib/websocket/driver/draft76.rb, line 31
    def close(reason = nil, code = nil)
      return false if @ready_state == 3
      @socket.write([0xFF, 0x00].pack('C*')) if @ready_state == 1
      @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 25
    def start
      return false unless super
      send_handshake_body
      true
    end

version() click to toggle source

    # File lib/websocket/driver/draft76.rb, line 21
    def version
      'hixie-76'
    end

### Private Instance Methods

handshake_response() click to toggle source

    # File lib/websocket/driver/draft76.rb, line 41
    def handshake_response
      env     = @socket.env
      key1    = env['HTTP_SEC_WEBSOCKET_KEY1']
      key2    = env['HTTP_SEC_WEBSOCKET_KEY2']

      raise ProtocolError.new('Missing required header: Sec-WebSocket-Key1') unless key1
      raise ProtocolError.new('Missing required header: Sec-WebSocket-Key2') unless key2

      number1 = number_from_key(key1)
      spaces1 = spaces_in_key(key1)

      number2 = number_from_key(key2)
      spaces2 = spaces_in_key(key2)

      if number1 % spaces1 != 0 or number2 % spaces2 != 0
        raise ProtocolError.new('Client sent invalid Sec-WebSocket-Key headers')
      end

      @key_values = [number1 / spaces1, number2 / spaces2]

      start   = 'HTTP/1.1 101 WebSocket Protocol Handshake'
      headers = [start, @headers.to_s, '']
      headers.join("\r\n")
    end

handshake_signature() click to toggle source

    # File lib/websocket/driver/draft76.rb, line 66
    def handshake_signature
      return nil unless @body.bytesize >= BODY_SIZE

      head = @body[0...BODY_SIZE]
      Digest::MD5.digest((@key_values + [head]).pack('N2A*'))
    end

number_from_key(key) click to toggle source

    # File lib/websocket/driver/draft76.rb, line 88
    def number_from_key(key)
      number = key.scan(/[0-9]/).join('')
      number == '' ? Float::NAN : number.to_i(10)
    end

parse_leading_byte(octet) click to toggle source
Calls superclass method `WebSocket::Driver::Draft75#parse_leading_byte`

    # File lib/websocket/driver/draft76.rb, line 81
    def parse_leading_byte(octet)
      return super unless octet == 0xFF
      @closing = true
      @length  = 0
      @stage   = 1
    end

send_handshake_body() click to toggle source

    # File lib/websocket/driver/draft76.rb, line 73
    def send_handshake_body
      return unless signature = handshake_signature
      @socket.write(signature)
      @stage = 0
      open
      parse(@body[BODY_SIZE..-1]) if @body.bytesize > BODY_SIZE
    end

spaces_in_key(key) click to toggle source

    # File lib/websocket/driver/draft76.rb, line 93
    def spaces_in_key(key)
      key.scan(/ /).size
    end