mirror of
https://github.com/faye/websocket-driver-ruby.git
synced 2025-11-01 13:59:38 +00:00
102 lines
2.4 KiB
Ruby
102 lines
2.4 KiB
Ruby
module WebSocket
|
|
class Driver
|
|
|
|
class Draft75 < Driver
|
|
def initialize(socket, options = {})
|
|
super
|
|
@stage = 0
|
|
|
|
@headers['Upgrade'] = 'WebSocket'
|
|
@headers['Connection'] = 'Upgrade'
|
|
@headers['WebSocket-Origin'] = @socket.env['HTTP_ORIGIN']
|
|
@headers['WebSocket-Location'] = @socket.url
|
|
end
|
|
|
|
def version
|
|
'hixie-75'
|
|
end
|
|
|
|
def close(reason = nil, code = nil)
|
|
return false if @ready_state == 3
|
|
@ready_state = 3
|
|
emit(:close, CloseEvent.new(nil, nil))
|
|
true
|
|
end
|
|
|
|
def parse(buffer)
|
|
return if @ready_state > 1
|
|
|
|
@reader.put(buffer)
|
|
|
|
@reader.each_byte do |data|
|
|
case @stage
|
|
when -1 then
|
|
@body << data
|
|
send_handshake_body
|
|
|
|
when 0 then
|
|
parse_leading_byte(data)
|
|
|
|
when 1 then
|
|
value = (data & 0x7F)
|
|
@length = value + 128 * @length
|
|
|
|
if @closing and @length.zero?
|
|
return close
|
|
elsif (0x80 & data) != 0x80
|
|
if @length.zero?
|
|
@stage = 0
|
|
else
|
|
@skipped = 0
|
|
@stage = 2
|
|
end
|
|
end
|
|
|
|
when 2 then
|
|
if data == 0xFF
|
|
@stage = 0
|
|
emit(:message, MessageEvent.new(Driver.encode(@buffer, :utf8)))
|
|
else
|
|
if @length
|
|
@skipped += 1
|
|
@stage = 0 if @skipped == @length
|
|
else
|
|
@buffer << data
|
|
return close if @buffer.size > @max_length
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def frame(data, type = nil, error_type = nil)
|
|
return queue([data, type, error_type]) if @ready_state == 0
|
|
frame = ["\x00", data, "\xFF"].map { |s| Driver.encode(s, :binary) } * ''
|
|
@socket.write(Driver.encode(frame, :binary))
|
|
true
|
|
end
|
|
|
|
private
|
|
|
|
def handshake_response
|
|
start = 'HTTP/1.1 101 Web Socket Protocol Handshake'
|
|
headers = [start, @headers.to_s, '']
|
|
headers.join("\r\n")
|
|
end
|
|
|
|
def parse_leading_byte(data)
|
|
if (0x80 & data) == 0x80
|
|
@length = 0
|
|
@stage = 1
|
|
else
|
|
@length = nil
|
|
@skipped = nil
|
|
@buffer = []
|
|
@stage = 2
|
|
end
|
|
end
|
|
end
|
|
|
|
end
|
|
end
|