98 lines
3.0 KiB
Rust
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();
|
|
}
|