1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
|
module WebSocket
class Driver
class Server < Driver
EVENTS = %w[open message error close]
def initialize(socket, options = {})
super
@http = HTTP::Request.new
@delegate = nil
end
def env
@http.complete? ? @http.env : nil
end
def url
return nil unless e = env
url = "ws://#{e['HTTP_HOST']}"
url << e['PATH_INFO']
url << "?#{e['QUERY_STRING']}" unless e['QUERY_STRING'] == ''
url
end
%w[add_extension set_header start frame text binary ping close].each do |method|
define_method(method) do |*args, &block|
if @delegate
@delegate.__send__(method, *args, &block)
else
@queue << [method, args, block]
true
end
end
end
%w[protocol version].each do |method|
define_method(method) do
@delegate && @delegate.__send__(method)
end
end
def parse(chunk)
return @delegate.parse(chunk) if @delegate
@http.parse(chunk)
return fail_request('Invalid HTTP request') if @http.error?
return unless @http.complete?
@delegate = Driver.rack(self, @options)
open
EVENTS.each do |event|
@delegate.on(event) { |e| emit(event, e) }
end
emit(:connect, ConnectEvent.new)
end
def write(buffer)
@socket.write(Driver.encode(buffer, :binary))
end
private
def fail_request(message)
emit(:error, ProtocolError.new(message))
emit(:close, CloseEvent.new(Hybi::ERRORS[:protocol_error], message))
end
def open
@queue.each do |method, args, block|
@delegate.__send__(method, *args, &block)
end
@queue = []
end
end
end
end
|