是否有更简单的方法来获取 Actix-Web HTTP 标头的字符串值?

Mar*_*kus 7 rust rust-actix

这是从 Actix-Web 请求中获取内容类型标头的唯一可能性吗?这必须检查标题是否可用或是否to_str失败...

let req: actix_web::HttpRequest;

let content_type: &str = req
    .request()
    .headers()
    .get(actix_web::http::header::CONTENT_TYPE)
    .unwrap()
    .to_str()
    .unwrap();
Run Code Online (Sandbox Code Playgroud)

arv*_*ve0 9

是的,这是“唯一”的可能性,但就是这样,因为:

  1. 标头可能不存在,headers().get(key)返回Option.
  2. 标头可能包含非 ASCII 字符,并且HeaderValue::to_str可能会失败。

actix-web 可以让您单独处理这些错误。

为简化起见,您可以创建一个不区分两个错误的辅助函数:

fn get_content_type<'a>(req: &'a HttpRequest) -> Option<&'a str> {
    req.headers().get("content-type")?.to_str().ok()
}
Run Code Online (Sandbox Code Playgroud)

完整示例:

use actix_web::{web, App, HttpRequest, HttpServer, Responder};

fn main() {
    HttpServer::new(|| App::new().route("/", web::to(handler)))
        .bind("127.0.0.1:8000")
        .expect("Cannot bind to port 8000")
        .run()
        .expect("Unable to run server");
}

fn handler(req: HttpRequest) -> impl Responder {
    if let Some(content_type) = get_content_type(&req) {
        format!("Got content-type = '{}'", content_type)
    } else {
        "No content-type header.".to_owned()
    }
}

fn get_content_type<'a>(req: &'a HttpRequest) -> Option<&'a str> {
    req.headers().get("content-type")?.to_str().ok()
}
Run Code Online (Sandbox Code Playgroud)

这会给你的结果:

fn get_content_type<'a>(req: &'a HttpRequest) -> Option<&'a str> {
    req.headers().get("content-type")?.to_str().ok()
}
Run Code Online (Sandbox Code Playgroud)

顺便说一句,你可能对守卫感兴趣:

web::route()
    .guard(guard::Get())
    .guard(guard::Header("content-type", "text/plain"))
    .to(handler)
Run Code Online (Sandbox Code Playgroud)