class WebSocket::Driver
def self.client(socket, options = {})
def self.client(socket, options = {}) Client.new(socket, options.merge(:masking => true)) end
def self.encode(string, encoding = nil)
def self.encode(string, encoding = nil) case string when Array then string = string.pack('C*') encoding ||= :binary when String then encoding ||= :utf8 end encodings = {:utf8 => 'UTF-8', :binary => 'ASCII-8BIT'} string.force_encoding(encodings[encoding]) if string.respond_to?(:force_encoding) return nil if encoding == :utf8 and not valid_utf8?(string) string end
def self.rack(socket, options = {})
def self.rack(socket, options = {}) env = socket.env if env['HTTP_SEC_WEBSOCKET_VERSION'] Hybi.new(socket, options.merge(:require_masking => true)) elsif env['HTTP_SEC_WEBSOCKET_KEY1'] Draft76.new(socket, options) else Draft75.new(socket, options) end end
def self.server(socket, options = {})
def self.server(socket, options = {}) Server.new(socket, options.merge(:require_masking => true)) end
def self.valid_utf8?(string)
def self.valid_utf8?(string) if defined?(UTF8_MATCH) UTF8_MATCH =~ string ? true : false else string.valid_encoding? end end
def self.validate_options(options, valid_keys)
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
def self.websocket?(env)
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
def add_extension(extension)
def add_extension(extension) false end
def binary(message)
def binary(message) false end
def close(reason = nil, code = nil)
def close(reason = nil, code = nil) return false unless @ready_state == 1 @ready_state = 3 emit(:close, CloseEvent.new(nil, nil)) true end
def initialize(socket, options = {})
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
def open
def open @ready_state = 1 @queue.each { |message| frame(*message) } @queue = [] emit(:open, OpenEvent.new) end
def ping(*args)
def ping(*args) false end
def pong(*args)
def pong(*args) false end
def queue(message)
def queue(message) @queue << message true end
def set_header(name, value)
def set_header(name, value) return false unless @ready_state <= 0 @headers[name] = value true end
def start
def start return false unless @ready_state == 0 response = handshake_response return false unless response @socket.write(Driver.encode(response, :binary)) open unless @stage == -1 true end
def state
def state return nil unless @ready_state >= 0 STATES[@ready_state] end
def text(message)
def text(message) frame(message) end