in src/main.rs [20:77]
fn request(
method: &str,
path: &str,
headers: HashMap<String, String>,
) -> std::io::Result<(u64, Vec<u8>)> {
let imds_url = get_imds_url();
let mut socket = TcpStream::connect(imds_url)?;
let header = format!(
"{} /{} HTTP/1.1\r\n{}\r\n",
method,
path,
headers
.iter()
.map(|(i, x)| format!("{}: {}\r\n", i, x))
.collect::<Vec<_>>()
.join("")
);
socket.write_all(header.as_bytes())?;
socket.flush()?;
let mut buf = Vec::new();
socket
.read_to_end(&mut buf)
.expect("failed to read response");
// We now want to extract the headers, we get each header line by ites delim "\r\n"
let mut header_lines: Vec<String> = Vec::new();
let mut header_buf: Vec<u8> = Vec::new();
let mut index = 0;
while index < buf.len() {
if index <= buf.len() - 2 && buf[index] == b'\r' && buf[index + 1] == b'\n' {
if header_buf.is_empty() {
// We are at the end of our headers
index += 2;
break;
} else {
let header = String::from_utf8(header_buf).expect("failed to parse header");
header_lines.push(header.clone());
header_buf = Vec::new();
index += 2;
}
} else {
header_buf.push(buf[index]);
index += 1;
}
}
// The first line will contain the response type
let response_status: Vec<&str> = header_lines[0].split_whitespace().collect();
// The important part here is the part 2 status code
let status_code = response_status[1];
let data = buf[index..].to_vec();
Ok((status_code.parse::<u64>().unwrap(), data))
}