direct_http/
direct_http.rs1use 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}