我正在开发一个带有框架的应用程序,rust
并且actix-web
我在应用程序中插入了一些中间件实例。
我计划中间件会修改响应的正文并在 call() 方法中返回响应,但我找不到解决方案。我找不到可以从中获取文本ServiceResponse
并对其进行修改的示例代码。
你们能帮我一些获取响应正文并修改它的示例代码吗?
以下是我使用的示例代码。我添加了一条评论以告知我想要SayHiMiddleware->call()
的“sample.rs”
// 示例.rs
use actix_service::{Service, Transform};
use actix_web::{dev::ServiceRequest, dev::ServiceResponse, Error};
use futures::future::{ok, FutureResult};
use futures::{Future, Poll};
// There are two steps in middleware processing.
// 1. Middleware initialization, middleware factory gets called with
// next service in chain as parameter.
// 2. Middleware's call method gets called with normal request.
pub struct SayHi;
// Middleware factory is `Transform` trait from actix-service crate
// `S` - type of the next service
// `B` - type of response's body
impl<S, B> Transform<S> for SayHi
where
S: Service<Request = ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
S::Future: 'static,
B: 'static,
{
type Request = ServiceRequest;
type Response = ServiceResponse<B>;
type Error = Error;
type InitError = ();
type Transform = SayHiMiddleware<S>;
type Future = FutureResult<Self::Transform, Self::InitError>;
fn new_transform(&self, service: S) -> Self::Future {
ok(SayHiMiddleware { service })
}
}
pub struct SayHiMiddleware<S> {
service: S,
}
impl<S, B> Service for SayHiMiddleware<S>
where
S: Service<Request = ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
S::Future: 'static,
B: 'static,
{
type Request = ServiceRequest;
type Response = ServiceResponse<B>;
type Error = Error;
type Future = Box<dyn Future<Item = Self::Response, Error = Self::Error>>;
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
self.service.poll_ready()
}
fn call(&mut self, req: ServiceRequest) -> Self::Future {
println!("Hi from start. You requested: {}", req.path());
Box::new(self.service.call(req).and_then(|res| {
// I want to get response body text and print the text.
// But I couldnt get the text from ServiceResponse instance..... help me guys T.T
// And is there way to combine with previous response body text and new text?????
// example (res->body->text is "aaaaa")) and I want to append new text to the string ( "aaaaa" + "bbbbb" )
println!("Hi from response");
Ok(res)
}))
}
}
// main.rs
use actix_web::{web, App, HttpServer};
use actix_service::Service;
use futures::future::Future;
#[allow(dead_code)]
mod redirect;
#[allow(dead_code)]
mod read_request_body;
#[allow(dead_code)]
mod read_response_body;
#[allow(dead_code)]
mod simple;
fn main() -> std::io::Result<()> {
std::env::set_var("RUST_LOG", "actix_web=debug");
env_logger::init();
HttpServer::new(|| {
App::new()
.wrap(redirect::CheckLogin)
.wrap(read_request_body::Logging)
.wrap(read_response_body::Logging)
.wrap(simple::SayHi)
.wrap_fn(|req, srv| {
println!("Hi from start. You requested: {}", req.path());
srv.call(req).map(|res| {
println!("Hi from response");
res
})
})
.service(web::resource("/login").to(|| {
"You are on /login. Go to src/redirect.rs to change this behavior."
}))
.service(
web::resource("/").to(|| {
"Hello, middleware! Check the console where the server is run."
}),
)
})
.bind("127.0.0.1:8080")?
.run()
}
谢谢...