use crate::http::{HttpRequest, parse_url, read_response, write_request};
use sim_kernel::{Error, Result};
use std::{net::TcpStream, time::Duration};
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct HttpGetResponse {
pub status: u16,
pub url: String,
pub body: Vec<u8>,
}
pub fn http_get(url: &str, timeout: Duration, max_body_bytes: usize) -> Result<HttpGetResponse> {
let parsed = parse_url(url, "http", "/")?;
let mut stream =
TcpStream::connect((parsed.host.as_str(), parsed.port)).map_err(host_io_error)?;
stream
.set_read_timeout(Some(timeout))
.map_err(host_io_error)?;
stream
.set_write_timeout(Some(timeout))
.map_err(host_io_error)?;
write_request(
&mut stream,
&HttpRequest {
method: "GET".to_owned(),
path: parsed.path.clone(),
headers: vec![("Host".to_owned(), parsed.host.clone())],
body: Vec::new(),
},
)?;
let response = read_response(&mut stream)?;
if response.body.len() > max_body_bytes {
return Err(Error::Eval(format!(
"http response exceeded {max_body_bytes} bytes"
)));
}
Ok(HttpGetResponse {
status: response.status,
url: url.to_owned(),
body: response.body,
})
}
fn host_io_error(error: std::io::Error) -> Error {
Error::HostError(error.to_string())
}