Allow Passwords for server
This commit is contained in:
parent
5020406acc
commit
ef1afa42fa
97
src/main.rs
97
src/main.rs
@ -31,10 +31,11 @@ fn main() {
|
||||
let mut args = env::args();
|
||||
args.next();
|
||||
let address = args.next().unwrap_or("127.0.0.1:8080".to_string());
|
||||
start_server(path, &address);
|
||||
let password = args.next();
|
||||
start_server(path, &address, password);
|
||||
}
|
||||
|
||||
fn start_server(path: PathBuf, address: &str) {
|
||||
fn start_server(path: PathBuf, address: &str, password: Option<String>) {
|
||||
let listener = TcpListener::bind(address).expect("Invalid bind address!");
|
||||
eprintln!("Strated server!");
|
||||
|
||||
@ -58,7 +59,8 @@ fn start_server(path: PathBuf, address: &str) {
|
||||
|
||||
let context = context.clone();
|
||||
let path = path.clone();
|
||||
pool.execute(move || handle_connection(context, path, stream));
|
||||
let password = password.clone();
|
||||
pool.execute(move || handle_connection(context, path, stream, password.as_deref()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,7 +141,12 @@ struct Context {
|
||||
infos: HashMap<Box<str>, Arc<Mutex<SiteInfo>>>,
|
||||
}
|
||||
|
||||
fn handle_connection(context: Arc<Mutex<Context>>, path: PathBuf, mut stream: TcpStream) {
|
||||
fn handle_connection(
|
||||
context: Arc<Mutex<Context>>,
|
||||
path: PathBuf,
|
||||
mut stream: TcpStream,
|
||||
password: Option<&str>,
|
||||
) {
|
||||
let Some(request) = Request::from(&stream) else {
|
||||
eprintln!("Invalid request!");
|
||||
return;
|
||||
@ -151,12 +158,86 @@ fn handle_connection(context: Arc<Mutex<Context>>, path: PathBuf, mut stream: Tc
|
||||
eprintln!("- Path: {}", request.path);
|
||||
eprintln!("- Version: {}", request.version);
|
||||
eprintln!("- Headers:");
|
||||
for header in request.headers {
|
||||
for header in &request.headers {
|
||||
eprintln!(" - {header}");
|
||||
}
|
||||
eprintln!("- Body: {}", request.body);
|
||||
eprintln!();
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
enum Access {
|
||||
None,
|
||||
Full,
|
||||
}
|
||||
|
||||
let mut access = Access::None;
|
||||
|
||||
let mut cookie = None;
|
||||
|
||||
if let Some(password) = password {
|
||||
for entry in request.body.split('&') {
|
||||
let Some((key, input)) = entry.split_once('=') else {
|
||||
continue;
|
||||
};
|
||||
|
||||
if key == "password" && input == password {
|
||||
access = Access::Full;
|
||||
cookie = Some(password);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if access == Access::None {
|
||||
for header in request.headers {
|
||||
let Some((key, values)) = header.split_once(':') else {
|
||||
continue;
|
||||
};
|
||||
let key = key.trim();
|
||||
|
||||
if key != "Cookie" {
|
||||
continue;
|
||||
}
|
||||
|
||||
for cookie in values.split(',') {
|
||||
let cookie = cookie.trim();
|
||||
let Some((name, state)) = cookie.split_once('=') else {
|
||||
continue;
|
||||
};
|
||||
if name != "password" {
|
||||
continue;
|
||||
}
|
||||
|
||||
if state != password {
|
||||
continue;
|
||||
}
|
||||
|
||||
access = Access::Full;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if access == Access::None {
|
||||
let _ = write!(stream, "HTTP/1.1 200 OK\r\n");
|
||||
let _ = write!(stream, "Content-Type: text/html; charset=\"utf-8\"\r\n");
|
||||
let _ = write!(stream, "\r\n");
|
||||
|
||||
let html = html! {
|
||||
h1 { "Authentification required" }
|
||||
form method="POST" {
|
||||
input type="password" name="password" placeholder="Password";
|
||||
br;
|
||||
input type="submit" value="Authenticate!";
|
||||
}
|
||||
};
|
||||
|
||||
let _ = stream.write_all(html.into_string().as_bytes());
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let (mut relative_path, _) = request
|
||||
.path
|
||||
.split_once('?')
|
||||
@ -261,6 +342,7 @@ fn handle_connection(context: Arc<Mutex<Context>>, path: PathBuf, mut stream: Tc
|
||||
file_paths,
|
||||
partial,
|
||||
start_level,
|
||||
cookie,
|
||||
)
|
||||
}
|
||||
|
||||
@ -301,6 +383,7 @@ fn handle_relative_connection(
|
||||
file_paths: DocumentPaths,
|
||||
partial: Option<usize>,
|
||||
start_level: usize,
|
||||
cookie: Option<&str>,
|
||||
) {
|
||||
let mut name = None;
|
||||
let mut text = None;
|
||||
@ -374,6 +457,10 @@ fn handle_relative_connection(
|
||||
|
||||
let _ = write!(stream, "HTTP/1.1 200 OK\r\n");
|
||||
let _ = write!(stream, "Content-Type: text/html; charset=\"utf-8\"\r\n");
|
||||
if let Some(password) = cookie {
|
||||
let _ = write!(stream, "Set-Cookie: password={password}\r\n");
|
||||
}
|
||||
|
||||
let _ = write!(stream, "\r\n");
|
||||
|
||||
let parent_path = relative_path
|
||||
|
||||
Loading…
Reference in New Issue
Block a user