mirror of
https://github.com/actix/examples
synced 2024-11-27 16:02:57 +01:00
improve awc_http example
This commit is contained in:
parent
3cd842fbd5
commit
9aef457a78
49
Cargo.lock
generated
49
Cargo.lock
generated
@ -564,6 +564,7 @@ dependencies = [
|
|||||||
"actix-service 2.0.2",
|
"actix-service 2.0.2",
|
||||||
"actix-utils 3.0.0",
|
"actix-utils 3.0.0",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
"http",
|
||||||
"log",
|
"log",
|
||||||
"openssl",
|
"openssl",
|
||||||
"pin-project-lite 0.2.8",
|
"pin-project-lite 0.2.8",
|
||||||
@ -638,7 +639,7 @@ dependencies = [
|
|||||||
"actix-tls 2.0.0",
|
"actix-tls 2.0.0",
|
||||||
"actix-utils 2.0.0",
|
"actix-utils 2.0.0",
|
||||||
"actix-web-codegen 0.4.0",
|
"actix-web-codegen 0.4.0",
|
||||||
"awc",
|
"awc 2.0.3",
|
||||||
"bytes 0.5.6",
|
"bytes 0.5.6",
|
||||||
"derive_more",
|
"derive_more",
|
||||||
"encoding_rs",
|
"encoding_rs",
|
||||||
@ -1227,6 +1228,41 @@ dependencies = [
|
|||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "awc"
|
||||||
|
version = "3.0.0-beta.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4a64a95bbf4905fd057ea45b70fdfeeb9c7ae09f03f091642c4e66a16ebb3ad5"
|
||||||
|
dependencies = [
|
||||||
|
"actix-codec 0.4.2",
|
||||||
|
"actix-http 3.0.0-rc.1",
|
||||||
|
"actix-rt 2.6.0",
|
||||||
|
"actix-service 2.0.2",
|
||||||
|
"actix-tls 3.0.2",
|
||||||
|
"actix-utils 3.0.0",
|
||||||
|
"ahash",
|
||||||
|
"base64 0.13.0",
|
||||||
|
"bytes 1.1.0",
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
"cookie 0.16.0",
|
||||||
|
"derive_more",
|
||||||
|
"futures-core",
|
||||||
|
"futures-util",
|
||||||
|
"h2 0.3.11",
|
||||||
|
"http",
|
||||||
|
"itoa 1.0.1",
|
||||||
|
"log",
|
||||||
|
"mime",
|
||||||
|
"percent-encoding",
|
||||||
|
"pin-project-lite 0.2.8",
|
||||||
|
"rand 0.8.4",
|
||||||
|
"rustls 0.20.2",
|
||||||
|
"serde 1.0.136",
|
||||||
|
"serde_json",
|
||||||
|
"serde_urlencoded",
|
||||||
|
"tokio 1.16.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "awc_examples"
|
name = "awc_examples"
|
||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
@ -1244,8 +1280,13 @@ dependencies = [
|
|||||||
name = "awc_https"
|
name = "awc_https"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"actix-web 3.3.3",
|
"actix-web 4.0.0-rc.1",
|
||||||
"openssl",
|
"awc 3.0.0-beta.20",
|
||||||
|
"env_logger 0.9.0",
|
||||||
|
"log",
|
||||||
|
"mime",
|
||||||
|
"rustls 0.20.2",
|
||||||
|
"webpki-roots 0.22.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -6758,7 +6799,7 @@ dependencies = [
|
|||||||
"actix-files 0.3.0",
|
"actix-files 0.3.0",
|
||||||
"actix-web 3.3.3",
|
"actix-web 3.3.3",
|
||||||
"actix-web-actors",
|
"actix-web-actors",
|
||||||
"awc",
|
"awc 2.0.3",
|
||||||
"bytes 0.5.6",
|
"bytes 0.5.6",
|
||||||
"env_logger 0.8.4",
|
"env_logger 0.8.4",
|
||||||
"futures",
|
"futures",
|
||||||
|
@ -5,6 +5,11 @@ authors = ["dowwie <dkcdkg@gmail.com>"]
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-web = "4.0.0-beta.21"
|
actix-web = "4.0.0-rc.1"
|
||||||
awc = {version = "3.0.0-beta.19", features = ["openssl"]}
|
awc = { version = "3.0.0-beta.19", features = ["rustls"] }
|
||||||
openssl = "0.10.38"
|
|
||||||
|
env_logger = "0.9"
|
||||||
|
log = "0.4"
|
||||||
|
mime = "0.3"
|
||||||
|
rustls = "0.20"
|
||||||
|
webpki-roots = "0.22"
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
The goal of this example is to show you how to use the actix-web client (awc)
|
The goal of this example is to show you how to use the `awc` for secure HTTPS communication using Rustls.
|
||||||
for https related communication. As of actix-web 2.0.0, one must be very
|
|
||||||
careful about setting up https communication. **You could use the default
|
|
||||||
awc api without configuring ssl but performance will be severely diminished**.
|
|
||||||
|
|
||||||
This example downloads a 1MB image from wikipedia.
|
It uses best practices for efficient client set up and demonstrates how to increase the default payload limit.
|
||||||
|
|
||||||
To run:
|
This example downloads a 10MB image from Wikipedia when hitting a server route. `cargo run` this example and go to <http://localhost:8080/> in your browser.
|
||||||
> curl http://localhost:3000 -o image.jpg
|
|
||||||
|
@ -1,40 +1,83 @@
|
|||||||
use actix_web::{web, App, HttpRequest, HttpResponse, HttpServer};
|
use std::{sync::Arc, time::Instant};
|
||||||
use awc::{Client, Connector};
|
|
||||||
use openssl::ssl::{SslConnector, SslMethod};
|
|
||||||
|
|
||||||
async fn index(_req: HttpRequest) -> HttpResponse {
|
use actix_web::{get, middleware, web::Data, App, HttpResponse, HttpServer};
|
||||||
let builder = SslConnector::builder(SslMethod::tls()).unwrap();
|
use awc::{http::header, Client, Connector};
|
||||||
|
use rustls::{ClientConfig, OwnedTrustAnchor, RootCertStore};
|
||||||
|
|
||||||
let client = Client::builder()
|
const MAP_URL: &str =
|
||||||
.connector(Connector::new().openssl(builder.build()))
|
"https://upload.wikimedia.org/wikipedia/commons/f/ff/Pizigani_1367_Chart_10MB.jpg";
|
||||||
.finish();
|
|
||||||
|
|
||||||
let now = std::time::Instant::now();
|
#[get("/")]
|
||||||
let payload =
|
async fn fetch_image(client: Data<Client>) -> HttpResponse {
|
||||||
client
|
let start = Instant::now();
|
||||||
.get("https://upload.wikimedia.org/wikipedia/commons/b/b9/Pizigani_1367_Chart_1MB.jpg")
|
|
||||||
.send()
|
let mut res = client.get(MAP_URL).send().await.unwrap();
|
||||||
.await
|
|
||||||
.unwrap()
|
if !res.status().is_success() {
|
||||||
|
log::error!("Wikipedia did not return expected image");
|
||||||
|
return HttpResponse::InternalServerError().finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
let payload = res
|
||||||
.body()
|
.body()
|
||||||
.limit(20_000_000) // sets max allowable payload size
|
// expected image is larger than default body limit
|
||||||
|
.limit(20_000_000) // 20MB
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
println!(
|
log::info!(
|
||||||
"awc time elapsed while reading bytes into memory: {} ms",
|
"it took {}ms to download image to memory",
|
||||||
now.elapsed().as_millis()
|
start.elapsed().as_millis()
|
||||||
);
|
);
|
||||||
|
|
||||||
HttpResponse::Ok().content_type("image/jpeg").body(payload)
|
HttpResponse::Ok()
|
||||||
|
.content_type(mime::IMAGE_JPEG)
|
||||||
|
.body(payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_web::main]
|
#[actix_web::main]
|
||||||
async fn main() -> std::io::Result<()> {
|
async fn main() -> std::io::Result<()> {
|
||||||
let port = 3000;
|
env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
|
||||||
|
|
||||||
HttpServer::new(|| App::new().service(web::resource("/").to(index)))
|
let client_tls_config = Arc::new(rustls_config());
|
||||||
.bind(("0.0.0.0", port))?
|
|
||||||
.run()
|
log::info!("starting HTTP serer at http://localhost:8080");
|
||||||
.await
|
|
||||||
|
HttpServer::new(move || {
|
||||||
|
// create client _inside_ `HttpServer::new` closure to have one per worker thread
|
||||||
|
let client = Client::builder()
|
||||||
|
// Wikipedia requires a User-Agent header to make requests
|
||||||
|
.add_default_header((header::USER_AGENT, "awc-example/1.0"))
|
||||||
|
// a "connector" wraps the stream into an encrypted connection
|
||||||
|
.connector(Connector::new().rustls(Arc::clone(&client_tls_config)))
|
||||||
|
.finish();
|
||||||
|
|
||||||
|
App::new()
|
||||||
|
.wrap(middleware::Logger::default())
|
||||||
|
.app_data(Data::new(client))
|
||||||
|
.service(fetch_image)
|
||||||
|
})
|
||||||
|
.bind(("127.0.0.1", 8080))?
|
||||||
|
.workers(2)
|
||||||
|
.run()
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create simple rustls client config from root certificates.
|
||||||
|
fn rustls_config() -> ClientConfig {
|
||||||
|
let mut root_store = RootCertStore::empty();
|
||||||
|
root_store.add_server_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.0.iter().map(
|
||||||
|
|ta| {
|
||||||
|
OwnedTrustAnchor::from_subject_spki_name_constraints(
|
||||||
|
ta.subject,
|
||||||
|
ta.spki,
|
||||||
|
ta.name_constraints,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
));
|
||||||
|
|
||||||
|
rustls::ClientConfig::builder()
|
||||||
|
.with_safe_defaults()
|
||||||
|
.with_root_certificates(root_store)
|
||||||
|
.with_no_client_auth()
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user