mirror of
https://github.com/actix/examples
synced 2024-11-23 22:41:07 +01:00
Return HttpResponse from middleware.
This commit is contained in:
parent
2df944c5e5
commit
123cd8fa95
12
middleware/middleware-return-httpresponse/Cargo.toml
Normal file
12
middleware/middleware-return-httpresponse/Cargo.toml
Normal file
@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "middleware-return-httpresponse"
|
||||
version = "1.0.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
actix-web = "4"
|
||||
env_logger = "0.9"
|
||||
futures-util = { version = "0.3.17", default-features = false, features = ["std"] }
|
||||
log = "0.4"
|
||||
pin-project = "1"
|
||||
serde = { version = "*", features = ["derive"] }
|
35
middleware/middleware-return-httpresponse/README.md
Normal file
35
middleware/middleware-return-httpresponse/README.md
Normal file
@ -0,0 +1,35 @@
|
||||
## Middleware : Return HttpResponse from Middleware
|
||||
|
||||
```rs
|
||||
cd middleware-return-httpresponse
|
||||
cargo run
|
||||
# Started http server: 127.0.0.1:8080
|
||||
```
|
||||
|
||||
## What is this?
|
||||
|
||||
A Middleware example which returning HttpResponse.
|
||||
|
||||
## How to test
|
||||
|
||||
### success case
|
||||
```sh
|
||||
curl http://127.0.0.1:8080/ -H 'Authorization:ok' | json_pp -json_opt pretty,canonical
|
||||
% Total % Received % Xferd Average Speed Time Time Time Current
|
||||
Dload Upload Total Spent Left Speed
|
||||
100 42 100 42 0 0 42000 0 --:--:-- --:--:-- --:--:-- 42000
|
||||
{
|
||||
"data" : "Hello this is success response!"
|
||||
}
|
||||
```
|
||||
|
||||
### failed case
|
||||
```sh
|
||||
curl http://127.0.0.1:8080/ | json_pp -json_opt pretty,canonical
|
||||
% Total % Received % Xferd Average Speed Time Time Time Current
|
||||
Dload Upload Total Spent Left Speed
|
||||
100 102 100 102 0 0 99k 0 --:--:-- --:--:-- --:--:-- 99k
|
||||
{
|
||||
"data" : "Hello this is default error message! you need to set Authorization header to get thru this."
|
||||
}
|
||||
```
|
40
middleware/middleware-return-httpresponse/src/main.rs
Normal file
40
middleware/middleware-return-httpresponse/src/main.rs
Normal file
@ -0,0 +1,40 @@
|
||||
use actix_web::{web, App, HttpServer, HttpResponse};
|
||||
|
||||
mod simple;
|
||||
|
||||
// You can move this struct to a separate file.
|
||||
// this struct below just for example.
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct HttpData {
|
||||
pub data: String,
|
||||
}
|
||||
// this implementation is optional
|
||||
impl Default for HttpData {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
data: "Hello this is success response!".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[actix_web::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
|
||||
|
||||
log::info!("starting HTTP server at http://localhost:8080");
|
||||
|
||||
HttpServer::new(|| {
|
||||
App::new()
|
||||
.wrap(simple::ReturnHttpResponse)
|
||||
.service(
|
||||
web::resource("/").to(|| async {
|
||||
HttpResponse::Ok().json(HttpData::default())
|
||||
}),
|
||||
)
|
||||
})
|
||||
.bind(("127.0.0.1", 8080))?
|
||||
.run()
|
||||
.await
|
||||
}
|
91
middleware/middleware-return-httpresponse/src/simple.rs
Normal file
91
middleware/middleware-return-httpresponse/src/simple.rs
Normal file
@ -0,0 +1,91 @@
|
||||
use std::{
|
||||
future::{ready, Ready},
|
||||
rc::Rc
|
||||
};
|
||||
|
||||
use actix_web::{
|
||||
dev::{self, Service, ServiceRequest, ServiceResponse, Transform},
|
||||
Error,
|
||||
http::{header, StatusCode}, HttpResponseBuilder
|
||||
};
|
||||
use futures_util::future::LocalBoxFuture;
|
||||
|
||||
|
||||
// You can move this struct to a separate file.
|
||||
// this struct below just for example.
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct HttpData {
|
||||
pub data: String,
|
||||
}
|
||||
// this implementation is optional
|
||||
impl Default for HttpData {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
data: "Hello this is default error message! you need to set Authorization header to get thru this.".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub struct ReturnHttpResponse;
|
||||
|
||||
impl<S: 'static> Transform<S, ServiceRequest> for ReturnHttpResponse
|
||||
where
|
||||
S: Service<ServiceRequest, Response = ServiceResponse, Error = Error>,
|
||||
S::Future: 'static
|
||||
{
|
||||
type Response = ServiceResponse;
|
||||
type Error = Error;
|
||||
type InitError = ();
|
||||
type Transform = AuthMiddleware<S>;
|
||||
type Future = Ready<Result<Self::Transform, Self::InitError>>;
|
||||
|
||||
fn new_transform(&self, service: S) -> Self::Future {
|
||||
ready(Ok(AuthMiddleware {
|
||||
service: Rc::new(service),
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AuthMiddleware<S> {
|
||||
// This is special: We need this to avoid lifetime issues.
|
||||
service: Rc<S>,
|
||||
}
|
||||
|
||||
impl<S> Service<ServiceRequest> for AuthMiddleware<S>
|
||||
where
|
||||
S: Service<ServiceRequest, Response = ServiceResponse, Error = Error> + 'static,
|
||||
S::Future: 'static
|
||||
{
|
||||
type Response = ServiceResponse;
|
||||
type Error = Error;
|
||||
type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
|
||||
|
||||
dev::forward_ready!(service);
|
||||
|
||||
fn call(&self, req: ServiceRequest) -> Self::Future {
|
||||
let svc = self.service.clone();
|
||||
|
||||
Box::pin(async move {
|
||||
|
||||
let headers = req.headers();
|
||||
let _ = match headers.get("Authorization") {
|
||||
Some(e) => e,
|
||||
None => {
|
||||
let new_response = HttpResponseBuilder::new(StatusCode::BAD_REQUEST)
|
||||
.insert_header((header::CONTENT_TYPE, "application/json"))
|
||||
.json(HttpData::default());
|
||||
return Ok(ServiceResponse::new(
|
||||
req.request().to_owned(), /* or req.request().clone() */
|
||||
new_response
|
||||
))
|
||||
}
|
||||
};
|
||||
|
||||
let res = svc.call(req).await?;
|
||||
Ok(res)
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user