Skip to content

Commit fe6ba77

Browse files
authored
Merge pull request #70 from dfinity/igornovg/axum08
Upgrade to axum 0.8
2 parents 8590b8e + e71322f commit fe6ba77

File tree

8 files changed

+208
-109
lines changed

8 files changed

+208
-109
lines changed

Cargo.lock

Lines changed: 164 additions & 70 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ anyhow = "1.0.93"
1010
arc-swap = "1.7.1"
1111
async-channel = "2.3.1"
1212
async-trait = "0.1.83"
13-
axum = "0.7.9"
14-
axum-extra = "0.9.6"
13+
axum = { version = "0.8.1", features = ["macros"] }
14+
axum-extra = "0.10.0"
1515
backoff = { version = "0.4.0", features = ["tokio"] }
1616
base64 = "0.22.1"
1717
bytes = "1.9.0"
@@ -33,7 +33,7 @@ derive-new = "0.7.0"
3333
fqdn = { version = "0.4.1", features = ["serde"] }
3434
futures = "0.3.31"
3535
futures-util = "0.3.31"
36-
governor = "0.6.0" # must match tower-governor deps
36+
governor = "0.8.0" # must match tower-governor deps
3737
hickory-resolver = { version = "0.24.1", features = [
3838
"dns-over-https-rustls",
3939
"webpki-roots",
@@ -49,7 +49,7 @@ ic-agent = { version = "0.39.3", features = [
4949
"ring",
5050
"_internal_dynamic-routing",
5151
] }
52-
ic-bn-lib = { git = "https://github.com/dfinity/ic-bn-lib", rev = "530f8e8ea577740213aff4b6dfa7a49cc32bae4a" }
52+
ic-bn-lib = { git = "https://github.com/dfinity/ic-bn-lib", rev = "686cff6ccd422716d48767a299ab33044a27d4ad" }
5353
ic-http-gateway = "0.2.0"
5454
ic-transport-types = "0.39.3"
5555
itertools = "0.13.0"
@@ -85,7 +85,8 @@ time = { version = "0.3.36", features = ["macros", "serde"] }
8585
tokio = { version = "1.42.0", features = ["full", "tracing"] }
8686
tokio-util = { version = "0.7.12", features = ["full"] }
8787
tower = { version = "0.5.1", features = ["limit"] }
88-
tower_governor = "0.4.3"
88+
# axum 0.8 support not yet released, use git
89+
tower_governor = { git = "https://github.com/benwis/tower-governor", rev = "bc9a6eacafcaec1e732886ceae8ae324bbd327df" }
8990
tower-http = { version = "0.6.1", features = ["cors", "compression-full"] }
9091
tower-service = "0.3.3"
9192
tracing = "0.1.40"

src/metrics/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,11 +158,12 @@ impl HttpMetrics {
158158
pub async fn middleware(
159159
State(state): State<Arc<HttpMetrics>>,
160160
Extension(conn_info): Extension<Arc<ConnInfo>>,
161-
tls_info: Option<Extension<Arc<TlsInfo>>>,
162161
Extension(request_id): Extension<RequestId>,
163162
request: Request,
164163
next: Next,
165164
) -> impl IntoResponse {
165+
let tls_info = request.extensions().get::<Arc<TlsInfo>>().cloned();
166+
166167
// Prepare to execute the request and count its body size
167168
let (parts, body) = request.into_parts();
168169
let (body, rx) = CountingBody::new(body);

src/metrics/runner.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ use std::{sync::Arc, time::Instant};
22

33
use anyhow::Error;
44
use arc_swap::ArcSwap;
5-
use axum::{async_trait, extract::State, response::IntoResponse};
5+
use async_trait::async_trait;
6+
use axum::{extract::State, response::IntoResponse};
67
use bytes::{BufMut, Bytes, BytesMut};
78
use http::header::CONTENT_TYPE;
89
use ic_bn_lib::tasks::Run;

src/routing/ic/handler.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,18 @@ pub struct HandlerState {
3131
}
3232

3333
// Main HTTP->IC request handler
34+
//#[axum::debug_handler]
3435
pub async fn handler(
3536
State(state): State<Arc<HandlerState>>,
36-
canister_id: Option<Extension<CanisterId>>,
3737
Extension(conn_info): Extension<Arc<ConnInfo>>,
3838
Extension(request_id): Extension<RequestId>,
3939
Extension(ctx): Extension<Arc<RequestCtx>>,
4040
request: Request,
4141
) -> Result<Response, ErrorCause> {
42-
let canister_id = canister_id
43-
.map(|x| (x.0).0)
42+
let canister_id = request
43+
.extensions()
44+
.get::<CanisterId>()
45+
.map(|x| x.0)
4446
.ok_or(ErrorCause::CanisterIdNotFound)?;
4547

4648
let (parts, body) = request.into_parts();

src/routing/middleware/canister_match.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,14 @@ impl CanisterMatcherState {
3939
pub async fn middleware(
4040
State(state): State<CanisterMatcherState>,
4141
Extension(ctx): Extension<Arc<RequestCtx>>,
42-
canister_id: Option<Extension<CanisterId>>,
4342
request: Request,
4443
next: Next,
4544
) -> Result<Response, ErrorCause> {
45+
let canister_id = request.extensions().get::<CanisterId>().copied();
46+
4647
if let Some(v) = canister_id {
4748
// Do not run for custom domains
48-
if !ctx.domain.custom && !state.0.check(v.0.into(), &ctx.authority) {
49+
if !ctx.domain.custom && !state.0.check(v.0, &ctx.authority) {
4950
return Err(ErrorCause::DomainCanisterMismatch);
5051
}
5152
}

src/routing/middleware/denylist.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::{path::PathBuf, sync::Arc};
33
use anyhow::{Context, Error};
44
use async_trait::async_trait;
55
use axum::{
6-
extract::{Extension, Request, State},
6+
extract::{Request, State},
77
middleware::Next,
88
response::Response,
99
};
@@ -81,14 +81,15 @@ impl Run for DenylistState {
8181

8282
pub async fn middleware(
8383
State(state): State<DenylistState>,
84-
country_code: Option<Extension<CountryCode>>,
85-
canister_id: Option<Extension<CanisterId>>,
8684
request: Request,
8785
next: Next,
8886
) -> Result<Response, ErrorCause> {
87+
let country_code = request.extensions().get::<CountryCode>().cloned();
88+
let canister_id = request.extensions().get::<CanisterId>().copied();
89+
8990
// Check denylisting if configured
9091
if let Some(v) = canister_id {
91-
if state.0.is_blocked(v.0.into(), country_code.map(|x| x.0)) {
92+
if state.0.is_blocked(v.0, country_code) {
9293
return Err(ErrorCause::Denylisted);
9394
}
9495
}

src/routing/mod.rs

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ use std::{str::FromStr, sync::Arc, time::Duration};
99

1010
use anyhow::{Context, Error};
1111
use axum::{
12-
extract::{Host, MatchedPath, OriginalUri, Request},
12+
extract::{MatchedPath, OriginalUri, Request},
1313
middleware::{from_fn, from_fn_with_state, FromFnLayer},
1414
response::{IntoResponse, Redirect},
1515
routing::{get, post},
1616
Extension, Router,
1717
};
18-
use axum_extra::middleware::option_layer;
18+
use axum_extra::{extract::Host, middleware::option_layer};
1919
use candid::Principal;
2020
use domain::{CustomDomainStorage, DomainResolver, ProvidesCustomDomains};
2121
use fqdn::FQDN;
@@ -102,14 +102,14 @@ impl From<Option<&MatchedPath>> for RequestType {
102102
};
103103

104104
match path.as_str() {
105-
"/api/v2/canister/:principal/query" => Self::Api(RequestTypeApi::Query),
106-
"/api/v2/canister/:principal/call" => Self::Api(RequestTypeApi::Call),
107-
"/api/v3/canister/:principal/call" => Self::Api(RequestTypeApi::SyncCall),
108-
"/api/v2/canister/:principal/read_state" => Self::Api(RequestTypeApi::ReadState),
109-
"/api/v2/subnet/:principal/read_state" => Self::Api(RequestTypeApi::ReadStateSubnet),
105+
"/api/v2/canister/{principal}/query" => Self::Api(RequestTypeApi::Query),
106+
"/api/v2/canister/{principal}/call" => Self::Api(RequestTypeApi::Call),
107+
"/api/v3/canister/{principal}/call" => Self::Api(RequestTypeApi::SyncCall),
108+
"/api/v2/canister/{principal}/read_state" => Self::Api(RequestTypeApi::ReadState),
109+
"/api/v2/subnet/{principal}/read_state" => Self::Api(RequestTypeApi::ReadStateSubnet),
110110
"/api/v2/status" => Self::Api(RequestTypeApi::Status),
111111
"/health" => Self::Health,
112-
"/registrations" | "/registrations/:id" => Self::Registrations,
112+
"/registrations" | "/registrations/{id}" => Self::Registrations,
113113
_ => Self::Unknown,
114114
}
115115
}
@@ -244,15 +244,13 @@ pub fn setup_router(
244244
};
245245

246246
// Metrics
247-
let metrics_mw = from_fn_with_state(
248-
Arc::new(metrics::HttpMetrics::new(
249-
registry,
250-
cli.log.log_requests,
251-
clickhouse,
252-
vector,
253-
)),
254-
metrics::middleware,
255-
);
247+
let metrics_state = Arc::new(metrics::HttpMetrics::new(
248+
registry,
249+
cli.log.log_requests,
250+
clickhouse,
251+
vector,
252+
));
253+
let metrics_mw = from_fn_with_state(metrics_state, metrics::middleware);
256254

257255
// Concurrency
258256
let concurrency_limit_mw = option_layer(
@@ -333,19 +331,19 @@ pub fn setup_router(
333331
// IC API proxy routers
334332
let router_api_v2 = Router::new()
335333
.route(
336-
"/canister/:principal/query",
334+
"/canister/{principal}/query",
337335
post(proxy::api_proxy).layer(cors_post.clone()),
338336
)
339337
.route(
340-
"/canister/:principal/call",
338+
"/canister/{principal}/call",
341339
post(proxy::api_proxy).layer(cors_post.clone()),
342340
)
343341
.route(
344-
"/canister/:principal/read_state",
342+
"/canister/{principal}/read_state",
345343
post(proxy::api_proxy).layer(cors_post.clone()),
346344
)
347345
.route(
348-
"/subnet/:principal/read_state",
346+
"/subnet/{principal}/read_state",
349347
post(proxy::api_proxy).layer(cors_post.clone()),
350348
)
351349
.route("/status", get(proxy::api_proxy).layer(cors_get.clone()))
@@ -354,7 +352,7 @@ pub fn setup_router(
354352

355353
let router_api_v3 = Router::new()
356354
.route(
357-
"/canister/:principal/call",
355+
"/canister/{principal}/call",
358356
post(proxy::api_proxy).layer(cors_post.clone()),
359357
)
360358
.fallback(|| async { (StatusCode::NOT_FOUND, "") })
@@ -421,7 +419,7 @@ pub fn setup_router(
421419

422420
let router = Router::new()
423421
.route(
424-
"/registrations/:id",
422+
"/registrations/{id}",
425423
get(proxy::issuer_proxy)
426424
.put(proxy::issuer_proxy)
427425
.delete(proxy::issuer_proxy)

0 commit comments

Comments
 (0)