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;
15#[cfg(feature = "default-send-request")]
16mod default_send_request;
17mod error;
18mod field_map;
19#[cfg(feature = "component-model-async")]
20pub mod handler;
21pub mod io;
22#[cfg(feature = "p2")]
23pub mod p2;
24#[cfg(feature = "p3")]
25pub mod p3;
26mod request_options;
27
28pub use ctx::*;
29#[cfg(feature = "default-send-request")]
30pub use default_send_request::*;
31pub use error::*;
32pub use field_map::*;
33pub use request_options::*;
34
35#[cfg(any(feature = "p2", feature = "p3"))]
39fn get_content_length(headers: &http::HeaderMap) -> wasmtime::Result<Option<u64>> {
40 let Some(v) = headers.get(header::CONTENT_LENGTH) else {
41 return Ok(None);
42 };
43 let v = v.to_str()?;
44 if v.is_empty() || !v.bytes().all(|b| b.is_ascii_digit()) {
48 wasmtime::bail!("invalid `content-length` header value: {v:?}");
49 }
50 let v = v.parse()?;
51 Ok(Some(v))
52}
53
54#[cfg(all(test, any(feature = "p2", feature = "p3")))]
55mod content_length_tests {
56 use super::get_content_length;
57 use http::{HeaderMap, HeaderValue, header};
58
59 fn headers(value: &str) -> HeaderMap {
60 let mut map = HeaderMap::new();
61 map.insert(
62 header::CONTENT_LENGTH,
63 HeaderValue::from_str(value).unwrap(),
64 );
65 map
66 }
67
68 #[test]
69 fn content_length_must_be_decimal_digits() {
70 assert_eq!(get_content_length(&HeaderMap::new()).unwrap(), None);
71 assert_eq!(get_content_length(&headers("0")).unwrap(), Some(0));
72 assert_eq!(get_content_length(&headers("1234")).unwrap(), Some(1234));
73
74 assert!(get_content_length(&headers("+5")).is_err());
76 assert!(get_content_length(&headers("-5")).is_err());
77 assert!(get_content_length(&headers(" 5")).is_err());
78 assert!(get_content_length(&headers("")).is_err());
79 }
80}
81
82pub const DEFAULT_FORBIDDEN_HEADERS: [HeaderName; 9] = [
85 header::CONNECTION,
86 HeaderName::from_static("keep-alive"),
87 header::PROXY_AUTHENTICATE,
88 header::PROXY_AUTHORIZATION,
89 HeaderName::from_static("proxy-connection"),
90 header::TRANSFER_ENCODING,
91 header::UPGRADE,
92 header::HOST,
93 HeaderName::from_static("http2-settings"),
94];