forked from tokio-rs/axum
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add an example for head request (tokio-rs#1175)
As tokio-rs#84 add get-head request, adding an example.
- Loading branch information
Showing
2 changed files
with
95 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
[package] | ||
name = "example-handle-head-request" | ||
version = "0.1.0" | ||
edition = "2021" | ||
publish = false | ||
|
||
[dependencies] | ||
axum = { path = "../../axum" } | ||
tokio = { version = "1.0", features = ["full"] } | ||
|
||
[dev-dependencies] | ||
tower = { version = "0.4", features = ["util"] } | ||
hyper = { version = "0.14", features = ["full"] } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
//! Run with | ||
//! | ||
//! ```not_rust | ||
//! cd examples && cargo run -p example-handle-head-reqeust | ||
//! ``` | ||
|
||
use axum::response::{IntoResponse, Response}; | ||
use axum::{http, routing::get, Router}; | ||
use std::net::SocketAddr; | ||
|
||
fn app() -> Router { | ||
Router::new().route("/get-head", get(get_head_handler)) | ||
} | ||
|
||
#[tokio::main] | ||
async fn main() { | ||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); | ||
|
||
axum::Server::bind(&addr) | ||
.serve(app().into_make_service()) | ||
.await | ||
.unwrap(); | ||
} | ||
|
||
// get routes will also be called for HEAD requests but will have the response body removed | ||
// can handle implicit head method request by extract `http::Method` from request | ||
async fn get_head_handler(method: http::Method) -> Response { | ||
// it usually makes sense to handle only special-case HEAD | ||
// if computing the body has some relevant cost | ||
if method == http::Method::HEAD { | ||
return ([("x-some-header", "header from HEAD")]).into_response(); | ||
} | ||
|
||
// then do some computing task in GET | ||
do_some_computing_task(); | ||
|
||
([("x-some-header", "header from GET")], "body from GET").into_response() | ||
} | ||
|
||
fn do_some_computing_task() { | ||
// TODO | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
use axum::body::Body; | ||
use axum::http::{Request, StatusCode}; | ||
use tower::ServiceExt; | ||
|
||
#[tokio::test] | ||
async fn test_get() { | ||
let app = app(); | ||
|
||
let response = app | ||
.oneshot(Request::get("/get-head").body(Body::empty()).unwrap()) | ||
.await | ||
.unwrap(); | ||
|
||
assert_eq!(response.status(), StatusCode::OK); | ||
assert_eq!(response.headers()["x-some-header"], "header from GET"); | ||
|
||
let body = hyper::body::to_bytes(response.into_body()).await.unwrap(); | ||
assert_eq!(&body[..], b"body from GET"); | ||
} | ||
|
||
#[tokio::test] | ||
async fn test_implicit_head() { | ||
let app = app(); | ||
|
||
let response = app | ||
.oneshot(Request::head("/get-head").body(Body::empty()).unwrap()) | ||
.await | ||
.unwrap(); | ||
|
||
assert_eq!(response.status(), StatusCode::OK); | ||
assert_eq!(response.headers()["x-some-header"], "header from HEAD"); | ||
|
||
let body = hyper::body::to_bytes(response.into_body()).await.unwrap(); | ||
assert!(body.is_empty()); | ||
} | ||
} |