parent
a4deffef77
commit
102d50a024
@ -0,0 +1,44 @@ |
|||||||
|
on: [push, pull_request] |
||||||
|
|
||||||
|
name: Cargo Build |
||||||
|
|
||||||
|
jobs: |
||||||
|
build: |
||||||
|
name: Build |
||||||
|
strategy: |
||||||
|
fail-fast: false |
||||||
|
matrix: |
||||||
|
config: |
||||||
|
- node: ubuntu-latest |
||||||
|
- node: windows-latest |
||||||
|
- node: macos-latest |
||||||
|
runs-on: ${{ matrix.config.node }} |
||||||
|
steps: |
||||||
|
- uses: actions/checkout@v2 |
||||||
|
- uses: actions-rs/toolchain@v1 |
||||||
|
with: |
||||||
|
profile: minimal |
||||||
|
toolchain: nightly |
||||||
|
override: true |
||||||
|
|
||||||
|
- uses: actions-rs/cargo@v1 |
||||||
|
with: |
||||||
|
command: install |
||||||
|
args: cargo-all-features |
||||||
|
- uses: actions-rs/cargo@v1 |
||||||
|
with: |
||||||
|
command: build-all-features |
||||||
|
|
||||||
|
- uses: actions-rs/cargo@v1 |
||||||
|
with: |
||||||
|
command: build-all-features |
||||||
|
|
||||||
|
- uses: actions-rs/cargo@v1 |
||||||
|
with: |
||||||
|
command: build |
||||||
|
args: --examples |
||||||
|
|
||||||
|
- uses: actions-rs/cargo@v1 |
||||||
|
with: |
||||||
|
command: build |
||||||
|
args: --benches --features __bench |
@ -0,0 +1,227 @@ |
|||||||
|
use criterion::{black_box, criterion_group, criterion_main, Criterion}; |
||||||
|
use hyper::client::connect::dns::GaiResolver; |
||||||
|
use hyper::client::HttpConnector; |
||||||
|
use hyper::header::HeaderName; |
||||||
|
use hyper::Uri; |
||||||
|
use hyper::{HeaderMap, Request, Response}; |
||||||
|
use hyper_reverse_proxy::benches as internal_benches; |
||||||
|
use hyper_reverse_proxy::ReverseProxy; |
||||||
|
use rand::distributions::Alphanumeric; |
||||||
|
use rand::prelude::*; |
||||||
|
use std::net::Ipv4Addr; |
||||||
|
use std::str::FromStr; |
||||||
|
use test_context::AsyncTestContext; |
||||||
|
use tokio::runtime::Runtime; |
||||||
|
use tokiotest_httpserver::HttpTestContext; |
||||||
|
|
||||||
|
lazy_static::lazy_static! { |
||||||
|
static ref PROXY_CLIENT: ReverseProxy<HttpConnector<GaiResolver>> = { |
||||||
|
ReverseProxy::new( |
||||||
|
hyper::Client::new(), |
||||||
|
) |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
fn create_proxied_response(b: &mut Criterion) { |
||||||
|
let headers_map = build_headers(); |
||||||
|
|
||||||
|
b.bench_function("create proxied response", |t| { |
||||||
|
t.iter(|| { |
||||||
|
let mut response = Response::builder().status(200); |
||||||
|
|
||||||
|
*response.headers_mut().unwrap() = headers_map.clone(); |
||||||
|
|
||||||
|
internal_benches::create_proxied_response(black_box(response.body(()).unwrap())); |
||||||
|
}) |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
fn generate_string() -> String { |
||||||
|
let take = rand::thread_rng().gen::<u8>().into(); |
||||||
|
rand::thread_rng() |
||||||
|
.sample_iter(&Alphanumeric) |
||||||
|
.take(take) |
||||||
|
.map(char::from) |
||||||
|
.collect() |
||||||
|
} |
||||||
|
|
||||||
|
fn build_headers() -> HeaderMap { |
||||||
|
let mut headers_map: HeaderMap = (&*internal_benches::hop_headers()) |
||||||
|
.iter() |
||||||
|
.map(|el: &'static HeaderName| (el.clone(), generate_string().parse().unwrap())) |
||||||
|
.collect(); |
||||||
|
|
||||||
|
for _i in 0..20 { |
||||||
|
'inserted: loop { |
||||||
|
if let Ok(value) = |
||||||
|
hyper::header::HeaderName::from_str(&generate_string().to_lowercase()) |
||||||
|
{ |
||||||
|
headers_map.insert(value, generate_string().parse().unwrap()); |
||||||
|
|
||||||
|
break 'inserted; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
headers_map |
||||||
|
} |
||||||
|
|
||||||
|
fn proxy_call(b: &mut Criterion) { |
||||||
|
let rt = Runtime::new().unwrap(); |
||||||
|
|
||||||
|
let uri = Uri::from_static("http://0.0.0.0:8080/me?hello=world"); |
||||||
|
|
||||||
|
let http_context: HttpTestContext = rt.block_on(async { AsyncTestContext::setup().await }); |
||||||
|
|
||||||
|
let forward_url = &format!("http://0.0.0.0:{}", http_context.port); |
||||||
|
|
||||||
|
let headers_map = build_headers(); |
||||||
|
|
||||||
|
let client_ip = std::net::IpAddr::from(Ipv4Addr::from_str("0.0.0.0").unwrap()); |
||||||
|
|
||||||
|
b.bench_function("proxy call", |c| { |
||||||
|
c.iter(|| { |
||||||
|
rt.block_on(async { |
||||||
|
let mut request = Request::builder().uri(uri.clone()); |
||||||
|
|
||||||
|
*request.headers_mut().unwrap() = headers_map.clone(); |
||||||
|
|
||||||
|
black_box(&PROXY_CLIENT) |
||||||
|
.call( |
||||||
|
black_box(client_ip), |
||||||
|
black_box(forward_url), |
||||||
|
black_box(request.body(hyper::Body::from("")).unwrap()), |
||||||
|
) |
||||||
|
.await |
||||||
|
.unwrap(); |
||||||
|
}) |
||||||
|
}) |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
fn forward_url_with_str_ending_slash(b: &mut Criterion) { |
||||||
|
let uri = Uri::from_static("https://0.0.0.0:8080/me"); |
||||||
|
let port = rand::thread_rng().gen::<u8>(); |
||||||
|
let forward_url = &format!("https://0.0.0.0:{}/", port); |
||||||
|
|
||||||
|
b.bench_function("forward url with str ending slash", |b| { |
||||||
|
b.iter(|| { |
||||||
|
let request = Request::builder().uri(uri.clone()).body(()); |
||||||
|
|
||||||
|
internal_benches::forward_uri(forward_url, &request.unwrap()); |
||||||
|
}) |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
fn forward_url_with_str_ending_slash_and_query(b: &mut Criterion) { |
||||||
|
let uri = Uri::from_static("https://0.0.0.0:8080/me?hello=world"); |
||||||
|
let port = rand::thread_rng().gen::<u8>(); |
||||||
|
let forward_url = &format!("https://0.0.0.0:{}/", port); |
||||||
|
|
||||||
|
b.bench_function("forward url with str ending slash and query", |t| { |
||||||
|
t.iter(|| { |
||||||
|
let request = Request::builder().uri(uri.clone()).body(()); |
||||||
|
|
||||||
|
internal_benches::forward_uri(forward_url, &request.unwrap()); |
||||||
|
}) |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
fn forward_url_no_ending_slash(b: &mut Criterion) { |
||||||
|
let uri = Uri::from_static("https://0.0.0.0:8080/me"); |
||||||
|
let port = rand::thread_rng().gen::<u8>(); |
||||||
|
let forward_url = &format!("https://0.0.0.0:{}", port); |
||||||
|
|
||||||
|
b.bench_function("forward url no ending slash", |t| { |
||||||
|
t.iter(|| { |
||||||
|
let request = Request::builder().uri(uri.clone()).body(()); |
||||||
|
|
||||||
|
internal_benches::forward_uri(forward_url, &request.unwrap()); |
||||||
|
}) |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
fn forward_url_with_query(b: &mut Criterion) { |
||||||
|
let uri = Uri::from_static("https://0.0.0.0:8080/me?hello=world"); |
||||||
|
let port = rand::thread_rng().gen::<u8>(); |
||||||
|
let forward_url = &format!("https://0.0.0.0:{}", port); |
||||||
|
|
||||||
|
b.bench_function("forward_url_with_query", |t| { |
||||||
|
t.iter(|| { |
||||||
|
let request = Request::builder().uri(uri.clone()).body(()); |
||||||
|
|
||||||
|
internal_benches::forward_uri(forward_url, &request.unwrap()); |
||||||
|
}) |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
fn create_proxied_request_forwarded_for_occupied(b: &mut Criterion) { |
||||||
|
let uri = Uri::from_static("https://0.0.0.0:8080/me?hello=world"); |
||||||
|
let port = rand::thread_rng().gen::<u8>(); |
||||||
|
let forward_url = &format!("https://0.0.0.0:{}", port); |
||||||
|
|
||||||
|
let mut headers_map = build_headers(); |
||||||
|
|
||||||
|
headers_map.insert( |
||||||
|
HeaderName::from_static("x-forwarded-for"), |
||||||
|
"0.0.0.0".parse().unwrap(), |
||||||
|
); |
||||||
|
|
||||||
|
let client_ip = std::net::IpAddr::from(Ipv4Addr::from_str("0.0.0.0").unwrap()); |
||||||
|
|
||||||
|
b.bench_function("create proxied request forwarded for occupied", |t| { |
||||||
|
t.iter(|| { |
||||||
|
let mut request = Request::builder().uri(uri.clone()); |
||||||
|
|
||||||
|
*request.headers_mut().unwrap() = headers_map.clone(); |
||||||
|
|
||||||
|
internal_benches::create_proxied_request( |
||||||
|
client_ip, |
||||||
|
forward_url, |
||||||
|
request.body(()).unwrap(), |
||||||
|
None, |
||||||
|
); |
||||||
|
}) |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
fn create_proxied_request_forwarded_for_vacant(b: &mut Criterion) { |
||||||
|
let uri = Uri::from_static("https://0.0.0.0:8080/me?hello=world"); |
||||||
|
let port = rand::thread_rng().gen::<u8>(); |
||||||
|
let forward_url = &format!("https://0.0.0.0:{}", port); |
||||||
|
|
||||||
|
let headers_map = build_headers(); |
||||||
|
|
||||||
|
let client_ip = std::net::IpAddr::from(Ipv4Addr::from_str("0.0.0.0").unwrap()); |
||||||
|
|
||||||
|
b.bench_function("create proxied request forwarded for vacant", |t| { |
||||||
|
t.iter(|| { |
||||||
|
let mut request = Request::builder().uri(uri.clone()); |
||||||
|
|
||||||
|
*request.headers_mut().unwrap() = headers_map.clone(); |
||||||
|
|
||||||
|
internal_benches::create_proxied_request( |
||||||
|
client_ip, |
||||||
|
forward_url, |
||||||
|
request.body(()).unwrap(), |
||||||
|
None, |
||||||
|
); |
||||||
|
}) |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
criterion_group!(external_api, proxy_call); |
||||||
|
criterion_group!(responses, create_proxied_response); |
||||||
|
criterion_group!( |
||||||
|
url_parsing, |
||||||
|
forward_url_with_query, |
||||||
|
forward_url_no_ending_slash, |
||||||
|
forward_url_with_str_ending_slash_and_query, |
||||||
|
forward_url_with_str_ending_slash |
||||||
|
); |
||||||
|
criterion_group!( |
||||||
|
requests, |
||||||
|
create_proxied_request_forwarded_for_vacant, |
||||||
|
create_proxied_request_forwarded_for_occupied |
||||||
|
); |
||||||
|
criterion_main!(external_api, responses, url_parsing, requests); |
Loading…
Reference in new issue