* refactor: move away from legacy `hyper::body::HttpBody`
this is an incremental step away from hyper 0.14's request and response
body interfaces, and towards the 1.0 body types. see
<https://github.com/linkerd/linkerd2/issues/8733> for more information
about upgrading to hyper 1.0.
hyper 0.14 provides a `hyper::body::Body` that is removed in the 1.0
interface. `hyper-util` now provides a workable default body type. hyper
0.14 reëxports `http_body::Body` as `HttpBody`. hyper 1.0 reëxports this
trait as `hyper::body::Body` without any renaming.
this commit moves application code away from hyper's legacy `Body` type
and the `HttpBody` trait alias. this commit moves assorted interfaces
towards the boxed `BoxBody` type instead. when possible, code is tweaked
such that it refers to the reëxport in `linkerd-proxy-http`, rather than
directly through `hyper`.
NB: this commit is based upon #3466.
Signed-off-by: katelyn martin <kate@buoyant.io>
* feat(http/box): `BoxBody::from_static` constructor
this commit relates to review feedback offered here:
https://github.com/linkerd/linkerd2-proxy/pull/3467#discussion_r1888979001
it is slightly ungainly to place a static string into a BoxBody,
something that is a fairly common pattern throughout e.g. our admin
server.
to help nudge the compiler to infer a `B: Body` of `String`, various
code follows a common convention of calling e.g.
`BoxBody:🆕:<String>("ready\n".into())` or,
`BoxBody::new("ready\n".to_string())`.
this commit helps reduce that boilerplate by adding a `from_static(..)`
constructor that accepts a static string.
```rust
/// Returns a [`BoxBody`] with the contents of a static string.
pub fn from_static(body: &'static str) -> Self {
Self::new(body.to_string())
}
```
Co-authored-by: Scott Fleener <scott@buoyant.io>
Signed-off-by: katelyn martin <kate@buoyant.io>
* refactor(app/admin): outline json bytes body construction
see <https://github.com/linkerd/linkerd2-proxy/pull/3467#discussion_r1888980453>.
@sfleen points out this unfortunate part of our diff:
```diff
- .body(json.into())
+ .body(BoxBody::new(http_body::Full::new(bytes::Bytes::from(json))))
```
this *is* a bit of an unfortunate edge, where boxing up a body feels
especially cumbersome.
this commit takes an attempt at tweaking the function in question so
that this large nested expression reads a bit nicer.
first, to justify why this gets a little more involved: hyper will no
longer provide the `Body` type after 1.0, so we are tasked with
providing our own body. for our purposes, `Full` works because we have a
single chunk of bytes in hand.
in order to create a `Full`, we must provide a `D: Buf`, which can be
satisfied by the following types:
<https://docs.rs/bytes/1.6.0/bytes/buf/trait.Buf.html#foreign-impls>
most simply, we can cast our vector of bytes into a `Bytes`.
with all of this in hand, we can hoist this creation of the body up out
of the `match` arm, and use `Result::map` to apply these constructors in
sequential order:
```rust
// Serialize the value into JSON, and then place the bytes in a boxed response body.
let json = serde_json::to_vec(val)
.map(Bytes::from)
.map(http_body::Full::new)
.map(BoxBody::new);
```
Signed-off-by: katelyn martin <kate@buoyant.io>
---------
Signed-off-by: katelyn martin <kate@buoyant.io>
Co-authored-by: Scott Fleener <scott@buoyant.io>