请求
提示
hyperlane 框架对 ctx 额外封装了子字段的方法,可以直接调用大部分子字段的 get 和 set 方法名称。 例如:调用 request 上的 get_method 方法, 一般需要从 ctx 解出 request,再调用request.get_method(), 可以简化成直接调用 ctx.get_request().get_method()。
调用规律
request仅支持get,不支持set,框架保证请求信息不会被意外修改。- 原
request的get方法的get名称后加request名称,中间使用_拼接。
获取请求信息
获取 request
let request: &Request = ctx.get_request();获取 method
let method: &RequestMethod = ctx.get_request().get_method();获取 host
let host: &RequestHost = ctx.get_request().get_host();获取 path
let path: &RequestPath = ctx.get_request().get_path();获取 version
let version: &RequestVersion = ctx.get_request().get_version();获取 querys
let querys: &RequestQuerys = ctx.get_request().get_querys();获取特定查询参数
// 尝试获取查询参数
let query_value: OptionRequestQuerysValue = ctx.get_request().get_query("key");
// 获取查询参数(获取不到则panic)
let query_value: RequestQuerysValue = ctx.get_request().get_query("key");获取 header
提示
hyperlane 框架请求头的 key 是经过全小写处理,建议使用框架定义的常量。
// 尝试获取请求头
let header: OptionRequestHeadersValue = ctx.get_request().get_header(CONTENT_TYPE);
// 获取请求头(获取不到则panic)
let header: RequestHeadersValue = ctx.get_request().get_header(CONTENT_TYPE);获取 headers
let headers: &RequestHeaders = ctx.get_request().get_headers();获取请求头的第一个值
// 尝试获取请求头的第一个值
let header_value: OptionRequestHeadersValueItem = ctx.get_request().get_header_front(CONTENT_TYPE);
// 获取请求头的第一个值(获取不到则panic)
let header_value: RequestHeadersValueItem = ctx.get_request().get_header_front(CONTENT_TYPE);获取请求头的最后一个值
// 尝试获取请求头的最后一个值
let header_value: OptionRequestHeadersValueItem = ctx.get_request().get_header_back(ACCEPT);
// 获取请求头的最后一个值(获取不到则panic)
let header_value: RequestHeadersValueItem = ctx.get_request().get_header_back(ACCEPT);获取请求头值的数量
// 尝试获取请求头值的数量
let header_count: OptionUsize = ctx.get_request().get_header_len(ACCEPT_ENCODING);
// 获取请求头值的数量(获取不到则panic)
let header_count: usize = ctx.get_request().get_header_len(ACCEPT_ENCODING);获取所有请求头值的总数量
let total_values: usize = ctx.get_request().get_headers_values_length();获取请求头的数量
let headers_count: usize = ctx.get_request().get_headers_length();检查是否存在特定请求头
let has_header: bool = ctx.get_request().get_has_header(CONTENT_TYPE);检查请求头是否包含特定值
let has_value: bool = ctx.get_request().get_has_header_value(CONTENT_TYPE, APPLICATION_JSON);获取请求体
let body: &RequestBody = ctx.get_request().get_body();获取 string 格式的请求体
let body: String = ctx.get_request().get_body_string();获取 json 格式的请求体
// 反序列化请求体
let body: ResultJsonError<T> = ctx.get_request().get_body_json::<T>();
// 反序列化请求体(反序列化失败则panic)
let body: T = ctx.get_request().get_body_json::<T>();获取请求升级类型
let upgrade_type: UpgradeType = ctx.get_request().get_upgrade_type();检查是否为 WebSocket 升级
let is_ws: bool = ctx.get_request().is_ws_upgrade_type();属性宏写法
提示
hyperlane 框架提供了属性宏来简化请求信息的获取,可以在 handle 方法上使用属性宏自动提取请求信息。
获取请求体
use hyperlane::*;
use hyperlane_macros::*;
#[route("/request_body")]
struct RequestBodyRoute;
impl ServerHook for RequestBodyRoute {
async fn new(_: &mut Stream, _: &mut Context) -> Self {
Self
}
#[request_body(body)]
async fn handle(self, stream: &mut Stream, ctx: &mut Context) -> Status {
// body is available as Vec<u8>
Status::Continue
}
}获取请求体 JSON
#[request_body_json(body: TestData)]
async fn handle(self, stream: &mut Stream, ctx: &mut Context) -> Status {
// body is available as the deserialized type
Status::Continue
}安全获取请求体 JSON(返回 Result)
#[request_body_json_result(body: TestData)]
async fn handle(self, stream: &mut Stream, ctx: &mut Context) -> Status {
// body is available as Result<T, serde_json::Error>
Status::Continue
}获取请求头
#[request_header(HOST => host_value)]
async fn handle(self, stream: &mut Stream, ctx: &mut Context) -> Status {
// host_value is available
Status::Continue
}安全获取请求头(返回 Option)
#[try_get_request_header(HOST => host_value)]
async fn handle(self, stream: &mut Stream, ctx: &mut Context) -> Status {
// host_value is available as Option<RequestHeadersValueItem>
Status::Continue
}获取所有请求头
#[request_headers(headers)]
async fn handle(self, stream: &mut Stream, ctx: &mut Context) -> Status {
// headers is available as RequestHeaders
Status::Continue
}获取查询参数
#[request_query("key" => query_value)]
async fn handle(self, stream: &mut Stream, ctx: &mut Context) -> Status {
// query_value is available
Status::Continue
}安全获取查询参数(返回 Option)
#[try_get_request_query("key" => query_value)]
async fn handle(self, stream: &mut Stream, ctx: &mut Context) -> Status {
// query_value is available as Option<RequestQuerysValue>
Status::Continue
}获取所有查询参数
#[request_querys(querys)]
async fn handle(self, stream: &mut Stream, ctx: &mut Context) -> Status {
// querys is available as RequestQuerys
Status::Continue
}获取请求路径
#[request_path(path)]
async fn handle(self, stream: &mut Stream, ctx: &mut Context) -> Status {
// path is available as RequestPath
Status::Continue
}获取请求版本
#[request_version(version)]
async fn handle(self, stream: &mut Context) -> Status {
// version is available as RequestVersion
Status::Continue
}使用 try_get_http_request 属性宏
提示
可以使用 #[try_get_http_request] 属性宏从 TCP 流中读取并解析下一个 HTTP 请求。
use hyperlane::*;
use hyperlane_macros::*;
#[route("/try_get_http_request")]
struct TryGetHttpRequestRoute;
impl ServerHook for TryGetHttpRequestRoute {
async fn new(_: &mut Stream, _: &mut Context) -> Self {
Self
}
#[try_get_http_request]
async fn handle(self, stream: &mut Stream, ctx: &mut Context) -> Status {
Status::Continue
}
}请求方法过滤
提示
hyperlane 框架提供了请求方法过滤的属性宏,只有匹配的请求方法才会执行 handle 方法。 不匹配时直接返回 Status::Continue,跳过当前路由。
单个方法过滤
#[is_get_method]
async fn handle(self, stream: &mut Stream, ctx: &mut Context) -> Status {
// Only GET requests will reach here
Status::Continue
}支持的方法过滤宏:#[is_get_method]、#[is_post_method]、#[is_put_method]、#[is_delete_method]、#[is_patch_method]、#[is_head_method]、#[is_options_method]、#[is_connect_method]、#[is_trace_method]
多方法过滤
提示
可以使用 #[methods] 同时匹配多个请求方法。
#[methods("GET", "POST")]
async fn handle(self, stream: &mut Stream, ctx: &mut Context) -> Status {
// Only GET or POST requests will reach here
Status::Continue
}请求版本过滤
提示
hyperlane 框架提供了 HTTP 版本过滤的属性宏,只有匹配的版本才会执行 handle 方法。
#[is_http1_1_version]
async fn handle(self, stream: &mut Stream, ctx: &mut Context) -> Status {
// Only HTTP/1.1 requests will reach here
Status::Continue
}支持的版本过滤宏:#[is_http0_9_version]、#[is_http1_0_version]、#[is_http1_1_version]、#[is_http2_version]、#[is_http3_version]、#[is_http1_1_or_higher_version]、#[is_http_version("1.1")]、#[is_unknown_version]
协议升级类型过滤
提示
hyperlane 框架提供了协议升级类型过滤的属性宏。
#[is_ws_upgrade_type]
async fn handle(self, stream: &mut Stream, ctx: &mut Context) -> Status {
// Only WebSocket upgrade requests will reach here
Status::Continue
}支持的升级类型过滤宏:#[is_ws_upgrade_type]、#[is_h2c_upgrade_type]、#[is_tls_upgrade_type]、#[is_unknown_upgrade_type]
转字符串
通过 to_string
提示
将获得完整的原始结构体字符串结构。
ctx.get_request().to_string();