diff --git a/Cargo.lock b/Cargo.lock index fa3da05..a1f6d00 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -81,6 +81,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "async-trait" +version = "0.1.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "atomic-waker" version = "1.1.2" @@ -93,6 +104,61 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +[[package]] +name = "axum" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" +dependencies = [ + "async-trait", + "axum-core", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper 1.0.1", + "tokio", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-core" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "sync_wrapper 0.1.2", + "tower-layer", + "tower-service", + "tracing", +] + [[package]] name = "backtrace" version = "0.3.71" @@ -1384,25 +1450,6 @@ dependencies = [ "phf", ] -[[package]] -name = "h2" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http 0.2.12", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - [[package]] name = "h2" version = "0.4.5" @@ -1414,7 +1461,7 @@ dependencies = [ "fnv", "futures-core", "futures-sink", - "http 1.1.0", + "http", "indexmap", "slab", "tokio", @@ -1465,17 +1512,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "http" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - [[package]] name = "http" version = "1.1.0" @@ -1487,17 +1523,6 @@ dependencies = [ "itoa", ] -[[package]] -name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes", - "http 0.2.12", - "pin-project-lite", -] - [[package]] name = "http-body" version = "1.0.0" @@ -1505,7 +1530,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" dependencies = [ "bytes", - "http 1.1.0", + "http", ] [[package]] @@ -1516,8 +1541,8 @@ checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" dependencies = [ "bytes", "futures-core", - "http 1.1.0", - "http-body 1.0.0", + "http", + "http-body", "pin-project-lite", ] @@ -1533,30 +1558,6 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" -[[package]] -name = "hyper" -version = "0.14.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2 0.3.26", - "http 0.2.12", - "http-body 0.4.6", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", -] - [[package]] name = "hyper" version = "1.3.1" @@ -1566,10 +1567,11 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.5", - "http 1.1.0", - "http-body 1.0.0", + "h2", + "http", + "http-body", "httparse", + "httpdate", "itoa", "pin-project-lite", "smallvec", @@ -1584,8 +1586,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c" dependencies = [ "futures-util", - "http 1.1.0", - "hyper 1.3.1", + "http", + "hyper", "hyper-util", "rustls", "rustls-pki-types", @@ -1602,7 +1604,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", "http-body-util", - "hyper 1.3.1", + "hyper", "hyper-util", "native-tls", "tokio", @@ -1619,9 +1621,9 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http 1.1.0", - "http-body 1.0.0", - "hyper 1.3.1", + "http", + "http-body", + "hyper", "pin-project-lite", "socket2", "tokio", @@ -1759,6 +1761,12 @@ dependencies = [ "regex-automata 0.1.10", ] +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + [[package]] name = "maud" version = "0.26.0" @@ -2269,11 +2277,11 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.4.5", - "http 1.1.0", - "http-body 1.0.0", + "h2", + "http", + "http-body", "http-body-util", - "hyper 1.3.1", + "hyper", "hyper-rustls", "hyper-tls", "hyper-util", @@ -2292,7 +2300,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", - "sync_wrapper", + "sync_wrapper 0.1.2", "system-configuration", "tokio", "tokio-native-tls", @@ -2447,6 +2455,12 @@ dependencies = [ "owned_ttf_parser", ] +[[package]] +name = "rustversion" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" + [[package]] name = "ryu" version = "1.0.18" @@ -2540,6 +2554,16 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_path_to_error" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" +dependencies = [ + "itoa", + "serde", +] + [[package]] name = "serde_spanned" version = "0.6.6" @@ -2598,6 +2622,7 @@ name = "shiny-robots" version = "0.1.0" dependencies = [ "anyhow", + "axum", "badge", "cadence", "crates-index", @@ -2607,7 +2632,6 @@ dependencies = [ "futures-util", "gix", "grass", - "hyper 0.14.28", "indexmap", "lru_time_cache", "maud", @@ -2623,6 +2647,7 @@ dependencies = [ "sha-1", "tokio", "toml 0.8.13", + "tower", "tracing", "tracing-subscriber", ] @@ -2713,6 +2738,12 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +[[package]] +name = "sync_wrapper" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" + [[package]] name = "system-configuration" version = "0.5.1" @@ -2744,7 +2775,7 @@ dependencies = [ "crossbeam-channel", "gix", "home", - "http 1.1.0", + "http", "libc", "memchr", "rayon", @@ -2992,6 +3023,7 @@ dependencies = [ "tokio", "tower-layer", "tower-service", + "tracing", ] [[package]] @@ -3012,6 +3044,7 @@ version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ + "log", "pin-project-lite", "tracing-attributes", "tracing-core", diff --git a/Cargo.toml b/Cargo.toml index dccc01c..5480416 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,13 +15,13 @@ edition = "2021" badge = { path = "./libs/badge" } anyhow = "1" +axum = "0.7" cadence = "1" crates-index = { version = "2", default-features = false, features = ["git"] } derive_more = "0.99" dotenvy = "0.15" font-awesome-as-a-crate = "0.3" futures-util = { version = "0.3", default-features = false, features = ["std"] } -hyper = { version = "0.14.10", features = ["full"] } indexmap = { version = "2", features = ["serde"] } lru_time_cache = "0.11" maud = "0.26" @@ -36,6 +36,7 @@ serde = { version = "1", features = ["derive"] } serde_urlencoded = "0.7" tokio = { version = "1.24.2", features = ["rt-multi-thread", "macros", "sync", "time"] } toml = "0.8" +tower = "0.4" tracing = "0.1.30" tracing-subscriber = { version = "0.3", features = ["env-filter"] } diff --git a/src/engine/mod.rs b/src/engine/mod.rs index 0193845..8679a00 100644 --- a/src/engine/mod.rs +++ b/src/engine/mod.rs @@ -13,11 +13,11 @@ use futures_util::{ stream::{self, BoxStream}, StreamExt as _, }; -use hyper::service::Service; use once_cell::sync::Lazy; use relative_path::{RelativePath, RelativePathBuf}; use rustsec::database::Database; use semver::VersionReq; +use tower::Service; use crate::interactors::crates::{GetPopularCrates, QueryCrate}; use crate::interactors::github::GetPopularRepos; diff --git a/src/interactors/crates.rs b/src/interactors/crates.rs index e490a64..971fbdf 100644 --- a/src/interactors/crates.rs +++ b/src/interactors/crates.rs @@ -3,9 +3,9 @@ use std::{fmt, str, task::Context, task::Poll}; use anyhow::{anyhow, Error}; use crates_index::{Crate, DependencyKind}; use futures_util::FutureExt as _; -use hyper::service::Service; use semver::{Version, VersionReq}; use serde::Deserialize; +use tower::Service; use tokio::task::spawn_blocking; diff --git a/src/interactors/github.rs b/src/interactors/github.rs index 32d5c86..35cd0b2 100644 --- a/src/interactors/github.rs +++ b/src/interactors/github.rs @@ -6,8 +6,8 @@ use std::{ use anyhow::Error; use futures_util::FutureExt as _; -use hyper::service::Service; use serde::Deserialize; +use tower::Service; use crate::{ models::repo::{RepoPath, Repository}, diff --git a/src/interactors/mod.rs b/src/interactors/mod.rs index 030174f..b6291cf 100644 --- a/src/interactors/mod.rs +++ b/src/interactors/mod.rs @@ -5,8 +5,8 @@ use std::{ use anyhow::{anyhow, Error}; use futures_util::FutureExt as _; -use hyper::service::Service; use relative_path::RelativePathBuf; +use tower::Service; use crate::{models::repo::RepoPath, BoxFuture}; diff --git a/src/interactors/rustsec.rs b/src/interactors/rustsec.rs index e28488e..0513179 100644 --- a/src/interactors/rustsec.rs +++ b/src/interactors/rustsec.rs @@ -2,8 +2,8 @@ use std::{fmt, sync::Arc, task::Context, task::Poll}; use anyhow::Error; use futures_util::FutureExt as _; -use hyper::service::Service; use rustsec::database::Database; +use tower::Service; use crate::BoxFuture; diff --git a/src/main.rs b/src/main.rs index 0b2d451..43a9113 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,13 +9,8 @@ use std::{ time::Duration, }; +use axum::{extract::Request, Router}; use cadence::{QueuingMetricSink, UdpMetricSink}; -use hyper::{ - server::conn::AddrStream, - service::{make_service_fn, service_fn}, - Server, -}; - use reqwest::redirect::Policy as RedirectPolicy; use tracing::Instrument as _; @@ -95,25 +90,20 @@ async fn main() { let mut engine = Engine::new(client.clone(), index); engine.set_metrics(metrics); - let make_svc = make_service_fn(move |_socket: &AddrStream| { - let engine = engine.clone(); + let app = App::new(engine.clone()); - async move { - let server = App::new(engine.clone()); - Ok::<_, hyper::Error>(service_fn(move |req| { - let server = server.clone(); - async move { - let path = req.uri().path().to_owned(); + let lst = tokio::net::TcpListener::bind(addr).await.unwrap(); - server - .handle(req) - .instrument(tracing::info_span!("@", %path)) - .await - } - })) - } + let router = Router::new().fallback(|req: Request| async move { + let path = req.uri().path().to_owned(); + + app.handle(req) + .instrument(tracing::info_span!("@", %path)) + .await + .unwrap() }); - let server = Server::bind(&addr).serve(make_svc); + + let server = axum::serve(lst, router); tracing::info!("Server running on port {port}"); diff --git a/src/server/mod.rs b/src/server/mod.rs index de32d29..e746bdc 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -1,11 +1,16 @@ use std::{env, sync::Arc, time::Instant}; +use axum::{ + body::Body, + extract::Request, + http::{ + header::{CACHE_CONTROL, CONTENT_TYPE, ETAG, LOCATION}, + Method, StatusCode, + }, + response::Response, +}; use badge::BadgeStyle; use futures_util::future; -use hyper::{ - header::{CACHE_CONTROL, CONTENT_TYPE, ETAG, LOCATION}, - Body, Error as HyperError, Method, Request, Response, StatusCode, -}; use once_cell::sync::Lazy; use route_recognizer::{Params, Router}; use semver::VersionReq; @@ -86,7 +91,7 @@ impl App { } } - pub async fn handle(&self, req: Request) -> Result, HyperError> { + pub async fn handle(&self, req: Request) -> Result, axum::Error> { let start = Instant::now(); // allows `/path/` to also match `/path` @@ -143,7 +148,7 @@ impl App { &self, _req: Request, _params: Params, - ) -> Result, HyperError> { + ) -> Result, axum::Error> { let engine = self.engine.clone(); let popular = @@ -168,7 +173,7 @@ impl App { req: Request, params: Params, format: StatusFormat, - ) -> Result, HyperError> { + ) -> Result, axum::Error> { let server = self.clone(); let site = params.find("site").expect("route param 'site' not found"); @@ -225,7 +230,7 @@ impl App { &self, _req: Request, params: Params, - ) -> Result, HyperError> { + ) -> Result, axum::Error> { let engine = self.engine.clone(); let name = params.find("name").expect("route param 'name' not found"); @@ -291,7 +296,7 @@ impl App { req: Request, params: Params, format: StatusFormat, - ) -> Result, HyperError> { + ) -> Result, axum::Error> { let server = self.clone(); let name = params.find("name").expect("route param 'name' not found"); diff --git a/src/server/views/badge.rs b/src/server/views/badge.rs index 0ee55c5..ffc59a1 100644 --- a/src/server/views/badge.rs +++ b/src/server/views/badge.rs @@ -1,6 +1,7 @@ +use axum::body::Body; +use axum::http::header::CONTENT_TYPE; +use axum::response::Response; use badge::{Badge, BadgeOptions}; -use hyper::header::CONTENT_TYPE; -use hyper::{Body, Response}; use crate::engine::AnalyzeDependenciesOutcome; use crate::server::ExtraConfig; diff --git a/src/server/views/html/error.rs b/src/server/views/html/error.rs index f5802e2..dfab2ee 100644 --- a/src/server/views/html/error.rs +++ b/src/server/views/html/error.rs @@ -1,6 +1,10 @@ -use hyper::{ - header::{CACHE_CONTROL, CONTENT_TYPE}, - Body, Response, StatusCode, +use axum::{ + body::Body, + http::{ + header::{CACHE_CONTROL, CONTENT_TYPE}, + StatusCode, + }, + response::Response, }; use maud::html; diff --git a/src/server/views/html/index.rs b/src/server/views/html/index.rs index a1ccae0..42bd174 100644 --- a/src/server/views/html/index.rs +++ b/src/server/views/html/index.rs @@ -1,4 +1,4 @@ -use hyper::{Body, Response}; +use axum::{body::Body, response::Response}; use maud::{html, Markup}; use crate::models::crates::CratePath; diff --git a/src/server/views/html/mod.rs b/src/server/views/html/mod.rs index 2f3457b..bfef5a7 100644 --- a/src/server/views/html/mod.rs +++ b/src/server/views/html/mod.rs @@ -1,7 +1,7 @@ use std::time::Duration; -use hyper::header::CONTENT_TYPE; -use hyper::{Body, Response}; +use axum::http::header::CONTENT_TYPE; +use axum::{body::Body, response::Response}; use maud::{html, Markup, Render, DOCTYPE}; pub mod error; diff --git a/src/server/views/html/status.rs b/src/server/views/html/status.rs index 19c0d23..e010e73 100644 --- a/src/server/views/html/status.rs +++ b/src/server/views/html/status.rs @@ -1,5 +1,5 @@ +use axum::{body::Body, response::Response}; use font_awesome_as_a_crate::{svg as fa, Type as FaType}; -use hyper::{Body, Response}; use indexmap::IndexMap; use maud::{html, Markup, PreEscaped}; use pulldown_cmark::{html, Parser}; diff --git a/src/utils/cache.rs b/src/utils/cache.rs index a09c706..7408b00 100644 --- a/src/utils/cache.rs +++ b/src/utils/cache.rs @@ -1,9 +1,9 @@ use std::{fmt, sync::Arc, time::Duration}; use derive_more::{Display, Error, From}; -use hyper::service::Service; use lru_time_cache::LruCache; use tokio::sync::Mutex; +use tower::Service; #[derive(Debug, Clone, Display, From, Error)] pub struct CacheError {