Skip to content

Working with Headers

Andrey edited this page Dec 1, 2023 · 11 revisions

This article no longer valid from 0.7.0 version...

Usually Headers can be read as a part of the MyHttpInput Macros using #[http_header()] attribute.

#[derive(MyHttpInput)]
pub struct MyInputData {
    #[http_header(name:"headerName", description:"Header description")]
    pub data_from_header: String,
}

But sometime we have to read a header during the function 'async fn handle_request(...)' execution. This is possible to perform with the construction such as:

let header_value = ctx.request.get_header("MyHeader");

It's important to know - that my_http_server is using a Hyper framework to serve HTTP Server. By Design, if we work with Body - Hyper takes an ownership of some internal structures of Hyper. This makes not possible to read headers in runtime after we had our Body reading operation.

For instance, we have a model which reads some field from body

#[derive(MyHttpInput)]
pub struct RefreshSessionTokenInputData {
    #[http_body(description:"Refresh token")]
    pub token: String,
}

That means if we wanted to read header at the moment of handling request

async fn handle_request(
    action: &RefreshSessionAction,
    input_data: RefreshSessionTokenInputData,
    ctx: &mut HttpContext,
) -> Result<HttpOkResult, HttpFailResult> {
    let header_value = ctx.request.get_header("MyHeader");

.....
}

we would get an runtime panic error which tells us - 'Headers can no be read after reading body'.

For performance reason my_http_server is not caching headers for every request. Developer has to decide the exact actions to cache headers in 'ctx.request' structure by marking at least one of the fields with 'cache_headers' parameter.

#[derive(MyHttpInput)]
pub struct RefreshSessionTokenInputData {
    #[http_body(description = "Refresh token", cache_headers)]
    pub token: String,
}

Clone this wiki locally