Skip to content

Commit

Permalink
upgrade axum, hyper, http, sentry & tower-http
Browse files Browse the repository at this point in the history
  • Loading branch information
syphar committed Jan 3, 2024
1 parent a851b1d commit 61009f3
Show file tree
Hide file tree
Showing 13 changed files with 286 additions and 184 deletions.
281 changes: 189 additions & 92 deletions Cargo.lock

Large diffs are not rendered by default.

21 changes: 11 additions & 10 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ exclude = [
consistency_check = ["crates-index", "itertools"]

[dependencies]
sentry = "0.31.0"
sentry-panic = "0.31.0"
sentry-tracing = "0.31.0"
sentry-tower = { version = "0.31.0", features = ["http"] }
sentry-anyhow = { version = "0.31.0", features = ["backtrace"] }
sentry = "0.32.1"
sentry-panic = "0.32.1"
sentry-tracing = "0.32.1"
sentry-tower = { version = "0.32.1", features = ["http"] }
sentry-anyhow = { version = "0.32.1", features = ["backtrace"] }
log = "0.4"
tracing = "0.1.37"
tracing-subscriber = { version = "0.3.16", default-features = false, features = ["ansi", "fmt", "env-filter", "tracing-log"] }
Expand Down Expand Up @@ -78,20 +78,20 @@ aws-config = "1.0.0"
aws-sdk-s3 = "1.3.0"
aws-sdk-cloudfront = "1.3.0"
aws-smithy-types-convert = { version = "0.60.0", features = ["convert-chrono"] }
http = "0.2.6"
http = "1.0.0"
uuid = { version = "1.1.2", features = ["v4"]}

# Data serialization and deserialization
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

# axum dependencies
axum = { version = "0.6.1", features = ["headers"]}
axum-extra = "0.8.0"
hyper = { version = "0.14.15", default-features = false }
axum = "0.7.3"
axum-extra = { version = "0.9.1", features = ["typed-header"] }
hyper = { version = "1.1.0", default-features = false }
tower = "0.4.11"
tower-service = "0.3.2"
tower-http = { version = "0.4.0", features = ["fs", "trace", "timeout", "catch-panic"] }
tower-http = { version = "0.5.0", features = ["fs", "trace", "timeout", "catch-panic"] }
mime = "0.3.16"
percent-encoding = "2.2.0"

Expand Down Expand Up @@ -120,6 +120,7 @@ procfs = "0.15.1"
[dev-dependencies]
criterion = "0.5.1"
kuchikiki = "0.8"
http02 = { version = "0.2.11", package = "http"}
rand = "0.8"
mockito = "1.0.2"
test-case = "3.0.0"
Expand Down
18 changes: 9 additions & 9 deletions src/cdn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -959,16 +959,16 @@ mod tests {
#[tokio::test]
async fn invalidate_path() {
let conn = StaticReplayClient::new(vec![ReplayEvent::new(
http::Request::builder()
http02::Request::builder()
.header("content-type", "application/xml")
.uri(http::uri::Uri::from_static(
.uri(http02::uri::Uri::from_static(
"https://cloudfront.amazonaws.com/2020-05-31/distribution/some_distribution/invalidation",
))
.body(SdkBody::from(
r#"<InvalidationBatch xmlns="http://cloudfront.amazonaws.com/doc/2020-05-31/"><Paths><Quantity>2</Quantity><Items><Path>/some/path*</Path><Path>/another/path/*</Path></Items></Paths><CallerReference>some_reference</CallerReference></InvalidationBatch>"#,
))
.unwrap(),
http::Response::builder()
http02::Response::builder()
.status(200)
.body(SdkBody::from(
r#"
Expand Down Expand Up @@ -1009,14 +1009,14 @@ mod tests {
#[tokio::test]
async fn get_invalidation_info_doesnt_exist() {
let conn = StaticReplayClient::new(vec![ReplayEvent::new(
http::Request::builder()
http02::Request::builder()
.header("content-type", "application/xml")
.uri(http::uri::Uri::from_static(
.uri(http02::uri::Uri::from_static(
"https://cloudfront.amazonaws.com/2020-05-31/distribution/some_distribution/invalidation/some_reference"
))
.body(SdkBody::empty())
.unwrap(),
http::Response::builder()
http02::Response::builder()
.status(404)
.body(SdkBody::empty())
.unwrap(),
Expand All @@ -1036,14 +1036,14 @@ mod tests {
#[tokio::test]
async fn get_invalidation_info_completed() {
let conn = StaticReplayClient::new(vec![ReplayEvent::new(
http::Request::builder()
http02::Request::builder()
.header("content-type", "application/xml")
.uri(http::uri::Uri::from_static(
.uri(http02::uri::Uri::from_static(
"https://cloudfront.amazonaws.com/2020-05-31/distribution/some_distribution/invalidation/some_reference"
))
.body(SdkBody::empty())
.unwrap(),
http::Response::builder()
http02::Response::builder()
.status(200)
.body(SdkBody::from(
r#"<Invalidation xmlns="http://cloudfront.amazonaws.com/doc/2020-05-31/">
Expand Down
35 changes: 18 additions & 17 deletions src/test/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,7 @@ use reqwest::{
use sqlx::Connection as _;
use std::thread::{self, JoinHandle};
use std::{
fs,
future::Future,
net::{SocketAddr, TcpListener},
panic,
rc::Rc,
str::FromStr,
sync::Arc,
time::Duration,
fs, future::Future, net::SocketAddr, panic, rc::Rc, str::FromStr, sync::Arc, time::Duration,
};
use tokio::runtime::{Builder, Runtime};
use tokio::sync::oneshot::Sender;
Expand Down Expand Up @@ -95,8 +88,10 @@ pub(crate) fn assert_no_cache(res: &Response) {
assert_eq!(
res.headers()
.get("Cache-Control")
.expect("missing cache-control header"),
cache::NO_CACHING,
.expect("missing cache-control header")
.to_str()
.unwrap(),
cache::NO_CACHING.to_str().unwrap(),
);
}

Expand All @@ -111,8 +106,11 @@ pub(crate) fn assert_cache_control(

if let Some(expected_directives) = cache_policy.render(config) {
assert_eq!(
cache_control.expect("missing cache-control header"),
expected_directives,
cache_control
.expect("missing cache-control header")
.to_str()
.unwrap(),
expected_directives.to_str().unwrap(),
);
} else {
assert!(cache_control.is_none());
Expand Down Expand Up @@ -707,9 +705,14 @@ impl TestFrontend {
debug!("loading template data");
let template_data = Arc::new(TemplateData::new(1).unwrap());

let runtime = context.runtime().unwrap();

debug!("binding local TCP port for axum");
let axum_listener =
TcpListener::bind("127.0.0.1:0".parse::<SocketAddr>().unwrap()).unwrap();
let axum_listener = runtime
.block_on(tokio::net::TcpListener::bind(
"127.0.0.1:0".parse::<SocketAddr>().unwrap(),
))
.unwrap();

let axum_addr = axum_listener.local_addr().unwrap();
debug!("bound to local address: {}", axum_addr);
Expand All @@ -723,9 +726,7 @@ impl TestFrontend {
let runtime = context.runtime().unwrap();
move || {
runtime.block_on(async {
axum::Server::from_tcp(axum_listener)
.unwrap()
.serve(axum_app.into_make_service())
axum::serve(axum_listener, axum_app.into_make_service())
.with_graceful_shutdown(async {
rx.await.ok();
})
Expand Down
6 changes: 3 additions & 3 deletions src/web/cache.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::config::Config;
use axum::{
http::Request as AxumHttpRequest, middleware::Next, response::Response as AxumResponse,
extract::Request as AxumHttpRequest, middleware::Next, response::Response as AxumResponse,
};
use http::{header::CACHE_CONTROL, HeaderValue};
use std::sync::Arc;
Expand All @@ -14,7 +14,7 @@ pub static NO_STORE_MUST_REVALIDATE: HeaderValue =
pub static FOREVER_IN_CDN_AND_BROWSER: HeaderValue = HeaderValue::from_static("max-age=31104000");

/// defines the wanted caching behaviour for a web response.
#[derive(Debug)]
#[derive(Debug, Clone)]
pub enum CachePolicy {
/// no browser or CDN caching.
/// In some cases the browser might still use cached content,
Expand Down Expand Up @@ -79,7 +79,7 @@ impl CachePolicy {
}
}

pub(crate) async fn cache_middleware<B>(req: AxumHttpRequest<B>, next: Next<B>) -> AxumResponse {
pub(crate) async fn cache_middleware(req: AxumHttpRequest, next: Next) -> AxumResponse {
let config = req
.extensions()
.get::<Arc<Config>>()
Expand Down
4 changes: 2 additions & 2 deletions src/web/csp.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::config::Config;
use axum::{
http::Request as AxumHttpRequest, middleware::Next, response::Response as AxumResponse,
extract::Request as AxumHttpRequest, middleware::Next, response::Response as AxumResponse,
};
use base64::{engine::general_purpose::STANDARD as b64, Engine};
use std::{
Expand Down Expand Up @@ -98,7 +98,7 @@ enum ContentType {
Other,
}

pub(crate) async fn csp_middleware<B>(mut req: AxumHttpRequest<B>, next: Next<B>) -> AxumResponse {
pub(crate) async fn csp_middleware(mut req: AxumHttpRequest, next: Next) -> AxumResponse {
let csp_report_only = req
.extensions()
.get::<Arc<Config>>()
Expand Down
10 changes: 4 additions & 6 deletions src/web/headers.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
use super::encode_url_path;
use anyhow::Result;
use axum::{
headers::{Header, HeaderName, HeaderValue},
http::uri::{PathAndQuery, Uri},
};
use axum::http::uri::{PathAndQuery, Uri};
use axum_extra::headers::{Header, HeaderName, HeaderValue};
use serde::Serialize;

/// simplified typed header for a `Link rel=canonical` header in the response.
Expand Down Expand Up @@ -35,7 +33,7 @@ impl Header for CanonicalUrl {
&http::header::LINK
}

fn decode<'i, I>(_values: &mut I) -> Result<Self, axum::headers::Error>
fn decode<'i, I>(_values: &mut I) -> Result<Self, axum_extra::headers::Error>
where
I: Iterator<Item = &'i HeaderValue>,
{
Expand Down Expand Up @@ -67,8 +65,8 @@ impl Serialize for CanonicalUrl {
mod tests {
use super::*;

use axum::headers::HeaderMapExt;
use axum::http::HeaderMap;
use axum_extra::headers::HeaderMapExt;

#[test]
fn test_serialize_canonical() {
Expand Down
9 changes: 4 additions & 5 deletions src/web/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ use crate::{
};
use anyhow::{Context as _, Result};
use axum::{
extract::{Extension, MatchedPath},
http::Request as AxumRequest,
extract::{Extension, MatchedPath, Request as AxumRequest},
http::{header::CONTENT_TYPE, StatusCode},
middleware::Next,
response::IntoResponse,
Expand Down Expand Up @@ -78,9 +77,9 @@ pub(super) async fn instance_metrics_handler(
/// request_recorder(request, next, Some("static resource")).await
/// }))
/// ```
pub(crate) async fn request_recorder<B>(
request: AxumRequest<B>,
next: Next<B>,
pub(crate) async fn request_recorder(
request: AxumRequest,
next: Next,
route_name: Option<&str>,
) -> impl IntoResponse {
let route_name = if let Some(rn) = route_name {
Expand Down
33 changes: 22 additions & 11 deletions src/web/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ mod status;
use crate::{impl_axum_webpage, Context};
use anyhow::Error;
use axum::{
extract::Extension,
http::Request as AxumRequest,
extract::{Extension, Request as AxumRequest},
http::StatusCode,
middleware,
middleware::Next,
Expand Down Expand Up @@ -234,7 +233,7 @@ async fn match_version(
Err(AxumNope::VersionNotFound)
}

async fn log_timeouts_to_sentry<B>(req: AxumRequest<B>, next: Next<B>) -> AxumResponse {
async fn log_timeouts_to_sentry(req: AxumRequest, next: Next) -> AxumResponse {
let uri = req.uri().clone();

let response = next.run(req).await;
Expand Down Expand Up @@ -309,13 +308,22 @@ pub fn start_background_metrics_webserver(
let runtime = context.runtime()?;

runtime.spawn(async move {
if let Err(err) = axum::Server::bind(&axum_addr)
.serve(metrics_axum_app)
match tokio::net::TcpListener::bind(axum_addr)
.await
.context("error running metrics web server")
.context("error binding socket for metrics web server")
{
report_error(&err);
}
Ok(listener) => {
if let Err(err) = axum::serve(listener, metrics_axum_app)
.await
.context("error running metrics web server")
{
report_error(&err);
}
}
Err(err) => {
report_error(&err);
}
};
});

Ok(())
Expand All @@ -341,8 +349,11 @@ pub fn start_web_server(addr: Option<SocketAddr>, context: &dyn Context) -> Resu

let app = build_axum_app(context, template_data)?.into_make_service();
context.runtime()?.block_on(async {
axum::Server::bind(&axum_addr)
.serve(app)
let listener = tokio::net::TcpListener::bind(axum_addr)
.await
.context("error binding socket for metrics web server")?;

axum::serve(listener, app)
.with_graceful_shutdown(shutdown_signal())
.await?;
Ok::<(), Error>(())
Expand Down Expand Up @@ -744,7 +755,7 @@ mod test {
.unwrap();
let web = env.frontend();
let response = web.get("/bat//").send()?;
assert_eq!(response.status(), StatusCode::NOT_FOUND);
assert_eq!(response.status().as_u16(), StatusCode::NOT_FOUND.as_u16());
Ok(())
})
}
Expand Down
Loading

0 comments on commit 61009f3

Please sign in to comment.