diff --git a/LICENSE-3rdparty.csv b/LICENSE-3rdparty.csv index 95fb38524ac..9e1bab93930 100644 --- a/LICENSE-3rdparty.csv +++ b/LICENSE-3rdparty.csv @@ -203,7 +203,6 @@ htmlescape,https://github.com/veddan/rust-htmlescape,Apache-2.0 OR MIT OR MP http,https://github.com/hyperium/http,MIT OR Apache-2.0,"Alex Crichton , Carl Lerche , Sean McArthur " http-body,https://github.com/hyperium/http-body,MIT,"Carl Lerche , Lucio Franco , Sean McArthur " http-body-util,https://github.com/hyperium/http-body,MIT,"Carl Lerche , Lucio Franco , Sean McArthur " -http-range-header,https://github.com/MarcusGrass/parse-range-headers,MIT,The http-range-header Authors http-serde,https://gitlab.com/kornelski/http-serde,Apache-2.0 OR MIT,Kornel httparse,https://github.com/seanmonstar/httparse,MIT OR Apache-2.0,Sean McArthur httpdate,https://github.com/pyfisch/httpdate,MIT OR Apache-2.0,Pyfisch @@ -242,7 +241,6 @@ jobserver,https://github.com/rust-lang/jobserver-rs,MIT OR Apache-2.0,Alex Crich js-sys,https://github.com/wasm-bindgen/wasm-bindgen/tree/master/crates/js-sys,MIT OR Apache-2.0,The wasm-bindgen Developers json_comments,https://github.com/tmccombs/json-comments-rs,Apache-2.0,Thayne McCombs lazy_static,https://github.com/rust-lang-nursery/lazy-static.rs,MIT OR Apache-2.0,Marvin Löbel -lazycell,https://github.com/indiv0/lazycell,MIT OR Apache-2.0,"Alex Crichton , Nikita Pekin " levenshtein_automata,https://github.com/tantivy-search/levenshtein-automata,MIT,Paul Masurel libc,https://github.com/rust-lang/libc,MIT OR Apache-2.0,The Rust Project Developers libloading,https://github.com/nagisa/rust_libloading,ISC,Simonas Kazlauskas @@ -287,7 +285,6 @@ mio,https://github.com/tokio-rs/mio,MIT,"Carl Lerche , Thomas mockall,https://github.com/asomers/mockall,MIT OR Apache-2.0,Alan Somers mockall_derive,https://github.com/asomers/mockall,MIT OR Apache-2.0,Alan Somers mrecordlog,https://github.com/quickwit-oss/mrecordlog,MIT,The mrecordlog Authors -multer,https://github.com/rousan/multer-rs,MIT,Rousan Ali multimap,https://github.com/havarnov/multimap,MIT OR Apache-2.0,Håvar Nøvik murmurhash32,https://github.com/quickwit-inc/murmurhash32,MIT,Paul Masurel nanorand,https://github.com/Absolucy/nanorand-rs,Zlib,Lucy @@ -402,7 +399,6 @@ rust-embed-impl,https://github.com/pyros2097/rust-embed,MIT,pyros2097 rust-stemmers,https://github.com/CurrySoftware/rust-stemmers,MIT OR BSD-3-Clause,"Jakob Demler , CurrySoftware " rustc-demangle,https://github.com/rust-lang/rustc-demangle,MIT OR Apache-2.0,Alex Crichton -rustc-hash,https://github.com/rust-lang-nursery/rustc-hash,Apache-2.0 OR MIT,The Rust Project Developers rustc-hash,https://github.com/rust-lang/rustc-hash,Apache-2.0 OR MIT,The Rust Project Developers rustix,https://github.com/bytecodealliance/rustix,Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT,"Dan Gohman , Jakub Konka " rustls,https://github.com/rustls/rustls,Apache-2.0 OR ISC OR MIT,The rustls Authors @@ -494,7 +490,6 @@ tokio-macros,https://github.com/tokio-rs/tokio,MIT,Tokio Contributors tokio-rustls,https://github.com/rustls/tokio-rustls,MIT OR Apache-2.0,The tokio-rustls Authors tokio-stream,https://github.com/tokio-rs/tokio,MIT,Tokio Contributors -tokio-tungstenite,https://github.com/snapview/tokio-tungstenite,MIT,"Daniel Abramov , Alexey Galakhov " tokio-util,https://github.com/tokio-rs/tokio,MIT,Tokio Contributors toml,https://github.com/toml-rs/toml,MIT OR Apache-2.0,Alex Crichton toml_datetime,https://github.com/toml-rs/toml,MIT OR Apache-2.0,The toml_datetime Authors @@ -516,7 +511,6 @@ tracing-serde,https://github.com/tokio-rs/tracing,MIT,Tokio Contributors , David Barsky , Tokio Contributors " try-lock,https://github.com/seanmonstar/try-lock,MIT,Sean McArthur ttl_cache,https://github.com/stusmall/ttl_cache,MIT OR Apache-2.0,Stu Small -tungstenite,https://github.com/snapview/tungstenite-rs,MIT OR Apache-2.0,"Alexey Galakhov, Daniel Abramov" typenum,https://github.com/paholg/typenum,MIT OR Apache-2.0,"Paho Lurie-Gregg , Andre Bogus " ulid,https://github.com/dylanhart/ulid-rs,MIT,dylanhart unarray,https://github.com/cameron1024/unarray,MIT OR Apache-2.0,The unarray Authors @@ -528,7 +522,6 @@ untrusted,https://github.com/briansmith/untrusted,ISC,Brian Smith , Bertram Truong " username,https://pijul.org/darcs/user,MIT OR Apache-2.0,Pierre-Étienne Meunier -utf-8,https://github.com/SimonSapin/rust-utf8,MIT OR Apache-2.0,Simon Sapin utf8-ranges,https://github.com/BurntSushi/utf8-ranges,Unlicense OR MIT,Andrew Gallant utf8_iter,https://github.com/hsivonen/utf8_iter,Apache-2.0 OR MIT,Henri Sivonen utf8parse,https://github.com/alacritty/vte,Apache-2.0 OR MIT,"Joe Wilm , Christian Duerr " @@ -556,7 +549,6 @@ wasm-timer,https://github.com/tomaka/wasm-timer,MIT,Pierre Krieger whichlang,https://github.com/quickwit-oss/whichlang,MIT,"Quickwit, Inc. " winapi,https://github.com/retep998/winapi-rs,MIT,Peter Atashian winapi,https://github.com/retep998/winapi-rs,MIT OR Apache-2.0,Peter Atashian diff --git a/quickwit/Cargo.lock b/quickwit/Cargo.lock index b732a7ae330..a5460b06d59 100644 --- a/quickwit/Cargo.lock +++ b/quickwit/Cargo.lock @@ -300,7 +300,7 @@ dependencies = [ "futures-lite 2.6.1", "parking", "polling", - "rustix 1.1.1", + "rustix 1.1.2", "slab", "windows-sys 0.60.2", ] @@ -331,7 +331,7 @@ dependencies = [ "cfg-if", "event-listener 5.4.1", "futures-lite 2.6.1", - "rustix 1.1.1", + "rustix 1.1.2", ] [[package]] @@ -346,7 +346,7 @@ dependencies = [ "cfg-if", "futures-core", "futures-io", - "rustix 1.1.1", + "rustix 1.1.2", "signal-hook-registry", "slab", "windows-sys 0.60.2", @@ -468,9 +468,9 @@ dependencies = [ [[package]] name = "aws-lc-rs" -version = "1.13.3" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c953fe1ba023e6b7730c0d4b031d06f267f23a46167dcbd40316644b10a17ba" +checksum = "94b8ff6c09cd57b16da53641caa860168b88c172a5ee163b0288d3d6eea12786" dependencies = [ "aws-lc-sys", "zeroize", @@ -478,11 +478,11 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.30.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbfd150b5dbdb988bcc8fb1fe787eb6b7ee6180ca24da683b61ea5405f3d43ff" +checksum = "0e44d16778acaf6a9ec9899b92cebd65580b83f685446bf2e1f5d3d732f99dcd" dependencies = [ - "bindgen 0.69.5", + "bindgen", "cc", "cmake", "dunce", @@ -1296,29 +1296,6 @@ dependencies = [ "serde", ] -[[package]] -name = "bindgen" -version = "0.69.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" -dependencies = [ - "bitflags 2.9.4", - "cexpr", - "clang-sys", - "itertools 0.12.1", - "lazy_static", - "lazycell", - "log", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash 1.1.0", - "shlex", - "syn 2.0.106", - "which", -] - [[package]] name = "bindgen" version = "0.72.1" @@ -1329,10 +1306,12 @@ dependencies = [ "cexpr", "clang-sys", "itertools 0.13.0", + "log", + "prettyplease", "proc-macro2", "quote", "regex", - "rustc-hash 2.1.1", + "rustc-hash", "shlex", "syn 2.0.106", ] @@ -1348,7 +1327,7 @@ dependencies = [ "miniserde", "peakmem-alloc", "perf-event", - "rustc-hash 2.1.1", + "rustc-hash", "rustop", "unicode-width 0.1.14", "yansi", @@ -3591,14 +3570,14 @@ dependencies = [ [[package]] name = "headers" -version = "0.3.9" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" +checksum = "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "bytes", "headers-core", - "http 0.2.12", + "http 1.3.1", "httpdate", "mime", "sha1", @@ -3606,11 +3585,11 @@ dependencies = [ [[package]] name = "headers-core" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4" dependencies = [ - "http 0.2.12", + "http 1.3.1", ] [[package]] @@ -3751,19 +3730,13 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "http-range-header" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" - [[package]] name = "http-serde" -version = "1.1.3" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f560b665ad9f1572cfcaf034f7fb84338a7ce945216d64a90fd81f046a3caee" +checksum = "0f056c8559e3757392c8d091e796416e4649d8e49e88b8d76df6c002f05027fd" dependencies = [ - "http 0.2.12", + "http 1.3.1", "serde", ] @@ -4286,15 +4259,6 @@ dependencies = [ "either", ] -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.13.0" @@ -4432,12 +4396,6 @@ dependencies = [ "spin 0.9.8", ] -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - [[package]] name = "levenshtein_automata" version = "0.2.1" @@ -4739,12 +4697,6 @@ version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" -[[package]] -name = "linux-raw-sys" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" - [[package]] name = "linux-raw-sys" version = "0.11.0" @@ -5034,24 +4986,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "multer" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01acbdc23469fd8fe07ab135923371d5f5a422fbf9c522158677c8eb15bc51c2" -dependencies = [ - "bytes", - "encoding_rs", - "futures-util", - "http 0.2.12", - "httparse", - "log", - "memchr", - "mime", - "spin 0.9.8", - "version_check", -] - [[package]] name = "multimap" version = "0.10.1" @@ -6185,7 +6119,7 @@ dependencies = [ "concurrent-queue", "hermit-abi", "pin-project-lite", - "rustix 1.1.1", + "rustix 1.1.2", "windows-sys 0.60.2", ] @@ -6765,6 +6699,7 @@ dependencies = [ "quickwit-storage", "quickwit-telemetry", "reqwest 0.12.23", + "rustls 0.23.31", "serde_json", "tabled", "tempfile", @@ -6901,7 +6836,7 @@ dependencies = [ "chrono", "cron", "enum-iterator", - "http 0.2.12", + "http 1.3.1", "http-serde", "humantime", "itertools 0.14.0", @@ -7163,6 +7098,7 @@ dependencies = [ "quickwit-storage", "rand 0.8.5", "reqwest 0.12.23", + "rustls 0.23.31", "serde_json", "tempfile", "tokio", @@ -7365,7 +7301,7 @@ dependencies = [ "quickwit-common", "quickwit-datetime", "regex", - "rustc-hash 2.1.1", + "rustc-hash", "serde", "serde_json", "serde_with", @@ -7467,6 +7403,8 @@ dependencies = [ "glob", "hex", "http 1.3.1", + "http-body 1.0.1", + "http-body-util", "http-serde", "humantime", "hyper 1.7.0", @@ -7501,8 +7439,8 @@ dependencies = [ "quickwit-telemetry", "regex", "rust-embed", - "rustls 0.21.12", - "rustls-pemfile", + "rustls 0.23.31", + "rustls-pemfile 2.2.0", "serde", "serde_json", "serde_qs 0.12.0", @@ -7511,14 +7449,14 @@ dependencies = [ "thiserror 2.0.16", "time", "tokio", - "tokio-rustls 0.24.1", + "tokio-rustls 0.26.2", "tokio-stream", "tokio-util", "tonic 0.13.1", "tonic-health", "tonic-reflection", "tower 0.5.2", - "tower-http 0.4.4", + "tower-http", "tracing", "utoipa", "warp", @@ -7605,7 +7543,7 @@ dependencies = [ "pin-project-lite", "quinn-proto", "quinn-udp", - "rustc-hash 2.1.1", + "rustc-hash", "rustls 0.23.31", "socket2 0.6.0", "thiserror 2.0.16", @@ -7625,7 +7563,7 @@ dependencies = [ "lru-slab", "rand 0.9.2", "ring 0.17.14", - "rustc-hash 2.1.1", + "rustc-hash", "rustls 0.23.31", "rustls-pki-types", "slab", @@ -7985,7 +7923,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "rustls 0.21.12", - "rustls-pemfile", + "rustls-pemfile 1.0.4", "serde", "serde_json", "serde_urlencoded", @@ -8037,7 +7975,7 @@ dependencies = [ "tokio-rustls 0.26.2", "tokio-util", "tower 0.5.2", - "tower-http 0.6.6", + "tower-http", "tower-service", "url", "wasm-bindgen", @@ -8283,12 +8221,6 @@ version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - [[package]] name = "rustc-hash" version = "2.1.1" @@ -8319,15 +8251,14 @@ dependencies = [ [[package]] name = "rustix" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9621e389a110cae094269936383d69b869492f03e5c1ed2d575a53c029d4441d" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ "bitflags 2.9.4", "errno", "libc", "linux-raw-sys 0.11.0", - "linux-raw-sys 0.9.4", "windows-sys 0.61.0", ] @@ -8366,7 +8297,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ "openssl-probe", - "rustls-pemfile", + "rustls-pemfile 1.0.4", "schannel", "security-framework 2.11.1", ] @@ -8392,6 +8323,15 @@ dependencies = [ "base64 0.21.7", ] +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "rustls-pki-types" version = "1.12.0" @@ -8780,12 +8720,9 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0431a35568651e363364210c91983c1da5eb29404d9f0928b67d4ebcfa7d330c" dependencies = [ - "futures", "percent-encoding", "serde", "thiserror 1.0.69", - "tracing", - "warp", ] [[package]] @@ -9205,7 +9142,7 @@ dependencies = [ "paste", "percent-encoding", "rustls 0.21.12", - "rustls-pemfile", + "rustls-pemfile 1.0.4", "serde", "serde_json", "sha2", @@ -9630,7 +9567,7 @@ dependencies = [ "rayon", "regex", "rust-stemmers", - "rustc-hash 2.1.1", + "rustc-hash", "serde", "serde_json", "sketches-ddsketch", @@ -9755,15 +9692,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.21.0" +version = "3.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15b61f8f20e3a6f7e0649d825294eaf317edce30f82cf6026e7e4cb9222a7d1e" +checksum = "84fa4d11fadde498443cca10fd3ac23c951f0dc59e080e9f4b93d4df4e4eea53" dependencies = [ "fastrand 2.3.0", "getrandom 0.3.3", "once_cell", - "rustix 1.1.1", - "windows-sys 0.60.2", + "rustix 1.1.2", + "windows-sys 0.61.0", ] [[package]] @@ -10061,18 +9998,6 @@ dependencies = [ "tokio-util", ] -[[package]] -name = "tokio-tungstenite" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" -dependencies = [ - "futures-util", - "log", - "tokio", - "tungstenite", -] - [[package]] name = "tokio-util" version = "0.7.16" @@ -10157,7 +10082,7 @@ dependencies = [ "percent-encoding", "pin-project", "prost 0.11.9", - "rustls-pemfile", + "rustls-pemfile 1.0.4", "tokio", "tokio-rustls 0.24.1", "tokio-stream", @@ -10309,40 +10234,23 @@ dependencies = [ "tracing", ] -[[package]] -name = "tower-http" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" -dependencies = [ - "async-compression", - "bitflags 2.9.4", - "bytes", - "futures-core", - "futures-util", - "http 0.2.12", - "http-body 0.4.6", - "http-range-header", - "pin-project-lite", - "tokio", - "tokio-util", - "tower-layer", - "tower-service", -] - [[package]] name = "tower-http" version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" dependencies = [ + "async-compression", "bitflags 2.9.4", "bytes", + "futures-core", "futures-util", "http 1.3.1", "http-body 1.0.1", "iri-string", "pin-project-lite", + "tokio", + "tokio-util", "tower 0.5.2", "tower-layer", "tower-service", @@ -10469,25 +10377,6 @@ dependencies = [ "linked-hash-map", ] -[[package]] -name = "tungstenite" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" -dependencies = [ - "byteorder", - "bytes", - "data-encoding", - "http 1.3.1", - "httparse", - "log", - "rand 0.8.5", - "sha1", - "thiserror 1.0.69", - "url", - "utf-8", -] - [[package]] name = "typenum" version = "1.18.0" @@ -10659,12 +10548,6 @@ dependencies = [ "winapi 0.2.8", ] -[[package]] -name = "utf-8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" - [[package]] name = "utf8-ranges" version = "1.0.5" @@ -10910,20 +10793,22 @@ dependencies = [ [[package]] name = "warp" -version = "0.3.7" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4378d202ff965b011c64817db11d5829506d3404edeadb61f190d111da3f231c" +checksum = "51d06d9202adc1f15d709c4f4a2069be5428aa912cc025d6f268ac441ab066b0" dependencies = [ "bytes", "futures-channel", "futures-util", "headers", - "http 0.2.12", - "hyper 0.14.32", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "hyper 1.7.0", + "hyper-util", "log", "mime", "mime_guess", - "multer", "percent-encoding", "pin-project", "scoped-tls", @@ -10931,7 +10816,6 @@ dependencies = [ "serde_json", "serde_urlencoded", "tokio", - "tokio-tungstenite", "tokio-util", "tower-service", "tracing", @@ -11117,18 +11001,6 @@ dependencies = [ "rustls-pki-types", ] -[[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix 0.38.44", -] - [[package]] name = "whichlang" version = "0.1.1" @@ -11689,7 +11561,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af3a19837351dc82ba89f8a125e22a3c475f05aba604acc023d62b2739ae2909" dependencies = [ "libc", - "rustix 1.1.1", + "rustix 1.1.2", ] [[package]] @@ -11880,7 +11752,7 @@ version = "2.0.16+zstd.1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" dependencies = [ - "bindgen 0.72.1", + "bindgen", "cc", "pkg-config", ] diff --git a/quickwit/Cargo.toml b/quickwit/Cargo.toml index a68147f782a..cc1f181d196 100644 --- a/quickwit/Cargo.toml +++ b/quickwit/Cargo.toml @@ -122,17 +122,17 @@ hex = "0.4" home = "0.5" hostname = "0.3" http = "1.3" -http-body-util = "0.1.3" -http-serde = "1.1" +http-body = "1.0" +http-body-util = "0.1" +http-serde = "2.1" humantime = "2.2" -hyper = { version = "1.6", features = ["client", "http1", "http2", "server"] } +hyper = { version = "1.7", features = ["client", "http1", "http2", "server"] } hyper-rustls = "0.27" hyper-util = { version = "0.1", features = ["full"] } indexmap = { version = "2.9", features = ["serde"] } indicatif = "0.17" itertools = "0.14" json_comments = "0.2" -legacy-http = { version = "0.2", package = "http" } libz-sys = "1.1" lindera-core = "0.27" lindera-dictionary = "0.27" @@ -204,8 +204,8 @@ reqwest-middleware = "0.4" reqwest-retry = "0.7" rust-embed = "6.8" rustc-hash = "2.1" -rustls = "0.21" -rustls-pemfile = "1.0" +rustls = "0.23" +rustls-pemfile = "2.2" sea-query = { version = "0.30" } sea-query-binder = { version = "0.5", features = [ "runtime-tokio-rustls", @@ -215,7 +215,7 @@ sea-query-binder = { version = "0.5", features = [ serde = { version = "1.0.219", features = ["derive", "rc"] } serde_json = "1.0" serde_json_borrow = "0.5" -serde_qs = { version = "0.12", features = ["warp"] } +serde_qs = { version = "0.12" } serde_with = "3.12" serde_yaml = "0.9" serial_test = { version = "3.2", features = ["file_locks"] } @@ -239,7 +239,7 @@ tikv-jemallocator = "0.5" time = { version = "0.3", features = ["std", "formatting", "macros"] } tokio = { version = "1.45", features = ["full"] } tokio-metrics = { version = "0.3", features = ["rt"] } -tokio-rustls = { version = "0.24", default-features = false } +tokio-rustls = { version = "0.26", default-features = false } tokio-stream = { version = "0.1", features = ["sync"] } tokio-util = { version = "0.7", features = ["full"] } toml = "0.7" @@ -260,7 +260,7 @@ tower = { version = "0.5", features = [ "util", ] } # legacy version because of warp -tower-http = { version = "0.4", features = [ +tower-http = { version = "0.6", features = [ "compression-gzip", "compression-zstd", "cors", @@ -285,20 +285,20 @@ vrl = { version = "0.22", default-features = false, features = [ "stdlib", "value", ] } -warp = "0.3" +warp = { version = "0.4", features = ["server", "test"] } whichlang = "0.1" wiremock = "0.6" zstd = "0.13" -aws-config = "1.6" +aws-config = "1.8" aws-credential-types = { version = "1.2", features = ["hardcoded-credentials"] } aws-runtime = "1.5" -aws-sdk-kinesis = "1.74" +aws-sdk-kinesis = "1.86" aws-sdk-s3 = "=1.62" -aws-sdk-sqs = "1.70" +aws-sdk-sqs = "1.82" aws-smithy-async = "1.2" -aws-smithy-http-client = { version = "1.0" } -aws-smithy-runtime = "1.8" +aws-smithy-http-client = { version = "1.1", features = ["default-client"] } +aws-smithy-runtime = "1.9" aws-smithy-types = { version = "1.3", features = [ "byte-stream-poll-next", "http-body-1-x", diff --git a/quickwit/quickwit-cli/Cargo.toml b/quickwit/quickwit-cli/Cargo.toml index 2ddbd21baae..c595cb7e90a 100644 --- a/quickwit/quickwit-cli/Cargo.toml +++ b/quickwit/quickwit-cli/Cargo.toml @@ -40,6 +40,7 @@ opentelemetry = { workspace = true } opentelemetry_sdk = { workspace = true } opentelemetry-otlp = { workspace = true } reqwest = { workspace = true } +rustls = { workspace = true } serde_json = { workspace = true } tabled = { workspace = true } tempfile = { workspace = true } diff --git a/quickwit/quickwit-cli/src/main.rs b/quickwit/quickwit-cli/src/main.rs index 989752dfd05..691725eab4e 100644 --- a/quickwit/quickwit-cli/src/main.rs +++ b/quickwit/quickwit-cli/src/main.rs @@ -89,6 +89,10 @@ async fn main_impl() -> anyhow::Result<()> { } }; + rustls::crypto::ring::default_provider() + .install_default() + .expect("rustls crypto ring default provider installation should not fail"); + #[cfg(feature = "jemalloc")] start_jemalloc_metrics_loop(); diff --git a/quickwit/quickwit-config/Cargo.toml b/quickwit/quickwit-config/Cargo.toml index df52a40ced7..7cf75818444 100644 --- a/quickwit/quickwit-config/Cargo.toml +++ b/quickwit/quickwit-config/Cargo.toml @@ -17,11 +17,11 @@ bytesize = { workspace = true } chrono = { workspace = true } cron = { workspace = true } enum-iterator = { workspace = true } +http = { workspace = true } http-serde = { workspace = true } humantime = { workspace = true } itertools = { workspace = true } json_comments = { workspace = true } -legacy-http = { workspace = true } new_string_template = { workspace = true } once_cell = { workspace = true } regex = { workspace = true } diff --git a/quickwit/quickwit-config/src/node_config/mod.rs b/quickwit/quickwit-config/src/node_config/mod.rs index 5b5176fda7f..bb8a17daaeb 100644 --- a/quickwit/quickwit-config/src/node_config/mod.rs +++ b/quickwit/quickwit-config/src/node_config/mod.rs @@ -23,7 +23,7 @@ use std::time::Duration; use anyhow::{bail, ensure}; use bytesize::ByteSize; -use legacy_http::HeaderMap; +use http::HeaderMap; use quickwit_common::net::HostAddr; use quickwit_common::shared_consts::{ DEFAULT_SHARD_BURST_LIMIT, DEFAULT_SHARD_SCALE_UP_FACTOR, DEFAULT_SHARD_THROUGHPUT_LIMIT, diff --git a/quickwit/quickwit-config/src/node_config/serialize.rs b/quickwit/quickwit-config/src/node_config/serialize.rs index ab8ae75243d..b5f39ceb0ac 100644 --- a/quickwit/quickwit-config/src/node_config/serialize.rs +++ b/quickwit/quickwit-config/src/node_config/serialize.rs @@ -19,7 +19,7 @@ use std::time::Duration; use anyhow::{Context, bail}; use bytesize::ByteSize; -use legacy_http::HeaderMap; +use http::HeaderMap; use quickwit_common::fs::get_disk_size; use quickwit_common::net::{Host, find_private_ip, get_short_hostname}; use quickwit_common::new_coolid; diff --git a/quickwit/quickwit-indexing/src/source/queue_sources/sqs_queue.rs b/quickwit/quickwit-indexing/src/source/queue_sources/sqs_queue.rs index 1e4c55142ac..d9159de1a35 100644 --- a/quickwit/quickwit-indexing/src/source/queue_sources/sqs_queue.rs +++ b/quickwit/quickwit-indexing/src/source/queue_sources/sqs_queue.rs @@ -318,21 +318,21 @@ pub mod test_helpers { /// /// Returns the queue URL to use for the source and a guard for the /// temporary mock server - pub fn start_mock_sqs_get_queue_attributes_endpoint() -> (String, oneshot::Sender<()>) { + pub async fn start_mock_sqs_get_queue_attributes_endpoint() -> (String, oneshot::Sender<()>) { let hello = warp::path!().map(|| "{}"); let (tx, rx) = oneshot::channel(); - let (addr, server) = - warp::serve(hello).bind_with_graceful_shutdown(([127, 0, 0, 1], 0), async { - rx.await.ok(); - }); - tokio::spawn(server); - let queue_url = format!("http://{}:{}/", addr.ip(), addr.port()); + let server = warp::serve(hello).bind(([127, 0, 0, 1], 0)).await; + let signal_future = async { + rx.await.ok(); + }; + server.graceful(signal_future); + let queue_url = "http://127.0.0.1:0/".to_string(); (queue_url, tx) } #[tokio::test] async fn test_mock_sqs_get_queue_attributes_endpoint() { - let (queue_url, _shutdown) = start_mock_sqs_get_queue_attributes_endpoint(); + let (queue_url, _shutdown) = start_mock_sqs_get_queue_attributes_endpoint().await; check_connectivity(&queue_url).await.unwrap(); drop(_shutdown); check_connectivity(&queue_url).await.unwrap_err(); diff --git a/quickwit/quickwit-integration-tests/Cargo.toml b/quickwit/quickwit-integration-tests/Cargo.toml index 23f2d884718..55308cff556 100644 --- a/quickwit/quickwit-integration-tests/Cargo.toml +++ b/quickwit/quickwit-integration-tests/Cargo.toml @@ -27,6 +27,7 @@ hyper-util = { workspace = true } itertools = { workspace = true } rand = { workspace = true } reqwest = { workspace = true } +rustls = { workspace = true } serde_json = { workspace = true } tempfile = { workspace = true } tokio = { workspace = true } diff --git a/quickwit/quickwit-integration-tests/src/test_utils/cluster_sandbox.rs b/quickwit/quickwit-integration-tests/src/test_utils/cluster_sandbox.rs index 81889a9311a..36fbadbbcea 100644 --- a/quickwit/quickwit-integration-tests/src/test_utils/cluster_sandbox.rs +++ b/quickwit/quickwit-integration-tests/src/test_utils/cluster_sandbox.rs @@ -176,6 +176,10 @@ pub struct ResolvedClusterConfig { impl ResolvedClusterConfig { /// Start a cluster using this config and waits for the nodes to be ready pub async fn start(self) -> ClusterSandbox { + rustls::crypto::ring::default_provider() + .install_default() + .expect("rustls crypto ring default provider installation should not fail"); + let mut node_shutdown_handles = Vec::new(); let runtimes_config = RuntimesConfig::light_for_tests(); let storage_resolver = StorageResolver::unconfigured(); diff --git a/quickwit/quickwit-lambda/README.md b/quickwit/quickwit-lambda/README.md index 26aacdb0a0c..88fa9c8748a 100644 --- a/quickwit/quickwit-lambda/README.md +++ b/quickwit/quickwit-lambda/README.md @@ -1,4 +1,4 @@ # Deprecation This package was removed in Q3 2025. The maintenance burden was high and the -feature was unused. +feature was unused. \ No newline at end of file diff --git a/quickwit/quickwit-serve/Cargo.toml b/quickwit/quickwit-serve/Cargo.toml index 0d31bfd3db1..99c8fe3922d 100644 --- a/quickwit/quickwit-serve/Cargo.toml +++ b/quickwit/quickwit-serve/Cargo.toml @@ -23,6 +23,8 @@ futures-util = { workspace = true } glob = { workspace = true } hex = { workspace = true } http = { workspace = true } +http-body = { workspace = true } +http-body-util = { workspace = true } http-serde = { workspace = true } humantime = { workspace = true } hyper = { workspace = true } @@ -55,7 +57,7 @@ tower = { workspace = true, features = ["limit"] } tower-http = { workspace = true } tracing = { workspace = true } utoipa = { workspace = true } -warp = { workspace = true } +warp = { workspace = true, features = ["server"] } zstd = { workspace = true } quickwit-actors = { workspace = true } diff --git a/quickwit/quickwit-serve/src/developer_api/heap_prof.rs b/quickwit/quickwit-serve/src/developer_api/heap_prof.rs index a1d3cd3d224..a6b833bc4ac 100644 --- a/quickwit/quickwit-serve/src/developer_api/heap_prof.rs +++ b/quickwit/quickwit-serve/src/developer_api/heap_prof.rs @@ -35,7 +35,7 @@ pub fn heap_prof_handlers() async fn start_profiler_handler( params: ProfilerQueryParams, - ) -> Result, warp::Rejection> { + ) -> Result { start_profiling(params.min_alloc_size, params.backtrace_every); let response = warp::reply::with_status("Heap profiling started", warp::http::StatusCode::OK) @@ -43,8 +43,7 @@ pub fn heap_prof_handlers() Ok(response) } - async fn stop_profiler_handler() - -> Result, warp::Rejection> { + async fn stop_profiler_handler() -> Result { stop_profiling(); let response = warp::reply::with_status("Heap profiling stopped", warp::http::StatusCode::OK) diff --git a/quickwit/quickwit-serve/src/elasticsearch_api/filter.rs b/quickwit/quickwit-serve/src/elasticsearch_api/filter.rs index 3104ded1b68..b8d2343f666 100644 --- a/quickwit/quickwit-serve/src/elasticsearch_api/filter.rs +++ b/quickwit/quickwit-serve/src/elasticsearch_api/filter.rs @@ -50,7 +50,7 @@ pub(crate) fn elasticsearch_filter() -> impl Filter + Clone { warp::path!("_elastic" / "_search") .and(warp::get().or(warp::post()).unify()) - .and(serde_qs::warp::query(serde_qs::Config::default())) + .and(warp::query()) } #[utoipa::path( @@ -74,7 +74,7 @@ pub(crate) fn elastic_bulk_filter( content_length_limit.as_u64(), )) .and(get_body_bytes()) - .and(serde_qs::warp::query(serde_qs::Config::default())) + .and(warp::query()) } #[utoipa::path( @@ -98,9 +98,7 @@ pub(crate) fn elastic_index_bulk_filter( content_length_limit.as_u64(), )) .and(get_body_bytes()) - .and(serde_qs::warp::query::( - serde_qs::Config::default(), - )) + .and(warp::query::()) } /// Like the warp json filter, but accepts an empty body and interprets it as `T::default`. @@ -138,7 +136,7 @@ pub(crate) fn elastic_index_field_capabilities_filter() -> impl Filter< warp::path!("_elastic" / String / "_field_caps") .and_then(extract_index_id_patterns) .and(warp::get().or(warp::post()).unify()) - .and(serde_qs::warp::query(serde_qs::Config::default())) + .and(warp::query()) .and(json_or_empty()) } @@ -154,7 +152,7 @@ pub(crate) fn elastic_field_capabilities_filter() -> impl Filter< warp::path!("_elastic" / "_field_caps") .and_then(extract_index_id_patterns_default) .and(warp::get().or(warp::post()).unify()) - .and(serde_qs::warp::query(serde_qs::Config::default())) + .and(warp::query()) .and(json_or_empty()) } @@ -173,7 +171,7 @@ pub(crate) fn elastic_index_count_filter() warp::path!("_elastic" / String / "_count") .and_then(extract_index_id_patterns) .and(warp::get().or(warp::post()).unify()) - .and(serde_qs::warp::query(serde_qs::Config::default())) + .and(warp::query()) .and(json_or_empty()) } @@ -183,7 +181,7 @@ pub(crate) fn elastic_delete_index_filter() warp::path!("_elastic" / String) .and(warp::delete()) .and_then(extract_index_id_patterns) - .and(serde_qs::warp::query(serde_qs::Config::default())) + .and(warp::query()) } // No support for any query parameters for now. @@ -212,7 +210,7 @@ pub(crate) fn elastic_index_cat_indices_filter() warp::path!("_elastic" / "_cat" / "indices" / String) .and_then(extract_index_id_patterns) .and(warp::get()) - .and(serde_qs::warp::query(serde_qs::Config::default())) + .and(warp::query()) } #[utoipa::path(get, tag = "Search", path = "/_cat/indices")] @@ -220,7 +218,7 @@ pub(crate) fn elastic_cat_indices_filter() -> impl Filter + Clone { warp::path!("_elastic" / "_cat" / "indices") .and(warp::get()) - .and(serde_qs::warp::query(serde_qs::Config::default())) + .and(warp::query()) } #[utoipa::path(get, tag = "Search", path = "/{index}/_search")] @@ -229,7 +227,7 @@ pub(crate) fn elastic_index_search_filter() warp::path!("_elastic" / String / "_search") .and_then(extract_index_id_patterns) .and(warp::get().or(warp::post()).unify()) - .and(serde_qs::warp::query(serde_qs::Config::default())) + .and(warp::query()) .and(json_or_empty()) } @@ -240,7 +238,7 @@ pub(crate) fn elastic_multi_search_filter() .and(warp::body::content_length_limit(BODY_LENGTH_LIMIT.as_u64())) .and(warp::body::bytes()) .and(warp::post()) - .and(serde_qs::warp::query(serde_qs::Config::default())) + .and(warp::query()) } fn merge_scroll_body_params( @@ -259,7 +257,7 @@ pub(crate) fn elastic_scroll_filter() warp::path!("_elastic" / "_search" / "scroll") .and(warp::body::content_length_limit(BODY_LENGTH_LIMIT.as_u64())) .and(warp::get().or(warp::post()).unify()) - .and(serde_qs::warp::query(serde_qs::Config::default())) + .and(warp::query()) .and(json_or_empty()) .map( |scroll_query_params: ScrollQueryParams, scroll_body: ScrollQueryParams| { diff --git a/quickwit/quickwit-serve/src/elasticsearch_api/model/error.rs b/quickwit/quickwit-serve/src/elasticsearch_api/model/error.rs index 713a3d8e5ce..c11807fb4fb 100644 --- a/quickwit/quickwit-serve/src/elasticsearch_api/model/error.rs +++ b/quickwit/quickwit-serve/src/elasticsearch_api/model/error.rs @@ -22,8 +22,6 @@ use quickwit_search::SearchError; use serde::{Deserialize, Serialize}; use warp::hyper::StatusCode; -use crate::convert_status_code_to_legacy_http; - #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ElasticsearchError { #[serde(with = "http_serde::status_code")] @@ -71,7 +69,7 @@ impl From for ElasticsearchError { additional_details: Default::default(), }; ElasticsearchError { - status: crate::convert_status_code_to_legacy_http(status), + status, error: reason, } } @@ -79,9 +77,7 @@ impl From for ElasticsearchError { impl From for ElasticsearchError { fn from(ingest_service_error: IngestServiceError) -> Self { - let status = crate::convert_status_code_to_legacy_http( - ingest_service_error.error_code().http_status_code(), - ); + let status = ingest_service_error.error_code().http_status_code(); let reason = ErrorCause { reason: Some(ingest_service_error.to_string()), @@ -113,7 +109,7 @@ impl From for ElasticsearchError { additional_details: Default::default(), }; ElasticsearchError { - status: crate::convert_status_code_to_legacy_http(status), + status, error: reason, } } @@ -133,7 +129,7 @@ impl From for ElasticsearchError { additional_details: Default::default(), }; ElasticsearchError { - status: convert_status_code_to_legacy_http(status), + status, error: reason, } } diff --git a/quickwit/quickwit-serve/src/format.rs b/quickwit/quickwit-serve/src/format.rs index 7b53f92f9c8..1f0d8fb19ec 100644 --- a/quickwit/quickwit-serve/src/format.rs +++ b/quickwit/quickwit-serve/src/format.rs @@ -80,8 +80,7 @@ struct FormatQueryString { pub(crate) fn extract_format_from_qs() -> impl Filter + Clone { - serde_qs::warp::query::(serde_qs::Config::default()) - .map(|format_qs: FormatQueryString| format_qs.format) + warp::query::().map(|format_qs: FormatQueryString| format_qs.format) } #[derive(Debug, Error)] diff --git a/quickwit/quickwit-serve/src/index_api/index_resource.rs b/quickwit/quickwit-serve/src/index_api/index_resource.rs index 29634af7881..cd0a5c0e4f6 100644 --- a/quickwit/quickwit-serve/src/index_api/index_resource.rs +++ b/quickwit/quickwit-serve/src/index_api/index_resource.rs @@ -81,7 +81,7 @@ pub fn list_indexes_metadata_handler( ) -> impl Filter + Clone { warp::path!("indexes") .and(warp::get()) - .and(serde_qs::warp::query(serde_qs::Config::default())) + .and(warp::query()) .and(with_arg(metastore)) .then(list_indexes_metadata) .and(extract_format_from_qs()) @@ -238,7 +238,7 @@ pub fn create_index_handler( ) -> impl Filter + Clone { warp::path!("indexes") .and(warp::post()) - .and(serde_qs::warp::query(serde_qs::Config::default())) + .and(warp::query()) .and(extract_config_format()) .and(warp::body::content_length_limit(1024 * 1024)) .and(warp::filters::body::bytes()) @@ -294,7 +294,7 @@ pub struct UpdateQueryParams { } fn update_index_qp() -> impl Filter + Clone { - serde_qs::warp::query::(serde_qs::Config::default()) + warp::query::() } pub fn update_index_handler( @@ -449,7 +449,7 @@ pub fn delete_index_handler( ) -> impl Filter + Clone { warp::path!("indexes" / String) .and(warp::delete()) - .and(serde_qs::warp::query(serde_qs::Config::default())) + .and(warp::query()) .and(with_arg(index_service)) .then(delete_index) .and(extract_format_from_qs()) diff --git a/quickwit/quickwit-serve/src/index_api/rest_handler.rs b/quickwit/quickwit-serve/src/index_api/rest_handler.rs index 1b6e3a7a649..bc4c8d9b105 100644 --- a/quickwit/quickwit-serve/src/index_api/rest_handler.rs +++ b/quickwit/quickwit-serve/src/index_api/rest_handler.rs @@ -1140,7 +1140,7 @@ mod tests { use quickwit_indexing::source::sqs_queue::test_helpers::start_mock_sqs_get_queue_attributes_endpoint; let metastore = metastore_for_test(); - let (queue_url, _guard) = start_mock_sqs_get_queue_attributes_endpoint(); + let (queue_url, _guard) = start_mock_sqs_get_queue_attributes_endpoint().await; let index_service = IndexService::new(metastore.clone(), StorageResolver::unconfigured()); let mut node_config = NodeConfig::for_test(); node_config.default_index_root_uri = Uri::for_test("file:///default-index-root-uri"); diff --git a/quickwit/quickwit-serve/src/index_api/source_resource.rs b/quickwit/quickwit-serve/src/index_api/source_resource.rs index 39eb09b8894..66f3069b228 100644 --- a/quickwit/quickwit-serve/src/index_api/source_resource.rs +++ b/quickwit/quickwit-serve/src/index_api/source_resource.rs @@ -111,7 +111,7 @@ pub struct UpdateQueryParams { } fn update_source_qp() -> impl Filter + Clone { - serde_qs::warp::query::(serde_qs::Config::default()) + warp::query::() } pub fn update_source_handler( diff --git a/quickwit/quickwit-serve/src/index_api/split_resource.rs b/quickwit/quickwit-serve/src/index_api/split_resource.rs index a439328ffa1..a062186e551 100644 --- a/quickwit/quickwit-serve/src/index_api/split_resource.rs +++ b/quickwit/quickwit-serve/src/index_api/split_resource.rs @@ -141,7 +141,7 @@ pub fn list_splits_handler( ) -> impl Filter + Clone { warp::path!("indexes" / String / "splits") .and(warp::get()) - .and(serde_qs::warp::query(serde_qs::Config::default())) + .and(warp::query()) .and(with_arg(metastore)) .then(list_splits) .and(extract_format_from_qs()) diff --git a/quickwit/quickwit-serve/src/ingest_api/rest_handler.rs b/quickwit/quickwit-serve/src/ingest_api/rest_handler.rs index a12d154c63c..9040c8fd700 100644 --- a/quickwit/quickwit-serve/src/ingest_api/rest_handler.rs +++ b/quickwit/quickwit-serve/src/ingest_api/rest_handler.rs @@ -98,9 +98,7 @@ fn ingest_filter( config.content_length_limit.as_u64(), )) .and(get_body_bytes()) - .and(serde_qs::warp::query::( - serde_qs::Config::default(), - )) + .and(warp::query::()) } fn ingest_handler( diff --git a/quickwit/quickwit-serve/src/jaeger_api/rest_handler.rs b/quickwit/quickwit-serve/src/jaeger_api/rest_handler.rs index 45d3d5d42f6..def8a4c6ca7 100644 --- a/quickwit/quickwit-serve/src/jaeger_api/rest_handler.rs +++ b/quickwit/quickwit-serve/src/jaeger_api/rest_handler.rs @@ -139,7 +139,7 @@ pub fn jaeger_traces_search_handler( ) -> impl Filter + Clone { jaeger_api_path_filter() .and(warp::path!("traces")) - .and(serde_qs::warp::query(serde_qs::Config::default())) + .and(warp::query()) .and(require(jaeger_service_opt)) .then(jaeger_traces_search) .map(|result| make_jaeger_api_response(result, BodyFormat::default())) diff --git a/quickwit/quickwit-serve/src/lib.rs b/quickwit/quickwit-serve/src/lib.rs index 91afc4a4dd7..44c0f648b5a 100644 --- a/quickwit/quickwit-serve/src/lib.rs +++ b/quickwit/quickwit-serve/src/lib.rs @@ -257,11 +257,6 @@ async fn balance_channel_for_service( BalanceChannel::from_stream(service_change_stream) } -fn convert_status_code_to_legacy_http(status_code: http::StatusCode) -> warp::http::StatusCode { - warp::http::StatusCode::from_u16(status_code.as_u16()) - .unwrap_or(warp::http::StatusCode::INTERNAL_SERVER_ERROR) -} - async fn start_ingest_client_if_needed( node_config: &NodeConfig, universe: &Universe, diff --git a/quickwit/quickwit-serve/src/rest.rs b/quickwit/quickwit-serve/src/rest.rs index 01f5207e544..e0e8e637f6b 100644 --- a/quickwit/quickwit-serve/src/rest.rs +++ b/quickwit/quickwit-serve/src/rest.rs @@ -13,23 +13,24 @@ // limitations under the License. use std::fmt::Formatter; -use std::pin::Pin; use std::sync::Arc; +use hyper_util::rt::{TokioExecutor, TokioIo}; +use hyper_util::server::conn::auto::Builder; +use hyper_util::service::TowerToHyperService; use quickwit_common::tower::BoxFutureInfaillible; use quickwit_config::{disable_ingest_v1, enable_ingest_v2}; use quickwit_search::SearchService; use tokio::net::TcpListener; +use tokio_rustls::TlsAcceptor; +use tokio_util::either::Either; use tower::ServiceBuilder; -use tower::make::Shared; use tower_http::compression::CompressionLayer; use tower_http::compression::predicate::{NotForContentType, Predicate, SizeAbove}; use tower_http::cors::CorsLayer; use tracing::{error, info}; use warp::filters::log::Info; use warp::hyper::http::HeaderValue; -use warp::hyper::server::accept::Accept; -use warp::hyper::server::conn::AddrIncoming; use warp::hyper::{Method, StatusCode, http}; use warp::{Filter, Rejection, Reply, redirect}; @@ -110,7 +111,7 @@ impl CompressionPredicate { impl Predicate for CompressionPredicate { fn should_compress(&self, response: &http::Response) -> bool - where B: warp::hyper::body::HttpBody { + where B: http_body::Body { if let Some(size_above) = self.size_above_opt { size_above.should_compress(response) } else { @@ -219,32 +220,61 @@ pub(crate) async fn start_rest_server( "starting REST server listening on {rest_listen_addr}" ); - let incoming = AddrIncoming::from_listener(tcp_listener)?; + let service = TowerToHyperService::new(service); - let maybe_tls_incoming = - if let Some(tls_config) = &quickwit_services.node_config.rest_config.tls { - let rustls_config = tls::make_rustls_config(tls_config)?; - EitherIncoming::Left(tls::TlsAcceptor::new(rustls_config, incoming)) - } else { - EitherIncoming::Right(incoming) - }; + let server = Builder::new(TokioExecutor::new()); + let graceful = hyper_util::server::graceful::GracefulShutdown::new(); + let mut shutdown_signal = std::pin::pin!(shutdown_signal); + readiness_trigger.await; - // `graceful_shutdown()` seems to be blocking in presence of existing connections. - // The following approach of dropping the serve supposedly is not bullet proof, but it seems to - // work in our unit test. - // - // See more of the discussion here: - // https://github.com/hyperium/hyper/issues/2386 - - let serve_fut = async move { + loop { tokio::select! { - res = warp::hyper::Server::builder(maybe_tls_incoming).serve(Shared::new(service)) => { res } - _ = shutdown_signal => { Ok(()) } + conn = tcp_listener.accept() => { + let (stream, _remote_addr) = match conn { + Ok(conn) => conn, + Err(err) => { + error!("failed to accept connection: {err:#}"); + continue; + } + }; + + let either_stream = + if let Some(tls_config) = &quickwit_services.node_config.rest_config.tls { + let rustls_config = tls::make_rustls_config(tls_config)?; + let acceptor = TlsAcceptor::from(rustls_config); + let tls_stream = match acceptor.accept(stream).await { + Ok(tls_stream) => tls_stream, + Err(err) => { + error!("failed to perform tls handshake: {err:#}"); + continue; + } + }; + Either::Left(tls_stream) + } else { + Either::Right(stream) + }; + + let conn = server.serve_connection_with_upgrades(TokioIo::new(either_stream), service.clone()); + let conn = graceful.watch(conn.into_owned()); + tokio::spawn(async move { + if let Err(err) = conn.await { + error!("failed to serve connection: {err:#}"); + } + }); + }, + _ = &mut shutdown_signal => { + info!("REST server shutdown signal received"); + break; + } } - }; + } + + tokio::select! { + _ = graceful.shutdown() => { + info!("gracefully shutdown"); + } + } - let (serve_res, _trigger_res) = tokio::join!(serve_fut, readiness_trigger); - serve_res?; Ok(()) } @@ -480,158 +510,37 @@ fn build_cors(cors_origins: &[String]) -> CorsLayer { mod tls { // most of this module is copied from hyper-tls examples, licensed under Apache 2.0, MIT or ISC - use std::future::Future; - use std::pin::Pin; use std::sync::Arc; - use std::task::{Context, Poll, ready}; use std::vec::Vec; use std::{fs, io}; use quickwit_config::TlsConfig; - use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; + use rustls::pki_types::{CertificateDer, PrivateKeyDer}; use tokio_rustls::rustls::ServerConfig; - use warp::hyper::server::accept::Accept; - use warp::hyper::server::conn::{AddrIncoming, AddrStream}; fn io_error(error: String) -> io::Error { io::Error::other(error) } // Load public certificate from file. - fn load_certs(filename: &str) -> io::Result> { + fn load_certs(filename: &str) -> io::Result>> { // Open certificate file. - let certfile = fs::read(filename) + let certfile = fs::File::open(filename) .map_err(|error| io_error(format!("failed to open {filename}: {error}")))?; - + let mut reader = io::BufReader::new(certfile); // Load and return certificate. - let certs = rustls_pemfile::certs(&mut certfile.as_ref()) - .map_err(|_| io_error("failed to load certificate".to_string()))?; - Ok(certs.into_iter().map(rustls::Certificate).collect()) + rustls_pemfile::certs(&mut reader).collect() } // Load private key from file. - fn load_private_key(filename: &str) -> io::Result { + fn load_private_key(filename: &str) -> io::Result> { // Open keyfile. - let keyfile = fs::read(filename) + let keyfile = fs::File::open(filename) .map_err(|error| io_error(format!("failed to open {filename}: {error}")))?; + let mut reader = io::BufReader::new(keyfile); // Load and return a single private key. - let keys = rustls_pemfile::pkcs8_private_keys(&mut keyfile.as_ref()) - .map_err(|_| io_error("failed to load private key".to_string()))?; - - if keys.len() != 1 { - return Err(io_error(format!( - "expected a single private key, got {}", - keys.len() - ))); - } - - Ok(rustls::PrivateKey(keys[0].clone())) - } - - pub struct TlsAcceptor { - config: Arc, - incoming: AddrIncoming, - } - - impl TlsAcceptor { - pub fn new(config: Arc, incoming: AddrIncoming) -> TlsAcceptor { - TlsAcceptor { config, incoming } - } - } - - impl Accept for TlsAcceptor { - type Conn = TlsStream; - type Error = io::Error; - - fn poll_accept( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Poll>> { - let pin = self.get_mut(); - match ready!(Pin::new(&mut pin.incoming).poll_accept(cx)) { - Some(Ok(sock)) => Poll::Ready(Some(Ok(TlsStream::new(sock, pin.config.clone())))), - Some(Err(e)) => Poll::Ready(Some(Err(e))), - None => Poll::Ready(None), - } - } - } - - enum State { - Handshaking(tokio_rustls::Accept), - Streaming(tokio_rustls::server::TlsStream), - } - - // tokio_rustls::server::TlsStream doesn't expose constructor methods, - // so we have to TlsAcceptor::accept and handshake to have access to it - // TlsStream implements AsyncRead/AsyncWrite handshaking tokio_rustls::Accept first - pub struct TlsStream { - state: State, - } - - impl TlsStream { - fn new(stream: AddrStream, config: Arc) -> TlsStream { - let accept = tokio_rustls::TlsAcceptor::from(config).accept(stream); - TlsStream { - state: State::Handshaking(accept), - } - } - } - - impl AsyncRead for TlsStream { - fn poll_read( - self: Pin<&mut Self>, - cx: &mut Context, - buf: &mut ReadBuf, - ) -> Poll> { - let pin = self.get_mut(); - match pin.state { - State::Handshaking(ref mut accept) => match ready!(Pin::new(accept).poll(cx)) { - Ok(mut stream) => { - let result = Pin::new(&mut stream).poll_read(cx, buf); - pin.state = State::Streaming(stream); - result - } - Err(err) => Poll::Ready(Err(err)), - }, - State::Streaming(ref mut stream) => Pin::new(stream).poll_read(cx, buf), - } - } - } - - impl AsyncWrite for TlsStream { - fn poll_write( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - buf: &[u8], - ) -> Poll> { - let pin = self.get_mut(); - match pin.state { - State::Handshaking(ref mut accept) => match ready!(Pin::new(accept).poll(cx)) { - Ok(mut stream) => { - let result = Pin::new(&mut stream).poll_write(cx, buf); - pin.state = State::Streaming(stream); - result - } - Err(err) => Poll::Ready(Err(err)), - }, - State::Streaming(ref mut stream) => Pin::new(stream).poll_write(cx, buf), - } - } - - fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - match self.state { - State::Handshaking(_) => Poll::Ready(Ok(())), - State::Streaming(ref mut stream) => Pin::new(stream).poll_flush(cx), - } - } - - fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - match self.state { - State::Handshaking(_) => Poll::Ready(Ok(())), - State::Streaming(ref mut stream) => Pin::new(stream).poll_shutdown(cx), - } - } + rustls_pemfile::private_key(&mut reader).map(|key| key.unwrap()) } pub fn make_rustls_config(config: &TlsConfig) -> anyhow::Result> { @@ -645,7 +554,6 @@ mod tls { } let mut cfg = rustls::ServerConfig::builder() - .with_safe_defaults() .with_no_client_auth() .with_single_cert(certs, key) .map_err(|error| io_error(error.to_string()))?; @@ -655,50 +563,6 @@ mod tls { } } -enum EitherIncoming { - Left(L), - Right(R), -} - -impl EitherIncoming { - pub fn as_pin_mut(self: Pin<&mut Self>) -> EitherIncoming, Pin<&mut R>> { - // SAFETY: `get_unchecked_mut` is fine because we don't move anything. - // We can use `new_unchecked` because the `inner` parts are guaranteed - // to be pinned, as they come from `self` which is pinned, and we never - // offer an unpinned `&mut A` or `&mut B` through `Pin<&mut Self>`. We - // also don't have an implementation of `Drop`, nor manual `Unpin`. - unsafe { - match self.get_unchecked_mut() { - EitherIncoming::Left(inner) => EitherIncoming::Left(Pin::new_unchecked(inner)), - EitherIncoming::Right(inner) => EitherIncoming::Right(Pin::new_unchecked(inner)), - } - } - } -} - -impl Accept for EitherIncoming -where - L: Accept, - R: Accept, -{ - type Conn = tokio_util::either::Either; - type Error = E; - - fn poll_accept( - self: Pin<&mut Self>, - cx: &mut std::task::Context<'_>, - ) -> std::task::Poll>> { - match self.as_pin_mut() { - EitherIncoming::Left(l) => l - .poll_accept(cx) - .map(|opt| opt.map(|res| res.map(tokio_util::either::Either::Left))), - EitherIncoming::Right(r) => r - .poll_accept(cx) - .map(|opt| opt.map(|res| res.map(tokio_util::either::Either::Right))), - } - } -} - #[cfg(test)] mod tests { use std::future::Future; diff --git a/quickwit/quickwit-serve/src/rest_api_response.rs b/quickwit/quickwit-serve/src/rest_api_response.rs index 3efd8158971..0bf56f831f0 100644 --- a/quickwit/quickwit-serve/src/rest_api_response.rs +++ b/quickwit/quickwit-serve/src/rest_api_response.rs @@ -40,9 +40,7 @@ pub(crate) fn into_rest_api_response( body_format: BodyFormat, ) -> RestApiResponse { let rest_api_result = result.map_err(|error| RestApiError { - status_code: crate::convert_status_code_to_legacy_http( - error.error_code().http_status_code(), - ), + status_code: error.error_code().http_status_code(), message: error.to_string(), }); let status_code = match &rest_api_result { diff --git a/quickwit/quickwit-serve/src/search_api/rest_handler.rs b/quickwit/quickwit-serve/src/search_api/rest_handler.rs index 557942ff668..6bc33186f89 100644 --- a/quickwit/quickwit-serve/src/search_api/rest_handler.rs +++ b/quickwit/quickwit-serve/src/search_api/rest_handler.rs @@ -298,7 +298,7 @@ fn search_get_filter() warp::path!(String / "search") .and_then(extract_index_id_patterns) .and(warp::get()) - .and(serde_qs::warp::query(serde_qs::Config::default())) + .and(warp::query()) } fn search_post_filter() @@ -315,7 +315,7 @@ fn search_plan_get_filter() warp::path!(String / "search-plan") .and_then(extract_index_id_patterns) .and(warp::get()) - .and(serde_qs::warp::query(serde_qs::Config::default())) + .and(warp::query()) } fn search_plan_post_filter() @@ -866,7 +866,7 @@ mod tests { .unwrap() .as_str() .unwrap() - .contains("unknown field `end_unix_timestamp`") + .contains("Invalid query string") ); } diff --git a/quickwit/quickwit-serve/src/ui_handler.rs b/quickwit/quickwit-serve/src/ui_handler.rs index 76743a73047..c6f748d9da7 100644 --- a/quickwit/quickwit-serve/src/ui_handler.rs +++ b/quickwit/quickwit-serve/src/ui_handler.rs @@ -60,7 +60,7 @@ async fn serve_impl(path: &str) -> Result, Rejection> { let asset = Asset::get(path_to_file).ok_or_else(warp::reject::not_found)?; let mime = mime_guess::from_path(path_to_file).first_or_octet_stream(); - let mut res = Response::new(asset.data.into()); + let mut res = Response::new(asset.data.into_owned().into()); res.headers_mut().insert( "content-type", HeaderValue::from_str(mime.as_ref()).unwrap(),