Skip to main content

zenith_api/
lib.rs

1//! Zenith API - 公开API与类型定义
2//!
3//! 本 crate 定义 Zenith 框架的所有公开类型、特征和接口,
4//! 是外部程序依赖的唯一入口点。
5//!
6//! # 设计原则
7//! - 热路径零堆分配:使用固定容量数组替代 String/Vec
8//! - Copy 语义:所有核心类型支持 Copy,避免昂贵的 Clone
9//! - 编译期安全:类型系统保证所有权唯一
10
11#![deny(unsafe_code)]
12#![deny(missing_debug_implementations)]
13#![warn(missing_docs)]
14
15pub mod normalize;
16
17// ---------------------------------------------------------------------------
18// 固定容量常量
19// ---------------------------------------------------------------------------
20
21/// 最大路径长度(字节)
22pub const MAX_PATH_LEN: usize = 1024;
23
24/// 最大查询字符串长度(字节)
25pub const MAX_QUERY_LEN: usize = 1024;
26
27/// 最大授权主机长度(字节)
28pub const MAX_AUTHORITY_LEN: usize = 256;
29
30/// 最大头部数量
31pub const MAX_HEADER_COUNT: usize = 32;
32
33/// 最大头部名称长度(字节)
34pub const MAX_HEADER_NAME_LEN: usize = 64;
35
36/// 最大头部值长度(字节)
37/// RFC 7230 建议整个头部块最小 8KB,单个值通常不超过 256 字节
38pub const MAX_HEADER_VALUE_LEN: usize = 256;
39
40/// 最大响应 Body 长度(字节)
41/// 小于此值的 Body 使用栈上固定数组,超过时使用堆分配
42pub const MAX_BODY_LEN: usize = 4096;
43
44// ---------------------------------------------------------------------------
45// 基础类型定义
46// ---------------------------------------------------------------------------
47
48/// 协议类型枚举
49#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
50pub enum Protocol {
51    /// HTTP/1.1 协议
52    Http1,
53    /// HTTP/2 协议
54    Http2,
55    /// HTTP/3 协议
56    Http3,
57    /// TCP 协议
58    Tcp,
59    /// UDP 协议
60    Udp,
61    /// QUIC 协议
62    Quic,
63}
64
65/// 传输层类型枚举
66#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
67pub enum Transport {
68    /// 明文传输
69    Plaintext,
70    /// TLS 1.3 加密传输
71    Tls13,
72}
73
74/// 请求方法枚举
75#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
76pub enum Method {
77    /// GET 方法
78    Get,
79    /// POST 方法
80    Post,
81    /// PUT 方法
82    Put,
83    /// DELETE 方法
84    Delete,
85    /// PATCH 方法
86    Patch,
87    /// HEAD 方法
88    Head,
89    /// OPTIONS 方法
90    Options,
91    /// CONNECT 方法
92    Connect,
93    /// TRACE 方法
94    Trace,
95}
96
97impl Method {
98    /// 获取方法的字符串表示
99    #[inline]
100    pub fn as_str(&self) -> &'static str {
101        match self {
102            Method::Get => "GET",
103            Method::Post => "POST",
104            Method::Put => "PUT",
105            Method::Delete => "DELETE",
106            Method::Patch => "PATCH",
107            Method::Head => "HEAD",
108            Method::Options => "OPTIONS",
109            Method::Connect => "CONNECT",
110            Method::Trace => "TRACE",
111        }
112    }
113}
114
115/// Method 解析错误
116#[derive(Debug, Clone, PartialEq, Eq)]
117pub struct MethodParseError(());
118
119impl std::fmt::Display for MethodParseError {
120    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
121        f.write_str("invalid HTTP method")
122    }
123}
124
125impl std::error::Error for MethodParseError {}
126
127impl std::str::FromStr for Method {
128    type Err = MethodParseError;
129
130    /// 将字符串解析为 Method(RFC 9110 严格大小写敏感)
131    ///
132    /// HTTP 方法令牌在语义上大小写敏感("GET" 与 "get" 是不同方法),
133    /// 与 `zenith_web::normalize::parse_method` 保持全库语义统一,防止
134    /// 双解析器分歧引入的规范化绕过(请求走私面)。零堆分配。
135    #[inline]
136    fn from_str(s: &str) -> Result<Self, Self::Err> {
137        // 严格精确匹配(RFC 9110 §9:method = token,大小写敏感)
138        Ok(match s {
139            "GET" => Method::Get,
140            "POST" => Method::Post,
141            "PUT" => Method::Put,
142            "DELETE" => Method::Delete,
143            "PATCH" => Method::Patch,
144            "HEAD" => Method::Head,
145            "OPTIONS" => Method::Options,
146            "CONNECT" => Method::Connect,
147            "TRACE" => Method::Trace,
148            _ => return Err(MethodParseError(())),
149        })
150    }
151}
152
153// ---------------------------------------------------------------------------
154// 规范化头条目(Copy 语义,零堆分配)
155// ---------------------------------------------------------------------------
156
157/// 规范化请求头(固定容量,Copy 语义)
158///
159/// 每个头部条目使用固定容量数组存储,避免堆分配。
160#[derive(Debug, Clone, Copy)]
161pub struct CanonicalHeader {
162    /// 头名称(最大 MAX_HEADER_NAME_LEN 字节)
163    pub name: [u8; MAX_HEADER_NAME_LEN],
164    /// 头名称实际长度
165    pub name_len: u8,
166    /// 头值(最大 MAX_HEADER_VALUE_LEN 字节)
167    pub value: [u8; MAX_HEADER_VALUE_LEN],
168    /// 头值实际长度
169    pub value_len: u16,
170}
171
172impl CanonicalHeader {
173    /// 创建空头部
174    #[inline]
175    pub const fn empty() -> Self {
176        Self {
177            name: [0u8; MAX_HEADER_NAME_LEN],
178            name_len: 0,
179            value: [0u8; MAX_HEADER_VALUE_LEN],
180            value_len: 0,
181        }
182    }
183
184    /// 重置头部(清空内容)
185    /// 用于对象池复用,避免重新创建对象的开销
186    #[inline]
187    pub fn reset(&mut self) {
188        // 不需要清零数组,后续写入会覆盖
189        self.name_len = 0;
190        self.value_len = 0;
191    }
192
193    /// 从字节切片创建头部(fail-closed)
194    ///
195    /// # Arguments
196    /// * `name` - 头名称(必须不超过 MAX_HEADER_NAME_LEN)
197    /// * `value` - 头值(必须不超过 MAX_HEADER_VALUE_LEN)
198    ///
199    /// # Returns
200    /// * `Some(CanonicalHeader)` - 创建成功
201    /// * `None` - 名称或值超长(拒绝静默截断,防止截断后语义被篡改)
202    pub fn from_bytes(name: &[u8], value: &[u8]) -> Option<Self> {
203        if name.len() > MAX_HEADER_NAME_LEN || value.len() > MAX_HEADER_VALUE_LEN {
204            return None;
205        }
206        let mut hdr = Self::empty();
207        let name_len = name.len() as u8;
208        hdr.name[..name.len()].copy_from_slice(name);
209        hdr.name_len = name_len;
210
211        let value_len = value.len() as u16;
212        hdr.value[..value.len()].copy_from_slice(value);
213        hdr.value_len = value_len;
214        Some(hdr)
215    }
216
217    /// 获取名称为字符串切片
218    #[inline]
219    pub fn name_str(&self) -> &str {
220        core::str::from_utf8(&self.name[..self.name_len as usize]).unwrap_or("")
221    }
222
223    /// 获取值为字符串切片
224    #[inline]
225    pub fn value_str(&self) -> &str {
226        core::str::from_utf8(&self.value[..self.value_len as usize]).unwrap_or("")
227    }
228
229    /// 是否为空
230    #[inline]
231    pub fn is_empty(&self) -> bool {
232        self.name_len == 0
233    }
234}
235
236// ---------------------------------------------------------------------------
237// Body 流(单消费者,借用语义)
238// ---------------------------------------------------------------------------
239
240/// Body 流(单消费者,借用语义,零拷贝)
241///
242/// Body 只能被读取一次,消费后标记为已消费。
243#[derive(Debug)]
244pub struct BodyStream<'a> {
245    /// Body 数据切片
246    data: &'a [u8],
247    /// 是否已消费
248    consumed: bool,
249}
250
251impl<'a> BodyStream<'a> {
252    /// 创建新 Body 流
253    #[inline]
254    pub fn new(data: &'a [u8]) -> Self {
255        Self {
256            data,
257            consumed: false,
258        }
259    }
260
261    /// 获取 Body 数据(仅首次调用有效)
262    ///
263    /// # Returns
264    /// * `Some(data)` - 首次调用返回数据
265    /// * `None` - 已消费或无数据
266    #[inline]
267    pub fn get_data(&mut self) -> Option<&'a [u8]> {
268        if self.consumed || self.data.is_empty() {
269            return None;
270        }
271        self.consumed = true;
272        Some(self.data)
273    }
274
275    /// 检查是否已消费
276    #[inline]
277    pub fn is_consumed(&self) -> bool {
278        self.consumed
279    }
280
281    /// 获取 Body 长度(不改变消费状态)
282    #[inline]
283    pub fn len(&self) -> usize {
284        self.data.len()
285    }
286
287    /// Body 是否为空
288    #[inline]
289    pub fn is_empty(&self) -> bool {
290        self.data.is_empty()
291    }
292}
293
294// ---------------------------------------------------------------------------
295// 规范化请求(零堆分配,固定容量,Copy 语义)
296// ---------------------------------------------------------------------------
297
298/// 统一规范化请求
299///
300/// 所有HTTP协议(HTTP/1.1、HTTP/2、HTTP/3)解析后都生成此结构,
301/// 全链路统一使用,避免协议差分攻击。
302///
303/// # 设计特点
304/// - 零堆分配(小 Body):Body <= MAX_BODY_LEN 使用栈上固定数组,避免堆分配
305/// - 大 Body 溢出:超过 MAX_BODY_LEN 时使用堆分配(Option<Vec<u8>>),保证正确性
306/// - 治理字段:generation、deadline、cancelled、resource_lease
307///
308/// # Copy 语义
309/// 由于大 Body 场景下引入了 `Option<Vec<u8>>`,CanonicalRequest 不再是 `Copy`,
310/// 仅保留 `Clone`。绝大多数小请求 (<= 4KiB body) 的 clone 开销仅为栈数组拷贝。
311#[derive(Debug, Clone)]
312pub struct CanonicalRequest {
313    /// 请求方法
314    pub method: Method,
315    /// 请求方案(http/https,固定容量)
316    scheme: [u8; 8],
317    /// 方案长度
318    scheme_len: u8,
319    /// 授权主机(固定容量)
320    authority: [u8; MAX_AUTHORITY_LEN],
321    /// 授权主机长度
322    authority_len: u16,
323    /// 规范化后的路径(固定容量)
324    normalized_path: [u8; MAX_PATH_LEN],
325    /// 路径长度
326    path_len: u16,
327    /// 规范化后的查询字符串(固定容量)
328    normalized_query: [u8; MAX_QUERY_LEN],
329    /// 查询字符串长度
330    query_len: u32,
331    /// 头部数组(固定容量)
332    headers: [CanonicalHeader; MAX_HEADER_COUNT],
333    /// 头部数量
334    header_count: u8,
335    /// 协议类型
336    pub protocol: Protocol,
337    /// 传输层类型
338    pub transport: Transport,
339    /// 代际号(用于 ChangeSet 版本控制)
340    pub generation: u64,
341    /// 截止时间(毫秒,0 表示无限制)
342    pub deadline_ms: u64,
343    /// 是否已取消
344    pub cancelled: bool,
345    /// 资源租约(令牌数,用于限流/配额)
346    pub resource_lease: u64,
347    /// 请求 Body 栈上缓冲区(<= MAX_BODY_LEN 时使用,零堆分配)
348    body_buffer: [u8; MAX_BODY_LEN],
349    /// 请求 Body 实际长度
350    body_len: u32,
351    /// 请求 Body 溢出堆缓冲区(> MAX_BODY_LEN 时使用)
352    body_overflow: Option<Vec<u8>>,
353}
354
355impl CanonicalRequest {
356    /// 创建空请求
357    pub const fn empty() -> Self {
358        Self {
359            method: Method::Get,
360            scheme: [0u8; 8],
361            scheme_len: 0,
362            authority: [0u8; MAX_AUTHORITY_LEN],
363            authority_len: 0,
364            normalized_path: [0u8; MAX_PATH_LEN],
365            path_len: 0,
366            normalized_query: [0u8; MAX_QUERY_LEN],
367            query_len: 0,
368            headers: [CanonicalHeader::empty(); MAX_HEADER_COUNT],
369            header_count: 0,
370            protocol: Protocol::Http1,
371            transport: Transport::Plaintext,
372            generation: 0,
373            deadline_ms: 0,
374            cancelled: false,
375            resource_lease: 0,
376            body_buffer: [0u8; MAX_BODY_LEN],
377            body_len: 0,
378            body_overflow: None,
379        }
380    }
381
382    /// 重置请求(清空所有字段)
383    /// 用于对象池复用,避免重新创建对象的开销
384    #[inline]
385    pub fn reset(&mut self) {
386        self.method = Method::Get;
387        self.scheme_len = 0;
388        self.authority_len = 0;
389        self.path_len = 0;
390        self.query_len = 0;
391        // 只重置使用过的头部
392        for i in 0..self.header_count as usize {
393            self.headers[i].reset();
394        }
395        self.header_count = 0;
396        self.protocol = Protocol::Http1;
397        self.transport = Transport::Plaintext;
398        self.generation = 0;
399        self.deadline_ms = 0;
400        self.cancelled = false;
401        self.resource_lease = 0;
402        // Body:不需要清零数组,后续写入会覆盖;清零堆溢出
403        self.body_len = 0;
404        self.body_overflow = None;
405    }
406
407    /// 设置请求 Body
408    ///
409    /// 性能设计:
410    /// - Body 长度 <= MAX_BODY_LEN:使用栈上缓冲区,零堆分配
411    /// - Body 长度 > MAX_BODY_LEN:使用堆分配,保证正确性不截断
412    pub fn set_body(&mut self, body: impl Into<Vec<u8>>) {
413        let body = body.into();
414        if body.len() <= MAX_BODY_LEN {
415            self.body_overflow = None;
416            self.body_buffer[..body.len()].copy_from_slice(&body);
417            self.body_len = body.len() as u32;
418        } else {
419            self.body_overflow = Some(body);
420            self.body_len = self
421                .body_overflow
422                .as_ref()
423                .map(|v| v.len())
424                .unwrap_or(0) as u32;
425        }
426    }
427
428    /// 获取请求 Body 的字节切片(零分配)
429    #[inline]
430    pub fn body(&self) -> &[u8] {
431        if let Some(ref overflow) = self.body_overflow {
432            overflow.as_slice()
433        } else {
434            &self.body_buffer[..self.body_len as usize]
435        }
436    }
437
438    /// 获取方案字符串
439    #[inline]
440    pub fn scheme_str(&self) -> &str {
441        core::str::from_utf8(&self.scheme[..self.scheme_len as usize]).unwrap_or("")
442    }
443
444    /// 设置方案(fail-closed)
445    ///
446    /// # Returns
447    /// * `true` - 设置成功
448    /// * `false` - 方案超长(拒绝静默截断,**不修改原值**直接返回 false;
449    ///   截断会篡改语义,下游必须检查返回值)
450    #[must_use]
451    pub fn set_scheme(&mut self, scheme: &str) -> bool {
452        if scheme.len() > 8 {
453            return false;
454        }
455        let len = scheme.len() as u8;
456        self.scheme[..scheme.len()].copy_from_slice(scheme.as_bytes());
457        self.scheme_len = len;
458        true
459    }
460
461    /// 获取授权主机字符串
462    #[inline]
463    pub fn authority_str(&self) -> &str {
464        core::str::from_utf8(&self.authority[..self.authority_len as usize]).unwrap_or("")
465    }
466
467    /// 设置授权主机(fail-closed)
468    ///
469    /// # Returns
470    /// * `true` - 设置成功
471    /// * `false` - authority 超长(拒绝静默截断,**不修改原值**直接返回 false)
472    #[must_use]
473    pub fn set_authority(&mut self, authority: &str) -> bool {
474        if authority.len() > MAX_AUTHORITY_LEN {
475            return false;
476        }
477        let len = authority.len() as u16;
478        self.authority[..authority.len()].copy_from_slice(authority.as_bytes());
479        self.authority_len = len;
480        true
481    }
482
483    /// 获取规范化路径
484    #[inline]
485    pub fn path_str(&self) -> &str {
486        core::str::from_utf8(&self.normalized_path[..self.path_len as usize]).unwrap_or("")
487    }
488
489    /// 获取规范化路径的字节切片(零分配)
490    #[inline]
491    pub fn path_bytes(&self) -> &[u8] {
492        &self.normalized_path[..self.path_len as usize]
493    }
494
495    /// 设置规范化路径(fail-closed)
496    ///
497    /// 输入为 request target 时,其中的 `?` 之后的部分会被拆分到 query 字段
498    /// (路由只匹配路径部分;若不拆分,`/api?x=1` 会作为整体参与路由匹配而被击穿)。
499    /// 输入不含 `?` 时 query 字段保持不变。
500    ///
501    /// # Returns
502    /// * `true` - 设置成功
503    /// * `false` - 路径部分超过 MAX_PATH_LEN 或拆分出的 query 超过
504    ///   MAX_QUERY_LEN(拒绝静默截断,**path 与 query 均不修改**,原子拒绝)
505    #[must_use]
506    pub fn set_path(&mut self, path: &str) -> bool {
507        // 拆分 request target 中的 query 部分
508        let (path_part, query_part) = match path.find('?') {
509            Some(pos) => (&path[..pos], Some(&path[pos + 1..])),
510            None => (path, None),
511        };
512        // 全量预检:任何一部分超长都原子拒绝,不部分落盘
513        if path_part.len() > MAX_PATH_LEN {
514            return false;
515        }
516        if let Some(query) = query_part
517            && query.len() > MAX_QUERY_LEN
518        {
519            return false;
520        }
521        self.normalized_path[..path_part.len()].copy_from_slice(path_part.as_bytes());
522        self.path_len = path_part.len() as u16;
523        if let Some(query) = query_part {
524            // 长度已预检,set_query 必然返回 true
525            let _ = self.set_query(query);
526        }
527        true
528    }
529
530    /// 获取规范化查询字符串
531    #[inline]
532    pub fn query_str(&self) -> &str {
533        core::str::from_utf8(&self.normalized_query[..self.query_len as usize]).unwrap_or("")
534    }
535
536    /// 设置规范化查询字符串(fail-closed)
537    ///
538    /// # Returns
539    /// * `true` - 设置成功
540    /// * `false` - query 超长(拒绝静默截断,**不修改原值**直接返回 false)
541    #[must_use]
542    pub fn set_query(&mut self, query: &str) -> bool {
543        if query.len() > MAX_QUERY_LEN {
544            return false;
545        }
546        let len = query.len() as u32;
547        self.normalized_query[..query.len()].copy_from_slice(query.as_bytes());
548        self.query_len = len;
549        true
550    }
551
552    /// 获取头部数量
553    #[inline]
554    pub fn header_count(&self) -> u8 {
555        self.header_count
556    }
557
558    /// 按索引获取头部
559    #[inline]
560    pub fn get_header(&self, idx: usize) -> Option<&CanonicalHeader> {
561        if idx < self.header_count as usize {
562            Some(&self.headers[idx])
563        } else {
564            None
565        }
566    }
567
568    /// 按名称查找头部(返回第一个匹配,ASCII 大小写不敏感)
569    ///
570    /// HTTP 头部名称按 RFC 7230 §3.2 为大小写不敏感;
571    /// 大小写敏感查找会被 `Host`/`host` 差分击穿,故统一不敏感比较。
572    #[inline]
573    pub fn find_header(&self, name: &str) -> Option<&CanonicalHeader> {
574        let name_bytes = name.as_bytes();
575        for i in 0..self.header_count as usize {
576            let hdr = &self.headers[i];
577            if hdr.name_len as usize == name_bytes.len()
578                && hdr.name[..hdr.name_len as usize].eq_ignore_ascii_case(name_bytes)
579            {
580                return Some(hdr);
581            }
582        }
583        None
584    }
585
586    /// 添加头部(超过最大数量或字段超长时返回错误)
587    ///
588    /// # 安全
589    /// - 拒绝包含 `\r` 或 `\n` 的头部名称和值,防止 HTTP 响应拆分攻击。
590    /// - 名称/值超长时 fail-closed 拒绝,禁止静默截断(截断会篡改头部语义)。
591    pub fn add_header(&mut self, name: &[u8], value: &[u8]) -> Result<(), &'static str> {
592        if self.header_count as usize >= MAX_HEADER_COUNT {
593            return Err("header count exceeded");
594        }
595        // 长度预检(fail-closed:超长直接拒绝)
596        if name.len() > MAX_HEADER_NAME_LEN {
597            return Err("header name too long");
598        }
599        if value.len() > MAX_HEADER_VALUE_LEN {
600            return Err("header value too long");
601        }
602        // 拒绝包含 CRLF 的头部,防止 HTTP 响应拆分攻击
603        if name.contains(&b'\r') || name.contains(&b'\n') {
604            return Err("header name contains CRLF");
605        }
606        if value.contains(&b'\r') || value.contains(&b'\n') {
607            return Err("header value contains CRLF");
608        }
609        let idx = self.header_count as usize;
610        // 长度已预检,from_bytes 必然成功;仍按 fail-closed 处理 None 而非 unwrap
611        self.headers[idx] = match CanonicalHeader::from_bytes(name, value) {
612            Some(hdr) => hdr,
613            None => return Err("header name or value too long"),
614        };
615        self.header_count += 1;
616        Ok(())
617    }
618
619    /// 迭代所有头部
620    #[inline]
621    pub fn headers_iter(&self) -> &[CanonicalHeader] {
622        &self.headers[..self.header_count as usize]
623    }
624
625    /// 设置已取消
626    #[inline]
627    pub fn cancel(&mut self) {
628        self.cancelled = true;
629    }
630
631    /// 检查是否已取消
632    #[inline]
633    pub fn is_cancelled(&self) -> bool {
634        self.cancelled
635    }
636}
637
638// ---------------------------------------------------------------------------
639// 规范化响应(零堆分配,固定容量)
640// ---------------------------------------------------------------------------
641
642/// 统一规范化响应
643///
644/// 所有HTTP协议处理后的统一响应结构。
645///
646/// # 设计特点
647/// - 零堆分配:小 Body 使用栈上固定数组,超过 MAX_BODY_LEN 时才使用堆
648/// - Copy 语义:仅当 Body 超过栈容量时放弃 Copy
649#[derive(Debug, Clone)]
650pub struct CanonicalResponse {
651    /// 状态码
652    pub status_code: u16,
653    /// 头部数组(固定容量)
654    headers: [CanonicalHeader; MAX_HEADER_COUNT],
655    /// 头部数量
656    header_count: u8,
657    /// Body 数据(栈上固定容量)
658    body_buffer: [u8; MAX_BODY_LEN],
659    /// Body 实际长度
660    body_len: u32,
661    /// Body 溢出数据(超过 MAX_BODY_LEN 时使用堆分配)
662    body_overflow: Option<Vec<u8>>,
663}
664
665impl CanonicalResponse {
666    /// 创建响应(零堆分配)
667    #[inline]
668    pub const fn new(status_code: u16) -> Self {
669        Self {
670            status_code,
671            headers: [CanonicalHeader::empty(); MAX_HEADER_COUNT],
672            header_count: 0,
673            body_buffer: [0u8; MAX_BODY_LEN],
674            body_len: 0,
675            body_overflow: None,
676        }
677    }
678
679    /// 创建简单的成功响应
680    #[inline]
681    pub const fn ok() -> Self {
682        Self::new(200)
683    }
684
685    /// 创建简单的错误响应
686    #[inline]
687    pub const fn error(status_code: u16) -> Self {
688        Self::new(status_code)
689    }
690
691    /// 重置响应(保留状态码,清空其他字段)
692    /// 用于对象池复用,避免重新创建对象的开销
693    #[inline]
694    pub fn reset(&mut self) {
695        // 只重置使用过的字段,不重置整个数组
696        for i in 0..self.header_count as usize {
697            self.headers[i].reset();
698        }
699        self.header_count = 0;
700        // 不需要重置 body_buffer,后续写入会覆盖
701        self.body_len = 0;
702        self.body_overflow = None;
703    }
704
705    /// 获取头部数量
706    #[inline]
707    pub fn header_count(&self) -> u8 {
708        self.header_count
709    }
710
711    /// 添加头部
712    ///
713    /// # 安全
714    /// 拒绝包含 `\r` 或 `\n` 的头部名称和值,防止 HTTP 响应拆分攻击。
715    pub fn add_header(&mut self, name: &[u8], value: &[u8]) -> Result<(), &'static str> {
716        if self.header_count as usize >= MAX_HEADER_COUNT {
717            return Err("header count exceeded");
718        }
719        // 拒绝包含 CRLF 的头部,防止 HTTP 响应拆分攻击
720        if name.contains(&b'\r') || name.contains(&b'\n') {
721            return Err("header name contains CRLF");
722        }
723        if value.contains(&b'\r') || value.contains(&b'\n') {
724            return Err("header value contains CRLF");
725        }
726        let idx = self.header_count as usize;
727        // from_bytes 在 name/value 超限时返回 None,fail-closed 上抛错误
728        self.headers[idx] = CanonicalHeader::from_bytes(name, value)
729            .ok_or("header name/value too long")?;
730        self.header_count += 1;
731        Ok(())
732    }
733
734    /// 设置 Body
735    ///
736    /// # 性能
737    /// - Body 长度 <= MAX_BODY_LEN:使用栈上缓冲区,零堆分配
738    /// - Body 长度 > MAX_BODY_LEN:使用堆分配
739    pub fn set_body(&mut self, body: impl Into<Vec<u8>>) {
740        let body = body.into();
741        if body.len() <= MAX_BODY_LEN {
742            self.body_overflow = None;
743            self.body_buffer[..body.len()].copy_from_slice(&body);
744            self.body_len = body.len() as u32;
745        } else {
746            self.body_overflow = Some(body);
747            self.body_len = self.body_overflow.as_ref().map(|v| v.len()).unwrap_or(0) as u32;
748        }
749    }
750
751    /// 获取 Body 引用
752    #[inline]
753    pub fn body(&self) -> &[u8] {
754        if let Some(ref overflow) = self.body_overflow {
755            overflow
756        } else {
757            &self.body_buffer[..self.body_len as usize]
758        }
759    }
760
761    /// 获取头部迭代器
762    #[inline]
763    pub fn headers_iter(&self) -> &[CanonicalHeader] {
764        &self.headers[..self.header_count as usize]
765    }
766
767    /// 按名称查找头部(ASCII 大小写不敏感,RFC 7230 §3.2)
768    #[inline]
769    pub fn find_header(&self, name: &str) -> Option<&CanonicalHeader> {
770        let name_bytes = name.as_bytes();
771        for i in 0..self.header_count as usize {
772            let hdr = &self.headers[i];
773            if hdr.name_len as usize == name_bytes.len()
774                && hdr.name[..hdr.name_len as usize].eq_ignore_ascii_case(name_bytes)
775            {
776                return Some(hdr);
777            }
778        }
779        None
780    }
781}
782
783impl Default for CanonicalRequest {
784    #[inline]
785    fn default() -> Self {
786        Self::empty()
787    }
788}
789
790impl Default for CanonicalResponse {
791    #[inline]
792    fn default() -> Self {
793        Self::new(200)
794    }
795}
796
797// ---------------------------------------------------------------------------
798// 服务注册特征
799// ---------------------------------------------------------------------------
800
801/// 服务注册特征
802pub trait Service: Send + Sync + 'static {
803    /// 处理规范化请求,返回规范化响应
804    fn handle(&self, request: CanonicalRequest) -> CanonicalResponse;
805}
806
807/// 服务工厂特征
808pub trait ServiceFactory: Send + Sync + 'static {
809    /// 创建新的服务实例
810    fn create(&self) -> Box<dyn Service>;
811}
812
813// ---------------------------------------------------------------------------
814// 测试
815// ---------------------------------------------------------------------------
816
817#[cfg(test)]
818mod tests {
819    use super::*;
820
821    #[test]
822    fn test_method_from_str() {
823        use std::str::FromStr;
824        assert_eq!(Method::from_str("GET"), Ok(Method::Get));
825        assert_eq!(Method::from_str("POST"), Ok(Method::Post));
826        // RFC 9110 大小写敏感:非大写方法一律拒绝(与 zenith-web parse_method 统一)
827        assert!(Method::from_str("post").is_err());
828        assert!(Method::from_str("Get").is_err());
829        assert!(Method::from_str("INVALID").is_err());
830    }
831
832    #[test]
833    fn test_method_as_str() {
834        assert_eq!(Method::Get.as_str(), "GET");
835        assert_eq!(Method::Post.as_str(), "POST");
836    }
837
838    #[test]
839    fn test_canonical_header_creation() {
840        let hdr = CanonicalHeader::from_bytes(b"content-type", b"application/json").unwrap();
841        assert_eq!(hdr.name_str(), "content-type");
842        assert_eq!(hdr.value_str(), "application/json");
843        assert_eq!(hdr.name_len, 12);
844        assert_eq!(hdr.value_len, 16);
845    }
846
847    #[test]
848    fn test_canonical_header_overlong_rejected() {
849        // 构造一个 100 字节的超长名称:fail-closed 拒绝,禁止静默截断
850        let long_name = b"this-is-a-very-long-header-name-that-should-exceed-the-maximum-sixty-four-bytes-limit-and-test-truncation";
851        assert!(long_name.len() > MAX_HEADER_NAME_LEN);
852        assert!(CanonicalHeader::from_bytes(long_name, b"value").is_none());
853
854        // 边界:恰好等于上限时允许
855        let exact_name = vec![b'n'; MAX_HEADER_NAME_LEN];
856        let hdr = CanonicalHeader::from_bytes(&exact_name, b"value").unwrap();
857        assert_eq!(hdr.name_len, MAX_HEADER_NAME_LEN as u8);
858    }
859
860    #[test]
861    fn test_canonical_request_creation() {
862        let mut request = CanonicalRequest::empty();
863        request.method = Method::Get;
864        assert!(request.set_scheme("https"));
865        assert!(request.set_authority("example.com"));
866        assert!(request.set_path("/api/test"));
867        assert!(request.set_query("key=value"));
868        request.protocol = Protocol::Http1;
869        request.transport = Transport::Tls13;
870
871        assert_eq!(request.method, Method::Get);
872        assert_eq!(request.scheme_str(), "https");
873        assert_eq!(request.authority_str(), "example.com");
874        assert_eq!(request.path_str(), "/api/test");
875        assert_eq!(request.query_str(), "key=value");
876    }
877
878    #[test]
879    fn test_canonical_request_headers() {
880        let mut request = CanonicalRequest::empty();
881        request
882            .add_header(b"content-type", b"application/json")
883            .unwrap();
884        request
885            .add_header(b"accept", b"text/html")
886            .unwrap();
887
888        assert_eq!(request.header_count(), 2);
889        assert!(request.find_header("content-type").is_some());
890        assert!(request.find_header("non-existent").is_none());
891
892        let hdr = request.find_header("accept").unwrap();
893        assert_eq!(hdr.value_str(), "text/html");
894    }
895
896    #[test]
897    fn test_canonical_request_header_limit() {
898        let mut request = CanonicalRequest::empty();
899        for i in 0..MAX_HEADER_COUNT {
900            let name = format!("header-{}", i);
901            request.add_header(name.as_bytes(), b"value").unwrap();
902        }
903        assert_eq!(request.header_count(), MAX_HEADER_COUNT as u8);
904
905        // 超过限制应返回错误
906        let result = request.add_header(b"overflow", b"value");
907        assert!(result.is_err());
908    }
909
910    #[test]
911    fn test_body_stream() {
912        let data = b"test body data";
913        let mut stream = BodyStream::new(data);
914
915        assert!(!stream.is_consumed());
916        assert_eq!(stream.len(), 14);
917        assert!(!stream.is_empty());
918
919        let result = stream.get_data();
920        assert_eq!(result, Some(&data[..]));
921        assert!(stream.is_consumed());
922
923        // 再次调用返回 None
924        let result2 = stream.get_data();
925        assert!(result2.is_none());
926    }
927
928    #[test]
929    fn test_body_stream_empty() {
930        let mut stream = BodyStream::new(b"");
931        assert!(stream.is_empty());
932        let result = stream.get_data();
933        assert!(result.is_none());
934    }
935
936    #[test]
937    fn test_governance_fields() {
938        let mut request = CanonicalRequest::empty();
939        request.generation = 42;
940        request.deadline_ms = 5000;
941        request.resource_lease = 100;
942
943        assert_eq!(request.generation, 42);
944        assert_eq!(request.deadline_ms, 5000);
945
946        request.cancel();
947        assert!(request.is_cancelled());
948    }
949
950    #[test]
951    fn test_canonical_response() {
952        let mut response = CanonicalResponse::new(200);
953        assert_eq!(response.status_code, 200);
954
955        response
956            .add_header(b"content-type", b"text/plain")
957            .unwrap();
958        assert_eq!(response.header_count(), 1);
959
960        response.set_body(b"Hello".to_vec());
961        assert_eq!(response.body(), b"Hello");
962    }
963
964    #[test]
965    fn test_canonical_response_helpers() {
966        let ok = CanonicalResponse::ok();
967        assert_eq!(ok.status_code, 200);
968
969        let error = CanonicalResponse::error(404);
970        assert_eq!(error.status_code, 404);
971    }
972
973    #[test]
974    fn test_request_copy_semantics() {
975        let mut request = CanonicalRequest::empty();
976        request.method = Method::Post;
977        assert!(request.set_path("/test"));
978        request.generation = 1;
979
980        // Clone 语义:CanonicalRequest 不再实现 Copy(含 Option<Vec<u8>> body_overflow)
981        let cloned = request.clone();
982        assert_eq!(cloned.method, Method::Post);
983        assert_eq!(cloned.path_str(), "/test");
984        assert_eq!(cloned.generation, 1);
985
986        // 修改原对象不影响克隆
987        request.method = Method::Get;
988        assert_ne!(request.method, cloned.method);
989    }
990
991    // ─────────────────────────────────────────────
992    // Method 全变体测试
993    // ─────────────────────────────────────────────
994
995    #[test]
996    fn test_method_all_variants_as_str() {
997        assert_eq!(Method::Get.as_str(), "GET");
998        assert_eq!(Method::Post.as_str(), "POST");
999        assert_eq!(Method::Put.as_str(), "PUT");
1000        assert_eq!(Method::Delete.as_str(), "DELETE");
1001        assert_eq!(Method::Patch.as_str(), "PATCH");
1002        assert_eq!(Method::Head.as_str(), "HEAD");
1003        assert_eq!(Method::Options.as_str(), "OPTIONS");
1004        assert_eq!(Method::Connect.as_str(), "CONNECT");
1005        assert_eq!(Method::Trace.as_str(), "TRACE");
1006    }
1007
1008    #[test]
1009    fn test_method_from_str_all_variants() {
1010        use std::str::FromStr;
1011        assert_eq!(Method::from_str("GET"), Ok(Method::Get));
1012        assert_eq!(Method::from_str("POST"), Ok(Method::Post));
1013        assert_eq!(Method::from_str("PUT"), Ok(Method::Put));
1014        assert_eq!(Method::from_str("DELETE"), Ok(Method::Delete));
1015        assert_eq!(Method::from_str("PATCH"), Ok(Method::Patch));
1016        assert_eq!(Method::from_str("HEAD"), Ok(Method::Head));
1017        assert_eq!(Method::from_str("OPTIONS"), Ok(Method::Options));
1018        assert_eq!(Method::from_str("CONNECT"), Ok(Method::Connect));
1019        assert_eq!(Method::from_str("TRACE"), Ok(Method::Trace));
1020    }
1021
1022    #[test]
1023    fn test_method_from_str_case_sensitive_strict() {
1024        // RFC 9110:method = token 大小写敏感。任何非精确大写均被拒绝,
1025        // 与 zenith_web::normalize::parse_method 语义统一(防双解析器分歧)。
1026        use std::str::FromStr;
1027        assert!(Method::from_str("get").is_err());
1028        assert!(Method::from_str("Get").is_err());
1029        assert!(Method::from_str("gEt").is_err());
1030        assert!(Method::from_str("post").is_err());
1031        assert!(Method::from_str("Post").is_err());
1032        assert!(Method::from_str("delete").is_err());
1033        assert!(Method::from_str(" GET").is_err());
1034        assert!(Method::from_str("GET ").is_err());
1035    }
1036
1037    #[test]
1038    fn test_method_from_str_invalid() {
1039        use std::str::FromStr;
1040        assert!(Method::from_str("").is_err());
1041        assert!(Method::from_str("UNKNOWN").is_err());
1042        assert!(Method::from_str("GET ").is_err());
1043        assert!(Method::from_str(" GET").is_err());
1044        assert!(Method::from_str("123").is_err());
1045    }
1046
1047    #[test]
1048    fn test_method_parse_error_display() {
1049        use std::str::FromStr;
1050        let err = Method::from_str("INVALID").unwrap_err();
1051        assert_eq!(format!("{}", err), "invalid HTTP method");
1052        assert!(format!("{:?}", err).contains("MethodParseError"));
1053    }
1054
1055    // ─────────────────────────────────────────────
1056    // Protocol / Transport 变体测试
1057    // ─────────────────────────────────────────────
1058
1059    #[test]
1060    fn test_protocol_variants() {
1061        let protocols = [
1062            Protocol::Http1,
1063            Protocol::Http2,
1064            Protocol::Http3,
1065            Protocol::Tcp,
1066            Protocol::Udp,
1067            Protocol::Quic,
1068        ];
1069        for (i, p) in protocols.iter().enumerate() {
1070            for (j, q) in protocols.iter().enumerate() {
1071                if i == j {
1072                    assert_eq!(p, q);
1073                } else {
1074                    assert_ne!(p, q);
1075                }
1076            }
1077        }
1078    }
1079
1080    #[test]
1081    fn test_transport_variants() {
1082        assert_eq!(Transport::Plaintext, Transport::Plaintext);
1083        assert_eq!(Transport::Tls13, Transport::Tls13);
1084        assert_ne!(Transport::Plaintext, Transport::Tls13);
1085    }
1086
1087    // ─────────────────────────────────────────────
1088    // CanonicalHeader 边界测试
1089    // ─────────────────────────────────────────────
1090
1091    #[test]
1092    fn test_canonical_header_empty() {
1093        let hdr = CanonicalHeader::empty();
1094        assert!(hdr.is_empty());
1095        assert_eq!(hdr.name_len, 0);
1096        assert_eq!(hdr.value_len, 0);
1097        assert_eq!(hdr.name_str(), "");
1098        assert_eq!(hdr.value_str(), "");
1099    }
1100
1101    #[test]
1102    fn test_canonical_header_value_overlong_rejected() {
1103        // 超长值:fail-closed 拒绝,禁止静默截断
1104        let long_value = vec![b'x'; MAX_HEADER_VALUE_LEN + 100];
1105        assert!(CanonicalHeader::from_bytes(b"name", &long_value).is_none());
1106
1107        // 边界:恰好等于上限时允许
1108        let exact_value = vec![b'x'; MAX_HEADER_VALUE_LEN];
1109        let hdr = CanonicalHeader::from_bytes(b"name", &exact_value).unwrap();
1110        assert_eq!(hdr.value_len, MAX_HEADER_VALUE_LEN as u16);
1111        assert_eq!(hdr.value_str().len(), MAX_HEADER_VALUE_LEN);
1112    }
1113
1114    #[test]
1115    fn test_canonical_header_zero_length() {
1116        let hdr = CanonicalHeader::from_bytes(b"", b"").unwrap();
1117        assert!(hdr.is_empty());
1118        assert_eq!(hdr.name_str(), "");
1119        assert_eq!(hdr.value_str(), "");
1120    }
1121
1122    #[test]
1123    fn test_canonical_header_invalid_utf8() {
1124        let invalid_utf8 = [0xFF, 0xFE, 0xFD];
1125        let hdr = CanonicalHeader::from_bytes(&invalid_utf8, b"value").unwrap();
1126        // 无效 UTF-8 应返回空字符串
1127        assert_eq!(hdr.name_str(), "");
1128    }
1129
1130    // ─────────────────────────────────────────────
1131    // CanonicalRequest 全字段验证
1132    // ─────────────────────────────────────────────
1133
1134    #[test]
1135    fn test_canonical_request_full_fields() {
1136        let mut req = CanonicalRequest::empty();
1137        req.method = Method::Put;
1138        assert!(req.set_scheme("https"));
1139        assert!(req.set_authority("api.example.com:8443"));
1140        assert!(req.set_path("/api/v1/users/42"));
1141        assert!(req.set_query("id=42&name=test&verbose=true"));
1142        req.protocol = Protocol::Http2;
1143        req.transport = Transport::Tls13;
1144        req.generation = 12345;
1145        req.deadline_ms = 30000;
1146        req.cancelled = false;
1147        req.resource_lease = 999;
1148
1149        assert_eq!(req.method, Method::Put);
1150        assert_eq!(req.scheme_str(), "https");
1151        assert_eq!(req.authority_str(), "api.example.com:8443");
1152        assert_eq!(req.path_str(), "/api/v1/users/42");
1153        assert_eq!(req.query_str(), "id=42&name=test&verbose=true");
1154        assert_eq!(req.protocol, Protocol::Http2);
1155        assert_eq!(req.transport, Transport::Tls13);
1156        assert_eq!(req.generation, 12345);
1157        assert_eq!(req.deadline_ms, 30000);
1158        assert!(!req.is_cancelled());
1159        assert_eq!(req.resource_lease, 999);
1160    }
1161
1162    #[test]
1163    fn test_canonical_request_scheme_overlong_rejected() {
1164        // fail-closed:超长方案原子拒绝(不修改原值),禁止静默截断
1165        let mut req = CanonicalRequest::empty();
1166        assert!(req.set_scheme("https"));
1167        assert!(!req.set_scheme("https-and-more"));
1168        // 原值保持不变
1169        assert_eq!(req.scheme_str(), "https");
1170
1171        // 边界:恰好 8 字节允许
1172        let mut req2 = CanonicalRequest::empty();
1173        assert!(req2.set_scheme("12345678"));
1174        assert_eq!(req2.scheme_str(), "12345678");
1175    }
1176
1177    #[test]
1178    fn test_canonical_request_path_overlong_rejected() {
1179        // fail-closed:超长路径原子拒绝(不修改原值),禁止静默截断
1180        let mut req = CanonicalRequest::empty();
1181        assert!(req.set_path("/original"));
1182        let long_path = "a".repeat(MAX_PATH_LEN + 100);
1183        assert!(!req.set_path(&long_path));
1184        assert_eq!(req.path_str(), "/original");
1185
1186        // 边界:恰好等于上限时允许
1187        let exact_path = "a".repeat(MAX_PATH_LEN);
1188        assert!(req.set_path(&exact_path));
1189        assert_eq!(req.path_str().len(), MAX_PATH_LEN);
1190    }
1191
1192    #[test]
1193    fn test_set_path_splits_query() {
1194        let mut req = CanonicalRequest::empty();
1195        // request target 中的 `?` 之后部分必须拆分到 query 字段,
1196        // 否则 "/api?x=1" 会作为整体参与路由匹配而被击穿
1197        assert!(req.set_path("/api/users?id=42&verbose=true"));
1198        assert_eq!(req.path_str(), "/api/users");
1199        assert_eq!(req.query_str(), "id=42&verbose=true");
1200
1201        // 无 `?` 时 query 保持原状
1202        let mut req2 = CanonicalRequest::empty();
1203        assert!(req2.set_query("keep=1"));
1204        assert!(req2.set_path("/plain/path"));
1205        assert_eq!(req2.path_str(), "/plain/path");
1206        assert_eq!(req2.query_str(), "keep=1");
1207
1208        // `?` 后为空:query 为空串
1209        let mut req3 = CanonicalRequest::empty();
1210        assert!(req3.set_path("/api?"));
1211        assert_eq!(req3.path_str(), "/api");
1212        assert_eq!(req3.query_str(), "");
1213    }
1214
1215    #[test]
1216    fn test_set_path_overlong_split_query_atomic_rejected() {
1217        // 路径部分合法但拆分出的 query 超长:path 与 query 均不修改(原子拒绝)
1218        let mut req = CanonicalRequest::empty();
1219        assert!(req.set_query("keep=1"));
1220        let long_target = format!("/ok?{}", "a".repeat(MAX_QUERY_LEN + 1));
1221        assert!(!req.set_path(&long_target));
1222        assert_eq!(req.path_str(), "");
1223        assert_eq!(req.query_str(), "keep=1");
1224    }
1225
1226    #[test]
1227    fn test_add_header_overlong_rejected() {
1228        let mut req = CanonicalRequest::empty();
1229
1230        // 名称超长:fail-closed 拒绝
1231        let long_name = vec![b'n'; MAX_HEADER_NAME_LEN + 1];
1232        let result = req.add_header(&long_name, b"value");
1233        assert_eq!(result, Err("header name too long"));
1234
1235        // 值超长:fail-closed 拒绝
1236        let long_value = vec![b'v'; MAX_HEADER_VALUE_LEN + 1];
1237        let result = req.add_header(b"name", &long_value);
1238        assert_eq!(result, Err("header value too long"));
1239
1240        // 两次拒绝均未污染头部表
1241        assert_eq!(req.header_count(), 0);
1242
1243        // 边界:恰好等于上限时允许
1244        let exact_name = vec![b'n'; MAX_HEADER_NAME_LEN];
1245        let exact_value = vec![b'v'; MAX_HEADER_VALUE_LEN];
1246        assert!(req.add_header(&exact_name, &exact_value).is_ok());
1247        assert_eq!(req.header_count(), 1);
1248    }
1249
1250    #[test]
1251    fn test_response_add_header_overlong_rejected() {
1252        let mut resp = CanonicalResponse::new(200);
1253
1254        let long_name = vec![b'n'; MAX_HEADER_NAME_LEN + 1];
1255        assert!(resp.add_header(&long_name, b"value").is_err());
1256
1257        let long_value = vec![b'v'; MAX_HEADER_VALUE_LEN + 1];
1258        assert!(resp.add_header(b"name", &long_value).is_err());
1259
1260        assert_eq!(resp.header_count(), 0);
1261    }
1262
1263    #[test]
1264    fn test_canonical_request_query_overlong_rejected() {
1265        // fail-closed:超长 query 原子拒绝(不修改原值),禁止静默截断
1266        let mut req = CanonicalRequest::empty();
1267        assert!(req.set_query("keep=1"));
1268        let long_query = "a".repeat(MAX_QUERY_LEN + 100);
1269        assert!(!req.set_query(&long_query));
1270        assert_eq!(req.query_str(), "keep=1");
1271
1272        // 边界:恰好等于上限时允许
1273        let exact_query = "a".repeat(MAX_QUERY_LEN);
1274        assert!(req.set_query(&exact_query));
1275        assert_eq!(req.query_str().len(), MAX_QUERY_LEN);
1276    }
1277
1278    #[test]
1279    fn test_canonical_request_authority_overlong_rejected() {
1280        // fail-closed:超长 authority 原子拒绝(不修改原值),禁止静默截断
1281        let mut req = CanonicalRequest::empty();
1282        assert!(req.set_authority("example.com"));
1283        let long_auth = "a".repeat(MAX_AUTHORITY_LEN + 100);
1284        assert!(!req.set_authority(&long_auth));
1285        assert_eq!(req.authority_str(), "example.com");
1286
1287        // 边界:恰好等于上限时允许
1288        let exact_auth = "a".repeat(MAX_AUTHORITY_LEN);
1289        assert!(req.set_authority(&exact_auth));
1290        assert_eq!(req.authority_str().len(), MAX_AUTHORITY_LEN);
1291    }
1292
1293    #[test]
1294    fn test_canonical_request_empty_strings() {
1295        let mut req = CanonicalRequest::empty();
1296        assert!(req.set_scheme(""));
1297        assert!(req.set_authority(""));
1298        assert!(req.set_path(""));
1299        assert!(req.set_query(""));
1300
1301        assert_eq!(req.scheme_str(), "");
1302        assert_eq!(req.authority_str(), "");
1303        assert_eq!(req.path_str(), "");
1304        assert_eq!(req.query_str(), "");
1305    }
1306
1307    // ─────────────────────────────────────────────
1308    // CanonicalRequest Header 操作边界
1309    // ─────────────────────────────────────────────
1310
1311    #[test]
1312    fn test_canonical_request_get_header_boundary() {
1313        let mut req = CanonicalRequest::empty();
1314        req.add_header(b"h1", b"v1").unwrap();
1315        req.add_header(b"h2", b"v2").unwrap();
1316
1317        assert!(req.get_header(0).is_some());
1318        assert!(req.get_header(1).is_some());
1319        assert!(req.get_header(2).is_none());
1320        assert!(req.get_header(100).is_none());
1321    }
1322
1323    #[test]
1324    fn test_canonical_request_find_header_case_insensitive() {
1325        let mut req = CanonicalRequest::empty();
1326        req.add_header(b"Content-Type", b"application/json").unwrap();
1327
1328        // find_header 是 ASCII 大小写不敏感的(RFC 7230 §3.2)
1329        assert!(req.find_header("Content-Type").is_some());
1330        assert!(req.find_header("content-type").is_some());
1331        assert!(req.find_header("CONTENT-TYPE").is_some());
1332        assert!(req.find_header("cOnTeNt-tYpE").is_some());
1333        // 不同名称仍然不匹配
1334        assert!(req.find_header("content-length").is_none());
1335    }
1336
1337    #[test]
1338    fn test_canonical_request_headers_iter() {
1339        let mut req = CanonicalRequest::empty();
1340        req.add_header(b"a", b"1").unwrap();
1341        req.add_header(b"b", b"2").unwrap();
1342        req.add_header(b"c", b"3").unwrap();
1343
1344        let headers = req.headers_iter();
1345        assert_eq!(headers.len(), 3);
1346        assert_eq!(headers[0].name_str(), "a");
1347        assert_eq!(headers[1].name_str(), "b");
1348        assert_eq!(headers[2].name_str(), "c");
1349    }
1350
1351    #[test]
1352    fn test_canonical_request_headers_iter_empty() {
1353        let req = CanonicalRequest::empty();
1354        assert!(req.headers_iter().is_empty());
1355    }
1356
1357    // ─────────────────────────────────────────────
1358    // CanonicalRequest 治理字段
1359    // ─────────────────────────────────────────────
1360
1361    #[test]
1362    fn test_canonical_request_cancel() {
1363        let mut req = CanonicalRequest::empty();
1364        assert!(!req.is_cancelled());
1365        req.cancel();
1366        assert!(req.is_cancelled());
1367        // 再次 cancel 应该还是 true
1368        req.cancel();
1369        assert!(req.is_cancelled());
1370    }
1371
1372    #[test]
1373    fn test_canonical_request_deadline_zero() {
1374        let mut req = CanonicalRequest::empty();
1375        assert_eq!(req.deadline_ms, 0);
1376        req.deadline_ms = 0;
1377        assert_eq!(req.deadline_ms, 0);
1378    }
1379
1380    #[test]
1381    fn test_canonical_request_resource_lease() {
1382        let mut req = CanonicalRequest::empty();
1383        assert_eq!(req.resource_lease, 0);
1384        req.resource_lease = u64::MAX;
1385        assert_eq!(req.resource_lease, u64::MAX);
1386    }
1387
1388    // ─────────────────────────────────────────────
1389    // BodyStream 边界测试
1390    // ─────────────────────────────────────────────
1391
1392    #[test]
1393    fn test_body_stream_single_use() {
1394        let data = b"hello";
1395        let mut stream = BodyStream::new(data);
1396        assert_eq!(stream.get_data(), Some(&data[..]));
1397        assert!(stream.is_consumed());
1398        assert!(stream.get_data().is_none());
1399        assert!(stream.get_data().is_none());
1400    }
1401
1402    #[test]
1403    fn test_body_stream_len_unchanged_after_consume() {
1404        let data = b"test data";
1405        let mut stream = BodyStream::new(data);
1406        assert_eq!(stream.len(), 9);
1407        let _ = stream.get_data();
1408        assert_eq!(stream.len(), 9);
1409    }
1410
1411    #[test]
1412    fn test_body_stream_empty_data_never_consumable() {
1413        let mut stream = BodyStream::new(b"");
1414        assert!(stream.is_empty());
1415        assert!(!stream.is_consumed());
1416        // 空数据即使首次调用也返回 None
1417        assert!(stream.get_data().is_none());
1418        // consumed 状态不变因为数据为空
1419        assert!(!stream.is_consumed());
1420    }
1421
1422    #[test]
1423    fn test_body_stream_large_data() {
1424        let large_data = vec![b'x'; 10000];
1425        let mut stream = BodyStream::new(&large_data);
1426        assert_eq!(stream.len(), 10000);
1427        assert!(!stream.is_empty());
1428        let result = stream.get_data().unwrap();
1429        assert_eq!(result.len(), 10000);
1430    }
1431
1432    // ─────────────────────────────────────────────
1433    // CanonicalResponse 全字段验证
1434    // ─────────────────────────────────────────────
1435
1436    #[test]
1437    fn test_canonical_response_full_fields() {
1438        let mut resp = CanonicalResponse::new(418);
1439        resp.add_header(b"content-type", b"text/plain").unwrap();
1440        resp.add_header(b"x-custom", b"value").unwrap();
1441        resp.set_body(b"I'm a teapot".to_vec());
1442
1443        assert_eq!(resp.status_code, 418);
1444        assert_eq!(resp.header_count(), 2);
1445        assert_eq!(resp.body(), b"I'm a teapot");
1446    }
1447
1448    #[test]
1449    fn test_canonical_response_header_limit() {
1450        let mut resp = CanonicalResponse::new(200);
1451        for i in 0..MAX_HEADER_COUNT {
1452            let name = format!("h{}", i);
1453            resp.add_header(name.as_bytes(), b"v").unwrap();
1454        }
1455        assert_eq!(resp.header_count(), MAX_HEADER_COUNT as u8);
1456        assert!(resp.add_header(b"overflow", b"v").is_err());
1457    }
1458
1459    #[test]
1460    fn test_canonical_response_find_header() {
1461        let mut resp = CanonicalResponse::new(200);
1462        resp.add_header(b"Server", b"zenith").unwrap();
1463        resp.add_header(b"Date", b"today").unwrap();
1464
1465        assert!(resp.find_header("Server").is_some());
1466        assert!(resp.find_header("Date").is_some());
1467        // ASCII 大小写不敏感(RFC 7230 §3.2)
1468        assert!(resp.find_header("server").is_some());
1469        assert!(resp.find_header("DATE").is_some());
1470        assert!(resp.find_header("X-Missing").is_none());
1471    }
1472
1473    #[test]
1474    fn test_canonical_response_headers_iter() {
1475        let mut resp = CanonicalResponse::new(200);
1476        resp.add_header(b"a", b"1").unwrap();
1477        resp.add_header(b"b", b"2").unwrap();
1478
1479        let headers = resp.headers_iter();
1480        assert_eq!(headers.len(), 2);
1481    }
1482
1483    #[test]
1484    fn test_canonical_response_body_empty() {
1485        let resp = CanonicalResponse::new(204);
1486        assert!(resp.body().is_empty());
1487    }
1488
1489    #[test]
1490    fn test_canonical_response_body_replace() {
1491        let mut resp = CanonicalResponse::new(200);
1492        resp.set_body(b"first".to_vec());
1493        assert_eq!(resp.body(), b"first");
1494        resp.set_body(b"second".to_vec());
1495        assert_eq!(resp.body(), b"second");
1496    }
1497
1498    // ─────────────────────────────────────────────
1499    // Service / ServiceFactory trait 对象测试
1500    // ─────────────────────────────────────────────
1501
1502    struct EchoService;
1503
1504    impl Service for EchoService {
1505        fn handle(&self, request: CanonicalRequest) -> CanonicalResponse {
1506            let mut resp = CanonicalResponse::ok();
1507            resp.set_body(request.path_str().as_bytes().to_vec());
1508            resp
1509        }
1510    }
1511
1512    struct EchoServiceFactory;
1513
1514    impl ServiceFactory for EchoServiceFactory {
1515        fn create(&self) -> Box<dyn Service> {
1516            Box::new(EchoService)
1517        }
1518    }
1519
1520    #[test]
1521    fn test_service_trait_object() {
1522        let service: Box<dyn Service> = Box::new(EchoService);
1523        let mut req = CanonicalRequest::empty();
1524        assert!(req.set_path("/hello"));
1525        let resp = service.handle(req);
1526        assert_eq!(resp.status_code, 200);
1527        assert_eq!(resp.body(), b"/hello");
1528    }
1529
1530    #[test]
1531    fn test_service_factory_trait() {
1532        let factory = EchoServiceFactory;
1533        let service = factory.create();
1534        let mut req = CanonicalRequest::empty();
1535        assert!(req.set_path("/test"));
1536        let resp = service.handle(req);
1537        assert_eq!(resp.body(), b"/test");
1538    }
1539
1540    // ─────────────────────────────────────────────
1541    // add_header CRLF 注入拒绝(响应拆分防护)
1542    // ─────────────────────────────────────────────
1543
1544    #[test]
1545    fn test_add_header_rejects_crlf() {
1546        let mut req = CanonicalRequest::empty();
1547
1548        // 名称含 CR/LF → Err
1549        assert_eq!(
1550            req.add_header(b"bad\rname", b"v"),
1551            Err("header name contains CRLF")
1552        );
1553        assert_eq!(
1554            req.add_header(b"bad\nname", b"v"),
1555            Err("header name contains CRLF")
1556        );
1557        assert_eq!(
1558            req.add_header(b"bad\r\nname", b"v"),
1559            Err("header name contains CRLF")
1560        );
1561
1562        // 值含 CR/LF → Err
1563        assert_eq!(
1564            req.add_header(b"name", b"bad\rvalue"),
1565            Err("header value contains CRLF")
1566        );
1567        assert_eq!(
1568            req.add_header(b"name", b"bad\nvalue"),
1569            Err("header value contains CRLF")
1570        );
1571        // 完整走私形态:值内注入整条头部
1572        assert!(req.add_header(b"name", b"ok\r\nEvil: x").is_err());
1573
1574        // 全部拒绝后头部表未被污染
1575        assert_eq!(req.header_count(), 0);
1576
1577        // CanonicalResponse 同样拒绝
1578        let mut resp = CanonicalResponse::new(200);
1579        assert_eq!(
1580            resp.add_header(b"bad\rname", b"v"),
1581            Err("header name contains CRLF")
1582        );
1583        assert_eq!(
1584            resp.add_header(b"name", b"bad\nvalue"),
1585            Err("header value contains CRLF")
1586        );
1587        assert_eq!(resp.header_count(), 0);
1588    }
1589
1590    // ─────────────────────────────────────────────
1591    // CanonicalRequest set_body 溢出堆路径
1592    // ─────────────────────────────────────────────
1593
1594    #[test]
1595    fn test_request_set_body_overflow_heap_path() {
1596        let mut req = CanonicalRequest::empty();
1597
1598        // 5000 字节 > MAX_BODY_LEN(4096):走 body_overflow 堆路径
1599        let big = vec![b'x'; 5000];
1600        assert!(big.len() > MAX_BODY_LEN);
1601        req.set_body(big.clone());
1602        // body() 可读全量,溢出缓冲区为 Some
1603        assert!(req.body_overflow.is_some());
1604        assert_eq!(req.body().len(), 5000);
1605        assert_eq!(req.body(), &big[..]);
1606
1607        // 回落到小 body:清空溢出,回到栈缓冲
1608        req.set_body(b"small".to_vec());
1609        assert!(req.body_overflow.is_none());
1610        assert_eq!(req.body(), b"small");
1611    }
1612}