Skip to content

Commit e8703c8

Browse files
committed
Bump version to v0.1.335; add RELEASES.md
Update workspace version to v0.1.335 and refresh lockfile/package versions accordingly. Add RELEASES.md containing recent release notes and highlights (v0.1.333 and prior). Also include a minor whitespace update in crates/rustapi-core/Cargo.toml.
2 parents b297d80 + f3bae58 commit e8703c8

11 files changed

Lines changed: 422 additions & 61 deletions

File tree

Cargo.lock

Lines changed: 48 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,15 @@ members = [
1616
]
1717

1818
[workspace.package]
19+
<<<<<<< HEAD
1920
<<<<<<< Updated upstream
2021
version = "0.1.300"
2122
=======
2223
version = "0.1.335"
2324
>>>>>>> Stashed changes
25+
=======
26+
version = "0.1.333"
27+
>>>>>>> f3bae5807de9f33f6f2de443f10e2c26cd15510d
2428
edition = "2021"
2529
authors = ["RustAPI Contributors"]
2630
license = "MIT OR Apache-2.0"
@@ -141,8 +145,12 @@ strip = false
141145

142146

143147

148+
<<<<<<< HEAD
144149
<<<<<<< Updated upstream
145150
=======
146151

147152

148153
>>>>>>> Stashed changes
154+
=======
155+
156+
>>>>>>> f3bae5807de9f33f6f2de443f10e2c26cd15510d

crates/rustapi-core/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,12 @@ replay = ["dep:async-trait"]
110110

111111

112112

113+
<<<<<<< HEAD
113114
<<<<<<< Updated upstream
114115
=======
115116

116117

117118
>>>>>>> Stashed changes
119+
=======
120+
121+
>>>>>>> f3bae5807de9f33f6f2de443f10e2c26cd15510d

crates/rustapi-core/src/app.rs

Lines changed: 46 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,20 +1072,7 @@ impl RustApi {
10721072
server.run().await
10731073
}
10741074

1075-
/// Run both HTTP/1.1 and HTTP/3 servers simultaneously
1076-
///
1077-
/// This allows clients to use either protocol. The HTTP/1.1 server
1078-
/// will advertise HTTP/3 availability via Alt-Svc header.
1079-
///
1080-
/// # Example
1081-
///
1082-
/// ```rust,ignore
1083-
/// RustApi::new()
1084-
/// .route("/", get(hello))
1085-
/// .run_dual_stack("0.0.0.0:8080", Http3Config::new("cert.pem", "key.pem"))
1086-
/// .await
1087-
/// ```
1088-
/// Configure HTTP/3 support
1075+
/// Configure HTTP/3 support for `run_http3` and `run_dual_stack`.
10891076
///
10901077
/// # Example
10911078
///
@@ -1101,10 +1088,10 @@ impl RustApi {
11011088
self
11021089
}
11031090

1104-
/// Run both HTTP/1.1 and HTTP/3 servers simultaneously
1091+
/// Run both HTTP/1.1 (TCP) and HTTP/3 (QUIC/UDP) simultaneously.
11051092
///
1106-
/// This allows clients to use either protocol. The HTTP/1.1 server
1107-
/// will advertise HTTP/3 availability via Alt-Svc header.
1093+
/// The HTTP/3 listener is bound to the same host and port as `http_addr`
1094+
/// so clients can upgrade to either protocol on one endpoint.
11081095
///
11091096
/// # Example
11101097
///
@@ -1118,22 +1105,53 @@ impl RustApi {
11181105
#[cfg(feature = "http3")]
11191106
pub async fn run_dual_stack(
11201107
mut self,
1121-
_http_addr: &str,
1108+
http_addr: &str,
11221109
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
1123-
// TODO: Dual-stack requires Router, LayerStack, InterceptorChain to implement Clone.
1124-
// For now, we only run HTTP/3.
1125-
// In the future, we can either:
1126-
// 1. Make Router/LayerStack/InterceptorChain Clone
1127-
// 2. Use Arc<RwLock<...>> pattern
1128-
// 3. Create shared state mechanism
1129-
1130-
let config = self
1110+
use std::sync::Arc;
1111+
1112+
let mut config = self
11311113
.http3_config
11321114
.take()
11331115
.ok_or("HTTP/3 config not set. Use .with_http3(...)")?;
11341116

1135-
tracing::warn!("run_dual_stack currently only runs HTTP/3. HTTP/1.1 support coming soon.");
1136-
self.run_http3(config).await
1117+
let http_socket: std::net::SocketAddr = http_addr.parse()?;
1118+
config.bind_addr = if http_socket.ip().is_ipv6() {
1119+
format!("[{}]", http_socket.ip())
1120+
} else {
1121+
http_socket.ip().to_string()
1122+
};
1123+
config.port = http_socket.port();
1124+
let http_addr = http_socket.to_string();
1125+
1126+
// Apply status page if configured
1127+
self.apply_status_page();
1128+
1129+
// Apply body limit layer if configured
1130+
if let Some(limit) = self.body_limit {
1131+
self.layers.prepend(Box::new(BodyLimitLayer::new(limit)));
1132+
}
1133+
1134+
let router = Arc::new(self.router);
1135+
let layers = Arc::new(self.layers);
1136+
let interceptors = Arc::new(self.interceptors);
1137+
1138+
let http1_server =
1139+
Server::from_shared(router.clone(), layers.clone(), interceptors.clone());
1140+
let http3_server =
1141+
crate::http3::Http3Server::new(&config, router, layers, interceptors).await?;
1142+
1143+
tracing::info!(
1144+
http1_addr = %http_addr,
1145+
http3_addr = %config.socket_addr(),
1146+
"Starting dual-stack HTTP/1.1 + HTTP/3 servers"
1147+
);
1148+
1149+
tokio::try_join!(
1150+
http1_server.run_with_shutdown(&http_addr, std::future::pending::<()>()),
1151+
http3_server.run_with_shutdown(std::future::pending::<()>()),
1152+
)?;
1153+
1154+
Ok(())
11371155
}
11381156
}
11391157

crates/rustapi-core/src/server.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,19 @@ impl Server {
3434
}
3535
}
3636

37+
#[cfg(feature = "http3")]
38+
pub fn from_shared(
39+
router: Arc<Router>,
40+
layers: Arc<LayerStack>,
41+
interceptors: Arc<InterceptorChain>,
42+
) -> Self {
43+
Self {
44+
router,
45+
layers,
46+
interceptors,
47+
}
48+
}
49+
3750
/// Run the server
3851
pub async fn run(self, addr: &str) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
3952
self.run_with_shutdown(addr, std::future::pending()).await

crates/rustapi-openapi/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Automated API specifications and Swagger UI integration for RustAPI.
1111

1212
1. **Reflection**: RustAPI macros collect metadata about your routes (path, method, input types, output types) at compile time
1313
2. **Schema Gen**: Uses RustAPI's native schema engine to generate OpenAPI-compatible JSON Schemas
14-
3. **Spec Build**: At runtime, assembles the full OpenAPI 3.0 JSON specification
14+
3. **Spec Build**: At runtime, assembles the full OpenAPI 3.1 JSON specification with schema ref integrity checks
1515
4. **UI Serve**: Embeds the Swagger UI assets and serves them at your specified path
1616

1717
## Route Metadata Macros

0 commit comments

Comments
 (0)