direct_http/
direct_http.rs

1use serde::Serialize;
2use smol::prelude::*;
3use smol::io;
4
5use std::net::{ TcpListener, TcpStream, SocketAddr };
6use serde::Serializer;
7
8mod request;
9mod response;
10mod router;
11mod rate_limiter;
12
13pub use response::Response;
14pub use router::{ ResponseHandler, Router };
15pub use request::{ Request, Method };
16pub use rate_limiter::MutexLimiter as Limiter;
17
18#[derive(Copy, Clone)]
19pub enum Status {
20	Ok = 200,
21	Created = 201,
22	Accepted = 202,
23	NoContent = 204,
24	BadRequest = 400,
25	Unauthorized = 401,
26	Forbidden = 403,
27	NotFound = 404,
28	MethodNotAllowed = 405,
29	TooManyRequests = 429,
30	InternalServerError = 500,
31}
32
33impl Serialize for Status {
34	fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
35		serializer.serialize_i32(*self as i32)
36	}
37}
38
39pub struct Server {
40	listener: smol::Async<TcpListener>,
41}
42
43impl Server {
44	pub fn new(addr: &str) -> Self {
45		let addr_parsed: std::net::SocketAddr = addr.parse().expect("Failed to parse address");
46		let listener = smol::Async::<TcpListener>::bind(addr_parsed).expect("Failed to create api server");
47
48		Server {
49			listener,
50		}
51	}
52
53	pub fn listen(self, router: Router, limiter: Limiter) {
54		limiter.start();
55		let router: &'static Router = Box::leak(Box::new(router));
56		smol::spawn(async move { self.client_acceptor(router, limiter).await }).detach();
57	}
58
59	async fn client_acceptor(self, router: &'static Router, limiter: Limiter) {
60		while let Ok((stream, addr)) = self.listener.accept().await {
61			let limiter_clone = limiter.clone();
62			smol
63				::spawn(async move {
64					let _ = handler(stream, addr, router, limiter_clone).await;
65				})
66				.detach();
67		}
68	}
69}
70
71const BUFFER_SIZE: usize = 2048;
72const TIMEOUT: u64 = 60;
73
74async fn handler(mut stream: smol::Async<TcpStream>, addr: SocketAddr, router: &'static Router, limiter: Limiter) -> io::Result<()> {
75	let mut buffer = [0; BUFFER_SIZE];
76
77	let ip = addr.ip().to_string();
78
79	loop {
80		let mut keep_alive = false;
81
82		if stream.read_timeout().await {
83			break;
84		}
85
86		let bytes_read = stream.read(&mut buffer).await?;
87
88		if bytes_read == 0 {
89			break;
90		}
91
92		let response = {
93			if !limiter.server_allow() || !limiter.client_allow(ip.clone()) {
94				Response::status(Status::TooManyRequests).message("Muitas requisições foram feitas. Tente novamente em alguns segundos.").finish()
95			} else {
96				match Request::new(&buffer[..bytes_read]) {
97					Some(mut request) => {
98						keep_alive = request.headers.get("connection").is_some_and(|value| value == "keep-alive");
99						router::handle(&mut request, &router).finish()
100					}
101					None => {
102						continue;
103					}
104				}
105			}
106		};
107
108		if stream.write_timeout().await {
109			break;
110		}
111
112		stream.write(response.as_bytes()).await?;
113
114		stream.flush().await?;
115
116		if !keep_alive {
117			break;
118		}
119	}
120
121	stream.close().await
122}
123
124#[async_trait::async_trait]
125trait Timeout {
126	async fn write_timeout(&self) -> bool;
127	async fn read_timeout(&self) -> bool;
128}
129
130#[async_trait::async_trait]
131impl Timeout for smol::Async<TcpStream> {
132	async fn write_timeout(&self) -> bool {
133		smol::future::race(async { Ok(self.writable()) }, async { Err(timer(TIMEOUT).await) }).await.is_err()
134	}
135
136	async fn read_timeout(&self) -> bool {
137		smol::future::race(async { Ok(self.readable()) }, async { Err(timer(TIMEOUT).await) }).await.is_err()
138	}
139}
140
141async fn timer(seconds: u64) {
142	smol::Timer::after(std::time::Duration::from_secs(seconds)).await;
143}