use std::fmt;
use std::io::prelude::*;
use std::net::TcpStream;
enum Method {
GET,
}
impl fmt::Display for Method {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let s = match self {
Method::GET => "GET",
};
write!(f, "{}", s)
}
}
pub struct HttpRequest<'a> {
method: Method,
path: &'a str,
host: &'a str,
accept: &'a str,
connection: &'a str,
}
impl<'a> fmt::Display for HttpRequest<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{} {} HTTP/1.1\r\n\
HOST: {}\r\n\
Accept: {}\r\n\
Connection: {}\r\n\r\n",
self.method, self.path, self.host, self.accept, self.connection
)
}
}
impl<'a> HttpRequest<'a> {
pub fn new(url: &'a url::Url) -> anyhow::Result<Self> {
Ok(HttpRequest {
method: Method::GET,
path: url.path(),
host: url
.host_str()
.ok_or_else(|| anyhow::format_err!("The URl does not have a valid hose"))?,
accept: "*",
connection: "close",
})
}
pub fn run(&self) -> anyhow::Result<(usize, Vec<u8>, std::time::Duration)> {
let mut addr = self.host.to_string();
addr.push_str(":80");
let mut stream = TcpStream::connect(&addr)?;
stream.write(self.to_string().as_bytes())?;
let mut buff = vec![0u8; 4096];
let instant = std::time::Instant::now();
let amount_read = stream.read_to_end(&mut buff)?;
Ok((amount_read, buff, instant.elapsed()))
}
}