mirror of
https://github.com/actix/actix-website
synced 2025-01-22 16:15:56 +01:00
Middleware section is done-ish.
This commit is contained in:
parent
1c3697197d
commit
eff4edb6fa
@ -6,9 +6,9 @@ weight: 220
|
|||||||
|
|
||||||
# Middleware
|
# Middleware
|
||||||
|
|
||||||
Actix's middleware system allows us to add additional behavior to request/response processing.
|
Actix-web's middleware system allows us to add additional behavior to request/response
|
||||||
Middleware can hook into an incoming request process, enabling us to modify requests
|
processing. Middleware can hook into an incoming request process, enabling us to modify
|
||||||
as well as halt request processing to return a response early.
|
requests as well as halt request processing to return a response early.
|
||||||
|
|
||||||
Middleware can also hook into response processing.
|
Middleware can also hook into response processing.
|
||||||
|
|
||||||
@ -19,31 +19,32 @@ Typically, middleware is involved in the following actions:
|
|||||||
* Modify application state
|
* Modify application state
|
||||||
* Access external services (redis, logging, sessions)
|
* Access external services (redis, logging, sessions)
|
||||||
|
|
||||||
Middleware is registered for each application and executed in same order as registration.
|
Middleware is registered for each `App`, `scope`, or `Resource` and executed in opposite
|
||||||
In general, a *middleware* is a type that implements the [*Service trait*][servicetrait] and
|
order as registration. In general, a *middleware* is a type that implements the
|
||||||
[*Transform trait*][transformtrait]. Each method in the traits has a default
|
[*Service trait*][servicetrait] and [*Transform trait*][transformtrait]. Each method in
|
||||||
implementation. Each method can return a result immediately or a *future* object.
|
the traits has a default implementation. Each method can return a result immediately
|
||||||
|
or a *future* object.
|
||||||
|
|
||||||
The following demonstrates creating a simple middleware:
|
The following demonstrates creating a simple middleware:
|
||||||
|
|
||||||
{{< include-example example="middleware" file="main.rs" section="main" >}}
|
{{< include-example example="middleware" file="main.rs" section="simple" >}}
|
||||||
|
|
||||||
> Actix provides several useful middlewares, such as *logging*, *user sessions*, etc.
|
> Actix-web provides several useful middlewares, such as *logging*, *user sessions*,
|
||||||
|
> *compress*, etc.
|
||||||
|
|
||||||
# Logging
|
# Logging
|
||||||
|
|
||||||
Logging is implemented as a middleware.
|
Logging is implemented as a middleware. It is common to register a logging middleware
|
||||||
It is common to register a logging middleware as the first middleware for the application.
|
as the first middleware for the application. Logging middleware must be registered for
|
||||||
Logging middleware must be registered for each application.
|
each application.
|
||||||
|
|
||||||
The `Logger` middleware uses the standard log crate to log information. You should enable logger
|
The `Logger` middleware uses the standard log crate to log information. You should enable logger
|
||||||
for *actix_web* package to see access log ([env_logger][envlogger]
|
for *actix_web* package to see access log ([env_logger][envlogger] or similar).
|
||||||
or similar).
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Create `Logger` middleware with the specified `format`.
|
Create `Logger` middleware with the specified `format`. Default `Logger` can be created
|
||||||
Default `Logger` can be created with `default` method, it uses the default format:
|
with `default` method, it uses the default format:
|
||||||
|
|
||||||
```ignore
|
```ignore
|
||||||
%a %t "%r" %s %b "%{Referer}i" "%{User-Agent}i" %T
|
%a %t "%r" %s %b "%{Referer}i" "%{User-Agent}i" %T
|
||||||
@ -60,29 +61,18 @@ INFO:actix_web::middleware::logger: 127.0.0.1:59947 [02/Dec/2017:00:22:40 -0800]
|
|||||||
|
|
||||||
## Format
|
## Format
|
||||||
|
|
||||||
`%%` The percent sign
|
- `%%` The percent sign
|
||||||
|
- `%a` Remote IP-address (IP-address of proxy if using reverse proxy)
|
||||||
`%a` Remote IP-address (IP-address of proxy if using reverse proxy)
|
- `%t` Time when the request was started to process
|
||||||
|
- `%P` The process ID of the child that serviced the request
|
||||||
`%t` Time when the request was started to process
|
- `%r` First line of request
|
||||||
|
- `%s` Response status code
|
||||||
`%P` The process ID of the child that serviced the request
|
- `%b` Size of response in bytes, including HTTP headers
|
||||||
|
- `%T` Time taken to serve the request, in seconds with floating fraction in .06f format
|
||||||
`%r` First line of request
|
- `%D` Time taken to serve the request, in milliseconds
|
||||||
|
- `%{FOO}i` request.headers['FOO']
|
||||||
`%s` Response status code
|
- `%{FOO}o` response.headers['FOO']
|
||||||
|
- `%{FOO}e` os.environ['FOO']
|
||||||
`%b` Size of response in bytes, including HTTP headers
|
|
||||||
|
|
||||||
`%T` Time taken to serve the request, in seconds with floating fraction in .06f format
|
|
||||||
|
|
||||||
`%D` Time taken to serve the request, in milliseconds
|
|
||||||
|
|
||||||
`%{FOO}i` request.headers['FOO']
|
|
||||||
|
|
||||||
`%{FOO}o` response.headers['FOO']
|
|
||||||
|
|
||||||
`%{FOO}e` os.environ['FOO']
|
|
||||||
|
|
||||||
## Default headers
|
## Default headers
|
||||||
|
|
||||||
@ -94,8 +84,9 @@ a specified header.
|
|||||||
|
|
||||||
## User sessions
|
## User sessions
|
||||||
|
|
||||||
Actix provides a general solution for session management. The [**actix-session**][actixsession]
|
Actix-web provides a general solution for session management. The
|
||||||
middleware can be used with different backend types to store session data in different backends.
|
[**actix-session**][actixsession] middleware can be used with different backend types
|
||||||
|
to store session data in different backends.
|
||||||
|
|
||||||
> By default, only cookie session backend is implemented. Other backend implementations
|
> By default, only cookie session backend is implemented. Other backend implementations
|
||||||
> can be added.
|
> can be added.
|
||||||
@ -115,8 +106,8 @@ The constructors take a key as an argument. This is the private key for cookie s
|
|||||||
when this value is changed, all session data is lost.
|
when this value is changed, all session data is lost.
|
||||||
|
|
||||||
In general, you create a `SessionStorage` middleware and initialize it with specific
|
In general, you create a `SessionStorage` middleware and initialize it with specific
|
||||||
backend implementation, such as a `CookieSession`. To access session data,
|
backend implementation, such as a `CookieSession`. To access session data the
|
||||||
[*HttpRequest::session()*][requestsession] must be used. This method returns a
|
[`Session`][requestsession] extractor must be used. This method returns a
|
||||||
[*Session*][sessionobj] object, which allows us to get or set session data.
|
[*Session*][sessionobj] object, which allows us to get or set session data.
|
||||||
|
|
||||||
{{< include-example example="middleware" file="user_sessions.rs" section="user-session" >}}
|
{{< include-example example="middleware" file="user_sessions.rs" section="user-session" >}}
|
||||||
@ -132,10 +123,10 @@ into a response.
|
|||||||
|
|
||||||
{{< include-example example="middleware" file="errorhandler.rs" section="error-handler" >}}
|
{{< include-example example="middleware" file="errorhandler.rs" section="error-handler" >}}
|
||||||
|
|
||||||
[sessionobj]: ../../actix-web/actix_web/middleware/session/struct.Session.html
|
[sessionobj]: https://docs.rs/actix-session/0.1.1/actix_session/struct.Session.html
|
||||||
[requestsession]: ../../actix-web/actix_web/middleware/session/trait.RequestSession.html#tymethod.session
|
[requestsession]: https://docs.rs/actix-session/0.1.1/actix_session/struct.Session.html
|
||||||
[cookiesession]: ../../actix-web/actix_web/middleware/session/struct.CookieSessionBackend.html
|
[cookiesession]: https://docs.rs/actix-session/0.1.1/actix_session/struct.CookieSession.html
|
||||||
[actixsession]: https://docs.rs/actix-session/0.1.1/actix_session/
|
[actixsession]: https://docs.rs/actix-session/0.1.1/actix_session/
|
||||||
[envlogger]: https://docs.rs/env_logger/*/env_logger/
|
[envlogger]: https://docs.rs/env_logger/*/env_logger/
|
||||||
[servicetrait]: ../../actix-web/actix_web/dev/trait.Service.html
|
[servicetrait]: https://docs.rs/actix-web/1.0.2/actix_web/dev/trait.Service.html
|
||||||
[transformtrait]: ../../actix-web/actix_web/dev/trait.Transform.html
|
[transformtrait]: https://docs.rs/actix-web/1.0.2/actix_web/dev/trait.Transform.html
|
||||||
|
@ -1,16 +1,24 @@
|
|||||||
// <default-headers>
|
// <default-headers>
|
||||||
use actix_web::{http, middleware, web, App, HttpResponse};
|
use actix_web::{http, middleware, HttpResponse};
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
App::new()
|
use actix_web::{web, App, HttpServer};
|
||||||
.wrap(middleware::DefaultHeaders::new().header("X-Version", "0.2"))
|
|
||||||
.service(
|
HttpServer::new(|| {
|
||||||
web::resource("/test")
|
App::new()
|
||||||
.route(web::get().to(|| HttpResponse::Ok()))
|
.wrap(middleware::DefaultHeaders::new().header("X-Version", "0.2"))
|
||||||
.route(
|
.service(
|
||||||
web::method(http::Method::HEAD)
|
web::resource("/test")
|
||||||
.to(|| HttpResponse::MethodNotAllowed()),
|
.route(web::get().to(|| HttpResponse::Ok()))
|
||||||
),
|
.route(
|
||||||
);
|
web::method(http::Method::HEAD)
|
||||||
|
.to(|| HttpResponse::MethodNotAllowed()),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.bind("127.0.0.1:8088")
|
||||||
|
.unwrap()
|
||||||
|
.run()
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
// </default-headers>
|
// </default-headers>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// <error-handler>
|
// <error-handler>
|
||||||
use actix_web::middleware::errhandlers::{ErrorHandlerResponse, ErrorHandlers};
|
use actix_web::middleware::errhandlers::{ErrorHandlerResponse, ErrorHandlers};
|
||||||
use actix_web::{dev, http, web, App, HttpResponse, Result};
|
use actix_web::{dev, http, HttpResponse, Result};
|
||||||
|
|
||||||
fn render_500<B>(mut res: dev::ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
|
fn render_500<B>(mut res: dev::ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
|
||||||
res.response_mut().headers_mut().insert(
|
res.response_mut().headers_mut().insert(
|
||||||
@ -11,15 +11,23 @@ fn render_500<B>(mut res: dev::ServiceResponse<B>) -> Result<ErrorHandlerRespons
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
App::new()
|
use actix_web::{web, App, HttpServer};
|
||||||
.wrap(
|
|
||||||
ErrorHandlers::new()
|
HttpServer::new(|| {
|
||||||
.handler(http::StatusCode::INTERNAL_SERVER_ERROR, render_500),
|
App::new()
|
||||||
)
|
.wrap(
|
||||||
.service(
|
ErrorHandlers::new()
|
||||||
web::resource("/test")
|
.handler(http::StatusCode::INTERNAL_SERVER_ERROR, render_500),
|
||||||
.route(web::get().to(|| HttpResponse::Ok()))
|
)
|
||||||
.route(web::head().to(|| HttpResponse::MethodNotAllowed())),
|
.service(
|
||||||
);
|
web::resource("/test")
|
||||||
|
.route(web::get().to(|| HttpResponse::Ok()))
|
||||||
|
.route(web::head().to(|| HttpResponse::MethodNotAllowed())),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.bind("127.0.0.1:8088")
|
||||||
|
.unwrap()
|
||||||
|
.run()
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
// </error-handler>
|
// </error-handler>
|
||||||
|
@ -1,14 +1,21 @@
|
|||||||
// <logger>
|
// <logger>
|
||||||
use actix_web::middleware::Logger;
|
use actix_web::middleware::Logger;
|
||||||
use actix_web::App;
|
|
||||||
use env_logger;
|
use env_logger;
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
|
use actix_web::{App, HttpServer};
|
||||||
|
|
||||||
std::env::set_var("RUST_LOG", "actix_web=info");
|
std::env::set_var("RUST_LOG", "actix_web=info");
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
|
|
||||||
App::new()
|
HttpServer::new(|| {
|
||||||
.wrap(Logger::default())
|
App::new()
|
||||||
.wrap(Logger::new("%a %{User-Agent}i"));
|
.wrap(Logger::default())
|
||||||
|
.wrap(Logger::new("%a %{User-Agent}i"))
|
||||||
|
})
|
||||||
|
.bind("127.0.0.1:8088")
|
||||||
|
.unwrap()
|
||||||
|
.run()
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
// </logger>
|
// </logger>
|
||||||
|
@ -2,9 +2,10 @@ pub mod default_headers;
|
|||||||
pub mod errorhandler;
|
pub mod errorhandler;
|
||||||
pub mod logger;
|
pub mod logger;
|
||||||
pub mod user_sessions;
|
pub mod user_sessions;
|
||||||
// <main>
|
|
||||||
|
// <simple>
|
||||||
use actix_service::{Service, Transform};
|
use actix_service::{Service, Transform};
|
||||||
use actix_web::{dev::ServiceRequest, dev::ServiceResponse, web, App, Error};
|
use actix_web::{dev::ServiceRequest, dev::ServiceResponse, Error};
|
||||||
use futures::future::{ok, FutureResult};
|
use futures::future::{ok, FutureResult};
|
||||||
use futures::{Future, Poll};
|
use futures::{Future, Poll};
|
||||||
|
|
||||||
@ -63,10 +64,19 @@ where
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// </main>
|
// </simple>
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
App::new().wrap(SayHi).service(
|
use actix_web::{web, App, HttpServer};
|
||||||
web::resource("/")
|
|
||||||
.to(|| "Hello, middleware! Check the console where the server is run."),
|
HttpServer::new(|| {
|
||||||
);
|
App::new().wrap(SayHi).service(
|
||||||
|
web::resource("/")
|
||||||
|
.to(|| "Hello, middleware! Check the console where the server is run."),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.bind("127.0.0.1:8088")
|
||||||
|
.unwrap()
|
||||||
|
.run()
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
@ -1,37 +1,33 @@
|
|||||||
// <user-session>
|
// <user-session>
|
||||||
use actix_session::{CookieSession, Session};
|
use actix_session::{CookieSession, Session};
|
||||||
use actix_web::{middleware::Logger, web, App, HttpRequest, HttpServer, Result};
|
use actix_web::{web, App, Error, HttpResponse, HttpServer};
|
||||||
|
|
||||||
/// simple index handler with session
|
pub fn index(session: Session) -> Result<HttpResponse, Error> {
|
||||||
fn index(session: Session, req: HttpRequest) -> Result<&'static str> {
|
// access session data
|
||||||
println!("{:?}", req);
|
|
||||||
|
|
||||||
// RequestSession trait is used for session access
|
|
||||||
let mut counter = 1;
|
|
||||||
if let Some(count) = session.get::<i32>("counter")? {
|
if let Some(count) = session.get::<i32>("counter")? {
|
||||||
println!("SESSION value: {}", count);
|
session.set("counter", count + 1)?;
|
||||||
counter = count + 1;
|
|
||||||
session.set("counter", counter)?;
|
|
||||||
} else {
|
} else {
|
||||||
session.set("counter", counter)?;
|
session.set("counter", 1)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok("welcome!")
|
Ok(HttpResponse::Ok().body(format!(
|
||||||
|
"Count is {:?}!",
|
||||||
|
session.get::<i32>("counter")?.unwrap()
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() -> std::io::Result<()> {
|
pub fn main() {
|
||||||
std::env::set_var("RUST_LOG", "actix_web=info");
|
|
||||||
env_logger::init();
|
|
||||||
|
|
||||||
HttpServer::new(|| {
|
HttpServer::new(|| {
|
||||||
App::new()
|
App::new()
|
||||||
// enable logger
|
.wrap(
|
||||||
.wrap(Logger::default())
|
CookieSession::signed(&[0; 32]) // <- create cookie based session middleware
|
||||||
// cookie session middleware
|
.secure(false),
|
||||||
.wrap(CookieSession::signed(&[0; 32]).secure(false))
|
)
|
||||||
.service(web::resource("/").to(index))
|
.service(web::resource("/").to(index))
|
||||||
})
|
})
|
||||||
.bind("127.0.0.1:8080")?
|
.bind("127.0.0.1:8088")
|
||||||
|
.unwrap()
|
||||||
.run()
|
.run()
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
// </user-session>
|
// </user-session>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user