From 96612748d1128b3bdcfa31ac2ccb77275f5ad569 Mon Sep 17 00:00:00 2001 From: Maarten de Vries Date: Sat, 6 Feb 2021 18:32:54 +0100 Subject: [PATCH] Expose `handshake::derive_accept_key` as public API. --- CHANGELOG.md | 1 + src/handshake/client.rs | 4 ++-- src/handshake/mod.rs | 15 +++++++++------ src/handshake/server.rs | 4 ++-- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8939190..084b1e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ - Add `CapacityError`, `UrlError`, and `ProtocolError` types to represent the different types of capacity, URL, and protocol errors respectively. - Modify variants `Error::Capacity`, `Error::Url`, and `Error::Protocol` to hold the above errors types instead of string error messages. +- Add `handshake::derive_accept_key` to facilitate external handshakes. # 0.12.0 diff --git a/src/handshake/client.rs b/src/handshake/client.rs index 92e5477..07c41c1 100644 --- a/src/handshake/client.rs +++ b/src/handshake/client.rs @@ -10,7 +10,7 @@ use httparse::Status; use log::*; use super::{ - convert_key, + derive_accept_key, headers::{FromHttparse, MAX_HEADERS}, machine::{HandshakeMachine, StageResult, TryParse}, HandshakeRole, MidHandshake, ProcessingResult, @@ -60,7 +60,7 @@ impl ClientHandshake { }; let client = { - let accept_key = convert_key(key.as_ref()).unwrap(); + let accept_key = derive_accept_key(key.as_ref()); ClientHandshake { verify_data: VerifyData { accept_key }, config, _marker: PhantomData } }; diff --git a/src/handshake/mod.rs b/src/handshake/mod.rs index 4714ee0..c2c63de 100644 --- a/src/handshake/mod.rs +++ b/src/handshake/mod.rs @@ -110,26 +110,29 @@ pub enum ProcessingResult { Done(FinalResult), } -/// Turns a Sec-WebSocket-Key into a Sec-WebSocket-Accept. -fn convert_key(input: &[u8]) -> Result { +/// Derive the `Sec-WebSocket-Accept` response header from a `Sec-WebSocket-Key` request header. +/// +/// This function can be used to perform a handshake before passing a raw TCP stream to +/// [`WebSocket::from_raw_socket`][crate::protocol::WebSocket::from_raw_socket]. +pub fn derive_accept_key(request_key: &[u8]) -> String { // ... field is constructed by concatenating /key/ ... // ... with the string "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" (RFC 6455) const WS_GUID: &[u8] = b"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; let mut sha1 = Sha1::default(); - sha1.update(input); + sha1.update(request_key); sha1.update(WS_GUID); - Ok(base64::encode(&sha1.finalize())) + base64::encode(&sha1.finalize()) } #[cfg(test)] mod tests { - use super::convert_key; + use super::derive_accept_key; #[test] fn key_conversion() { // example from RFC 6455 assert_eq!( - convert_key(b"dGhlIHNhbXBsZSBub25jZQ==").unwrap(), + derive_accept_key(b"dGhlIHNhbXBsZSBub25jZQ=="), "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=" ); } diff --git a/src/handshake/server.rs b/src/handshake/server.rs index f80c11b..fddf953 100644 --- a/src/handshake/server.rs +++ b/src/handshake/server.rs @@ -13,7 +13,7 @@ use httparse::Status; use log::*; use super::{ - convert_key, + derive_accept_key, headers::{FromHttparse, MAX_HEADERS}, machine::{HandshakeMachine, StageResult, TryParse}, HandshakeRole, MidHandshake, ProcessingResult, @@ -75,7 +75,7 @@ fn create_parts(request: &HttpRequest) -> Result { .version(request.version()) .header("Connection", "Upgrade") .header("Upgrade", "websocket") - .header("Sec-WebSocket-Accept", convert_key(key.as_bytes())?); + .header("Sec-WebSocket-Accept", derive_accept_key(key.as_bytes())); Ok(builder) }