class WebSocket::Driver

Constants

CloseEvent
ConfigurationError
ConnectEvent
MAX_LENGTH
MessageEvent
OpenEvent
PingEvent
PongEvent
ProtocolError
STATES
URIError

Attributes

protocol[R]
ready_state[R]

Public Class Methods

new(socket, options = {}) click to toggle source
Calls superclass method WebSocket::Driver::EventEmitter::new
# File lib/websocket/driver.rb, line 71
def initialize(socket, options = {})
  super()
  Driver.validate_options(options, [:max_length, :masking, :require_masking, :protocols])

  @socket      = socket
  @reader      = StreamReader.new
  @options     = options
  @max_length  = options[:max_length] || MAX_LENGTH
  @headers     = Headers.new
  @queue       = []
  @ready_state = 0
end

Private Class Methods

client(socket, options = {}) click to toggle source
# File lib/websocket/driver.rb, line 173
def self.client(socket, options = {})
  Client.new(socket, options.merge(:masking => true))
end
encode(data, encoding = nil) click to toggle source
# File lib/websocket/driver.rb, line 197
def self.encode(data, encoding = nil)
  if Array === data
    encoding ||= Encoding::BINARY
    return data.pack('C*').force_encoding(encoding)
  end

  encoding ||= Encoding::UTF_8

  return data if data.encoding == encoding
  return data.encode(encoding) unless data.encoding == Encoding::BINARY

  data = data.dup if data.frozen?
  data.force_encoding(encoding)
end
rack(socket, options = {}) click to toggle source
# File lib/websocket/driver.rb, line 181
def self.rack(socket, options = {})
  env     = socket.env
  version = env['HTTP_SEC_WEBSOCKET_VERSION']
  key     = env['HTTP_SEC_WEBSOCKET_KEY']
  key1    = env['HTTP_SEC_WEBSOCKET_KEY1']
  key2    = env['HTTP_SEC_WEBSOCKET_KEY2']

  if version or key
    Hybi.new(socket, options.merge(:require_masking => true))
  elsif key1 or key2
    Draft76.new(socket, options)
  else
    Draft75.new(socket, options)
  end
end
server(socket, options = {}) click to toggle source
# File lib/websocket/driver.rb, line 177
def self.server(socket, options = {})
  Server.new(socket, options.merge(:require_masking => true))
end
validate_options(options, valid_keys) click to toggle source
# File lib/websocket/driver.rb, line 212
def self.validate_options(options, valid_keys)
  options.keys.each do |key|
    unless valid_keys.include?(key)
      raise ConfigurationError, "Unrecognized option: #{ key.inspect }"
    end
  end
end
websocket?(env) click to toggle source
# File lib/websocket/driver.rb, line 220
def self.websocket?(env)
  connection = env['HTTP_CONNECTION'] || ''
  upgrade    = env['HTTP_UPGRADE']    || ''

  env['REQUEST_METHOD'] == 'GET' and
  connection.downcase.split(/ *, */).include?('upgrade') and
  upgrade.downcase == 'websocket'
end

Public Instance Methods

add_extension(extension) click to toggle source
# File lib/websocket/driver.rb, line 89
def add_extension(extension)
  false
end
binary(message) click to toggle source
# File lib/websocket/driver.rb, line 122
def binary(message)
  false
end
close(reason = nil, code = nil) click to toggle source
# File lib/websocket/driver.rb, line 134
def close(reason = nil, code = nil)
  return false unless @ready_state == 1
  @ready_state = 3
  emit(:close, CloseEvent.new(nil, nil))
  true
end
ping(*args) click to toggle source
# File lib/websocket/driver.rb, line 126
def ping(*args)
  false
end
pong(*args) click to toggle source
# File lib/websocket/driver.rb, line 130
def pong(*args)
  false
end
set_header(name, value) click to toggle source
# File lib/websocket/driver.rb, line 93
def set_header(name, value)
  return false unless @ready_state <= 0
  @headers[name] = value
  true
end
start() click to toggle source
# File lib/websocket/driver.rb, line 99
def start
  return false unless @ready_state == 0

  unless Driver.websocket?(@socket.env)
    return fail_handshake(ProtocolError.new('Not a WebSocket request'))
  end

  begin
    response = handshake_response
  rescue => error
    return fail_handshake(error)
  end

  @socket.write(response)
  open unless @stage == -1
  true
end
state() click to toggle source
# File lib/websocket/driver.rb, line 84
def state
  return nil unless @ready_state >= 0
  STATES[@ready_state]
end
text(message) click to toggle source
# File lib/websocket/driver.rb, line 117
def text(message)
  message = Driver.encode(message, Encoding::UTF_8)
  frame(message, :text)
end

Private Instance Methods

fail(type, message) click to toggle source
# File lib/websocket/driver.rb, line 155
def fail(type, message)
  @ready_state = 2
  emit(:error, ProtocolError.new(message))
  close
end
fail_handshake(error) click to toggle source
# File lib/websocket/driver.rb, line 143
def fail_handshake(error)
  headers = Headers.new
  headers['Content-Type'] = 'text/plain'
  headers['Content-Length'] = error.message.bytesize

  headers = ['HTTP/1.1 400 Bad Request', headers.to_s, error.message]
  @socket.write(headers.join("\r\n"))
  fail(:protocol_error, error.message)

  false
end
open() click to toggle source
# File lib/websocket/driver.rb, line 161
def open
  @ready_state = 1
  @queue.each { |message| frame(*message) }
  @queue = []
  emit(:open, OpenEvent.new)
end
queue(message) click to toggle source
# File lib/websocket/driver.rb, line 168
def queue(message)
  @queue << message
  true
end