use courierust::courierust_bytes::BytesMut;
use courierust::courierust_crypto::md5::md5_hex;
use courierust::courierust_crypto::sha256::sha256_hex;
use courierust::courierust_h2::connection::{Config as H2Config, Connection};
use courierust::courierust_h2::priority::Priority;
use courierust::courierust_hpack::{Decoder, Encoder, HeaderField};
use courierust::courierust_http::header::{HeaderName, HeaderValue};
use std::sync::mpsc;
struct Pipe {
rx: mpsc::Receiver<Vec<u8>>,
}
struct Sink {
tx: mpsc::Sender<Vec<u8>>,
}
impl courierust::courierust_io::Read for Pipe {
fn read(&mut self, buf: &mut [u8]) -> courierust::Result<usize> {
match self.rx.try_recv() {
Ok(v) => {
let n = core::cmp::min(buf.len(), v.len());
buf[..n].copy_from_slice(&v[..n]);
Ok(n)
}
Err(_) => Ok(0), }
}
}
impl courierust::courierust_io::Write for Sink {
fn write(&mut self, buf: &[u8]) -> courierust::Result<usize> {
self.tx
.send(buf.to_vec())
.map_err(|_| courierust::Error::io("pipe closed"))?;
Ok(buf.len())
}
fn flush(&mut self) -> courierust::Result<()> {
Ok(())
}
}
fn main() -> courierust::Result<()> {
let mut enc = Encoder::new();
let mut dec = Decoder::new(4096, 1 << 20);
let fields = vec![
HeaderField::new(
HeaderName::from_lowercase(":method"),
HeaderValue::from_static("GET"),
),
HeaderField::new(
HeaderName::from_lowercase(":path"),
HeaderValue::from_static("/"),
),
HeaderField::new(
HeaderName::from_lowercase("user-agent"),
HeaderValue::from_static("courierust"),
),
];
let mut wire = BytesMut::with_capacity(64);
enc.encode(&fields, &mut wire);
let decoded = dec.decode(wire.as_slice())?;
println!(
"HPACK: encoded {} bytes -> decoded {} fields",
wire.len(),
decoded.len()
);
assert_eq!(decoded.len(), fields.len());
let (a2b, a2b_rx) = mpsc::channel::<Vec<u8>>();
let (b2a, b2a_rx) = mpsc::channel::<Vec<u8>>();
let reader = Pipe { rx: b2a_rx }; let writer = Sink { tx: a2b }; let mut conn = Connection::new(
reader,
writer,
H2Config {
client: true,
..Default::default()
},
);
let sid = conn.open_request(Priority::default())?;
conn.send_headers(sid, &fields, false)?; conn.send_data(
sid,
courierust::courierust_bytes::Bytes::from_static(b"hello"),
true,
)?;
conn.flush()?;
let sent = a2b_rx
.try_recv()
.expect("outbound bytes should be in the pipe");
println!(
"h2: stream {sid} open, {} outbound bytes written",
sent.len()
);
let _ = b2a;
println!("md5(hello) = {}", md5_hex(b"hello"));
println!("sha256(hello) = {}", sha256_hex(b"hello"));
Ok(())
}