Files
locutus-server/src/websocket/mod.rs

98 lines
3.0 KiB
Rust

use crate::error::*;
use crate::http;
use base64;
use sha1;
pub fn connection_handler(
client: &mut http::HttpStream,
req: &http::Request,
mut res: http::Response,
) {
client.server_keep_alive = false;
if let http::Method::GET = req.method {
} else {
res.status(405);
res.add_header("Allow", "GET");
res.send(&mut client.stream).unwrap();
return;
}
if let Some(connection) = req.find_header("Connection") {
if !connection.eq_ignore_ascii_case("upgrade") {
return http::error_handler(
client,
res,
Error::new(Kind::WebSocketError, Class::ClientError)
.set_desc("invalid value for header field 'Connection'".to_string()),
);
}
} else {
return http::error_handler(
client,
res,
Error::new(Kind::WebSocketError, Class::ClientError)
.set_desc("unable to find header field 'Connection'".to_string()),
);
}
if let Some(upgrade) = req.find_header("Upgrade") {
if !upgrade.eq_ignore_ascii_case("websocket") {
return http::error_handler(
client,
res,
Error::new(Kind::WebSocketError, Class::ClientError)
.set_desc("invalid value for header field 'Upgrade'".to_string()),
);
}
} else {
return http::error_handler(
client,
res,
Error::new(Kind::WebSocketError, Class::ClientError)
.set_desc("unable to find header field 'Upgrade'".to_string()),
);
}
if let Some(version) = req.find_header("Sec-WebSocket-Version") {
if !version.eq("13") {
return http::error_handler(
client,
res,
Error::new(Kind::WebSocketError, Class::ClientError)
.set_desc("invalid value for header field 'Sec-WebSocket-Key'".to_string()),
);
}
} else {
return http::error_handler(
client,
res,
Error::new(Kind::WebSocketError, Class::ClientError)
.set_desc("unable to find header field 'Sec-WebSocket-Version'".to_string()),
);
}
if let Some(key) = req.find_header("Sec-WebSocket-Key") {
let mut hasher = sha1::Sha1::new();
hasher.update(key.as_bytes());
hasher.update("258EAFA5-E914-47DA-95CA-C5AB0DC85B11".as_bytes());
let key = base64::encode(hasher.digest().bytes());
res.add_header("Sec-WebSocket-Accept", key.as_str());
} else {
return http::error_handler(
client,
res,
Error::new(Kind::WebSocketError, Class::ClientError)
.set_desc("unable to find header field 'Sec-WebSocket-Key'".to_string()),
);
}
res.add_header("Connection", "Upgrade");
res.add_header("Upgrade", "websocket");
// TODO implement websocket
res.status(101);
res.send(&mut client.stream).unwrap();
}