Implemented WebSocket handshake
This commit is contained in:
@ -1,8 +1,15 @@
|
||||
use crate::error::*;
|
||||
use crate::http;
|
||||
|
||||
pub fn connection_handler(client: &mut http::HttpStream, req: &http::Request) {
|
||||
use base64;
|
||||
use sha1;
|
||||
|
||||
pub fn connection_handler(
|
||||
client: &mut http::HttpStream,
|
||||
req: &http::Request,
|
||||
mut res: http::Response,
|
||||
) {
|
||||
client.server_keep_alive = false;
|
||||
let mut res = http::Response::new();
|
||||
|
||||
if let http::Method::GET = req.method {
|
||||
} else {
|
||||
@ -12,7 +19,79 @@ pub fn connection_handler(client: &mut http::HttpStream, req: &http::Request) {
|
||||
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(501);
|
||||
res.status(101);
|
||||
res.send(&mut client.stream).unwrap();
|
||||
}
|
||||
|
Reference in New Issue
Block a user