diff options
Diffstat (limited to 'pingora-core/tests')
-rw-r--r-- | pingora-core/tests/keys/key.pem | 5 | ||||
-rw-r--r-- | pingora-core/tests/keys/public.pem | 4 | ||||
-rw-r--r-- | pingora-core/tests/keys/server.crt | 13 | ||||
-rw-r--r-- | pingora-core/tests/keys/server.csr | 9 | ||||
-rw-r--r-- | pingora-core/tests/nginx.conf | 92 | ||||
-rw-r--r-- | pingora-core/tests/nginx_proxy.conf | 86 | ||||
-rw-r--r-- | pingora-core/tests/pingora_conf.yaml | 5 | ||||
-rw-r--r-- | pingora-core/tests/test_basic.rs | 60 | ||||
-rw-r--r-- | pingora-core/tests/utils/mod.rs | 123 |
9 files changed, 397 insertions, 0 deletions
diff --git a/pingora-core/tests/keys/key.pem b/pingora-core/tests/keys/key.pem new file mode 100644 index 0000000..0fe68f2 --- /dev/null +++ b/pingora-core/tests/keys/key.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIN5lAOvtlKwtc/LR8/U77dohJmZS30OuezU9gL6vmm6DoAoGCCqGSM49 +AwEHoUQDQgAE2f/1Fm1HjySdokPq2T0F1xxol9nSEYQ+foFINeaWYk+FxMGpriJT +Bb8AGka87cWklw1ZqytfaT6pkureDbTkwg== +-----END EC PRIVATE KEY----- diff --git a/pingora-core/tests/keys/public.pem b/pingora-core/tests/keys/public.pem new file mode 100644 index 0000000..0866a04 --- /dev/null +++ b/pingora-core/tests/keys/public.pem @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2f/1Fm1HjySdokPq2T0F1xxol9nS +EYQ+foFINeaWYk+FxMGpriJTBb8AGka87cWklw1ZqytfaT6pkureDbTkwg== +-----END PUBLIC KEY----- diff --git a/pingora-core/tests/keys/server.crt b/pingora-core/tests/keys/server.crt new file mode 100644 index 0000000..afb2d1e --- /dev/null +++ b/pingora-core/tests/keys/server.crt @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB9zCCAZ2gAwIBAgIUMI7aLvTxyRFCHhw57hGt4U6yupcwCgYIKoZIzj0EAwIw +ZDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1TYW4gRnJhbmNp +c2NvMRgwFgYDVQQKDA9DbG91ZGZsYXJlLCBJbmMxFjAUBgNVBAMMDW9wZW5ydXN0 +eS5vcmcwHhcNMjIwNDExMjExMzEzWhcNMzIwNDA4MjExMzEzWjBkMQswCQYDVQQG +EwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xGDAWBgNV +BAoMD0Nsb3VkZmxhcmUsIEluYzEWMBQGA1UEAwwNb3BlbnJ1c3R5Lm9yZzBZMBMG +ByqGSM49AgEGCCqGSM49AwEHA0IABNn/9RZtR48knaJD6tk9BdccaJfZ0hGEPn6B +SDXmlmJPhcTBqa4iUwW/ABpGvO3FpJcNWasrX2k+qZLq3g205MKjLTArMCkGA1Ud +EQQiMCCCDyoub3BlbnJ1c3R5Lm9yZ4INb3BlbnJ1c3R5Lm9yZzAKBggqhkjOPQQD +AgNIADBFAiAjISZ9aEKmobKGlT76idO740J6jPaX/hOrm41MLeg69AIhAJqKrSyz +wD/AAF5fR6tXmBqlnpQOmtxfdy13wDr4MT3h +-----END CERTIFICATE----- diff --git a/pingora-core/tests/keys/server.csr b/pingora-core/tests/keys/server.csr new file mode 100644 index 0000000..ca75dce --- /dev/null +++ b/pingora-core/tests/keys/server.csr @@ -0,0 +1,9 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBJzCBzgIBADBsMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEW +MBQGA1UEBwwNU2FuIEZyYW5jaXNjbzEYMBYGA1UECgwPQ2xvdWRmbGFyZSwgSW5j +MRYwFAYDVQQDDA1vcGVucnVzdHkub3JnMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD +QgAE2f/1Fm1HjySdokPq2T0F1xxol9nSEYQ+foFINeaWYk+FxMGpriJTBb8AGka8 +7cWklw1ZqytfaT6pkureDbTkwqAAMAoGCCqGSM49BAMCA0gAMEUCIFyDN8eamnoY +XydKn2oI7qImigxahyCftzjxkIEV5IKbAiEAo5l72X4U+YTVYmyPPnJIj2v5nA1R +RuUfMh5sXzwlwuM= +-----END CERTIFICATE REQUEST----- diff --git a/pingora-core/tests/nginx.conf b/pingora-core/tests/nginx.conf new file mode 100644 index 0000000..55f2e24 --- /dev/null +++ b/pingora-core/tests/nginx.conf @@ -0,0 +1,92 @@ + +#user nobody; +worker_processes 1; + +error_log /dev/stdout; +#error_log logs/error.log notice; +#error_log logs/error.log info; + +pid logs/nginx.pid; +master_process off; +daemon off; + +events { + worker_connections 4096; +} + + +http { + #include mime.types; + #default_type application/octet-stream; + + #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + # '$status $body_bytes_sent "$http_referer" ' + # '"$http_user_agent" "$http_x_forwarded_for"'; + + # access_log logs/access.log main; + access_log off; + + sendfile on; + #tcp_nopush on; + + #keepalive_timeout 0; + keepalive_timeout 10; + keepalive_requests 99999; + + #gzip on; + + server { + listen 8000; + listen [::]:8000; + listen 8443 ssl http2; + #listen 8443 ssl http2; + server_name localhost; + + ssl_certificate keys/server.crt; + ssl_certificate_key keys/key.pem; + ssl_protocols TLSv1.2; + ssl_ciphers TLS-AES-128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256; + + #charset koi8-r; + + #access_log logs/host.access.log main; + + location / { + root /home/yuchen/nfs/tmp; + index index.html index.htm; + } + location /test { + keepalive_timeout 20; + return 200; + } + location /test2 { + keepalive_timeout 0; + return 200 "hello world"; + } + location /test3 { + keepalive_timeout 0; + return 200; + #content_by_lua_block { + # ngx.print("hello world") + #} + } + + location /test4 { + keepalive_timeout 20; + rewrite_by_lua_block { + ngx.exit(200) + } + #return 201; + + } + + #error_page 404 /404.html; + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root html; + } + } +} diff --git a/pingora-core/tests/nginx_proxy.conf b/pingora-core/tests/nginx_proxy.conf new file mode 100644 index 0000000..0acbd93 --- /dev/null +++ b/pingora-core/tests/nginx_proxy.conf @@ -0,0 +1,86 @@ + +#user nobody; +worker_processes 1; + +error_log /dev/stdout; +#error_log logs/error.log notice; +#error_log logs/error.log info; + +#pid logs/nginx.pid; +master_process off; +daemon off; + +events { + worker_connections 4096; +} + + +http { + #include mime.types; + #default_type application/octet-stream; + + #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + # '$status $body_bytes_sent "$http_referer" ' + # '"$http_user_agent" "$http_x_forwarded_for"'; + + # access_log logs/access.log main; + access_log off; + + sendfile on; + #tcp_nopush on; + + keepalive_timeout 30; + keepalive_requests 99999; + + upstream plantext { + server 127.0.0.1:8000; + keepalive 128; + keepalive_requests 99999; + } + + upstream ssl { + server 127.0.0.1:8443; + keepalive 128; + keepalive_requests 99999; + } + + #gzip on; + + server { + listen 8001; + listen [::]:8001; + server_name localproxy; + + location / { + keepalive_timeout 30; + proxy_pass http://plantext; + proxy_http_version 1.1; + proxy_set_header Connection "Keep-Alive"; + } + + } + + server { + listen 8002 ssl; + listen [::]:8002 ssl; + server_name localproxy_https; + + ssl_certificate keys/server.crt; + ssl_certificate_key keys/key.pem; + ssl_protocols TLSv1.2; + ssl_ciphers TLS-AES-128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256; + + location / { + keepalive_timeout 30; + proxy_pass https://ssl; + proxy_http_version 1.1; + proxy_ssl_session_reuse off; + proxy_ssl_verify on; + proxy_ssl_server_name on; + proxy_ssl_name "openrusty.org"; + proxy_ssl_trusted_certificate keys/server.crt; + proxy_set_header Connection "Keep-Alive"; + } + + } +} diff --git a/pingora-core/tests/pingora_conf.yaml b/pingora-core/tests/pingora_conf.yaml new file mode 100644 index 0000000..c21ae15 --- /dev/null +++ b/pingora-core/tests/pingora_conf.yaml @@ -0,0 +1,5 @@ +--- +version: 1 +client_bind_to_ipv4: + - 127.0.0.2 +ca_file: tests/keys/server.crt
\ No newline at end of file diff --git a/pingora-core/tests/test_basic.rs b/pingora-core/tests/test_basic.rs new file mode 100644 index 0000000..171f757 --- /dev/null +++ b/pingora-core/tests/test_basic.rs @@ -0,0 +1,60 @@ +// Copyright 2024 Cloudflare, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +mod utils; + +use hyper::Client; +use hyperlocal::{UnixClientExt, Uri}; +use utils::init; + +#[tokio::test] +async fn test_http() { + init(); + let res = reqwest::get("http://127.0.0.1:6145").await.unwrap(); + assert_eq!(res.status(), reqwest::StatusCode::OK); +} + +#[tokio::test] +async fn test_https_http2() { + init(); + + let client = reqwest::Client::builder() + .danger_accept_invalid_certs(true) + .build() + .unwrap(); + + let res = client.get("https://127.0.0.1:6146").send().await.unwrap(); + assert_eq!(res.status(), reqwest::StatusCode::OK); + assert_eq!(res.version(), reqwest::Version::HTTP_2); + + let client = reqwest::Client::builder() + .danger_accept_invalid_certs(true) + .http1_only() + .build() + .unwrap(); + + let res = client.get("https://127.0.0.1:6146").send().await.unwrap(); + assert_eq!(res.status(), reqwest::StatusCode::OK); + assert_eq!(res.version(), reqwest::Version::HTTP_11); +} + +#[tokio::test] +async fn test_uds() { + init(); + let url = Uri::new("/tmp/echo.sock", "/").into(); + let client = Client::unix(); + + let res = client.get(url).await.unwrap(); + assert_eq!(res.status(), reqwest::StatusCode::OK); +} diff --git a/pingora-core/tests/utils/mod.rs b/pingora-core/tests/utils/mod.rs new file mode 100644 index 0000000..1555b7d --- /dev/null +++ b/pingora-core/tests/utils/mod.rs @@ -0,0 +1,123 @@ +// Copyright 2024 Cloudflare, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use once_cell::sync::Lazy; +use std::{thread, time}; + +use pingora_core::listeners::Listeners; +use pingora_core::server::configuration::Opt; +use pingora_core::server::Server; +use pingora_core::services::listening::Service; +use structopt::StructOpt; + +use async_trait::async_trait; +use bytes::Bytes; +use http::{Response, StatusCode}; +use pingora_timeout::timeout; +use std::sync::Arc; +use std::time::Duration; + +use pingora_core::apps::http_app::ServeHttp; +use pingora_core::protocols::http::ServerSession; + +#[derive(Clone)] +pub struct EchoApp; + +#[async_trait] +impl ServeHttp for EchoApp { + async fn response(&self, http_stream: &mut ServerSession) -> Response<Vec<u8>> { + // read timeout of 2s + let read_timeout = 2000; + let body = match timeout( + Duration::from_millis(read_timeout), + http_stream.read_request_body(), + ) + .await + { + Ok(res) => match res.unwrap() { + Some(bytes) => bytes, + None => Bytes::from("no body!"), + }, + Err(_) => { + panic!("Timed out after {:?}ms", read_timeout); + } + }; + + Response::builder() + .status(StatusCode::OK) + .header(http::header::CONTENT_TYPE, "text/html") + .header(http::header::CONTENT_LENGTH, body.len()) + .body(body.to_vec()) + .unwrap() + } +} + +pub fn new_http_echo_app() -> Arc<EchoApp> { + Arc::new(EchoApp {}) +} + +pub struct MyServer { + pub handle: thread::JoinHandle<()>, +} + +fn entry_point(opt: Option<Opt>) { + env_logger::init(); + + let cert_path = format!("{}/tests/keys/server.crt", env!("CARGO_MANIFEST_DIR")); + let key_path = format!("{}/tests/keys/key.pem", env!("CARGO_MANIFEST_DIR")); + + let mut my_server = Server::new(opt).unwrap(); + my_server.bootstrap(); + + let mut listeners = Listeners::tcp("0.0.0.0:6145"); + listeners.add_uds("/tmp/echo.sock", None); + + let mut tls_settings = + pingora_core::listeners::TlsSettings::intermediate(&cert_path, &key_path).unwrap(); + tls_settings.enable_h2(); + listeners.add_tls_with_settings("0.0.0.0:6146", None, tls_settings); + + let echo_service_http = Service::with_listeners( + "Echo Service HTTP".to_string(), + listeners, + new_http_echo_app(), + ); + + my_server.add_service(echo_service_http); + my_server.run_forever(); +} + +impl MyServer { + pub fn start() -> Self { + let opts: Vec<String> = vec![ + "pingora".into(), + "-c".into(), + "tests/pingora_conf.yaml".into(), + ]; + let server_handle = thread::spawn(|| { + entry_point(Some(Opt::from_iter(opts))); + }); + // wait until the server is up + thread::sleep(time::Duration::from_secs(2)); + MyServer { + handle: server_handle, + } + } +} + +pub static TEST_SERVER: Lazy<MyServer> = Lazy::new(MyServer::start); + +pub fn init() { + let _ = *TEST_SERVER; +} |