tokio
This commit is contained in:
parent
772cb421cb
commit
e2e5138faf
8 changed files with 474 additions and 75 deletions
125
src/main.rs
125
src/main.rs
|
|
@ -1,54 +1,97 @@
|
|||
mod request;
|
||||
mod response;
|
||||
mod shared_enums;
|
||||
mod websoket_connection;
|
||||
|
||||
use std::{
|
||||
io::{BufReader, Write},
|
||||
net::TcpListener,
|
||||
time::Duration,
|
||||
};
|
||||
use std::time::Duration;
|
||||
use std::{path::Path, str::FromStr};
|
||||
|
||||
use tokio::io::AsyncWriteExt;
|
||||
use tokio::net::{TcpListener, TcpStream};
|
||||
use tokio::time;
|
||||
|
||||
use crate::websoket_connection::WebsocketConnection;
|
||||
use crate::{
|
||||
request::Connection,
|
||||
request::{Connection, ServerPath},
|
||||
response::{Response, ResponseCode, ResponseHeader},
|
||||
shared_enums::{Content, ContentType},
|
||||
};
|
||||
|
||||
fn main() -> std::io::Result<()> {
|
||||
let listener = TcpListener::bind("127.0.0.1:8080")?;
|
||||
for incoming_stream in listener.incoming() {
|
||||
let mut stream = incoming_stream?;
|
||||
stream.set_read_timeout(Some(Duration::from_millis(500)))?;
|
||||
#[tokio::main]
|
||||
async fn main() -> tokio::io::Result<()> {
|
||||
let listener = TcpListener::bind("127.0.0.1:8080").await?;
|
||||
loop {
|
||||
let (stream, _) = listener.accept().await?;
|
||||
|
||||
loop {
|
||||
let reader = BufReader::new(&stream);
|
||||
let req = match request::Request::from_bufreader(reader) {
|
||||
Ok(r) => r,
|
||||
Err(_) => break,
|
||||
};
|
||||
|
||||
println!("{req:?}");
|
||||
|
||||
let response = match req.path.to_matchable().as_slice(){
|
||||
["css.css"] => Response::new().with_code(ResponseCode::Ok).with_data(b"body{background-color: #121212;} h1{color: #ffffff;} p{color: #025da9;}".to_vec()).with_header(ResponseHeader::ContentType(Content::new(ContentType::Text(shared_enums::TextType::Css)))),
|
||||
|
||||
_ => Response::new()
|
||||
.with_code(ResponseCode::Ok)
|
||||
.with_data(b"<!doctype html><html lang=\"en\"><head><link rel=\"stylesheet\" href=\"css.css\"><meta charset=\"UTF-8\"/><title>Hello World!</title></head><body><h1>HTTP server testing</h1><p>Lorem ipsum</p></body></html>".to_vec())
|
||||
.with_header(ResponseHeader::ContentType(Content::html_utf8())).with_header(ResponseHeader::Connection(Connection::KeepAlive)),
|
||||
};
|
||||
|
||||
response.respond(&mut stream)?;
|
||||
|
||||
stream.flush()?;
|
||||
|
||||
if req.headers.contains(&request::RequestHeader::Connection(
|
||||
request::Connection::Close,
|
||||
)) {
|
||||
println!("Connection closed");
|
||||
break;
|
||||
}
|
||||
}
|
||||
tokio::spawn(handle_connection(stream));
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_connection(stream: TcpStream) -> tokio::io::Result<()> {
|
||||
if let Some(ws) = handle_http_connection(stream).await? {
|
||||
handle_websocket(ws).await?
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_http_connection(
|
||||
mut stream: TcpStream,
|
||||
) -> tokio::io::Result<Option<websoket_connection::WebsocketConnection>> {
|
||||
loop {
|
||||
let req = match time::timeout(
|
||||
Duration::from_millis(500),
|
||||
request::Request::from_bufreader(&mut stream),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(Ok(r)) => r,
|
||||
Ok(Err(_)) => {
|
||||
println!("Wrong request");
|
||||
break;
|
||||
}
|
||||
Err(_) => {
|
||||
println!("Timed out");
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
println!("{req:?}");
|
||||
|
||||
let response = match req.path.to_matchable().as_slice() {
|
||||
["public", file] => {
|
||||
match Response::from_file(Path::new(format!("./public/{file}").as_str())) {
|
||||
Ok(resp) => resp,
|
||||
Err(_) => Response::new().with_code(ResponseCode::NotFound),
|
||||
}
|
||||
}
|
||||
["websocket"] => {
|
||||
return Ok(Some(WebsocketConnection::initialize_connection(req)?));
|
||||
}
|
||||
[] => Response::new()
|
||||
.with_code(ResponseCode::PermanentRedirect)
|
||||
.with_header(ResponseHeader::Connection(Connection::KeepAlive))
|
||||
.with_header(ResponseHeader::Location(
|
||||
ServerPath::from_str("/public/index.html").unwrap(),
|
||||
)),
|
||||
|
||||
_ => Response::new().with_code(ResponseCode::NotFound),
|
||||
};
|
||||
|
||||
response.respond(&mut stream).await?;
|
||||
|
||||
stream.flush().await?;
|
||||
|
||||
if req.headers.contains(&request::RequestHeader::Connection(
|
||||
request::Connection::Close,
|
||||
)) {
|
||||
println!("Connection closed");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
async fn handle_websocket(mut web_socket: WebsocketConnection) -> tokio::io::Result<()> {
|
||||
todo!()
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue