高级功能宏
2025/11/29大约 6 分钟hyperlane-macros
高级功能宏
高级功能宏提供了更复杂和专业的 HTTP 服务器功能,包括主机过滤、Referer 检查、连接状态处理、WebSocket 流处理等。
主机和来源控制
#[host]
限制请求必须有特定的主机头。
用法
use hyperlane::*;
use hyperlane_macros::*;
#[route("/host")]
struct Host;
impl ServerHook for Host {
async fn new(_ctx: &Context) -> Self {
Self
}
#[prologue_macros(response_body("host string literal: localhost"), send)]
async fn handle(self, ctx: &Context) {}
}
impl Host {
#[host("localhost")]
async fn host_with_ref_self(&self, ctx: &Context) {}
}
#[host("localhost")]
async fn standalone_host_handler(ctx: &Context) {}说明
- 接受字符串字面量指定期望的主机值
- 应用于接受
&Context参数的异步函数 - 确保请求的主机头与指定值匹配
- 适用于虚拟主机和多站点部署
#[reject_host]
拒绝没有主机头的请求。
用法
use hyperlane::*;
use hyperlane_macros::*;
#[route("/reject_host")]
struct RejectHost;
impl ServerHook for RejectHost {
async fn new(_ctx: &Context) -> Self {
Self
}
#[prologue_macros(
reject_host("filter.localhost"),
response_body("host filter string literal")
)]
async fn handle(self, ctx: &Context) {}
}
impl RejectHost {
#[reject_host("filter.localhost")]
async fn reject_host_with_ref_self(&self, ctx: &Context) {}
}
#[reject_host("filter.localhost")]
async fn standalone_reject_host_handler(ctx: &Context) {}说明
- 无参数
- 确保请求有主机头存在
- 适用于需要主机验证的场景
- 过滤掉没有主机头的请求
#[referer]
限制请求必须有特定的 Referer。
用法
use hyperlane::*;
use hyperlane_macros::*;
#[route("/referer")]
struct Referer;
impl ServerHook for Referer {
async fn new(_ctx: &Context) -> Self {
Self
}
#[prologue_macros(
referer("http://localhost"),
response_body("referer string literal: http://localhost")
)]
async fn handle(self, ctx: &Context) {}
}
impl Referer {
#[referer("http://localhost")]
async fn referer_with_ref_self(&self, ctx: &Context) {}
}
#[referer("http://localhost")]
async fn standalone_referer_handler(ctx: &Context) {}说明
- 接受字符串字面量指定期望的 Referer 值
- 应用于接受
&Context参数的异步函数 - 确保 HTTP Referer 头与指定值匹配
- 适用于防盗链和来源验证
#[reject_referer]
拒绝有特定 Referer 的请求。
用法
use hyperlane::*;
use hyperlane_macros::*;
#[reject_referer("http://localhost")]
async fn standalone_reject_referer_handler(ctx: &Context) {}说明
- 接受字符串字面量指定要过滤的 Referer 值
- 应用于接受
&Context参数的异步函数 - 拒绝来自特定来源的请求
- 适用于防止恶意访问
连接状态处理
#[aborted]
处理已中止的请求场景。
用法
use hyperlane::*;
use hyperlane_macros::*;
#[route("/aborted")]
struct Aborted;
impl ServerHook for Aborted {
async fn new(_ctx: &Context) -> Self {
Self
}
#[aborted]
async fn handle(self, ctx: &Context) {}
}
impl Aborted {
#[aborted]
async fn aborted_with_ref_self(&self, ctx: &Context) {}
}
#[aborted]
async fn standalone_aborted_handler(ctx: &Context) {}说明
- 无参数
- 配置函数处理客户端中止请求的情况
- 为中断或取消的请求提供适当的处理
- 应用于接受
&Context参数的异步函数
#[closed]
处理已关闭连接的场景。
用法
use hyperlane::*;
use hyperlane_macros::*;
#[route("/closed")]
struct ClosedTest;
impl ServerHook for ClosedTest {
async fn new(_ctx: &Context) -> Self {
Self
}
#[closed]
async fn handle(self, ctx: &Context) {}
}
impl ClosedTest {
#[closed]
async fn closed_with_ref_self(&self, ctx: &Context) {}
}
#[closed]
async fn standalone_closed_handler(ctx: &Context) {}说明
- 无参数
- 配置函数处理连接已关闭的情况
- 为终止或断开的连接提供适当的处理
- 应用于接受
&Context参数的异步函数
WebSocket 流处理
#[ws_from_stream]
从流中处理 WebSocket 数据。
用法
use hyperlane::*;
use hyperlane_macros::*;
#[route("/ws")]
struct Websocket;
impl ServerHook for Websocket {
async fn new(_ctx: &Context) -> Self {
Self
}
#[ws]
#[ws_from_stream]
async fn handle(self, ctx: &Context) {
let body: RequestBody = ctx.get_request_body().await;
let body_list: Vec<ResponseBody> = WebSocketFrame::create_frame_list(&body);
ctx.send_body_list_with_data(&body_list).await.unwrap();
}
}
impl Websocket {
#[ws_from_stream]
async fn ws_from_stream_with_ref_self(&self, ctx: &Context) {}
}
#[ws_from_stream]
async fn standalone_ws_from_stream_handler(ctx: &Context) {}说明
- 无参数
- 用于从 WebSocket 流中读取数据
- 通常与
#[ws]宏配合使用 - 应用于接受
&Context参数的异步函数
#[stream]
包装函数体进行 WebSocket 流处理。
用法
use hyperlane::*;
use hyperlane_macros::*;
#[route("/ws1")]
struct Websocket1;
impl ServerHook for Websocket1 {
async fn new(_ctx: &Context) -> Self {
Self
}
#[stream(1024)]
async fn handle(self, ctx: &Context) {
// WebSocket 处理逻辑
}
}
impl Websocket1 {
#[stream]
async fn stream_with_ref_self(&self, ctx: &Context) {}
}
#[stream(2048)]
async fn standalone_stream_handler(ctx: &Context) {}参数
- 可选的缓冲区大小参数(默认值)
说明
- 生成代码包装函数体,检查是否可以从 WebSocket 流中读取数据
- 只有当从流中成功读取数据时才执行函数体
- 接受可选的缓冲区大小参数
- 应于 WebSocket 实时通信场景
功能说明
Arguments:
TokenStream: 从 WebSocket 流读取的缓冲区TokenStream: 要修改的函数项
Returns:
- 返回包含 WebSocket 流处理逻辑的修改后函数的 TokenStream
使用示例
// 使用默认缓冲区大小
#[stream]
async fn default_buffer_handler(ctx: &Context) {}
// 使用自定义缓冲区大小
#[stream(1024)]
async fn custom_buffer_handler(ctx: &Context) {}
// 无参数的独立处理函数
#[stream]
async fn standalone_stream_handler(ctx: &Context) {}高级使用场景
防盗链实现
use hyperlane::*;
use hyperlane_macros::*;
#[route("/protected-resource")]
struct ProtectedResource;
impl ServerHook for ProtectedResource {
async fn new(_ctx: &Context) -> Self {
Self
}
#[prologue_macros(
host("example.com"),
referer("https://example.com"),
reject_referer("https://malicious-site.com")
)]
#[epilogue_macros(
response_header("X-Content-Type-Options", "nosniff"),
response_body("Protected content"),
send
)]
async fn handle(self, ctx: &Context) {}
}WebSocket 实时通信
use hyperlane::*;
use hyperlane_macros::*;
#[route("/websocket")]
struct WebSocketHandler;
impl ServerHook for WebSocketHandler {
async fn new(_ctx: &Context) -> Self {
Self
}
#[ws]
#[stream(4096)]
async fn handle(self, ctx: &Context) {
// 处理 WebSocket 消息
let body: RequestBody = ctx.get_request_body().await;
let frames: Vec<ResponseBody> = WebSocketFrame::create_frame_list(&body);
// 发送响应
ctx.send_body_list_with_data(&frames).await.unwrap();
// 检查连接状态
if ctx.is_connection_closed().await {
log::info!("WebSocket connection closed");
}
}
}优雅关闭处理
use hyperlane::*;
use hyperlane_macros::*;
#[route("/graceful-shutdown")]
struct GracefulShutdown;
impl ServerHook for GracefulShutdown {
async fn new(_ctx: &Context) -> Self {
Self
}
#[prologue_macros(
// 检查连接状态
reject(ctx.is_connection_aborted().await)
)]
#[epilogue_macros(
flush, // 确保数据发送完成
send
)]
async fn handle(self, ctx: &Context) {
// 执行清理操作
cleanup_resources().await;
// 发送完成信号
ctx.set_response_body("Shutdown complete").await;
}
}
#[closed]
async fn cleanup_handler(ctx: &Context) {
// 连接关闭时的清理逻辑
log::info!("Performing cleanup for closed connection");
release_resources().await;
}
#[aborted]
async fn abort_handler(ctx: &Context) {
// 请求中止时的清理逻辑
log::info!("Handling aborted request");
rollback_transactions().await;
}多重验证组合
use hyperlane::*;
use hyperlane_macros::*;
#[route("/api/secure")]
struct SecureApi;
impl ServerHook for SecureApi {
async fn new(_ctx: &Context) -> Self {
Self
}
#[prologue_macros(
// 主机验证
host("api.example.com"),
// 来源验证
referer("https://app.example.com"),
// 协议验证
tls,
http1_1_or_higher,
// 方法验证
methods(get, post),
// 连接状态检查
reject(ctx.is_connection_aborted().await)
)]
#[epilogue_macros(
// 安全头部
response_header("X-Frame-Options", "DENY"),
response_header("X-Content-Type-Options", "nosniff"),
response_header("Strict-Transport-Security", "max-age=31536000"),
// 响应数据
response_body(&generate_secure_response()),
send
)]
async fn handle(self, ctx: &Context) {}
}使用建议
安全策略:
- 组合使用主机和 Referer 验证
- 实施 TLS 加密传输
- 添加适当的安全响应头
- 定期更新安全策略
连接管理:
- 处理各种连接状态(正常、关闭、中止)
- 实现优雅的连接关闭
- 监控连接状态变化
- 提供连接恢复机制
WebSocket 开发:
- 合理设置缓冲区大小
- 处理连接异常
- 实现心跳机制
- 考虑并发连接数限制
性能优化:
- 避免不必要的验证
- 优化流处理缓冲区
- 减少连接建立开销
- 使用连接池
错误处理:
- 为各种异常情况提供处理逻辑
- 记录详细的错误日志
- 实现用户友好的错误响应
- 提供错误恢复机制
监控和调试:
- 记录关键操作日志
- 监控连接状态
- 追踪请求处理时间
- 实现健康检查端点