| 153 | } |
| 154 | |
| 155 | fn decode_chunked_body(mut body: &[u8]) -> anyhow::Result<Vec<u8>> { |
| 156 | let mut decoded = Vec::new(); |
| 157 | loop { |
| 158 | let line_end = body |
| 159 | .windows(2) |
| 160 | .position(|window| window == b"\r\n") |
| 161 | .ok_or_else(|| anyhow::anyhow!("Chunked response ended before a chunk size."))?; |
| 162 | let size_text = std::str::from_utf8(&body[..line_end]) |
| 163 | .context("parse chunk size as UTF-8")? |
| 164 | .split(';') |
| 165 | .next() |
| 166 | .unwrap_or("") |
| 167 | .trim(); |
| 168 | let size = usize::from_str_radix(size_text, 16).context("parse chunk size")?; |
| 169 | body = &body[line_end + 2..]; |
| 170 | if size == 0 { |
| 171 | return Ok(decoded); |
| 172 | } |
| 173 | if body.len() < size + 2 { |
| 174 | anyhow::bail!("Chunked response ended before a full chunk."); |
| 175 | } |
| 176 | decoded.extend_from_slice(&body[..size]); |
| 177 | body = &body[size + 2..]; |
| 178 | } |
| 179 | } |
| 180 | |
| 181 | fn url_path_component(value: &str) -> String { |
| 182 | value |