@@ -3,13 +3,12 @@ use wtx::{
33 codec:: i64_string,
44 collection:: { ArrayVectorU8 , Vector } ,
55 http:: {
6- Header , KnownHeaderName , ReqResBuffer , StatusCode ,
6+ Header , HttpRecvParams , KnownHeaderName , ReqResBuffer , StatusCode ,
77 server_framework:: {
88 JsonReply , PathOwned , Router , ServerFrameworkBuilder , State , VerbatimParams , get,
99 } ,
1010 } ,
1111 misc:: Wrapper ,
12- rng:: { ChaCha20 , CryptoSeedableRng } ,
1312 sync:: Arc ,
1413} ;
1514
@@ -23,21 +22,18 @@ async fn main() -> wtx::Result<()> {
2322 let dataset = load_dataset ( ) ;
2423 let router = Router :: paths ( wtx:: paths!(
2524 ( "/baseline2" , get( endpoint_baseline2) ) ,
26- ( "/health" , get( endpoint_health) ) ,
2725 ( "/json/{count}" , get( endpoint_json) ) ,
2826 ) ) ?;
29- // HttpArena's baseline-h2c / json-h2c profiles run h2load against
30- // http://localhost:8082 with prior-knowledge h2c — no TLS. wtx's .tokio
31- // entrypoint routes through http2_tokio(), which speaks HTTP/2 cleartext
32- // from the connection preface and rejects HTTP/1.1 by construction. That
33- // satisfies validate.sh's anti-cheat: the h2c port must not dual-serve h1.
34- ServerFrameworkBuilder :: new ( ChaCha20 :: from_std_random ( ) ?, router)
35- . with_conn_aux ( move |_| Ok ( ConnAux { dataset : dataset. clone ( ) } ) )
27+ ServerFrameworkBuilder :: new ( HttpRecvParams :: with_permissive_params ( ) , router)
28+ . with_conn_aux ( move || Ok ( ConnAux { dataset : dataset. clone ( ) } ) )
3629 . tokio (
3730 "0.0.0.0:8082" ,
3831 |_error| { } ,
3932 |_| Ok ( ( ) ) ,
40- |_| Ok ( ( ) ) ,
33+ |stream| {
34+ stream. set_nodelay ( true ) ?;
35+ Ok ( ( ) )
36+ } ,
4137 |_error| { } ,
4238 )
4339 . await
@@ -46,53 +42,33 @@ async fn main() -> wtx::Result<()> {
4642async fn endpoint_baseline2 (
4743 state : State < ' _ , ConnAux , ( ) , ReqResBuffer > ,
4844) -> wtx:: Result < VerbatimParams > {
49- // h2load sends GET /baseline2?a=1&b=1 with empty body. Sum integer
50- // values from the query string; non-integer values silently skip
51- // (matches the reference nginx/h2o/actix contracts).
5245 let mut sum: i64 = 0 ;
53- for ( _k, v) in state. req . rrd . uri . query_params ( ) {
54- if let Ok ( n) = v. parse :: < i64 > ( ) {
55- sum = sum. wrapping_add ( n) ;
56- }
46+ for ( _, value) in state. req . rrd . uri . query_params ( ) {
47+ sum = sum. wrapping_add ( value. parse ( ) ?) ;
5748 }
5849 state. req . rrd . clear ( ) ;
5950 state. req . rrd . body . extend_from_copyable_slice ( i64_string ( sum) . as_bytes ( ) ) ?;
60- state. req . rrd . headers . push_from_iter ( Header :: from_name_and_value (
61- KnownHeaderName :: Server . into ( ) ,
62- [ "wtx" ] ,
63- ) ) ?;
64- state. req . rrd . headers . push_from_iter ( Header :: from_name_and_value (
65- KnownHeaderName :: ContentType . into ( ) ,
66- [ "text/plain" ] ,
67- ) ) ?;
51+ state. req . rrd . headers . push_from_iter_many ( [
52+ Header :: from_name_and_value ( KnownHeaderName :: ContentType . into ( ) , [ "text/plain" ] . into_iter ( ) ) ,
53+ Header :: from_name_and_value ( KnownHeaderName :: Server . into ( ) , [ "wtx" ] . into_iter ( ) )
54+ ] ) ?;
6855 Ok ( VerbatimParams ( StatusCode :: Ok ) )
6956}
7057
71- async fn endpoint_health ( ) { }
72-
7358async fn endpoint_json (
7459 state : State < ' _ , ConnAux , ( ) , ReqResBuffer > ,
7560 PathOwned ( count) : PathOwned < usize > ,
7661) -> wtx:: Result < JsonReply > {
77- // Contract: GET /json/{count}?m={multiplier}
78- // - Take first `count` items from /data/dataset.json (clamped to len)
79- // - For each item, compute total = price × quantity × m
80- // - Serialize {items, count} as JSON per request (no cache — tuned
81- // rules in docs/test-profiles/h1/isolated/json-processing forbid
82- // pre-computed response caches).
83- let m: i64 = state
84- . req
85- . rrd
86- . uri
87- . query_params ( )
88- . find ( |( k, _) | * k == "m" )
89- . and_then ( |( _, v) | v. parse ( ) . ok ( ) )
90- . unwrap_or ( 1 ) ;
62+ let mut m: f64 = 1.0 ;
63+ for ( key, value) in state. req . rrd . uri . query_params ( ) {
64+ if key != "m" {
65+ continue ;
66+ }
67+ m = f64:: from ( value. parse :: < i32 > ( ) ?) ;
68+ break ;
69+ }
9170 let dataset_len = state. conn_aux . dataset . len ( ) ;
9271 let clamped = if count > dataset_len { dataset_len } else { count } ;
93- let m_f = m as f64 ;
94- // Drop the request headers/body before composing the response so client
95- // request headers (user-agent, accept, …) don't echo back to the caller.
9672 state. req . rrd . clear ( ) ;
9773 let items = state. conn_aux . dataset . iter ( ) . take ( clamped) . map ( move |el| {
9874 Ok ( ProcessedItem {
@@ -104,15 +80,13 @@ async fn endpoint_json(
10480 active : el. active ,
10581 tags : ArrayVectorU8 :: from_iterator ( el. tags . iter ( ) . map ( |el| el. as_str ( ) ) ) ?,
10682 rating : RatingOut { score : el. rating . score , count : el. rating . count } ,
107- total : el. price * ( el. quantity as f64 ) * m_f ,
83+ total : el. price * el. quantity * m ,
10884 } )
10985 } ) ;
11086 let resp = JsonResponse { count : clamped, items : Wrapper ( items) } ;
11187 serde_json:: to_writer ( & mut state. req . rrd . body , & resp) . unwrap_or_default ( ) ;
112- state. req . rrd . headers . push_from_iter ( Header :: from_name_and_value (
113- KnownHeaderName :: Server . into ( ) ,
114- [ "wtx" ] ,
115- ) ) ?;
88+ let header = Header :: from_name_and_value ( KnownHeaderName :: Server . into ( ) , [ "wtx" ] ) ;
89+ state. req . rrd . headers . push_from_iter ( header) ?;
11690 Ok ( JsonReply ( StatusCode :: Ok ) )
11791}
11892
@@ -130,7 +104,7 @@ struct DatasetItem {
130104 name : String ,
131105 category : String ,
132106 price : f64 ,
133- quantity : i64 ,
107+ quantity : f64 ,
134108 active : bool ,
135109 tags : ArrayVectorU8 < String , 6 > ,
136110 rating : Rating ,
@@ -153,7 +127,7 @@ struct ProcessedItem<'any> {
153127 name : & ' any str ,
154128 category : & ' any str ,
155129 price : f64 ,
156- quantity : i64 ,
130+ quantity : f64 ,
157131 active : bool ,
158132 tags : ArrayVectorU8 < & ' any str , 6 > ,
159133 rating : RatingOut ,
0 commit comments