(mut body: &[u8])
| 1127 | } |
| 1128 | |
| 1129 | fn decode_chunked_body(mut body: &[u8]) -> Result<Vec<u8>, String> { |
| 1130 | let mut decoded = Vec::new(); |
| 1131 | loop { |
| 1132 | let line_end = body |
| 1133 | .windows(2) |
| 1134 | .position(|window| window == b"\r\n") |
| 1135 | .ok_or_else(|| "Metro returned malformed chunked HTTP.".to_owned())?; |
| 1136 | let size_line = std::str::from_utf8(&body[..line_end]) |
| 1137 | .map_err(|_| "Metro returned non-UTF-8 chunk metadata.".to_owned())?; |
| 1138 | let size_text = size_line.split(';').next().unwrap_or("").trim(); |
| 1139 | let size = usize::from_str_radix(size_text, 16) |
| 1140 | .map_err(|_| "Metro returned invalid chunk size.".to_owned())?; |
| 1141 | body = &body[line_end + 2..]; |
| 1142 | if size == 0 { |
| 1143 | return Ok(decoded); |
| 1144 | } |
| 1145 | if body.len() < size + 2 || body.get(size..size + 2) != Some(b"\r\n") { |
| 1146 | return Err("Metro returned truncated chunked HTTP.".to_owned()); |
| 1147 | } |
| 1148 | decoded.extend_from_slice(&body[..size]); |
| 1149 | body = &body[size + 2..]; |
| 1150 | } |
| 1151 | } |
| 1152 | |
| 1153 | fn split_path_query(value: &str) -> (&str, Option<&str>) { |
| 1154 | match value.split_once('?') { |
no test coverage detected