Expose `handshake::derive_accept_key` as public API.

This commit is contained in:
Maarten de Vries 2021-02-06 18:32:54 +01:00
parent 5586d0af51
commit 96612748d1
4 changed files with 14 additions and 10 deletions

View File

@ -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

View File

@ -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<S: Read + Write> ClientHandshake<S> {
};
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 }
};

View File

@ -110,26 +110,29 @@ pub enum ProcessingResult<Stream, FinalResult> {
Done(FinalResult),
}
/// Turns a Sec-WebSocket-Key into a Sec-WebSocket-Accept.
fn convert_key(input: &[u8]) -> Result<String, Error> {
/// 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="
);
}

View File

@ -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<T>(request: &HttpRequest<T>) -> Result<Builder> {
.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)
}