in key/aziot-key-client/src/lib.rs [504:566]
fn try_parse_response(
buf: &[u8],
new_read: usize,
) -> std::io::Result<Option<(Option<u16>, &[u8])>> {
let mut headers = [httparse::EMPTY_HEADER; 16];
let mut res = httparse::Response::new(&mut headers);
let body_start_pos = match res.parse(buf) {
Ok(httparse::Status::Complete(body_start_pos)) => body_start_pos,
Ok(httparse::Status::Partial) if new_read == 0 => return Ok(None),
Ok(httparse::Status::Partial) => return Err(std::io::ErrorKind::UnexpectedEof.into()),
Err(err) => return Err(std::io::Error::new(std::io::ErrorKind::Other, err)),
};
let res_status_code = res.code;
let mut content_length = None;
let mut is_json = false;
for header in &headers {
if header.name.eq_ignore_ascii_case("content-length") {
let value = std::str::from_utf8(header.value)
.map_err(|err| std::io::Error::new(std::io::ErrorKind::Other, err))?;
let value: usize = value
.parse()
.map_err(|err| std::io::Error::new(std::io::ErrorKind::Other, err))?;
content_length = Some(value);
} else if header.name.eq_ignore_ascii_case("content-type") {
let value = std::str::from_utf8(header.value)
.map_err(|err| std::io::Error::new(std::io::ErrorKind::Other, err))?;
if value == "application/json" {
is_json = true;
}
}
}
if (res_status_code == Some(204) && content_length.unwrap_or_default() != 0)
|| (res_status_code != Some(204) && !is_json)
{
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
"malformed HTTP response",
));
}
let body = &buf[body_start_pos..];
let body = if let Some(content_length) = content_length {
if body.len() < content_length {
return Ok(None);
}
&body[..content_length]
} else {
// Without a content-length, read until there's no more to read.
if new_read == 0 {
body
} else {
return Ok(None);
}
};
Ok(Some((res_status_code, body)))
}