1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-11-30 18:34:36 +01:00

Merge pull request #160 from memoryruins/guide

Guide: edits to first half
This commit is contained in:
Nikolay Kim 2018-04-05 19:44:42 -07:00 committed by GitHub
commit 12586db15c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 180 additions and 164 deletions

View File

@ -1,11 +1,8 @@
# Quick start
Before you can start writing a actix web applications, youll need a version of Rust installed.
We recommend you use rustup to install or configure such a version.
## Install Rust
Before we begin, we need to install Rust using the [rustup](https://www.rustup.rs/) installer:
Before we begin, we need to install Rust using the [rustup](https://www.rustup.rs/):
```bash
curl https://sh.rustup.rs -sSf | sh
@ -21,9 +18,10 @@ Actix web framework requires rust version 1.21 and up.
## Running Examples
The fastest way to start experimenting with actix web is to clone the actix web repository
and run the included examples in the examples/ directory. The following set of
commands runs the `basics` example:
The fastest way to start experimenting with actix web is to clone the
[repository](https://github.com/actix/actix-web) and run the included examples.
The following set of commands runs the `basics` example:
```bash
git clone https://github.com/actix/actix-web

View File

@ -1,14 +1,10 @@
# Getting Started
Lets create and run our first actix web application. Well create a new Cargo project
that depends on actix web and then run the application.
In the previous section we already installed the required rust version. Now let's create new cargo projects.
Lets write our first actix web application!
## Hello, world!
Lets write our first actix web application! Start by creating a new binary-based
Cargo project and changing into the new directory:
Start by creating a new binary-based Cargo project and changing into the new directory:
```bash
cargo new hello-world --bin
@ -24,11 +20,12 @@ actix = "0.5"
actix-web = "0.4"
```
In order to implement a web server, first we need to create a request handler.
In order to implement a web server, we first need to create a request handler.
A request handler is a function that accepts an `HttpRequest` instance as its only parameter
and returns a type that can be converted into `HttpResponse`:
Filename: src/main.rs
```rust
# extern crate actix_web;
# use actix_web::*;
@ -64,10 +61,10 @@ connections. The server accepts a function that should return an `HttpHandler` i
.run();
```
That's it. Now, compile and run the program with `cargo run`.
That's it! Now, compile and run the program with `cargo run`.
Head over to ``http://localhost:8088/`` to see the results.
Here is full source of main.rs file:
The full source of src/main.rs is listed below:
```rust
# use std::thread;
@ -80,7 +77,7 @@ fn index(req: HttpRequest) -> &'static str {
fn main() {
# // In the doctest suite we can't run blocking code - deliberately leak a thread
# // If copying this example in show-all mode make sure you skip the thread spawn
# // If copying this example in show-all mode, make sure you skip the thread spawn
# // call.
# thread::spawn(|| {
HttpServer::new(
@ -92,7 +89,11 @@ fn main() {
}
```
Note on the `actix` crate. Actix web framework is built on top of actix actor library.
> **Note**: actix web is built upon [actix](https://github.com/actix/actix),
> an [actor model](https://en.wikipedia.org/wiki/Actor_model) framework in Rust.
`actix::System` initializes actor system, `HttpServer` is an actor and must run within a
properly configured actix system. For more information please check
[actix documentation](https://actix.github.io/actix/actix/)
properly configured actix system.
> For more information, check out the [actix documentation](https://actix.github.io/actix/actix/)
> and [actix guide](https://actix.github.io/actix/guide/).

View File

@ -1,20 +1,21 @@
# Application
Actix web provides some primitives to build web servers and applications with Rust.
It provides routing, middlewares, pre-processing of requests, and post-processing of responses,
Actix web provides various primitives to build web servers and applications with Rust.
It provides routing, middlewares, pre-processing of requests, post-processing of responses,
websocket protocol handling, multipart streams, etc.
All actix web servers are built around the `App` instance.
It is used for registering routes for resources, and middlewares.
It also stores application specific state that is shared across all handlers
within same application.
It is used for registering routes for resources and middlewares.
It also stores application state shared across all handlers within same application.
Application acts as a namespace for all routes, i.e all routes for a specific application
Applications act as a namespace for all routes, i.e all routes for a specific application
have the same url path prefix. The application prefix always contains a leading "/" slash.
If supplied prefix does not contain leading slash, it gets inserted.
The prefix should consist of value path segments. i.e for an application with prefix `/app`
any request with the paths `/app`, `/app/` or `/app/test` would match,
but path `/application` would not match.
If a supplied prefix does not contain leading slash, it is automatically inserted.
The prefix should consist of value path segments.
> For an application with prefix `/app`,
> any request with the paths `/app`, `/app/`, or `/app/test` would match;
> however, the path `/application` would not match.
```rust,ignore
# extern crate actix_web;
@ -31,10 +32,11 @@ but path `/application` would not match.
# }
```
In this example application with `/app` prefix and `index.html` resource
gets created. This resource is available as on `/app/index.html` url.
For more information check
[*URL Matching*](./qs_5.html#using-a-application-prefix-to-compose-applications) section.
In this example, an application with the `/app` prefix and a `index.html` resource
are created. This resource is available through the `/app/index.html` url.
> For more information, check the
> [URL Dispatch](./qs_5.html#using-a-application-prefix-to-compose-applications) section.
Multiple applications can be served with one server:
@ -59,18 +61,17 @@ fn main() {
}
```
All `/app1` requests route to the first application, `/app2` to the second and then all other to the third.
Applications get matched based on registration order, if an application with more general
prefix is registered before a less generic one, that would effectively block the less generic
application from getting matched. For example, if *application* with prefix "/" gets registered
as first application, it would match all incoming requests.
All `/app1` requests route to the first application, `/app2` to the second, and all other to the third.
**Applications get matched based on registration order**. If an application with a more generic
prefix is registered before a less generic one, it would effectively block the less generic
application matching. For example, if an `App` with the prefix `"/"` was registered
as the first application, it would match all incoming requests.
## State
Application state is shared with all routes and resources within the same application.
State can be accessed with the `HttpRequest::state()` method as a read-only,
but an interior mutability pattern with `RefCell` can be used to achieve state mutability.
State can be accessed with `HttpContext::state()` when using an http actor.
When using an http actor,state can be accessed with the `HttpRequest::state()` as read-only,
but interior mutability with `RefCell` can be used to achieve state mutability.
State is also available for route matching predicates and middlewares.
Let's write a simple application that uses shared state. We are going to store request count
@ -102,8 +103,8 @@ fn main() {
}
```
Note on application state, http server accepts an application factory rather than an application
instance. Http server constructs an application instance for each thread, so application state
must be constructed multiple times. If you want to share state between different threads, a
shared object should be used, like `Arc`. Application state does not need to be `Send` and `Sync`
but the application factory must be `Send` + `Sync`.
> **Note**: http server accepts an application factory rather than an application
> instance. Http server constructs an application instance for each thread, thus application state
> must be constructed multiple times. If you want to share state between different threads, a
> shared object should be used, e.g. `Arc`. Application state does not need to be `Send` and `Sync`,
> but the application factory must be `Send` + `Sync`.

View File

@ -1,13 +1,19 @@
# Server
The [*HttpServer*](../actix_web/struct.HttpServer.html) type is responsible for
serving http requests. *HttpServer* accepts application factory as a parameter,
Application factory must have `Send` + `Sync` boundaries. More about that in the
*multi-threading* section. To bind to a specific socket address, `bind()` must be used.
This method can be called multiple times. To start the http server, one of the *start*
methods can be used. `start()` method starts a simple server, `start_tls()` or `start_ssl()`
starts ssl server. *HttpServer* is an actix actor, it has to be initialized
within a properly configured actix system:
The [**HttpServer**](../actix_web/struct.HttpServer.html) type is responsible for
serving http requests.
`HttpServer` accepts an application factory as a parameter, and the
application factory must have `Send` + `Sync` boundaries. More about that in the
*multi-threading* section.
To bind to a specific socket address, `bind()` must be used, and it may be called multiple times.
To start the http server, one of the start methods.
- use `start()` for a simple server
- use `start_tls()` or `start_ssl()` for a ssl server
`HttpServer` is an actix actor. It must be initialized within a properly configured actix system:
```rust
# extern crate actix;
@ -29,17 +35,17 @@ fn main() {
}
```
It is possible to start a server in a separate thread with the *spawn()* method. In that
case the server spawns a new thread and creates a new actix system in it. To stop
this server, send a `StopServer` message.
> It is possible to start a server in a separate thread with the `spawn()` method. In that
> case the server spawns a new thread and creates a new actix system in it. To stop
> this server, send a `StopServer` message.
Http server is implemented as an actix actor. It is possible to communicate with the server
via a messaging system. All start methods like `start()`, `start_ssl()`, etc. return the
address of the started http server. Actix http server accepts several messages:
`HttpServer` is implemented as an actix actor. It is possible to communicate with the server
via a messaging system. All start methods, e.g. `start()` and `start_ssl()`, return the
address of the started http server. It accepts several messages:
* `PauseServer` - Pause accepting incoming connections
* `ResumeServer` - Resume accepting incoming connections
* `StopServer` - Stop incoming connection processing, stop all workers and exit
- `PauseServer` - Pause accepting incoming connections
- `ResumeServer` - Resume accepting incoming connections
- `StopServer` - Stop incoming connection processing, stop all workers and exit
```rust
# extern crate futures;
@ -74,7 +80,7 @@ fn main() {
## Multi-threading
Http server automatically starts an number of http workers, by default
`HttpServer` automatically starts an number of http workers, by default
this number is equal to number of logical CPUs in the system. This number
can be overridden with the `HttpServer::threads()` method.
@ -92,8 +98,10 @@ fn main() {
```
The server creates a separate application instance for each created worker. Application state
is not shared between threads, to share state `Arc` could be used. Application state
does not need to be `Send` and `Sync` but application factory must be `Send` + `Sync`.
is not shared between threads. To share state, `Arc` could be used.
> Application state does not need to be `Send` and `Sync`,
> but factories must be `Send` + `Sync`.
## SSL
@ -123,22 +131,21 @@ fn main() {
}
```
Note on *HTTP/2.0* protocol over tls without prior knowledge, it requires
[tls alpn](https://tools.ietf.org/html/rfc7301). At the moment only
`openssl` has `alpn ` support.
Please check [example](https://github.com/actix/actix-web/tree/master/examples/tls)
for a full example.
> **Note**: the *HTTP/2.0* protocol requires
> [tls alpn](https://tools.ietf.org/html/rfc7301).
> At the moment, only `openssl` has `alpn` support.
> For a full example, check out
> [examples/tls](https://github.com/actix/actix-web/tree/master/examples/tls).
## Keep-Alive
Actix can wait for requests on a keep-alive connection. *Keep alive*
connection behavior is defined by server settings.
Actix can wait for requests on a keep-alive connection.
* `75` or `Some(75)` or `KeepAlive::Timeout(75)` - enable 75 sec *keep alive* timer according
request and response settings.
* `None` or `KeepAlive::Disabled` - disable *keep alive*.
* `KeepAlive::Tcp(75)` - Use `SO_KEEPALIVE` socket option.
> *keep alive* connection behavior is defined by server settings.
- `75`, `Some(75)`, `KeepAlive::Timeout(75)` - enable 75 second *keep alive* timer.
- `None` or `KeepAlive::Disabled` - disable *keep alive*.
- `KeepAlive::Tcp(75)` - use `SO_KEEPALIVE` socket option.
```rust
# extern crate actix_web;
@ -163,11 +170,12 @@ fn main() {
}
```
If first option is selected then *keep alive* state is
If the first option is selected, then *keep alive* state is
calculated based on the response's *connection-type*. By default
`HttpResponse::connection_type` is not defined in that case *keep alive*
defined by request's http version. Keep alive is off for *HTTP/1.0*
and is on for *HTTP/1.1* and *HTTP/2.0*.
`HttpResponse::connection_type` is not defined. In that case *keep alive* is
defined by the request's http version.
> *keep alive* is **off** for *HTTP/1.0* and is **on** for *HTTP/1.1* and *HTTP/2.0*.
*Connection type* can be change with `HttpResponseBuilder::connection_type()` method.
@ -186,19 +194,19 @@ fn index(req: HttpRequest) -> HttpResponse {
## Graceful shutdown
Actix http server supports graceful shutdown. After receiving a stop signal, workers
have a specific amount of time to finish serving requests. Workers still alive after the
`HttpServer` supports graceful shutdown. After receiving a stop signal, workers
have a specific amount of time to finish serving requests. Any workers still alive after the
timeout are force-dropped. By default the shutdown timeout is set to 30 seconds.
You can change this parameter with the `HttpServer::shutdown_timeout()` method.
You can send a stop message to the server with the server address and specify if you want
graceful shutdown or not. The `start()` methods return address of the server.
graceful shutdown or not. The `start()` methods returns address of the server.
Http server handles several OS signals. *CTRL-C* is available on all OSs,
`HttpServer` handles several OS signals. *CTRL-C* is available on all OSs,
other signals are available on unix systems.
* *SIGINT* - Force shutdown workers
* *SIGTERM* - Graceful shutdown workers
* *SIGQUIT* - Force shutdown workers
- *SIGINT* - Force shutdown workers
- *SIGTERM* - Graceful shutdown workers
- *SIGQUIT* - Force shutdown workers
It is possible to disable signal handling with `HttpServer::disable_signals()` method.
> It is possible to disable signal handling with `HttpServer::disable_signals()` method.

View File

@ -1,17 +1,18 @@
# Handler
A request handler can be any object that implements
[*Handler trait*](../actix_web/dev/trait.Handler.html).
Request handling happens in two stages. First the handler object is called.
Handler can return any object that implements
[*Responder trait*](../actix_web/trait.Responder.html#foreign-impls).
Then `respond_to()` is called on the returned object. And finally
result of the `respond_to()` call is converted to a `Reply` object.
[`Handler` trait](../actix_web/dev/trait.Handler.html).
Request handling happens in two stages. First the handler object is called,
returning any object that implements the
[`Responder` trait](../actix_web/trait.Responder.html#foreign-impls).
Then, `respond_to()` is called on the returned object, converting itself to a `Reply` or `Error`.
By default actix provides `Responder` implementations for some standard types,
like `&'static str`, `String`, etc.
For a complete list of implementations, check
[*Responder documentation*](../actix_web/trait.Responder.html#foreign-impls).
such as `&'static str`, `String`, etc.
> For a complete list of implementations, check
> [*Responder documentation*](../actix_web/trait.Responder.html#foreign-impls).
Examples of valid handlers:
@ -39,15 +40,16 @@ fn index(req: HttpRequest) -> Box<Future<Item=HttpResponse, Error=Error>> {
}
```
Some notes on shared application state and handler state. If you noticed
*Handler* trait is generic over *S*, which defines application state type. So
application state is accessible from handler with the `HttpRequest::state()` method.
But state is accessible as a read-only reference - if you need mutable access to state
you have to implement it yourself. On other hand, handler can mutably access its own state
as the `handle` method takes a mutable reference to *self*. Beware, actix creates multiple copies
of application state and handlers, unique for each thread, so if you run your
application in several threads, actix will create the same amount as number of threads
of application state objects and handler objects.
*Handler* trait is generic over *S*, which defines the application state's type.
Application state is accessible from the handler with the `HttpRequest::state()` method;
however, state is accessible as a read-only reference. If you need mutable access to state,
it must be implemented.
> **Note**: Alternatively, the handler can mutably access its own state because the `handle` method takes
> mutable reference to *self*. **Beware**, actix creates multiple copies
> of the application state and the handlers, unique for each thread. If you run your
> application in several threads, actix will create the same amount as number of threads
> of application state objects and handler objects.
Here is an example of a handler that stores the number of processed requests:
@ -69,8 +71,8 @@ impl<S> Handler<S> for MyHandler {
# fn main() {}
```
This handler will work, but `self.0` will be different depending on the number of threads and
number of requests processed per thread. A proper implementation would use `Arc` and `AtomicUsize`
Although this handler will work, `self.0` will be different depending on the number of threads and
number of requests processed per thread. A proper implementation would use `Arc` and `AtomicUsize`.
```rust
# extern crate actix;
@ -111,14 +113,15 @@ fn main() {
}
```
Be careful with synchronization primitives like *Mutex* or *RwLock*. Actix web framework
handles requests asynchronously; by blocking thread execution all concurrent
request handling processes would block. If you need to share or update some state
from multiple threads consider using the [actix](https://actix.github.io/actix/actix/) actor system.
> Be careful with synchronization primitives like `Mutex` or `RwLock`. Actix web framework
> handles requests asynchronously. By blocking thread execution, all concurrent
> request handling processes would block. If you need to share or update some state
> from multiple threads, consider using the [actix](https://actix.github.io/actix/actix/) actor system.
## Response with custom type
To return a custom type directly from a handler function, the type needs to implement the `Responder` trait.
To return a custom type directly from a handler function, the type needs to implement the `Responder` trait.
Let's create a response for a custom type that serializes to an `application/json` response:
```rust
@ -171,10 +174,10 @@ fn main() {
## Async handlers
There are two different types of async handlers.
There are two different types of async handlers. Response objects can be generated asynchronously
or more precisely, any type that implements the [*Responder*](../actix_web/trait.Responder.html) trait.
Response objects can be generated asynchronously or more precisely, any type
that implements the [*Responder*](../actix_web/trait.Responder.html) trait. In this case the handler must return a `Future` object that resolves to the *Responder* type, i.e:
In this case, the handler must return a `Future` object that resolves to the *Responder* type, i.e:
```rust
# extern crate actix_web;
@ -205,8 +208,8 @@ fn main() {
}
```
Or the response body can be generated asynchronously. In this case body
must implement stream trait `Stream<Item=Bytes, Error=Error>`, i.e:
Or the response body can be generated asynchronously. In this case, body
must implement the stream trait `Stream<Item=Bytes, Error=Error>`, i.e:
```rust
# extern crate actix_web;
@ -233,7 +236,7 @@ fn main() {
Both methods can be combined. (i.e Async response with streaming body)
It is possible to return a `Result` where the `Result::Item` type can be `Future`.
In this example the `index` handler can return an error immediately or return a
In this example, the `index` handler can return an error immediately or return a
future that resolves to a `HttpResponse`.
```rust
@ -265,11 +268,11 @@ fn index(req: HttpRequest) -> Result<Box<Future<Item=HttpResponse, Error=Error>>
## Different return types (Either)
Sometimes you need to return different types of responses. For example
you can do error check and return error and return async response otherwise.
Or any result that requires two different types.
For this case the [*Either*](../actix_web/enum.Either.html) type can be used.
*Either* allows combining two different responder types into a single type.
Sometimes, you need to return different types of responses. For example,
you can error check and return errors, return async responses, or any result that requires two different types.
For this case, the [`Either`](../actix_web/enum.Either.html) type can be used.
`Either` allows combining two different responder types into a single type.
```rust
# extern crate actix_web;

View File

@ -1,10 +1,11 @@
# Errors
Actix uses [`Error` type](../actix_web/error/struct.Error.html)
Actix uses the [`Error` type](../actix_web/error/struct.Error.html)
and [`ResponseError` trait](../actix_web/error/trait.ResponseError.html)
for handling handler's errors.
Any error that implements the `ResponseError` trait can be returned as an error value.
*Handler* can return an *Result* object; actix by default provides
`Handler` can return an `Result` object. By default, actix provides a
`Responder` implementation for compatible result types. Here is the implementation
definition:
@ -12,7 +13,8 @@ definition:
impl<T: Responder, E: Into<Error>> Responder for Result<T, E>
```
And any error that implements `ResponseError` can be converted into an `Error` object.
Any error that implements `ResponseError` can be converted into an `Error` object.
For example, if the *handler* function returns `io::Error`, it would be converted
into an `HttpInternalServerError` response. Implementation for `io::Error` is provided
by default.
@ -35,7 +37,7 @@ fn index(req: HttpRequest) -> io::Result<fs::NamedFile> {
## Custom error response
To add support for custom errors, all we need to do is just implement the `ResponseError` trait
To add support for custom errors, all we need to do is implement the `ResponseError` trait
for the custom error type. The `ResponseError` trait has a default implementation
for the `error_response()` method: it generates a *500* response.
@ -109,7 +111,7 @@ fn index(req: HttpRequest) -> Result<&'static str, MyError> {
## Error helpers
Actix provides a set of error helper types. It is possible to use them for generating
specific error responses. We can use helper types for the first example with custom error.
specific error responses. We can use the helper types for the first example with a custom error.
```rust
# extern crate actix_web;

View File

@ -2,17 +2,19 @@
URL dispatch provides a simple way for mapping URLs to `Handler` code using a simple pattern
matching language. If one of the patterns matches the path information associated with a request,
a particular handler object is invoked. A handler is a specific object that implements the
`Handler` trait, defined in your application, that receives the request and returns
a response object. More information is available in the [handler section](../qs_4.html).
a particular handler object is invoked.
> A handler is a specific object that implements the
> `Handler` trait, defined in your application, that receives the request and returns
> a response object. More information is available in the [handler section](../qs_4.html).
## Resource configuration
Resource configuration is the act of adding a new resources to an application.
A resource has a name, which acts as an identifier to be used for URL generation.
The name also allows developers to add routes to existing resources.
A resource also has a pattern, meant to match against the *PATH* portion of a *URL*,
it does not match against the *QUERY* portion (the portion following the scheme and
A resource also has a pattern, meant to match against the *PATH* portion of a *URL*.
It does not match against the *QUERY* portion (the portion following the scheme and
port, e.g., */foo/bar* in the *URL* *http://localhost:8080/foo/bar?q=value*).
The [App::resource](../actix_web/struct.App.html#method.resource) methods
@ -43,7 +45,7 @@ The *Configuration function* has the following type:
```
The *Configuration function* can set a name and register specific routes.
If a resource does not contain any route or does not have any matching routes it
If a resource does not contain any route or does not have any matching routes, it
returns *NOT FOUND* http response.
## Configuring a Route
@ -55,8 +57,9 @@ all requests and the default handler is `HttpNotFound`.
The application routes incoming requests based on route criteria which are defined during
resource registration and route registration. Resource matches all routes it contains in
the order the routes were registered via `Resource::route()`. A *Route* can contain
any number of *predicates* but only one handler.
the order the routes were registered via `Resource::route()`.
> A *Route* can contain any number of *predicates* but only one handler.
```rust
# extern crate actix_web;
@ -74,10 +77,11 @@ fn main() {
}
```
In this example `HttpResponse::Ok()` is returned for *GET* requests,
if request contains `Content-Type` header and value of this header is *text/plain*
and path equals to `/path`. Resource calls handle of the first matching route.
If a resource can not match any route a "NOT FOUND" response is returned.
In this example, `HttpResponse::Ok()` is returned for *GET* requests.
If a request contains `Content-Type` header, the value of this header is *text/plain*,
and path equals to `/path`, Resource calls handle of the first matching route.
If a resource can not match any route, a "NOT FOUND" response is returned.
[*Resource::route()*](../actix_web/struct.Resource.html#method.route) returns a
[*Route*](../actix_web/struct.Route.html) object. Route can be configured with a
@ -118,9 +122,7 @@ arguments provided to a route configuration returns `false` during a check, that
skipped and route matching continues through the ordered set of routes.
If any route matches, the route matching process stops and the handler associated with
the route is invoked.
If no route matches after all route patterns are exhausted, a *NOT FOUND* response get returned.
the route is invoked. If no route matches after all route patterns are exhausted, a *NOT FOUND* response get returned.
## Resource pattern syntax
@ -208,8 +210,9 @@ For example, for the URL */abc/*:
* */abc/{foo}* will not match.
* */{foo}/* will match.
Note that path will be URL-unquoted and decoded into valid unicode string before
matching pattern and values representing matched path segments will be URL-unquoted too.
> **Note**: path will be URL-unquoted and decoded into valid unicode string before
> matching pattern and values representing matched path segments will be URL-unquoted too.
So for instance, the following pattern:
```
@ -292,11 +295,11 @@ any) is skipped.
For security purposes, if a segment meets any of the following conditions,
an `Err` is returned indicating the condition met:
* Decoded segment starts with any of: `.` (except `..`), `*`
* Decoded segment ends with any of: `:`, `>`, `<`
* Decoded segment contains any of: `/`
* On Windows, decoded segment contains any of: '\'
* Percent-encoding results in invalid UTF8.
* Decoded segment starts with any of: `.` (except `..`), `*`
* Decoded segment ends with any of: `:`, `>`, `<`
* Decoded segment contains any of: `/`
* On Windows, decoded segment contains any of: '\'
* Percent-encoding results in invalid UTF8.
As a result of these conditions, a `PathBuf` parsed from request path parameter is
safe to interpolate within, or use as a suffix of, a path without additional checks.
@ -350,8 +353,8 @@ fn main() {
}
```
It also possible to extract path information to a tuple, in this case you don't need
to define extra type, just use tuple for as a `Path` generic type.
It also possible to extract path information to a tuple. In this case, you don't need
to define an extra type; use a tuple as a `Path` generic type.
Here is previous example re-written using tuple instead of specific type.
@ -433,21 +436,21 @@ fn main() {
By normalizing it means:
- Add a trailing slash to the path.
- Double slashes are replaced by one.
* Add a trailing slash to the path.
* Double slashes are replaced by one.
The handler returns as soon as it finds a path that resolves
correctly. The order if all enable is 1) merge, 3) both merge and append
and 3) append. If the path resolves with
at least one of those conditions, it will redirect to the new path.
If *append* is *true* append slash when needed. If a resource is
If *append* is *true*, append slash when needed. If a resource is
defined with trailing slash and the request doesn't have one, it will
be appended automatically.
If *merge* is *true*, merge multiple consecutive slashes in the path into one.
This handler designed to be use as a handler for application's *default resource*.
This handler designed to be used as a handler for application's *default resource*.
```rust
# extern crate actix_web;
@ -468,7 +471,7 @@ fn main() {
In this example `/resource`, `//resource///` will be redirected to `/resource/`.
In this example path normalization handler is registered for all methods,
In this example, the path normalization handler is registered for all methods,
but you should not rely on this mechanism to redirect *POST* requests. The redirect of the
slash-appending *Not Found* will turn a *POST* request into a GET, losing any
*POST* data in the original request.
@ -493,7 +496,7 @@ fn main() {
## Using an Application Prefix to Compose Applications
The `App::prefix()`" method allows to set a specific application prefix.
The `App::prefix()` method allows to set a specific application prefix.
This prefix represents a resource prefix that will be prepended to all resource patterns added
by the resource configuration. This can be used to help mount a set of routes at a different
location than the included callable's author intended while still maintaining the same
@ -556,7 +559,7 @@ fn main() {
}
```
In this example *index* handler will be called only if request contains *CONTENT-TYPE* header.
In this example, *index* handler will be called only if request contains *CONTENT-TYPE* header.
Predicates have access to the application's state via `HttpRequest::state()`.
Also predicates can store extra information in
@ -565,7 +568,7 @@ Also predicates can store extra information in
### Modifying predicate values
You can invert the meaning of any predicate value by wrapping it in a `Not` predicate.
For example if you want to return "METHOD NOT ALLOWED" response for all methods
For example, if you want to return "METHOD NOT ALLOWED" response for all methods
except "GET":
```rust