mirror of
https://github.com/actix/examples
synced 2024-11-23 14:31:07 +01:00
format markdown
This commit is contained in:
parent
f27cc4b6b4
commit
e239414a55
@ -44,6 +44,7 @@
|
|||||||
- [Mozilla Services Skeleton App](https://github.com/mozilla-services/skeleton)
|
- [Mozilla Services Skeleton App](https://github.com/mozilla-services/skeleton)
|
||||||
|
|
||||||
## Paid Resources
|
## Paid Resources
|
||||||
|
|
||||||
- [book] [Zero2prod by Luca Palmieri](https://algoluca.gumroad.com/l/zero2prod): Takes you on a journey to discover the world of backend development in Rust.
|
- [book] [Zero2prod by Luca Palmieri](https://algoluca.gumroad.com/l/zero2prod): Takes you on a journey to discover the world of backend development in Rust.
|
||||||
|
|
||||||
## Contribute
|
## Contribute
|
||||||
|
@ -26,7 +26,7 @@ Now with the cookie `auth-example` sent in a GET request, the `user1` is recogni
|
|||||||
> GET / HTTP/1.1
|
> GET / HTTP/1.1
|
||||||
> Host: localhost:8080
|
> Host: localhost:8080
|
||||||
> Cookie: auth-example=GRm2Vku0UpFbJ3CNTKbndzIYHVGi8wc8eoXm/Axtf2BO
|
> Cookie: auth-example=GRm2Vku0UpFbJ3CNTKbndzIYHVGi8wc8eoXm/Axtf2BO
|
||||||
>
|
>
|
||||||
< HTTP/1.1 200 OK
|
< HTTP/1.1 200 OK
|
||||||
<
|
<
|
||||||
Hello user1
|
Hello user1
|
||||||
|
@ -33,7 +33,6 @@
|
|||||||
- [sparkpost](https://crates.io/crates/sparkpost) // Rust bindings for sparkpost email api v1.
|
- [sparkpost](https://crates.io/crates/sparkpost) // Rust bindings for sparkpost email api v1.
|
||||||
- [uuid](https://crates.io/crates/uuid) // A library to generate and parse UUIDs.
|
- [uuid](https://crates.io/crates/uuid) // A library to generate and parse UUIDs.
|
||||||
|
|
||||||
|
|
||||||
Read the full tutorial series on [gill.net.in](https://gill.net.in)
|
Read the full tutorial series on [gill.net.in](https://gill.net.in)
|
||||||
|
|
||||||
- [Auth Web Microservice with Rust using Actix Web v2 - Complete Tutorial](https://gill.net.in/posts/auth-microservice-rust-actix-web1.0-diesel-complete-tutorial/)
|
- [Auth Web Microservice with Rust using Actix Web v2 - Complete Tutorial](https://gill.net.in/posts/auth-microservice-rust-actix-web1.0-diesel-complete-tutorial/)
|
||||||
|
@ -2,9 +2,8 @@
|
|||||||
|
|
||||||
Demonstrates how to serve static files. Inside the `./static` folder you will find 2 subfolders:
|
Demonstrates how to serve static files. Inside the `./static` folder you will find 2 subfolders:
|
||||||
|
|
||||||
* `root`: A tree of files that will be served at the web root `/`. This includes the `css` and `js` folders, each
|
- `root`: A tree of files that will be served at the web root `/`. This includes the `css` and `js` folders, each containing an example file.
|
||||||
containing an example file.
|
- `images`: A list of images that will be served at `/images` path, with file listing enabled.
|
||||||
* `images`: A list of images that will be served at `/images` path, with file listing enabled.
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
@ -1,16 +1,20 @@
|
|||||||
# Actix Web CORS example
|
# Cross-Origin Resource Sharing (CORS)
|
||||||
|
|
||||||
## Run Server
|
## Run Server
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cd cors/backend
|
cd cors/backend
|
||||||
cargo run
|
cargo run
|
||||||
```
|
```
|
||||||
|
|
||||||
## Run Frontend
|
## Run Frontend
|
||||||
|
|
||||||
In a separate terminal, also run:
|
In a separate terminal, also run:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cd cors/frontend
|
cd cors/frontend
|
||||||
npm install
|
npm install
|
||||||
npm run serve
|
npm run serve
|
||||||
```
|
```
|
||||||
|
|
||||||
then open browser at: http://localhost:8080
|
then open browser at: http://localhost:8080
|
||||||
|
@ -1,23 +1,27 @@
|
|||||||
# Usage:
|
# Usage:
|
||||||
|
|
||||||
This is an example demonstrating the construction of async state with `App::data_factory`
|
This is an example demonstrating the construction of async state with `App::data_factory`
|
||||||
|
|
||||||
## Reason:
|
## Reason:
|
||||||
|
|
||||||
Use of a `data_factory` would make sense in these situations:
|
Use of a `data_factory` would make sense in these situations:
|
||||||
|
|
||||||
- When async state does not necessarily have to be shared between workers/threads.
|
- When async state does not necessarily have to be shared between workers/threads.
|
||||||
|
|
||||||
- When an async state would spawn tasks on `actix-rt`. If state was centralized there could be a possibility the tasks get an unbalanced distribution on the workers/threads
|
- When an async state would spawn tasks on `actix-rt`. If state was centralized there could be a possibility the tasks get an unbalanced distribution on the workers/threads (`actix-rt` would spawn tasks on local thread whenever it's called)
|
||||||
(`actix-rt` would spawn tasks on local thread whenever it's called)
|
|
||||||
|
|
||||||
## Requirement:
|
## Requirement:
|
||||||
|
|
||||||
- `rustc 1.58 stable`
|
- `rustc 1.58 stable`
|
||||||
- `redis` server listen on `127.0.0.1:6379`(or use `REDIS_URL` env argument when starting the example)
|
- `redis` server listen on `127.0.0.1:6379`(or use `REDIS_URL` env argument when starting the example)
|
||||||
|
|
||||||
## Endpoints:
|
## Endpoints:
|
||||||
|
|
||||||
- use a work load generator(e.g wrk) to benchmark the end points:
|
- use a work load generator(e.g wrk) to benchmark the end points:
|
||||||
|
|
||||||
http://127.0.0.1:8080/pool prebuilt shared redis pool
|
http://127.0.0.1:8080/pool prebuilt shared redis pool
|
||||||
http://127.0.0.1:8080/pool2 data_factory redis pool
|
http://127.0.0.1:8080/pool2 data_factory redis pool
|
||||||
|
|
||||||
## Context:
|
## Context:
|
||||||
The real world difference can be vary by the work you are doing but in general it's a good idea to
|
|
||||||
spread your *identical* async tasks evenly between threads and have as little cross threads synchronization as possible.
|
The real world difference can be vary by the work you are doing but in general it's a good idea to spread your _identical_ async tasks evenly between threads and have as little cross threads synchronization as possible.
|
||||||
|
@ -48,30 +48,35 @@ cargo run
|
|||||||
Inserts a new user into the SQLite DB.
|
Inserts a new user into the SQLite DB.
|
||||||
|
|
||||||
Provide a JSON payload with a name. Eg:
|
Provide a JSON payload with a name. Eg:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{ "name": "bill" }
|
{ "name": "bill" }
|
||||||
```
|
```
|
||||||
|
|
||||||
On success, a response like the following is returned:
|
On success, a response like the following is returned:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"id": "9e46baba-a001-4bb3-b4cf-4b3e5bab5e97",
|
"id": "9e46baba-a001-4bb3-b4cf-4b3e5bab5e97",
|
||||||
"name": "bill"
|
"name": "bill"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Client Examples</summary>
|
<summary>Client Examples</summary>
|
||||||
|
|
||||||
Using [HTTPie](https://httpie.org/):
|
Using [HTTPie](https://httpie.org/):
|
||||||
```sh
|
|
||||||
http POST localhost:8080/user name=bill
|
```sh
|
||||||
```
|
http POST localhost:8080/user name=bill
|
||||||
|
```
|
||||||
|
|
||||||
|
Using cURL:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -S -X POST --header "Content-Type: application/json" --data '{"name":"bill"}' http://localhost:8080/user
|
||||||
|
```
|
||||||
|
|
||||||
Using cURL:
|
|
||||||
```sh
|
|
||||||
curl -S -X POST --header "Content-Type: application/json" --data '{"name":"bill"}' http://localhost:8080/user
|
|
||||||
```
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
#### `GET /user/{user_uid}`
|
#### `GET /user/{user_uid}`
|
||||||
@ -81,15 +86,18 @@ Gets a user from the DB using its UID (returned from the insert request or taken
|
|||||||
<details>
|
<details>
|
||||||
<summary>Client Examples</summary>
|
<summary>Client Examples</summary>
|
||||||
|
|
||||||
Using [HTTPie](https://httpie.org/):
|
Using [HTTPie](https://httpie.org/):
|
||||||
```sh
|
|
||||||
http localhost:8080/user/9e46baba-a001-4bb3-b4cf-4b3e5bab5e97
|
```sh
|
||||||
```
|
http localhost:8080/user/9e46baba-a001-4bb3-b4cf-4b3e5bab5e97
|
||||||
|
```
|
||||||
|
|
||||||
|
Using cURL:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -S http://localhost:8080/user/9e46baba-a001-4bb3-b4cf-4b3e5bab5e97
|
||||||
|
```
|
||||||
|
|
||||||
Using cURL:
|
|
||||||
```sh
|
|
||||||
curl -S http://localhost:8080/user/9e46baba-a001-4bb3-b4cf-4b3e5bab5e97
|
|
||||||
```
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
### Explore The SQLite DB
|
### Explore The SQLite DB
|
||||||
@ -103,7 +111,6 @@ sqlite> .tables
|
|||||||
sqlite> SELECT * FROM users;
|
sqlite> SELECT * FROM users;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Using Other Databases
|
## Using Other Databases
|
||||||
|
|
||||||
You can find a complete example of Diesel + PostgreSQL at: [https://github.com/TechEmpower/FrameworkBenchmarks/tree/master/frameworks/Rust/actix](https://github.com/TechEmpower/FrameworkBenchmarks/tree/master/frameworks/Rust/actix)
|
You can find a complete example of Diesel + PostgreSQL at: [https://github.com/TechEmpower/FrameworkBenchmarks/tree/master/frameworks/Rust/actix](https://github.com/TechEmpower/FrameworkBenchmarks/tree/master/frameworks/Rust/actix)
|
||||||
|
@ -1,23 +1,16 @@
|
|||||||
# MongoDB
|
# MongoDB
|
||||||
|
|
||||||
Simple example of MongoDB usage with Actix Web. For more information on the MongoDB Rust driver,
|
Simple example of MongoDB usage with Actix Web. For more information on the MongoDB Rust driver, visit the [documentation](https://docs.rs/mongodb/2.0.0/mongodb/index.html) and [source code](https://github.com/mongodb/mongo-rust-driver).
|
||||||
visit the [documentation](https://docs.rs/mongodb/2.0.0/mongodb/index.html) and
|
|
||||||
[source code](https://github.com/mongodb/mongo-rust-driver).
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
### Install MongoDB
|
### Install MongoDB
|
||||||
|
|
||||||
Visit the [MongoDB Download Center](https://www.mongodb.com/try) for instructions on how to use
|
Visit the [MongoDB Download Center](https://www.mongodb.com/try) for instructions on how to use MongoDB Atlas or set up MongoDB locally.
|
||||||
MongoDB Atlas or set up MongoDB locally.
|
|
||||||
|
|
||||||
### Set an environment variable
|
### Set an environment variable
|
||||||
|
|
||||||
The example code creates a client with the URI set by the `MONGODB_URI` environment variable. The
|
The example code creates a client with the URI set by the `MONGODB_URI` environment variable. The default URI for a standalone `mongod` running on localhost is "mongodb://localhost:27017". For more information on MongoDB URIs, visit the [connection string](https://docs.mongodb.com/manual/reference/connection-string/) entry in the MongoDB manual.
|
||||||
default URI for a standalone `mongod` running on localhost is "mongodb://localhost:27017". For more
|
|
||||||
information on MongoDB URIs, visit the
|
|
||||||
[connection string](https://docs.mongodb.com/manual/reference/connection-string/) entry in the
|
|
||||||
MongoDB manual.
|
|
||||||
|
|
||||||
### Run the example
|
### Run the example
|
||||||
|
|
||||||
|
@ -11,62 +11,56 @@
|
|||||||
|
|
||||||
1. Create database user
|
1. Create database user
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
createuser -P test_user
|
createuser -P test_user
|
||||||
```
|
```
|
||||||
|
|
||||||
Enter a password of your choice. The following instructions assume you
|
Enter a password of your choice. The following instructions assume you used `testing` as password.
|
||||||
used `testing` as password.
|
|
||||||
|
|
||||||
This step is **optional** and you can also use an existing database user
|
This step is **optional** and you can also use an existing database user for that. Just make sure to replace `test_user` by the database user of your choice in the following steps and change the `.env` file containing the configuration accordingly.
|
||||||
for that. Just make sure to replace `test_user` by the database user
|
|
||||||
of your choice in the following steps and change the `.env` file
|
|
||||||
containing the configuration accordingly.
|
|
||||||
|
|
||||||
2. Create database
|
2. Create database
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
createdb -O test_user testing_db
|
createdb -O test_user testing_db
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Initialize database
|
3. Initialize database
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
psql -f sql/schema.sql testing_db
|
psql -f sql/schema.sql testing_db
|
||||||
```
|
```
|
||||||
|
|
||||||
This step can be repeated and clears the database as it drops and
|
This step can be repeated and clears the database as it drops and recreates the schema `testing` which is used within the database.
|
||||||
recreates the schema `testing` which is used within the database.
|
|
||||||
|
|
||||||
4. Create `.env` file:
|
4. Create `.env` file:
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
SERVER_ADDR=127.0.0.1:8080
|
SERVER_ADDR=127.0.0.1:8080
|
||||||
PG.USER=test_user
|
PG.USER=test_user
|
||||||
PG.PASSWORD=testing
|
PG.PASSWORD=testing
|
||||||
PG.HOST=127.0.0.1
|
PG.HOST=127.0.0.1
|
||||||
PG.PORT=5432
|
PG.PORT=5432
|
||||||
PG.DBNAME=testing_db
|
PG.DBNAME=testing_db
|
||||||
PG.POOL.MAX_SIZE=16
|
PG.POOL.MAX_SIZE=16
|
||||||
```
|
```
|
||||||
|
|
||||||
5. Run the server:
|
5. Run the server:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
cargo run
|
cargo run
|
||||||
```
|
```
|
||||||
|
|
||||||
6. Using a different terminal send an HTTP POST request to the running server:
|
6. Using a different terminal send an HTTP POST request to the running server:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
echo '{"email": "ferris@thecrab.com", "first_name": "ferris", "last_name": "crab", "username": "ferreal"}' | http -f --json --print h POST http://127.0.0.1:8080/users
|
echo '{"email": "ferris@thecrab.com", "first_name": "ferris", "last_name": "crab", "username": "ferreal"}' | http -f --json --print h POST http://127.0.0.1:8080/users
|
||||||
```
|
```
|
||||||
|
|
||||||
**...or using curl...**
|
**...or using curl...**
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
curl -d '{"email": "ferris@thecrab.com", "first_name": "ferris", "last_name": "crab", "username": "ferreal"}' -H 'Content-Type: application/json' http://127.0.0.1:8080/users
|
curl -d '{"email": "ferris@thecrab.com", "first_name": "ferris", "last_name": "crab", "username": "ferreal"}' -H 'Content-Type: application/json' http://127.0.0.1:8080/users
|
||||||
```
|
```
|
||||||
|
|
||||||
A unique constraint exists for username, so sending this request twice
|
A unique constraint exists for username, so sending this request twice will return an internal server error (HTTP 500).
|
||||||
will return an internal server error (HTTP 500).
|
|
||||||
|
@ -61,5 +61,5 @@ At any time, verify the contents of Redis using its CLI:
|
|||||||
echo "MGET mydomain:one mydomain:two mydomain:three" | redis-cli
|
echo "MGET mydomain:one mydomain:two mydomain:three" | redis-cli
|
||||||
```
|
```
|
||||||
|
|
||||||
[HTTPie]: https://httpie.org
|
[httpie]: https://httpie.org
|
||||||
[cURL]: https://curl.haxx.se
|
[curl]: https://curl.haxx.se
|
||||||
|
@ -5,13 +5,13 @@ Getting started using databases with Actix Web, asynchronously.
|
|||||||
### init database sqlite
|
### init database sqlite
|
||||||
|
|
||||||
From the root directory of this project:
|
From the root directory of this project:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
bash db/setup_db.sh
|
bash db/setup_db.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
This creates a sqlite database, weather.db, in the root.
|
This creates a sqlite database, weather.db, in the root.
|
||||||
|
|
||||||
|
|
||||||
### server
|
### server
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
@ -26,7 +26,6 @@ cargo run
|
|||||||
|
|
||||||
[http://127.0.0.1:8080/parallel_weather](http://127.0.0.1:8080/parallel_weather)
|
[http://127.0.0.1:8080/parallel_weather](http://127.0.0.1:8080/parallel_weather)
|
||||||
|
|
||||||
|
|
||||||
### sqlite client
|
### sqlite client
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
@ -7,10 +7,10 @@ cd forms/multipart
|
|||||||
cargo run
|
cargo run
|
||||||
```
|
```
|
||||||
|
|
||||||
``` open web browser to localhost:8080 and upload file(s) ```
|
`open web browser to localhost:8080 and upload file(s)`
|
||||||
|
|
||||||
### Result
|
### Result
|
||||||
|
|
||||||
``` file(s) will show up in ./tmp in the same directory as the running process ```
|
`file(s) will show up in ./tmp in the same directory as the running process`
|
||||||
|
|
||||||
Note: this is a naive implementation and will panic on any error
|
Note: this is a naive implementation and will panic on any error
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
# GraphQL using Juniper
|
# GraphQL using Juniper
|
||||||
|
|
||||||
[Juniper](https://github.com/graphql-rust/juniper) integration for Actix Web.
|
[Juniper](https://github.com/graphql-rust/juniper) integration for Actix Web. If you want more advanced example, see also the [juniper-advanced example].
|
||||||
If you want more advanced example, see also the [juniper-advanced example].
|
|
||||||
|
|
||||||
[juniper-advanced example]: https://github.com/actix/examples/tree/master/graphql/juniper-advanced
|
[juniper-advanced example]: https://github.com/actix/examples/tree/master/graphql/juniper-advanced
|
||||||
|
|
||||||
@ -37,9 +36,7 @@ _Result:_
|
|||||||
"data": {
|
"data": {
|
||||||
"human": {
|
"human": {
|
||||||
"name": "Luke",
|
"name": "Luke",
|
||||||
"appearsIn": [
|
"appearsIn": ["NEW_HOPE"],
|
||||||
"NEW_HOPE"
|
|
||||||
],
|
|
||||||
"homePlanet": "Mars"
|
"homePlanet": "Mars"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -50,7 +47,9 @@ _Mutation example:_
|
|||||||
|
|
||||||
```graphql
|
```graphql
|
||||||
mutation {
|
mutation {
|
||||||
createHuman(newHuman: {name: "Fresh Kid Ice", appearsIn: EMPIRE, homePlanet: "earth"}) {
|
createHuman(
|
||||||
|
newHuman: { name: "Fresh Kid Ice", appearsIn: EMPIRE, homePlanet: "earth" }
|
||||||
|
) {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
appearsIn
|
appearsIn
|
||||||
@ -67,9 +66,7 @@ _Result:_
|
|||||||
"createHuman": {
|
"createHuman": {
|
||||||
"id": "1234",
|
"id": "1234",
|
||||||
"name": "Fresh Kid Ice",
|
"name": "Fresh Kid Ice",
|
||||||
"appearsIn": [
|
"appearsIn": ["EMPIRE"],
|
||||||
"EMPIRE"
|
|
||||||
],
|
|
||||||
"homePlanet": "earth"
|
"homePlanet": "earth"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
# guards
|
# guards
|
||||||
|
|
||||||
Shows how to set up custom routing guards.
|
Shows how to set up custom routing guards.
|
||||||
|
|
||||||
- Routing different API versions using a header instead of path.
|
- Routing different API versions using a header instead of path.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
@ -30,5 +31,5 @@ Using [cURL]:
|
|||||||
curl 'localhost:8080/api/hello' -H 'accept-version: 1'
|
curl 'localhost:8080/api/hello' -H 'accept-version: 1'
|
||||||
```
|
```
|
||||||
|
|
||||||
[HTTPie]: https://httpie.org
|
[httpie]: https://httpie.org
|
||||||
[cURL]: https://curl.haxx.se
|
[curl]: https://curl.haxx.se
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
## HTTP naïve proxy example
|
## HTTP naïve proxy example
|
||||||
|
|
||||||
This is a relatively simple HTTP proxy, forwarding HTTP requests to another HTTP server, including
|
This is a relatively simple HTTP proxy, forwarding HTTP requests to another HTTP server, including request body, headers, and streaming uploads.
|
||||||
request body, headers, and streaming uploads.
|
|
||||||
|
|
||||||
To start:
|
To start:
|
||||||
|
|
||||||
``` shell
|
```shell
|
||||||
cargo run -- <listen addr> <listen port> <forward addr> <forward port>
|
cargo run -- <listen addr> <listen port> <forward addr> <forward port>
|
||||||
# example:
|
# example:
|
||||||
cargo run -- 127.0.0.1 3333 127.0.0.1 8080
|
cargo run -- 127.0.0.1 3333 127.0.0.1 8080
|
||||||
|
@ -4,9 +4,7 @@
|
|||||||
|
|
||||||
### Certificate
|
### Certificate
|
||||||
|
|
||||||
We put the self-signed certificate in this directory as an example
|
We put the self-signed certificate in this directory as an example but your browser would complain that it isn't secure. So we recommend to use [`mkcert`] to trust it. To use local CA, you should run:
|
||||||
but your browser would complain that it isn't secure.
|
|
||||||
So we recommend to use [`mkcert`] to trust it. To use local CA, you should run:
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
mkcert -install
|
mkcert -install
|
||||||
@ -30,5 +28,5 @@ cargo run (or ``cargo watch -x run``)
|
|||||||
|
|
||||||
### web client
|
### web client
|
||||||
|
|
||||||
- curl: ``curl -v https://127.0.0.1:8443/index.html --compressed -k``
|
- curl: `curl -v https://127.0.0.1:8443/index.html --compressed -k`
|
||||||
- browser: [https://127.0.0.1:8443/index.html](https://127.0.0.1:8443/index.html)
|
- browser: [https://127.0.0.1:8443/index.html](https://127.0.0.1:8443/index.html)
|
||||||
|
@ -4,8 +4,7 @@
|
|||||||
|
|
||||||
### Certificate
|
### Certificate
|
||||||
|
|
||||||
All the self-signed certificate are in the ./certs directory, including the CA certificate
|
All the self-signed certificate are in the ./certs directory, including the CA certificate generated by [`mkcert`] that was used to create the server and client certs.
|
||||||
generated by [`mkcert`] that was used to create the server and client certs.
|
|
||||||
|
|
||||||
### Server
|
### Server
|
||||||
|
|
||||||
@ -19,15 +18,17 @@ The server runs HTTP on port 8080 and HTTPS on port 8443.
|
|||||||
### Providing Client Cert
|
### Providing Client Cert
|
||||||
|
|
||||||
Using [HTTPie]:
|
Using [HTTPie]:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
http https://127.0.0.1:8443/ --verify=certs/rootCA.pem --cert=certs/client-cert.pem --cert-key=certs/client-key.pem
|
http https://127.0.0.1:8443/ --verify=certs/rootCA.pem --cert=certs/client-cert.pem --cert-key=certs/client-key.pem
|
||||||
```
|
```
|
||||||
|
|
||||||
Using [cURL]:
|
Using [cURL]:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
curl https://127.0.0.1:8443/ --cacert certs/rootCA.pem --cert certs/client-cert.pem --key certs/client-key.pem
|
curl https://127.0.0.1:8443/ --cacert certs/rootCA.pem --cert certs/client-cert.pem --key certs/client-key.pem
|
||||||
```
|
```
|
||||||
|
|
||||||
[`mkcert`]: https://github.com/FiloSottile/mkcert
|
[`mkcert`]: https://github.com/FiloSottile/mkcert
|
||||||
[cURL]: https://curl.haxx.se/
|
[curl]: https://curl.haxx.se/
|
||||||
[HTTPie]: https://httpie.org/
|
[httpie]: https://httpie.org/
|
||||||
|
@ -4,9 +4,7 @@
|
|||||||
|
|
||||||
### Certificate
|
### Certificate
|
||||||
|
|
||||||
We put the self-signed certificate in this directory as an example
|
We put the self-signed certificate in this directory as an example but your browser would complain that it isn't secure. So we recommend to use [`mkcert`] to trust it. To use local CA, you should run:
|
||||||
but your browser would complain that it isn't secure.
|
|
||||||
So we recommend to use [`mkcert`] to trust it. To use local CA, you should run:
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
mkcert -install
|
mkcert -install
|
||||||
@ -19,6 +17,7 @@ mkcert 127.0.0.1 localhost
|
|||||||
```
|
```
|
||||||
|
|
||||||
For `rsa` keys use `rsa_private_keys` function instead `pkcs8_private_keys`
|
For `rsa` keys use `rsa_private_keys` function instead `pkcs8_private_keys`
|
||||||
|
|
||||||
```rs
|
```rs
|
||||||
let mut keys = pkcs8_private_keys(key_file).unwrap(); // pkcs8
|
let mut keys = pkcs8_private_keys(key_file).unwrap(); // pkcs8
|
||||||
let mut keys = rsa_private_keys(key_file).unwrap(); // rsa
|
let mut keys = rsa_private_keys(key_file).unwrap(); // rsa
|
||||||
@ -34,10 +33,9 @@ cargo run # (or ``cargo watch -x run``)
|
|||||||
# Started http server: 127.0.0.1:8443
|
# Started http server: 127.0.0.1:8443
|
||||||
```
|
```
|
||||||
|
|
||||||
If you prefer reloading you can substitute `cargo watch -x run`.
|
If you prefer reloading you can substitute `cargo watch -x run`. That requires you install the `cargo-watch` crate.
|
||||||
That requires you install the `cargo-watch` crate.
|
|
||||||
|
|
||||||
### web client
|
### web client
|
||||||
|
|
||||||
- curl: ``curl -v https://127.0.0.1:8443/index.html --compressed -k``
|
- curl: `curl -v https://127.0.0.1:8443/index.html --compressed -k`
|
||||||
- browser: [https://127.0.0.1:8443/index.html](https://127.0.0.1:8443/index.html)
|
- browser: [https://127.0.0.1:8443/index.html](https://127.0.0.1:8443/index.html)
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
# JSON decode errors
|
# JSON decode errors
|
||||||
|
|
||||||
This example demonstrates how to return useful error messages to the client
|
This example demonstrates how to return useful error messages to the client when the server receives a request with invalid JSON, or which cannot be deserialized to the expected model. By configuring an `error_handler` on the route, we can set appropriate response codes and return the string representation of the error.
|
||||||
when the server receives a request with invalid JSON, or which cannot be
|
|
||||||
deserialized to the expected model. By configuring an `error_handler` on the
|
|
||||||
route, we can set appropriate response codes and return the string
|
|
||||||
representation of the error.
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
@ -16,9 +12,7 @@ cargo run
|
|||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
The examples use `curl -i` in order to show the status line with the response
|
The examples use `curl -i` in order to show the status line with the response code. The response headers have been omitted for brevity, and replaced with an ellipsis `...`.
|
||||||
code. The response headers have been omitted for brevity, and replaced with an
|
|
||||||
ellipsis `...`.
|
|
||||||
|
|
||||||
- A well-formed request
|
- A well-formed request
|
||||||
|
|
||||||
@ -27,7 +21,7 @@ ellipsis `...`.
|
|||||||
HTTP/1.1 200 OK
|
HTTP/1.1 200 OK
|
||||||
...
|
...
|
||||||
|
|
||||||
Hello Alice!
|
Hello Alice!
|
||||||
```
|
```
|
||||||
|
|
||||||
- Missing `Content-Type` header
|
- Missing `Content-Type` header
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
This is a contrived example intended to illustrate a few important Actix Web features.
|
This is a contrived example intended to illustrate a few important Actix Web features.
|
||||||
|
|
||||||
*Imagine* that you have a process that involves 3 steps. The steps here
|
_Imagine_ that you have a process that involves 3 steps. The steps here are dumb in that they do nothing other than call an HTTP endpoint that returns the json that was posted to it. The intent here is to illustrate how to chain these steps together as futures and return a final result in a response.
|
||||||
are dumb in that they do nothing other than call an HTTP endpoint that
|
|
||||||
returns the json that was posted to it. The intent here is to illustrate
|
|
||||||
how to chain these steps together as futures and return a final result
|
|
||||||
in a response.
|
|
||||||
|
|
||||||
Actix Web features illustrated here include:
|
Actix Web features illustrated here include:
|
||||||
|
|
||||||
@ -14,7 +10,6 @@ Actix Web features illustrated here include:
|
|||||||
- POSTing json body
|
- POSTing json body
|
||||||
3. chaining futures into a single response used by an asynch endpoint
|
3. chaining futures into a single response used by an asynch endpoint
|
||||||
|
|
||||||
|
|
||||||
### server
|
### server
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
@ -23,5 +18,4 @@ cargo run
|
|||||||
# Started http server: 127.0.0.1:8080
|
# Started http server: 127.0.0.1:8080
|
||||||
```
|
```
|
||||||
|
|
||||||
Example query from the command line using httpie:
|
Example query from the command line using httpie: `echo '{"id":"1", "name": "JohnDoe"}' | http 127.0.0.1:8080/something`
|
||||||
```echo '{"id":"1", "name": "JohnDoe"}' | http 127.0.0.1:8080/something```
|
|
||||||
|
@ -18,31 +18,31 @@ With [Postman](https://www.getpostman.com/) or [Rested](moz-extension://60daeb1c
|
|||||||
|
|
||||||
- POST / (embed serde-json):
|
- POST / (embed serde-json):
|
||||||
|
|
||||||
- method : ``POST``
|
- method : `POST`
|
||||||
- url : ``http://127.0.0.1:8080/``
|
- url : `http://127.0.0.1:8080/`
|
||||||
- header : ``Content-Type`` = ``application/json``
|
- header : `Content-Type` = `application/json`
|
||||||
- body (raw) : ``{"name": "Test user", "number": 100}``
|
- body (raw) : `{"name": "Test user", "number": 100}`
|
||||||
|
|
||||||
- POST /manual (manual serde-json):
|
- POST /manual (manual serde-json):
|
||||||
|
|
||||||
- method : ``POST``
|
- method : `POST`
|
||||||
- url : ``http://127.0.0.1:8080/manual``
|
- url : `http://127.0.0.1:8080/manual`
|
||||||
- header : ``Content-Type`` = ``application/json``
|
- header : `Content-Type` = `application/json`
|
||||||
- body (raw) : ``{"name": "Test user", "number": 100}``
|
- body (raw) : `{"name": "Test user", "number": 100}`
|
||||||
|
|
||||||
- POST /mjsonrust (manual json-rust):
|
- POST /mjsonrust (manual json-rust):
|
||||||
|
|
||||||
- method : ``POST``
|
- method : `POST`
|
||||||
- url : ``http://127.0.0.1:8080/mjsonrust``
|
- url : `http://127.0.0.1:8080/mjsonrust`
|
||||||
- header : ``Content-Type`` = ``application/json``
|
- header : `Content-Type` = `application/json`
|
||||||
- body (raw) : ``{"name": "Test user", "number": 100}`` (you can also test ``{notjson}``)
|
- body (raw) : `{"name": "Test user", "number": 100}` (you can also test `{notjson}`)
|
||||||
|
|
||||||
### python client
|
### python client
|
||||||
|
|
||||||
- ``pip install aiohttp``
|
- `pip install aiohttp`
|
||||||
- ``python client.py``
|
- `python client.py`
|
||||||
|
|
||||||
if ubuntu :
|
if ubuntu :
|
||||||
|
|
||||||
- ``pip3 install aiohttp``
|
- `pip3 install aiohttp`
|
||||||
- ``python3 client.py``
|
- `python3 client.py`
|
||||||
|
@ -17,7 +17,6 @@ $ curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "metho
|
|||||||
# {"jsonrpc":"2.0","result":"pong","error":null,"id":1}
|
# {"jsonrpc":"2.0","result":"pong","error":null,"id":1}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
**python**
|
**python**
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
@ -28,8 +28,7 @@ A middleware demonstrating how to read out the outgoing response body.
|
|||||||
|
|
||||||
### `simple::SayHi`
|
### `simple::SayHi`
|
||||||
|
|
||||||
A minimal middleware demonstrating the sequence of operations in an actix middleware.
|
A minimal middleware demonstrating the sequence of operations in an actix middleware. There is a second version of the same middleware using `wrap_fn` which shows how easily a middleware can be implemented in actix.
|
||||||
There is a second version of the same middleware using `wrap_fn` which shows how easily a middleware can be implemented in actix.
|
|
||||||
|
|
||||||
## See Also
|
## See Also
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
# actix-sse
|
# actix-sse
|
||||||
|
|
||||||
Example of server-sent events, aka `EventSource`, with actix web.
|
Example of server-sent events, aka `EventSource`, with actix web.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
@ -12,9 +13,10 @@ Open http://127.0.0.1:8080/ with a browser, then send events with another HTTP c
|
|||||||
curl 127.0.0.1:8080/broadcast/my_message
|
curl 127.0.0.1:8080/broadcast/my_message
|
||||||
```
|
```
|
||||||
|
|
||||||
*my_message* should appear in the browser with a timestamp.
|
_my_message_ should appear in the browser with a timestamp.
|
||||||
|
|
||||||
## Performance
|
## Performance
|
||||||
|
|
||||||
This implementation can serve thousands of clients on a 2021 MacBook with no problems.
|
This implementation can serve thousands of clients on a 2021 MacBook with no problems.
|
||||||
|
|
||||||
Run `node ./benchmark.js` to benchmark your own system:
|
Run `node ./benchmark.js` to benchmark your own system:
|
||||||
@ -24,7 +26,8 @@ $ node benchmark.js
|
|||||||
Connected: 1000, connection time: 201 ms, total broadcast time: 20 ms^C⏎
|
Connected: 1000, connection time: 201 ms, total broadcast time: 20 ms^C⏎
|
||||||
```
|
```
|
||||||
|
|
||||||
### Error *Too many open files*
|
### Error _Too many open files_
|
||||||
|
|
||||||
You may be limited to a maximal number of connections (open file descriptors). Setting maximum number of open file descriptors to 2048:
|
You may be limited to a maximal number of connections (open file descriptors). Setting maximum number of open file descriptors to 2048:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
Demonstrates how to shutdown the web server in a couple of ways:
|
Demonstrates how to shutdown the web server in a couple of ways:
|
||||||
|
|
||||||
1. remotely, via http request
|
1. remotely, via http request
|
||||||
- Created in response to actix/actix-web#1315
|
- Created in response to actix/actix-web#1315
|
||||||
1. sending a SIGINT signal to the server (control-c)
|
1. sending a SIGINT signal to the server (control-c)
|
||||||
- actix-server natively supports SIGINT
|
- actix-server natively supports SIGINT
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
@ -22,6 +22,6 @@ cargo run --bin shutdown-server
|
|||||||
### Available Routes
|
### Available Routes
|
||||||
|
|
||||||
- [GET /hello](http://localhost:8080/hello)
|
- [GET /hello](http://localhost:8080/hello)
|
||||||
- Regular hello world route
|
- Regular hello world route
|
||||||
- [POST /stop](http://localhost:8080/stop)
|
- [POST /stop](http://localhost:8080/stop)
|
||||||
- Calling this will shutdown the server and exit
|
- Calling this will shutdown the server and exit
|
||||||
|
@ -7,4 +7,5 @@ cd templating/yarte
|
|||||||
cargo test
|
cargo test
|
||||||
cargo run
|
cargo run
|
||||||
```
|
```
|
||||||
|
|
||||||
> open `localhost:8080`
|
> open `localhost:8080`
|
||||||
|
@ -9,9 +9,6 @@ curl --unix-socket /tmp/actix-uds.socket http://localhost/
|
|||||||
Hello world!
|
Hello world!
|
||||||
```
|
```
|
||||||
|
|
||||||
Although this will only one thread for handling incoming connections
|
Although this will only one thread for handling incoming connections according to the [documentation](https://actix.github.io/actix-web/actix_web/struct.HttpServer.html#method.bind_uds).
|
||||||
according to the [documentation](https://actix.github.io/actix-web/actix_web/struct.HttpServer.html#method.bind_uds).
|
|
||||||
|
|
||||||
And it does not delete the socket file (`/tmp/actix-uds.socket`) when stopping
|
And it does not delete the socket file (`/tmp/actix-uds.socket`) when stopping the server, so it will fail to start next time you run it unless you delete the socket file manually.
|
||||||
the server, so it will fail to start next time you run it unless you delete
|
|
||||||
the socket file manually.
|
|
||||||
|
@ -1,26 +1,25 @@
|
|||||||
# Websocket chat broker example
|
# Websocket chat broker example
|
||||||
|
|
||||||
This is a different implementation of the
|
This is a different implementation of the [websocket chat example](https://github.com/actix/examples/tree/master/websockets/chat)
|
||||||
[websocket chat example](https://github.com/actix/examples/tree/master/websockets/chat)
|
|
||||||
|
|
||||||
Differences:
|
Differences:
|
||||||
|
|
||||||
* Chat Server Actor is a System Service that runs in the same thread as the HttpServer/WS Listener.
|
- Chat Server Actor is a System Service that runs in the same thread as the HttpServer/WS Listener.
|
||||||
* The [actix-broker](https://github.com/Chris-Ricketts/actix-broker) crate is used to facilitate the sending of some messages between the Chat Session and Server Actors where the session does not require a response.
|
- The [actix-broker](https://github.com/Chris-Ricketts/actix-broker) crate is used to facilitate the sending of some messages between the Chat Session and Server Actors where the session does not require a response.
|
||||||
* The Client is not required to send Ping messages. The Chat Server Actor auto-clears dead sessions.
|
- The Client is not required to send Ping messages. The Chat Server Actor auto-clears dead sessions.
|
||||||
|
|
||||||
Possible Improvements:
|
Possible Improvements:
|
||||||
|
|
||||||
* Could the Chat Server Actor be simultaneously a System Service (accessible to the Chat Session via the System Registry) and also run in a separate thread?
|
- Could the Chat Server Actor be simultaneously a System Service (accessible to the Chat Session via the System Registry) and also run in a separate thread?
|
||||||
|
|
||||||
## Server
|
## Server
|
||||||
|
|
||||||
Chat server listens for incoming tcp connections. Server can access several types of message:
|
Chat server listens for incoming tcp connections. Server can access several types of message:
|
||||||
|
|
||||||
* `/list` - list all available rooms
|
- `/list` - list all available rooms
|
||||||
* `/join name` - join room, if room does not exist, create new one
|
- `/join name` - join room, if room does not exist, create new one
|
||||||
* `/name name` - set session name
|
- `/name name` - set session name
|
||||||
* `some message` - just string, send message to all peers in same room
|
- `some message` - just string, send message to all peers in same room
|
||||||
|
|
||||||
To start server use command: `cargo run`
|
To start server use command: `cargo run`
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
# Websocket chat example
|
# Websocket chat example
|
||||||
|
|
||||||
This is extension of the
|
This is extension of the [actix chat example](https://github.com/actix/actix/tree/master/examples/chat)
|
||||||
[actix chat example](https://github.com/actix/actix/tree/master/examples/chat)
|
|
||||||
|
|
||||||
Added features:
|
Added features:
|
||||||
|
|
||||||
|
@ -1,27 +1,25 @@
|
|||||||
# Websocket chat example
|
# Websocket chat example
|
||||||
|
|
||||||
This is extension of the
|
This is extension of the [actix chat example](https://github.com/actix/actix/tree/master/examples/chat)
|
||||||
[actix chat example](https://github.com/actix/actix/tree/master/examples/chat)
|
|
||||||
|
|
||||||
Added features:
|
Added features:
|
||||||
|
|
||||||
* Browser WebSocket client
|
- Browser WebSocket client
|
||||||
* Chat server runs in separate thread
|
- Chat server runs in separate thread
|
||||||
* Tcp listener runs in separate thread
|
- Tcp listener runs in separate thread
|
||||||
* Application state is shared with the websocket server and a resource at `/count/`
|
- Application state is shared with the websocket server and a resource at `/count/`
|
||||||
|
|
||||||
## Server
|
## Server
|
||||||
|
|
||||||
1. Chat server listens for incoming tcp connections. Server can access several types of message:
|
1. Chat server listens for incoming tcp connections. Server can access several types of message:
|
||||||
|
|
||||||
* `/list` - list all available rooms
|
- `/list` - list all available rooms
|
||||||
* `/join name` - join room, if room does not exist, create new one
|
- `/join name` - join room, if room does not exist, create new one
|
||||||
* `/name name` - set session name
|
- `/name name` - set session name
|
||||||
* `some message` - just string, send message to all peers in same room
|
- `some message` - just string, send message to all peers in same room
|
||||||
* client has to send heartbeat `Ping` messages, if server does not receive a heartbeat message for 10 seconds connection gets dropped
|
- client has to send heartbeat `Ping` messages, if server does not receive a heartbeat message for 10 seconds connection gets dropped
|
||||||
|
|
||||||
2. [http://localhost:8080/count/](http://localhost:8080/count/) is a
|
2. [http://localhost:8080/count/](http://localhost:8080/count/) is a non-websocket endpoint and will affect and display state.
|
||||||
non-websocket endpoint and will affect and display state.
|
|
||||||
|
|
||||||
To start server use command: `cargo run --bin websocket-chat-server`
|
To start server use command: `cargo run --bin websocket-chat-server`
|
||||||
|
|
||||||
|
@ -25,10 +25,10 @@ cargo run --bin websocket-client
|
|||||||
|
|
||||||
### python client
|
### python client
|
||||||
|
|
||||||
- ``pip install aiohttp``
|
- `pip install aiohttp`
|
||||||
- ``python websocket-client.py``
|
- `python websocket-client.py`
|
||||||
|
|
||||||
if ubuntu :
|
if ubuntu :
|
||||||
|
|
||||||
- ``pip3 install aiohttp``
|
- `pip3 install aiohttp`
|
||||||
- ``python3 websocket-client.py``
|
- `python3 websocket-client.py`
|
||||||
|
Loading…
Reference in New Issue
Block a user