# Get a frame's information
private fun read_frame_info do
var fst_byte = origin.read_byte
var snd_byte = origin.read_byte
if fst_byte < 0 or snd_byte < 0 then
last_error = new IOError("Error: bad frame")
close
return
end
# First byte in msg is formatted this way :
# |(fin - 1bit)|(RSV1 - 1bit)|(RSV2 - 1bit)|(RSV3 - 1bit)|(opcode - 4bits)
# fin = Flag indicating if current frame is the last one for the current message
# RSV1/2/3 = Extension flags, unsupported
# Opcode values :
# %x0 denotes a continuation frame
# %x1 denotes a text frame
# %x2 denotes a binary frame
# %x3-7 are reserved for further non-control frames
# %x8 denotes a connection close
# %x9 denotes a ping
# %xA denotes a pong
# %xB-F are reserved for further control frames
var opcode = fst_byte & 0b0000_1111
if opcode == 9 then
origin.write_bytes(pong_msg)
return
end
if opcode == 8 then
close
return
end
frame_type = opcode
# Second byte is formatted this way :
# |(mask - 1bit)|(payload length - 7 bits)
# As specified, if the payload length is 126 or 127
# The next 16 or 64 bits contain an extended payload length
var mask_flag = snd_byte & 0b1000_0000
var len = snd_byte & 0b0111_1111
var payload_ext_len = 0
if len == 126 then
var tmp = origin.read_bytes(2)
if tmp.length != 2 then
last_error = new IOError("Error: received interrupted frame")
origin.close
return
end
payload_ext_len += tmp[0].to_i << 8
payload_ext_len += tmp[1].to_i
else if len == 127 then
var tmp = origin.read_bytes(8)
if tmp.length != 8 then
last_error = new IOError("Error: received interrupted frame")
origin.close
return
end
for i in [0 .. 8[ do
payload_ext_len += tmp[i].to_i << (8 * (7 - i))
end
end
if mask_flag != 0 then
origin.read_bytes_to_cstring(mask, 4)
has_mask = true
else
mask.memset(0, 4)
has_mask = false
end
if payload_ext_len != 0 then
len = payload_ext_len
end
frame_length = len
frame_cursor = 0
end
lib/websocket/websocket.nit:174,2--245,4