in src/azure/client.rs [397:444]
fn parse_multipart_body_fields(body: Bytes, boundary: &[u8]) -> Result<Vec<MultipartField>> {
let start_marker = [b"--", boundary, b"\r\n"].concat();
let next_marker = &start_marker[..start_marker.len() - 2];
let end_marker = [b"--", boundary, b"--\r\n"].concat();
// There should be at most 256 responses per batch
let mut fields = Vec::with_capacity(256);
let mut remaining: &[u8] = body.as_ref();
loop {
remaining = remaining
.strip_prefix(start_marker.as_slice())
.ok_or_else(|| invalid_response("missing start marker for field"))?;
// The documentation only mentions two headers for fields, we leave some extra margin
let mut scratch = [httparse::EMPTY_HEADER; 10];
let mut headers = HeaderMap::new();
match httparse::parse_headers(remaining, &mut scratch) {
Ok(httparse::Status::Complete((pos, headers_slice))) => {
remaining = &remaining[pos..];
for header in headers_slice {
headers.insert(
HeaderName::from_bytes(header.name.as_bytes()).expect("valid"),
HeaderValue::from_bytes(header.value).expect("valid"),
);
}
}
_ => return Err(invalid_response("unable to parse field headers").into()),
};
let next_pos = remaining
.windows(next_marker.len())
.position(|window| window == next_marker)
.ok_or_else(|| invalid_response("early EOF while seeking to next boundary"))?;
fields.push(MultipartField {
headers,
content: body.slice_ref(&remaining[..next_pos]),
});
remaining = &remaining[next_pos..];
// Support missing final CRLF
if remaining == end_marker || remaining == &end_marker[..end_marker.len() - 2] {
break;
}
}
Ok(fields)
}