diff options
| author | Fuwn <[email protected]> | 2022-03-27 03:57:18 +0000 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2022-03-27 03:57:18 +0000 |
| commit | bb012b09bc74a1b37ae662c3fc6c50aec515e832 (patch) | |
| tree | eb6f290502de36c0fe43d6fcdc7a49c1f0ae16da | |
| parent | feat(router): modules (diff) | |
| download | windmark-bb012b09bc74a1b37ae662c3fc6c50aec515e832.tar.xz windmark-bb012b09bc74a1b37ae662c3fc6c50aec515e832.zip | |
feat(router): async!
| -rw-r--r-- | Cargo.toml | 7 | ||||
| -rw-r--r-- | examples/windmark.rs | 4 | ||||
| -rw-r--r-- | src/lib.rs | 42 | ||||
| -rw-r--r-- | src/returnable.rs | 3 |
4 files changed, 35 insertions, 21 deletions
@@ -15,18 +15,19 @@ keywords = ["gemini"] categories = ["web-programming"] [features] -logger = ["pretty_env_logger", "log"] +logger = ["pretty_env_logger"] [dependencies] # TCP openssl = "0.10.38" -# tokio = { version = "1.17.0", features = ["full"] } +tokio = { version = "0.2.4", features = ["full"] } # tokio-openssl = "0.5.0" # tokio-uds = "0.2.7" +tokio-openssl = "0.4.0" # Logging pretty_env_logger = { version = "0.4.0", optional = true } -log = { version = "0.4.16", optional = true } +log = "0.4.16" # URL url = "2.2.2" diff --git a/examples/windmark.rs b/examples/windmark.rs index e1cb513..a733be2 100644 --- a/examples/windmark.rs +++ b/examples/windmark.rs @@ -23,7 +23,8 @@ extern crate log; use windmark::Response; -fn main() -> std::io::Result<()> { +#[tokio::main] +async fn main() -> std::io::Result<()> { windmark::Router::new() .set_private_key_file("windmark_private.pem") .set_certificate_chain_file("windmark_pair.pem") @@ -107,4 +108,5 @@ fn main() -> std::io::Result<()> { } }) .run() + .await } @@ -33,15 +33,19 @@ pub(crate) mod returnable; pub mod status; pub mod utilities; -#[cfg(feature = "logger")] #[macro_use] extern crate log; -use std::{net::TcpStream, sync::Arc}; +use std::sync::Arc; use matchit::Params; use openssl::ssl::{self, SslAcceptor, SslMethod}; pub use response::Response; +use tokio::{ + io::{AsyncReadExt, AsyncWriteExt}, + net::TcpStream, + stream::StreamExt, +}; use url::Url; use crate::{ @@ -205,7 +209,7 @@ impl Router { /// # Errors /// /// if the `TcpListener` could not be bound. - pub fn run(&mut self) -> std::io::Result<()> { + pub async fn run(&mut self) -> std::io::Result<()> { self.create_acceptor(); #[cfg(feature = "logger")] @@ -214,31 +218,39 @@ impl Router { } let acceptor = self.ssl_acceptor.clone(); - let listener = std::net::TcpListener::bind("0.0.0.0:1965")?; + let mut listener = tokio::net::TcpListener::bind("0.0.0.0:1965").await?; #[cfg(feature = "logger")] info!("windmark is listening for connections"); - for stream in listener.incoming() { + while let Some(stream) = listener.incoming().next().await { match stream { Ok(stream) => { let acceptor = acceptor.clone(); let self_clone = self.clone(); - std::thread::spawn(move || { - let mut stream = acceptor.accept(stream).unwrap(); - - self_clone.handle(&mut stream); + tokio::spawn(async move { + match tokio_openssl::accept(&acceptor, stream).await { + Ok(mut stream) => { + if let Err(e) = self_clone.handle(&mut stream).await { + error!("handle error: {}", e); + } + } + Err(e) => error!("ssl error: {:?}", e), + } }); } - Err(e) => eprintln!("tcp error: {:?}", e), + Err(e) => error!("tcp error: {:?}", e), } } Ok(()) } - fn handle(&self, stream: &mut ssl::SslStream<std::net::TcpStream>) { + async fn handle( + &self, + stream: &mut tokio_openssl::SslStream<tokio::net::TcpStream>, + ) -> std::io::Result<()> { let mut buffer = [0u8; 1024]; let mut url = Url::parse("gemini://fuwn.me/").unwrap(); let mut response_status = 0; @@ -246,7 +258,7 @@ impl Router { let mut header = String::new(); let content; - while let Ok(size) = stream.ssl_read(&mut buffer) { + while let Ok(size) = stream.read(&mut buffer).await { let content = String::from_utf8(buffer[0..size].to_vec()).unwrap(); url = url::Url::parse(&content.replace("\r\n", "")).unwrap(); @@ -311,7 +323,7 @@ impl Router { } stream - .ssl_write( + .write_all( format!( "{}{}\r\n{}", response_status, @@ -326,7 +338,7 @@ impl Router { ) .as_bytes(), ) - .unwrap(); + .await?; (self.post_route_callback)(stream.get_ref(), &url, { if let Ok(route) = &route { @@ -336,7 +348,7 @@ impl Router { } }); - stream.shutdown().unwrap(); + stream.shutdown().await } fn create_acceptor(&mut self) { diff --git a/src/returnable.rs b/src/returnable.rs index 79a3d7a..8f4ee81 100644 --- a/src/returnable.rs +++ b/src/returnable.rs @@ -16,9 +16,8 @@ // Copyright (C) 2022-2022 Fuwn <[email protected]> // SPDX-License-Identifier: GPL-3.0-only -use std::net::TcpStream; - use matchit::Params; +use tokio::net::TcpStream; use url::Url; pub struct RouteContext<'a> { |