From b57c3f3318bbbe68267966a0a21b4cae17f2254f Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Tue, 4 Jun 2024 12:52:26 -0400 Subject: [PATCH 01/29] upgrade to hyper v1 This defines a `dropshot::Body` type that is used for both requests and responses, in place of the now-gone `hyper::Body`. --- Cargo.lock | 137 ++++++++++----- dropshot/Cargo.toml | 14 +- dropshot/examples/file_server.rs | 10 +- dropshot/examples/index.rs | 2 +- dropshot/examples/multipart.rs | 2 +- dropshot/src/api_description.rs | 2 +- dropshot/src/body.rs | 121 ++++++++++++++ dropshot/src/error.rs | 2 +- dropshot/src/extractor/body.rs | 44 ++--- dropshot/src/extractor/common.rs | 12 +- dropshot/src/extractor/raw_request.rs | 6 +- dropshot/src/handler.rs | 26 +-- dropshot/src/http_util.rs | 11 +- dropshot/src/lib.rs | 5 +- dropshot/src/router.rs | 2 +- dropshot/src/server.rs | 201 ++++++++++++++--------- dropshot/src/test_util.rs | 69 +++++--- dropshot/src/websocket.rs | 19 ++- dropshot/tests/fail/bad_channel17.stderr | 2 +- dropshot/tests/fail/bad_channel18.stderr | 2 +- dropshot/tests/fail/bad_channel19.stderr | 2 +- dropshot/tests/test_config.rs | 73 ++++++-- dropshot/tests/test_demo.rs | 6 +- dropshot/tests/test_detached_shutdown.rs | 2 +- dropshot/tests/test_multipart.rs | 3 +- dropshot/tests/test_openapi.rs | 4 +- dropshot/tests/test_pagination.rs | 8 +- dropshot/tests/test_streaming.rs | 31 ++-- dropshot/tests/test_tls.rs | 36 ++-- 29 files changed, 584 insertions(+), 270 deletions(-) create mode 100644 dropshot/src/body.rs diff --git a/Cargo.lock b/Cargo.lock index e14b5fa1b..056cd6ab2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -355,10 +355,12 @@ dependencies = [ "form_urlencoded", "futures", "hostname 0.4.0", - "http 0.2.9", + "http", + "http-body-util", "hyper", "hyper-rustls", "hyper-staticfile", + "hyper-util", "indexmap", "lazy_static", "libc", @@ -647,16 +649,16 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.26" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +checksum = "816ec7294445779408f36fe57bc5b7fc1cf59664059096c65f905c1c61f58069" dependencies = [ "bytes", "fnv", "futures-core", "futures-sink", "futures-util", - "http 0.2.9", + "http", "indexmap", "slab", "tokio", @@ -709,9 +711,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.9" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea" dependencies = [ "bytes", "fnv", @@ -719,24 +721,25 @@ dependencies = [ ] [[package]] -name = "http" +name = "http-body" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" dependencies = [ "bytes", - "fnv", - "itoa", + "http", ] [[package]] -name = "http-body" -version = "0.4.3" +name = "http-body-util" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "399c583b2979440c60be0821a6199eca73bc3c8dcd9d070d75ac726e2c6186e5" +checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" dependencies = [ "bytes", - "http 0.2.9", + "futures-core", + "http", + "http-body", "pin-project-lite", ] @@ -760,53 +763,52 @@ checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440" [[package]] name = "hyper" -version = "0.14.27" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +checksum = "9f24ce812868d86d19daa79bf3bf9175bc44ea323391147a5e3abde2a283871b" dependencies = [ "bytes", "futures-channel", - "futures-core", "futures-util", "h2", - "http 0.2.9", + "http", "http-body", "httparse", "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.9", + "smallvec", "tokio", - "tower-service", - "tracing", "want", ] [[package]] name = "hyper-rustls" -version = "0.25.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "399c78f9338483cb7e630c8474b07268983c6bd5acee012e4211f9f7bb21b070" +checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c" dependencies = [ "futures-util", - "http 0.2.9", + "http", "hyper", + "hyper-util", "log", "rustls", "rustls-native-certs", "rustls-pki-types", "tokio", "tokio-rustls", + "tower-service", ] [[package]] name = "hyper-staticfile" -version = "0.9.5" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "318ca89e4827e7fe4ddd2824f52337239796ae8ecc761a663324407dc3d8d7e7" +checksum = "847250e0ccf0c0537daf49fc5c5ff69d43a752edbabc5274bc8322e8b092c55e" dependencies = [ "futures-util", - "http 0.2.9", + "http", "http-range", "httpdate", "hyper", @@ -818,6 +820,26 @@ dependencies = [ "winapi", ] +[[package]] +name = "hyper-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b875924a60b96e5d7b9ae7b066540b1dd1cbd90d1828f54c92e02a283351c56" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "pin-project-lite", + "socket2", + "tokio", + "tower", + "tower-service", + "tracing", +] + [[package]] name = "iana-time-zone" version = "0.1.47" @@ -989,7 +1011,7 @@ dependencies = [ "bytes", "encoding_rs", "futures-util", - "http 1.0.0", + "http", "httparse", "memchr", "mime", @@ -1162,6 +1184,26 @@ dependencies = [ "sha2", ] +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "pin-project-lite" version = "0.2.12" @@ -1691,19 +1733,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.7.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" - -[[package]] -name = "socket2" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" -dependencies = [ - "libc", - "winapi", -] +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" @@ -1897,7 +1929,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.5", + "socket2", "tokio-macros", "windows-sys 0.48.0", ] @@ -1984,6 +2016,27 @@ dependencies = [ "winnow", ] +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + [[package]] name = "tower-service" version = "0.3.1" @@ -2038,7 +2091,7 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http 1.0.0", + "http", "httparse", "log", "rand", diff --git a/dropshot/Cargo.toml b/dropshot/Cargo.toml index b39da231e..1845620f8 100644 --- a/dropshot/Cargo.toml +++ b/dropshot/Cargo.toml @@ -23,7 +23,8 @@ debug-ignore = "1.0.5" form_urlencoded = "1.2.1" futures = "0.3.30" hostname = "0.4.0" -http = "0.2.9" +http = "1" +http-body-util = "0.1.1" indexmap = "2.2.6" multer = "3.1.0" paste = "1.0.15" @@ -54,7 +55,11 @@ version = "^0.10.2-dev" path = "../dropshot_endpoint" [dependencies.hyper] -version = "0.14" +version = "1" +features = [ "full" ] + +[dependencies.hyper-util] +version = "0.1.5" features = [ "full" ] [dependencies.openapiv3] @@ -86,8 +91,8 @@ features = [ "uuid1" ] async-channel = "2.3.1" buf-list = "1.0.3" expectorate = "1.1.0" -hyper-rustls = "0.25.0" -hyper-staticfile = "0.9" +hyper-rustls = "0.26.0" +hyper-staticfile = "0.10" lazy_static = "1.5.0" libc = "0.2.155" mime_guess = "2.0.4" @@ -120,3 +125,4 @@ version_check = "0.9.4" [features] usdt-probes = ["usdt/asm"] + diff --git a/dropshot/examples/file_server.rs b/dropshot/examples/file_server.rs index df9392496..c9d6fdd9a 100644 --- a/dropshot/examples/file_server.rs +++ b/dropshot/examples/file_server.rs @@ -3,6 +3,7 @@ //! Example using Dropshot to serve files use dropshot::ApiDescription; +use dropshot::Body; use dropshot::ConfigLogging; use dropshot::ConfigLoggingLevel; use dropshot::HttpError; @@ -10,7 +11,6 @@ use dropshot::HttpServerStarter; use dropshot::RequestContext; use dropshot::{endpoint, Path}; use http::{Response, StatusCode}; -use hyper::Body; use schemars::JsonSchema; use serde::Deserialize; use std::path::PathBuf; @@ -133,7 +133,11 @@ async fn static_content( format!("failed to read file {:?}: {:#}", entry, e), ) })?; - let file_stream = hyper_staticfile::FileBytesStream::new(file); + + let file_access = hyper_staticfile::vfs::TokioFileAccess::new(file); + let file_stream = + hyper_staticfile::util::FileBytesStream::new(file_access); + let body = Body::wrap(hyper_staticfile::Body::Full(file_stream)); // Derive the MIME type from the file name let content_type = mime_guess::from_path(&entry) @@ -143,7 +147,7 @@ async fn static_content( Ok(Response::builder() .status(StatusCode::OK) .header(http::header::CONTENT_TYPE, content_type) - .body(file_stream.into_body())?) + .body(body)?) } } diff --git a/dropshot/examples/index.rs b/dropshot/examples/index.rs index 48d3b74e8..1fceee5e5 100644 --- a/dropshot/examples/index.rs +++ b/dropshot/examples/index.rs @@ -2,6 +2,7 @@ //! Example use of Dropshot for matching wildcard paths to serve static content. use dropshot::ApiDescription; +use dropshot::Body; use dropshot::ConfigDropshot; use dropshot::ConfigLogging; use dropshot::ConfigLoggingLevel; @@ -10,7 +11,6 @@ use dropshot::HttpServerStarter; use dropshot::RequestContext; use dropshot::{endpoint, Path}; use http::{Response, StatusCode}; -use hyper::Body; use schemars::JsonSchema; use serde::Deserialize; diff --git a/dropshot/examples/multipart.rs b/dropshot/examples/multipart.rs index 8080d7aa1..b61649db4 100644 --- a/dropshot/examples/multipart.rs +++ b/dropshot/examples/multipart.rs @@ -3,6 +3,7 @@ use dropshot::endpoint; use dropshot::ApiDescription; +use dropshot::Body; use dropshot::ConfigDropshot; use dropshot::ConfigLogging; use dropshot::ConfigLoggingLevel; @@ -11,7 +12,6 @@ use dropshot::HttpServerStarter; use dropshot::MultipartBody; use dropshot::RequestContext; use http::{Response, StatusCode}; -use hyper::Body; #[tokio::main] async fn main() -> Result<(), String> { diff --git a/dropshot/src/api_description.rs b/dropshot/src/api_description.rs index c6c49623b..305512816 100644 --- a/dropshot/src/api_description.rs +++ b/dropshot/src/api_description.rs @@ -1129,6 +1129,7 @@ mod test { use crate::handler::RequestContext; use crate::ApiDescription; use crate::ApiEndpoint; + use crate::Body; use crate::EndpointTagPolicy; use crate::Path; use crate::Query; @@ -1136,7 +1137,6 @@ mod test { use crate::TagDetails; use crate::CONTENT_TYPE_JSON; use http::Method; - use hyper::Body; use hyper::Response; use openapiv3::OpenAPI; use schemars::JsonSchema; diff --git a/dropshot/src/body.rs b/dropshot/src/body.rs new file mode 100644 index 000000000..3181279ca --- /dev/null +++ b/dropshot/src/body.rs @@ -0,0 +1,121 @@ +use std::pin::Pin; +use std::task::{Context, Poll}; + +use http_body_util::combinators::BoxBody; +use http_body_util::BodyExt; +use hyper::body::{Body as HttpBody, Bytes, Frame}; + +type BoxError = Box; + +#[derive(Debug)] +pub struct Body { + inner: BoxBody, +} + +#[derive(Debug)] +pub(crate) struct DataStream(Body); + +impl Body { + /// Create an empty body. + pub fn empty() -> Self { + let inner = http_body_util::Empty::new() + .map_err(|never| match never {}) + .boxed(); + Body { inner } + } + + /// Create a full body from a specific buffer. + pub fn full(buf: impl Into) -> Self { + let inner = http_body_util::Full::new(buf.into()) + .map_err(|never| match never {}) + .boxed(); + Body { inner } + } + + /// Wrap any body as a dropshot Body. + pub fn wrap(under: B) -> Self + where + B: HttpBody + Send + Sync + 'static, + B::Error: Into, + { + let inner = under.map_err(Into::into).boxed(); + Body { inner } + } + + /// Converts this body into an `impl Stream` of only the data frames. + pub(crate) fn into_data_stream(self) -> DataStream { + DataStream(self) + } +} + +impl Default for Body { + fn default() -> Body { + Body::empty() + } +} + +impl From for Body { + fn from(b: Bytes) -> Body { + Body::full(b) + } +} + +impl From> for Body { + fn from(s: Vec) -> Body { + Body::full(s) + } +} + +impl From for Body { + fn from(s: String) -> Body { + Body::full(s) + } +} + +impl From<&'static str> for Body { + fn from(s: &'static str) -> Body { + Body::full(s) + } +} + +impl HttpBody for Body { + type Data = Bytes; + type Error = BoxError; + + #[inline] + fn poll_frame( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll, Self::Error>>> { + Pin::new(&mut self.inner).poll_frame(cx) + } + + #[inline] + fn size_hint(&self) -> hyper::body::SizeHint { + self.inner.size_hint() + } + + #[inline] + fn is_end_stream(&self) -> bool { + self.inner.is_end_stream() + } +} + +impl futures::Stream for DataStream { + type Item = Result; + + fn poll_next( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + loop { + match futures::ready!(Pin::new(&mut self.0).poll_frame(cx)?) { + Some(frame) => match frame.into_data() { + Ok(data) => return Poll::Ready(Some(Ok(data))), + Err(_frame) => {} + }, + None => return Poll::Ready(None), + } + } + } +} diff --git a/dropshot/src/error.rs b/dropshot/src/error.rs index 7ee2d762b..c550a3053 100644 --- a/dropshot/src/error.rs +++ b/dropshot/src/error.rs @@ -275,7 +275,7 @@ impl HttpError { pub fn into_response( self, request_id: &str, - ) -> hyper::Response { + ) -> hyper::Response { // TODO-hardening: consider handling the operational errors that the // Serde serialization fails or the response construction fails. In // those cases, we should probably try to report this as a serious diff --git a/dropshot/src/extractor/body.rs b/dropshot/src/extractor/body.rs index 52757a28a..db474f097 100644 --- a/dropshot/src/extractor/body.rs +++ b/dropshot/src/extractor/body.rs @@ -19,12 +19,11 @@ use bytes::Bytes; use bytes::BytesMut; use futures::Stream; use futures::TryStreamExt; -use hyper::body::HttpBody; +use http_body_util::BodyExt; use schemars::schema::InstanceType; use schemars::schema::SchemaObject; use schemars::JsonSchema; use serde::de::DeserializeOwned; -use std::convert::Infallible; use std::fmt::Debug; // TypedBody: body extractor for formats that can be deserialized to a specific @@ -57,7 +56,7 @@ pub struct MultipartBody { impl ExclusiveExtractor for MultipartBody { async fn from_request( _rqctx: &RequestContext, - request: hyper::Request, + request: hyper::Request, ) -> Result { let (parts, body) = request.into_parts(); // Get the content-type header. @@ -87,7 +86,10 @@ impl ExclusiveExtractor for MultipartBody { ) })?; Ok(MultipartBody { - content: multer::Multipart::new(body, boundary.to_string()), + content: multer::Multipart::new( + body.into_data_stream(), + boundary.to_string(), + ), }) } @@ -121,7 +123,7 @@ impl ExclusiveExtractor for MultipartBody { /// to the content type, and deserialize it to an instance of `BodyType`. async fn http_request_load_body( rqctx: &RequestContext, - request: hyper::Request, + request: hyper::Request, ) -> Result, HttpError> where BodyType: JsonSchema + DeserializeOwned + Send + Sync, @@ -204,7 +206,7 @@ where { async fn from_request( rqctx: &RequestContext, - request: hyper::Request, + request: hyper::Request, ) -> Result, HttpError> { http_request_load_body(rqctx, request).await } @@ -258,7 +260,7 @@ impl UntypedBody { impl ExclusiveExtractor for UntypedBody { async fn from_request( rqctx: &RequestContext, - request: hyper::Request, + request: hyper::Request, ) -> Result { let server = &rqctx.server; let body = request.into_body(); @@ -282,12 +284,12 @@ impl ExclusiveExtractor for UntypedBody { /// raw bytes available to the consumer. #[derive(Debug)] pub struct StreamingBody { - body: hyper::Body, + body: crate::Body, cap: usize, } impl StreamingBody { - fn new(body: hyper::Body, cap: usize) -> Self { + fn new(body: crate::Body, cap: usize) -> Self { Self { body, cap } } @@ -295,8 +297,7 @@ impl StreamingBody { #[doc(hidden)] pub fn __from_bytes(data: Bytes) -> Self { let cap = data.len(); - let stream = futures::stream::iter([Ok::<_, Infallible>(data)]); - let body = hyper::Body::wrap_stream(stream); + let body = crate::Body::from(data); Self { body, cap } } @@ -377,12 +378,21 @@ impl StreamingBody { ) -> impl Stream> + Send { async_stream::try_stream! { let mut bytes_read: usize = 0; - while let Some(buf_res) = self.body.data().await { - let buf = buf_res?; + while let Some(frame_res) = self.body.frame().await { + let frame = frame_res.map_err(|e| HttpError::for_bad_request( + None, + format!("error streaming request body: {}", e), + ))?; + let Ok(buf) = frame.into_data() else { continue }; // skip trailers let len = buf.len(); if bytes_read + len > self.cap { - http_dump_body(&mut self.body).await?; + http_dump_body(&mut self.body).await.map_err(|e| { + HttpError::for_bad_request( + None, + format!("error streaming request body: {}", e), + ) + })?; // TODO-correctness check status code Err(HttpError::for_bad_request( None, @@ -393,10 +403,6 @@ impl StreamingBody { bytes_read += len; yield buf; } - - // Read the trailers as well, even though we're not going to do anything - // with them. - self.body.trailers().await?; } } @@ -417,7 +423,7 @@ impl StreamingBody { impl ExclusiveExtractor for StreamingBody { async fn from_request( rqctx: &RequestContext, - request: hyper::Request, + request: hyper::Request, ) -> Result { let server = &rqctx.server; diff --git a/dropshot/src/extractor/common.rs b/dropshot/src/extractor/common.rs index 2eec965af..31f964506 100644 --- a/dropshot/src/extractor/common.rs +++ b/dropshot/src/extractor/common.rs @@ -25,7 +25,7 @@ pub trait ExclusiveExtractor: Send + Sync + Sized { /// Construct an instance of this type from a `RequestContext`. async fn from_request( rqctx: &RequestContext, - request: hyper::Request, + request: hyper::Request, ) -> Result; fn metadata( @@ -56,7 +56,7 @@ pub trait SharedExtractor: Send + Sync + Sized { impl ExclusiveExtractor for S { async fn from_request( rqctx: &RequestContext, - _request: hyper::Request, + _request: hyper::Request, ) -> Result { ::from_request(rqctx).await } @@ -96,7 +96,7 @@ pub trait RequestExtractor: Send + Sync + Sized { /// Construct an instance of this type from a `RequestContext`. async fn from_request( rqctx: &RequestContext, - request: hyper::Request, + request: hyper::Request, ) -> Result; fn metadata( @@ -109,7 +109,7 @@ pub trait RequestExtractor: Send + Sync + Sized { impl RequestExtractor for () { async fn from_request( _rqctx: &RequestContext, - _request: hyper::Request, + _request: hyper::Request, ) -> Result { Ok(()) } @@ -129,7 +129,7 @@ impl RequestExtractor for () { impl RequestExtractor for (X,) { async fn from_request( rqctx: &RequestContext, - request: hyper::Request, + request: hyper::Request, ) -> Result { Ok((X::from_request(rqctx, request).await?,)) } @@ -162,7 +162,7 @@ macro_rules! impl_rqextractor_for_tuple { { async fn from_request( rqctx: &RequestContext, - request: hyper::Request + request: hyper::Request ) -> Result<( $($S,)+ X ), HttpError> { futures::try_join!( diff --git a/dropshot/src/extractor/raw_request.rs b/dropshot/src/extractor/raw_request.rs index be6d31411..4fb52eb49 100644 --- a/dropshot/src/extractor/raw_request.rs +++ b/dropshot/src/extractor/raw_request.rs @@ -13,11 +13,11 @@ use std::fmt::Debug; /// [`hyper::Request`]. #[derive(Debug)] pub struct RawRequest { - request: hyper::Request, + request: hyper::Request, } impl RawRequest { - pub fn into_inner(self) -> hyper::Request { + pub fn into_inner(self) -> hyper::Request { self.request } } @@ -26,7 +26,7 @@ impl RawRequest { impl ExclusiveExtractor for RawRequest { async fn from_request( _rqctx: &RequestContext, - request: hyper::Request, + request: hyper::Request, ) -> Result { Ok(RawRequest { request }) } diff --git a/dropshot/src/handler.rs b/dropshot/src/handler.rs index b17a56b91..111d91f2f 100644 --- a/dropshot/src/handler.rs +++ b/dropshot/src/handler.rs @@ -41,6 +41,7 @@ use crate::api_description::ApiEndpointBodyContentType; use crate::api_description::ApiEndpointHeader; use crate::api_description::ApiEndpointResponse; use crate::api_description::ApiSchemaGenerator; +use crate::body::Body; use crate::pagination::PaginationParams; use crate::router::VariableSet; use crate::schema_util::make_subschema_for; @@ -51,7 +52,6 @@ use crate::to_map::to_map; use async_trait::async_trait; use http::HeaderMap; use http::StatusCode; -use hyper::Body; use hyper::Response; use schemars::JsonSchema; use serde::de::DeserializeOwned; @@ -67,8 +67,10 @@ use std::marker::PhantomData; use std::num::NonZeroU32; use std::sync::Arc; +pub type ResponseBody = Body; + /// Type alias for the result returned by HTTP handler functions. -pub type HttpHandlerResult = Result, HttpError>; +pub type HttpHandlerResult = Result, HttpError>; /// Handle for various interfaces useful during request processing. #[derive(Debug)] @@ -139,7 +141,7 @@ impl RequestInfo { /// /// This is provided for source compatibility. In previous versions of /// Dropshot, `RequestContext.request` was an - /// `Arc>>`. Now, it's just + /// `Arc>>`. Now, it's just /// `RequestInfo`, which provides many of the same functions as /// `hyper::Request` does. Consumers _should_ just use `rqctx.request` /// instead of this function. @@ -374,7 +376,7 @@ pub trait RouteHandler: Debug + Send + Sync { async fn handle_request( &self, rqctx: RequestContext, - request: hyper::Request, + request: hyper::Request, ) -> HttpHandlerResult; } @@ -437,7 +439,7 @@ where async fn handle_request( &self, rqctx: RequestContext, - request: hyper::Request, + request: hyper::Request, ) -> HttpHandlerResult { // This is where the magic happens: in the code below, `funcparams` has // type `FuncParams`, which is a tuple type describing the extractor @@ -499,8 +501,8 @@ where // See the discussion on macro `impl_HttpHandlerFunc_for_func_with_params` for a // great deal of context on this. -/// HttpResponse must produce a `Result, HttpError>` and generate -/// the response metadata. Typically one should use `Response` or an +/// HttpResponse must produce a `Result, HttpError>` and generate +/// the response metadata. Typically one should use `Response` or an /// implementation of `HttpTypedResponse`. pub trait HttpResponse { /// Generate the response to the HTTP call. @@ -513,7 +515,7 @@ pub trait HttpResponse { /// `Response` is used for free-form responses. The implementation of /// `to_result()` is trivial, and we don't have any typed metadata to return. -impl HttpResponse for Response { +impl HttpResponse for Response { fn to_result(self) -> HttpHandlerResult { Ok(self) } @@ -522,12 +524,12 @@ impl HttpResponse for Response { } } -/// Wraps a [hyper::Body] so that it can be used with coded response types such +/// Wraps a [dropshot::Body] so that it can be used with coded response types such /// as [HttpResponseOk]. -pub struct FreeformBody(pub Body); +pub struct FreeformBody(pub ResponseBody); -impl From for FreeformBody { - fn from(body: Body) -> Self { +impl From for FreeformBody { + fn from(body: ResponseBody) -> Self { Self(body) } } diff --git a/dropshot/src/http_util.rs b/dropshot/src/http_util.rs index c2f87f7af..8c454ed47 100644 --- a/dropshot/src/http_util.rs +++ b/dropshot/src/http_util.rs @@ -2,7 +2,8 @@ //! General-purpose HTTP-related facilities use bytes::Bytes; -use hyper::body::HttpBody; +use http_body_util::BodyExt; +use hyper::body::Body as HttpBody; use serde::de::DeserializeOwned; use super::error::HttpError; @@ -35,9 +36,11 @@ where // TODO better understand pin_mut!() // TODO do we need to use saturating_add() here? let mut nbytesread: usize = 0; - while let Some(maybebuf) = body.data().await { - let buf = maybebuf?; - nbytesread += buf.len(); + while let Some(maybefr) = body.frame().await { + let fr = maybefr?; + if let Ok(buf) = fr.into_data() { + nbytesread += buf.len(); + } } // TODO-correctness why does the is_end_stream() assertion fail? diff --git a/dropshot/src/lib.rs b/dropshot/src/lib.rs index 3bd18d81a..ad987fb8f 100644 --- a/dropshot/src/lib.rs +++ b/dropshot/src/lib.rs @@ -264,7 +264,7 @@ //! use dropshot::TypedBody; //! use dropshot::Query; //! use dropshot::RequestContext; -//! use hyper::Body; +//! use dropshot::Body; //! use hyper::Response; //! use schemars::JsonSchema; //! use serde::Deserialize; @@ -578,6 +578,7 @@ mod dtrace; mod api_description; +mod body; mod config; mod error; mod extractor; @@ -610,6 +611,7 @@ pub use api_description::OpenApiDefinition; pub use api_description::TagConfig; pub use api_description::TagDetails; pub use api_description::TagExternalDocs; +pub use body::Body; pub use config::ConfigDropshot; pub use config::ConfigTls; pub use config::HandlerTaskMode; @@ -664,7 +666,6 @@ pub use server::ShutdownWaitFuture; pub use server::{HttpServer, HttpServerStarter}; pub use websocket::WebsocketChannelResult; pub use websocket::WebsocketConnection; -pub use websocket::WebsocketConnectionRaw; pub use websocket::WebsocketEndpointResult; pub use websocket::WebsocketUpgrade; diff --git a/dropshot/src/router.rs b/dropshot/src/router.rs index 9bb578707..41149c3b5 100644 --- a/dropshot/src/router.rs +++ b/dropshot/src/router.rs @@ -733,9 +733,9 @@ mod test { use crate::router::VariableValue; use crate::ApiEndpoint; use crate::ApiEndpointResponse; + use crate::Body; use http::Method; use http::StatusCode; - use hyper::Body; use hyper::Response; use serde::Deserialize; use std::collections::BTreeMap; diff --git a/dropshot/src/server.rs b/dropshot/src/server.rs index 3bee0d27b..d7f11e09b 100644 --- a/dropshot/src/server.rs +++ b/dropshot/src/server.rs @@ -6,7 +6,7 @@ use super::config::{ConfigDropshot, ConfigTls}; #[cfg(feature = "usdt-probes")] use super::dtrace::probes; use super::error::HttpError; -use super::handler::RequestContext; +use super::handler::{RequestContext, ResponseBody}; use super::http_util::HEADER_REQUEST_ID; use super::router::HttpRouter; use super::ProbeRegistration; @@ -18,12 +18,7 @@ use futures::future::{ }; use futures::lock::Mutex; use futures::stream::{Stream, StreamExt}; -use hyper::server::{ - conn::{AddrIncoming, AddrStream}, - Server, -}; use hyper::service::Service; -use hyper::Body; use hyper::Request; use hyper::Response; use rustls; @@ -188,18 +183,21 @@ impl HttpServerStarter { WrappedHttpServerStarter::Https(https) => { https.start(rx, log_close) } - } + }; + /* .map(|r| { r.map_err(|e| format!("waiting for server: {e}"))? .map_err(|e| format!("server stopped: {e}")) - }); + })*/ info!(self.app_state.log, "listening"); let handler_waitgroup = self.handler_waitgroup; let join_handle = async move { // After the server shuts down, we also want to wait for any // detached handler futures to complete. - () = join_handle.await?; + () = join_handle + .await + .map_err(|e| format!("server stopped: {e}"))?; () = handler_waitgroup.wait().await; Ok(()) }; @@ -247,7 +245,8 @@ enum WrappedHttpServerStarter { } struct InnerHttpServerStarter( - Server>, + TcpListener, + ServerConnectionHandler, ); type InnerHttpServerStarterNewReturn = @@ -257,17 +256,41 @@ impl InnerHttpServerStarter { /// Begins execution of the underlying Http server. fn start( self, - close_signal: tokio::sync::oneshot::Receiver<()>, + mut close_signal: tokio::sync::oneshot::Receiver<()>, log_close: Logger, - ) -> tokio::task::JoinHandle> { - let graceful = self.0.with_graceful_shutdown(async move { - close_signal.await.expect( - "dropshot server shutting down without invoking close()", - ); - info!(log_close, "received request to begin graceful shutdown"); - }); + ) -> tokio::task::JoinHandle<()> { + use hyper_util::rt::{TokioExecutor, TokioIo, TokioTimer}; + use hyper_util::server::conn::auto; + + tokio::spawn(async move { + let mut builder = auto::Builder::new(TokioExecutor::new()); + // http/1 settings + builder.http1().timer(TokioTimer::new()); - tokio::spawn(graceful) + let graceful = + hyper_util::server::graceful::GracefulShutdown::new(); + + loop { + tokio::select! { + Ok((sock, remote_addr)) = self.0.accept() => { + let fut = builder.serve_connection_with_upgrades( + TokioIo::new(sock), + self.1.make_svc(remote_addr), + ); + let fut = graceful.watch(fut.into_owned()); + tokio::spawn(fut); + }, + + _ = &mut close_signal => { + info!(log_close, "received request to begin graceful shutdown"); + break; + } + } + } + + // optional: could use another select on a timeout + graceful.shutdown().await + }) } /// Set up an HTTP server bound on the specified address that runs @@ -281,9 +304,11 @@ impl InnerHttpServerStarter { private: C, log: &Logger, handler_waitgroup_worker: waitgroup::Worker, - ) -> Result, hyper::Error> { - let incoming = AddrIncoming::bind(&config.bind_address)?; - let local_addr = incoming.local_addr(); + ) -> Result, std::io::Error> { + let std_listener = std::net::TcpListener::bind(&config.bind_address)?; + std_listener.set_nonblocking(true)?; + let incoming = TcpListener::from_std(std_listener)?; + let local_addr = incoming.local_addr()?; let app_state = Arc::new(DropshotState { private, @@ -296,9 +321,13 @@ impl InnerHttpServerStarter { }); let make_service = ServerConnectionHandler::new(app_state.clone()); - let builder = hyper::Server::builder(incoming); - let server = builder.serve(make_service); - Ok((InnerHttpServerStarter(server), app_state, local_addr)) + //let builder = hyper::Server::builder(incoming); + //let server = builder.serve(make_service); + Ok(( + InnerHttpServerStarter(incoming, make_service), + app_state, + local_addr, + )) } } @@ -386,6 +415,10 @@ impl HttpsAcceptor { } } + async fn accept(&mut self) -> Option> { + self.stream.next().await + } + fn new_stream( log: slog::Logger, tls_acceptor: Arc>, @@ -452,21 +485,9 @@ impl HttpsAcceptor { } } -impl hyper::server::accept::Accept for HttpsAcceptor { - type Conn = TlsConn; - type Error = std::io::Error; - - fn poll_accept( - mut self: Pin<&mut Self>, - ctx: &mut core::task::Context, - ) -> core::task::Poll>> { - let pinned = Pin::new(&mut self.stream); - pinned.poll_next(ctx) - } -} - struct InnerHttpsServerStarter( - Server>, + HttpsAcceptor, + ServerConnectionHandler, ); /// Create a TLS configuration from the Dropshot config structure. @@ -545,18 +566,43 @@ type InnerHttpsServerStarterNewReturn = impl InnerHttpsServerStarter { /// Begins execution of the underlying Http server. fn start( - self, - close_signal: tokio::sync::oneshot::Receiver<()>, + mut self, + mut close_signal: tokio::sync::oneshot::Receiver<()>, log_close: Logger, - ) -> tokio::task::JoinHandle> { - let graceful = self.0.with_graceful_shutdown(async move { - close_signal.await.expect( - "dropshot server shutting down without invoking close()", - ); - info!(log_close, "received request to begin graceful shutdown"); - }); + ) -> tokio::task::JoinHandle<()> { + use hyper_util::rt::{TokioExecutor, TokioIo, TokioTimer}; + use hyper_util::server::conn::auto; + + tokio::spawn(async move { + let mut builder = auto::Builder::new(TokioExecutor::new()); + // http/1 settings + builder.http1().timer(TokioTimer::new()); + + let graceful = + hyper_util::server::graceful::GracefulShutdown::new(); + + loop { + tokio::select! { + Some(Ok(sock)) = self.0.accept() => { + let remote_addr = sock.remote_addr(); + let fut = builder.serve_connection_with_upgrades( + TokioIo::new(sock), + self.1.make_svc(remote_addr), + ); + let fut = graceful.watch(fut.into_owned()); + tokio::spawn(fut); + }, + + _ = &mut close_signal => { + info!(log_close, "received request to begin graceful shutdown"); + break; + } + } + } - tokio::spawn(graceful) + // optional: could use another select on a timeout + graceful.shutdown().await + }) } fn new( @@ -597,9 +643,13 @@ impl InnerHttpsServerStarter { }); let make_service = ServerConnectionHandler::new(Arc::clone(&app_state)); - let server = Server::builder(https_acceptor).serve(make_service); + //let server = Server::builder(https_acceptor).serve(make_service); - Ok((InnerHttpsServerStarter(server), app_state, local_addr)) + Ok(( + InnerHttpsServerStarter(https_acceptor, make_service), + app_state, + local_addr, + )) } } @@ -608,14 +658,7 @@ impl Service<&TlsConn> for ServerConnectionHandler { type Error = GenericError; type Future = BoxFuture<'static, Result>; - fn poll_ready( - &mut self, - _ctx: &mut Context<'_>, - ) -> Poll> { - Poll::Ready(Ok(())) - } - - fn call(&mut self, conn: &TlsConn) -> Self::Future { + fn call(&self, conn: &TlsConn) -> Self::Future { let server = Arc::clone(&self.server); let remote_addr = conn.remote_addr(); Box::pin(http_connection_handle(server, remote_addr)) @@ -774,8 +817,8 @@ async fn http_connection_handle( async fn http_request_handle_wrap( server: Arc>, remote_addr: SocketAddr, - request: Request, -) -> Result, GenericError> { + request: Request, +) -> Result, GenericError> { // This extra level of indirection makes error handling much more // straightforward, since the request handling code can simply return early // with an error and we'll treat it like an error from any of the endpoints @@ -900,17 +943,18 @@ async fn http_request_handle_wrap( async fn http_request_handle( server: Arc>, - request: Request, + request: Request, request_id: &str, request_log: Logger, remote_addr: std::net::SocketAddr, -) -> Result, HttpError> { +) -> Result, HttpError> { // TODO-hardening: is it correct to (and do we correctly) read the entire // request body even if we decide it's too large and are going to send a 400 // response? // TODO-hardening: add a request read timeout as well so that we don't allow // this to take forever. // TODO-correctness: Do we need to dump the body on errors? + let request = request.map(crate::Body::wrap); let method = request.method(); let uri = request.uri(); let lookup_result = @@ -1019,8 +1063,14 @@ impl ServerConnectionHandler { fn new(server: Arc>) -> Self { ServerConnectionHandler { server } } + + fn make_svc(&self, remote_addr: SocketAddr) -> ServerRequestHandler { + info!(self.server.log, "accepted connection"; "remote_addr" => %remote_addr); + ServerRequestHandler::new(self.server.clone(), remote_addr) + } } +/* TODO(SEAN) impl Service<&AddrStream> for ServerConnectionHandler { // Recall that a Service in this context is just something that takes a // request (which could be anything) and produces a response (which could be @@ -1032,14 +1082,6 @@ impl Service<&AddrStream> for ServerConnectionHandler { type Error = GenericError; type Future = BoxFuture<'static, Result>; - fn poll_ready( - &mut self, - _cx: &mut Context<'_>, - ) -> Poll> { - // TODO is this right? - Poll::Ready(Ok(())) - } - fn call(&mut self, conn: &AddrStream) -> Self::Future { // We're given a borrowed reference to the AddrStream, but our interface // is async (which is good, so that we can support time-consuming @@ -1053,6 +1095,7 @@ impl Service<&AddrStream> for ServerConnectionHandler { Box::pin(http_connection_handle(server, remote_addr)) } } +*/ /// ServerRequestHandler is a Hyper Service implementation that forwards /// incoming requests to `http_request_handle_wrap()`, including as an argument @@ -1073,20 +1116,14 @@ impl ServerRequestHandler { } } -impl Service> for ServerRequestHandler { - type Response = Response; +impl Service> + for ServerRequestHandler +{ + type Response = Response; type Error = GenericError; type Future = BoxFuture<'static, Result>; - fn poll_ready( - &mut self, - _cx: &mut Context<'_>, - ) -> Poll> { - // TODO is this right? - Poll::Ready(Ok(())) - } - - fn call(&mut self, req: Request) -> Self::Future { + fn call(&self, req: Request) -> Self::Future { Box::pin(http_request_handle_wrap( Arc::clone(&self.server), self.remote_addr, diff --git a/dropshot/src/test_util.rs b/dropshot/src/test_util.rs index f94eeb35a..404f79fd9 100644 --- a/dropshot/src/test_util.rs +++ b/dropshot/src/test_util.rs @@ -6,14 +6,12 @@ use camino::Utf8PathBuf; use chrono::DateTime; use chrono::Utc; use http::method::Method; -use hyper::body::to_bytes; -use hyper::client::HttpConnector; -use hyper::Body; -use hyper::Client; +use http_body_util::BodyExt as _; use hyper::Request; use hyper::Response; use hyper::StatusCode; use hyper::Uri; +use hyper_util::client::legacy::{connect::HttpConnector, Client}; use serde::de::DeserializeOwned; use serde::Deserialize; use serde::Serialize; @@ -28,6 +26,7 @@ use std::sync::atomic::AtomicU32; use std::sync::atomic::Ordering; use crate::api_description::ApiDescription; +use crate::body::Body; use crate::config::ConfigDropshot; use crate::error::HttpErrorResponseBody; use crate::http_util::CONTENT_TYPE_URL_ENCODED; @@ -77,7 +76,7 @@ pub struct ClientTestContext { /// actual bind address of the HTTP server under test pub bind_address: SocketAddr, /// HTTP client, used for making requests against the test server - pub client: Client, + pub client: Client, /// logger for the test suite HTTP client pub client_log: Logger, } @@ -87,7 +86,8 @@ impl ClientTestContext { pub fn new(server_addr: SocketAddr, log: Logger) -> ClientTestContext { ClientTestContext { bind_address: server_addr, - client: Client::new(), + client: Client::builder(hyper_util::rt::TokioExecutor::new()) + .build(HttpConnector::new()), client_log: log, } } @@ -121,8 +121,8 @@ impl ClientTestContext { path: &str, request_body: Option, expected_status: StatusCode, - ) -> Result, HttpErrorResponseBody> { - let body: Body = match request_body { + ) -> Result, HttpErrorResponseBody> { + let body = match request_body { None => Body::empty(), Some(input) => serde_json::to_string(&input).unwrap().into(), }; @@ -141,7 +141,7 @@ impl ClientTestContext { path: &str, request_body: Option, expected_status: StatusCode, - ) -> Result, HttpErrorResponseBody> { + ) -> Result, HttpErrorResponseBody> { let body: Body = match request_body { None => Body::empty(), Some(input) => serde_urlencoded::to_string(&input).unwrap().into(), @@ -161,7 +161,7 @@ impl ClientTestContext { method: Method, path: &str, expected_status: StatusCode, - ) -> Result, HttpErrorResponseBody> { + ) -> Result, HttpErrorResponseBody> { self.make_request_with_body( method, path, @@ -204,7 +204,7 @@ impl ClientTestContext { path: &str, body: Body, expected_status: StatusCode, - ) -> Result, HttpErrorResponseBody> { + ) -> Result, HttpErrorResponseBody> { let uri = self.url(path); let request = Request::builder() .method(method) @@ -220,7 +220,7 @@ impl ClientTestContext { path: &str, body: Body, expected_status: StatusCode, - ) -> Result, HttpErrorResponseBody> { + ) -> Result, HttpErrorResponseBody> { let uri = self.url(path); let request = Request::builder() .method(method) @@ -235,7 +235,7 @@ impl ClientTestContext { &self, request: Request, expected_status: StatusCode, - ) -> Result, HttpErrorResponseBody> { + ) -> Result, HttpErrorResponseBody> { let time_before = chrono::offset::Utc::now().timestamp(); info!(self.client_log, "client request"; "method" => %request.method(), @@ -320,9 +320,12 @@ impl ClientTestContext { // For "204 No Content" responses, validate that we got no content in // the body. if status == StatusCode::NO_CONTENT { - let body_bytes = to_bytes(response.body_mut()) + let body_bytes = response + .body_mut() + .collect() .await - .expect("error reading body"); + .expect("error reading body") + .to_bytes(); assert_eq!(0, body_bytes.len()); } @@ -519,15 +522,19 @@ impl TestContext { /// asynchronously read the body of the response and parse it accordingly, /// returning a vector of T. pub async fn read_ndjson( - response: &mut Response, + response: &mut Response, ) -> Vec { let headers = response.headers(); assert_eq!( crate::CONTENT_TYPE_NDJSON, headers.get(http::header::CONTENT_TYPE).expect("missing content-type") ); - let body_bytes = - to_bytes(response.body_mut()).await.expect("error reading body"); + let body_bytes = response + .body_mut() + .collect() + .await + .expect("error reading body") + .to_bytes(); let body_string = String::from_utf8(body_bytes.as_ref().into()) .expect("response contained non-UTF-8 bytes"); @@ -549,30 +556,42 @@ pub async fn read_ndjson( /// be parseable via Serde as type T, asynchronously read the body of the /// response and parse it, returning an instance of T. pub async fn read_json( - response: &mut Response, + response: &mut Response, ) -> T { let headers = response.headers(); assert_eq!( crate::CONTENT_TYPE_JSON, headers.get(http::header::CONTENT_TYPE).expect("missing content-type") ); - let body_bytes = - to_bytes(response.body_mut()).await.expect("error reading body"); + let body_bytes = response + .body_mut() + .collect() + .await + .expect("error reading body") + .to_bytes(); serde_json::from_slice(body_bytes.as_ref()) .expect("failed to parse server body as expected type") } /// Given a Hyper Response whose body is expected to be a UTF-8-encoded string, /// asynchronously read the body. -pub async fn read_string(response: &mut Response) -> String { - let body_bytes = - to_bytes(response.body_mut()).await.expect("error reading body"); +pub async fn read_string( + response: &mut Response, +) -> String { + let body_bytes = response + .body_mut() + .collect() + .await + .expect("error reading body") + .to_bytes(); String::from_utf8(body_bytes.as_ref().into()) .expect("response contained non-UTF-8 bytes") } /// Given a Hyper Response, extract and parse the Content-Length header. -pub fn read_content_length(response: &Response) -> usize { +pub fn read_content_length( + response: &Response, +) -> usize { response .headers() .get(http::header::CONTENT_LENGTH) diff --git a/dropshot/src/websocket.rs b/dropshot/src/websocket.rs index dfcea7530..013a20aff 100644 --- a/dropshot/src/websocket.rs +++ b/dropshot/src/websocket.rs @@ -7,6 +7,7 @@ //! which will be spawned to handle the incoming connection. use crate::api_description::ExtensionMode; +use crate::body::Body; use crate::{ ApiEndpointBodyContentType, ExclusiveExtractor, ExtractorMetadata, HttpError, RequestContext, ServerContext, @@ -17,7 +18,6 @@ use http::header; use http::Response; use http::StatusCode; use hyper::upgrade::OnUpgrade; -use hyper::Body; use schemars::JsonSchema; use serde_json::json; use sha1::{Digest, Sha1}; @@ -42,7 +42,8 @@ pub type WebsocketChannelResult = /// [WebsocketUpgrade::handle]'s return type. /// The `#[endpoint]` handler must return the value returned by /// [WebsocketUpgrade::handle]. (This is done for you by `#[channel]`.) -pub type WebsocketEndpointResult = Result, HttpError>; +pub type WebsocketEndpointResult = + Result, HttpError>; /// The upgraded connection passed as the last argument to the websocket /// handler function. [`WebsocketConnection::into_inner`] can be used to @@ -51,11 +52,14 @@ pub type WebsocketEndpointResult = Result, HttpError>; pub struct WebsocketConnection(WebsocketConnectionRaw); /// A type that implements [tokio::io::AsyncRead] + [tokio::io::AsyncWrite]. -pub type WebsocketConnectionRaw = hyper::upgrade::Upgraded; +// Not public, since it uses less-stable hyper-util. +type WebsocketConnectionRaw = hyper_util::rt::TokioIo; impl WebsocketConnection { /// Consumes `self` and returns the held raw connection. - pub fn into_inner(self) -> WebsocketConnectionRaw { + pub fn into_inner( + self, + ) -> impl tokio::io::AsyncRead + tokio::io::AsyncWrite { self.0 } } @@ -87,7 +91,7 @@ fn derive_accept_key(request_key: &[u8]) -> String { impl ExclusiveExtractor for WebsocketUpgrade { async fn from_request( rqctx: &RequestContext, - request: hyper::Request, + request: hyper::Request, ) -> Result { if !request .headers() @@ -229,7 +233,8 @@ impl WebsocketUpgrade { tokio::spawn(async move { match upgrade_fut.await { Ok(upgrade) => { - match handler(WebsocketConnection(upgrade)).await { + let io = hyper_util::rt::TokioIo::new(upgrade); + match handler(WebsocketConnection(io)).await { Ok(x) => Ok(x), Err(e) => { error!( @@ -294,6 +299,7 @@ impl JsonSchema for WebsocketUpgrade { #[cfg(test)] mod tests { + use crate::body::Body; use crate::config::HandlerTaskMode; use crate::router::HttpRouter; use crate::server::{DropshotState, ServerConfig}; @@ -303,7 +309,6 @@ mod tests { }; use debug_ignore::DebugIgnore; use http::Request; - use hyper::Body; use std::net::{IpAddr, Ipv6Addr, SocketAddr}; use std::num::NonZeroU32; use std::sync::Arc; diff --git a/dropshot/tests/fail/bad_channel17.stderr b/dropshot/tests/fail/bad_channel17.stderr index 85d0f0912..4b81fb8ac 100644 --- a/dropshot/tests/fail/bad_channel17.stderr +++ b/dropshot/tests/fail/bad_channel17.stderr @@ -20,7 +20,7 @@ note: required by a bound in `need_shared_extractor` | ------------------- required by a bound in this function = note: this error originates in the attribute macro `channel` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0277]: the trait bound `fn(RequestContext<()>, WebsocketConnection, WebsocketUpgrade) -> impl Future, HttpError>> { for ApiEndpoint< as RequestContextArgument>::Context>>::from::two_websocket_channels}: dropshot::handler::HttpHandlerFunc<_, _, _>` is not satisfied +error[E0277]: the trait bound `fn(RequestContext<()>, WebsocketConnection, WebsocketUpgrade) -> impl Future, HttpError>> { for ApiEndpoint< as RequestContextArgument>::Context>>::from::two_websocket_channels}: dropshot::handler::HttpHandlerFunc<_, _, _>` is not satisfied --> tests/fail/bad_channel17.rs:16:10 | 12 | / #[channel { diff --git a/dropshot/tests/fail/bad_channel18.stderr b/dropshot/tests/fail/bad_channel18.stderr index 66f9dca14..764218b15 100644 --- a/dropshot/tests/fail/bad_channel18.stderr +++ b/dropshot/tests/fail/bad_channel18.stderr @@ -44,7 +44,7 @@ note: required by a bound in `WebsocketUpgrade::handle` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `WebsocketUpgrade::handle` = note: this error originates in the attribute macro `channel` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0277]: the trait bound `fn(RequestContext<()>, WebsocketConnection, WebsocketUpgrade) -> impl Future, HttpError>> { for ApiEndpoint< as RequestContextArgument>::Context>>::from::websocket_channel_not_last}: dropshot::handler::HttpHandlerFunc<_, _, _>` is not satisfied +error[E0277]: the trait bound `fn(RequestContext<()>, WebsocketConnection, WebsocketUpgrade) -> impl Future, HttpError>> { for ApiEndpoint< as RequestContextArgument>::Context>>::from::websocket_channel_not_last}: dropshot::handler::HttpHandlerFunc<_, _, _>` is not satisfied --> tests/fail/bad_channel18.rs:23:10 | 19 | / #[channel { diff --git a/dropshot/tests/fail/bad_channel19.stderr b/dropshot/tests/fail/bad_channel19.stderr index cc546409d..8440b76be 100644 --- a/dropshot/tests/fail/bad_channel19.stderr +++ b/dropshot/tests/fail/bad_channel19.stderr @@ -20,7 +20,7 @@ note: required by a bound in `need_shared_extractor` | ------ required by a bound in this function = note: this error originates in the attribute macro `channel` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0277]: the trait bound `fn(RequestContext<()>, std::string::String, WebsocketUpgrade) -> impl Future, HttpError>> { for ApiEndpoint< as RequestContextArgument>::Context>>::from::non_extractor_as_last_argument}: dropshot::handler::HttpHandlerFunc<_, _, _>` is not satisfied +error[E0277]: the trait bound `fn(RequestContext<()>, std::string::String, WebsocketUpgrade) -> impl Future, HttpError>> { for ApiEndpoint< as RequestContextArgument>::Context>>::from::non_extractor_as_last_argument}: dropshot::handler::HttpHandlerFunc<_, _, _>` is not satisfied --> tests/fail/bad_channel19.rs:23:10 | 19 | / #[channel { diff --git a/dropshot/tests/test_config.rs b/dropshot/tests/test_config.rs index e6a038fdf..b414bd290 100644 --- a/dropshot/tests/test_config.rs +++ b/dropshot/tests/test_config.rs @@ -3,6 +3,7 @@ //! Tests for configuration file. use dropshot::test_util::read_config; +use dropshot::Body; use dropshot::{ ConfigDropshot, ConfigTls, HandlerTaskMode, HttpError, HttpResponseOk, RequestContext, @@ -118,11 +119,15 @@ fn make_config( // test logic trait TestConfigBindServer where - C: hyper::client::connect::Connect + Clone + Send + Sync + 'static, + C: hyper_util::client::legacy::connect::Connect + + Clone + + Send + + Sync + + 'static, { type Context: Send + Sync + 'static; - fn make_client(&self) -> hyper::Client; + fn make_client(&self) -> hyper_util::client::legacy::Client; fn make_server(&self, bind_port: u16) -> HttpServer; fn make_uri(&self, bind_port: u16) -> hyper::Uri; } @@ -131,7 +136,11 @@ where // it binds to ports as expected. async fn test_config_bind_server(test_config: T, bind_port: u16) where - C: hyper::client::connect::Connect + Clone + Send + Sync + 'static, + C: hyper_util::client::legacy::connect::Connect + + Clone + + Send + + Sync + + 'static, T: TestConfigBindServer, { let client = test_config.make_client(); @@ -184,15 +193,22 @@ async fn test_config_bind_address_http() { struct ConfigBindServerHttp { log: slog::Logger, } - impl TestConfigBindServer + impl + TestConfigBindServer for ConfigBindServerHttp { type Context = i32; fn make_client( &self, - ) -> hyper::Client { - hyper::Client::new() + ) -> hyper_util::client::legacy::Client< + hyper_util::client::legacy::connect::HttpConnector, + Body, + > { + hyper_util::client::legacy::Client::builder( + hyper_util::rt::TokioExecutor::new(), + ) + .build(hyper_util::client::legacy::connect::HttpConnector::new()) } fn make_uri(&self, bind_port: u16) -> hyper::Uri { @@ -227,15 +243,20 @@ async fn test_config_bind_address_https() { impl<'a> TestConfigBindServer< - hyper_rustls::HttpsConnector, + hyper_rustls::HttpsConnector< + hyper_util::client::legacy::connect::HttpConnector, + >, > for ConfigBindServerHttps<'a> { type Context = i32; fn make_client( &self, - ) -> hyper::Client< - hyper_rustls::HttpsConnector, + ) -> hyper_util::client::legacy::Client< + hyper_rustls::HttpsConnector< + hyper_util::client::legacy::connect::HttpConnector, + >, + Body, > { // Configure TLS to trust the self-signed cert let mut root_store = rustls::RootCertStore { roots: vec![] }; @@ -251,7 +272,10 @@ async fn test_config_bind_address_https() { .https_only() .enable_http1() .build(); - hyper::Client::builder().build(https_connector) + hyper_util::client::legacy::Client::builder( + hyper_util::rt::TokioExecutor::new(), + ) + .build(https_connector) } fn make_uri(&self, bind_port: u16) -> hyper::Uri { @@ -299,15 +323,20 @@ async fn test_config_bind_address_https_buffer() { impl<'a> TestConfigBindServer< - hyper_rustls::HttpsConnector, + hyper_rustls::HttpsConnector< + hyper_util::client::legacy::connect::HttpConnector, + >, > for ConfigBindServerHttps<'a> { type Context = i32; fn make_client( &self, - ) -> hyper::Client< - hyper_rustls::HttpsConnector, + ) -> hyper_util::client::legacy::Client< + hyper_rustls::HttpsConnector< + hyper_util::client::legacy::connect::HttpConnector, + >, + Body, > { // Configure TLS to trust the self-signed cert let mut root_store = rustls::RootCertStore { roots: vec![] }; @@ -323,7 +352,11 @@ async fn test_config_bind_address_https_buffer() { .https_only() .enable_http1() .build(); - hyper::Client::builder().build(https_connector) + + hyper_util::client::legacy::Client::builder( + hyper_util::rt::TokioExecutor::new(), + ) + .build(https_connector) } fn make_uri(&self, bind_port: u16) -> hyper::Uri { @@ -395,15 +428,21 @@ struct ConfigHandlerTaskModeHttp { log: slog::Logger, } -impl TestConfigBindServer +impl TestConfigBindServer for ConfigHandlerTaskModeHttp { type Context = HandlerTaskModeContext; fn make_client( &self, - ) -> hyper::Client { - hyper::Client::new() + ) -> hyper_util::client::legacy::Client< + hyper_util::client::legacy::connect::HttpConnector, + Body, + > { + hyper_util::client::legacy::Client::builder( + hyper_util::rt::TokioExecutor::new(), + ) + .build(hyper_util::client::legacy::connect::HttpConnector::new()) } fn make_server(&self, bind_port: u16) -> HttpServer { diff --git a/dropshot/tests/test_demo.rs b/dropshot/tests/test_demo.rs index bfc4f0d94..27f2b4d97 100644 --- a/dropshot/tests/test_demo.rs +++ b/dropshot/tests/test_demo.rs @@ -25,6 +25,7 @@ use dropshot::test_util::read_string; use dropshot::test_util::TEST_HEADER_1; use dropshot::test_util::TEST_HEADER_2; use dropshot::ApiDescription; +use dropshot::Body; use dropshot::HttpError; use dropshot::HttpResponseDeleted; use dropshot::HttpResponseFound; @@ -47,7 +48,6 @@ use futures::stream::StreamExt; use futures::SinkExt; use futures::TryStreamExt; use http::StatusCode; -use hyper::Body; use hyper::Method; use hyper::Response; use schemars::JsonSchema; @@ -1255,12 +1255,14 @@ async fn demo_handler_raw_request( _rqctx: RequestContext, raw_request: RawRequest, ) -> Result, HttpError> { + use http_body_util::BodyExt; + let request = raw_request.into_inner(); let (parts, body) = request.into_parts(); // This is not generally a good pattern because it allows untrusted // consumers to use up all memory. This is just a narrow test. - let whole_body = hyper::body::to_bytes(body).await.unwrap(); + let whole_body = body.collect().await.unwrap().to_bytes(); Ok(HttpResponseOk(DemoRaw { nbytes: whole_body.len(), method: parts.method.to_string(), diff --git a/dropshot/tests/test_detached_shutdown.rs b/dropshot/tests/test_detached_shutdown.rs index b5e755ff8..2c11f7fbe 100644 --- a/dropshot/tests/test_detached_shutdown.rs +++ b/dropshot/tests/test_detached_shutdown.rs @@ -3,11 +3,11 @@ //! Test cases for graceful shutdown of a server running tasks in //! `HandlerTaskMode::Detached`. +use dropshot::Body; use dropshot::{ endpoint, ApiDescription, HandlerTaskMode, HttpError, RequestContext, }; use http::{Method, Response, StatusCode}; -use hyper::Body; use std::time::Duration; use tokio::sync::mpsc; diff --git a/dropshot/tests/test_multipart.rs b/dropshot/tests/test_multipart.rs index c9ec51491..3728ce501 100644 --- a/dropshot/tests/test_multipart.rs +++ b/dropshot/tests/test_multipart.rs @@ -4,10 +4,9 @@ use dropshot::test_util::read_string; use dropshot::{ - endpoint, ApiDescription, HttpError, MultipartBody, RequestContext, + endpoint, ApiDescription, Body, HttpError, MultipartBody, RequestContext, }; use http::{Method, Response, StatusCode}; -use hyper::Body; extern crate slog; diff --git a/dropshot/tests/test_openapi.rs b/dropshot/tests/test_openapi.rs index 1f3d8708f..b9be0b31b 100644 --- a/dropshot/tests/test_openapi.rs +++ b/dropshot/tests/test_openapi.rs @@ -1,5 +1,6 @@ // Copyright 2023 Oxide Computer Company +use dropshot::Body; use dropshot::{ endpoint, http_response_found, http_response_see_other, http_response_temporary_redirect, ApiDescription, FreeformBody, HttpError, @@ -9,7 +10,6 @@ use dropshot::{ HttpResponseUpdatedNoContent, MultipartBody, PaginationParams, Path, Query, RequestContext, ResultsPage, TagConfig, TagDetails, TypedBody, UntypedBody, }; -use hyper::Body; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use std::{collections::HashMap, io::Cursor, str::from_utf8}; @@ -361,7 +361,7 @@ async fn handler17( async fn handler18( _rqctx: RequestContext<()>, ) -> Result, HttpError> { - let (_, body) = Body::channel(); + let body = Body::empty(); Ok(HttpResponseOk(body.into())) } diff --git a/dropshot/tests/test_pagination.rs b/dropshot/tests/test_pagination.rs index 0c1fdf64e..51d3d3ab0 100644 --- a/dropshot/tests/test_pagination.rs +++ b/dropshot/tests/test_pagination.rs @@ -11,6 +11,7 @@ use dropshot::test_util::objects_list_page; use dropshot::test_util::ClientTestContext; use dropshot::test_util::LogContext; use dropshot::ApiDescription; +use dropshot::Body; use dropshot::ConfigLogging; use dropshot::ConfigLoggingIfExists; use dropshot::ConfigLoggingLevel; @@ -25,8 +26,6 @@ use dropshot::ResultsPage; use dropshot::WhichPage; use http::Method; use http::StatusCode; -use hyper::Body; -use hyper::Client; use hyper::Request; use schemars::JsonSchema; use serde::de::DeserializeOwned; @@ -832,7 +831,10 @@ async fn start_example(path: &str, port: u16) -> ExampleContext { let server_addr = SocketAddr::from((Ipv4Addr::LOCALHOST, port)); let client = ClientTestContext::new(server_addr, logctx.log.new(o!())); let url = client.url("/"); - let raw_client = Client::new(); + let raw_client = hyper_util::client::legacy::Client::builder( + hyper_util::rt::TokioExecutor::new(), + ) + .build(hyper_util::client::legacy::connect::HttpConnector::new()); let rv = ExampleContext { child, client, logctx: Some(logctx) }; while start.elapsed().as_secs() < 10 { diff --git a/dropshot/tests/test_streaming.rs b/dropshot/tests/test_streaming.rs index d931cc46d..fffa51bef 100644 --- a/dropshot/tests/test_streaming.rs +++ b/dropshot/tests/test_streaming.rs @@ -2,10 +2,10 @@ //! Test cases for streaming requests. +use dropshot::Body; use dropshot::{endpoint, ApiDescription, HttpError, RequestContext}; use http::{Method, Response, StatusCode}; -use hyper::{body::HttpBody, Body}; -use hyper_staticfile::FileBytesStream; +use http_body_util::BodyExt; use tokio::io::{AsyncSeekExt, AsyncWriteExt}; extern crate slog; @@ -46,10 +46,10 @@ async fn api_streaming( } file.seek(std::io::SeekFrom::Start(0)).await.unwrap(); - let file_stream = FileBytesStream::new(file); - Ok(Response::builder() - .status(StatusCode::OK) - .body(file_stream.into_body())?) + let file_access = hyper_staticfile::vfs::TokioFileAccess::new(file); + let file_stream = hyper_staticfile::util::FileBytesStream::new(file_access); + let body = Body::wrap(hyper_staticfile::Body::Full(file_stream)); + Ok(Response::builder().status(StatusCode::OK).body(body)?) } #[endpoint { @@ -64,8 +64,8 @@ async fn api_not_streaming( .body(serde_json::to_string("not-streaming").unwrap().into())?) } -fn check_has_transfer_encoding( - response: &Response, +fn check_has_transfer_encoding( + response: &Response, expected_value: Option<&str>, ) { let transfer_encoding_header = response.headers().get("transfer-encoding"); @@ -96,10 +96,12 @@ async fn test_streaming_server_streaming_client() { let mut chunk_count = 0; let mut byte_count = 0; - while let Some(chunk) = response.body_mut().data().await { + while let Some(chunk) = response.body_mut().frame().await { let chunk = chunk.expect("Should have received chunk without error"); - byte_count += chunk.len(); - chunk_count += 1; + if let Ok(chunk) = chunk.into_data() { + byte_count += chunk.len(); + chunk_count += 1; + } } assert!( @@ -128,9 +130,12 @@ async fn test_streaming_server_buffered_client() { .expect("Expected GET request to succeed"); check_has_transfer_encoding(&response, Some("chunked")); - let body_bytes = hyper::body::to_bytes(response.body_mut()) + let body_bytes = response + .body_mut() + .collect() .await - .expect("Error reading body"); + .expect("Error reading body") + .to_bytes(); assert_eq!( BUF_SIZE * BUF_COUNT, body_bytes.len(), diff --git a/dropshot/tests/test_tls.rs b/dropshot/tests/test_tls.rs index d06f62d21..7ce50db2a 100644 --- a/dropshot/tests/test_tls.rs +++ b/dropshot/tests/test_tls.rs @@ -90,8 +90,11 @@ fn make_https_client< T: rustls::client::danger::ServerCertVerifier + Send + Sync + 'static, >( verifier: Arc, -) -> hyper::Client< - hyper_rustls::HttpsConnector, +) -> hyper_util::client::legacy::Client< + hyper_rustls::HttpsConnector< + hyper_util::client::legacy::connect::HttpConnector, + >, + dropshot::Body, > { let tls_config = rustls::ClientConfig::builder() .dangerous() @@ -102,7 +105,10 @@ fn make_https_client< .https_only() .enable_http1() .build(); - hyper::Client::builder().build(https_connector) + hyper_util::client::legacy::Client::builder( + hyper_util::rt::TokioExecutor::new(), + ) + .build(https_connector) } fn make_server( @@ -156,7 +162,7 @@ async fn test_tls_certificate_loading() { let request = hyper::Request::builder() .method(http::method::Method::GET) .uri(&uri) - .body(hyper::Body::empty()) + .body(dropshot::Body::empty()) .unwrap(); let verifier_called = Arc::new(AtomicUsize::new(0)); @@ -211,14 +217,14 @@ async fn test_tls_only() { let https_request = hyper::Request::builder() .method(http::method::Method::GET) .uri(&https_uri) - .body(hyper::Body::empty()) + .body(dropshot::Body::empty()) .unwrap(); let http_uri: hyper::Uri = format!("http://localhost:{}/", port).parse().unwrap(); let http_request = hyper::Request::builder() .method(http::method::Method::GET) .uri(&http_uri) - .body(hyper::Body::empty()) + .body(dropshot::Body::empty()) .unwrap(); let https_client = make_https_client(make_pki_verifier(&certs)); @@ -226,16 +232,20 @@ async fn test_tls_only() { // Send an HTTP request, it should fail due to parse error, since // the server and client are speaking different protocols - let http_client = hyper::Client::builder().build_http(); - let error = http_client.request(http_request).await.unwrap_err(); - assert!(error.is_parse()); + let http_client = hyper_util::client::legacy::Client::builder( + hyper_util::rt::TokioExecutor::new(), + ) + .build(hyper_util::client::legacy::connect::HttpConnector::new()); + let _error = http_client.request(http_request).await.unwrap_err(); + // cannot check if parse error... + //assert!(error.is_parse()); // Make an HTTPS request again, to make sure the HTTP client didn't // interfere with HTTPS request processing let https_request = hyper::Request::builder() .method(http::method::Method::GET) .uri(&https_uri) - .body(hyper::Body::empty()) + .body(dropshot::Body::empty()) .unwrap(); https_client.request(https_request).await.unwrap(); @@ -263,7 +273,7 @@ async fn test_tls_refresh_certificates() { hyper::Request::builder() .method(http::method::Method::GET) .uri(&https_uri) - .body(hyper::Body::empty()) + .body(dropshot::Body::empty()) .unwrap() }; @@ -445,7 +455,7 @@ async fn test_server_is_https() { let https_request = hyper::Request::builder() .method(http::method::Method::GET) .uri(format!("https://localhost:{}/?tls=true", port)) - .body(hyper::Body::empty()) + .body(dropshot::Body::empty()) .unwrap(); let res = https_client.request(https_request).await.unwrap(); assert_eq!(res.status(), hyper::StatusCode::OK); @@ -454,7 +464,7 @@ async fn test_server_is_https() { let https_request = hyper::Request::builder() .method(http::method::Method::GET) .uri(format!("https://localhost:{}/?tls=false", port)) - .body(hyper::Body::empty()) + .body(dropshot::Body::empty()) .unwrap(); let res = https_client.request(https_request).await.unwrap(); assert_eq!(res.status(), hyper::StatusCode::BAD_REQUEST); From 6e05fb7ba409604923ab364cdd47795095d6e240 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Fri, 7 Jun 2024 11:30:38 -0400 Subject: [PATCH 02/29] remove ResponseBody alias --- dropshot/src/body.rs | 2 ++ dropshot/src/error.rs | 2 +- dropshot/src/handler.rs | 16 +++++++--------- dropshot/src/server.rs | 9 +++++---- dropshot/src/websocket.rs | 3 +-- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/dropshot/src/body.rs b/dropshot/src/body.rs index 3181279ca..e707f89bc 100644 --- a/dropshot/src/body.rs +++ b/dropshot/src/body.rs @@ -1,3 +1,5 @@ +// Copyright 2024 Oxide Computer Company + use std::pin::Pin; use std::task::{Context, Poll}; diff --git a/dropshot/src/error.rs b/dropshot/src/error.rs index c550a3053..f79da003e 100644 --- a/dropshot/src/error.rs +++ b/dropshot/src/error.rs @@ -275,7 +275,7 @@ impl HttpError { pub fn into_response( self, request_id: &str, - ) -> hyper::Response { + ) -> hyper::Response { // TODO-hardening: consider handling the operational errors that the // Serde serialization fails or the response construction fails. In // those cases, we should probably try to report this as a serious diff --git a/dropshot/src/handler.rs b/dropshot/src/handler.rs index 111d91f2f..7b424ef66 100644 --- a/dropshot/src/handler.rs +++ b/dropshot/src/handler.rs @@ -67,10 +67,8 @@ use std::marker::PhantomData; use std::num::NonZeroU32; use std::sync::Arc; -pub type ResponseBody = Body; - /// Type alias for the result returned by HTTP handler functions. -pub type HttpHandlerResult = Result, HttpError>; +pub type HttpHandlerResult = Result, HttpError>; /// Handle for various interfaces useful during request processing. #[derive(Debug)] @@ -501,8 +499,8 @@ where // See the discussion on macro `impl_HttpHandlerFunc_for_func_with_params` for a // great deal of context on this. -/// HttpResponse must produce a `Result, HttpError>` and generate -/// the response metadata. Typically one should use `Response` or an +/// HttpResponse must produce a `Result, HttpError>` and generate +/// the response metadata. Typically one should use `Response` or an /// implementation of `HttpTypedResponse`. pub trait HttpResponse { /// Generate the response to the HTTP call. @@ -515,7 +513,7 @@ pub trait HttpResponse { /// `Response` is used for free-form responses. The implementation of /// `to_result()` is trivial, and we don't have any typed metadata to return. -impl HttpResponse for Response { +impl HttpResponse for Response { fn to_result(self) -> HttpHandlerResult { Ok(self) } @@ -526,10 +524,10 @@ impl HttpResponse for Response { /// Wraps a [dropshot::Body] so that it can be used with coded response types such /// as [HttpResponseOk]. -pub struct FreeformBody(pub ResponseBody); +pub struct FreeformBody(pub Body); -impl From for FreeformBody { - fn from(body: ResponseBody) -> Self { +impl From for FreeformBody { + fn from(body: Body) -> Self { Self(body) } } diff --git a/dropshot/src/server.rs b/dropshot/src/server.rs index d7f11e09b..074dd4d7d 100644 --- a/dropshot/src/server.rs +++ b/dropshot/src/server.rs @@ -2,11 +2,12 @@ //! Generic server-wide state and facilities use super::api_description::ApiDescription; +use super::body::Body; use super::config::{ConfigDropshot, ConfigTls}; #[cfg(feature = "usdt-probes")] use super::dtrace::probes; use super::error::HttpError; -use super::handler::{RequestContext, ResponseBody}; +use super::handler::RequestContext; use super::http_util::HEADER_REQUEST_ID; use super::router::HttpRouter; use super::ProbeRegistration; @@ -818,7 +819,7 @@ async fn http_request_handle_wrap( server: Arc>, remote_addr: SocketAddr, request: Request, -) -> Result, GenericError> { +) -> Result, GenericError> { // This extra level of indirection makes error handling much more // straightforward, since the request handling code can simply return early // with an error and we'll treat it like an error from any of the endpoints @@ -947,7 +948,7 @@ async fn http_request_handle( request_id: &str, request_log: Logger, remote_addr: std::net::SocketAddr, -) -> Result, HttpError> { +) -> Result, HttpError> { // TODO-hardening: is it correct to (and do we correctly) read the entire // request body even if we decide it's too large and are going to send a 400 // response? @@ -1119,7 +1120,7 @@ impl ServerRequestHandler { impl Service> for ServerRequestHandler { - type Response = Response; + type Response = Response; type Error = GenericError; type Future = BoxFuture<'static, Result>; diff --git a/dropshot/src/websocket.rs b/dropshot/src/websocket.rs index 013a20aff..e382169b5 100644 --- a/dropshot/src/websocket.rs +++ b/dropshot/src/websocket.rs @@ -42,8 +42,7 @@ pub type WebsocketChannelResult = /// [WebsocketUpgrade::handle]'s return type. /// The `#[endpoint]` handler must return the value returned by /// [WebsocketUpgrade::handle]. (This is done for you by `#[channel]`.) -pub type WebsocketEndpointResult = - Result, HttpError>; +pub type WebsocketEndpointResult = Result, HttpError>; /// The upgraded connection passed as the last argument to the websocket /// handler function. [`WebsocketConnection::into_inner`] can be used to From da17e4cc9738b9dab0d824090d4865662bb4fdd9 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Fri, 7 Jun 2024 12:58:51 -0400 Subject: [PATCH 03/29] remove unused line --- dropshot/src/server.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/dropshot/src/server.rs b/dropshot/src/server.rs index 074dd4d7d..8eac8d870 100644 --- a/dropshot/src/server.rs +++ b/dropshot/src/server.rs @@ -644,7 +644,6 @@ impl InnerHttpsServerStarter { }); let make_service = ServerConnectionHandler::new(Arc::clone(&app_state)); - //let server = Server::builder(https_acceptor).serve(make_service); Ok(( InnerHttpsServerStarter(https_acceptor, make_service), From 96c093e6fdee128526f8fd12f5b5a3f092917af9 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Mon, 10 Jun 2024 14:34:32 -0400 Subject: [PATCH 04/29] remove commented out lines --- dropshot/src/server.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/dropshot/src/server.rs b/dropshot/src/server.rs index 8eac8d870..72fb30b79 100644 --- a/dropshot/src/server.rs +++ b/dropshot/src/server.rs @@ -185,11 +185,6 @@ impl HttpServerStarter { https.start(rx, log_close) } }; - /* - .map(|r| { - r.map_err(|e| format!("waiting for server: {e}"))? - .map_err(|e| format!("server stopped: {e}")) - })*/ info!(self.app_state.log, "listening"); let handler_waitgroup = self.handler_waitgroup; @@ -322,8 +317,6 @@ impl InnerHttpServerStarter { }); let make_service = ServerConnectionHandler::new(app_state.clone()); - //let builder = hyper::Server::builder(incoming); - //let server = builder.serve(make_service); Ok(( InnerHttpServerStarter(incoming, make_service), app_state, From 0140ee8df9f456fe56996cce74c1e741dd2e17bc Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Mon, 10 Jun 2024 14:37:46 -0400 Subject: [PATCH 05/29] add a doc to Body --- dropshot/src/body.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/dropshot/src/body.rs b/dropshot/src/body.rs index e707f89bc..e3e5a30fa 100644 --- a/dropshot/src/body.rs +++ b/dropshot/src/body.rs @@ -9,6 +9,7 @@ use hyper::body::{Body as HttpBody, Bytes, Frame}; type BoxError = Box; +/// A body type for both requests and responses in Dropshot. #[derive(Debug)] pub struct Body { inner: BoxBody, From 12eb307b3acdd9f59e25a220846a8da14d51fad5 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Mon, 10 Jun 2024 16:06:27 -0400 Subject: [PATCH 06/29] remove more commented out old code --- dropshot/src/server.rs | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/dropshot/src/server.rs b/dropshot/src/server.rs index 72fb30b79..f7c7975e1 100644 --- a/dropshot/src/server.rs +++ b/dropshot/src/server.rs @@ -1063,33 +1063,6 @@ impl ServerConnectionHandler { } } -/* TODO(SEAN) -impl Service<&AddrStream> for ServerConnectionHandler { - // Recall that a Service in this context is just something that takes a - // request (which could be anything) and produces a response (which could be - // anything). This being a connection handler, the request type is an - // AddrStream (which wraps a TCP connection) and the response type is - // another Service: one that accepts HTTP requests and produces HTTP - // responses. - type Response = ServerRequestHandler; - type Error = GenericError; - type Future = BoxFuture<'static, Result>; - - fn call(&mut self, conn: &AddrStream) -> Self::Future { - // We're given a borrowed reference to the AddrStream, but our interface - // is async (which is good, so that we can support time-consuming - // operations as part of receiving requests). To avoid having to ensure - // that conn's lifetime exceeds that of this async operation, we simply - // copy the only useful information out of the conn: the SocketAddr. We - // may want to create our own connection type to encapsulate the socket - // address and any other per-connection state that we want to keep. - let server = Arc::clone(&self.server); - let remote_addr = conn.remote_addr(); - Box::pin(http_connection_handle(server, remote_addr)) - } -} -*/ - /// ServerRequestHandler is a Hyper Service implementation that forwards /// incoming requests to `http_request_handle_wrap()`, including as an argument /// the backend server state object. We could use `service_fn` here using a From 437f9f89abdb23348ff1e26476e9f9d3c2d870dc Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Mon, 10 Jun 2024 16:10:55 -0400 Subject: [PATCH 07/29] add comment about TcpListener::from_std --- dropshot/src/server.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dropshot/src/server.rs b/dropshot/src/server.rs index f7c7975e1..033a4c154 100644 --- a/dropshot/src/server.rs +++ b/dropshot/src/server.rs @@ -301,6 +301,8 @@ impl InnerHttpServerStarter { log: &Logger, handler_waitgroup_worker: waitgroup::Worker, ) -> Result, std::io::Error> { + // We use `from_std` instead of just calling `bind` here directly + // to avoid invoking an async function. let std_listener = std::net::TcpListener::bind(&config.bind_address)?; std_listener.set_nonblocking(true)?; let incoming = TcpListener::from_std(std_listener)?; From 57789e0f4a0f2018a33ba896585edf946905a0d3 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Mon, 10 Jun 2024 16:18:01 -0400 Subject: [PATCH 08/29] stick to hyper 1.3 --- dropshot/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dropshot/Cargo.toml b/dropshot/Cargo.toml index 1845620f8..a5f73f863 100644 --- a/dropshot/Cargo.toml +++ b/dropshot/Cargo.toml @@ -55,7 +55,7 @@ version = "^0.10.2-dev" path = "../dropshot_endpoint" [dependencies.hyper] -version = "1" +version = "1.3" features = [ "full" ] [dependencies.hyper-util] From 52c532afba23e1fd29bc1ac396a10d2156780523 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Mon, 10 Jun 2024 16:23:40 -0400 Subject: [PATCH 09/29] test_util returns dropshot::Body --- dropshot/src/test_util.rs | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/dropshot/src/test_util.rs b/dropshot/src/test_util.rs index 404f79fd9..d349fad13 100644 --- a/dropshot/src/test_util.rs +++ b/dropshot/src/test_util.rs @@ -121,7 +121,7 @@ impl ClientTestContext { path: &str, request_body: Option, expected_status: StatusCode, - ) -> Result, HttpErrorResponseBody> { + ) -> Result, HttpErrorResponseBody> { let body = match request_body { None => Body::empty(), Some(input) => serde_json::to_string(&input).unwrap().into(), @@ -141,7 +141,7 @@ impl ClientTestContext { path: &str, request_body: Option, expected_status: StatusCode, - ) -> Result, HttpErrorResponseBody> { + ) -> Result, HttpErrorResponseBody> { let body: Body = match request_body { None => Body::empty(), Some(input) => serde_urlencoded::to_string(&input).unwrap().into(), @@ -161,7 +161,7 @@ impl ClientTestContext { method: Method, path: &str, expected_status: StatusCode, - ) -> Result, HttpErrorResponseBody> { + ) -> Result, HttpErrorResponseBody> { self.make_request_with_body( method, path, @@ -204,7 +204,7 @@ impl ClientTestContext { path: &str, body: Body, expected_status: StatusCode, - ) -> Result, HttpErrorResponseBody> { + ) -> Result, HttpErrorResponseBody> { let uri = self.url(path); let request = Request::builder() .method(method) @@ -220,7 +220,7 @@ impl ClientTestContext { path: &str, body: Body, expected_status: StatusCode, - ) -> Result, HttpErrorResponseBody> { + ) -> Result, HttpErrorResponseBody> { let uri = self.url(path); let request = Request::builder() .method(method) @@ -235,7 +235,7 @@ impl ClientTestContext { &self, request: Request, expected_status: StatusCode, - ) -> Result, HttpErrorResponseBody> { + ) -> Result, HttpErrorResponseBody> { let time_before = chrono::offset::Utc::now().timestamp(); info!(self.client_log, "client request"; "method" => %request.method(), @@ -329,6 +329,7 @@ impl ClientTestContext { assert_eq!(0, body_bytes.len()); } + let mut response = response.map(Body::wrap); // If this was a successful response, there's nothing else to check // here. Return the response so the caller can validate the content if // they want. @@ -522,7 +523,7 @@ impl TestContext { /// asynchronously read the body of the response and parse it accordingly, /// returning a vector of T. pub async fn read_ndjson( - response: &mut Response, + response: &mut Response, ) -> Vec { let headers = response.headers(); assert_eq!( @@ -556,7 +557,7 @@ pub async fn read_ndjson( /// be parseable via Serde as type T, asynchronously read the body of the /// response and parse it, returning an instance of T. pub async fn read_json( - response: &mut Response, + response: &mut Response, ) -> T { let headers = response.headers(); assert_eq!( @@ -576,7 +577,7 @@ pub async fn read_json( /// Given a Hyper Response whose body is expected to be a UTF-8-encoded string, /// asynchronously read the body. pub async fn read_string( - response: &mut Response, + response: &mut Response, ) -> String { let body_bytes = response .body_mut() @@ -590,7 +591,7 @@ pub async fn read_string( /// Given a Hyper Response, extract and parse the Content-Length header. pub fn read_content_length( - response: &Response, + response: &Response, ) -> usize { response .headers() From c7c2339188a0a7649cd1830264cbceac18a89376 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Fri, 14 Jun 2024 10:48:07 -0400 Subject: [PATCH 10/29] revert docs text about RequestInfo --- dropshot/src/handler.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dropshot/src/handler.rs b/dropshot/src/handler.rs index 7b424ef66..c75965c08 100644 --- a/dropshot/src/handler.rs +++ b/dropshot/src/handler.rs @@ -139,7 +139,7 @@ impl RequestInfo { /// /// This is provided for source compatibility. In previous versions of /// Dropshot, `RequestContext.request` was an - /// `Arc>>`. Now, it's just + /// `Arc>>`. Now, it's just /// `RequestInfo`, which provides many of the same functions as /// `hyper::Request` does. Consumers _should_ just use `rqctx.request` /// instead of this function. From d2220739a1181ec650e3b28a8867adadb43faf00 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Fri, 14 Jun 2024 10:48:25 -0400 Subject: [PATCH 11/29] consolidate into a single read_bytes function --- dropshot/src/test_util.rs | 41 ++++++++++++++++----------------------- 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/dropshot/src/test_util.rs b/dropshot/src/test_util.rs index d349fad13..a2cdace8b 100644 --- a/dropshot/src/test_util.rs +++ b/dropshot/src/test_util.rs @@ -320,12 +320,7 @@ impl ClientTestContext { // For "204 No Content" responses, validate that we got no content in // the body. if status == StatusCode::NO_CONTENT { - let body_bytes = response - .body_mut() - .collect() - .await - .expect("error reading body") - .to_bytes(); + let body_bytes = read_bytes(&mut response).await; assert_eq!(0, body_bytes.len()); } @@ -530,14 +525,7 @@ pub async fn read_ndjson( crate::CONTENT_TYPE_NDJSON, headers.get(http::header::CONTENT_TYPE).expect("missing content-type") ); - let body_bytes = response - .body_mut() - .collect() - .await - .expect("error reading body") - .to_bytes(); - let body_string = String::from_utf8(body_bytes.as_ref().into()) - .expect("response contained non-UTF-8 bytes"); + let body_string = read_string(response).await; // TODO-cleanup: Consider using serde_json::StreamDeserializer or maybe // implementing an NDJSON-based Serde type? @@ -564,12 +552,7 @@ pub async fn read_json( crate::CONTENT_TYPE_JSON, headers.get(http::header::CONTENT_TYPE).expect("missing content-type") ); - let body_bytes = response - .body_mut() - .collect() - .await - .expect("error reading body") - .to_bytes(); + let body_bytes = read_bytes(response).await; serde_json::from_slice(body_bytes.as_ref()) .expect("failed to parse server body as expected type") } @@ -579,14 +562,24 @@ pub async fn read_json( pub async fn read_string( response: &mut Response, ) -> String { - let body_bytes = response + let body_bytes = read_bytes(response).await; + String::from_utf8(body_bytes.as_ref().into()) + .expect("response contained non-UTF-8 bytes") +} + +async fn read_bytes( + response: &mut Response, +) -> hyper::body::Bytes +where + B: hyper::body::Body + Unpin, + B::Error: std::fmt::Debug, +{ + response .body_mut() .collect() .await .expect("error reading body") - .to_bytes(); - String::from_utf8(body_bytes.as_ref().into()) - .expect("response contained non-UTF-8 bytes") + .to_bytes() } /// Given a Hyper Response, extract and parse the Content-Length header. From 009b86440b64e3c975fe0d8e01f2b98b61cbf63f Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Fri, 14 Jun 2024 10:48:38 -0400 Subject: [PATCH 12/29] remove commented out assertion --- dropshot/tests/test_tls.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dropshot/tests/test_tls.rs b/dropshot/tests/test_tls.rs index 7ce50db2a..bbd30587d 100644 --- a/dropshot/tests/test_tls.rs +++ b/dropshot/tests/test_tls.rs @@ -237,8 +237,8 @@ async fn test_tls_only() { ) .build(hyper_util::client::legacy::connect::HttpConnector::new()); let _error = http_client.request(http_request).await.unwrap_err(); - // cannot check if parse error... - //assert!(error.is_parse()); + // cannot check if it is a "hyper parse error", but would like to if + // hyper::Error gains the ability in the future // Make an HTTPS request again, to make sure the HTTP client didn't // interfere with HTTPS request processing From 806be5948aa8dd7642023c102708dccb7ff0fe42 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Fri, 14 Jun 2024 13:26:15 -0400 Subject: [PATCH 13/29] remove unused Service<&TlsConn> --- dropshot/src/server.rs | 34 +++++++--------------------------- 1 file changed, 7 insertions(+), 27 deletions(-) diff --git a/dropshot/src/server.rs b/dropshot/src/server.rs index 033a4c154..422f8bcd6 100644 --- a/dropshot/src/server.rs +++ b/dropshot/src/server.rs @@ -271,7 +271,7 @@ impl InnerHttpServerStarter { Ok((sock, remote_addr)) = self.0.accept() => { let fut = builder.serve_connection_with_upgrades( TokioIo::new(sock), - self.1.make_svc(remote_addr), + self.1.make_http_request_handler(remote_addr), ); let fut = graceful.watch(fut.into_owned()); tokio::spawn(fut); @@ -583,7 +583,7 @@ impl InnerHttpsServerStarter { let remote_addr = sock.remote_addr(); let fut = builder.serve_connection_with_upgrades( TokioIo::new(sock), - self.1.make_svc(remote_addr), + self.1.make_http_request_handler(remote_addr), ); let fut = graceful.watch(fut.into_owned()); tokio::spawn(fut); @@ -648,18 +648,6 @@ impl InnerHttpsServerStarter { } } -impl Service<&TlsConn> for ServerConnectionHandler { - type Response = ServerRequestHandler; - type Error = GenericError; - type Future = BoxFuture<'static, Result>; - - fn call(&self, conn: &TlsConn) -> Self::Future { - let server = Arc::clone(&self.server); - let remote_addr = conn.remote_addr(); - Box::pin(http_connection_handle(server, remote_addr)) - } -} - type SharedBoxFuture = Shared + Send>>>; /// Future returned by [`HttpServer::wait_for_shutdown()`]. @@ -793,18 +781,6 @@ impl FusedFuture for HttpServer { } } -/// Initial entry point for handling a new connection to the HTTP server. -/// This is invoked by Hyper when a new connection is accepted. This function -/// must return a Hyper Service object that will handle requests for this -/// connection. -async fn http_connection_handle( - server: Arc>, - remote_addr: SocketAddr, -) -> Result, GenericError> { - info!(server.log, "accepted connection"; "remote_addr" => %remote_addr); - Ok(ServerRequestHandler::new(server, remote_addr)) -} - /// Initial entry point for handling a new request to the HTTP server. This is /// invoked by Hyper when a new request is received. This function returns a /// Result that either represents a valid HTTP response or an error (which will @@ -1059,7 +1035,11 @@ impl ServerConnectionHandler { ServerConnectionHandler { server } } - fn make_svc(&self, remote_addr: SocketAddr) -> ServerRequestHandler { + /// Initial entry point for handling a new connection to the HTTP server. + /// This is invoked by Hyper when a new connection is accepted. This function + /// must return a Hyper Service object that will handle requests for this + /// connection. + fn make_http_request_handler(&self, remote_addr: SocketAddr) -> ServerRequestHandler { info!(self.server.log, "accepted connection"; "remote_addr" => %remote_addr); ServerRequestHandler::new(self.server.clone(), remote_addr) } From 8b9ca26fc1bbbc1713daf751bf0c25735b25572b Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Fri, 14 Jun 2024 13:42:57 -0400 Subject: [PATCH 14/29] re-add WebsocketConnectionRaw --- dropshot/src/lib.rs | 1 + dropshot/src/websocket.rs | 62 +++++++++++++++++++++++++++++++++++---- 2 files changed, 57 insertions(+), 6 deletions(-) diff --git a/dropshot/src/lib.rs b/dropshot/src/lib.rs index ad987fb8f..cf7d935f5 100644 --- a/dropshot/src/lib.rs +++ b/dropshot/src/lib.rs @@ -666,6 +666,7 @@ pub use server::ShutdownWaitFuture; pub use server::{HttpServer, HttpServerStarter}; pub use websocket::WebsocketChannelResult; pub use websocket::WebsocketConnection; +pub use websocket::WebsocketConnectionRaw; pub use websocket::WebsocketEndpointResult; pub use websocket::WebsocketUpgrade; diff --git a/dropshot/src/websocket.rs b/dropshot/src/websocket.rs index e382169b5..c723ce5d2 100644 --- a/dropshot/src/websocket.rs +++ b/dropshot/src/websocket.rs @@ -23,6 +23,9 @@ use serde_json::json; use sha1::{Digest, Sha1}; use slog::Logger; use std::future::Future; +use std::pin::Pin; +use std::task::Context; +use std::task::Poll; /// WebsocketUpgrade is an ExclusiveExtractor used to upgrade and handle an HTTP /// request as a websocket when present in a Dropshot endpoint's function @@ -51,14 +54,14 @@ pub type WebsocketEndpointResult = Result, HttpError>; pub struct WebsocketConnection(WebsocketConnectionRaw); /// A type that implements [tokio::io::AsyncRead] + [tokio::io::AsyncWrite]. -// Not public, since it uses less-stable hyper-util. -type WebsocketConnectionRaw = hyper_util::rt::TokioIo; +// A newtype so as to not expose the less-stable hyper-util type. +pub struct WebsocketConnectionRaw( + hyper_util::rt::TokioIo, +); impl WebsocketConnection { /// Consumes `self` and returns the held raw connection. - pub fn into_inner( - self, - ) -> impl tokio::io::AsyncRead + tokio::io::AsyncWrite { + pub fn into_inner(self) -> WebsocketConnectionRaw { self.0 } } @@ -233,7 +236,8 @@ impl WebsocketUpgrade { match upgrade_fut.await { Ok(upgrade) => { let io = hyper_util::rt::TokioIo::new(upgrade); - match handler(WebsocketConnection(io)).await { + let raw = WebsocketConnectionRaw(io); + match handler(WebsocketConnection(raw)).await { Ok(x) => Ok(x), Err(e) => { error!( @@ -296,6 +300,52 @@ impl JsonSchema for WebsocketUpgrade { } } +impl tokio::io::AsyncRead for WebsocketConnectionRaw { + fn poll_read( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut tokio::io::ReadBuf<'_>, + ) -> Poll> { + Pin::new(&mut self.0).poll_read(cx, buf) + } +} + +impl tokio::io::AsyncWrite for WebsocketConnectionRaw { + fn poll_write( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + Pin::new(&mut self.0).poll_write(cx, buf) + } + + fn is_write_vectored(&self) -> bool { + self.0.is_write_vectored() + } + + fn poll_write_vectored( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &[std::io::IoSlice<'_>], + ) -> Poll> { + Pin::new(&mut self.0).poll_write_vectored(cx, bufs) + } + + fn poll_flush( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + Pin::new(&mut self.0).poll_flush(cx) + } + + fn poll_shutdown( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + Pin::new(&mut self.0).poll_shutdown(cx) + } +} + #[cfg(test)] mod tests { use crate::body::Body; From 79a92f49f40c65464f774cc2f689ab646b5f0541 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Fri, 14 Jun 2024 13:43:04 -0400 Subject: [PATCH 15/29] fmt --- dropshot/src/server.rs | 5 ++++- dropshot/src/test_util.rs | 19 ++++--------------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/dropshot/src/server.rs b/dropshot/src/server.rs index 422f8bcd6..eab2a9526 100644 --- a/dropshot/src/server.rs +++ b/dropshot/src/server.rs @@ -1039,7 +1039,10 @@ impl ServerConnectionHandler { /// This is invoked by Hyper when a new connection is accepted. This function /// must return a Hyper Service object that will handle requests for this /// connection. - fn make_http_request_handler(&self, remote_addr: SocketAddr) -> ServerRequestHandler { + fn make_http_request_handler( + &self, + remote_addr: SocketAddr, + ) -> ServerRequestHandler { info!(self.server.log, "accepted connection"; "remote_addr" => %remote_addr); ServerRequestHandler::new(self.server.clone(), remote_addr) } diff --git a/dropshot/src/test_util.rs b/dropshot/src/test_util.rs index a2cdace8b..caff1cbc4 100644 --- a/dropshot/src/test_util.rs +++ b/dropshot/src/test_util.rs @@ -559,33 +559,22 @@ pub async fn read_json( /// Given a Hyper Response whose body is expected to be a UTF-8-encoded string, /// asynchronously read the body. -pub async fn read_string( - response: &mut Response, -) -> String { +pub async fn read_string(response: &mut Response) -> String { let body_bytes = read_bytes(response).await; String::from_utf8(body_bytes.as_ref().into()) .expect("response contained non-UTF-8 bytes") } -async fn read_bytes( - response: &mut Response, -) -> hyper::body::Bytes +async fn read_bytes(response: &mut Response) -> hyper::body::Bytes where B: hyper::body::Body + Unpin, B::Error: std::fmt::Debug, { - response - .body_mut() - .collect() - .await - .expect("error reading body") - .to_bytes() + response.body_mut().collect().await.expect("error reading body").to_bytes() } /// Given a Hyper Response, extract and parse the Content-Length header. -pub fn read_content_length( - response: &Response, -) -> usize { +pub fn read_content_length(response: &Response) -> usize { response .headers() .get(http::header::CONTENT_LENGTH) From 41deb685e9b4640f4dc7f5e6650f069767a49b98 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Fri, 14 Jun 2024 13:50:12 -0400 Subject: [PATCH 16/29] change Body::full to Body::with_content --- dropshot/src/body.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dropshot/src/body.rs b/dropshot/src/body.rs index e3e5a30fa..bf3585e85 100644 --- a/dropshot/src/body.rs +++ b/dropshot/src/body.rs @@ -27,8 +27,8 @@ impl Body { Body { inner } } - /// Create a full body from a specific buffer. - pub fn full(buf: impl Into) -> Self { + /// Create a body with content from a specific buffer. + pub fn with_content(buf: impl Into) -> Self { let inner = http_body_util::Full::new(buf.into()) .map_err(|never| match never {}) .boxed(); @@ -59,25 +59,25 @@ impl Default for Body { impl From for Body { fn from(b: Bytes) -> Body { - Body::full(b) + Body::with_content(b) } } impl From> for Body { fn from(s: Vec) -> Body { - Body::full(s) + Body::with_content(s) } } impl From for Body { fn from(s: String) -> Body { - Body::full(s) + Body::with_content(s) } } impl From<&'static str> for Body { fn from(s: &'static str) -> Body { - Body::full(s) + Body::with_content(s) } } From e4fa983cf699fc10caee4d45b884d16fdcd675c5 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Fri, 14 Jun 2024 14:33:57 -0400 Subject: [PATCH 17/29] handle tcp accept errors like hyper used to --- dropshot/src/server.rs | 70 ++++++++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 23 deletions(-) diff --git a/dropshot/src/server.rs b/dropshot/src/server.rs index eab2a9526..0ae8075e2 100644 --- a/dropshot/src/server.rs +++ b/dropshot/src/server.rs @@ -241,7 +241,7 @@ enum WrappedHttpServerStarter { } struct InnerHttpServerStarter( - TcpListener, + HttpAcceptor, ServerConnectionHandler, ); @@ -305,8 +305,10 @@ impl InnerHttpServerStarter { // to avoid invoking an async function. let std_listener = std::net::TcpListener::bind(&config.bind_address)?; std_listener.set_nonblocking(true)?; - let incoming = TcpListener::from_std(std_listener)?; - let local_addr = incoming.local_addr()?; + let tcp = TcpListener::from_std(std_listener)?; + let local_addr = tcp.local_addr()?; + let incoming = + HttpAcceptor { tcp, log: log.new(o!("local_addr" => local_addr)) }; let app_state = Arc::new(DropshotState { private, @@ -327,6 +329,39 @@ impl InnerHttpServerStarter { } } +/// This accepts connections more gracefully from a TcpListener. +struct HttpAcceptor { + tcp: TcpListener, + log: slog::Logger, +} + +impl HttpAcceptor { + async fn accept(&self) -> std::io::Result<(TcpStream, SocketAddr)> { + loop { + match self.tcp.accept().await { + Ok((socket, addr)) => return Ok((socket, addr)), + Err(e) => match e.kind() { + // These are errors on the individual socket that we + // tried to accept, and so can be ignored. + std::io::ErrorKind::ConnectionRefused + | std::io::ErrorKind::ConnectionAborted + | std::io::ErrorKind::ConnectionReset => (), + + // This could EMFILE implying resource exhaustion. + // Sleep a little bit and try again. + _ => { + warn!(self.log, "accept error"; "error" => e); + tokio::time::sleep(std::time::Duration::from_millis( + 100, + )) + .await; + } + }, + } + } + } +} + /// Wrapper for TlsStream that also carries the remote SocketAddr #[derive(Debug)] struct TlsConn { @@ -400,13 +435,13 @@ impl HttpsAcceptor { pub fn new( log: slog::Logger, tls_acceptor: Arc>, - tcp_listener: TcpListener, + http_acceptor: HttpAcceptor, ) -> HttpsAcceptor { HttpsAcceptor { stream: Box::new(Box::pin(Self::new_stream( log, tls_acceptor, - tcp_listener, + http_acceptor, ))), } } @@ -418,7 +453,7 @@ impl HttpsAcceptor { fn new_stream( log: slog::Logger, tls_acceptor: Arc>, - tcp_listener: TcpListener, + http_acceptor: HttpAcceptor, ) -> impl Stream> { stream! { let mut tls_negotiations = futures::stream::FuturesUnordered::new(); @@ -444,26 +479,14 @@ impl HttpsAcceptor { }, } }, - accept_result = tcp_listener.accept() => { + accept_result = http_acceptor.accept() => { let (socket, addr) = match accept_result { Ok(v) => v, Err(e) => { - match e.kind() { - std::io::ErrorKind::ConnectionAborted => { - continue; - }, - // The other errors that can be returned - // under POSIX are all programming errors or - // resource exhaustion. For now, handle - // these by no longer accepting new - // connections. - // TODO-robustness: Consider handling these - // more gracefully. - _ => { - yield Err(e); - break; - } - } + // The HttpAcceptor already handled transient errors. + // At this point, it's a bad one. + yield Err(e); + break; } }; @@ -625,6 +648,7 @@ impl InnerHttpsServerStarter { let local_addr = tcp.local_addr()?; let logger = log.new(o!("local_addr" => local_addr)); + let tcp = HttpAcceptor { tcp, log: logger.clone() }; let https_acceptor = HttpsAcceptor::new(logger.clone(), acceptor.clone(), tcp); From 31144df4506087e47e06d26418e75c43da698b89 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Fri, 14 Jun 2024 14:36:32 -0400 Subject: [PATCH 18/29] add comments about graceful shutdown --- dropshot/src/server.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dropshot/src/server.rs b/dropshot/src/server.rs index 0ae8075e2..7f83899f2 100644 --- a/dropshot/src/server.rs +++ b/dropshot/src/server.rs @@ -263,6 +263,9 @@ impl InnerHttpServerStarter { // http/1 settings builder.http1().timer(TokioTimer::new()); + // Use a graceful watcher to keep track of all existing connections, + // and when the close_signal is trigger, force all known conns + // to start a graceful shutdown. let graceful = hyper_util::server::graceful::GracefulShutdown::new(); @@ -597,6 +600,9 @@ impl InnerHttpsServerStarter { // http/1 settings builder.http1().timer(TokioTimer::new()); + // Use a graceful watcher to keep track of all existing connections, + // and when the close_signal is trigger, force all known conns + // to start a graceful shutdown. let graceful = hyper_util::server::graceful::GracefulShutdown::new(); From 02f761968a4178d5c4fe138dd6aad7b108d8a7f8 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Mon, 17 Jun 2024 10:17:19 -0400 Subject: [PATCH 19/29] add some breaking changes to changelog --- CHANGELOG.adoc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 29126f795..fe5edc977 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -15,6 +15,10 @@ https://github.com/oxidecomputer/dropshot/compare/v0.10.1\...HEAD[Full list of commits] +=== Breaking Changes + +* https://github.com/oxidecomputer/dropshot/pull/1028[#1028] Upgraded to hyper v1.0. This means types from the `http` must come from v1.x. Dropshot no longer expects requests and responses to use the `hyper::Body` type, but rather `dropshot::Body`. It behaves very similar. + == 0.10.1 (released 2024-05-15) https://github.com/oxidecomputer/dropshot/compare/v0.10.0\...v0.10.1[Full list of commits] From e3f249cb7fbe8ee5c38a656662f6e33144f6f640 Mon Sep 17 00:00:00 2001 From: David Pacheco Date: Fri, 21 Jun 2024 11:30:43 -0700 Subject: [PATCH 20/29] update CHANGELOG.adoc --- CHANGELOG.adoc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index fe5edc977..e2f6d482f 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -17,7 +17,13 @@ https://github.com/oxidecomputer/dropshot/compare/v0.10.1\...HEAD[Full list of c === Breaking Changes -* https://github.com/oxidecomputer/dropshot/pull/1028[#1028] Upgraded to hyper v1.0. This means types from the `http` must come from v1.x. Dropshot no longer expects requests and responses to use the `hyper::Body` type, but rather `dropshot::Body`. It behaves very similar. +* https://github.com/oxidecomputer/dropshot/pull/1028[#1028] Updates Dropshot for `hyper` 1.0 and `http` 1.0. Since consumers provide Dropshot with values from `hyper` and `http`, you'll need to update to `hyper` 1.0 and `http` 1.0 (or newer compatible versions), too. ++ +**What you need to do:** +1. Update your crate's dependencies on `hyper` and `http` to 1.0 (or a newer compatible version) in Cargo.toml. +2. Replace any references to `hyper::Body` with `dropshot::Body` instead. ++ +There are no other known breaking changes in these crates that affect Dropshot. If you have any trouble with this upgrade, please let us know by filing an issue. == 0.10.1 (released 2024-05-15) From b3869773d2fd8846378d3e585715bda2e5c78b3d Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Fri, 21 Jun 2024 15:18:23 -0400 Subject: [PATCH 21/29] Update dropshot/src/server.rs Co-authored-by: David Pacheco --- dropshot/src/server.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dropshot/src/server.rs b/dropshot/src/server.rs index 7f83899f2..55fd51d92 100644 --- a/dropshot/src/server.rs +++ b/dropshot/src/server.rs @@ -332,7 +332,7 @@ impl InnerHttpServerStarter { } } -/// This accepts connections more gracefully from a TcpListener. +/// Accepts TCP connections like a `TcpListener`, but ignores transient errors rather than propagating them to the caller struct HttpAcceptor { tcp: TcpListener, log: slog::Logger, From 21f0aa0afcb82fba5b397a71fc89fbc5115fe758 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Fri, 21 Jun 2024 15:28:27 -0400 Subject: [PATCH 22/29] remove possiblity of error from tcp accept --- dropshot/src/server.rs | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/dropshot/src/server.rs b/dropshot/src/server.rs index 55fd51d92..d830755c8 100644 --- a/dropshot/src/server.rs +++ b/dropshot/src/server.rs @@ -262,6 +262,8 @@ impl InnerHttpServerStarter { let mut builder = auto::Builder::new(TokioExecutor::new()); // http/1 settings builder.http1().timer(TokioTimer::new()); + // http/2 settings + builder.http2().timer(TokioTimer::new()); // Use a graceful watcher to keep track of all existing connections, // and when the close_signal is trigger, force all known conns @@ -271,7 +273,7 @@ impl InnerHttpServerStarter { loop { tokio::select! { - Ok((sock, remote_addr)) = self.0.accept() => { + (sock, remote_addr) = self.0.accept() => { let fut = builder.serve_connection_with_upgrades( TokioIo::new(sock), self.1.make_http_request_handler(remote_addr), @@ -339,10 +341,10 @@ struct HttpAcceptor { } impl HttpAcceptor { - async fn accept(&self) -> std::io::Result<(TcpStream, SocketAddr)> { + async fn accept(&self) -> (TcpStream, SocketAddr) { loop { match self.tcp.accept().await { - Ok((socket, addr)) => return Ok((socket, addr)), + Ok((socket, addr)) => return (socket, addr), Err(e) => match e.kind() { // These are errors on the individual socket that we // tried to accept, and so can be ignored. @@ -482,17 +484,7 @@ impl HttpsAcceptor { }, } }, - accept_result = http_acceptor.accept() => { - let (socket, addr) = match accept_result { - Ok(v) => v, - Err(e) => { - // The HttpAcceptor already handled transient errors. - // At this point, it's a bad one. - yield Err(e); - break; - } - }; - + (socket, addr) = http_acceptor.accept() => { let tls_negotiation = tls_acceptor .lock() .await From 796918e58bbe2317a2fcabdf2ae97734fa77d9c9 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Mon, 24 Jun 2024 14:18:58 -0400 Subject: [PATCH 23/29] add HttpAcceptor unit test --- dropshot/src/server.rs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/dropshot/src/server.rs b/dropshot/src/server.rs index d830755c8..1a3985c4e 100644 --- a/dropshot/src/server.rs +++ b/dropshot/src/server.rs @@ -1204,4 +1204,29 @@ mod test { let (server, _) = create_test_server(); std::mem::drop(server); } + + #[tokio::test] + async fn test_http_acceptor_happy_path() { + const TOTAL: usize = 100; + let tcp = + tokio::net::TcpListener::bind("0.0.0.0:0").await.expect("bind"); + let addr = tcp.local_addr().expect("local_addr"); + let acceptor = + HttpAcceptor { log: slog::Logger::root(slog::Discard, o!()), tcp }; + + let t1 = tokio::spawn(async move { + for _ in 0..TOTAL { + let _ = acceptor.accept().await; + } + }); + + let t2 = tokio::spawn(async move { + for _ in 0..TOTAL { + tokio::net::TcpStream::connect(&addr).await.expect("connect"); + } + }); + + t1.await.expect("task 1"); + t2.await.expect("task 2"); + } } From 209afa2918d22df615f44eb6c4fd6e031da5e598 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Wed, 26 Jun 2024 12:53:53 -0400 Subject: [PATCH 24/29] bump lockfile --- Cargo.lock | 800 +++++++++++++++++++++++------------------------------ 1 file changed, 351 insertions(+), 449 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 056cd6ab2..a5bc323d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "addr2line" -version = "0.20.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" dependencies = [ "gimli", ] @@ -63,7 +63,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn", ] [[package]] @@ -74,26 +74,26 @@ checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn", ] [[package]] name = "atomic-waker" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1181e1e0d1fce796a03db1ae795d67167da795f9cf4a39c37589e85ef57f26d3" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" -version = "0.3.68" +version = "0.3.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" dependencies = [ "addr2line", "cc", @@ -112,21 +112,15 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.4.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "block-buffer" -version = "0.10.2" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] @@ -142,15 +136,15 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.12.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" @@ -169,12 +163,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.83" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" -dependencies = [ - "libc", -] +checksum = "ac367972e516d45567c7eafc73d24e1c193dcf200a8d94e9db7b3d38b349572d" [[package]] name = "cfg-if" @@ -192,7 +183,7 @@ dependencies = [ "iana-time-zone", "num-traits", "serde", - "windows-targets 0.52.0", + "windows-targets 0.52.5", ] [[package]] @@ -206,22 +197,22 @@ dependencies = [ [[package]] name = "console" -version = "0.15.7" +version = "0.15.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" dependencies = [ "encode_unicode", "lazy_static", "libc", "unicode-width", - "windows-sys 0.45.0", + "windows-sys 0.52.0", ] [[package]] name = "core-foundation" -version = "0.9.2" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ "core-foundation-sys", "libc", @@ -229,37 +220,33 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.3" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "cpufeatures" -version = "0.2.2" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] [[package]] name = "crossbeam-channel" -version = "0.5.1" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" dependencies = [ - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.15" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" -dependencies = [ - "cfg-if", -] +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crypto-common" @@ -273,9 +260,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.4.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" [[package]] name = "debug-ignore" @@ -410,7 +397,7 @@ dependencies = [ "schema", "serde", "serde_tokenstream", - "syn 2.0.68", + "syn", ] [[package]] @@ -426,9 +413,9 @@ dependencies = [ [[package]] name = "dyn-clone" -version = "1.0.4" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee2626afccd7561a06cf1367e2950c4718ea04565e20fb5029b6c7d8ad09abcf" +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" [[package]] name = "encode_unicode" @@ -438,24 +425,24 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" -version = "0.8.32" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if", ] [[package]] name = "equivalent" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -463,9 +450,9 @@ dependencies = [ [[package]] name = "event-listener" -version = "5.0.0" +version = "5.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b72557800024fabbaa2449dd4bf24e37b93702d457a4d4f2b0dd1f0f039f20c1" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" dependencies = [ "concurrent-queue", "parking", @@ -495,9 +482,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "fnv" @@ -570,7 +557,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn", ] [[package]] @@ -605,9 +592,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.5" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", @@ -615,9 +602,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.11" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -626,21 +613,21 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.3" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" [[package]] name = "glob" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "goblin" -version = "0.8.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb07a4ffed2093b118a525b1d8f5204ae274faed5604537caf7135d0f18d9887" +checksum = "1b363a30c165f666402fe6a3024d3bec7ebc898f96a4a23bd1c99f8dbf3f4f47" dependencies = [ "log", "plain", @@ -649,15 +636,15 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "816ec7294445779408f36fe57bc5b7fc1cf59664059096c65f905c1c61f58069" +checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" dependencies = [ + "atomic-waker", "bytes", "fnv", "futures-core", "futures-sink", - "futures-util", "http", "indexmap", "slab", @@ -668,24 +655,15 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" - -[[package]] -name = "hermit-abi" -version = "0.1.19" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "hermit-abi" -version = "0.3.6" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd5256b483761cd23699d0da46cc6fd2ee3be420bbe6d020ae4a091e70b7e9fd" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hostname" @@ -711,9 +689,9 @@ dependencies = [ [[package]] name = "http" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", @@ -732,12 +710,12 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", - "futures-core", + "futures-util", "http", "http-body", "pin-project-lite", @@ -745,27 +723,27 @@ dependencies = [ [[package]] name = "http-range" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eee9694f83d9b7c09682fdb32213682939507884e5bcf227be9aff5d644b90dc" +checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573" [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" [[package]] name = "httpdate" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f24ce812868d86d19daa79bf3bf9175bc44ea323391147a5e3abde2a283871b" +checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" dependencies = [ "bytes", "futures-channel", @@ -842,25 +820,33 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.47" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c495f162af0bf17656d0014a0eded5f3cd2f365fdd204548c2869db89359dc7" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" dependencies = [ "android_system_properties", "core-foundation-sys", + "iana-time-zone-haiku", "js-sys", - "once_cell", "wasm-bindgen", - "winapi", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", ] [[package]] name = "idna" -version = "0.2.3" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ - "matches", "unicode-bidi", "unicode-normalization", ] @@ -882,22 +868,22 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" dependencies = [ - "hermit-abi 0.3.6", + "hermit-abi", "libc", "windows-sys 0.52.0", ] [[package]] name = "itoa" -version = "1.0.1" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" -version = "0.3.59" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] @@ -914,29 +900,37 @@ version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags", + "libc", +] + [[package]] name = "linux-raw-sys" -version = "0.4.12" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "lock_api" -version = "0.4.6" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ + "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.17" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "match_cfg" @@ -944,17 +938,11 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" -[[package]] -name = "matches" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" - [[package]] name = "memchr" -version = "2.6.0" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76fc44e2588d5b436dbc3c6cf62aef290f90dab6235744a93dfe1cc18f451e2c" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memmap" @@ -968,9 +956,9 @@ dependencies = [ [[package]] name = "mime" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "mime_guess" @@ -984,9 +972,9 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", ] @@ -1028,48 +1016,54 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-traits" -version = "0.2.14" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "num_cpus" -version = "1.13.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.1.19", + "hermit-abi", "libc", ] [[package]] name = "num_threads" -version = "0.1.3" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97ba99ba6393e2c3734791401b66902d981cb03bf190af674ca69949b6d5fb15" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" dependencies = [ "libc", ] [[package]] name = "object" -version = "0.31.1" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +checksum = "576dfe1fc8f9df304abb159d767a29d0476f7750fbf8aa7ad07816004a207434" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.13.1" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "openapiv3" @@ -1084,9 +1078,9 @@ dependencies = [ [[package]] name = "openssl-probe" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "parking" @@ -1096,9 +1090,9 @@ checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -1106,15 +1100,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.4" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-sys 0.42.0", + "windows-targets 0.52.5", ] [[package]] @@ -1141,9 +1135,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.6" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f200d8d83c44a45b21764d1916299752ca035d15ecd46faca3e9a2a2bf6ad06" +checksum = "560131c633294438da9f7c4b08189194b20946c8274c6b9e38881a7874dc8ee8" dependencies = [ "memchr", "thiserror", @@ -1152,9 +1146,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.6" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcd6ab1236bbdb3a49027e920e693192ebfe8913f6d60e294de57463a493cfde" +checksum = "26293c9193fbca7b1a3bf9b79dc1e388e927e6cacaa78b4a3ab705a1d3d41459" dependencies = [ "pest", "pest_generator", @@ -1162,22 +1156,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.6" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a31940305ffc96863a735bef7c7994a00b325a7138fdbc5bda0f1a0476d3275" +checksum = "3ec22af7d3fb470a85dd2ca96b7c577a1eb4ef6f1683a9fe9a8c16e136c04687" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.68", + "syn", ] [[package]] name = "pest_meta" -version = "2.7.6" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7ff62f5259e53b78d1af898941cdcdccfae7385cf7d793a6e55de5d05bb4b7d" +checksum = "d7a240022f37c361ec1878d646fc5b7d7c4d28d5946e1a80ad5a7a4f4ca0bdcd" dependencies = [ "once_cell", "pest", @@ -1201,14 +1195,14 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn", ] [[package]] name = "pin-project-lite" -version = "0.2.12" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -1230,9 +1224,9 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.15" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "pretty-hex" @@ -1247,7 +1241,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ "proc-macro2", - "syn 2.0.68", + "syn", ] [[package]] @@ -1270,14 +1264,13 @@ dependencies = [ [[package]] name = "rand" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", "rand_core", - "rand_hc", ] [[package]] @@ -1292,22 +1285,13 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ "getrandom", ] -[[package]] -name = "rand_hc" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" -dependencies = [ - "rand_core", -] - [[package]] name = "rcgen" version = "0.13.1" @@ -1323,50 +1307,52 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.10" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" dependencies = [ - "bitflags 1.3.2", + "bitflags", ] [[package]] name = "redox_users" -version = "0.4.0" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ "getrandom", - "redox_syscall", + "libredox", + "thiserror", ] [[package]] name = "ring" -version = "0.17.7" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", + "cfg-if", "getrandom", "libc", "spin", "untrusted", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustix" -version = "0.38.31" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.4.0", + "bitflags", "errno", "libc", "linux-raw-sys", @@ -1418,9 +1404,9 @@ checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" [[package]] name = "rustls-webpki" -version = "0.102.1" +version = "0.102.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef4ca26037c909dedb327b48c3327d0ba91d3dd3c4e05dad328f210ffb68e95b" +checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e" dependencies = [ "ring", "rustls-pki-types", @@ -1429,24 +1415,23 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.5" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61b3909d758bb75c79f23d4736fac9433868679d3ad2ea7a61e3c25cfda9a088" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "ryu" -version = "1.0.5" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "schannel" -version = "0.1.19" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" dependencies = [ - "lazy_static", - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -1458,7 +1443,7 @@ dependencies = [ "proc-macro2", "quote", "schema-derive", - "syn 2.0.68", + "syn", ] [[package]] @@ -1470,7 +1455,7 @@ dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.68", + "syn", ] [[package]] @@ -1496,7 +1481,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.68", + "syn", ] [[package]] @@ -1522,16 +1507,16 @@ checksum = "7f81c2fde025af7e69b1d1420531c8a8811ca898919db177141a85313b1cb932" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn", ] [[package]] name = "security-framework" -version = "2.4.2" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525bc1abfda2e1998d152c45cf13e696f76d0a4972310b22fac1658b05df7c87" +checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" dependencies = [ - "bitflags 1.3.2", + "bitflags", "core-foundation", "core-foundation-sys", "libc", @@ -1540,9 +1525,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.4.2" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9dd14d83160b528b7bfd66439110573efcfbe281b17fc2ca9f39f550d619c7e" +checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" dependencies = [ "core-foundation-sys", "libc", @@ -1565,25 +1550,25 @@ checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn", ] [[package]] name = "serde_derive_internals" -version = "0.29.0" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "330f01ce65a3a5fe59a60c82f3c9a024b573b8a6e875bd233fe5f934e71d54e3" +checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn", ] [[package]] name = "serde_json" -version = "1.0.117" +version = "1.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +checksum = "d947f6b3163d8857ea16c4fa0dd4840d52f3041039a85decd46867eb1abef2e4" dependencies = [ "itoa", "ryu", @@ -1618,7 +1603,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.68", + "syn", ] [[package]] @@ -1657,24 +1642,27 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] [[package]] name = "similar" -version = "2.2.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "420acb44afdae038210c99e69aae24109f32f15500aa708e81d46c9f29d55fcf" +checksum = "fa42c91313f1d05da9b26f267f931cf178d4aba455b4c4622dd7355eb80c6640" [[package]] name = "slab" -version = "0.4.5" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] [[package]] name = "slog" @@ -1739,12 +1727,12 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" -version = "0.5.5" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1765,20 +1753,9 @@ dependencies = [ [[package]] name = "subtle" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" - -[[package]] -name = "syn" -version = "1.0.109" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" @@ -1822,62 +1799,63 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.1.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] [[package]] name = "thiserror" -version = "1.0.56" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.56" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn", ] [[package]] name = "thread-id" -version = "4.0.0" +version = "4.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fdfe0627923f7411a43ec9ec9c39c3a9b4151be313e0922042581fb6c9b717f" +checksum = "f0ec81c46e9eb50deaa257be2f148adf052d1fb7701cfd55ccfab2525280b70b" dependencies = [ "libc", - "redox_syscall", "winapi", ] [[package]] name = "thread_local" -version = "1.1.4" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" dependencies = [ + "cfg-if", "once_cell", ] [[package]] name = "time" -version = "0.3.31" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", "libc", + "num-conv", "num_threads", "powerfmt", "serde", @@ -1893,27 +1871,28 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ + "num-conv", "time-core", ] [[package]] name = "tinyvec" -version = "1.5.1" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" +checksum = "c55115c6fbe2d2bef26eb09ad74bde02d8255476fc0c7b515ef09fbb35742d82" dependencies = [ "tinyvec_macros", ] [[package]] name = "tinyvec_macros" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" @@ -1942,7 +1921,7 @@ checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn", ] [[package]] @@ -1970,16 +1949,15 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.7" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5427d89453009325de0d8f342c9490009f76e999cb7672d77e46267448f7e6b2" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] @@ -2039,9 +2017,9 @@ checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" [[package]] name = "tower-service" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" @@ -2064,9 +2042,9 @@ dependencies = [ [[package]] name = "try-lock" -version = "0.2.3" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "trybuild" @@ -2102,9 +2080,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.14.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "ucd-trie" @@ -2114,45 +2092,45 @@ checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" [[package]] name = "unicase" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" dependencies = [ "version_check", ] [[package]] name = "unicode-bidi" -version = "0.3.7" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" -version = "1.0.0" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" -version = "0.1.19" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" dependencies = [ "tinyvec", ] [[package]] name = "unicode-segmentation" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode-width" -version = "0.1.9" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" [[package]] name = "untrusted" @@ -2162,13 +2140,12 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.2.2" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna", - "matches", "percent-encoding", ] @@ -2198,7 +2175,7 @@ dependencies = [ "proc-macro2", "quote", "serde_tokenstream", - "syn 2.0.68", + "syn", "usdt-impl", ] @@ -2216,7 +2193,7 @@ dependencies = [ "quote", "serde", "serde_json", - "syn 2.0.68", + "syn", "thiserror", "thread-id", "version_check", @@ -2232,7 +2209,7 @@ dependencies = [ "proc-macro2", "quote", "serde_tokenstream", - "syn 2.0.68", + "syn", "usdt-impl", ] @@ -2244,9 +2221,9 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] name = "uuid" -version = "1.9.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ea73390fe27785838dcbf75b91b1d84799e28f1ce71e6f372a5dc2200c80de5" +checksum = "5de17fd2f7da591098415cff336e12965a28061ddace43b59cb3c430179c9439" dependencies = [ "getrandom", "serde", @@ -2269,11 +2246,10 @@ dependencies = [ [[package]] name = "want" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" dependencies = [ - "log", "try-lock", ] @@ -2285,9 +2261,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.82" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2295,24 +2271,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.82" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 1.0.109", + "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.82" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2320,22 +2296,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.82" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.82" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "winapi" @@ -2355,11 +2331,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -2375,7 +2351,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" dependencies = [ "windows-core", - "windows-targets 0.52.0", + "windows-targets 0.52.5", ] [[package]] @@ -2384,31 +2360,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.0", -] - -[[package]] -name = "windows-sys" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", + "windows-targets 0.52.5", ] [[package]] @@ -2417,7 +2369,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.48.0", + "windows-targets 0.48.5", ] [[package]] @@ -2426,185 +2378,135 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", -] - -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", + "windows-targets 0.52.5", ] [[package]] name = "windows-targets" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.48.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" [[package]] -name = "windows_i686_gnu" -version = "0.52.0" +name = "windows_i686_gnullvm" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "winnow" -version = "0.6.5" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8" +checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1" dependencies = [ "memchr", ] @@ -2620,9 +2522,9 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.32" +version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" dependencies = [ "byteorder", "zerocopy-derive", @@ -2630,17 +2532,17 @@ dependencies = [ [[package]] name = "zerocopy-derive" -version = "0.7.32" +version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.68", + "syn", ] [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" From 4e89c0ad44573b9ef3ab89f5c00122c1b6a76109 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Fri, 28 Jun 2024 07:32:17 -0400 Subject: [PATCH 25/29] bless newer trybuild output --- dropshot/tests/fail/bad_channel17.stderr | 2 +- dropshot/tests/fail/bad_channel18.stderr | 2 +- dropshot/tests/fail/bad_channel19.stderr | 2 +- dropshot/tests/fail/bad_channel1b.stderr | 4 ++-- dropshot/tests/fail/bad_channel4.stderr | 4 ++-- dropshot/tests/fail/bad_channel5.stderr | 4 ++-- dropshot/tests/fail/bad_channel9.stderr | 4 ++-- dropshot/tests/fail/bad_endpoint12.stderr | 2 +- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/dropshot/tests/fail/bad_channel17.stderr b/dropshot/tests/fail/bad_channel17.stderr index 4b81fb8ac..ca503c569 100644 --- a/dropshot/tests/fail/bad_channel17.stderr +++ b/dropshot/tests/fail/bad_channel17.stderr @@ -29,7 +29,7 @@ error[E0277]: the trait bound `fn(RequestContext<()>, WebsocketConnection, Webso 15 | | }] | |__- required by a bound introduced by this call 16 | async fn two_websocket_channels( - | ^^^^^^^^^^^^^^^^^^^^^^ the trait `dropshot::handler::HttpHandlerFunc<_, _, _>` is not implemented for fn item `fn(RequestContext<()>, WebsocketConnection, WebsocketUpgrade) -> impl Future, HttpError>> { for ApiEndpoint< as RequestContextArgument>::Context>>::from::two_websocket_channels}` + | ^^^^^^^^^^^^^^^^^^^^^^ the trait `dropshot::handler::HttpHandlerFunc<_, _, _>` is not implemented for fn item `fn(RequestContext<()>, WebsocketConnection, WebsocketUpgrade) -> impl Future, HttpError>> { for ApiEndpoint< as RequestContextArgument>::Context>>::from::two_websocket_channels}` | note: required by a bound in `ApiEndpoint::::new` --> src/api_description.rs diff --git a/dropshot/tests/fail/bad_channel18.stderr b/dropshot/tests/fail/bad_channel18.stderr index 764218b15..ae7018b7a 100644 --- a/dropshot/tests/fail/bad_channel18.stderr +++ b/dropshot/tests/fail/bad_channel18.stderr @@ -53,7 +53,7 @@ error[E0277]: the trait bound `fn(RequestContext<()>, WebsocketConnection, Webso 22 | | }] | |__- required by a bound introduced by this call 23 | async fn websocket_channel_not_last( - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `dropshot::handler::HttpHandlerFunc<_, _, _>` is not implemented for fn item `fn(RequestContext<()>, WebsocketConnection, WebsocketUpgrade) -> impl Future, HttpError>> { for ApiEndpoint< as RequestContextArgument>::Context>>::from::websocket_channel_not_last}` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `dropshot::handler::HttpHandlerFunc<_, _, _>` is not implemented for fn item `fn(RequestContext<()>, WebsocketConnection, WebsocketUpgrade) -> impl Future, HttpError>> { for ApiEndpoint< as RequestContextArgument>::Context>>::from::websocket_channel_not_last}` | note: required by a bound in `ApiEndpoint::::new` --> src/api_description.rs diff --git a/dropshot/tests/fail/bad_channel19.stderr b/dropshot/tests/fail/bad_channel19.stderr index 8440b76be..bf3b91bec 100644 --- a/dropshot/tests/fail/bad_channel19.stderr +++ b/dropshot/tests/fail/bad_channel19.stderr @@ -29,7 +29,7 @@ error[E0277]: the trait bound `fn(RequestContext<()>, std::string::String, Webso 22 | | }] | |__- required by a bound introduced by this call 23 | async fn non_extractor_as_last_argument( - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `dropshot::handler::HttpHandlerFunc<_, _, _>` is not implemented for fn item `fn(RequestContext<()>, std::string::String, WebsocketUpgrade) -> impl Future, HttpError>> { for ApiEndpoint< as RequestContextArgument>::Context>>::from::non_extractor_as_last_argument}` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `dropshot::handler::HttpHandlerFunc<_, _, _>` is not implemented for fn item `fn(RequestContext<()>, std::string::String, WebsocketUpgrade) -> impl Future, HttpError>> { for ApiEndpoint< as RequestContextArgument>::Context>>::from::non_extractor_as_last_argument}` | note: required by a bound in `ApiEndpoint::::new` --> src/api_description.rs diff --git a/dropshot/tests/fail/bad_channel1b.stderr b/dropshot/tests/fail/bad_channel1b.stderr index 96a712dfd..73e0a4ec9 100644 --- a/dropshot/tests/fail/bad_channel1b.stderr +++ b/dropshot/tests/fail/bad_channel1b.stderr @@ -10,7 +10,7 @@ error[E0277]: the trait bound `WebsocketUpgrade: RequestContextArgument` is not = help: the trait `RequestContextArgument` is implemented for `RequestContext` = note: this error originates in the attribute macro `channel` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0277]: the trait bound `fn(WebsocketUpgrade) -> impl Future, HttpError>> { for ApiEndpoint<::Context>>::from::bad_channel}: dropshot::handler::HttpHandlerFunc<_, _, _>` is not satisfied +error[E0277]: the trait bound `fn(WebsocketUpgrade) -> impl Future, HttpError>> { for ApiEndpoint<::Context>>::from::bad_channel}: dropshot::handler::HttpHandlerFunc<_, _, _>` is not satisfied --> tests/fail/bad_channel1b.rs:12:10 | 8 | / #[channel { @@ -19,7 +19,7 @@ error[E0277]: the trait bound `fn(WebsocketUpgrade) -> impl Future` is not implemented for fn item `fn(WebsocketUpgrade) -> impl Future, HttpError>> { for ApiEndpoint<::Context>>::from::bad_channel}` + | ^^^^^^^^^^^ the trait `dropshot::handler::HttpHandlerFunc<_, _, _>` is not implemented for fn item `fn(WebsocketUpgrade) -> impl Future, HttpError>> { for ApiEndpoint<::Context>>::from::bad_channel}` | note: required by a bound in `ApiEndpoint::::new` --> src/api_description.rs diff --git a/dropshot/tests/fail/bad_channel4.stderr b/dropshot/tests/fail/bad_channel4.stderr index f837e31d4..2e0e503ca 100644 --- a/dropshot/tests/fail/bad_channel4.stderr +++ b/dropshot/tests/fail/bad_channel4.stderr @@ -139,7 +139,7 @@ note: required by a bound in `dropshot::Query` | pub struct Query { | ^^^^^^^^^^^^^^^^ required by this bound in `Query` -error[E0277]: the trait bound `fn(RequestContext<()>, dropshot::Query, WebsocketUpgrade) -> impl Future, HttpError>> { for ApiEndpoint< as RequestContextArgument>::Context>>::from::bad_channel}: dropshot::handler::HttpHandlerFunc<_, _, _>` is not satisfied +error[E0277]: the trait bound `fn(RequestContext<()>, dropshot::Query, WebsocketUpgrade) -> impl Future, HttpError>> { for ApiEndpoint< as RequestContextArgument>::Context>>::from::bad_channel}: dropshot::handler::HttpHandlerFunc<_, _, _>` is not satisfied --> tests/fail/bad_channel4.rs:20:10 | 16 | / #[channel { @@ -148,7 +148,7 @@ error[E0277]: the trait bound `fn(RequestContext<()>, dropshot::Query` is not implemented for fn item `fn(RequestContext<()>, dropshot::Query, WebsocketUpgrade) -> impl Future, HttpError>> { for ApiEndpoint< as RequestContextArgument>::Context>>::from::bad_channel}` + | ^^^^^^^^^^^ the trait `dropshot::handler::HttpHandlerFunc<_, _, _>` is not implemented for fn item `fn(RequestContext<()>, dropshot::Query, WebsocketUpgrade) -> impl Future, HttpError>> { for ApiEndpoint< as RequestContextArgument>::Context>>::from::bad_channel}` | note: required by a bound in `ApiEndpoint::::new` --> src/api_description.rs diff --git a/dropshot/tests/fail/bad_channel5.stderr b/dropshot/tests/fail/bad_channel5.stderr index 0a79e6642..b7c2c2cc9 100644 --- a/dropshot/tests/fail/bad_channel5.stderr +++ b/dropshot/tests/fail/bad_channel5.stderr @@ -70,7 +70,7 @@ note: required by a bound in `dropshot::Query` | pub struct Query { | ^^^^^^^^^^^^^^^^ required by this bound in `Query` -error[E0277]: the trait bound `fn(RequestContext<()>, dropshot::Query, WebsocketUpgrade) -> impl Future, HttpError>> { for ApiEndpoint< as RequestContextArgument>::Context>>::from::bad_channel}: dropshot::handler::HttpHandlerFunc<_, _, _>` is not satisfied +error[E0277]: the trait bound `fn(RequestContext<()>, dropshot::Query, WebsocketUpgrade) -> impl Future, HttpError>> { for ApiEndpoint< as RequestContextArgument>::Context>>::from::bad_channel}: dropshot::handler::HttpHandlerFunc<_, _, _>` is not satisfied --> tests/fail/bad_channel5.rs:22:10 | 18 | / #[channel { @@ -79,7 +79,7 @@ error[E0277]: the trait bound `fn(RequestContext<()>, dropshot::Query` is not implemented for fn item `fn(RequestContext<()>, dropshot::Query, WebsocketUpgrade) -> impl Future, HttpError>> { for ApiEndpoint< as RequestContextArgument>::Context>>::from::bad_channel}` + | ^^^^^^^^^^^ the trait `dropshot::handler::HttpHandlerFunc<_, _, _>` is not implemented for fn item `fn(RequestContext<()>, dropshot::Query, WebsocketUpgrade) -> impl Future, HttpError>> { for ApiEndpoint< as RequestContextArgument>::Context>>::from::bad_channel}` | note: required by a bound in `ApiEndpoint::::new` --> src/api_description.rs diff --git a/dropshot/tests/fail/bad_channel9.stderr b/dropshot/tests/fail/bad_channel9.stderr index 48e372042..435b695c2 100644 --- a/dropshot/tests/fail/bad_channel9.stderr +++ b/dropshot/tests/fail/bad_channel9.stderr @@ -18,7 +18,7 @@ error[E0277]: the trait bound `dropshot::Query: RequestContextArgum = help: the trait `RequestContextArgument` is implemented for `RequestContext` = note: this error originates in the attribute macro `channel` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0277]: the trait bound `fn(dropshot::Query, WebsocketUpgrade) -> impl Future, HttpError>> { for ApiEndpoint< as RequestContextArgument>::Context>>::from::bad_channel}: dropshot::handler::HttpHandlerFunc<_, _, _>` is not satisfied +error[E0277]: the trait bound `fn(dropshot::Query, WebsocketUpgrade) -> impl Future, HttpError>> { for ApiEndpoint< as RequestContextArgument>::Context>>::from::bad_channel}: dropshot::handler::HttpHandlerFunc<_, _, _>` is not satisfied --> tests/fail/bad_channel9.rs:23:10 | 19 | / #[channel { @@ -27,7 +27,7 @@ error[E0277]: the trait bound `fn(dropshot::Query, WebsocketUpgrade 22 | | }] | |__- required by a bound introduced by this call 23 | async fn bad_channel( - | ^^^^^^^^^^^ the trait `dropshot::handler::HttpHandlerFunc<_, _, _>` is not implemented for fn item `fn(dropshot::Query, WebsocketUpgrade) -> impl Future, HttpError>> { for ApiEndpoint< as RequestContextArgument>::Context>>::from::bad_channel}` + | ^^^^^^^^^^^ the trait `dropshot::handler::HttpHandlerFunc<_, _, _>` is not implemented for fn item `fn(dropshot::Query, WebsocketUpgrade) -> impl Future, HttpError>> { for ApiEndpoint< as RequestContextArgument>::Context>>::from::bad_channel}` | note: required by a bound in `ApiEndpoint::::new` --> src/api_description.rs diff --git a/dropshot/tests/fail/bad_endpoint12.stderr b/dropshot/tests/fail/bad_endpoint12.stderr index aa8cd2285..c1b441d84 100644 --- a/dropshot/tests/fail/bad_endpoint12.stderr +++ b/dropshot/tests/fail/bad_endpoint12.stderr @@ -6,7 +6,7 @@ error[E0277]: the trait bound `String: HttpResponse` is not satisfied | = help: the following other types implement trait `HttpResponse`: HttpResponseHeaders - http::response::Response + http::response::Response = note: required for `String` to implement `HttpResponse` note: required for `Result` to implement `ResultTrait` --> tests/fail/bad_endpoint12.rs:15:6 From 78310b48f66a55f12b4f7d5889b8e8650d7db004 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Fri, 28 Jun 2024 16:43:03 -0400 Subject: [PATCH 26/29] use 127.0.0.1 in acceptor tests, to make windows happy --- dropshot/src/server.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dropshot/src/server.rs b/dropshot/src/server.rs index 1a3985c4e..f1329e76f 100644 --- a/dropshot/src/server.rs +++ b/dropshot/src/server.rs @@ -1209,7 +1209,7 @@ mod test { async fn test_http_acceptor_happy_path() { const TOTAL: usize = 100; let tcp = - tokio::net::TcpListener::bind("0.0.0.0:0").await.expect("bind"); + tokio::net::TcpListener::bind("127.0.0.1:0").await.expect("bind"); let addr = tcp.local_addr().expect("local_addr"); let acceptor = HttpAcceptor { log: slog::Logger::root(slog::Discard, o!()), tcp }; From 6d0c5df43cb49aea332daa7259638a1d52bd9b5a Mon Sep 17 00:00:00 2001 From: "Adam H. Leventhal" Date: Thu, 26 Sep 2024 11:06:27 -0700 Subject: [PATCH 27/29] cargo.lock --- Cargo.lock | 50 ++++---------------------------------------------- 1 file changed, 4 insertions(+), 46 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 94f846a1e..9bba05e15 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -726,9 +726,9 @@ dependencies = [ [[package]] name = "http" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", @@ -837,9 +837,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.7" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9" +checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" dependencies = [ "bytes", "futures-channel", @@ -850,7 +850,6 @@ dependencies = [ "pin-project-lite", "socket2", "tokio", - "tower", "tower-service", "tracing", ] @@ -1205,26 +1204,6 @@ dependencies = [ "sha2", ] -[[package]] -name = "pin-project" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.75", -] - [[package]] name = "pin-project-lite" version = "0.2.12" @@ -2046,27 +2025,6 @@ dependencies = [ "winnow", ] -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "pin-project", - "pin-project-lite", - "tokio", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - [[package]] name = "tower-service" version = "0.3.1" From 21769f2e21d77e5a7a9f3d401cf2cd51d8eead4c Mon Sep 17 00:00:00 2001 From: "Adam H. Leventhal" Date: Thu, 26 Sep 2024 11:36:44 -0700 Subject: [PATCH 28/29] fix changelog --- CHANGELOG.adoc | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 63d2a4a6a..20c4ae483 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -15,6 +15,16 @@ https://github.com/oxidecomputer/dropshot/compare/v0.11.0\...HEAD[Full list of commits] +=== Breaking Changes + +* https://github.com/oxidecomputer/dropshot/pull/1028[#1028] Updates Dropshot for `hyper` 1.0 and `http` 1.0. Since consumers provide Dropshot with values from `hyper` and `http`, you'll need to update to `hyper` 1.0 and `http` 1.0 (or newer compatible versions), too. ++ +**What you need to do:** +1. Update your crate's dependencies on `hyper` and `http` to 1.0 (or a newer compatible version) in Cargo.toml. +2. Replace any references to `hyper::Body` with `dropshot::Body` instead. ++ +There are no other known breaking changes in these crates that affect Dropshot. If you have any trouble with this upgrade, please let us know by filing an issue. + == 0.11.0 (released 2024-08-21) https://github.com/oxidecomputer/dropshot/compare/v0.10.1\...v0.11.0[Full list of commits] @@ -37,16 +47,6 @@ generated OpenAPI spec. * Trait-based API definitions. See https://docs.rs/dropshot_endpoint/latest/dropshot_endpoint/attr.api_description.html[the documentation] for details. * https://github.com/oxidecomputer/dropshot/pull/1049[#1049] Added `HttpResponse::status_code()` -=== Breaking Changes - -* https://github.com/oxidecomputer/dropshot/pull/1028[#1028] Updates Dropshot for `hyper` 1.0 and `http` 1.0. Since consumers provide Dropshot with values from `hyper` and `http`, you'll need to update to `hyper` 1.0 and `http` 1.0 (or newer compatible versions), too. -+ -**What you need to do:** -1. Update your crate's dependencies on `hyper` and `http` to 1.0 (or a newer compatible version) in Cargo.toml. -2. Replace any references to `hyper::Body` with `dropshot::Body` instead. -+ -There are no other known breaking changes in these crates that affect Dropshot. If you have any trouble with this upgrade, please let us know by filing an issue. - == 0.10.1 (released 2024-05-15) https://github.com/oxidecomputer/dropshot/compare/v0.10.0\...v0.10.1[Full list of commits] From 35c897b26aa0f9241c5b523a84ec009e8999ba97 Mon Sep 17 00:00:00 2001 From: "Adam H. Leventhal" Date: Thu, 26 Sep 2024 11:45:13 -0700 Subject: [PATCH 29/29] update changelog again --- CHANGELOG.adoc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 20c4ae483..10f79209c 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -18,11 +18,13 @@ https://github.com/oxidecomputer/dropshot/compare/v0.11.0\...HEAD[Full list of c === Breaking Changes * https://github.com/oxidecomputer/dropshot/pull/1028[#1028] Updates Dropshot for `hyper` 1.0 and `http` 1.0. Since consumers provide Dropshot with values from `hyper` and `http`, you'll need to update to `hyper` 1.0 and `http` 1.0 (or newer compatible versions), too. -+ -**What you need to do:** + +==== Upgrading to hyper 1.0 + 1. Update your crate's dependencies on `hyper` and `http` to 1.0 (or a newer compatible version) in Cargo.toml. 2. Replace any references to `hyper::Body` with `dropshot::Body` instead. -+ +3. You may need to update your use of `dropshot::Body`; the `http-body-util` can be helpful. + There are no other known breaking changes in these crates that affect Dropshot. If you have any trouble with this upgrade, please let us know by filing an issue. == 0.11.0 (released 2024-08-21)