Skip to content

Commit

Permalink
Merge pull request #269 from c410-f3r/misc
Browse files Browse the repository at this point in the history
Allow the building for ESP32 targets
  • Loading branch information
c410-f3r authored Nov 15, 2024
2 parents bceec41 + dbd36e6 commit 73852f7
Show file tree
Hide file tree
Showing 87 changed files with 2,336 additions and 1,124 deletions.
529 changes: 417 additions & 112 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ A collection of different transport implementations and related tools focused pr
10. [WebSocket Client/Server](https://c410-f3r.github.io/wtx/web-socket/index.html)
11. [WebSocket over HTTP/2](https://c410-f3r.github.io/wtx/web-socket-over-http2/index.html)

Every feature is optional and must be set at compile time. Please see the intended documentation for further information.

Embedded devices with a working heap allocator can use this `no_std` crate.

## Performance
Expand Down
3 changes: 3 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Security policy

You can report security vulnerabilities with as much information as possible through our [security page](https://github.com/c410-f3r/wtx/security). Security advisories will be available at <https://github.com/c410-f3r/wtx/security/advisories>.
3 changes: 3 additions & 0 deletions clippy.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
disallowed-methods = [
"<[u8]>::rsplit",
"<[u8]>::split",
"alloc::sync::Arc",
"core::str::from_utf8",
"core::sync::atomic::AtomicU64",
"core::sync::atomic::AtomicUsize",
"str::rsplit",
]
disallowed-types = [
Expand Down
2 changes: 2 additions & 0 deletions wtx-docs/src/grpc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ Basic implementation that currently only supports unary calls. gRPC is an high-p

Due to the lack of an official parser, the definitions of a `Service` must be manually typed.

Independent benchmarks are available <https://github.com/LesnyRumcajs/grpc_bench>.

To use this functionality, it is necessary to activate the `grpc` feature.

## Client Example
Expand Down
2 changes: 1 addition & 1 deletion wtx-docs/src/web-socket-over-http2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ While HTTP/2 inherently supports full-duplex communication, web browsers typical
1. Servers can efficiently handle multiple concurrent streams within a single TCP connection
2. Client applications can continue using existing WebSocket APIs without modification

For this particular scenario, the `no-masking` parameter defined in <https://datatracker.ietf.org/doc/html/draft-damjanovic-websockets-nomasking-02> is also supported.
For this particular scenario the `no-masking` parameter defined in <https://datatracker.ietf.org/doc/html/draft-damjanovic-websockets-nomasking-02> is also supported.

To use this functionality, it is necessary to activate the `http2` and `web-socket` features.

Expand Down
3 changes: 2 additions & 1 deletion wtx-instances/generic-examples/grpc-server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@ async fn main() -> wtx::Result<()> {
)?;
ServerFrameworkBuilder::new(router)
.with_req_aux(|| QuickProtobuf::default())
.listen_tokio_rustls(
.tokio_rustls(
(wtx_instances::CERT, wtx_instances::KEY),
&wtx_instances::host_from_args(),
Xorshift64::from(simple_seed()),
|error| eprintln!("{error}"),
|_| Ok(()),
)
.await
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ async fn main() -> wtx::Result<()> {
let router = Router::new(wtx::paths!(("/hello", get(hello))), CorsMiddleware::permissive())?;
ServerFrameworkBuilder::new(router)
.without_aux()
.listen_tokio("0.0.0.0:9000", Xorshift64::from(simple_seed()), |error: wtx::Error| {
eprintln!("{error:?}")
})
.tokio(
"0.0.0.0:9000",
Xorshift64::from(simple_seed()),
|error: wtx::Error| eprintln!("{error:?}"),
|_| Ok(()),
)
.await?;
Ok(())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@ async fn main() -> wtx::Result<()> {
Router::paths(wtx::paths!(("/permanent", get(permanent)), ("/temporary", get(temporary))))?;
ServerFrameworkBuilder::new(router)
.without_aux()
.listen_tokio(&wtx_instances::host_from_args(), Xorshift64::from(simple_seed()), |error| {
eprintln!("{error}")
})
.tokio(
&wtx_instances::host_from_args(),
Xorshift64::from(simple_seed()),
|error| eprintln!("{error}"),
|_| Ok(()),
)
.await
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ async fn main() -> wtx::Result<()> {
let rng_clone = rng.clone();
ServerFrameworkBuilder::new(router)
.with_conn_aux(move || (session.clone(), rng_clone.clone()))
.listen_tokio("0.0.0.0:9000", rng, |err| eprintln!("{err:?}"))
.tokio("0.0.0.0:9000", rng, |err| eprintln!("{err:?}"), |_| Ok(()))
.await?;
Ok(())
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! An HTTP server framework showcasing nested routes, request middlewares, response
//! middlewares, dynamic routes, PostgreSQL connections and JSON deserialization/serialization.
//! An HTTP server framework showcasing nested routes, middlewares, manual streams, dynamic routes,
//! PostgreSQL connections and JSON deserialization/serialization.
//!
//! Currently, only HTTP/2 is supported.
//!
Expand All @@ -11,15 +11,16 @@ extern crate wtx;
extern crate wtx_instances;

use core::{fmt::Write, ops::ControlFlow};
use tokio::net::TcpStream;
use tokio::net::{tcp::OwnedWriteHalf, TcpStream};
use wtx::{
database::{Executor, Record},
http::{
server_framework::{
get, post, Middleware, PathOwned, Router, SerdeJson, ServerFrameworkBuilder, StateClean,
},
ReqResBuffer, Request, Response, StatusCode,
ManualStream, ReqResBuffer, Request, Response, StatusCode,
},
http2::{Http2Buffer, Http2DataTokio, Http2ErrorCode, ServerStream},
misc::{simple_seed, Xorshift64},
pool::{PostgresRM, SimplePoolTokio},
};
Expand All @@ -35,14 +36,18 @@ async fn main() -> wtx::Result<()> {
"/say",
Router::new(wtx::paths!(("/hello", get(hello)), ("/world", get(world))), CustomMiddleware,)?,
),
("/stream", get(stream)),
))?;
let rm = PostgresRM::tokio("postgres://USER:PASSWORD@localhost/DB_NAME".into());
let pool = Pool::new(4, rm);
ServerFrameworkBuilder::new(router)
.with_req_aux(move || pool.clone())
.listen_tokio(&wtx_instances::host_from_args(), Xorshift64::from(simple_seed()), |error| {
eprintln!("{error:?}")
})
.tokio(
&wtx_instances::host_from_args(),
Xorshift64::from(simple_seed()),
|error| eprintln!("{error:?}"),
|_| Ok(()),
)
.await
}

Expand Down Expand Up @@ -76,6 +81,17 @@ async fn json(_: SerdeJson<DeserializeExample>) -> wtx::Result<SerdeJson<Seriali
Ok(SerdeJson(SerializeExample { _baz: [1, 2, 3, 4] }))
}

async fn stream(
mut manual_stream: ManualStream<
(),
ServerStream<Http2DataTokio<Http2Buffer, OwnedWriteHalf, false>>,
Pool,
>,
) -> wtx::Result<()> {
manual_stream.stream.common().send_go_away(Http2ErrorCode::NoError).await;
Ok(())
}

async fn world() -> &'static str {
"world"
}
Expand Down
35 changes: 21 additions & 14 deletions wtx-instances/http2-examples/http2-server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ use tokio::{io::WriteHalf, net::TcpStream};
use tokio_rustls::server::TlsStream;
use wtx::{
http::{
AutoStream, ManualServerStreamTokio, OptionedServer, ReqResBuffer, Response, StatusCode,
StreamMode,
is_web_socket_handshake, AutoStream, ManualServerStreamTokio, OperationMode, OptionedServer,
ReqResBuffer, Response, StatusCode,
},
http2::{is_web_socket_handshake, Http2Buffer, Http2Params, WebSocketOverStream},
http2::{Http2Buffer, Http2Params, WebSocketOverStream},
misc::{simple_seed, TokioRustlsAcceptor, Vector, Xorshift64},
web_socket::{Frame, OpCode},
};
Expand All @@ -33,14 +33,17 @@ async fn main() -> wtx::Result<()> {
},
|error| eprintln!("{error}"),
manual,
|| Ok((Vector::new(), ReqResBuffer::empty())),
|headers, method, protocol| {
Ok(if is_web_socket_handshake(headers, method, protocol) {
StreamMode::Manual(())
} else {
StreamMode::Auto
})
|_, protocol, req, _| {
Ok((
(),
if is_web_socket_handshake(&mut req.rrd.headers, req.method, protocol) {
OperationMode::Manual
} else {
OperationMode::Auto
},
))
},
|| Ok((Vector::new(), ReqResBuffer::empty())),
(
|| {
TokioRustlsAcceptor::without_client_auth()
Expand All @@ -54,17 +57,21 @@ async fn main() -> wtx::Result<()> {
.await
}

async fn auto(mut ha: AutoStream<(), Vector<u8>>) -> Result<Response<ReqResBuffer>, wtx::Error> {
async fn auto(
_: (),
mut ha: AutoStream<(), Vector<u8>>,
) -> Result<Response<ReqResBuffer>, wtx::Error> {
ha.req.rrd.clear();
Ok(ha.req.into_response(StatusCode::Ok))
}

async fn manual(
mut hm: ManualServerStreamTokio<(), Http2Buffer, Vector<u8>, (), WriteHalf<TlsStream<TcpStream>>>,
_: (),
mut hm: ManualServerStreamTokio<(), Http2Buffer, Vector<u8>, WriteHalf<TlsStream<TcpStream>>>,
) -> Result<(), wtx::Error> {
let rng = Xorshift64::from(simple_seed());
hm.headers.clear();
let mut wos = WebSocketOverStream::new(&hm.headers, false, rng, hm.stream).await?;
hm.req.rrd.headers.clear();
let mut wos = WebSocketOverStream::new(&hm.req.rrd.headers, false, rng, hm.stream).await?;
loop {
let mut frame = wos.read_frame(&mut hm.stream_aux).await?;
match (frame.op_code(), frame.text_payload()) {
Expand Down
9 changes: 5 additions & 4 deletions wtx-instances/http2-examples/http2-web-socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ extern crate wtx_instances;
use core::mem;
use tokio::net::TcpListener;
use wtx::{
http::{Headers, ReqResBuffer},
http2::{is_web_socket_handshake, Http2Buffer, Http2Params, Http2Tokio, WebSocketOverStream},
http::{is_web_socket_handshake, Headers, ReqResBuffer},
http2::{Http2Buffer, Http2Params, Http2Tokio, WebSocketOverStream},
misc::{simple_seed, Either, TokioRustlsAcceptor, Vector, Xorshift64},
web_socket::{Frame, OpCode},
};
Expand All @@ -34,8 +34,9 @@ async fn main() -> wtx::Result<()> {
.await?;
tokio::spawn(frame_reader);
let (mut stream, headers_opt) = match http2
.stream(ReqResBuffer::empty(), |headers, method, protocol| {
is_web_socket_handshake(headers, method, protocol).then(|| mem::take(headers))
.stream(ReqResBuffer::empty(), |req, protocol| {
let rslt = is_web_socket_handshake(&req.rrd.headers, req.method, protocol);
rslt.then(|| mem::take(&mut req.rrd.headers))
})
.await?
{
Expand Down
11 changes: 6 additions & 5 deletions wtx-instances/src/bin/h2load.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
use tokio::net::tcp::OwnedWriteHalf;
use wtx::{
http::{
AutoStream, ManualServerStreamTokio, OptionedServer, ReqResBuffer, Response, StatusCode,
StreamMode,
AutoStream, ManualServerStreamTokio, OperationMode, OptionedServer, ReqResBuffer, Response,
StatusCode,
},
http2::{Http2Buffer, Http2Params},
misc::{simple_seed, Xorshift64},
Expand All @@ -28,19 +28,20 @@ async fn main() -> wtx::Result<()> {
},
|error| eprintln!("{error}"),
manual,
|_, _, _, _| Ok(((), OperationMode::Auto)),
|| Ok(((), ReqResBuffer::empty())),
|_, _, _| Ok(StreamMode::Auto),
(|| Ok(()), |_| {}, |_, stream| async move { Ok(stream.into_split()) }),
)
.await
}
async fn auto(mut ha: AutoStream<(), ()>) -> Result<Response<ReqResBuffer>, wtx::Error> {
async fn auto(_: (), mut ha: AutoStream<(), ()>) -> Result<Response<ReqResBuffer>, wtx::Error> {
ha.req.rrd.clear();
Ok(ha.req.into_response(StatusCode::Ok))
}

async fn manual(
_: ManualServerStreamTokio<(), Http2Buffer, (), (), OwnedWriteHalf>,
_: (),
_: ManualServerStreamTokio<(), Http2Buffer, (), OwnedWriteHalf>,
) -> Result<(), wtx::Error> {
Ok(())
}
11 changes: 6 additions & 5 deletions wtx-instances/src/bin/h2spec-high-server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
use tokio::net::tcp::OwnedWriteHalf;
use wtx::{
http::{
AutoStream, ManualServerStreamTokio, OptionedServer, ReqResBuffer, Response, StatusCode,
StreamMode,
AutoStream, ManualServerStreamTokio, OperationMode, OptionedServer, ReqResBuffer, Response,
StatusCode,
},
http2::{Http2Buffer, Http2Params},
misc::{simple_seed, Xorshift64},
Expand All @@ -20,21 +20,22 @@ async fn main() -> wtx::Result<()> {
|| Ok(((), Http2Buffer::new(Xorshift64::from(simple_seed())), Http2Params::default())),
|error| eprintln!("{error}"),
manual,
|_, _, _, _| Ok(((), OperationMode::Auto)),
|| Ok(((), ReqResBuffer::empty())),
|_, _, _| Ok(StreamMode::Auto),
(|| Ok(()), |_| {}, |_, stream| async move { Ok(stream.into_split()) }),
)
.await
}

async fn auto(mut ha: AutoStream<(), ()>) -> Result<Response<ReqResBuffer>, wtx::Error> {
async fn auto(_: (), mut ha: AutoStream<(), ()>) -> Result<Response<ReqResBuffer>, wtx::Error> {
ha.req.rrd.clear();
ha.req.rrd.body.extend_from_copyable_slice(b"Hello")?;
Ok(ha.req.into_response(StatusCode::Ok))
}

async fn manual(
_: ManualServerStreamTokio<(), Http2Buffer, (), (), OwnedWriteHalf>,
_: (),
_: ManualServerStreamTokio<(), Http2Buffer, (), OwnedWriteHalf>,
) -> Result<(), wtx::Error> {
Ok(())
}
2 changes: 1 addition & 1 deletion wtx-instances/src/bin/h2spec-low-server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ async fn main() -> wtx::Result<()> {
let _jh = tokio::spawn(frame_reader);
loop {
let (mut http2_stream, headers) = match http2
.stream(ReqResBuffer::default(), |headers, _, _| mem::take(headers))
.stream(ReqResBuffer::default(), |req, _| mem::take(&mut req.rrd.headers))
.await?
{
Either::Left(_) => return wtx::Result::Ok(()),
Expand Down
Loading

0 comments on commit 73852f7

Please sign in to comment.