2020-04-08 20:44:30 +03:00
|
|
|
module websocket
|
2020-04-08 15:22:31 +03:00
|
|
|
|
2020-05-17 14:51:18 +03:00
|
|
|
fn (mut ws Client) read_handshake(seckey string){
|
2020-04-08 15:22:31 +03:00
|
|
|
l.d("reading handshake...")
|
|
|
|
mut bytes_read := 0
|
2020-04-24 08:32:51 +03:00
|
|
|
max_buffer := 1024
|
2020-04-08 15:22:31 +03:00
|
|
|
buffer_size := 1
|
|
|
|
mut buffer := malloc(max_buffer)
|
|
|
|
|
|
|
|
for bytes_read <= max_buffer {
|
|
|
|
res := ws.read_from_server(buffer + bytes_read, buffer_size)
|
2020-05-17 14:51:18 +03:00
|
|
|
if res == 0 || res == -1 {
|
2020-04-08 15:22:31 +03:00
|
|
|
l.f("read_handshake: Failed to read handshake.")
|
|
|
|
}
|
|
|
|
if buffer[bytes_read] == `\n` && buffer[bytes_read-1] == `\r` && buffer[bytes_read-2] == `\n` && buffer[bytes_read-3] == `\r` {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
bytes_read += buffer_size
|
|
|
|
}
|
|
|
|
buffer[max_buffer+1] = `\0`
|
|
|
|
ws.handshake_handler(string(byteptr(buffer)), seckey)
|
|
|
|
}
|
|
|
|
|
2020-05-17 14:51:18 +03:00
|
|
|
fn (mut ws Client) handshake_handler(handshake_response, seckey string){
|
2020-04-08 15:22:31 +03:00
|
|
|
l.d("handshake_handler:\r\n${handshake_response}")
|
|
|
|
lines := handshake_response.split_into_lines()
|
2020-05-17 14:51:18 +03:00
|
|
|
|
2020-04-08 15:22:31 +03:00
|
|
|
header := lines[0]
|
|
|
|
if !header.starts_with("HTTP/1.1 101") && !header.starts_with("HTTP/1.0 101") {
|
|
|
|
l.f("handshake_handler: invalid HTTP status response code")
|
|
|
|
}
|
|
|
|
|
|
|
|
for i in 1..lines.len {
|
|
|
|
if lines[i].len <= 0 || lines[i] == "\r\n" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
keys := lines[i].split(":")
|
|
|
|
|
|
|
|
match keys[0] {
|
2020-04-24 08:32:51 +03:00
|
|
|
"Upgrade", "upgrade" {
|
|
|
|
ws.flags << .has_upgrade
|
2020-04-08 15:22:31 +03:00
|
|
|
}
|
2020-04-24 08:32:51 +03:00
|
|
|
"Connection", "connection" {
|
|
|
|
ws.flags << .has_connection
|
2020-04-08 15:22:31 +03:00
|
|
|
}
|
2020-04-24 08:32:51 +03:00
|
|
|
"Sec-WebSocket-Accept", "sec-websocket-accept" {
|
2020-04-08 15:22:31 +03:00
|
|
|
l.d("comparing hashes")
|
2020-04-24 08:32:51 +03:00
|
|
|
l.d("seckey: ${seckey}")
|
|
|
|
challenge := create_key_challenge_response(seckey)
|
|
|
|
l.d("challenge: ${challenge}")
|
|
|
|
l.d("response: ${keys[1]}")
|
|
|
|
if keys[1].trim_space() != challenge {
|
2020-04-08 15:22:31 +03:00
|
|
|
l.e("handshake_handler: Sec-WebSocket-Accept header does not match computed sha1/base64 response.")
|
|
|
|
}
|
2020-04-24 08:32:51 +03:00
|
|
|
ws.flags << .has_accept
|
2020-04-08 15:22:31 +03:00
|
|
|
unsafe {
|
2020-04-24 08:32:51 +03:00
|
|
|
challenge.free()
|
2020-04-08 15:22:31 +03:00
|
|
|
}
|
|
|
|
} else {}
|
|
|
|
}
|
|
|
|
unsafe {
|
|
|
|
keys.free()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ws.flags.len < 3 {
|
|
|
|
ws.close(1002, "invalid websocket HTTP headers")
|
|
|
|
l.e("invalid websocket HTTP headers")
|
|
|
|
}
|
|
|
|
l.i("handshake successful!")
|
|
|
|
unsafe {
|
|
|
|
handshake_response.free()
|
|
|
|
lines.free()
|
|
|
|
header.free()
|
|
|
|
}
|
|
|
|
}
|