How to perform content negotiation? #3858
-
|
I can't seem to figure out how to examine an accept header. There are various references to the Accept header name in the code, and some wildcard matching functionality in accept.rs, but no examples. Is there an extractor? The Either handler example is somewhat contrived in that it does not attempt to examine an Accept header. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 5 replies
-
|
@drauschenbach actix-web has a typed use actix_web::{get, web, HttpResponse};
use actix_web::http::header::{Accept, ContentType};
#[get("/resource")]
async fn handler(accept: web::Header<Accept>) -> HttpResponse {
let data = serde_json::json!({"key": "value"});
// preference() returns the highest-q mime type
let preferred = accept.preference();
if preferred == mime::APPLICATION_JSON || preferred == mime::STAR_STAR {
HttpResponse::Ok().content_type(ContentType::json()).json(&data)
} else if preferred == mime::TEXT_HTML {
HttpResponse::Ok().content_type(ContentType::html()).body("<h1>value</h1>")
} else {
HttpResponse::NotAcceptable().finish()
}
}for proper server-driven negotiation (walking the full q-factor list), use fn negotiate(accept: &Accept, supported: &[mime::Mime]) -> Option<mime::Mime> {
for requested in accept.ranked() {
for s in supported {
if requested == *s
|| (requested.type_() == s.type_() && requested.subtype() == mime::STAR)
|| requested == mime::STAR_STAR
{
return Some(s.clone());
}
}
}
None
}note: wrap in ref: Accept docs | web::Header extractor | QualityItem |
Beta Was this translation helpful? Give feedback.
@drauschenbach you're right, that's a misleading doc example. the source code shows
HttpResponse::Ok().insert_header(Accept(...))which puts anAcceptheader on a response, butAcceptis a request header per RFC 7231 §5.3.2.it's just a lazy doc example demonstrating how to construct the type, not showing actual usage. the
common_header!macro generates all the header types with the same pattern and the examples just show "here's how to build this struct" rather than where it belongs in a real request/response flow.a server can technically send
Acceptin a response in one edge case: HTTPOPTIONSresponses (to indicate what content types the endpoint accepts), but that's via theAccepthe…