use crate::server::redirect;
use kern::Fail;
use std::io::prelude::*;
use std::net::TcpListener;
use std::sync::Arc;
use std::thread::spawn;
use std::thread::JoinHandle;
use std::time::Duration;
pub fn listen_redirect(
unsecure_addr: impl AsRef<str>,
secure_addr: String,
) -> Result<JoinHandle<()>, Fail> {
let listener = TcpListener::bind(unsecure_addr.as_ref()).or_else(Fail::from)?;
let secure_addr = Arc::new(secure_addr);
spawn(move || loop {
if let Ok((mut stream, _)) = listener.accept() {
let secure_addr = secure_addr.clone();
spawn(move || {
stream
.set_read_timeout(Some(Duration::from_secs(2)))
.unwrap();
let mut buf = Vec::new();
let mut temp_buf = vec![0u8; 64];
while !buf.contains(&b'\n') && buf.len() < 2048 {
let len = stream.read(&mut temp_buf).unwrap();
buf.extend(&temp_buf[..len]);
}
let pos = buf.iter().position(|&b| b == b'\r').unwrap();
buf.truncate(pos + 1);
let url = match String::from_utf8(buf) {
Ok(full_url) => full_url.split(' ').nth(1).unwrap().to_string(),
_ => panic!("Unsecure request line is not UTF-8"),
};
stream
.write_all(&redirect(&format!("https://{}{}", &secure_addr, url)))
.unwrap();
stream.flush().unwrap();
});
}
})
.join()
.or_else(|_| Fail::from("Thread crashed"))
}