MCPcopy Create free account
hub / github.com/NVIDIA/OpenShell / parse_body_length

Function parse_body_length

crates/openshell-supervisor-network/src/l7/rest.rs:1691–1732  ·  view source on GitHub ↗

Parse Content-Length or Transfer-Encoding from HTTP headers. Per RFC 7230 Section 3.3.3, rejects requests containing both `Content-Length` and `Transfer-Encoding` headers to prevent request smuggling via CL/TE ambiguity.

(headers: &str)

Source from the content-addressed store, hash-verified

1689/// `Content-Length` and `Transfer-Encoding` headers to prevent request
1690/// smuggling via CL/TE ambiguity.
1691pub(crate) fn parse_body_length(headers: &str) -> Result<BodyLength> {
1692 let mut has_te_chunked = false;
1693 let mut cl_value: Option<u64> = None;
1694
1695 for line in headers.lines().skip(1) {
1696 let lower = line.to_ascii_lowercase();
1697 if lower.starts_with("transfer-encoding:") {
1698 let val = lower.split_once(':').map_or("", |(_, v)| v.trim());
1699 if val.split(',').any(|enc| enc.trim() == "chunked") {
1700 has_te_chunked = true;
1701 }
1702 }
1703 if lower.starts_with("content-length:") {
1704 let val = lower.split_once(':').map_or("", |(_, v)| v.trim());
1705 let len: u64 = val
1706 .parse()
1707 .map_err(|_| miette!("Request contains invalid Content-Length value"))?;
1708 if let Some(prev) = cl_value
1709 && prev != len
1710 {
1711 return Err(miette!(
1712 "Request contains multiple Content-Length headers with differing values ({prev} vs {len})"
1713 ));
1714 }
1715 cl_value = Some(len);
1716 }
1717 }
1718
1719 if has_te_chunked && cl_value.is_some() {
1720 return Err(miette!(
1721 "Request contains both Transfer-Encoding and Content-Length headers"
1722 ));
1723 }
1724
1725 if has_te_chunked {
1726 return Ok(BodyLength::Chunked);
1727 }
1728 if let Some(len) = cl_value {
1729 return Ok(BodyLength::ContentLength(len));
1730 }
1731 Ok(BodyLength::None)
1732}
1733
1734/// Relay exactly `len` bytes from reader to writer.
1735async fn relay_fixed<R, W>(

Callers 11

handle_forward_proxyFunction · 0.85
parse_http_requestFunction · 0.85
relay_responseFunction · 0.85
parse_content_lengthFunction · 0.85
parse_chunkedFunction · 0.85
parse_no_bodyFunction · 0.85
te_substring_not_chunkedFunction · 0.85

Calls 1

parseMethod · 0.45

Tested by 5

parse_content_lengthFunction · 0.68
parse_chunkedFunction · 0.68
parse_no_bodyFunction · 0.68
te_substring_not_chunkedFunction · 0.68