Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wtx 0.20.0 #229

Merged
merged 2 commits into from
Sep 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion wtx-instances/generic-examples/grpc-client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use wtx_instances::grpc_bindings::wtx::{GenericRequest, GenericResponse};
#[tokio::main]
async fn main() -> wtx::Result<()> {
let mut client = Client::new(ClientFramework::tokio(1).build(), QuickProtobuf);
let mut rrb = ReqResBuffer::default();
let mut rrb = ReqResBuffer::empty();
rrb.uri.reset(format_args!("http://127.0.0.1:9000"))?;
let res = client
.send_unary_req(
Expand Down
2 changes: 1 addition & 1 deletion wtx-instances/generic-examples/http-client-framework.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use wtx::{
#[tokio::main]
async fn main() -> wtx::Result<()> {
let uri = Uri::new("http://www.example.com");
let buffer = ReqResBuffer::default();
let buffer = ReqResBuffer::empty();
let client = ClientFramework::tokio(1).build();
let res = client.send(Method::Get, buffer, &uri.to_ref()).await?;
println!("{}", from_utf8_basic(&res.rrd.data)?);
Expand Down
2 changes: 1 addition & 1 deletion wtx-instances/generic-examples/http2-client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ async fn main() -> wtx::Result<()> {
)
.await?;
let _jh = tokio::spawn(frame_reader);
let rrb = ReqResBuffer::default();
let rrb = ReqResBuffer::empty();
let mut stream = http2.stream().await?;
stream.send_req(Request::http2(Method::Get, b"Hello!"), &uri.to_ref()).await?;
let (res_rrb, opt) = stream.recv_res(rrb).await?;
Expand Down
2 changes: 1 addition & 1 deletion wtx-instances/generic-examples/http2-server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ async fn main() -> wtx::Result<()> {
|| Ok(((), Http2Buffer::new(StdRng::default()), Http2Params::default())),
|error| eprintln!("{error}"),
handle,
|| Ok(((), ReqResBuffer::default())),
|| Ok(((), ReqResBuffer::empty())),
(
|| {
TokioRustlsAcceptor::without_client_auth()
Expand Down
2 changes: 1 addition & 1 deletion wtx-instances/src/bin/h2spec-server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ async fn main() -> wtx::Result<()> {
|| Ok(((), Http2Buffer::new(StdRng::default()), Http2Params::default())),
|error| eprintln!("{error}"),
handle,
|| Ok(((), ReqResBuffer::default())),
|| Ok(((), ReqResBuffer::empty())),
(|| Ok(()), |_| {}, |_, stream| async move { Ok(stream.into_split()) }),
)
.await
Expand Down
2 changes: 1 addition & 1 deletion wtx-ui/src/http_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub(crate) async fn http_client(http_client: HttpClient) {
_ => tracing_tree_init(Some("trace")).unwrap(),
}
let client = ClientFramework::tokio_rustls(1).build();
let mut rrb = ReqResBuffer::default();
let mut rrb = ReqResBuffer::empty();
for pair in header {
let (name, values) = str_split_once1(&pair, b':').unwrap();
rrb
Expand Down
2 changes: 1 addition & 1 deletion wtx/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ license = "Apache-2.0"
name = "wtx"
readme = "README.md"
repository = "https://github.com/c410-f3r/wtx"
version = "0.19.0"
version = "0.20.0"

[package.metadata.docs.rs]
all-features = true
2 changes: 1 addition & 1 deletion wtx/src/client_api_framework/network/transport/wtx_http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ where
[elem._as_str().as_bytes()],
))?;
}
let mut rrb = ReqResBuffer::default();
let mut rrb = ReqResBuffer::empty();
mem::swap(&mut rrb.data, &mut pkgs_aux.byte_buffer);
mem::swap(&mut rrb.headers, headers);
let mut res = (*client).send(*method, rrb, &uri.to_ref()).await?;
Expand Down
16 changes: 8 additions & 8 deletions wtx/src/grpc/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,17 +80,17 @@ where

#[inline]
fn push_headers(headers: &mut Headers) -> crate::Result<()> {
let array = [
headers.push_from_iter_many([
Header::from_name_and_value(
KnownHeaderName::ContentType.into(),
["application/grpc".as_bytes()],
["application/grpc".as_bytes()].into_iter(),
),
Header::from_name_and_value(KnownHeaderName::Te.into(), ["trailers".as_bytes()]),
Header::from_name_and_value(KnownHeaderName::UserAgent.into(), [WTX_USER_AGENT.as_bytes()]),
];
for header in array {
headers.push_from_iter(header)?;
}
Header::from_name_and_value(KnownHeaderName::Te.into(), ["trailers".as_bytes()].into_iter()),
Header::from_name_and_value(
KnownHeaderName::UserAgent.into(),
[WTX_USER_AGENT.as_bytes()].into_iter(),
),
])?;
Ok(())
}
}
22 changes: 12 additions & 10 deletions wtx/src/grpc/grpc_res_middleware.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,18 @@ where
ra: &mut GrpcManager<DRSR>,
res: Response<&mut RRD>,
) -> Result<(), E> {
res.rrd.headers_mut().push_from_iter(Header::from_name_and_value(
KnownHeaderName::ContentType.into(),
[Mime::Grpc.as_str().as_bytes()],
))?;
res.rrd.headers_mut().push_from_iter(Header {
is_sensitive: false,
is_trailer: true,
name: b"grpc-status",
value: [ra.status_code_mut().number_as_str().as_bytes()],
})?;
res.rrd.headers_mut().push_from_iter_many([
Header::from_name_and_value(
KnownHeaderName::ContentType.into(),
[Mime::Grpc.as_str().as_bytes()].into_iter(),
),
Header {
is_sensitive: false,
is_trailer: true,
name: b"grpc-status",
value: [ra.status_code_mut().number_as_str().as_bytes()].into_iter(),
},
])?;
Ok(())
}
}
11 changes: 7 additions & 4 deletions wtx/src/http/client_framework/integration_tests.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
use crate::{
http::client_framework::{ClientFramework, ReqBuilder},
http::{
client_framework::{ClientFramework, ReqBuilder},
ReqResBuffer,
},
misc::Uri,
};

#[tokio::test]
async fn popular_sites() {
let _res = ReqBuilder::get()
let _res = ReqBuilder::get(ReqResBuffer::empty())
.send(&ClientFramework::tokio_rustls(1).build(), &Uri::new("https://github.com"))
.await
.unwrap();
let _res = ReqBuilder::get()
let _res = ReqBuilder::get(ReqResBuffer::empty())
.send(&ClientFramework::tokio_rustls(1).build(), &Uri::new("https://duckduckgo.com"))
.await
.unwrap();
let _res = ReqBuilder::get()
let _res = ReqBuilder::get(ReqResBuffer::empty())
.send(&ClientFramework::tokio_rustls(1).build(), &Uri::new("https://www.google.com"))
.await
.unwrap();
Expand Down
17 changes: 6 additions & 11 deletions wtx/src/http/client_framework/req_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ impl<RRB> ReqBuilder<RRB>
where
RRB: LeaseMut<ReqResBuffer>,
{
/// A instance suitable for `GET` requests.
#[inline]
pub fn get(rrb: RRB) -> Self {
Self { method: Method::Get, rrb }
}

/// Sends a request with inner parameters.
#[inline]
pub async fn send<HD, RL, RM, SW>(
Expand Down Expand Up @@ -82,14 +88,3 @@ where
Ok(self)
}
}

impl<RRB> ReqBuilder<RRB>
where
RRB: Default,
{
/// Performs a heap allocation to create a buffer suitable for `GET` requests.
#[inline]
pub fn get() -> Self {
Self { method: Method::Get, rrb: RRB::default() }
}
}
49 changes: 40 additions & 9 deletions wtx/src/http/headers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ impl Headers {
/// headers.push_from_fmt(Header::from_name_and_value(b"name", format_args!("{}", 1))).unwrap();
/// assert_eq!(headers.get_by_idx(0).unwrap(), Header::from_name_and_value(b"name", "1".as_bytes()));
/// ```
#[inline]
#[inline(always)]
pub fn push_from_fmt(&mut self, header: Header<'_, Arguments<'_>>) -> crate::Result<()> {
let header_begin = self.bytes.len();
#[cfg(feature = "std")]
Expand Down Expand Up @@ -188,7 +188,7 @@ impl Headers {
/// headers.push_from_iter(Header::from_name_and_value(b"name", ["value0".as_bytes(), "_value1".as_bytes()])).unwrap();
/// assert_eq!(headers.get_by_idx(0).unwrap(), Header::from_name_and_value(b"name", "value0_value1".as_bytes()));
/// ```
#[inline]
#[inline(always)]
pub fn push_from_iter<'bytes, V>(&mut self, header: Header<'bytes, V>) -> crate::Result<()>
where
V: IntoIterator<Item = &'bytes [u8]>,
Expand All @@ -206,10 +206,7 @@ impl Headers {
}

let iter = header.value.into_iter();
let mut header_len = header.name.len();
for elem in iter.clone() {
header_len = header_len.wrapping_add(elem.len());
}
let header_len = Self::header_len(header.name, iter.clone());
self.reserve(header_len, 1)?;
let header_begin = self.bytes.len();
let mut header_end = header_begin;
Expand All @@ -235,6 +232,26 @@ impl Headers {
Ok(())
}

/// Similarly to [`Self::push_from_iter`], pushes several headers.
#[inline]
pub fn push_from_iter_many<'bytes, const N: usize, V>(
&mut self,
headers: [Header<'bytes, V>; N],
) -> crate::Result<()>
where
V: Clone + Iterator<Item = &'bytes [u8]>,
{
let mut header_len: usize = 0;
for header in &headers {
header_len = header_len.wrapping_add(Self::header_len(header.name, header.value.clone()));
}
self.reserve(header_len, N)?;
for header in headers {
self.push_from_iter(header)?;
}
Ok(())
}

/// Reserves capacity for at least `bytes` more bytes to be inserted. The same thing is applied
/// to the number of headers.
///
Expand All @@ -252,15 +269,29 @@ impl Headers {
self.trailers
}

#[inline]
fn header_len<'bytes>(header_name: &[u8], iter: impl Iterator<Item = &'bytes [u8]>) -> usize {
let mut header_len = header_name.len();
for elem in iter {
header_len = header_len.wrapping_add(elem.len());
}
header_len
}

#[inline]
fn manage_trailers(is_trailer: bool, prev_len: usize, trailers: &mut Trailers) {
if is_trailer {
*trailers = match trailers {
*trailers = if is_trailer {
match trailers {
Trailers::Mixed => Trailers::Mixed,
Trailers::None => Trailers::Tail(prev_len),
Trailers::Tail(idx) => Trailers::Tail(*idx),
}
}
} else {
match trailers {
Trailers::Mixed | Trailers::Tail(_) => Trailers::Mixed,
Trailers::None => Trailers::None,
}
};
}

#[inline]
Expand Down
13 changes: 4 additions & 9 deletions wtx/src/http/req_res_buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ pub struct ReqResBuffer {
}

impl ReqResBuffer {
pub(crate) const fn empty() -> Self {
ReqResBuffer::new(Vector::new(), Headers::new(), UriString::_empty(String::new()))
/// Empty instance
#[inline]
pub const fn empty() -> Self {
Self::new(Vector::new(), Headers::new(), UriString::_empty(String::new()))
}

/// Constructor shortcut
Expand Down Expand Up @@ -116,13 +118,6 @@ impl ReqResDataMut for ReqResBuffer {
}
}

impl Default for ReqResBuffer {
#[inline]
fn default() -> Self {
Self::empty()
}
}

impl Lease<[u8]> for ReqResBuffer {
#[inline]
fn lease(&self) -> &[u8] {
Expand Down
4 changes: 2 additions & 2 deletions wtx/src/http/server_framework.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ where
move || Ok((CA::conn_aux(ca_cb())?, Http2Buffer::new(StdRng::default()), cp.to_hp())),
err_cb,
Self::handle,
move || Ok(((ra_cb.clone(), Arc::clone(&router)), ReqResBuffer::default())),
move || Ok(((ra_cb.clone(), Arc::clone(&router)), ReqResBuffer::empty())),
(|| Ok(()), |_| {}, |_, stream| async move { Ok(stream.into_split()) }),
)
.await
Expand All @@ -96,7 +96,7 @@ where
move || Ok((CA::conn_aux(ca_cb())?, Http2Buffer::new(StdRng::default()), cp.to_hp())),
err_cb,
Self::handle,
move || Ok(((ra_cb.clone(), router.clone()), ReqResBuffer::default())),
move || Ok(((ra_cb.clone(), Arc::clone(&router)), ReqResBuffer::empty())),
(
|| {
crate::misc::TokioRustlsAcceptor::without_client_auth()
Expand Down
4 changes: 2 additions & 2 deletions wtx/src/http2/tests/connections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ async fn connections() {
}

async fn client(uri: &UriString) {
let mut rrb = ReqResBuffer::default();
let mut rrb = ReqResBuffer::empty();
rrb.headers.reserve(6, 1).unwrap();
let (frame_header, mut http2) = Http2Tokio::connect(
Http2Buffer::new(NoStdRng::default()),
Expand Down Expand Up @@ -58,7 +58,7 @@ async fn server(uri: &UriString) {
let listener = TcpListener::bind(uri.hostname_with_implied_port()).await.unwrap();
let _server_jh = tokio::spawn(async move {
let (stream, _) = listener.accept().await.unwrap();
let mut rrb = ReqResBuffer::default();
let mut rrb = ReqResBuffer::empty();
let (frame_header, mut http2) = Http2Tokio::accept(
Http2Buffer::new(NoStdRng::default()),
Http2Params::default(),
Expand Down
6 changes: 3 additions & 3 deletions wtx/src/misc/bytes_fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ use core::{
str,
};

/// A wrapper that allows the formatting of byte slices through [`Display`].
/// A wrapper that allows the formatting of byte slices through [`Display`]. Should only
/// be used with vectors.
#[derive(Debug)]
pub struct BytesFmt<'bytes>(
/// Bytes
Expand All @@ -14,8 +15,7 @@ impl<'bytes> Display for BytesFmt<'bytes> {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
for elem in self.0.iter().copied() {
// SAFETY: `BytesFmt` is intended to be used with vectors but even if the caller uses a
// string container, the worse-case scenario will be a sequence of strange characters.
// SAFETY: `BytesFmt` is intended to be used with vectors.
f.write_str(unsafe { str::from_utf8_unchecked(&[elem]) })?;
}
Ok(())
Expand Down
Loading
Loading