diff --git a/Cargo.lock b/Cargo.lock index 7868ad66b8e..f935f0d429f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -48,9 +48,9 @@ checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" [[package]] name = "alloc-stdlib" -version = "0.2.2" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +checksum = "0e76a019e91224d279006ff972f1e984179a6e9feb050adba6ce8274aef23195" dependencies = [ "alloc-no-stdlib", ] @@ -160,11 +160,11 @@ dependencies = [ [[package]] name = "ar_archive_writer" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb93bbb63b9c227414f6eb3a0adfddca591a8ce1e9b60661bb08969b87e340b" +checksum = "4087686b4b0a3427190bae57a1d9a478dbb2d40c5dc1bd6e2b6d797913bdd348" dependencies = [ - "object", + "object 0.37.3", ] [[package]] @@ -175,9 +175,9 @@ checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" [[package]] name = "arc-swap" -version = "1.9.1" +version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a3a1fd6f75306b68087b831f025c712524bcb19aad54e557b1129cfa0a2b207" +checksum = "c049c0be4daef0b145cb3555416b3b8ef5b7888a38aea1a3a155801fe7b0810b" dependencies = [ "rustversion", ] @@ -239,9 +239,9 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "axum" @@ -364,7 +364,7 @@ dependencies = [ "cfg-if", "libc", "miniz_oxide", - "object", + "object 0.37.3", "rustc-demangle", "windows-link 0.2.1", ] @@ -419,7 +419,7 @@ dependencies = [ "quote", "regex", "rustc-hash", - "shlex", + "shlex 1.3.0", "syn", ] @@ -440,9 +440,9 @@ checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" [[package]] name = "bitflags" -version = "2.11.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" dependencies = [ "serde_core", ] @@ -478,13 +478,13 @@ dependencies = [ [[package]] name = "brotli" -version = "8.0.2" +version = "8.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bd8b9603c7aa97359dbd97ecf258968c95f3adddd6db2f7e7a5bef101c84560" +checksum = "5cc91aac060a7a1e25823bdccbfb6af1875b88f17c6daac97894eed8207166b3" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", - "brotli-decompressor 5.0.0", + "brotli-decompressor 5.0.3", ] [[package]] @@ -499,9 +499,9 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "5.0.0" +version = "5.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03" +checksum = "3a32acac15fe1967bc3986b2a6347dffc965602354ea6f450ad07e8bfd253583" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -509,20 +509,20 @@ dependencies = [ [[package]] name = "bstr" -version = "1.12.1" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" +checksum = "5cee35f73844aa3014bb606320a6c1f010249dbdf43342fe54b5a4f6a8ed4b79" dependencies = [ "memchr", "regex-automata", - "serde", + "serde_core", ] [[package]] name = "bumpalo" -version = "3.20.2" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "bytecount" @@ -538,9 +538,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.11.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +checksum = "8ae3f5d315924270530207e2a68396c3cc547f6dca3fbdca317cfb1a51edb593" dependencies = [ "serde", ] @@ -562,14 +562,14 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.61" +version = "1.2.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d" +checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96" dependencies = [ "find-msvc-tools", "jobserver", "libc", - "shlex", + "shlex 2.0.1", ] [[package]] @@ -593,11 +593,22 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +[[package]] +name = "chacha20" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "rand_core 0.10.1", +] + [[package]] name = "chrono" -version = "0.4.44" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" dependencies = [ "iana-time-zone", "num-traits", @@ -668,9 +679,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.6.3" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "660c0520455b1013b9bcb0393d5f643d7e4454fb69c915b8d6d2aa0e9a45acc3" +checksum = "db8b397918185f0161ff3d6fcaa9e4bfc09b8367caf6e1d4a2848e5477ed027b" dependencies = [ "clap", ] @@ -728,7 +739,7 @@ version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce2548391e9c1929c21bf6aa2680af86fe4c1b33e6cea9ac1cfeec0bd11218cf" dependencies = [ - "brotli 8.0.2", + "brotli 8.0.4", "bzip2", "compression-core", "flate2", @@ -768,9 +779,9 @@ dependencies = [ [[package]] name = "console" -version = "0.16.3" +version = "0.16.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d64e8af5551369d19cf50138de61f1c42074ab970f74e99be916646777f8fc87" +checksum = "4fe5f465a4f6fee88fad41b85d990f84c835335e85b5d9e6e63e0d06d28cba7c" dependencies = [ "encode_unicode", "libc", @@ -779,12 +790,12 @@ dependencies = [ [[package]] name = "const-hex" -version = "1.19.0" +version = "1.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20d9a563d167a9cce0f94153382b33cb6eded6dfabff03c69ad65a28ea1514e0" +checksum = "33e2a781ebdf4467d1428dc4593067825fb646f6871475098d8577421af73558" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "proptest", "serde_core", ] @@ -847,6 +858,15 @@ dependencies = [ "libc", ] +[[package]] +name = "cpufeatures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +dependencies = [ + "libc", +] + [[package]] name = "crash-context" version = "0.6.3" @@ -1008,9 +1028,9 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", "typenum", @@ -1023,7 +1043,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "curve25519-dalek-derive", "digest", "fiat-crypto", @@ -1140,9 +1160,6 @@ name = "deranged" version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" -dependencies = [ - "powerfmt", -] [[package]] name = "derive_more" @@ -1205,9 +1222,9 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" dependencies = [ "proc-macro2", "quote", @@ -1304,9 +1321,9 @@ dependencies = [ [[package]] name = "either" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" dependencies = [ "serde", ] @@ -1362,32 +1379,20 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" -[[package]] -name = "enum-as-inner" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "enumset" -version = "1.1.10" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b07a8dfbbbfc0064c0a6bdf9edcf966de6b1c33ce344bdeca3b41615452634" +checksum = "839c4174b41e75c8f7306110b2c51996a293b8d1d850edd529011841d9fede7d" dependencies = [ "enumset_derive", ] [[package]] name = "enumset_derive" -version = "0.14.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43e744e4ea338060faee68ed933e46e722fb7f3617e722a5772d7e856d8b3ce" +checksum = "4bd536557b58c682b217b8fb199afdff47cd3eff260623f19e77074eb073d63a" dependencies = [ "darling", "proc-macro2", @@ -1702,9 +1707,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.9" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", @@ -1732,10 +1737,22 @@ checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "libc", - "r-efi", + "r-efi 5.3.0", "wasip2", ] +[[package]] +name = "getrandom" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +dependencies = [ + "cfg-if", + "libc", + "r-efi 6.0.0", + "rand_core 0.10.1", +] + [[package]] name = "gimli" version = "0.32.3" @@ -1785,9 +1802,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733" +checksum = "6cb093c84e8bd9b188d4c4a8cb6579fc016968d14c99882163cd3ff402a4f155" dependencies = [ "atomic-waker", "bytes", @@ -1843,9 +1860,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.17.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" [[package]] name = "hashlink" @@ -1875,46 +1892,70 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] -name = "hickory-proto" -version = "0.25.2" +name = "hickory-net" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8a6fe56c0038198998a6f217ca4e7ef3a5e51f46163bd6dd60b5c71ca6c6502" +checksum = "e2295ed2f9c31e471e1428a8f88a3f0e1f4b27c15049592138d1eebe9c35b183" dependencies = [ "async-trait", "cfg-if", "data-encoding", - "enum-as-inner", "futures-channel", "futures-io", "futures-util", + "hickory-proto", + "idna", + "ipnet", + "jni", + "rand 0.10.2", + "thiserror 2.0.18", + "tinyvec", + "tokio", + "tracing", + "url", +] + +[[package]] +name = "hickory-proto" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bab31817bfb44672a252e97fe81cd0c18d1b2cf892108922f6818820df8c643" +dependencies = [ + "data-encoding", "idna", "ipnet", + "jni", "once_cell", - "rand 0.9.4", + "prefix-trie", + "rand 0.10.2", "ring", "thiserror 2.0.18", "tinyvec", - "tokio", "tracing", "url", ] [[package]] name = "hickory-resolver" -version = "0.25.2" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc62a9a99b0bfb44d2ab95a7208ac952d31060efc16241c87eaf36406fecf87a" +checksum = "f0d58d28879ceecde6607729660c2667a081ccdc082e082675042793960f178c" dependencies = [ "cfg-if", "futures-util", + "hickory-net", "hickory-proto", "ipconfig", + "ipnet", + "jni", "moka", + "ndk-context", "once_cell", "parking_lot", - "rand 0.9.4", + "rand 0.10.2", "resolv-conf", "smallvec", + "system-configuration", "thiserror 2.0.18", "tokio", "tracing", @@ -1960,9 +2001,9 @@ dependencies = [ [[package]] name = "http" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425" dependencies = [ "bytes", "itoa", @@ -2005,15 +2046,15 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "human-size" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9994b79e8c1a39b3166c63ae7823bb2b00831e2a96a31399c50fe69df408eaeb" +checksum = "67f1f25c36d3e2a9ed0caf095f1183bb94dd176a1c81521943e416f8ef749fda" [[package]] name = "humantime" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" +checksum = "15cdd26707701c53297e2fa6afb323d55fbc1d0810c3aec078ae3ef0424c3c15" [[package]] name = "humantime-serde" @@ -2027,9 +2068,9 @@ dependencies = [ [[package]] name = "hyper" -version = "1.9.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" +checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498" dependencies = [ "atomic-waker", "bytes", @@ -2256,7 +2297,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.17.0", + "hashbrown 0.17.1", ] [[package]] @@ -2267,11 +2308,11 @@ checksum = "a588916bfdfd92e71cacef98a63d9b1f0d74d6599980d11894290e7ddefffcf7" [[package]] name = "insta" -version = "1.47.2" +version = "1.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b4a6248eb93a4401ed2f37dfe8ea592d3cf05b7cf4f8efa867b6895af7e094e" +checksum = "86f0f8fee8c926415c58d6ae43a08523a26faccb2323f5e6b644fe7dd4ef6b82" dependencies = [ - "console 0.16.3", + "console 0.16.4", "once_cell", "pest", "pest_derive", @@ -2299,6 +2340,9 @@ name = "ipnet" version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" +dependencies = [ + "serde", +] [[package]] name = "ipnetwork" @@ -2306,16 +2350,6 @@ version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf370abdafd54d13e54a620e8c3e1145f28e46cc9d704bc6d94414559df41763" -[[package]] -name = "iri-string" -version = "0.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25e659a4bb38e810ebc252e53b5814ff908a8c58c2a9ce2fae1bbec24cbf4e20" -dependencies = [ - "memchr", - "serde", -] - [[package]] name = "is-terminal" version = "0.4.17" @@ -2375,6 +2409,55 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +[[package]] +name = "jni" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" +dependencies = [ + "cfg-if", + "combine", + "jni-macros", + "jni-sys", + "log", + "simd_cesu8", + "thiserror 2.0.18", + "walkdir", + "windows-link 0.2.1", +] + +[[package]] +name = "jni-macros" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "simd_cesu8", + "syn", +] + +[[package]] +name = "jni-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +dependencies = [ + "jni-sys-macros", +] + +[[package]] +name = "jni-sys-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +dependencies = [ + "quote", + "syn", +] + [[package]] name = "jobserver" version = "0.1.34" @@ -2387,13 +2470,12 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.97" +version = "0.3.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1840c94c045fbcf8ba2812c95db44499f7c64910a912551aaaa541decebcacf" +checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" dependencies = [ "cfg-if", "futures-util", - "once_cell", "wasm-bindgen", ] @@ -2433,9 +2515,9 @@ dependencies = [ [[package]] name = "jsonwebtoken" -version = "10.3.0" +version = "10.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0529410abe238729a60b108898784df8984c87f6054c9c4fcacc47e4803c1ce1" +checksum = "eba32bfb4ffdeaca3e34431072faf01745c9b26d25504aa7a6cf5684334fc4fc" dependencies = [ "base64", "ed25519-dalek", @@ -2452,6 +2534,7 @@ dependencies = [ "sha2", "signature", "simple_asn1", + "zeroize", ] [[package]] @@ -2475,9 +2558,9 @@ dependencies = [ [[package]] name = "libbz2-rs-sys" -version = "0.2.3" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3a6a8c165077efc8f3a971534c50ea6a1a18b329ef4a66e897a7e3a1494565f" +checksum = "34b357333733e8260735ba5894eb928c02ecc69c78715f01a8019e7fa7f2db4c" [[package]] name = "libc" @@ -2487,9 +2570,9 @@ checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libfuzzer-sys" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12a681b7dd8ce12bff52488013ba614b869148d54dd79836ab85aafdd53f08d" +checksum = "a9fd2f41a1cba099f79a0b6b6c35656cf7c03351a7bae8ff0f28f25270f929d2" dependencies = [ "arbitrary", "cc", @@ -2507,18 +2590,18 @@ dependencies = [ [[package]] name = "liblzma" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6033b77c21d1f56deeae8014eb9fbe7bdf1765185a6c508b5ca82eeaed7f899" +checksum = "45aec2360b3933207e27908049d8e4df4e476b58180afb1e56b2a4fb72efe4ba" dependencies = [ "liblzma-sys", ] [[package]] name = "liblzma-sys" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a60851d15cd8c5346eca4ab8babff585be2ae4bc8097c067291d3ffe2add3b6" +checksum = "a046c7f353ba30f810545151e04f63545833803f5b86ee3ddf1517247fe560a5" dependencies = [ "cc", "libc", @@ -2543,14 +2626,14 @@ dependencies = [ [[package]] name = "libredox" -version = "0.1.16" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" +checksum = "c943259e342f1e06ff2da7a83eabdfe7f92ce10262688dbf1895ff0b3e6e4652" dependencies = [ "bitflags", "libc", "plain", - "redox_syscall 0.7.5", + "redox_syscall 0.9.0", ] [[package]] @@ -2566,9 +2649,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.28" +version = "1.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc3a226e576f50782b3305c5ccf458698f92798987f551c6a02efe8276721e22" +checksum = "85bc9657773828b90eeb625adff10eeac83cc21bbfd8e23a03eaa8a33c9e28d9" dependencies = [ "cc", "libc", @@ -2599,9 +2682,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.29" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" [[package]] name = "lru" @@ -2614,9 +2697,9 @@ dependencies = [ [[package]] name = "lz4_flex" -version = "0.11.6" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "373f5eceeeab7925e0c1098212f2fbc4d416adec9d35051a6ab251e824c1854a" +checksum = "7ef0d4ed8669f8f8826eb00dc878084aa8f253506c4fd5e8f58f5bce72ddb97e" dependencies = [ "twox-hash", ] @@ -2683,33 +2766,24 @@ checksum = "120fa187be19d9962f0926633453784691731018a2bf936ddb4e29101b79c4a7" [[package]] name = "memchr" -version = "2.8.0" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" [[package]] name = "memmap2" -version = "0.9.10" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3" +checksum = "d1219ed1b7f229ee7104d281dd01d6802fe28bb6e95d292942c4daacdeb798c0" dependencies = [ "libc", ] -[[package]] -name = "memoffset" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" -dependencies = [ - "autocfg", -] - [[package]] name = "metrics" -version = "0.24.5" +version = "0.24.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff56c2e7dce6bd462e3b8919986a617027481b1dcc703175b58cf9dd98a2f071" +checksum = "89550ee9f79e88fef3119de263694973a8adb26c21d75322164fb8c493039fe2" dependencies = [ "portable-atomic", "rapidhash", @@ -2732,9 +2806,9 @@ dependencies = [ [[package]] name = "metrics-util" -version = "0.20.3" +version = "0.20.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e56997f084e57b045edf17c3ed8ba7f9f779c670df8206dfd1c736f4c02dc4a" +checksum = "96f8722f8562635f92f8ed992f26df0532266eb03d5202607c20c0d7e9745e13" dependencies = [ "aho-corasick", "crossbeam-epoch", @@ -2787,7 +2861,7 @@ dependencies = [ "memmap2", "minidump-common", "num-traits", - "procfs-core", + "procfs-core 0.17.0", "prost 0.13.5", "range-map", "scroll", @@ -2814,9 +2888,9 @@ dependencies = [ [[package]] name = "minidump-writer" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e1fc14d6ded915b8e850801465e7096f77ed60bf87e4e85878d463720d9dc4d" +checksum = "48ef5778fc71c10d6bac1ec6b971ba0cc4b67cd8f3f0f7689dfdaab75884082f" dependencies = [ "bitflags", "byteorder", @@ -2829,14 +2903,12 @@ dependencies = [ "log", "mach2", "memmap2", - "memoffset", "minidump-common", - "nix 0.29.0", - "procfs-core", + "nix 0.30.1", + "procfs-core 0.18.0", "scroll", "serde", "serde_json", - "tempfile", "thiserror 2.0.18", ] @@ -2858,9 +2930,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" dependencies = [ "libc", "wasi", @@ -2918,6 +2990,12 @@ dependencies = [ "tempfile", ] +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + [[package]] name = "new_debug_unreachable" version = "1.0.6" @@ -2935,9 +3013,9 @@ dependencies = [ [[package]] name = "nix" -version = "0.29.0" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" +checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" dependencies = [ "bitflags", "cfg-if", @@ -2947,9 +3025,9 @@ dependencies = [ [[package]] name = "nix" -version = "0.30.1" +version = "0.31.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" +checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" dependencies = [ "bitflags", "cfg-if", @@ -3051,9 +3129,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" [[package]] name = "num-derive" @@ -3317,6 +3395,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "object" +version = "0.39.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e5a6c098c7a3b6547378093f5cc30bc54fd361ce711e05293a5cc589562739b" +dependencies = [ + "memchr", +] + [[package]] name = "objectstore-client" version = "0.1.12" @@ -3324,6 +3411,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2713028097b2f0f00696d7d389a877f7370c02813548124c4422941f669732f3" dependencies = [ "async-compression", + "base64", "bytes", "futures-util", "infer", @@ -3379,9 +3467,9 @@ checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" [[package]] name = "openssl" -version = "0.10.79" +version = "0.10.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf0b434746ee2832f4f0baf10137e1cabb18cbe6912c69e2e33263c45250f542" +checksum = "77823a27f0babb03091cb9ed9ef80af3b39dbc82f97e8fa530374b7dafd87a45" dependencies = [ "bitflags", "cfg-if", @@ -3410,18 +3498,18 @@ checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" [[package]] name = "openssl-src" -version = "300.6.0+3.6.2" +version = "300.6.1+3.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8e8cbfd3a4a8c8f089147fd7aaa33cf8c7450c4d09f8f80698a0cf093abeff4" +checksum = "46eb8fb9fb3b61ce1c0f8a026c4c1a0714d3a9e138e7fbde78753ce2babc3846" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.115" +version = "0.9.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "158fe5b292746440aa6e7a7e690e55aeb72d41505e2804c23c6973ad0e9c9781" +checksum = "b47e7e6bb2c38cd930d25a23b40fa52e068c10e85f3e03a7f5ba5aaca5713695" dependencies = [ "cc", "libc", @@ -3453,7 +3541,7 @@ dependencies = [ "const-hex", "opentelemetry", "opentelemetry_sdk", - "prost 0.14.3", + "prost 0.14.4", "serde", "serde_json", "tonic", @@ -3492,13 +3580,13 @@ dependencies = [ [[package]] name = "os_info" -version = "3.14.0" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4022a17595a00d6a369236fdae483f0de7f0a339960a53118b818238e132224" +checksum = "9cf20a545b305cf1da722b236b5155c9bb35f1d5ceb28c048bd96ca842f41b5b" dependencies = [ "android_system_properties", "log", - "nix 0.30.1", + "nix 0.31.3", "objc2", "objc2-foundation", "objc2-ui-kit", @@ -3716,18 +3804,18 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.12" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf0d9e68100b3a7989b4901972f265cd542e560a3a8a724e1e20322f4d06ce9" +checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.12" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a990e22f43e84855daf260dded30524ef4a9021cc7541c26540500a50b624389" +checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" dependencies = [ "proc-macro2", "quote", @@ -3837,6 +3925,17 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" +[[package]] +name = "prefix-trie" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cf6e3177f0684016a5c209b00882e15f8bdd3f3bb48f0491df10cd102d0c6e7" +dependencies = [ + "either", + "ipnet", + "num-traits", +] + [[package]] name = "pretty-hex" version = "0.4.2" @@ -3909,6 +4008,16 @@ name = "procfs-core" version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "239df02d8349b06fc07398a3a1697b06418223b1c7725085e801e7c0fc6a12ec" +dependencies = [ + "bitflags", + "hex", +] + +[[package]] +name = "procfs-core" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6401bf7b6af22f78b563665d15a22e9aef27775b79b149a66ca022468a4e405" dependencies = [ "bitflags", "hex", @@ -3942,12 +4051,12 @@ dependencies = [ [[package]] name = "prost" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2ea70524a2f82d518bce41317d0fae74151505651af45faf1ffbd6fd33f0568" +checksum = "528ac67416ff8646872a3c02cad9cc4ee5dc9f9540c9b10771855c95cb2e5ae1" dependencies = [ "bytes", - "prost-derive 0.14.3", + "prost-derive 0.14.4", ] [[package]] @@ -3965,9 +4074,9 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b" +checksum = "b570b25f7617e43d59005d0990ccb79e950a423952cea19671b7a876da390adf" dependencies = [ "anyhow", "itertools 0.14.0", @@ -3978,18 +4087,18 @@ dependencies = [ [[package]] name = "prost-types" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8991c4cbdb8bc5b11f0b074ffe286c30e523de90fee5ba8132f1399f23cb3dd7" +checksum = "f94967dc7688f3054c7fac87473ffae4cc4c3904800e2d9f5b857246d8963b0a" dependencies = [ - "prost 0.14.3", + "prost 0.14.4", ] [[package]] name = "psl" -version = "2.1.206" +version = "2.1.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0fd5dad387c0ff76cf1ac9f0f90ee4f1d966c969edfe7325e73141bf4352e0a" +checksum = "9826c2fe4dade07e9da1af2e18427257877bc8bc27aa810f6fbb52d907a480cc" dependencies = [ "psl-types", ] @@ -4027,9 +4136,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.45" +version = "1.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" dependencies = [ "proc-macro2", ] @@ -4040,6 +4149,12 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + [[package]] name = "r2d2" version = "0.8.10" @@ -4082,6 +4197,17 @@ dependencies = [ "rand_core 0.9.5", ] +[[package]] +name = "rand" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" +dependencies = [ + "chacha20", + "getrandom 0.4.3", + "rand_core 0.10.1", +] + [[package]] name = "rand_chacha" version = "0.3.1" @@ -4120,6 +4246,12 @@ dependencies = [ "getrandom 0.3.4", ] +[[package]] +name = "rand_core" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" + [[package]] name = "rand_pcg" version = "0.9.0" @@ -4158,9 +4290,9 @@ dependencies = [ [[package]] name = "rapidhash" -version = "4.4.1" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e48930979c155e2f33aa36ab3119b5ee81332beb6482199a8ecd6029b80b59" +checksum = "32b266a82f4aa99bb5c25e28d11cc44ace63d91adbcbcee4d323e2ae3d49ef37" dependencies = [ "rustversion", ] @@ -4249,9 +4381,9 @@ dependencies = [ [[package]] name = "redis" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72d32a1ac9123f0d84fda64bfc02a271d9868483162dd2d9099b5c362ece064c" +checksum = "2fa6f8e4b491d7a8ef3a9550a4d71969bd0064f46e32b8dbbcc7fc60dad94fed" dependencies = [ "arc-swap", "arcstr", @@ -4269,7 +4401,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "r2d2", - "rand 0.9.4", + "rand 0.10.2", "ryu", "sha1_smol", "socket2", @@ -4291,18 +4423,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.7.5" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4666a1a60d8412eab19d94f6d13dcc9cea0a5ef4fdf6a5db306537413c661b1b" +checksum = "c5102a6aaa05aa011a238e178e6bca86d2cb56fc9f586d37cb80f5bca6e07759" dependencies = [ "bitflags", ] [[package]] name = "regex" -version = "1.12.3" +version = "1.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba" dependencies = [ "aho-corasick", "memchr", @@ -4329,9 +4461,9 @@ checksum = "cab834c73d247e67f4fae452806d17d3c7501756d98c8808d7c9c7aa7d18f973" [[package]] name = "regex-syntax" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] name = "relay" @@ -4773,7 +4905,7 @@ dependencies = [ "hashbrown 0.15.5", "insta", "itertools 0.14.0", - "prost 0.14.3", + "prost 0.14.4", "relay-base-schema", "relay-dynamic-config", "relay-event-schema", @@ -4797,7 +4929,7 @@ dependencies = [ "dircpy", "lz4_flex", "minidump-writer", - "object", + "object 0.39.1", "rmpv", "tempfile", "tracing", @@ -4945,7 +5077,7 @@ dependencies = [ "papaya", "pin-project-lite", "priority-queue", - "prost 0.14.3", + "prost 0.14.4", "prost-types", "rand 0.9.4", "regex", @@ -5074,9 +5206,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62e0021ea2c22aed41653bc7e1419abb2c97e038ff2c33d0e1309e49a97deec0" +checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3" dependencies = [ "base64", "bytes", @@ -5178,9 +5310,9 @@ dependencies = [ [[package]] name = "ron" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4147b952f3f819eca0e99527022f7d6a8d05f111aeb0a62960c74eb283bec8fc" +checksum = "81116b9531d61eabc41aeb228e4b6b2435bcca3233b98cf3b3077d4e6e9debb3" dependencies = [ "bitflags", "once_cell", @@ -5246,9 +5378,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.40" +version = "0.23.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" +checksum = "6b92b125634d9b795e7beca796cc790df15a7fb38323bf3196fda83292d06b1f" dependencies = [ "once_cell", "rustls-pki-types", @@ -5259,9 +5391,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.14.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" +checksum = "764899a24af3980067ee14bc143654f297b22eaebfe3c7b6b211920a5a59b046" dependencies = [ "zeroize", ] @@ -5477,13 +5609,13 @@ dependencies = [ [[package]] name = "sentry-kafka-schemas" -version = "2.1.36" +version = "2.1.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad1514576cbe4c0b7b67f66011fedc2a04af192c01f25f411ab853bb1b3d08f8" +checksum = "fc1002ddc5a5bfa04bd283dc597a8786c8e0a01c9b487107f8b7e64a9d360666" dependencies = [ "jsonschema", - "prost 0.14.3", - "sentry_protos 0.8.25", + "prost 0.14.4", + "sentry_protos 0.37.3", "serde", "serde_json", "serde_yaml", @@ -5591,7 +5723,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ce7306945b58bf13c874a5b0a52c8e08c5150eba2e893131d9f2c6cd992e50f" dependencies = [ - "prost 0.14.3", + "prost 0.14.4", "prost-types", "tonic", "tonic-prost", @@ -5599,11 +5731,11 @@ dependencies = [ [[package]] name = "sentry_protos" -version = "0.8.25" +version = "0.37.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "343036b521fd129643d1cb9681720941b7c555ab294d005c4f3b1e8f3cc776f3" +checksum = "8110e2eccc106d97eb9c7367606a5dcf32542ffa34f7c568e5bd0fd15a000d8f" dependencies = [ - "prost 0.14.3", + "prost 0.14.4", "prost-types", "tonic", "tonic-prost", @@ -5669,9 +5801,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" dependencies = [ "itoa", "memchr", @@ -5732,7 +5864,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest", ] @@ -5749,7 +5881,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest", ] @@ -5774,6 +5906,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + [[package]] name = "signal-hook-registry" version = "1.4.8" @@ -5800,6 +5938,22 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" +[[package]] +name = "simd_cesu8" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33" +dependencies = [ + "rustc_version", + "simdutf8", +] + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + [[package]] name = "similar" version = "2.7.0" @@ -5852,9 +6006,9 @@ checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" -version = "1.15.1" +version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" dependencies = [ "serde", ] @@ -5872,9 +6026,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" dependencies = [ "libc", "windows-sys 0.61.2", @@ -6193,9 +6347,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.117" +version = "2.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" dependencies = [ "proc-macro2", "quote", @@ -6270,7 +6424,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.3.4", + "getrandom 0.4.3", "once_cell", "rustix", "windows-sys 0.61.2", @@ -6337,12 +6491,11 @@ dependencies = [ [[package]] name = "time" -version = "0.3.47" +version = "0.3.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" +checksum = "18dfaaeddcb932337b5e7866ee7d0ce9b76d2fd092997146f187ec09b4558a50" dependencies = [ "deranged", - "itoa", "num-conv", "powerfmt", "serde_core", @@ -6352,15 +6505,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" [[package]] name = "time-macros" -version = "0.2.27" +version = "0.2.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" +checksum = "c431b87111666e491a90baa837f914fb45cd5dc3c268591b0220ff5057f2085f" dependencies = [ "num-conv", "time-core", @@ -6484,9 +6637,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.25.11+spec-1.1.0" +version = "0.25.12+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b" +checksum = "d2153edc6955a6c354fad8f5efd38b6a8769bdccf9fe50f8e1329f81b0baa5d7" dependencies = [ "indexmap", "toml_datetime", @@ -6505,9 +6658,9 @@ dependencies = [ [[package]] name = "tonic" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fec7c61a0695dc1887c1b53952990f3ad2e3a31453e1f49f10e75424943a93ec" +checksum = "ac2a5518c70fa84342385732db33fb3f44bc4cc748936eb5833d2df34d6445ef" dependencies = [ "async-trait", "axum", @@ -6534,12 +6687,12 @@ dependencies = [ [[package]] name = "tonic-prost" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a55376a0bbaa4975a3f10d009ad763d8f4108f067c7c2e74f3001fb49778d309" +checksum = "50849f68853be452acf590cde0b146665b8d507b3b8af17261df47e02c209ea0" dependencies = [ "bytes", - "prost 0.14.3", + "prost 0.14.4", "tonic", ] @@ -6564,9 +6717,9 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.8" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" dependencies = [ "async-compression", "bitflags", @@ -6576,7 +6729,6 @@ dependencies = [ "http", "http-body", "http-body-util", - "iri-string", "pin-project-lite", "tokio", "tokio-util", @@ -6584,6 +6736,7 @@ dependencies = [ "tower-layer", "tower-service", "tracing", + "url", ] [[package]] @@ -6694,9 +6847,9 @@ checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" [[package]] name = "typenum" -version = "1.20.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" [[package]] name = "uaparser" @@ -6777,9 +6930,9 @@ checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d" [[package]] name = "unicode-segmentation" -version = "1.13.2" +version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" +checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" [[package]] name = "unicode-width" @@ -6870,11 +7023,11 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.20.0" +version = "1.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee48d38b119b0cd71fe4141b30f5ba9c7c5d9f4e7a3a8b4a674e4b6ef789976f" +checksum = "bf80a72845275afea99e7f2b434723d3bc7e38470fcd1c7ed39a599c73319a53" dependencies = [ - "getrandom 0.3.4", + "getrandom 0.4.3", "js-sys", "serde_core", "sha1_smol", @@ -6926,9 +7079,9 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.3+wasi-0.2.9" +version = "1.0.4+wasi-0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" dependencies = [ "wit-bindgen", ] @@ -6941,9 +7094,9 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.120" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df52b6d9b87e0c74c9edfa1eb2d9bf85e5d63515474513aa50fa181b3c4f5db1" +checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" dependencies = [ "cfg-if", "once_cell", @@ -6954,9 +7107,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.70" +version = "0.4.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af934872acec734c2d80e6617bbb5ff4f12b052dd8e6332b0817bce889516084" +checksum = "c62df1340f32221cb9c54d6a27b030e3dba64361d4a95bed55f9aacb44da291d" dependencies = [ "js-sys", "wasm-bindgen", @@ -6964,9 +7117,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.120" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b1041f495fb322e64aca85f5756b2172e35cd459376e67f2a6c9dffcedb103" +checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -6974,9 +7127,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.120" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dcd0ff20416988a18ac686d4d4d0f6aae9ebf08a389ff5d29012b05af2a1b41" +checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" dependencies = [ "bumpalo", "proc-macro2", @@ -6987,9 +7140,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.120" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49757b3c82ebf16c57d69365a142940b384176c24df52a087fb748e2085359ea" +checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" dependencies = [ "unicode-ident", ] @@ -7015,9 +7168,9 @@ checksum = "bfbc1480663d640f8c9f7a1ac70922eea60ac16fea79df883177df3bc7bb8b49" [[package]] name = "web-sys" -version = "0.3.97" +version = "0.3.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eadbac71025cd7b0834f20d1fe8472e8495821b4e9801eb0a60bd1f19827602" +checksum = "8622dcb61c0bcc9fffa6938bed81210af2da9a7e4a1a834b2e37a59b6dfb6141" dependencies = [ "js-sys", "wasm-bindgen", @@ -7025,9 +7178,9 @@ dependencies = [ [[package]] name = "webpki-root-certs" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31141ce3fc3e300ae89b78c0dd67f9708061d1d2eda54b8209346fd6be9a92c" +checksum = "0d46a5a140e6f7afeccd8eae97eff335163939eac8b929834875168b29b3d267" dependencies = [ "rustls-pki-types", ] @@ -7397,9 +7550,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ee1708bef14716a11bae175f579062d4554d95be2c6829f518df847b7b3fdd0" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" dependencies = [ "memchr", ] @@ -7418,15 +7571,15 @@ checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" [[package]] name = "xxhash-rust" -version = "0.8.15" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdd20c5420375476fbd4394763288da7eb0cc0b8c11deed431a91562af7335d3" +checksum = "4d93c89cdc2d3a63c3ec48ffe926931bdc069eafa8e4402fe6d8f790c9d1e576" [[package]] name = "yoke" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" dependencies = [ "stable_deref_trait", "yoke-derive", @@ -7447,18 +7600,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.48" +version = "0.8.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" +checksum = "ce1022995ff5ff5d841ad7d994facc23098cd40152f2c1d11cd607c6f530653f" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.48" +version = "0.8.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930" dependencies = [ "proc-macro2", "quote", @@ -7467,9 +7620,9 @@ dependencies = [ [[package]] name = "zerofrom" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" dependencies = [ "zerofrom-derive", ] @@ -7488,9 +7641,23 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.8.2" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] name = "zerotrie" diff --git a/Cargo.toml b/Cargo.toml index 2237d748b54..8506a3e4818 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -90,7 +90,15 @@ android_trace_log = { version = "0.3", features = ["serde"] } # Keep it pinned until it's possible to disable backtrace. anyhow = "=1.0.69" arc-swap = "1" -async-compression = { version = "0.4", features = ["tokio", "gzip", "brotli", "deflate", "zstd", "bzip2", "xz"] } +async-compression = { version = "0.4", features = [ + "brotli", + "bzip2", + "deflate", + "gzip", + "tokio", + "xz", + "zstd", +] } async-trait = "0.1" axum = "0.8" axum-extra = "0.12" @@ -153,7 +161,7 @@ metrics = "0.24" metrics-exporter-dogstatsd = "0.9" num-traits = "0.2" num_cpus = "1" -objectstore-client = "0.1" +objectstore-client = { version = "0.1", features = ["multipart"] } opentelemetry-semantic-conventions = "0.31" opentelemetry-proto = { version = "0.31", default-features = false } papaya = "0.2" diff --git a/relay-server/src/endpoints/upload.rs b/relay-server/src/endpoints/upload.rs index 021a7bf51c9..07f3705b2db 100644 --- a/relay-server/src/endpoints/upload.rs +++ b/relay-server/src/endpoints/upload.rs @@ -31,8 +31,8 @@ use crate::services::objectstore; use crate::services::projects::cache::Project; use crate::services::projects::project::ProjectState; use crate::services::upload::{ - self, ByteStream, Final, LocationQueryParams, ProjectContext, Provisional, SignedLocation, - UploadLength, + self, ByteStream, Final, LocationData, LocationQueryParams, ProjectContext, Provisional, + SignedLocation, }; use crate::services::upstream::UpstreamRequestError; use crate::statsd::RelayCounters; @@ -133,7 +133,7 @@ impl IntoResponse for Error { } } -impl IntoResponse for SignedLocation { +impl IntoResponse for SignedLocation { fn into_response(self) -> Response { let mut headers = tus::response_headers(); match self.into_header_value() { @@ -204,6 +204,7 @@ async fn handle_patch( Path(upload::LocationPath { project_id, key }): Path, Query(LocationQueryParams { upload_length, + upload_id, upload_signature, other, }): Query>, @@ -214,8 +215,14 @@ async fn handle_patch( relay_log::trace!("Validating headers"); tus::validate_patch_headers(&headers).map_err(Error::from)?; - let location = - SignedLocation::from_parts(project_id, key, upload_length, upload_signature, other); + let location = SignedLocation::from_parts( + project_id, + key, + upload_length, + upload_id, + upload_signature, + other, + ); let config = state.config(); @@ -240,7 +247,7 @@ async fn handle_patch( .boxed(); let stream = MeteredStream::new(stream, "upload"); - let (lower_bound, upper_bound) = match upload_length.value() { + let (lower_bound, upper_bound) = match upload_length { None => (1, config.max_upload_size()), Some(u) => (u, u), }; diff --git a/relay-server/src/processing/utils/attachments.rs b/relay-server/src/processing/utils/attachments.rs index 89d3a5be63a..ff7a0ba0a2f 100644 --- a/relay-server/src/processing/utils/attachments.rs +++ b/relay-server/src/processing/utils/attachments.rs @@ -55,7 +55,7 @@ fn validate(item: &Item, config: &Config) -> Result<(), ProcessingError> { let location = signed_location .verify(chrono::Utc::now(), config) .map_err(|_| ProcessingError::InvalidAttachmentRef)?; - let signed_length = location.length.into_inner(); + let signed_length = location.location_data.length(); match item.attachment_body_size() == signed_length { true => Ok(()), diff --git a/relay-server/src/services/objectstore.rs b/relay-server/src/services/objectstore.rs index 454cf5e2fab..98699b0a4f6 100644 --- a/relay-server/src/services/objectstore.rs +++ b/relay-server/src/services/objectstore.rs @@ -5,11 +5,13 @@ use std::num::NonZeroU16; use std::sync::Arc; use std::time::Duration; +use async_compression::tokio::bufread::ZstdEncoder; use bytes::Bytes; use futures::StreamExt; use http::StatusCode; use objectstore_client::{ - Client, ExpirationPolicy, SecretKey as SigningKey, Session, TokenGenerator, Usecase, + Client, Compression, ExpirationPolicy, SecretKey as SigningKey, Session, TokenGenerator, + Usecase, }; use relay_base_schema::organization::OrganizationId; use relay_base_schema::project::ProjectId; @@ -19,6 +21,7 @@ use relay_system::{ Addr, AsyncResponse, FromMessage, Interface, LoadShed, NoResponse, Sender, SimpleService, }; use sentry_protos::snuba::v1::TraceItem; +use tokio_util::io::{ReaderStream, StreamReader}; use crate::constants::DEFAULT_ATTACHMENT_RETENTION; use crate::envelope::{ContentType, Item, ItemType}; @@ -43,6 +46,7 @@ pub enum Objectstore { TraceAttachment(Managed), EventAttachment(Managed), RawProfile(Managed), + Create(Create, Sender>), Stream(Stream, Sender>), } @@ -54,6 +58,7 @@ impl Objectstore { Self::EventAttachment(_) => MessageKind::EventAttachment, Self::RawProfile(_) => MessageKind::RawProfile, Self::Stream { .. } => MessageKind::Stream, + Self::Create { .. } => MessageKind::Create, } } @@ -68,6 +73,7 @@ impl Objectstore { Self::EventAttachment(_) => 1, Self::RawProfile(_) => 1, Self::Stream { .. } => 1, + Self::Create { .. } => 0, } } } @@ -114,6 +120,7 @@ enum MessageKind { TraceAttachment, RawProfile, Stream, + Create, } impl MessageKind { @@ -124,15 +131,31 @@ impl MessageKind { Self::TraceAttachment => "attachment_v2", Self::RawProfile => "profile_raw", Self::Stream => "stream", + Self::Create => "create", } } } +/// A request to create a new objectstore multipart upload. +pub struct Create { + pub organization_id: OrganizationId, + pub project_id: ProjectId, + pub key: String, +} + +impl FromMessage for Objectstore { + type Response = AsyncResponse>; + + fn from_message(message: Create, sender: Sender>) -> Self { + Self::Create(message, sender) + } +} + /// A stream that can be uploaded to objectstore. pub struct Stream { pub organization_id: OrganizationId, pub project_id: ProjectId, - pub key: String, + pub upload_ref: UploadRef, pub stream: BoundedStream>, } @@ -300,6 +323,15 @@ impl ObjectstoreKey { } } +/// Identifier needed to resume an existing upload. +#[derive(Debug, Clone)] +pub struct UploadRef { + /// They key of the file (chosen by relay). + pub key: String, + /// The ID of the multipart upload session (chosen by objectstore). + pub upload_id: String, +} + impl fmt::Display for ObjectstoreKey { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0.fmt(f) @@ -423,6 +455,9 @@ impl LoadShed for ObjectstoreService { Objectstore::Stream(_, sender) => { sender.send(Err(error)); } + Objectstore::Create(_, sender) => { + sender.send(Err(error)); + } } } } @@ -462,6 +497,13 @@ impl ObjectstoreServiceInner { Objectstore::RawProfile(profile) => { self.handle_raw_profile(profile).await; } + Objectstore::Create(create, sender) => { + let result = self.handle_create(create).await; + if let Err(error) = &result { + error.log(MessageKind::Create); + } + sender.send(result); + } Objectstore::Stream(stream, sender) => { let result = self.handle_stream(stream).await; if let Err(error) = &result { @@ -708,11 +750,31 @@ impl ObjectstoreServiceInner { Ok(Some(stored_key)) } + async fn handle_create(&self, create: Create) -> Result { + let Create { + organization_id, + project_id, + key, + } = create; + let session = self.session(&self.event_attachments, organization_id, project_id)?; + + let multipart_upload = session + .initiate_multipart_upload() + .key(&key) + .compression(Compression::Zstd) // make explicit because parts need to be manually compressed. + .send() + .await?; + debug_assert_eq!(&key, multipart_upload.key()); + let upload_id = multipart_upload.upload_id().to_string(); + + Ok(UploadRef { key, upload_id }) + } + async fn handle_stream(&self, stream: Stream) -> Result { let Stream { organization_id, project_id, - key, + upload_ref, stream, } = stream; let session = self.session(&self.event_attachments, organization_id, project_id)?; @@ -720,8 +782,10 @@ impl ObjectstoreServiceInner { self.upload( MessageKind::Stream, &session, - Some(key), - Body::Stream(TakeOnce::new(stream)), + BodyTarget::Stream { + body: TakeOnce::new(stream), + upload_ref, + }, None, None, ) @@ -741,8 +805,7 @@ impl ObjectstoreServiceInner { self.upload( kind, session, - key, - Body::Bytes(payload), + BodyTarget::Bytes { body: payload, key }, retention_hours, content_type, ) @@ -753,15 +816,14 @@ impl ObjectstoreServiceInner { &self, kind: MessageKind, session: &Session, - key: Option, - body: Body, + body: BodyTarget, retention_hours: Option, content_type: Option, ) -> Result { let mut attempts = 0; let timeout = match &body { - Body::Bytes(_) => self.timeout, - Body::Stream(_) => self.stream_timeout, + BodyTarget::Bytes { .. } => self.timeout, + BodyTarget::Stream { .. } => self.stream_timeout, }; let result = tokio::time::timeout(timeout, async { let mut result = None; @@ -771,15 +833,8 @@ impl ObjectstoreServiceInner { }; attempts += 1; result.replace( - self.attempt_upload( - kind, - session, - key.clone(), - body, - retention_hours, - content_type, - ) - .await, + self.attempt_upload(kind, session, body, retention_hours, content_type) + .await, ); if attempts < self.max_attempts.get() @@ -815,37 +870,61 @@ impl ObjectstoreServiceInner { &self, kind: MessageKind, session: &Session, - key: Option, body: BodyAttempt, retention_hours: Option, content_type: Option, ) -> Result { - let mut request = match body { - BodyAttempt::Bytes(bytes) => session.put(bytes), - BodyAttempt::Stream(stream) => session.put_stream(stream.boxed()), - }; - - if let Some(content_type) = content_type { - request = request.content_type(content_type.as_str()); - } - if let Some(retention_hours) = retention_hours { - request = request.expiration_policy(ExpirationPolicy::TimeToLive( - Duration::from_hours(retention_hours.into()), - )); - } - if let Some(key) = key { - request = request.key(key); - } + match body { + BodyAttempt::Bytes { body, key } => { + let mut request = session.put(body); + if let Some(content_type) = content_type { + request = request.content_type(content_type.as_str()); + } + if let Some(retention_hours) = retention_hours { + request = request.expiration_policy(ExpirationPolicy::TimeToLive( + Duration::from_hours(retention_hours.into()), + )); + } + if let Some(key) = key { + request = request.key(key); + } + let response = relay_statsd::metric!( + timer(RelayTimers::AttachmentUploadDuration), + type = kind.as_str(), + { + request.send().await? + }); - let response = relay_statsd::metric!( - timer(RelayTimers::AttachmentUploadDuration), - type = kind.as_str(), - { - request.send().await + Ok(ObjectstoreKey(response.key)) } - )?; + BodyAttempt::Stream { body, upload_ref } => { + let UploadRef { key, upload_id } = upload_ref; + let multipart_upload = session.resume_multipart_upload(key, upload_id)?; + + let body = ReaderStream::new(ZstdEncoder::new(StreamReader::new(body))); + let mut body = body.enumerate(); + + let result = relay_statsd::metric!( + timer(RelayTimers::AttachmentUploadDuration), + type = kind.as_str(), + { + let mut parts = vec![]; + // FIXME: wait for objectstore to allow omitting the content length. + // Submitting every element of the stream as a separate HTTP request is not + // efficient. + while let Some((i, chunk)) = body.next().await { + let chunk = chunk?; + let part_number = u32::try_from(i + 1) + .map_err(|_| objectstore_client::Error::InvalidPartNumber(u32::MAX))?; + let part = multipart_upload.put(chunk, part_number, None).await?; + parts.push(part); + } + multipart_upload.complete(parts).await? + }); - Ok(ObjectstoreKey(response.key)) + Ok(ObjectstoreKey(result)) + } + } } fn session( @@ -867,16 +946,30 @@ impl ObjectstoreServiceInner { /// Common interface for calls to [`ObjectstoreServiceInner::upload`]. /// /// This type is shared across retries. -enum Body { - Bytes(Bytes), - Stream(TakeOnce>>), +enum BodyTarget { + Bytes { + body: Bytes, + key: Option, + }, + Stream { + body: TakeOnce>>, + upload_ref: UploadRef, + }, } -impl Body { +impl BodyTarget { fn try_clone(&self) -> Option { match self { - Self::Bytes(bytes) => Some(BodyAttempt::Bytes(bytes.clone())), - Self::Stream(stream) => RetryableStream::new(stream.clone()).map(BodyAttempt::Stream), + Self::Bytes { body: bytes, key } => Some(BodyAttempt::Bytes { + body: bytes.clone(), + key: key.clone(), + }), + Self::Stream { body, upload_ref } => { + RetryableStream::new(body.clone()).map(|body| BodyAttempt::Stream { + body, + upload_ref: upload_ref.clone(), + }) + } } } } @@ -885,8 +978,14 @@ impl Body { /// /// This type is instantiated for every retry. enum BodyAttempt { - Bytes(Bytes), - Stream(RetryableStream>>), + Bytes { + body: Bytes, + key: Option, + }, + Stream { + body: RetryableStream>>, + upload_ref: UploadRef, + }, } fn is_retryable(error: &objectstore_client::Error) -> bool { @@ -965,7 +1064,10 @@ mod tests { .send(Stream { organization_id: OrganizationId::new(0), project_id: ProjectId::new(1), - key: "my_file".into(), + upload_ref: UploadRef { + key: "my_file".into(), + upload_id: "my_upload".into(), + }, stream, }) .await diff --git a/relay-server/src/services/upload.rs b/relay-server/src/services/upload.rs index 79f320b245c..595f28a13ad 100644 --- a/relay-server/src/services/upload.rs +++ b/relay-server/src/services/upload.rs @@ -227,12 +227,12 @@ pub struct Service { } /// A response channel that emits a metric for each response. -pub struct InstrumentedSender { +pub struct InstrumentedSender { metric: RelayCounters, inner: Sender, Error>>, } -impl InstrumentedSender { +impl InstrumentedSender { fn send(self, result: Result, Error>) { let result_msg = match &result { Ok(_) => "success", @@ -272,13 +272,32 @@ impl Service { SignedLocation::try_from_response(response) } #[cfg(feature = "processing")] - Backend::Objectstore { addr: _, config } => { - // We can create & sign a location right here, no need to query the objectstore service. + Backend::Objectstore { addr, config } => { + use crate::services::objectstore::UploadRef; + let key = Uuid::now_v7().as_simple().to_string(); + let Scoping { + organization_id, + project_id, + .. + } = project.scoping; + + let UploadRef { key, upload_id } = addr + .send(objectstore::Create { + organization_id, + project_id, + key, + }) + .await + .map_err(Error::ObjectstoreServiceUnavailable)??; + Location { project_id: project.scoping.project_id, key, - length: Provisional(length), + location_data: Provisional { + upload_length: length, + upload_id, + }, other: Default::default(), } .try_sign(config) @@ -303,34 +322,44 @@ impl Service { } #[cfg(feature = "processing")] Backend::Objectstore { addr, config } => { + use crate::services::objectstore::UploadRef; + let Location { project_id, key, - length, + location_data, other, } = location.verify(received, config)?; let scoping = project.scoping; debug_assert_eq!(scoping.project_id, project_id); - debug_assert!(stream.length().is_none_or(|l| Some(l) == length.value())); + debug_assert!( + stream + .length() + .is_none_or(|l| Some(l) == location_data.upload_length()) + ); let byte_counter = stream.byte_counter(); let key = addr .send(objectstore::Stream { organization_id: scoping.organization_id, project_id, - key, + upload_ref: UploadRef { + key, + upload_id: location_data.upload_id, + }, stream, }) .await .map_err(Error::ObjectstoreServiceUnavailable)?? .into_inner(); - let length = Final(byte_counter.get()); Location { project_id, key, - length, + location_data: Final { + upload_length: byte_counter.get(), + }, other, } .try_sign(config) @@ -340,7 +369,7 @@ impl Service { async fn timeout(&self, future: F) -> Result, Error> where - L: UploadLength, + L: LocationData, F: IntoFuture, Error>>, { tokio::time::timeout(self.timeout, future).await? @@ -371,23 +400,45 @@ impl LoadShed for Service { } } -/// An interface for known or unknown upload lengths. +/// An interface to retrieve query parameters from different location types. /// /// This allows code sharing between [`Provisional`] and [`Final`] upload locations. -pub trait UploadLength: for<'de> Deserialize<'de> { - fn value(&self) -> Option; +pub trait LocationData: for<'de> Deserialize<'de> { + type LengthType: for<'de> Deserialize<'de>; + type IdType: for<'de> Deserialize<'de>; + + fn from_parts(upload_length: Self::LengthType, upload_id: Self::IdType) -> Self; + + fn upload_length(&self) -> Option; + fn upload_id(&self) -> Option<&str>; } /// A provisional upload length which may or may not yet be known. /// /// See also [`Final`]. -#[derive(Debug, Clone, Copy, Deserialize)] -#[serde(transparent)] -pub struct Provisional(Option); +#[derive(Debug, Clone, Deserialize)] +pub struct Provisional { + pub upload_length: Option, + pub upload_id: String, +} -impl UploadLength for Provisional { - fn value(&self) -> Option { - self.0 +impl LocationData for Provisional { + type LengthType = Option; + type IdType = String; + + fn from_parts(upload_length: Self::LengthType, upload_id: Self::IdType) -> Self { + Self { + upload_length, + upload_id, + } + } + + fn upload_length(&self) -> Option { + self.upload_length + } + + fn upload_id(&self) -> Option<&str> { + Some(&self.upload_id) } } @@ -395,18 +446,31 @@ impl UploadLength for Provisional { /// /// See also [`Provisional`]. #[derive(Debug, Clone, Copy, Deserialize)] -pub struct Final(usize); +pub struct Final { + upload_length: usize, +} impl Final { /// Get the value. - pub fn into_inner(self) -> usize { - self.0 + pub fn length(&self) -> usize { + self.upload_length } } -impl UploadLength for Final { - fn value(&self) -> Option { - Some(self.0) +impl LocationData for Final { + type LengthType = usize; + type IdType = Option<()>; // the option is here to be able to parse an URL without &upload_id. + + fn from_parts(upload_length: usize, _upload_id: Option<()>) -> Self { + Self { upload_length } + } + + fn upload_length(&self) -> Option { + Some(self.upload_length) + } + + fn upload_id(&self) -> Option<&str> { + None } } @@ -423,27 +487,30 @@ pub struct Location { pub project_id: ProjectId, /// Objectstore identifier. pub key: String, - /// Value of the `Upload-Length` header. `None` if `Upload-Defer-Length: 1`. - pub length: L, + /// Upload length and upload ID. + pub location_data: L, + /// Additional fields, retained for forward compatibility. pub other: UploadParams, } -impl Location { +impl Location { fn try_to_uri(&self) -> Result { let Location { project_id, key, - length, + location_data, other, } = self; #[derive(Debug, Serialize)] struct QueryParams<'a> { pub upload_length: Option, + pub upload_id: Option<&'a str>, #[serde(flatten)] pub other: &'a UploadParams, } let params = QueryParams { - upload_length: length.value(), + upload_length: location_data.upload_length(), + upload_id: location_data.upload_id(), other, }; let query = serde_urlencoded::to_string(params)?; @@ -481,11 +548,10 @@ pub struct LocationPath { /// Query parameters for the upload endpoint. #[derive(Debug, Deserialize)] -#[serde(bound = "L: UploadLength")] -pub struct LocationQueryParams { - #[serde(alias = "length")] - pub upload_length: L, - #[serde(alias = "signature")] +#[serde(bound = "L: LocationData")] +pub struct LocationQueryParams { + pub upload_length: L::LengthType, + pub upload_id: L::IdType, pub upload_signature: String, #[serde(flatten)] pub other: UploadParams, @@ -532,19 +598,20 @@ impl<'de> Deserialize<'de> for UploadParams { /// A verifiable [`Location`] signed by this Relay or an upstream Relay. #[derive(Debug)] -pub struct SignedLocation { +pub struct SignedLocation { location: Location, signature: Signature, } -impl SignedLocation { +impl SignedLocation { /// Creates an unverified location from path and query params. /// /// Call `verify` to make sure the signature is correct. pub fn from_parts( project_id: ProjectId, key: String, - length: L, + upload_length: L::LengthType, + upload_id: L::IdType, signature: String, other: UploadParams, ) -> Self { @@ -552,7 +619,7 @@ impl SignedLocation { location: Location { project_id, key, - length, + location_data: LocationData::from_parts(upload_length, upload_id), other, }, signature: Signature(signature), @@ -616,7 +683,7 @@ impl SignedLocation { impl SignedLocation where - L: UploadLength, + L: LocationData, LocationQueryParams: for<'de> Deserialize<'de>, { fn try_from_response(response: Response) -> Result { @@ -654,6 +721,7 @@ where // Parse query parameters. let LocationQueryParams { upload_length, + upload_id, upload_signature, other, } = serde_urlencoded::from_str(query).ok()?; @@ -662,6 +730,7 @@ where project_id, key, upload_length, + upload_id, upload_signature, other, )) @@ -868,7 +937,10 @@ mod tests { Location { project_id: ProjectId::new(42), key: "upload-key".to_owned(), - length: Provisional(Some(123)), + location_data: Provisional { + upload_length: Some(123), + upload_id: "my_upload".to_owned(), + }, other: UploadParams::default(), } } @@ -960,39 +1032,52 @@ mod tests { #[test] fn parse_location_incomplete() { - let url = "signature=foo"; + let url = "upload_signature=foo&upload_id=abc"; // Can only parse provisional: let provisional: LocationQueryParams = serde_urlencoded::from_str(url).unwrap(); - assert!(provisional.upload_length.0.is_none()); + assert!(provisional.upload_length.is_none()); assert!(serde_urlencoded::from_str::>(url).is_err()); } #[test] fn parse_location_complete() { - let json = r#"signature=foo&length=123"#; + let json = r#"upload_signature=foo&upload_length=123&upload_id=abc"#; let provisional: LocationQueryParams = serde_urlencoded::from_str(json).unwrap(); - assert_eq!(provisional.upload_length.0, Some(123)); + assert_eq!(provisional.upload_length, Some(123)); + assert_eq!(&provisional.upload_id, "abc"); + + let json = r#"upload_signature=foo&upload_length=123"#; let full: LocationQueryParams = serde_urlencoded::from_str(json).unwrap(); - assert_eq!(full.upload_length.0, 123); + assert_eq!(full.upload_length, 123); } #[test] fn parse_location_with_other() { - let json = - r#"upload_signature=foo&upload_length=123¬_an_upload_param=123&upload_type=bar"#; + let json = r#"upload_signature=foo&upload_id=abc¬_an_upload_param=123&upload_type=bar"#; let provisional: LocationQueryParams = serde_urlencoded::from_str(json).unwrap(); insta::assert_debug_snapshot!(provisional, @r#" LocationQueryParams { - upload_length: Provisional( - Some( - 123, - ), + upload_length: None, + upload_id: "abc", + upload_signature: "foo", + other: UploadParams( + { + "upload_type": "bar", + }, + ), + } + "#); + let full: LocationQueryParams = serde_urlencoded::from_str(json).unwrap(); + insta::assert_debug_snapshot!(full, @r#" + LocationQueryParams { + upload_length: Final( + 123, ), upload_signature: "foo", other: UploadParams( @@ -1002,6 +1087,26 @@ mod tests { ), } "#); + } + + #[test] + fn parse_final_location_with_other() { + let json = + r#"upload_signature=foo&upload_length=123¬_an_upload_param=123&upload_type=bar"#; + + let provisional: LocationQueryParams = serde_urlencoded::from_str(json).unwrap(); + insta::assert_debug_snapshot!(provisional, @r#" + LocationQueryParams { + upload_length: 123, + upload_id: None, + upload_signature: "foo", + other: UploadParams( + { + "upload_type": "bar", + }, + ), + } + "#); let full: LocationQueryParams = serde_urlencoded::from_str(json).unwrap(); insta::assert_debug_snapshot!(full, @r#" LocationQueryParams { diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 2855ccd073b..c04b822e94b 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -47,7 +47,11 @@ objectstore, ) -from .consts import DUMMY_UPLOAD_LOCATION, ZSTD_MAGIC_HEADER +from .consts import ( + DUMMY_UPLOAD_FINAL_LOCATION, + DUMMY_UPLOAD_PROVISIONAL_LOCATION, + ZSTD_MAGIC_HEADER, +) @pytest.fixture(scope="session") @@ -309,7 +313,7 @@ def create(**opts): return Response( "", status=201, - headers={"Location": DUMMY_UPLOAD_LOCATION}, + headers={"Location": DUMMY_UPLOAD_PROVISIONAL_LOCATION}, ) @mini_sentry.app.route("/api//upload//", methods=["PATCH"]) @@ -319,5 +323,5 @@ def upload(**opts): return Response( "", status=204, - headers={"Location": DUMMY_UPLOAD_LOCATION}, + headers={"Location": DUMMY_UPLOAD_FINAL_LOCATION}, ) diff --git a/tests/integration/consts.py b/tests/integration/consts.py index 91d60f244da..8e5a150fb8d 100644 --- a/tests/integration/consts.py +++ b/tests/integration/consts.py @@ -2,6 +2,7 @@ METRICS_EXTRACTION_MIN_SUPPORTED_VERSION = 4 DUMMY_UPLOAD_PATH = "/api/42/upload/019cdc82ed6c7761ba21fd34b86481c2/" -DUMMY_UPLOAD_LOCATION = f"{DUMMY_UPLOAD_PATH}?upload_length=11&upload_signature=z_fUMhT0EZqJz6OQtwGHqTlOOLPpTVpvPa-rYTg18FVWZM1OGny-LeVJB5H-sSR_5e--I1xt-FlCmRG2bsmcAQ.eyJ0IjoiMjAyNi0wMy0xMVQxMDo0ODoxMy45NDM1ODNaIn0" +DUMMY_UPLOAD_PROVISIONAL_LOCATION = f"{DUMMY_UPLOAD_PATH}?upload_length=11&upload_id=my_upload&upload_signature=z_fUMhT0EZqJz6OQtwGHqTlOOLPpTVpvPa-rYTg18FVWZM1OGny-LeVJB5H-sSR_5e--I1xt-FlCmRG2bsmcAQ.eyJ0IjoiMjAyNi0wMy0xMVQxMDo0ODoxMy45NDM1ODNaIn0" +DUMMY_UPLOAD_FINAL_LOCATION = f"{DUMMY_UPLOAD_PATH}?upload_length=11&upload_signature=z_fUMhT0EZqJz6OQtwGHqTlOOLPpTVpvPa-rYTg18FVWZM1OGny-LeVJB5H-sSR_5e--I1xt-FlCmRG2bsmcAQ.eyJ0IjoiMjAyNi0wMy0xMVQxMDo0ODoxMy45NDM1ODNaIn0" ZSTD_MAGIC_HEADER = b"\x28\xb5\x2f\xfd" diff --git a/tests/integration/test_minidump.py b/tests/integration/test_minidump.py index 9dda28003ea..d4219258348 100644 --- a/tests/integration/test_minidump.py +++ b/tests/integration/test_minidump.py @@ -13,9 +13,9 @@ from urllib3.filepost import encode_multipart_formdata from sentry_relay.consts import DataCategory +from tests.integration.consts import DUMMY_UPLOAD_FINAL_LOCATION from .asserts import matches_any, time_within_delta from .test_attachment_ref import upload_and_make_ref -from .consts import DUMMY_UPLOAD_LOCATION MINIDUMP_ATTACHMENT_NAME = "upload_file_minidump" EVENT_ATTACHMENT_NAME = "__sentry-event" @@ -1131,7 +1131,7 @@ def test_minidump_objectstore_uploads( logs.headers["content_type"] == "application/vnd.sentry.attachment-ref+json" ) assert json.loads(logs.payload.bytes) == { - "location": DUMMY_UPLOAD_LOCATION, + "location": DUMMY_UPLOAD_FINAL_LOCATION, } else: assert ( @@ -1146,7 +1146,7 @@ def test_minidump_objectstore_uploads( == "application/vnd.sentry.attachment-ref+json" ) assert json.loads(minidump.payload.bytes) == { - "location": DUMMY_UPLOAD_LOCATION, + "location": DUMMY_UPLOAD_FINAL_LOCATION, "content_type": "application/x-dmp", } else: diff --git a/tests/integration/test_upload.py b/tests/integration/test_upload.py index 3adc2a53e79..1153e62bda5 100644 --- a/tests/integration/test_upload.py +++ b/tests/integration/test_upload.py @@ -10,7 +10,11 @@ from enum import Enum import pytest -from .consts import DUMMY_UPLOAD_PATH, DUMMY_UPLOAD_LOCATION +from .consts import ( + DUMMY_UPLOAD_FINAL_LOCATION, + DUMMY_UPLOAD_PATH, + DUMMY_UPLOAD_PROVISIONAL_LOCATION, +) class FeatureState(Enum): @@ -89,7 +93,10 @@ def test_forward_patch( data = b"hello world" response = relay.patch( "%s&sentry_key=%s" - % (DUMMY_UPLOAD_LOCATION, mini_sentry.get_dsn_public_key(project_id)), + % ( + DUMMY_UPLOAD_PROVISIONAL_LOCATION, + mini_sentry.get_dsn_public_key(project_id), + ), headers={ "Tus-Resumable": "1.0.0", "Content-Type": "application/offset+octet-stream", @@ -121,7 +128,9 @@ def create(**opts): create_attempts += 1 if create_attempts == 1: return Response("", status=503) - return Response("", status=201, headers={"Location": DUMMY_UPLOAD_LOCATION}) + return Response( + "", status=201, headers={"Location": DUMMY_UPLOAD_PROVISIONAL_LOCATION} + ) project_id = 42 project_key = mini_sentry.get_dsn_public_key(project_id) @@ -273,7 +282,10 @@ def test_upload_body_size( data = "x" * size response = relay.patch( "%s&sentry_key=%s" - % (DUMMY_UPLOAD_LOCATION, mini_sentry.get_dsn_public_key(project_id)), + % ( + DUMMY_UPLOAD_PROVISIONAL_LOCATION, + mini_sentry.get_dsn_public_key(project_id), + ), headers={ "Tus-Resumable": "1.0.0", "Content-Type": "application/offset+octet-stream", @@ -346,7 +358,9 @@ def test_timeout( @mini_sentry.app.route(DUMMY_UPLOAD_PATH, methods=["PATCH"]) def slow_upload(**opts): time.sleep(2) - return Response("", status=204, headers={"Location": DUMMY_UPLOAD_LOCATION}) + return Response( + "", status=204, headers={"Location": DUMMY_UPLOAD_FINAL_LOCATION} + ) project_id = 42 relay = relay( @@ -360,7 +374,10 @@ def slow_upload(**opts): data = b"hello world" response = relay.patch( "%s&sentry_key=%s" - % (DUMMY_UPLOAD_LOCATION, mini_sentry.get_dsn_public_key(project_id)), + % ( + DUMMY_UPLOAD_PROVISIONAL_LOCATION, + mini_sentry.get_dsn_public_key(project_id), + ), headers={ "Tus-Resumable": "1.0.0", "Upload-Offset": "0", @@ -538,7 +555,7 @@ def slow_upstream(**opts): def do_upload(): return relay.patch( - f"{DUMMY_UPLOAD_LOCATION}&sentry_key={project_key}", + f"{DUMMY_UPLOAD_PROVISIONAL_LOCATION}&sentry_key={project_key}", headers={ "Content-Length": str(len(data)), "Content-Type": "application/offset+octet-stream",