Repository: cloudflare/daphne
Pull request #719 (2024-11-19 17:06:01)

Upgrade daphne-server to http 1
Upgrades to http 1 and axum 0.7, which is a breaking change but for us means a simplification of the code as we no longer have to care about the Body of a request, it is now `axum::body::Body` instead of being generic.


Patch:
diff --git a/Cargo.lock b/Cargo.lock
index 5c5b10c..569ec39 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -204,6 +204,12 @@ dependencies = [
  "syn 2.0.76",
 ]
 
+[[package]]
+name = "atomic-waker"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
+
 [[package]]
 name = "autocfg"
 version = "1.3.0"
@@ -237,38 +243,6 @@ dependencies = [
  "paste",
 ]
 
-[[package]]
-name = "axum"
-version = "0.6.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf"
-dependencies = [
- "async-trait",
- "axum-core 0.3.4",
- "bitflags 1.3.2",
- "bytes",
- "futures-util",
- "http 0.2.12",
- "http-body 0.4.6",
- "hyper 0.14.30",
- "itoa",
- "matchit",
- "memchr",
- "mime",
- "percent-encoding",
- "pin-project-lite",
- "rustversion",
- "serde",
- "serde_json",
- "serde_path_to_error",
- "serde_urlencoded",
- "sync_wrapper 0.1.2",
- "tokio",
- "tower",
- "tower-layer",
- "tower-service",
-]
-
 [[package]]
 name = "axum"
 version = "0.7.5"
@@ -276,12 +250,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf"
 dependencies = [
  "async-trait",
- "axum-core 0.4.3",
+ "axum-core",
  "bytes",
  "futures-util",
- "http 1.1.0",
- "http-body 1.0.1",
+ "http",
+ "http-body",
  "http-body-util",
+ "hyper",
+ "hyper-util",
  "itoa",
  "matchit",
  "memchr",
@@ -290,29 +266,16 @@ dependencies = [
  "pin-project-lite",
  "rustversion",
  "serde",
+ "serde_json",
+ "serde_path_to_error",
+ "serde_urlencoded",
  "sync_wrapper 1.0.1",
+ "tokio",
  "tower",
  "tower-layer",
  "tower-service",
 ]
 
-[[package]]
-name = "axum-core"
-version = "0.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c"
-dependencies = [
- "async-trait",
- "bytes",
- "futures-util",
- "http 0.2.12",
- "http-body 0.4.6",
- "mime",
- "rustversion",
- "tower-layer",
- "tower-service",
-]
-
 [[package]]
 name = "axum-core"
 version = "0.4.3"
@@ -322,8 +285,8 @@ dependencies = [
  "async-trait",
  "bytes",
  "futures-util",
- "http 1.1.0",
- "http-body 1.0.1",
+ "http",
+ "http-body",
  "http-body-util",
  "mime",
  "pin-project-lite",
@@ -340,13 +303,13 @@ version = "0.9.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0be6ea09c9b96cb5076af0de2e383bd2bc0c18f827cf1967bdd353e0b910d733"
 dependencies = [
- "axum 0.7.5",
- "axum-core 0.4.3",
+ "axum",
+ "axum-core",
  "bytes",
  "futures-util",
  "headers",
- "http 1.1.0",
- "http-body 1.0.1",
+ "http",
+ "http-body",
  "http-body-util",
  "mime",
  "pin-project-lite",
@@ -579,7 +542,7 @@ dependencies = [
  "js-sys",
  "num-traits",
  "wasm-bindgen",
- "windows-targets 0.52.6",
+ "windows-targets",
 ]
 
 [[package]]
@@ -893,10 +856,10 @@ dependencies = [
  "prio",
  "prometheus",
  "rand",
- "reqwest 0.12.7",
+ "reqwest",
  "rustls 0.23.12",
- "rustls-native-certs 0.7.2",
- "rustls-pemfile 2.1.3",
+ "rustls-native-certs",
+ "rustls-pemfile",
  "sentry",
  "serde",
  "serde_json",
@@ -945,7 +908,7 @@ version = "0.3.0"
 dependencies = [
  "anyhow",
  "assert_matches",
- "axum 0.6.20",
+ "axum",
  "clap",
  "config",
  "daphne",
@@ -955,8 +918,7 @@ dependencies = [
  "futures",
  "hex",
  "hpke-rs",
- "http 0.2.12",
- "hyper 0.14.30",
+ "http",
  "mappable-rc",
  "p256",
  "paste",
@@ -964,7 +926,7 @@ dependencies = [
  "prometheus",
  "rand",
  "rcgen",
- "reqwest 0.11.27",
+ "reqwest",
  "serde",
  "serde_json",
  "serde_yaml",
@@ -995,7 +957,7 @@ dependencies = [
 name = "daphne-worker"
 version = "0.3.0"
 dependencies = [
- "axum 0.7.5",
+ "axum",
  "axum-extra",
  "bytes",
  "chrono",
@@ -1006,12 +968,12 @@ dependencies = [
  "getrandom",
  "headers",
  "hex",
- "http 1.1.0",
+ "http",
  "paste",
  "prio",
  "prometheus",
  "rand",
- "reqwest 0.12.7",
+ "reqwest",
  "serde",
  "serde-wasm-bindgen 0.6.5",
  "serde_json",
@@ -1204,15 +1166,6 @@ version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "658bbadc628dc286b9ae02f0cb0f5411c056eb7487b72f0083203f115de94060"
 
-[[package]]
-name = "encoding_rs"
-version = "0.8.34"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59"
-dependencies = [
- "cfg-if",
-]
-
 [[package]]
 name = "equivalent"
 version = "1.0.1"
@@ -1444,16 +1397,16 @@ dependencies = [
 
 [[package]]
 name = "h2"
-version = "0.3.26"
+version = "0.4.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8"
+checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e"
 dependencies = [
+ "atomic-waker",
  "bytes",
  "fnv",
  "futures-core",
  "futures-sink",
- "futures-util",
- "http 0.2.12",
+ "http",
  "indexmap",
  "slab",
  "tokio",
@@ -1495,7 +1448,7 @@ dependencies = [
  "base64 0.21.7",
  "bytes",
  "headers-core",
- "http 1.1.0",
+ "http",
  "httpdate",
  "mime",
  "sha1",
@@ -1507,7 +1460,7 @@ version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4"
 dependencies = [
- "http 1.1.0",
+ "http",
 ]
 
 [[package]]
@@ -1615,17 +1568,6 @@ dependencies = [
  "x25519-dalek",
 ]
 
-[[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"
@@ -1637,17 +1579,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.1"
@@ -1655,7 +1586,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
 dependencies = [
  "bytes",
- "http 1.1.0",
+ "http",
 ]
 
 [[package]]
@@ -1666,8 +1597,8 @@ checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f"
 dependencies = [
  "bytes",
  "futures-util",
- "http 1.1.0",
- "http-body 1.0.1",
+ "http",
+ "http-body",
  "pin-project-lite",
 ]
 
@@ -1683,30 +1614,6 @@ version = "1.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
 
-[[package]]
-name = "hyper"
-version = "0.14.30"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9"
-dependencies = [
- "bytes",
- "futures-channel",
- "futures-core",
- "futures-util",
- "h2",
- "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.4.1"
@@ -1716,9 +1623,11 @@ dependencies = [
  "bytes",
  "futures-channel",
  "futures-util",
- "http 1.1.0",
- "http-body 1.0.1",
+ "h2",
+ "http",
+ "http-body",
  "httparse",
+ "httpdate",
  "itoa",
  "pin-project-lite",
  "smallvec",
@@ -1726,20 +1635,6 @@ dependencies = [
  "want",
 ]
 
-[[package]]
-name = "hyper-rustls"
-version = "0.24.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590"
-dependencies = [
- "futures-util",
- "http 0.2.12",
- "hyper 0.14.30",
- "rustls 0.21.12",
- "tokio",
- "tokio-rustls 0.24.1",
-]
-
 [[package]]
 name = "hyper-rustls"
 version = "0.27.2"
@@ -1747,14 +1642,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155"
 dependencies = [
  "futures-util",
- "http 1.1.0",
- "hyper 1.4.1",
+ "http",
+ "hyper",
  "hyper-util",
  "rustls 0.23.12",
- "rustls-native-certs 0.7.2",
+ "rustls-native-certs",
  "rustls-pki-types",
  "tokio",
- "tokio-rustls 0.26.0",
+ "tokio-rustls",
  "tower-service",
  "webpki-roots 0.26.3",
 ]
@@ -1768,9 +1663,9 @@ dependencies = [
  "bytes",
  "futures-channel",
  "futures-util",
- "http 1.1.0",
- "http-body 1.0.1",
- "hyper 1.4.1",
+ "http",
+ "http-body",
+ "hyper",
  "pin-project-lite",
  "socket2",
  "tokio",
@@ -1941,7 +1836,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
 dependencies = [
  "cfg-if",
- "windows-targets 0.52.6",
+ "windows-targets",
 ]
 
 [[package]]
@@ -2234,7 +2129,7 @@ dependencies = [
  "libc",
  "redox_syscall",
  "smallvec",
- "windows-targets 0.52.6",
+ "windows-targets",
 ]
 
 [[package]]
@@ -2685,47 +2580,6 @@ version = "0.8.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
 
-[[package]]
-name = "reqwest"
-version = "0.11.27"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62"
-dependencies = [
- "base64 0.21.7",
- "bytes",
- "encoding_rs",
- "futures-core",
- "futures-util",
- "h2",
- "http 0.2.12",
- "http-body 0.4.6",
- "hyper 0.14.30",
- "hyper-rustls 0.24.2",
- "ipnet",
- "js-sys",
- "log",
- "mime",
- "once_cell",
- "percent-encoding",
- "pin-project-lite",
- "rustls 0.21.12",
- "rustls-native-certs 0.6.3",
- "rustls-pemfile 1.0.4",
- "serde",
- "serde_json",
- "serde_urlencoded",
- "sync_wrapper 0.1.2",
- "system-configuration",
- "tokio",
- "tokio-rustls 0.24.1",
- "tower-service",
- "url",
- "wasm-bindgen",
- "wasm-bindgen-futures",
- "web-sys",
- "winreg",
-]
-
 [[package]]
 name = "reqwest"
 version = "0.12.7"
@@ -2737,11 +2591,11 @@ dependencies = [
  "futures-channel",
  "futures-core",
  "futures-util",
- "http 1.1.0",
- "http-body 1.0.1",
+ "http",
+ "http-body",
  "http-body-util",
- "hyper 1.4.1",
- "hyper-rustls 0.27.2",
+ "hyper",
+ "hyper-rustls",
  "hyper-util",
  "ipnet",
  "js-sys",
@@ -2752,15 +2606,15 @@ dependencies = [
  "pin-project-lite",
  "quinn",
  "rustls 0.23.12",
- "rustls-native-certs 0.7.2",
- "rustls-pemfile 2.1.3",
+ "rustls-native-certs",
+ "rustls-pemfile",
  "rustls-pki-types",
  "serde",
  "serde_json",
  "serde_urlencoded",
  "sync_wrapper 1.0.1",
  "tokio",
- "tokio-rustls 0.26.0",
+ "tokio-rustls",
  "tower-service",
  "url",
  "wasm-bindgen",
@@ -2893,18 +2747,6 @@ dependencies = [
  "zeroize",
 ]
 
-[[package]]
-name = "rustls-native-certs"
-version = "0.6.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00"
-dependencies = [
- "openssl-probe",
- "rustls-pemfile 1.0.4",
- "schannel",
- "security-framework",
-]
-
 [[package]]
 name = "rustls-native-certs"
 version = "0.7.2"
@@ -2912,21 +2754,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "04182dffc9091a404e0fc069ea5cd60e5b866c3adf881eff99a32d048242dffa"
 dependencies = [
  "openssl-probe",
- "rustls-pemfile 2.1.3",
+ "rustls-pemfile",
  "rustls-pki-types",
  "schannel",
  "security-framework",
 ]
 
-[[package]]
-name = "rustls-pemfile"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
-dependencies = [
- "base64 0.21.7",
-]
-
 [[package]]
 name = "rustls-pemfile"
 version = "2.1.3"
@@ -3061,7 +2894,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "00421ed8fa0c995f07cde48ba6c89e80f2b312f74ff637326f392fbfd23abe02"
 dependencies = [
  "httpdate",
- "reqwest 0.12.7",
+ "reqwest",
  "rustls 0.21.12",
  "sentry-backtrace",
  "sentry-contexts",
@@ -3442,27 +3275,6 @@ dependencies = [
  "unicode-xid",
 ]
 
-[[package]]
-name = "system-configuration"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
-dependencies = [
- "bitflags 1.3.2",
- "core-foundation",
- "system-configuration-sys",
-]
-
-[[package]]
-name = "system-configuration-sys"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9"
-dependencies = [
- "core-foundation-sys",
- "libc",
-]
-
 [[package]]
 name = "tap"
 version = "1.0.1"
@@ -3611,16 +3423,6 @@ dependencies = [
  "syn 2.0.76",
 ]
 
-[[package]]
-name = "tokio-rustls"
-version = "0.24.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
-dependencies = [
- "rustls 0.21.12",
- "tokio",
-]
-
 [[package]]
 name = "tokio-rustls"
 version = "0.26.0"
@@ -4077,7 +3879,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be"
 dependencies = [
  "windows-core",
- "windows-targets 0.52.6",
+ "windows-targets",
 ]
 
 [[package]]
@@ -4086,7 +3888,7 @@ version = "0.52.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
 dependencies = [
- "windows-targets 0.52.6",
+ "windows-targets",
 ]
 
 [[package]]
@@ -4097,7 +3899,7 @@ checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0"
 dependencies = [
  "windows-result",
  "windows-strings",
- "windows-targets 0.52.6",
+ "windows-targets",
 ]
 
 [[package]]
@@ -4106,7 +3908,7 @@ version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e"
 dependencies = [
- "windows-targets 0.52.6",
+ "windows-targets",
 ]
 
 [[package]]
@@ -4116,16 +3918,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10"
 dependencies = [
  "windows-result",
- "windows-targets 0.52.6",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.48.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
-dependencies = [
- "windows-targets 0.48.5",
+ "windows-targets",
 ]
 
 [[package]]
@@ -4134,7 +3927,7 @@ version = "0.52.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
 dependencies = [
- "windows-targets 0.52.6",
+ "windows-targets",
 ]
 
 [[package]]
@@ -4143,22 +3936,7 @@ version = "0.59.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
 dependencies = [
- "windows-targets 0.52.6",
-]
-
-[[package]]
-name = "windows-targets"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
-dependencies = [
- "windows_aarch64_gnullvm 0.48.5",
- "windows_aarch64_msvc 0.48.5",
- "windows_i686_gnu 0.48.5",
- "windows_i686_msvc 0.48.5",
- "windows_x86_64_gnu 0.48.5",
- "windows_x86_64_gnullvm 0.48.5",
- "windows_x86_64_msvc 0.48.5",
+ "windows-targets",
 ]
 
 [[package]]
@@ -4167,46 +3945,28 @@ version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
 dependencies = [
- "windows_aarch64_gnullvm 0.52.6",
- "windows_aarch64_msvc 0.52.6",
- "windows_i686_gnu 0.52.6",
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
  "windows_i686_gnullvm",
- "windows_i686_msvc 0.52.6",
- "windows_x86_64_gnu 0.52.6",
- "windows_x86_64_gnullvm 0.52.6",
- "windows_x86_64_msvc 0.52.6",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
 ]
 
-[[package]]
-name = "windows_aarch64_gnullvm"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
-
 [[package]]
 name = "windows_aarch64_gnullvm"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
 
-[[package]]
-name = "windows_aarch64_msvc"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
-
 [[package]]
 name = "windows_aarch64_msvc"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
 
-[[package]]
-name = "windows_i686_gnu"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
-
 [[package]]
 name = "windows_i686_gnu"
 version = "0.52.6"
@@ -4219,64 +3979,30 @@ version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
 
-[[package]]
-name = "windows_i686_msvc"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
-
 [[package]]
 name = "windows_i686_msvc"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
 
-[[package]]
-name = "windows_x86_64_gnu"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
-
 [[package]]
 name = "windows_x86_64_gnu"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
 
-[[package]]
-name = "windows_x86_64_gnullvm"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
-
 [[package]]
 name = "windows_x86_64_gnullvm"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
 
-[[package]]
-name = "windows_x86_64_msvc"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
-
 [[package]]
 name = "windows_x86_64_msvc"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
 
-[[package]]
-name = "winreg"
-version = "0.50.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
-dependencies = [
- "cfg-if",
- "windows-sys 0.48.0",
-]
-
 [[package]]
 name = "worker"
 version = "0.3.4"
@@ -4288,8 +4014,8 @@ dependencies = [
  "chrono",
  "futures-channel",
  "futures-util",
- "http 1.1.0",
- "http-body 1.0.1",
+ "http",
+ "http-body",
  "js-sys",
  "matchit",
  "pin-project",
diff --git a/Cargo.toml b/Cargo.toml
index dde6b9e..7a6a69f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -56,9 +56,6 @@ hpke-rs = "0.2.0"
 hpke-rs-crypto = "0.2.0"
 hpke-rs-rust-crypto = "0.2.0"
 http = "1"
-http-body-util = "0.1"
-hyper = "0.14.29"
-itertools = "0.12.1"
 mappable-rc = "0.1.1"
 matchit = "0.7.3"
 p256 = { version = "0.13.2", features = ["ecdsa-core", "ecdsa", "pem"] }
@@ -70,7 +67,6 @@ rayon = "1.10.0"
 rcgen = "0.12.1"
 regex = "1.10.5"
 reqwest = { version = "0.12.5", default-features = false, features = ["rustls-tls-native-roots"] }
-reqwest-wasm = "0.11.16"
 ring = "0.17.8"
 rustls = "0.23.10"
 rustls-native-certs = "0.7"
@@ -88,7 +84,6 @@ tracing = "0.1.40"
 tracing-core = "0.1.32"
 tracing-subscriber = "0.3.18"
 url = { version = "2.5.2", features = ["serde"] }
-wasm-streams = "0.4"
 webpki = "0.22.4"
 worker = { version = "0.3.3", features = ["http"] }
 x509-parser = "0.15.1"
diff --git a/crates/daphne-server/Cargo.toml b/crates/daphne-server/Cargo.toml
index d7c5999..b1e9150 100644
--- a/crates/daphne-server/Cargo.toml
+++ b/crates/daphne-server/Cargo.toml
@@ -16,14 +16,12 @@ description = "Workers backend for Daphne"
 all-features = true
 
 [dependencies]
-axum = "0.6.0" # held back to use http 0.2
 daphne = { path = "../daphne" }
 daphne-service-utils = { path = "../daphne-service-utils", features = ["durable_requests"] }
 either.workspace = true
 futures.workspace = true
 hex.workspace = true
-http = "0.2" # held back to use http 0.2
-hyper.workspace = true
+http.workspace = true
 mappable-rc.workspace = true
 p256.workspace = true
 prio.workspace = true
@@ -32,12 +30,16 @@ serde.workspace = true
 serde_json.workspace = true
 thiserror.workspace = true
 tokio.workspace = true
-tower.workspace = true
+tower = { workspace = true, features = ["util"] }
 tracing.workspace = true
 url.workspace = true
 
+[dependencies.axum]
+workspace = true
+features = ["query", "json", "tokio", "http1", "http2"]
+
 [dependencies.reqwest]
-version = "0.11" # held back to use http 0.2
+workspace = true
 default-features = false
 features = ["rustls-tls-native-roots", "json"]
 
diff --git a/crates/daphne-server/examples/service.rs b/crates/daphne-server/examples/service.rs
index bc63c08..328d9e0 100644
--- a/crates/daphne-server/examples/service.rs
+++ b/crates/daphne-server/examples/service.rs
@@ -9,6 +9,7 @@ use daphne_server::{
 };
 use daphne_service_utils::DapRole;
 use serde::{Deserialize, Serialize};
+use tokio::net::TcpListener;
 use tracing_subscriber::EnvFilter;
 use url::Url;
 
@@ -120,11 +121,15 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Sync + Send>> {
         .init();
 
     // hand the router to axum for it to run
-    let serve = axum::Server::bind(&std::net::SocketAddr::new(
-        "0.0.0.0".parse().unwrap(),
-        config.port,
-    ))
-    .serve(router.into_make_service());
+    let serve = axum::serve(
+        TcpListener::bind(std::net::SocketAddr::new(
+            "0.0.0.0".parse().unwrap(),
+            config.port,
+        ))
+        .await
+        .unwrap(),
+        router,
+    );
 
     let ctrl_c = tokio::signal::ctrl_c();
 
diff --git a/crates/daphne-server/src/lib.rs b/crates/daphne-server/src/lib.rs
index f4731d3..102dfce 100644
--- a/crates/daphne-server/src/lib.rs
+++ b/crates/daphne-server/src/lib.rs
@@ -79,8 +79,6 @@ mod storage_proxy_connection;
 ///
 /// let router = router::new(DapRole::Helper, app);
 ///
-/// # // this is so I don't have to annotate the types of `router::new`
-/// # let router: axum::Router<(), axum::body::Body> = router;
 /// # Ok::<(), daphne::DapError>(())
 /// ```
 pub struct App {
diff --git a/crates/daphne-server/src/router/aggregator.rs b/crates/daphne-server/src/router/aggregator.rs
index e923068..8efd592 100644
--- a/crates/daphne-server/src/router/aggregator.rs
+++ b/crates/daphne-server/src/router/aggregator.rs
@@ -4,7 +4,6 @@
 use std::sync::Arc;
 
 use axum::{
-    body::HttpBody,
     extract::{Path, Query, State},
     response::{AppendHeaders, IntoResponse},
     routing::get,
@@ -22,12 +21,9 @@ use serde::Deserialize;
 
 use super::{AxumDapResponse, DaphneService};
 
-pub fn add_aggregator_routes<A, B>(router: super::Router<A, B>) -> super::Router<A, B>
+pub fn add_aggregator_routes<A>(router: super::Router<A>) -> super::Router<A>
 where
     A: DapAggregator + DaphneService + Send + Sync + 'static,
-    B: Send + HttpBody + 'static,
-    B::Data: Send,
-    B::Error: Send + Sync,
 {
     router.route("/:version/hpke_config", get(hpke_config))
 }
diff --git a/crates/daphne-server/src/router/extractor.rs b/crates/daphne-server/src/router/extractor.rs
index af14bd2..ef3b3ce 100644
--- a/crates/daphne-server/src/router/extractor.rs
+++ b/crates/daphne-server/src/router/extractor.rs
@@ -5,21 +5,22 @@ use std::io::Cursor;
 
 use axum::{
     async_trait,
-    body::{Bytes, HttpBody},
-    extract::{FromRequest, FromRequestParts, Path},
+    body::Bytes,
+    extract::{FromRequest, FromRequestParts, Path, Request},
 };
 use daphne::{
     constants::DapMediaType,
     error::DapAbort,
     fatal_error,
     messages::{
-        request::resource, taskprov::TaskprovAdvertisement, AggregateShareReq,
-        AggregationJobInitReq, CollectionReq, Report, TaskId,
+        request::{CollectionPollReq, RequestBody},
+        taskprov::TaskprovAdvertisement,
+        AggregateShareReq, AggregationJobInitReq, CollectionReq, Report, TaskId,
     },
     DapError, DapRequest, DapRequestMeta, DapVersion,
 };
 use daphne_service_utils::{bearer_token::BearerToken, http_headers};
-use http::{header::CONTENT_TYPE, HeaderMap, Request};
+use http::{header::CONTENT_TYPE, HeaderMap};
 use prio::codec::ParameterizedDecode;
 use serde::Deserialize;
 
@@ -28,7 +29,7 @@ use crate::metrics;
 use super::{AxumDapResponse, DaphneService};
 
 /// Trait used to decode a DAP http body.
-pub trait DecodeFromDapHttpBody: Sized {
+pub trait DecodeFromDapHttpBody: RequestBody + Sized {
     fn decode_from_http_body(bytes: Bytes, meta: &DapRequestMeta) -> Result<Self, DapAbort>;
 }
 
@@ -59,6 +60,12 @@ impl_decode_from_dap_http_body!(
     CollectionReq,
 );
 
+/// Using `()` ignores the body of a request.
+impl DecodeFromDapHttpBody for CollectionPollReq {
+    fn decode_from_http_body(_bytes: Bytes, _meta: &DapRequestMeta) -> Result<Self, DapAbort> {
+        Ok(Self)
+    }
+}
 /// Using `()` ignores the body of a request.
 impl DecodeFromDapHttpBody for () {
     fn decode_from_http_body(_bytes: Bytes, _meta: &DapRequestMeta) -> Result<Self, DapAbort> {
@@ -70,7 +77,7 @@ impl DecodeFromDapHttpBody for () {
 /// in through the `R` type parameter in [`DapRequestExtractor`] and
 /// [`UnauthenticatedDapRequestExtractor`].
 mod resource_parsers {
-    use daphne::messages::request::resource;
+    use daphne::messages::{AggregationJobId, CollectionJobId};
     use serde::{de::DeserializeOwned, Deserialize};
 
     #[derive(Deserialize)]
@@ -78,7 +85,7 @@ mod resource_parsers {
         /// This field name defines the parameter name in the route matcher because we use
         /// `#[serde(flatten)]` in the
         /// `UnauthenticatedDapRequestExtractor::from_request::PathParams::resource_parser` field.
-        agg_job_id: resource::AggregationJobId,
+        agg_job_id: AggregationJobId,
     }
 
     #[derive(Deserialize)]
@@ -86,7 +93,7 @@ mod resource_parsers {
         /// This field name defines the parameter name in the route matcher because we use
         /// `#[serde(flatten)]` in the
         /// `UnauthenticatedDapRequestExtractor::from_request::PathParams::resource_parser` field.
-        collect_job_id: resource::CollectionJobId,
+        collect_job_id: CollectionJobId,
     }
 
     /// This parser has no fields, so `#[serde(flatten)]` correctly omits this field from the
@@ -113,28 +120,25 @@ mod resource_parsers {
         };
     }
 
-    impl_parser!(AggregationJobIdParser => resource::AggregationJobId |value| value.agg_job_id);
-    impl_parser!(CollectionJobIdParser  => resource::CollectionJobId  |value| value.collect_job_id);
-    impl_parser!(NoneParser             => resource::None             |_| resource::None);
+    impl_parser!(AggregationJobIdParser => AggregationJobId |value| value.agg_job_id);
+    impl_parser!(CollectionJobIdParser  => CollectionJobId  |value| value.collect_job_id);
+    impl_parser!(NoneParser             => ()               |_| ());
 }
 
 /// An axum extractor capable of parsing a [`DapRequest`]. See [`DapRequest`] for an explanation on
 /// the type parameters.
-#[derive(Debug)]
-pub(super) struct UnauthenticatedDapRequestExtractor<P, R>(pub DapRequest<P, R>);
+pub(super) struct UnauthenticatedDapRequestExtractor<B: RequestBody>(pub DapRequest<B>);
 
 #[async_trait]
-impl<S, B, P, R> FromRequest<S, B, P> for UnauthenticatedDapRequestExtractor<P, R>
+impl<S, B> FromRequest<S> for UnauthenticatedDapRequestExtractor<B>
 where
-    P: DecodeFromDapHttpBody,
+    B: DecodeFromDapHttpBody,
+    B::ResourceId: resource_parsers::Resource,
     S: DaphneService + Send + Sync,
-    B: HttpBody + Send + 'static,
-    <B as HttpBody>::Data: Send,
-    R: resource_parsers::Resource,
 {
     type Rejection = AxumDapResponse;
 
-    async fn from_request(req: Request<B>, state: &S) -> Result<Self, Self::Rejection> {
+    async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
         #[derive(Debug, Deserialize)]
         #[serde(deny_unknown_fields)]
         struct PathParams<R: resource_parsers::Resource> {
@@ -145,7 +149,7 @@ where
         }
 
         let (mut parts, body) = req.into_parts();
-        let Path(PathParams::<R> {
+        let Path(PathParams::<B::ResourceId> {
             version,
             task_id,
             resource_parser,
@@ -177,7 +181,7 @@ where
 
         // TODO(mendess): this allocates needlessly, if prio supported some kind of
         // AsyncParameterizedDecode we could avoid this allocation
-        let payload = hyper::body::to_bytes(body).await;
+        let payload = axum::body::to_bytes(body, usize::MAX).await;
 
         let Ok(payload) = payload else {
             return Err(AxumDapResponse::new_error(
@@ -199,7 +203,7 @@ where
             media_type,
         };
 
-        let payload = P::decode_from_http_body(payload, &meta)
+        let payload = B::decode_from_http_body(payload, &meta)
             .map_err(|e| AxumDapResponse::new_error(e, state.server_metrics()))?;
 
         let request = DapRequest {
@@ -238,24 +242,20 @@ pub mod dap_sender {
 /// # Type and const parameters
 /// - `SENDER`: The role that is expected to send this request. See [`dap_sender`] for possible values.
 /// - `P` and `R`: See [`DapRequest`] for an explanation these type parameters.
-#[derive(Debug)]
-pub(super) struct DapRequestExtractor<const SENDER: dap_sender::DapSender, P, R = resource::None>(
-    pub DapRequest<P, R>,
+pub(super) struct DapRequestExtractor<const SENDER: dap_sender::DapSender, B: RequestBody>(
+    pub DapRequest<B>,
 );
 
 #[async_trait]
-impl<const SENDER: dap_sender::DapSender, S, B, P, R> FromRequest<S, B, P>
-    for DapRequestExtractor<SENDER, P, R>
+impl<const SENDER: dap_sender::DapSender, S, B> FromRequest<S> for DapRequestExtractor<SENDER, B>
 where
-    P: DecodeFromDapHttpBody + Send + Sync,
+    B: DecodeFromDapHttpBody + Send + Sync,
+    B::ResourceId: resource_parsers::Resource,
     S: DaphneService + Send + Sync,
-    B: HttpBody + Send + 'static,
-    <B as HttpBody>::Data: Send,
-    R: resource_parsers::Resource,
 {
     type Rejection = AxumDapResponse;
 
-    async fn from_request(req: Request<B>, state: &S) -> Result<Self, Self::Rejection> {
+    async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
         let bearer_token = extract_header_as_str(req.headers(), http_headers::DAP_AUTH_TOKEN)
             .map(BearerToken::from);
         let cf_tls_client_auth =
@@ -336,9 +336,8 @@ mod test {
     };
 
     use axum::{
-        body::{Body, HttpBody},
-        extract::State,
-        http::{header::CONTENT_TYPE, Request, StatusCode},
+        body::Body,
+        extract::{Request, State},
         response::IntoResponse,
         routing::get,
         Router,
@@ -347,10 +346,12 @@ mod test {
         async_test_versions,
         constants::DapMediaType,
         messages::{
-            request::resource, taskprov::TaskprovAdvertisement, AggregationJobId, Base64Encode,
-            CollectionJobId, TaskId,
+            request::{CollectionPollReq, RequestBody},
+            taskprov::TaskprovAdvertisement,
+            AggregationJobId, AggregationJobInitReq, Base64Encode, CollectionJobId, CollectionReq,
+            TaskId,
         },
-        DapError, DapRequestMeta, DapSender, DapVersion,
+        DapError, DapRequest, DapRequestMeta, DapSender, DapVersion,
     };
     use daphne_service_utils::{bearer_token::BearerToken, http_headers};
     use either::Either::{self, Left};
@@ -362,17 +363,18 @@ mod test {
     };
     use tower::ServiceExt;
 
-    use crate::metrics::{DaphnePromServiceMetrics, DaphneServiceMetrics};
+    use crate::{
+        metrics::{DaphnePromServiceMetrics, DaphneServiceMetrics},
+        router::extractor::UnauthenticatedDapRequestExtractor,
+    };
 
-    use super::{dap_sender::FROM_LEADER, resource_parsers};
+    use super::{dap_sender::FROM_LEADER, resource_parsers, DecodeFromDapHttpBody};
+    use http::{header, StatusCode};
+    use prio::codec::ParameterizedEncode;
 
     const BEARER_TOKEN: &str = "test-token";
 
-    // In these tests we don't care about the body, so we can type alias it away.
-    type DapRequest<R = resource::None> = daphne::DapRequest<(), R>;
-    type UnauthenticatedDapRequestExtractor<R = resource::None> =
-        super::UnauthenticatedDapRequestExtractor<(), R>;
-    type DapRequestExtractor<R = resource::None> = super::DapRequestExtractor<FROM_LEADER, (), R>;
+    type DapRequestExtractor<B> = super::DapRequestExtractor<FROM_LEADER, B>;
 
     /// Return a function that will parse a request using the [`DapRequestExtractor`] or
     /// [`UnauthenticatedDapRequestExtractor`] and return the parsed request.
@@ -382,17 +384,15 @@ mod test {
     ///  - `/:version/:task_id/parse-mandatory-fields` uses the [`UnauthenticatedDapRequestExtractor`]
     ///  - `/:version/:agg_job_id/parse-agg-job-id` uses the [`UnauthenticatedDapRequestExtractor`]
     ///  - `/:version/:collect_job_id/parse-collect-job-id` uses the [`UnauthenticatedDapRequestExtractor`]
-    async fn test<B, R>(req: Request<B>) -> Result<DapRequest<R>, StatusCode>
+    async fn test<B>(req: Request) -> Result<DapRequest<B>, StatusCode>
     where
-        B: Send + Sync + 'static + HttpBody,
-        B::Data: Send,
-        B::Error: Send + Sync + std::error::Error,
-        R: resource_parsers::Resource + 'static,
+        B: DecodeFromDapHttpBody + Send + Sync + 'static,
+        B::ResourceId: resource_parsers::Resource + Send,
     {
-        type Channel<R> = Sender<DapRequest<R>>;
+        type Channel<B> = Sender<DapRequest<B>>;
 
         #[axum::async_trait]
-        impl<R: Send> super::DaphneService for Channel<R> {
+        impl<R: Send + Sync + RequestBody<ResourceId: Send + Sync>> super::DaphneService for Channel<R> {
             fn server_metrics(&self) -> &dyn DaphneServiceMetrics {
                 // These tests don't care about metrics so we just store a static instance here so I
                 // can implement the DaphneService trait for Channel.
@@ -428,33 +428,33 @@ mod test {
 
         // create a router that takes the send end of the channel as state
         let router = Router::new()
-            .route("/:version/:task_id/auth", get(auth_handler::<R>))
+            .route("/:version/:task_id/auth", get(auth_handler::<B>))
             .route(
                 "/:version/:task_id/parse-mandatory-fields",
-                get(handler::<R>),
+                get(handler::<B>),
             )
             .route(
                 "/:version/:task_id/:agg_job_id/parse-agg-job-id",
-                get(handler::<R>),
+                get(handler::<B>),
             )
             .route(
                 "/:version/:task_id/:collect_job_id/parse-collect-job-id",
-                get(handler::<R>),
+                get(handler::<B>),
             )
             .with_state(Arc::new(tx));
 
         // unauthenticated handler that simply sends the received request through the channel
-        async fn handler<R>(
-            State(ch): State<Arc<Channel<R>>>,
-            req: UnauthenticatedDapRequestExtractor<R>,
+        async fn handler<B: RequestBody>(
+            State(ch): State<Arc<Channel<B>>>,
+            req: UnauthenticatedDapRequestExtractor<B>,
         ) -> impl IntoResponse {
             ch.send(req.0).await.unwrap();
         }
 
         // unauthenticated handler that simply sends the received request through the channel
-        async fn auth_handler<R>(
-            State(ch): State<Arc<Channel<R>>>,
-            req: DapRequestExtractor<R>,
+        async fn auth_handler<B: RequestBody>(
+            State(ch): State<Arc<Channel<B>>>,
+            req: DapRequestExtractor<B>,
         ) -> impl IntoResponse {
             ch.send(req.0).await.unwrap();
         }
@@ -472,7 +472,9 @@ mod test {
             // get the request sent through the channel in the handler
             StatusCode::OK => Ok(rx.recv().now_or_never().unwrap().unwrap()),
             code => {
-                let payload = hyper::body::to_bytes(resp.into_body()).await.unwrap();
+                let payload = axum::body::to_bytes(resp.into_body(), usize::MAX)
+                    .await
+                    .unwrap();
                 eprintln!(
                     "body was: {}",
                     String::from_utf8_lossy(&payload).into_owned()
@@ -488,14 +490,14 @@ mod test {
 
     async fn parse_mandatory_fields(version: DapVersion) {
         let task_id = mk_task_id();
-        let req = test::<_, resource::None>(
+        let req = test::<()>(
             Request::builder()
                 .uri(format!(
                     "/{version}/{}/parse-mandatory-fields",
                     task_id.to_base64url()
                 ))
                 .header(
-                    CONTENT_TYPE,
+                    header::CONTENT_TYPE,
                     DapMediaType::AggregateShareReq
                         .as_str_for_version(version)
                         .unwrap(),
@@ -517,7 +519,7 @@ mod test {
         let task_id = mk_task_id();
         let agg_job_id = AggregationJobId(thread_rng().gen());
 
-        let req = test::<_, resource::AggregationJobId>(
+        let req = test::<AggregationJobInitReq>(
             Request::builder()
                 .uri(format!(
                     "/{version}/{}/{}/parse-agg-job-id",
@@ -525,7 +527,21 @@ mod test {
                     agg_job_id.to_base64url(),
                 ))
                 .header(http_headers::DAP_AUTH_TOKEN, BEARER_TOKEN)
-                .body(Body::empty())
+                .header(
+                    header::CONTENT_TYPE,
+                    DapMediaType::AggregationJobInitReq
+                        .as_str_for_version(version)
+                        .unwrap(),
+                )
+                .body(Body::from(
+                    AggregationJobInitReq {
+                        agg_param: vec![],
+                        part_batch_sel: daphne::messages::PartialBatchSelector::TimeInterval,
+                        prep_inits: vec![],
+                    }
+                    .get_encoded_with_param(&version)
+                    .unwrap(),
+                ))
                 .unwrap(),
         )
         .await
@@ -541,7 +557,7 @@ mod test {
         let task_id = mk_task_id();
         let collect_job_id = CollectionJobId(thread_rng().gen());
 
-        let req = test::<_, resource::CollectionJobId>(
+        let req = test::<CollectionReq>(
             Request::builder()
                 .uri(format!(
                     "/{version}/{}/{}/parse-collect-job-id",
@@ -549,7 +565,25 @@ mod test {
                     collect_job_id.to_base64url(),
                 ))
                 .header(http_headers::DAP_AUTH_TOKEN, BEARER_TOKEN)
-                .body(Body::empty())
+                .header(
+                    header::CONTENT_TYPE,
+                    DapMediaType::CollectionReq
+                        .as_str_for_version(version)
+                        .unwrap(),
+                )
+                .body(Body::from(
+                    CollectionReq {
+                        query: daphne::messages::Query::TimeInterval {
+                            batch_interval: daphne::messages::Interval {
+                                start: 1,
+                                duration: 1,
+                            },
+                        },
+                        agg_param: vec![],
+                    }
+                    .get_encoded_with_param(&version)
+                    .unwrap(),
+                ))
                 .unwrap(),
         )
         .await
@@ -561,8 +595,32 @@ mod test {
 
     async_test_versions! { parse_collect_job_id }
 
+    async fn parse_collect_job_id_from_poll_request(version: DapVersion) {
+        let task_id = mk_task_id();
+        let collect_job_id = CollectionJobId(thread_rng().gen());
+
+        let req = test::<CollectionPollReq>(
+            Request::builder()
+                .uri(format!(
+                    "/{version}/{}/{}/parse-collect-job-id",
+                    task_id.to_base64url(),
+                    collect_job_id.to_base64url(),
+                ))
+                .header(http_headers::DAP_AUTH_TOKEN, BEARER_TOKEN)
+                .body(Body::empty())
+                .unwrap(),
+        )
+        .await
+        .unwrap();
+
+        assert_eq!(req.resource_id, collect_job_id);
+        assert_eq!(req.task_id, task_id);
+    }
+
+    async_test_versions! { parse_collect_job_id_from_poll_request }
+
     async fn incorrect_bearer_tokens_are_rejected(version: DapVersion) {
-        let status_code = test::<_, resource::None>(
+        let status_code = test::<()>(
             Request::builder()
                 .uri(format!("/{version}/{}/auth", mk_task_id().to_base64url()))
                 .header(http_headers::DAP_AUTH_TOKEN, "something incorrect")
@@ -578,7 +636,7 @@ mod test {
     async_test_versions! { incorrect_bearer_tokens_are_rejected }
 
     async fn missing_auth_is_rejected(version: DapVersion) {
-        let status_code = test::<_, resource::None>(
+        let status_code = test::<()>(
             Request::builder()
                 .uri(format!("/{version}/{}/auth", mk_task_id().to_base64url()))
                 .body(Body::empty())
@@ -614,7 +672,7 @@ mod test {
             },
         };
 
-        let req = test::<_, resource::None>(
+        let req = test::<()>(
             Request::builder()
                 .uri(format!(
                     "/{version}/{}/auth",
@@ -640,7 +698,7 @@ mod test {
     async_test_versions! { mtls_auth_is_enough }
 
     async fn incorrect_bearer_tokens_are_rejected_even_with_mtls_auth(version: DapVersion) {
-        let code = test::<_, resource::None>(
+        let code = test::<()>(
             Request::builder()
                 .uri(format!("/{version}/{}/auth", mk_task_id().to_base64url()))
                 .header(http_headers::DAP_AUTH_TOKEN, "something incorrect")
@@ -657,7 +715,7 @@ mod test {
     async_test_versions! { incorrect_bearer_tokens_are_rejected_even_with_mtls_auth }
 
     async fn invalid_mtls_auth_is_rejected_despite_correct_bearer_token(version: DapVersion) {
-        let code = test::<_, resource::None>(
+        let code = test::<()>(
             Request::builder()
                 .uri(format!("/{version}/{}/auth", mk_task_id().to_base64url()))
                 .header(http_headers::DAP_AUTH_TOKEN, BEARER_TOKEN)
diff --git a/crates/daphne-server/src/router/helper.rs b/crates/daphne-server/src/router/helper.rs
index 403697b..d6f8ece 100644
--- a/crates/daphne-server/src/router/helper.rs
+++ b/crates/daphne-server/src/router/helper.rs
@@ -4,12 +4,11 @@
 use std::sync::Arc;
 
 use axum::{
-    body::HttpBody,
     extract::State,
     routing::{post, put},
 };
 use daphne::{
-    messages::{request::resource, AggregateShareReq, AggregationJobInitReq},
+    messages::{AggregateShareReq, AggregationJobInitReq},
     roles::{helper, DapHelper},
 };
 use http::StatusCode;
@@ -20,12 +19,7 @@ use super::{
     extractor::dap_sender::FROM_LEADER, AxumDapResponse, DapRequestExtractor, DaphneService,
 };
 
-pub(super) fn add_helper_routes<B>(router: super::Router<App, B>) -> super::Router<App, B>
-where
-    B: Send + HttpBody + 'static,
-    B::Data: Send,
-    B::Error: Send + Sync,
-{
+pub(super) fn add_helper_routes(router: super::Router<App>) -> super::Router<App> {
     router
         .route(
             "/:version/tasks/:task_id/aggregation_jobs/:agg_job_id",
@@ -44,11 +38,7 @@ where
 )]
 async fn agg_job(
     State(app): State<Arc<App>>,
-    DapRequestExtractor(req): DapRequestExtractor<
-        FROM_LEADER,
-        AggregationJobInitReq,
-        resource::AggregationJobId,
-    >,
+    DapRequestExtractor(req): DapRequestExtractor<FROM_LEADER, AggregationJobInitReq>,
 ) -> AxumDapResponse {
     let timer = std::time::Instant::now();
 
diff --git a/crates/daphne-server/src/router/leader.rs b/crates/daphne-server/src/router/leader.rs
index 528e7aa..06584e9 100644
--- a/crates/daphne-server/src/router/leader.rs
+++ b/crates/daphne-server/src/router/leader.rs
@@ -4,9 +4,8 @@
 use std::sync::Arc;
 
 use axum::{
-    body::HttpBody,
-    extract::{Path, State},
-    http::{Request, StatusCode},
+    extract::{Path, Request, State},
+    http::StatusCode,
     middleware::{from_fn, Next},
     response::{IntoResponse, Response},
     routing::{get, post, put},
@@ -14,7 +13,7 @@ use axum::{
 use daphne::{
     constants::DapMediaType,
     error::DapAbort,
-    messages::{self, request::resource},
+    messages::{self, request::CollectionPollReq},
     roles::leader::{self, DapLeader},
     DapError, DapVersion,
 };
@@ -33,9 +32,9 @@ struct PathVersion {
     presented_version: DapVersion,
 }
 
-fn require_version<B: Send + 'static>(
+fn require_version(
     expected_version: DapVersion,
-) -> impl Copy + Fn(Path<PathVersion>, Request<B>, Next<B>) -> BoxFuture<'static, Response> {
+) -> impl Copy + Fn(Path<PathVersion>, Request, Next) -> BoxFuture<'static, Response> {
     move |Path(PathVersion { presented_version }), req, next| {
         async move {
             if presented_version != expected_version {
@@ -47,12 +46,9 @@ fn require_version<B: Send + 'static>(
     }
 }
 
-pub(super) fn add_leader_routes<A, B>(router: super::Router<A, B>) -> super::Router<A, B>
+pub(super) fn add_leader_routes<A>(router: super::Router<A>) -> super::Router<A>
 where
     A: DapLeader + DaphneService + Send + Sync + 'static,
-    B: Send + HttpBody + 'static,
-    B::Data: Send,
-    B::Error: Send + Sync,
 {
     router
         .route(
@@ -86,10 +82,7 @@ where
 )]
 async fn upload<A>(
     State(app): State<Arc<A>>,
-    UnauthenticatedDapRequestExtractor(req): UnauthenticatedDapRequestExtractor<
-        messages::Report,
-        resource::None,
-    >,
+    UnauthenticatedDapRequestExtractor(req): UnauthenticatedDapRequestExtractor<messages::Report>,
 ) -> Response
 where
     A: DapLeader + DaphneService + Send + Sync,
@@ -109,11 +102,7 @@ where
 )]
 async fn start_collection_job<A>(
     State(app): State<Arc<A>>,
-    DapRequestExtractor(req): DapRequestExtractor<
-        FROM_COLLECTOR,
-        messages::CollectionReq,
-        resource::CollectionJobId,
-    >,
+    DapRequestExtractor(req): DapRequestExtractor<FROM_COLLECTOR, messages::CollectionReq>,
 ) -> Response
 where
     A: DapLeader + DaphneService + Send + Sync,
@@ -133,7 +122,7 @@ where
 )]
 async fn poll_collect<A>(
     State(app): State<Arc<A>>,
-    DapRequestExtractor(req): DapRequestExtractor<FROM_COLLECTOR, (), resource::CollectionJobId>,
+    DapRequestExtractor(req): DapRequestExtractor<FROM_COLLECTOR, CollectionPollReq>,
 ) -> Response
 where
     A: DapLeader + DaphneService + Send + Sync,
diff --git a/crates/daphne-server/src/router/mod.rs b/crates/daphne-server/src/router/mod.rs
index 3d21bbe..044ffba 100644
--- a/crates/daphne-server/src/router/mod.rs
+++ b/crates/daphne-server/src/router/mod.rs
@@ -11,8 +11,7 @@ pub mod test_routes;
 use std::sync::Arc;
 
 use axum::{
-    body::HttpBody,
-    extract::State,
+    extract::{Request, State},
     http::{header::CONTENT_TYPE, HeaderValue, StatusCode},
     middleware::Next,
     response::IntoResponse,
@@ -24,12 +23,11 @@ use daphne::{
 };
 use daphne_service_utils::{bearer_token::BearerToken, DapRole};
 use either::Either;
-use http::Request;
 
 use crate::{metrics::DaphneServiceMetrics, App};
 use extractor::{DapRequestExtractor, UnauthenticatedDapRequestExtractor};
 
-type Router<A, B> = axum::Router<Arc<A>, B>;
+type Router<A> = axum::Router<Arc<A>>;
 
 /// Capabilities necessary when running a native daphne service.
 #[axum::async_trait]
@@ -88,12 +86,7 @@ where
     }
 }
 
-pub fn new<B>(role: DapRole, aggregator: App) -> axum::Router<(), B>
-where
-    B: Send + HttpBody + 'static,
-    B::Data: Send,
-    B::Error: Send + Sync + Into<Box<dyn std::error::Error + Send + Sync>>,
-{
+pub fn new(role: DapRole, aggregator: App) -> axum::Router<()> {
     let router = axum::Router::new();
 
     let router = aggregator::add_aggregator_routes(router);
@@ -106,10 +99,10 @@ where
     #[cfg(feature = "test-utils")]
     let router = test_routes::add_test_routes(router, role);
 
-    async fn request_metrics<B>(
+    async fn request_metrics(
         State(app): State<Arc<App>>,
-        req: Request<B>,
-        next: Next<B>,
+        req: Request,
+        next: Next,
     ) -> impl IntoResponse {
         tracing::info!(method = %req.method(), uri = %req.uri(), "received request");
         let resp = next.run(req).await;
diff --git a/crates/daphne/src/messages/request.rs b/crates/daphne/src/messages/request.rs
index 1808227..a1135ff 100644
--- a/crates/daphne/src/messages/request.rs
+++ b/crates/daphne/src/messages/request.rs
@@ -3,24 +3,36 @@
 
 use std::ops::Deref;
 
-use super::taskprov::TaskprovAdvertisement;
+use super::{
+    taskprov::TaskprovAdvertisement, AggregateShareReq, AggregationJobId, AggregationJobInitReq,
+    CollectionJobId, CollectionReq, Report,
+};
 use crate::{constants::DapMediaType, error::DapAbort, messages::TaskId, DapVersion};
 
-pub mod resource {
-    /// Aggregation job resource.
-    pub use crate::messages::AggregationJobId;
-    /// Collection job resource.
-    pub use crate::messages::CollectionJobId;
-
-    /// Undefined (or undetermined) resource.
-    ///
-    /// The resource of a DAP request is undefined if there is not a unique object (in the context
-    /// of a DAP task) that the request pertains to. For example:
-    ///
-    ///   * The Client->Aggregator request for the HPKE config or to upload a report
-    ///   * The Leader->Helper request for an aggregate share
-    #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)]
-    pub struct None;
+pub trait RequestBody {
+    type ResourceId;
+}
+
+/// A poll request has no body, but requires a `CollectionJobId`.
+pub struct CollectionPollReq;
+
+macro_rules! impl_req_body {
+    ($($body:tt | $id:tt)*) => {
+        $(impl RequestBody for $body {
+                type ResourceId = $id;
+        })*
+    };
+}
+
+impl_req_body! {
+//  body type             | id type
+//  --------------------- | ----------------
+    Report                | ()
+    AggregationJobInitReq | AggregationJobId
+    AggregateShareReq     | ()
+    CollectionReq         | CollectionJobId
+    CollectionPollReq     | CollectionJobId
+    ()                    | ()
 }
 
 /// Fields common to all DAP requests.
@@ -50,32 +62,25 @@ impl DapRequestMeta {
 }
 
 /// DAP request.
-///
-/// # Type parameters
-/// - `P`: is the payload of the request.
-/// - `R`: is the resource id this request points to. Possible values of this are:
-///     - [`AggregationJobId`](resource::AggregationJobId)
-///     - [`CollectionJobId`](resource::CollectionJobId)
-///     - [`None`](resource::None)
 #[derive(Debug)]
 #[cfg_attr(test, derive(Default))]
-pub struct DapRequest<P, R = resource::None> {
+pub struct DapRequest<B: RequestBody> {
     pub meta: DapRequestMeta,
 
     /// The resource with which this request is associated.
-    pub resource_id: R,
+    pub resource_id: B::ResourceId,
 
     /// Request payload.
-    pub payload: P,
+    pub payload: B,
 }
 
-impl<P, R> AsRef<DapRequestMeta> for DapRequest<P, R> {
+impl<B: RequestBody> AsRef<DapRequestMeta> for DapRequest<B> {
     fn as_ref(&self) -> &DapRequestMeta {
         &self.meta
     }
 }
 
-impl<P, R> Deref for DapRequest<P, R> {
+impl<B: RequestBody> Deref for DapRequest<B> {
     type Target = DapRequestMeta;
     fn deref(&self) -> &Self::Target {
         &self.meta
diff --git a/crates/daphne/src/roles/helper.rs b/crates/daphne/src/roles/helper.rs
index ceede1d..23235b3 100644
--- a/crates/daphne/src/roles/helper.rs
+++ b/crates/daphne/src/roles/helper.rs
@@ -11,9 +11,8 @@ use crate::{
     constants::DapMediaType,
     error::DapAbort,
     messages::{
-        constant_time_eq, request::resource, AggregateShare, AggregateShareReq,
-        AggregationJobInitReq, AggregationJobResp, PartialBatchSelector, TaskId, TransitionFailure,
-        TransitionVar,
+        constant_time_eq, AggregateShare, AggregateShareReq, AggregationJobInitReq,
+        AggregationJobResp, PartialBatchSelector, TaskId, TransitionFailure, TransitionVar,
     },
     metrics::{DaphneMetrics, DaphneRequestType, ReportStatus},
     protocol::aggregator::{InitializedReport, ReplayProtection, ReportProcessedStatus},
@@ -27,7 +26,7 @@ pub trait DapHelper: DapAggregator {}
 
 pub async fn handle_agg_job_init_req<A: DapHelper + Sync>(
     aggregator: &A,
-    req: DapRequest<AggregationJobInitReq, resource::AggregationJobId>,
+    req: DapRequest<AggregationJobInitReq>,
     replay_protection: ReplayProtection,
 ) -> Result<DapResponse, DapError> {
     let task_id = req.task_id;
diff --git a/crates/daphne/src/roles/leader/mod.rs b/crates/daphne/src/roles/leader/mod.rs
index fe14e29..eff1752 100644
--- a/crates/daphne/src/roles/leader/mod.rs
+++ b/crates/daphne/src/roles/leader/mod.rs
@@ -18,9 +18,9 @@ use crate::{
     error::DapAbort,
     fatal_error,
     messages::{
-        request::resource, taskprov::TaskprovAdvertisement, AggregateShare, AggregateShareReq,
-        AggregationJobId, AggregationJobResp, Base64Encode, BatchId, BatchSelector, Collection,
-        CollectionJobId, CollectionReq, Interval, PartialBatchSelector, Query, Report, TaskId,
+        taskprov::TaskprovAdvertisement, AggregateShare, AggregateShareReq, AggregationJobId,
+        AggregationJobResp, Base64Encode, BatchId, BatchSelector, Collection, CollectionJobId,
+        CollectionReq, Interval, PartialBatchSelector, Query, Report, TaskId,
     },
     metrics::{DaphneRequestType, ReportStatus},
     roles::resolve_task_config,
@@ -236,7 +236,7 @@ pub async fn handle_upload_req<A: DapLeader>(
 /// poll later on to get the collection.
 pub async fn handle_coll_job_req<A: DapLeader>(
     aggregator: &A,
-    req: &DapRequest<CollectionReq, resource::CollectionJobId>,
+    req: &DapRequest<CollectionReq>,
 ) -> Result<(), DapError> {
     let global_config = aggregator.get_global_config().await?;
     let now = aggregator.get_current_time();
diff --git a/crates/daphne/src/roles/mod.rs b/crates/daphne/src/roles/mod.rs
index cf07bc8..3afc2ca 100644
--- a/crates/daphne/src/roles/mod.rs
+++ b/crates/daphne/src/roles/mod.rs
@@ -136,7 +136,7 @@ mod test {
         constants::DapMediaType,
         hpke::{HpkeKemId, HpkeProvider, HpkeReceiverConfig},
         messages::{
-            request::resource, AggregateShareReq, AggregationJobId, AggregationJobInitReq,
+            request::RequestBody, AggregateShareReq, AggregationJobId, AggregationJobInitReq,
             AggregationJobResp, BatchId, BatchSelector, Collection, CollectionJobId, CollectionReq,
             Extension, HpkeCiphertext, Interval, PartialBatchSelector, Query, Report, TaskId, Time,
             TransitionFailure, TransitionVar,
@@ -389,7 +389,7 @@ mod test {
             &self,
             report: Report,
             task_id: &TaskId,
-        ) -> DapRequest<Report, resource::None> {
+        ) -> DapRequest<Report> {
             let task_config = self.leader.unchecked_get_task_config(task_id).await;
             let version = task_config.version;
 
@@ -400,7 +400,7 @@ mod test {
                     task_id: *task_id,
                     ..Default::default()
                 },
-                resource_id: resource::None,
+                resource_id: Default::default(),
                 payload: report,
             }
         }
@@ -409,7 +409,7 @@ mod test {
             &self,
             query: Query,
             task_id: &TaskId,
-        ) -> DapRequest<CollectionReq, resource::CollectionJobId> {
+        ) -> DapRequest<CollectionReq> {
             self.gen_test_coll_job_req_for_collection(query, DapAggregationParam::Empty, task_id)
                 .await
         }
@@ -419,7 +419,7 @@ mod test {
             query: Query,
             agg_param: DapAggregationParam,
             task_id: &TaskId,
-        ) -> DapRequest<CollectionReq, resource::CollectionJobId> {
+        ) -> DapRequest<CollectionReq> {
             let task_config = self.leader.unchecked_get_task_config(task_id).await;
 
             Self::collector_req(
@@ -438,10 +438,7 @@ mod test {
             task_id: &TaskId,
             agg_param: DapAggregationParam,
             reports: Vec<Report>,
-        ) -> (
-            DapAggregationJobState,
-            DapRequest<AggregationJobInitReq, resource::AggregationJobId>,
-        ) {
+        ) -> (DapAggregationJobState, DapRequest<AggregationJobInitReq>) {
             let mut rng = thread_rng();
             let task_config = self.leader.unchecked_get_task_config(task_id).await;
             let part_batch_sel = match task_config.query {
@@ -520,13 +517,13 @@ mod test {
                 .unwrap()
         }
 
-        pub fn leader_req<P, R>(
+        pub fn leader_req<B: RequestBody>(
             task_id: &TaskId,
             task_config: &DapTaskConfig,
-            agg_job_id: R,
+            agg_job_id: B::ResourceId,
             media_type: DapMediaType,
-            payload: P,
-        ) -> DapRequest<P, R> {
+            payload: B,
+        ) -> DapRequest<B> {
             DapRequest {
                 meta: DapRequestMeta {
                     version: task_config.version,
@@ -539,12 +536,12 @@ mod test {
             }
         }
 
-        pub fn collector_req<C>(
+        pub fn collector_req(
             task_id: &TaskId,
             task_config: &DapTaskConfig,
             media_type: DapMediaType,
-            payload: C,
-        ) -> DapRequest<C, resource::CollectionJobId> {
+            payload: CollectionReq,
+        ) -> DapRequest<CollectionReq> {
             let mut rng = thread_rng();
             let coll_job_id = CollectionJobId(rng.gen());
 
@@ -667,7 +664,7 @@ mod test {
         let req = Test::leader_req(
             &t.time_interval_task_id,
             &task_config,
-            resource::None,
+            (),
             DapMediaType::AggregateShareReq,
             AggregateShareReq {
                 batch_sel: BatchSelector::FixedSizeByBatchId {
@@ -693,7 +690,7 @@ mod test {
         let req = Test::leader_req(
             &t.fixed_size_task_id,
             &task_config,
-            resource::None,
+            (),
             DapMediaType::AggregateShareReq,
             AggregateShareReq {
                 batch_sel: BatchSelector::FixedSizeByBatchId {
@@ -875,7 +872,7 @@ mod test {
                 task_id: TaskId([0; 32]),
                 ..Default::default()
             },
-            resource_id: resource::None,
+            resource_id: (),
             payload: report_invalid_task_id,
         };
 
@@ -904,7 +901,7 @@ mod test {
                 task_id: *task_id,
                 ..Default::default()
             },
-            resource_id: resource::None,
+            resource_id: (),
             payload: report.clone(),
         };
 
@@ -1464,7 +1461,7 @@ mod test {
                     task_id,
                     taskprov_advertisement: Some(taskprov_advertisement.clone()),
                 },
-                resource_id: resource::None,
+                resource_id: (),
                 payload: report,
             };
             leader::handle_upload_req(&*t.leader, req).await.unwrap();


Test patch:
diff --git a/crates/daphne-server/src/router/test_routes.rs b/crates/daphne-server/src/router/test_routes.rs
index e00e589..bf9120b 100644
--- a/crates/daphne-server/src/router/test_routes.rs
+++ b/crates/daphne-server/src/router/test_routes.rs
@@ -4,7 +4,6 @@
 use std::sync::Arc;
 
 use axum::{
-    body::HttpBody,
     extract::{Path, State},
     http::StatusCode,
     response::{IntoResponse, Response},
@@ -27,12 +26,7 @@ use crate::App;
 
 use super::{AxumDapResponse, DaphneService};
 
-pub fn add_test_routes<B>(router: super::Router<App, B>, role: DapRole) -> super::Router<App, B>
-where
-    B: Send + HttpBody + 'static,
-    B::Data: Send,
-    B::Error: Send + Sync + Into<Box<dyn std::error::Error + Send + Sync>>,
-{
+pub fn add_test_routes(router: super::Router<App>, role: DapRole) -> super::Router<App> {
     let router = if role == DapRole::Leader {
         router
             .route("/internal/process", post(leader_process))
diff --git a/crates/daphne-server/tests/e2e/test_runner.rs b/crates/daphne-server/tests/e2e/test_runner.rs
index 1cee9cf..1fabcde 100644
--- a/crates/daphne-server/tests/e2e/test_runner.rs
+++ b/crates/daphne-server/tests/e2e/test_runner.rs
@@ -26,6 +26,7 @@ use std::{
     num::NonZeroUsize,
     ops::Range,
 };
+use tokio::time::timeout;
 use url::Url;
 
 const VDAF_CONFIG: &VdafConfig = &VdafConfig::Prio3(Prio3Config::Sum { bits: 10 });
@@ -198,14 +199,17 @@ impl TestRunner {
                         Err(e) => Some(format!("connection to {url} failed: {e:?}")),
                     }
                 })
-                .collect::<Vec<_>>()
-                .await;
-            match failed_connections.first() {
-                Some(failure) if attempt == MAX_ATTEMPTS => {
+                .collect::<Vec<_>>();
+            match timeout(std::time::Duration::from_secs(5), failed_connections)
+                .await
+                .map(|f| f.first().cloned())
+            {
+                Ok(Some(failure)) if attempt == MAX_ATTEMPTS => {
                     panic!("One of the aggregators was not ready in time: {failure}")
                 }
-                Some(_) => tokio::time::sleep(std::time::Duration::from_secs(1)).await,
-                None => break,
+                Ok(Some(_)) => tokio::time::sleep(std::time::Duration::from_secs(1)).await,
+                Err(_elapsed) => {}
+                Ok(None) => break,
             }
         }
 
diff --git a/crates/daphne/src/testing/mod.rs b/crates/daphne/src/testing/mod.rs
index 7753a6f..fb666b1 100644
--- a/crates/daphne/src/testing/mod.rs
+++ b/crates/daphne/src/testing/mod.rs
@@ -12,9 +12,9 @@ use crate::{
     fatal_error,
     hpke::{HpkeConfig, HpkeKemId, HpkeProvider, HpkeReceiverConfig},
     messages::{
-        self, request::resource, AggregationJobId, AggregationJobInitReq, AggregationJobResp,
-        Base64Encode, BatchId, BatchSelector, Collection, CollectionJobId, HpkeCiphertext,
-        Interval, PartialBatchSelector, Report, ReportId, TaskId, Time,
+        self, AggregationJobId, AggregationJobInitReq, AggregationJobResp, Base64Encode, BatchId,
+        BatchSelector, Collection, CollectionJobId, HpkeCiphertext, Interval, PartialBatchSelector,
+        Report, ReportId, TaskId, Time,
     },
     metrics::{prometheus::DaphnePromMetrics, DaphneMetrics},
     roles::{
@@ -972,7 +972,7 @@ impl DapLeader for InMemoryAggregator {
                 &**self.peer.as_ref().expect("peer not configured"),
                 DapRequest {
                     payload: re_encode(&meta, payload),
-                    resource_id: resource::AggregationJobId::try_from_base64url(
+                    resource_id: AggregationJobId::try_from_base64url(
                         url.path().split('/').last().unwrap(),
                     )
                     .unwrap(),
@@ -986,7 +986,7 @@ impl DapLeader for InMemoryAggregator {
                 &**self.peer.as_ref().expect("peer not configured"),
                 DapRequest {
                     payload: re_encode(&meta, payload),
-                    resource_id: resource::None,
+                    resource_id: (),
                     meta,
                 },
             )
@@ -1010,7 +1010,7 @@ impl DapLeader for InMemoryAggregator {
                 &**self.peer.as_ref().expect("peer not configured"),
                 DapRequest {
                     payload: re_encode(&meta, payload),
-                    resource_id: resource::AggregationJobId::try_from_base64url(
+                    resource_id: AggregationJobId::try_from_base64url(
                         url.path().split('/').last().unwrap(),
                     )
                     .unwrap(),