Skip to content

Commit

Permalink
bye syn@v1
Browse files Browse the repository at this point in the history
  • Loading branch information
fasterthanlime committed Aug 30, 2024
1 parent 7e15f28 commit 26be2fe
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 42 deletions.
47 changes: 12 additions & 35 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion crates/loona-h2/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ HTTP/2 parser and base types
rust-version = "1.75"

[dependencies]
enum-repr = "0.2.6"
enumflags2 = "0.7.10"
nom = { version = "7.1.3", default-features = false }
buffet = { version = "0.3.0", path = "../buffet" }
Expand Down
149 changes: 143 additions & 6 deletions crates/loona-h2/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
use std::{fmt, io::Write, ops::RangeInclusive};

use byteorder::{BigEndian, WriteBytesExt};
use enum_repr::EnumRepr;

pub use enumflags2;
use enumflags2::{bitflags, BitFlags};
Expand Down Expand Up @@ -35,8 +34,7 @@ pub trait IntoPiece {
}

/// See <https://httpwg.org/specs/rfc9113.html#FrameTypes>
#[EnumRepr(type = "u8")]
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RawFrameType {
Data = 0x00,
Headers = 0x01,
Expand All @@ -50,6 +48,53 @@ pub enum RawFrameType {
Continuation = 0x09,
}

impl RawFrameType {
pub fn repr(&self) -> u8 {
*self as u8
}

pub fn from_repr(value: u8) -> Option<Self> {
match value {
0x00 => Some(RawFrameType::Data),
0x01 => Some(RawFrameType::Headers),
0x02 => Some(RawFrameType::Priority),
0x03 => Some(RawFrameType::RstStream),
0x04 => Some(RawFrameType::Settings),
0x05 => Some(RawFrameType::PushPromise),
0x06 => Some(RawFrameType::Ping),
0x07 => Some(RawFrameType::GoAway),
0x08 => Some(RawFrameType::WindowUpdate),
0x09 => Some(RawFrameType::Continuation),
_ => None,
}
}
}

#[test]
fn test_raw_frame_type_roundtrip() {
let variants = [
RawFrameType::Data,
RawFrameType::Headers,
RawFrameType::Priority,
RawFrameType::RstStream,
RawFrameType::Settings,
RawFrameType::PushPromise,
RawFrameType::Ping,
RawFrameType::GoAway,
RawFrameType::WindowUpdate,
RawFrameType::Continuation,
];

for &variant in &variants {
let repr = variant as u8;
let roundtripped = RawFrameType::from_repr(repr).unwrap();
assert_eq!(variant, roundtripped, "Failed to roundtrip {:?}", variant);
}

// Test that an invalid repr returns None
assert_eq!(RawFrameType::from_repr(0xFF), None);
}

/// Typed flags for various frame types
#[derive(Debug, Clone, Copy)]
pub enum FrameType {
Expand Down Expand Up @@ -551,7 +596,6 @@ impl From<KnownErrorCode> for ErrorCode {
}
}

#[EnumRepr(type = "u32")]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum KnownErrorCode {
/// The associated condition is not a result of an error. For example, a
Expand Down Expand Up @@ -611,6 +655,61 @@ pub enum KnownErrorCode {
Http1_1Required = 0x0d,
}

impl KnownErrorCode {
pub fn from_repr(value: u32) -> Option<Self> {
match value {
0x00 => Some(KnownErrorCode::NoError),
0x01 => Some(KnownErrorCode::ProtocolError),
0x02 => Some(KnownErrorCode::InternalError),
0x03 => Some(KnownErrorCode::FlowControlError),
0x04 => Some(KnownErrorCode::SettingsTimeout),
0x05 => Some(KnownErrorCode::StreamClosed),
0x06 => Some(KnownErrorCode::FrameSizeError),
0x07 => Some(KnownErrorCode::RefusedStream),
0x08 => Some(KnownErrorCode::Cancel),
0x09 => Some(KnownErrorCode::CompressionError),
0x0a => Some(KnownErrorCode::ConnectError),
0x0b => Some(KnownErrorCode::EnhanceYourCalm),
0x0c => Some(KnownErrorCode::InadequateSecurity),
0x0d => Some(KnownErrorCode::Http1_1Required),
_ => None,
}
}

pub fn repr(&self) -> u32 {
*self as u32
}
}

#[test]
fn test_known_error_code_roundtrip() {
let error_codes = [
KnownErrorCode::NoError,
KnownErrorCode::ProtocolError,
KnownErrorCode::InternalError,
KnownErrorCode::FlowControlError,
KnownErrorCode::SettingsTimeout,
KnownErrorCode::StreamClosed,
KnownErrorCode::FrameSizeError,
KnownErrorCode::RefusedStream,
KnownErrorCode::Cancel,
KnownErrorCode::CompressionError,
KnownErrorCode::ConnectError,
KnownErrorCode::EnhanceYourCalm,
KnownErrorCode::InadequateSecurity,
KnownErrorCode::Http1_1Required,
];

for &original in &error_codes {
let repr = original.repr();
let roundtripped = KnownErrorCode::from_repr(repr).unwrap();
assert_eq!(original, roundtripped, "Failed to roundtrip {:?}", original);
}

// Test that an invalid repr returns None
assert_eq!(KnownErrorCode::from_repr(0xFF), None);
}

impl TryFrom<ErrorCode> for KnownErrorCode {
type Error = ();

Expand Down Expand Up @@ -761,8 +860,7 @@ pub enum SettingsError {
SettingsMaxFrameSizeInvalid { actual: u32 },
}

#[EnumRepr(type = "u16")]
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Setting {
HeaderTableSize = 0x01,
EnablePush = 0x02,
Expand All @@ -772,6 +870,45 @@ pub enum Setting {
MaxHeaderListSize = 0x06,
}

impl Setting {
pub fn repr(&self) -> u16 {
*self as u16
}

pub fn from_repr(value: u16) -> Option<Self> {
match value {
0x01 => Some(Setting::HeaderTableSize),
0x02 => Some(Setting::EnablePush),
0x03 => Some(Setting::MaxConcurrentStreams),
0x04 => Some(Setting::InitialWindowSize),
0x05 => Some(Setting::MaxFrameSize),
0x06 => Some(Setting::MaxHeaderListSize),
_ => None,
}
}
}

#[test]
fn test_setting_roundtrip() {
let settings = [
Setting::HeaderTableSize,
Setting::EnablePush,
Setting::MaxConcurrentStreams,
Setting::InitialWindowSize,
Setting::MaxFrameSize,
Setting::MaxHeaderListSize,
];

for &setting in &settings {
let repr = setting.repr();
let roundtripped = Setting::from_repr(repr).unwrap();
assert_eq!(setting, roundtripped, "Failed to roundtrip {:?}", setting);
}

// Test that an invalid repr returns None
assert_eq!(Setting::from_repr(0x07), None);
}

impl Settings {
pub const MAX_INITIAL_WINDOW_SIZE: u32 = (1 << 31) - 1;
pub const MAX_FRAME_SIZE_ALLOWED_RANGE: RangeInclusive<u32> = (1 << 14)..=((1 << 24) - 1);
Expand Down

0 comments on commit 26be2fe

Please sign in to comment.