wasmtime_wasi_http/
lib.rs1#![deny(missing_docs)]
8#![doc(test(attr(deny(warnings))))]
9#![doc(test(attr(allow(dead_code, unused_variables, unused_mut))))]
10#![cfg_attr(docsrs, feature(doc_cfg))]
11
12use http::{HeaderName, header};
13
14mod ctx;
15mod field_map;
16#[cfg(feature = "component-model-async")]
17pub mod handler;
18pub mod io;
19#[cfg(feature = "p2")]
20pub mod p2;
21#[cfg(feature = "p3")]
22pub mod p3;
23
24pub use ctx::*;
25pub use field_map::*;
26
27#[cfg(any(feature = "p2", feature = "p3"))]
31fn get_content_length(headers: &http::HeaderMap) -> wasmtime::Result<Option<u64>> {
32 let Some(v) = headers.get(header::CONTENT_LENGTH) else {
33 return Ok(None);
34 };
35 let v = v.to_str()?;
36 if v.is_empty() || !v.bytes().all(|b| b.is_ascii_digit()) {
40 wasmtime::bail!("invalid `content-length` header value: {v:?}");
41 }
42 let v = v.parse()?;
43 Ok(Some(v))
44}
45
46#[cfg(all(test, any(feature = "p2", feature = "p3")))]
47mod content_length_tests {
48 use super::get_content_length;
49 use http::{HeaderMap, HeaderValue, header};
50
51 fn headers(value: &str) -> HeaderMap {
52 let mut map = HeaderMap::new();
53 map.insert(
54 header::CONTENT_LENGTH,
55 HeaderValue::from_str(value).unwrap(),
56 );
57 map
58 }
59
60 #[test]
61 fn content_length_must_be_decimal_digits() {
62 assert_eq!(get_content_length(&HeaderMap::new()).unwrap(), None);
63 assert_eq!(get_content_length(&headers("0")).unwrap(), Some(0));
64 assert_eq!(get_content_length(&headers("1234")).unwrap(), Some(1234));
65
66 assert!(get_content_length(&headers("+5")).is_err());
68 assert!(get_content_length(&headers("-5")).is_err());
69 assert!(get_content_length(&headers(" 5")).is_err());
70 assert!(get_content_length(&headers("")).is_err());
71 }
72}
73
74pub const DEFAULT_FORBIDDEN_HEADERS: [HeaderName; 9] = [
77 header::CONNECTION,
78 HeaderName::from_static("keep-alive"),
79 header::PROXY_AUTHENTICATE,
80 header::PROXY_AUTHORIZATION,
81 HeaderName::from_static("proxy-connection"),
82 header::TRANSFER_ENCODING,
83 header::UPGRADE,
84 header::HOST,
85 HeaderName::from_static("http2-settings"),
86];