use super::{Header, headers}; use crate::http::Limits; use std::{hint::black_box, time::Instant}; #[test] fn request_and_response_preserve_shared_body_storage() { let shared = bytes::Bytes::from(vec![0x80; 65536]); let request = hyper::Request::builder() .method("POST") .uri("/echo") .header("host", "localhost") .body(shared.clone()) .unwrap(); let request = super::request_value(request); assert_eq!(request.body.as_ptr(), shared.as_ptr()); let response = super::response_value(super::Response { status: 200, headers: Vec::new(), body: request.body, }) .unwrap(); assert_eq!(response.body().as_ptr(), shared.as_ptr()); assert_eq!(response.body(), &shared); } #[test] #[ignore = "explicit release performance probe"] fn header_buffer_cost() { let limits = Limits { header_bytes: 131072, ..Limits::default() } .check() .unwrap(); println!("\ncase,sample,iterations,elapsed_ns,checksum"); for (name, count, bytes) in [("short", 8, 32), ("wide", 32, 32), ("large", 4, 16384)] { let input = (0..count) .map(|index| Header { name: format!("x-field-{index}"), value: vec![0x80; bytes].into(), }) .collect::>(); let converted = headers(input.clone(), &limits, false, 80).unwrap(); for field in &input { assert_eq!( converted.get(field.name.as_str()).unwrap().as_bytes(), field.value ); } let convert = || { let output = headers(black_box(input.clone()), &limits, false, 80).unwrap(); black_box(output.values().map(|value| value.len()).sum::()) }; for _ in 0..100 { assert_eq!(convert(), count * bytes); } for sample in 0..15 { let started = Instant::now(); let mut checksum = 0; for _ in 0..1000 { checksum += convert(); } let elapsed = started.elapsed().as_nanos(); assert_eq!(checksum, count * bytes * 1000); println!("http_headers_{name},{sample},1000,{elapsed},{checksum}"); } } }