pub(crate) const H2_PREFACE: &[u8; 24] = b"PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n";
#[must_use]
pub fn is_h2_preface(input: &[u8]) -> Option<bool> {
let n = input.len().min(H2_PREFACE.len());
if input[..n] != H2_PREFACE[..n] {
return Some(false);
}
if n == H2_PREFACE.len() {
Some(true)
} else {
None
}
}
#[cfg(test)]
mod tests {
use alloc::vec::Vec;
use super::*;
#[test]
fn test_is_h2_preface_every_prefix_length() {
for len in 0..H2_PREFACE.len() {
assert_eq!(is_h2_preface(&H2_PREFACE[..len]), None, "{len}");
}
assert_eq!(is_h2_preface(H2_PREFACE), Some(true));
let mut more = H2_PREFACE.to_vec();
more.extend_from_slice(b"\x00\x00\x12\x04");
assert_eq!(is_h2_preface(&more), Some(true));
}
#[test]
fn test_is_h2_preface_any_differing_byte_is_false() {
for at in 0..H2_PREFACE.len() {
let mut bad: Vec<u8> = H2_PREFACE.to_vec();
bad[at] ^= 0x20;
assert_eq!(is_h2_preface(&bad), Some(false), "{at}");
assert_eq!(is_h2_preface(&bad[..=at]), Some(false), "{at}");
}
assert_eq!(is_h2_preface(b"PRI * HTTP/1.1\r\n\r\n"), Some(false));
}
}