sark-h2 0.26.3

Fiber-free HTTP/2 protocol primitives and manifold server for sark
use sark_core::manifold::stream::Boundary;
use sark_h2::{
    ServerRole,
    conn::{CLIENT_PREFACE, event::Event, machine::Connection},
    frame::{
        Ack, Block,
        layout::Headers,
        payload::{Continuation, Ping},
    },
    hpack::encode::Encoder,
    stream::Id,
};
use sark_http::field::metadata::map::record::Entry;

#[test]
fn reads_split_headers() {
    let encoder = Encoder::try_new(4096);
    let mut encoder = encoder.expect("test operation must succeed");
    let mut block = Vec::new();
    encoder
        .try_encode(
            [
                Entry::new(b":method", b"GET"),
                Entry::new(b":scheme", b"http"),
                Entry::new(b":authority", b"x"),
                Entry::new(b":path", b"/"),
                Entry::new(b"x-fragments", b"retained"),
            ],
            &mut block,
        )
        .expect("HPACK table");
    assert!(block.len() > 2);
    let mut wire = CLIENT_PREFACE.to_vec();
    wire.extend_from_slice(&[0, 0, 0, 4, 0, 0, 0, 0, 0]);
    let first = Headers::new(
        Id::FIRST_CLIENT,
        Boundary::End,
        Block::More,
        None,
        &block[..1],
    );
    let first = first.expect("test owner must be present");
    (first.encode(&mut wire))
        .as_ref()
        .expect("test operation must succeed");
    let last = block.len() - 1;
    for (part, end) in [(&block[1..last], Block::More), (&block[last..], Block::End)] {
        let next = Continuation::new(Id::FIRST_CLIENT, end, part);
        let next = next.expect("test owner must be present");
        (next.encode(&mut wire))
            .as_ref()
            .expect("test operation must succeed");
    }
    for width in [1, 2, 3, 5, 8, 9, 13, 32, 128] {
        let server = Connection::<ServerRole>::try_new();
        let mut server = server.expect("test operation must succeed");
        for part in wire.chunks(width) {
            assert!(
                server.ingress().ingest(part).is_ok(),
                "test operation must succeed"
            );
        }
        let mut seen = 0;
        while let Some(event) = server.ingress().poll_event() {
            if let Event::Headers { head, .. } = event {
                let (headers, _, _) = head.into_parts();
                assert_eq!(headers.get(b"x-fragments"), Some(b"retained".as_slice()));
                seen += 1;
            }
        }
        assert_eq!(seen, 1, "input chunk size {width}");
    }
}

#[test]
fn skips_split_extensions() {
    let mut wire = CLIENT_PREFACE.to_vec();
    wire.extend_from_slice(&[0, 0, 0, 4, 0, 0, 0, 0, 0]);
    wire.extend_from_slice(&[0, 0, 4, 254, 0, 0, 0, 0, 0, 1, 2, 3, 4]);
    (Ping {
        ack: Ack::Required,
        opaque: [7; 8],
    }
    .encode(&mut wire))
    .as_ref()
    .expect("test operation must succeed");
    for width in 1..=17 {
        let server = Connection::<ServerRole>::try_new();
        let mut server = server.expect("test operation must succeed");
        for part in wire.chunks(width) {
            assert!(
                server.ingress().ingest(part).is_ok(),
                "test operation must succeed"
            );
        }
        let mut seen = 0;
        while let Some(event) = server.ingress().poll_event() {
            if let Event::Ping { opaque, .. } = event {
                assert_eq!(opaque, [7; 8]);
                seen += 1;
            }
        }
        assert_eq!(seen, 1, "input chunk size {width}");
    }
}