From 8797329225018c4d0ab990166dd020338ae292dc Mon Sep 17 00:00:00 2001 From: Yuchen Wu Date: Tue, 27 Feb 2024 20:25:44 -0800 Subject: [PATCH] Release Pingora version 0.1.0 Co-authored-by: Andrew Hauck Co-authored-by: Edward Wang --- .github/CONTRIBUTING.md | 51 + .github/ISSUE_TEMPLATE/bug_report.md | 37 + .github/ISSUE_TEMPLATE/feature_request.md | 27 + .gitignore | 9 +- .rustfmt.toml | 0 Cargo.toml | 35 +- README.md | 64 +- docs/README.md | 14 + docs/assets/pingora_banner.png | Bin 0 -> 240701 bytes docs/quick_start.md | 324 ++++ docs/user_guide/conf.md | 33 + docs/user_guide/ctx.md | 116 ++ docs/user_guide/daemon.md | 7 + docs/user_guide/error_log.md | 13 + docs/user_guide/errors.md | 53 + docs/user_guide/failover.md | 67 + docs/user_guide/graceful.md | 19 + docs/user_guide/index.md | 31 + docs/user_guide/internals.md | 256 +++ docs/user_guide/modify_filter.md | 133 ++ docs/user_guide/panic.md | 10 + docs/user_guide/peer.md | 35 + docs/user_guide/phase.md | 126 ++ docs/user_guide/phase_chart.md | 30 + docs/user_guide/pooling.md | 22 + docs/user_guide/prom.md | 22 + docs/user_guide/start_stop.md | 27 + docs/user_guide/systemd.md | 14 + pingora-boringssl/Cargo.toml | 36 + pingora-boringssl/LICENSE | 202 ++ pingora-boringssl/src/boring_tokio.rs | 305 ++++ pingora-boringssl/src/ext.rs | 192 ++ pingora-boringssl/src/lib.rs | 34 + pingora-cache/Cargo.toml | 64 + pingora-cache/LICENSE | 202 ++ pingora-cache/benches/lru_memory.rs | 96 + pingora-cache/benches/lru_serde.rs | 46 + pingora-cache/benches/simple_lru_memory.rs | 78 + pingora-cache/src/cache_control.rs | 839 +++++++++ pingora-cache/src/eviction/lru.rs | 431 +++++ pingora-cache/src/eviction/mod.rs | 89 + pingora-cache/src/eviction/simple_lru.rs | 445 +++++ pingora-cache/src/filters.rs | 673 +++++++ pingora-cache/src/hashtable.rs | 112 ++ pingora-cache/src/key.rs | 302 +++ pingora-cache/src/lib.rs | 1093 +++++++++++ pingora-cache/src/lock.rs | 336 ++++ pingora-cache/src/max_file_size.rs | 75 + pingora-cache/src/memory.rs | 510 ++++++ pingora-cache/src/meta.rs | 608 ++++++ pingora-cache/src/predictor.rs | 228 +++ pingora-cache/src/put.rs | 754 ++++++++ pingora-cache/src/storage.rs | 122 ++ pingora-cache/src/trace.rs | 98 + pingora-cache/src/variance.rs | 120 ++ pingora-core/Cargo.toml | 81 + pingora-core/LICENSE | 202 ++ pingora-core/src/apps/http_app.rs | 210 +++ pingora-core/src/apps/mod.rs | 135 ++ pingora-core/src/apps/prometheus_http_app.rs | 60 + pingora-core/src/connectors/http/mod.rs | 221 +++ pingora-core/src/connectors/http/v1.rs | 119 ++ pingora-core/src/connectors/http/v2.rs | 531 ++++++ pingora-core/src/connectors/l4.rs | 313 ++++ pingora-core/src/connectors/mod.rs | 477 +++++ pingora-core/src/connectors/offload.rs | 77 + pingora-core/src/connectors/tls.rs | 309 ++++ pingora-core/src/lib.rs | 69 + pingora-core/src/listeners/l4.rs | 311 ++++ pingora-core/src/listeners/mod.rs | 248 +++ pingora-core/src/listeners/tls.rs | 152 ++ pingora-core/src/modules/http/compression.rs | 65 + pingora-core/src/modules/http/mod.rs | 277 +++ pingora-core/src/modules/mod.rs | 16 + pingora-core/src/protocols/digest.rs | 66 + .../src/protocols/http/body_buffer.rs | 61 + pingora-core/src/protocols/http/client.rs | 161 ++ .../src/protocols/http/compression/brotli.rs | 161 ++ .../src/protocols/http/compression/gzip.rs | 103 ++ .../src/protocols/http/compression/mod.rs | 612 +++++++ .../src/protocols/http/compression/zstd.rs | 91 + pingora-core/src/protocols/http/date.rs | 90 + pingora-core/src/protocols/http/error_resp.rs | 41 + pingora-core/src/protocols/http/mod.rs | 57 + pingora-core/src/protocols/http/server.rs | 333 ++++ pingora-core/src/protocols/http/v1/body.rs | 1015 ++++++++++ pingora-core/src/protocols/http/v1/client.rs | 1085 +++++++++++ pingora-core/src/protocols/http/v1/common.rs | 237 +++ pingora-core/src/protocols/http/v1/mod.rs | 20 + pingora-core/src/protocols/http/v1/server.rs | 1566 ++++++++++++++++ pingora-core/src/protocols/http/v2/client.rs | 480 +++++ pingora-core/src/protocols/http/v2/mod.rs | 18 + pingora-core/src/protocols/http/v2/server.rs | 488 +++++ pingora-core/src/protocols/l4/ext.rs | 297 +++ pingora-core/src/protocols/l4/listener.rs | 59 + pingora-core/src/protocols/l4/mod.rs | 20 + pingora-core/src/protocols/l4/socket.rs | 185 ++ pingora-core/src/protocols/l4/stream.rs | 378 ++++ pingora-core/src/protocols/mod.rs | 253 +++ pingora-core/src/protocols/raw_connect.rs | 271 +++ pingora-core/src/protocols/ssl/client.rs | 78 + pingora-core/src/protocols/ssl/digest.rs | 65 + pingora-core/src/protocols/ssl/mod.rs | 246 +++ pingora-core/src/protocols/ssl/server.rs | 193 ++ pingora-core/src/server/configuration/mod.rs | 267 +++ pingora-core/src/server/daemon.rs | 112 ++ pingora-core/src/server/mod.rs | 341 ++++ pingora-core/src/server/transfer_fd/mod.rs | 461 +++++ pingora-core/src/services/background.rs | 84 + pingora-core/src/services/listening.rs | 232 +++ pingora-core/src/services/mod.rs | 55 + pingora-core/src/upstreams/mod.rs | 17 + pingora-core/src/upstreams/peer.rs | 537 ++++++ pingora-core/src/utils/mod.rs | 232 +++ pingora-core/tests/keys/key.pem | 5 + pingora-core/tests/keys/public.pem | 4 + pingora-core/tests/keys/server.crt | 13 + pingora-core/tests/keys/server.csr | 9 + pingora-core/tests/nginx.conf | 92 + pingora-core/tests/nginx_proxy.conf | 86 + pingora-core/tests/pingora_conf.yaml | 5 + pingora-core/tests/test_basic.rs | 60 + pingora-core/tests/utils/mod.rs | 123 ++ pingora-error/Cargo.toml | 17 + pingora-error/LICENSE | 202 ++ pingora-error/src/immut_str.rs | 71 + pingora-error/src/lib.rs | 589 ++++++ pingora-header-serde/Cargo.toml | 32 + pingora-header-serde/LICENSE | 202 ++ pingora-header-serde/samples/test/1 | 15 + pingora-header-serde/samples/test/2 | 15 + pingora-header-serde/samples/test/3 | 15 + pingora-header-serde/samples/test/4 | 15 + pingora-header-serde/samples/test/5 | 15 + pingora-header-serde/samples/test/6 | 15 + pingora-header-serde/samples/test/7 | 14 + pingora-header-serde/src/dict.rs | 88 + pingora-header-serde/src/lib.rs | 203 ++ pingora-header-serde/src/thread_zstd.rs | 79 + pingora-header-serde/src/trainer.rs | 23 + pingora-http/Cargo.toml | 26 + pingora-http/LICENSE | 202 ++ pingora-http/src/case_header_name.rs | 116 ++ pingora-http/src/lib.rs | 672 +++++++ pingora-ketama/Cargo.toml | 32 + pingora-ketama/LICENSE | 202 ++ pingora-ketama/benches/memory.rs | 22 + pingora-ketama/benches/simple.rs | 45 + .../examples/health_aware_selector.rs | 94 + pingora-ketama/src/lib.rs | 447 +++++ pingora-ketama/test-data/README.md | 18 + pingora-ketama/test-data/nginx.conf | 29 + .../test-data/sample-nginx-upstream.csv | 1001 ++++++++++ pingora-ketama/test-data/trace.sh | 6 + pingora-limits/Cargo.toml | 8 +- pingora-limits/benches/benchmark.rs | 2 +- pingora-limits/src/estimator.rs | 2 +- pingora-limits/src/inflight.rs | 2 +- pingora-limits/src/lib.rs | 8 +- pingora-limits/src/rate.rs | 2 +- pingora-load-balancing/Cargo.toml | 33 + pingora-load-balancing/LICENSE | 202 ++ pingora-load-balancing/src/background.rs | 61 + pingora-load-balancing/src/discovery.rs | 107 ++ pingora-load-balancing/src/health_check.rs | 384 ++++ pingora-load-balancing/src/lib.rs | 487 +++++ .../src/selection/algorithms.rs | 61 + .../src/selection/consistent.rs | 135 ++ pingora-load-balancing/src/selection/mod.rs | 171 ++ .../src/selection/weighted.rs | 208 +++ pingora-lru/Cargo.toml | 34 + pingora-lru/LICENSE | 202 ++ pingora-lru/benches/bench_linked_list.rs | 144 ++ pingora-lru/benches/bench_lru.rs | 148 ++ pingora-lru/src/lib.rs | 661 +++++++ pingora-lru/src/linked_list.rs | 439 +++++ pingora-memory-cache/Cargo.toml | 27 + pingora-memory-cache/LICENSE | 202 ++ pingora-memory-cache/src/lib.rs | 249 +++ pingora-memory-cache/src/read_through.rs | 689 +++++++ pingora-openssl/Cargo.toml | 29 + pingora-openssl/LICENSE | 202 ++ pingora-openssl/src/ext.rs | 209 +++ pingora-openssl/src/lib.rs | 33 + pingora-pool/Cargo.toml | 29 + pingora-pool/LICENSE | 202 ++ pingora-pool/src/connection.rs | 530 ++++++ pingora-pool/src/lib.rs | 28 + pingora-pool/src/lru.rs | 177 ++ pingora-proxy/Cargo.toml | 49 + pingora-proxy/LICENSE | 202 ++ pingora-proxy/examples/ctx.rs | 99 + pingora-proxy/examples/gateway.rs | 136 ++ pingora-proxy/examples/load_balancer.rs | 96 + pingora-proxy/src/lib.rs | 628 +++++++ pingora-proxy/src/proxy_cache.rs | 1203 ++++++++++++ pingora-proxy/src/proxy_common.rs | 93 + pingora-proxy/src/proxy_h1.rs | 596 ++++++ pingora-proxy/src/proxy_h2.rs | 616 +++++++ pingora-proxy/src/proxy_purge.rs | 90 + pingora-proxy/src/proxy_trait.rs | 365 ++++ pingora-proxy/src/subrequest.rs | 134 ++ pingora-proxy/tests/headers.dict | Bin 0 -> 6202645 bytes pingora-proxy/tests/keys/key.pem | 5 + pingora-proxy/tests/keys/public.pem | 4 + pingora-proxy/tests/keys/server.crt | 13 + pingora-proxy/tests/keys/server.csr | 9 + pingora-proxy/tests/pingora_conf.yaml | 5 + pingora-proxy/tests/test_basic.rs | 736 ++++++++ pingora-proxy/tests/test_upstream.rs | 1625 +++++++++++++++++ pingora-proxy/tests/utils/cert.rs | 47 + pingora-proxy/tests/utils/conf/keys/README.md | 18 + pingora-proxy/tests/utils/conf/keys/ca1.crt | 32 + .../tests/utils/conf/keys/ca1.key.pem | 51 + pingora-proxy/tests/utils/conf/keys/ca2.crt | 32 + .../tests/utils/conf/keys/ca_chain.cert | 60 + .../tests/utils/conf/keys/ca_chain.srl | 1 + .../tests/utils/conf/keys/cert_chain.crt | 40 + .../tests/utils/conf/keys/curve_test.384.crt | 11 + .../utils/conf/keys/curve_test.384.key.pem | 6 + .../tests/utils/conf/keys/curve_test.521.crt | 13 + .../utils/conf/keys/curve_test.521.key.pem | 7 + pingora-proxy/tests/utils/conf/keys/ex1.crt | 17 + .../tests/utils/conf/keys/ex1.key.b64 | 1 + .../tests/utils/conf/keys/intermediate.crt | 27 + .../tests/utils/conf/keys/intermediate.csr | 16 + .../tests/utils/conf/keys/intermediate.key | 28 + .../tests/utils/conf/keys/intermediate.srl | 1 + pingora-proxy/tests/utils/conf/keys/key.pem | 5 + pingora-proxy/tests/utils/conf/keys/leaf.crt | 20 + pingora-proxy/tests/utils/conf/keys/leaf.csr | 17 + pingora-proxy/tests/utils/conf/keys/leaf.key | 28 + pingora-proxy/tests/utils/conf/keys/leaf2.crt | 25 + pingora-proxy/tests/utils/conf/keys/leaf2.csr | 28 + pingora-proxy/tests/utils/conf/keys/leaf2.key | 51 + .../tests/utils/conf/keys/public.pem | 4 + pingora-proxy/tests/utils/conf/keys/root.crt | 33 + pingora-proxy/tests/utils/conf/keys/root.key | 52 + pingora-proxy/tests/utils/conf/keys/root.srl | 1 + .../tests/utils/conf/keys/server.crt | 13 + .../tests/utils/conf/keys/server.csr | 9 + .../tests/utils/conf/origin/.gitignore | 6 + .../tests/utils/conf/origin/conf/keys | 1 + .../tests/utils/conf/origin/conf/nginx.conf | 432 +++++ .../tests/utils/conf/origin/html/index.html | 1 + pingora-proxy/tests/utils/mock_origin.rs | 36 + pingora-proxy/tests/utils/mod.rs | 32 + pingora-proxy/tests/utils/server_utils.rs | 399 ++++ pingora-proxy/tests/utils/websocket.rs | 58 + pingora-runtime/Cargo.toml | 30 + pingora-runtime/LICENSE | 202 ++ pingora-runtime/benches/hello.rs | 106 ++ pingora-runtime/src/lib.rs | 265 +++ pingora-timeout/Cargo.toml | 37 + pingora-timeout/LICENSE | 202 ++ pingora-timeout/benches/benchmark.rs | 169 ++ pingora-timeout/src/fast_timeout.rs | 132 ++ pingora-timeout/src/lib.rs | 175 ++ pingora-timeout/src/timer.rs | 328 ++++ pingora/Cargo.toml | 50 + pingora/LICENSE | 202 ++ pingora/examples/app/echo.rs | 98 + pingora/examples/app/mod.rs | 16 + pingora/examples/app/proxy.rs | 104 ++ pingora/examples/client.rs | 40 + pingora/examples/server.rs | 163 ++ pingora/examples/service/echo.rs | 24 + pingora/examples/service/mod.rs | 16 + pingora/examples/service/proxy.rs | 46 + pingora/src/lib.rs | 102 ++ pingora/tests/pingora_conf.yaml | 5 + tinyufo/Cargo.toml | 41 + tinyufo/LICENSE | 202 ++ tinyufo/README.md | 49 + tinyufo/benches/bench_hit_ratio.rs | 100 + tinyufo/benches/bench_memory.rs | 120 ++ tinyufo/benches/bench_perf.rs | 290 +++ tinyufo/src/estimation.rs | 188 ++ tinyufo/src/lib.rs | 632 +++++++ 279 files changed, 48111 insertions(+), 18 deletions(-) create mode 100644 .github/CONTRIBUTING.md create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .rustfmt.toml create mode 100644 docs/README.md create mode 100644 docs/assets/pingora_banner.png create mode 100644 docs/quick_start.md create mode 100644 docs/user_guide/conf.md create mode 100644 docs/user_guide/ctx.md create mode 100644 docs/user_guide/daemon.md create mode 100644 docs/user_guide/error_log.md create mode 100644 docs/user_guide/errors.md create mode 100644 docs/user_guide/failover.md create mode 100644 docs/user_guide/graceful.md create mode 100644 docs/user_guide/index.md create mode 100644 docs/user_guide/internals.md create mode 100644 docs/user_guide/modify_filter.md create mode 100644 docs/user_guide/panic.md create mode 100644 docs/user_guide/peer.md create mode 100644 docs/user_guide/phase.md create mode 100644 docs/user_guide/phase_chart.md create mode 100644 docs/user_guide/pooling.md create mode 100644 docs/user_guide/prom.md create mode 100644 docs/user_guide/start_stop.md create mode 100644 docs/user_guide/systemd.md create mode 100644 pingora-boringssl/Cargo.toml create mode 100644 pingora-boringssl/LICENSE create mode 100644 pingora-boringssl/src/boring_tokio.rs create mode 100644 pingora-boringssl/src/ext.rs create mode 100644 pingora-boringssl/src/lib.rs create mode 100644 pingora-cache/Cargo.toml create mode 100644 pingora-cache/LICENSE create mode 100644 pingora-cache/benches/lru_memory.rs create mode 100644 pingora-cache/benches/lru_serde.rs create mode 100644 pingora-cache/benches/simple_lru_memory.rs create mode 100644 pingora-cache/src/cache_control.rs create mode 100644 pingora-cache/src/eviction/lru.rs create mode 100644 pingora-cache/src/eviction/mod.rs create mode 100644 pingora-cache/src/eviction/simple_lru.rs create mode 100644 pingora-cache/src/filters.rs create mode 100644 pingora-cache/src/hashtable.rs create mode 100644 pingora-cache/src/key.rs create mode 100644 pingora-cache/src/lib.rs create mode 100644 pingora-cache/src/lock.rs create mode 100644 pingora-cache/src/max_file_size.rs create mode 100644 pingora-cache/src/memory.rs create mode 100644 pingora-cache/src/meta.rs create mode 100644 pingora-cache/src/predictor.rs create mode 100644 pingora-cache/src/put.rs create mode 100644 pingora-cache/src/storage.rs create mode 100644 pingora-cache/src/trace.rs create mode 100644 pingora-cache/src/variance.rs create mode 100644 pingora-core/Cargo.toml create mode 100644 pingora-core/LICENSE create mode 100644 pingora-core/src/apps/http_app.rs create mode 100644 pingora-core/src/apps/mod.rs create mode 100644 pingora-core/src/apps/prometheus_http_app.rs create mode 100644 pingora-core/src/connectors/http/mod.rs create mode 100644 pingora-core/src/connectors/http/v1.rs create mode 100644 pingora-core/src/connectors/http/v2.rs create mode 100644 pingora-core/src/connectors/l4.rs create mode 100644 pingora-core/src/connectors/mod.rs create mode 100644 pingora-core/src/connectors/offload.rs create mode 100644 pingora-core/src/connectors/tls.rs create mode 100644 pingora-core/src/lib.rs create mode 100644 pingora-core/src/listeners/l4.rs create mode 100644 pingora-core/src/listeners/mod.rs create mode 100644 pingora-core/src/listeners/tls.rs create mode 100644 pingora-core/src/modules/http/compression.rs create mode 100644 pingora-core/src/modules/http/mod.rs create mode 100644 pingora-core/src/modules/mod.rs create mode 100644 pingora-core/src/protocols/digest.rs create mode 100644 pingora-core/src/protocols/http/body_buffer.rs create mode 100644 pingora-core/src/protocols/http/client.rs create mode 100644 pingora-core/src/protocols/http/compression/brotli.rs create mode 100644 pingora-core/src/protocols/http/compression/gzip.rs create mode 100644 pingora-core/src/protocols/http/compression/mod.rs create mode 100644 pingora-core/src/protocols/http/compression/zstd.rs create mode 100644 pingora-core/src/protocols/http/date.rs create mode 100644 pingora-core/src/protocols/http/error_resp.rs create mode 100644 pingora-core/src/protocols/http/mod.rs create mode 100644 pingora-core/src/protocols/http/server.rs create mode 100644 pingora-core/src/protocols/http/v1/body.rs create mode 100644 pingora-core/src/protocols/http/v1/client.rs create mode 100644 pingora-core/src/protocols/http/v1/common.rs create mode 100644 pingora-core/src/protocols/http/v1/mod.rs create mode 100644 pingora-core/src/protocols/http/v1/server.rs create mode 100644 pingora-core/src/protocols/http/v2/client.rs create mode 100644 pingora-core/src/protocols/http/v2/mod.rs create mode 100644 pingora-core/src/protocols/http/v2/server.rs create mode 100644 pingora-core/src/protocols/l4/ext.rs create mode 100644 pingora-core/src/protocols/l4/listener.rs create mode 100644 pingora-core/src/protocols/l4/mod.rs create mode 100644 pingora-core/src/protocols/l4/socket.rs create mode 100644 pingora-core/src/protocols/l4/stream.rs create mode 100644 pingora-core/src/protocols/mod.rs create mode 100644 pingora-core/src/protocols/raw_connect.rs create mode 100644 pingora-core/src/protocols/ssl/client.rs create mode 100644 pingora-core/src/protocols/ssl/digest.rs create mode 100644 pingora-core/src/protocols/ssl/mod.rs create mode 100644 pingora-core/src/protocols/ssl/server.rs create mode 100644 pingora-core/src/server/configuration/mod.rs create mode 100644 pingora-core/src/server/daemon.rs create mode 100644 pingora-core/src/server/mod.rs create mode 100644 pingora-core/src/server/transfer_fd/mod.rs create mode 100644 pingora-core/src/services/background.rs create mode 100644 pingora-core/src/services/listening.rs create mode 100644 pingora-core/src/services/mod.rs create mode 100644 pingora-core/src/upstreams/mod.rs create mode 100644 pingora-core/src/upstreams/peer.rs create mode 100644 pingora-core/src/utils/mod.rs create mode 100644 pingora-core/tests/keys/key.pem create mode 100644 pingora-core/tests/keys/public.pem create mode 100644 pingora-core/tests/keys/server.crt create mode 100644 pingora-core/tests/keys/server.csr create mode 100644 pingora-core/tests/nginx.conf create mode 100644 pingora-core/tests/nginx_proxy.conf create mode 100644 pingora-core/tests/pingora_conf.yaml create mode 100644 pingora-core/tests/test_basic.rs create mode 100644 pingora-core/tests/utils/mod.rs create mode 100644 pingora-error/Cargo.toml create mode 100644 pingora-error/LICENSE create mode 100644 pingora-error/src/immut_str.rs create mode 100644 pingora-error/src/lib.rs create mode 100644 pingora-header-serde/Cargo.toml create mode 100644 pingora-header-serde/LICENSE create mode 100644 pingora-header-serde/samples/test/1 create mode 100644 pingora-header-serde/samples/test/2 create mode 100644 pingora-header-serde/samples/test/3 create mode 100644 pingora-header-serde/samples/test/4 create mode 100644 pingora-header-serde/samples/test/5 create mode 100644 pingora-header-serde/samples/test/6 create mode 100644 pingora-header-serde/samples/test/7 create mode 100644 pingora-header-serde/src/dict.rs create mode 100644 pingora-header-serde/src/lib.rs create mode 100644 pingora-header-serde/src/thread_zstd.rs create mode 100644 pingora-header-serde/src/trainer.rs create mode 100644 pingora-http/Cargo.toml create mode 100644 pingora-http/LICENSE create mode 100644 pingora-http/src/case_header_name.rs create mode 100644 pingora-http/src/lib.rs create mode 100644 pingora-ketama/Cargo.toml create mode 100644 pingora-ketama/LICENSE create mode 100644 pingora-ketama/benches/memory.rs create mode 100644 pingora-ketama/benches/simple.rs create mode 100644 pingora-ketama/examples/health_aware_selector.rs create mode 100644 pingora-ketama/src/lib.rs create mode 100644 pingora-ketama/test-data/README.md create mode 100644 pingora-ketama/test-data/nginx.conf create mode 100644 pingora-ketama/test-data/sample-nginx-upstream.csv create mode 100755 pingora-ketama/test-data/trace.sh create mode 100644 pingora-load-balancing/Cargo.toml create mode 100644 pingora-load-balancing/LICENSE create mode 100644 pingora-load-balancing/src/background.rs create mode 100644 pingora-load-balancing/src/discovery.rs create mode 100644 pingora-load-balancing/src/health_check.rs create mode 100644 pingora-load-balancing/src/lib.rs create mode 100644 pingora-load-balancing/src/selection/algorithms.rs create mode 100644 pingora-load-balancing/src/selection/consistent.rs create mode 100644 pingora-load-balancing/src/selection/mod.rs create mode 100644 pingora-load-balancing/src/selection/weighted.rs create mode 100644 pingora-lru/Cargo.toml create mode 100644 pingora-lru/LICENSE create mode 100644 pingora-lru/benches/bench_linked_list.rs create mode 100644 pingora-lru/benches/bench_lru.rs create mode 100644 pingora-lru/src/lib.rs create mode 100644 pingora-lru/src/linked_list.rs create mode 100644 pingora-memory-cache/Cargo.toml create mode 100644 pingora-memory-cache/LICENSE create mode 100644 pingora-memory-cache/src/lib.rs create mode 100644 pingora-memory-cache/src/read_through.rs create mode 100644 pingora-openssl/Cargo.toml create mode 100644 pingora-openssl/LICENSE create mode 100644 pingora-openssl/src/ext.rs create mode 100644 pingora-openssl/src/lib.rs create mode 100644 pingora-pool/Cargo.toml create mode 100644 pingora-pool/LICENSE create mode 100644 pingora-pool/src/connection.rs create mode 100644 pingora-pool/src/lib.rs create mode 100644 pingora-pool/src/lru.rs create mode 100644 pingora-proxy/Cargo.toml create mode 100644 pingora-proxy/LICENSE create mode 100644 pingora-proxy/examples/ctx.rs create mode 100644 pingora-proxy/examples/gateway.rs create mode 100644 pingora-proxy/examples/load_balancer.rs create mode 100644 pingora-proxy/src/lib.rs create mode 100644 pingora-proxy/src/proxy_cache.rs create mode 100644 pingora-proxy/src/proxy_common.rs create mode 100644 pingora-proxy/src/proxy_h1.rs create mode 100644 pingora-proxy/src/proxy_h2.rs create mode 100644 pingora-proxy/src/proxy_purge.rs create mode 100644 pingora-proxy/src/proxy_trait.rs create mode 100644 pingora-proxy/src/subrequest.rs create mode 100644 pingora-proxy/tests/headers.dict create mode 100644 pingora-proxy/tests/keys/key.pem create mode 100644 pingora-proxy/tests/keys/public.pem create mode 100644 pingora-proxy/tests/keys/server.crt create mode 100644 pingora-proxy/tests/keys/server.csr create mode 100644 pingora-proxy/tests/pingora_conf.yaml create mode 100644 pingora-proxy/tests/test_basic.rs create mode 100644 pingora-proxy/tests/test_upstream.rs create mode 100644 pingora-proxy/tests/utils/cert.rs create mode 100644 pingora-proxy/tests/utils/conf/keys/README.md create mode 100644 pingora-proxy/tests/utils/conf/keys/ca1.crt create mode 100644 pingora-proxy/tests/utils/conf/keys/ca1.key.pem create mode 100644 pingora-proxy/tests/utils/conf/keys/ca2.crt create mode 100644 pingora-proxy/tests/utils/conf/keys/ca_chain.cert create mode 100644 pingora-proxy/tests/utils/conf/keys/ca_chain.srl create mode 100644 pingora-proxy/tests/utils/conf/keys/cert_chain.crt create mode 100644 pingora-proxy/tests/utils/conf/keys/curve_test.384.crt create mode 100644 pingora-proxy/tests/utils/conf/keys/curve_test.384.key.pem create mode 100644 pingora-proxy/tests/utils/conf/keys/curve_test.521.crt create mode 100644 pingora-proxy/tests/utils/conf/keys/curve_test.521.key.pem create mode 100644 pingora-proxy/tests/utils/conf/keys/ex1.crt create mode 100644 pingora-proxy/tests/utils/conf/keys/ex1.key.b64 create mode 100644 pingora-proxy/tests/utils/conf/keys/intermediate.crt create mode 100644 pingora-proxy/tests/utils/conf/keys/intermediate.csr create mode 100644 pingora-proxy/tests/utils/conf/keys/intermediate.key create mode 100644 pingora-proxy/tests/utils/conf/keys/intermediate.srl create mode 100644 pingora-proxy/tests/utils/conf/keys/key.pem create mode 100644 pingora-proxy/tests/utils/conf/keys/leaf.crt create mode 100644 pingora-proxy/tests/utils/conf/keys/leaf.csr create mode 100644 pingora-proxy/tests/utils/conf/keys/leaf.key create mode 100644 pingora-proxy/tests/utils/conf/keys/leaf2.crt create mode 100644 pingora-proxy/tests/utils/conf/keys/leaf2.csr create mode 100644 pingora-proxy/tests/utils/conf/keys/leaf2.key create mode 100644 pingora-proxy/tests/utils/conf/keys/public.pem create mode 100644 pingora-proxy/tests/utils/conf/keys/root.crt create mode 100644 pingora-proxy/tests/utils/conf/keys/root.key create mode 100644 pingora-proxy/tests/utils/conf/keys/root.srl create mode 100644 pingora-proxy/tests/utils/conf/keys/server.crt create mode 100644 pingora-proxy/tests/utils/conf/keys/server.csr create mode 100644 pingora-proxy/tests/utils/conf/origin/.gitignore create mode 120000 pingora-proxy/tests/utils/conf/origin/conf/keys create mode 100644 pingora-proxy/tests/utils/conf/origin/conf/nginx.conf create mode 100644 pingora-proxy/tests/utils/conf/origin/html/index.html create mode 100644 pingora-proxy/tests/utils/mock_origin.rs create mode 100644 pingora-proxy/tests/utils/mod.rs create mode 100644 pingora-proxy/tests/utils/server_utils.rs create mode 100644 pingora-proxy/tests/utils/websocket.rs create mode 100644 pingora-runtime/Cargo.toml create mode 100644 pingora-runtime/LICENSE create mode 100644 pingora-runtime/benches/hello.rs create mode 100644 pingora-runtime/src/lib.rs create mode 100644 pingora-timeout/Cargo.toml create mode 100644 pingora-timeout/LICENSE create mode 100644 pingora-timeout/benches/benchmark.rs create mode 100644 pingora-timeout/src/fast_timeout.rs create mode 100644 pingora-timeout/src/lib.rs create mode 100644 pingora-timeout/src/timer.rs create mode 100644 pingora/Cargo.toml create mode 100644 pingora/LICENSE create mode 100644 pingora/examples/app/echo.rs create mode 100644 pingora/examples/app/mod.rs create mode 100644 pingora/examples/app/proxy.rs create mode 100644 pingora/examples/client.rs create mode 100644 pingora/examples/server.rs create mode 100644 pingora/examples/service/echo.rs create mode 100644 pingora/examples/service/mod.rs create mode 100644 pingora/examples/service/proxy.rs create mode 100644 pingora/src/lib.rs create mode 100644 pingora/tests/pingora_conf.yaml create mode 100644 tinyufo/Cargo.toml create mode 100644 tinyufo/LICENSE create mode 100644 tinyufo/README.md create mode 100644 tinyufo/benches/bench_hit_ratio.rs create mode 100644 tinyufo/benches/bench_memory.rs create mode 100644 tinyufo/benches/bench_perf.rs create mode 100644 tinyufo/src/estimation.rs create mode 100644 tinyufo/src/lib.rs diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 0000000..383a2be --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,51 @@ +# Contributing + +Welcome to Pingora! Before you make a contribution, be it a bug report, documentation improvement, +pull request (PR), etc., please read and follow these guidelines. + +## Start with filing an issue + +More often than not, **start by filing an issue on GitHub**. If you have a bug report or feature +request, open a GitHub issue. Non-trivial PRs will also require a GitHub issue. The issue provides +us with a space to discuss proposed changes with you and the community. + +Having a discussion via GitHub issue upfront is the best way to ensure your contribution lands in +Pingora. We don't want you to spend your time making a PR, only to find that we won't accept it on +a design basis. For example, we may find that your proposed feature works better as a third-party +module built on top of or for use with Pingora and encourage you to pursue that direction instead. + +**You do not need to file an issue for small fixes.** What counts as a "small" or trivial fix is a +judgment call, so here's a few examples to clarify: +- fixing a typo +- refactoring a bit of code +- most documentation or comment edits + +Still, _sometimes_ we may review your PR and ask you to file an issue if we expect there are larger +design decisions to be made. + +## Making a PR + +After you've filed an issue, you can make your PR referencing that issue number. Once you open your +PR, it will be labelled _needs review_. A maintainer will review your PR as soon as they can. The +reviewer may ask for changes - they will mark the PR as _changes requested_ and _work in progress_ +and will give you details about the requested changes. Feel free to ask lots of questions! The +maintainers are there to help you. + +### Caveats + +Currently, internal contributions will take priority. Today Pingora is being maintained by +Cloudflare's Content Delivery team, and internal Cloudflare proxy services are a primary user of +Pingora. We value the community's work on Pingora, but the reality is that our team has a limited +amount of resources and time. We can't promise we will review or address all PRs or issues in a +timely manner. + +## Conduct + +Pingora and Cloudflare OpenSource generally follows the [Contributor Covenant Code of Conduct]. +Violating the CoC could result in a warning or a ban to Pingora or any and all repositories in the Cloudflare organization. + +[Contributor Covenant Code of Conduct]: https://github.com/cloudflare/.github/blob/26b37ca2ba7ab3d91050ead9f2c0e30674d3b91e/CODE_OF_CONDUCT.md + +## Contact + +If you have any questions, please reach out to [opensource@cloudflare.com](mailto:opensource@cloudflare.com). diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..434a12e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,37 @@ +--- +name: Bug Report +about: Report an issue to help us improve +title: '' +labels: '' +assignees: '' +--- + +## Describe the bug + +A clear and concise description of what the bug is. + +## Pingora info + +Please include the following information about your environment: + +**Pingora version**: release number of commit hash +**Rust version**: i.e. `cargo --version` +**Operating system version**: e.g. Ubuntu 22.04, Debian 12.4 + +## Steps to reproduce + +Please provide step-by-step instructions to reproduce the issue. Include any relevant code +snippets. + +## Expected results + +What were you expecting to happen? + +## Observed results + +What actually happened? + +## Additional context + +What other information would you like to provide? e.g. screenshots, how you're working around the +issue, or other clues you think could be helpful to identify the root cause. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..cc8d785 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,27 @@ +--- +name: Feature request +about: Propose a new feature +title: '' +labels: '' +assignees: '' +--- + +## What is the problem your feature solves, or the need it fulfills? + +A clear and concise description of why this feature should be added. What is the problem? Who is +this for? + +## Describe the solution you'd like + +What do you propose to resolve the problem or fulfill the need above? How would you like it to +work? + +## Describe alternatives you've considered + +What other solutions, features, or workarounds have you considered that might also solve the issue? +What are the tradeoffs for these alternatives compared to what you're proposing? + +## Additional context + +This could include references to documentation or papers, prior art, screenshots, or benchmark +results. diff --git a/.gitignore b/.gitignore index 8fbdd57..1e0037e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ -**/target +Cargo.lock +/target **/*.rs.bk -**/Cargo.lock -**/dhat-heap.json +dhat-heap.json .vscode -.cover \ No newline at end of file +.idea +.cover diff --git a/.rustfmt.toml b/.rustfmt.toml new file mode 100644 index 0000000..e69de29 diff --git a/Cargo.toml b/Cargo.toml index d9e553f..1fb8c97 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,4 +1,37 @@ [workspace] +resolver = "2" members = [ + "pingora", + "pingora-core", + "pingora-pool", + "pingora-error", "pingora-limits", -] \ No newline at end of file + "pingora-timeout", + "pingora-header-serde", + "pingora-proxy", + "pingora-cache", + "pingora-http", + "pingora-lru", + "pingora-openssl", + "pingora-boringssl", + "pingora-runtime", + "pingora-ketama", + "pingora-load-balancing", + "pingora-memory-cache", + "tinyufo", +] + +[workspace.dependencies] +tokio = "1" +async-trait = "0.1.42" +httparse = "1" +bytes = "1.0" +http = "1.0.0" +log = "0.4" +h2 = ">=0.4.2" +once_cell = "1" +lru = "0" +ahash = ">=0.8.9" + +[profile.bench] +debug = true diff --git a/README.md b/README.md index cbfaf2e..cd80748 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,65 @@ # Pingora -[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) +![Pingora banner image](./docs/assets/pingora_banner.png) -A library for building fast, reliable and evolvable network services. +## What is Pingora +Pingora is a Rust framework to [build fast, reliable and programmable networked systems](https://blog.cloudflare.com/pingora-open-source). + +Pingora is battle tested as it has been serving more than 40 million Internet requests per second for [more than a few years](https://blog.cloudflare.com/how-we-built-pingora-the-proxy-that-connects-cloudflare-to-the-internet). + +## Feature highlights +* Async Rust: fast and reliable +* HTTP 1/2 end to end proxy +* TLS over OpenSSL or BoringSSL +* gRPC and websocket proxying +* Graceful reload +* Customizable load balancing and failover strategies +* Support for a variety of observability tools + +## Reasons to use Pingora +* **Security** is your top priority: Pingora is a more memory safe alternative for services that are written in C/C++. +* Your service is **performance-sensitive**: Pingora is fast and efficient. +* Your service requires extensive **customization**: The APIs Pingora proxy framework provides are highly programmable. + +# Getting started + +See our [quick starting guide](./docs/quick_start.md) to see how easy it is to build a load balancer. + +Our [user guide](./docs/user_guide/index.md) covers more topics such as how to configure and run Pingora servers, as well as how to build custom HTTP server and proxy logic on top of Pingora's framework. + +API docs are also available for all the crates. + +# Notable crates in this workspace +* Pingora: the "public facing" crate to build to build networked systems and proxies. +* Pingora-core: this crates defined the protocols, functionalities and basic traits. +* Pingora-proxy: the logic and APIs to build HTTP proxies. +* Pingora-error: the common error type used across Pingora crates +* Pingora-http: the HTTP header definitions and APIs +* Pingora-openssl & pingora-boringssl: SSL related extensions and APIs +* Pingora-ketama: the [Ketama](https://github.com/RJ/ketama) consistent algorithm +* Pingora-limits: efficient counting algorithms +* Pingora-load-balancing: load balancing algorithm extensions for pingora proxy +* Pingora-memory-cache: Async in-memory caching with cache lock to prevent cache stampede. +* Pingora-timeout: A more efficient async timer system. +* TinyUfo: The caching algorithm behind pingora-memory-cache. + +# System requirements + +## Systems +Linux is our tier 1 environment and main focus. + +We will try our best for most code to compile for Unix environments. This is for developers and users to have an easier time developing with Pingora in Unix-like environments like macOS (though some features might be missing) + +Both x86_64 and aarch64 architectures will be supported. + +## Rust version + +Pingora keeps a rolling MSRV (minimum supported Rust version) policy of 6 months. This means we will accept PRs that upgrade the MSRV as long as the new Rust version used is at least 6 months old. + +Our current MSRV is 1.72. + +# Contributing +Please see our [contribution guidelines](./.github/CONTRIBUTING.md). + +# License +This project is Licensed under [Apache License, Version 2.0](./LICENSE). diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..06e1394 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,14 @@ +# Pingora User Manual + +## Quick Start +In this section we show you how to build a barebones load balancer. + +[Read the quick start here.](quick_start.md) + +## User Guide +Covers how to configure and run Pingora servers, as well as how to build custom HTTP server and proxy logic on top of Pingora's framework. + +[Read the user guide here.](user_guide/index.md) + +## API Reference +TBD diff --git a/docs/assets/pingora_banner.png b/docs/assets/pingora_banner.png new file mode 100644 index 0000000000000000000000000000000000000000..43c6932ea8ba53762e5cc141a3100022bbd3d65e GIT binary patch literal 240701 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

(peer: &P, bind_to: Option) -> Result +where + P: Peer + Send + Sync, +{ + if peer.get_proxy().is_some() { + return proxy_connect(peer) + .await + .err_context(|| format!("Fail to establish CONNECT proxy: {}", peer)); + } + let mut stream: Stream = match peer.address() { + SocketAddr::Inet(addr) => { + let connect_future = tcp_connect(addr, bind_to.as_ref()); + let conn_res = match peer.connection_timeout() { + Some(t) => pingora_timeout::timeout(t, connect_future) + .await + .explain_err(ConnectTimedout, |_| { + format!("timeout {t:?} connecting to server {peer}") + })?, + None => connect_future.await, + }; + match conn_res { + Ok(socket) => { + debug!("connected to new server: {}", peer.address()); + if let Some(ka) = peer.tcp_keepalive() { + debug!("Setting tcp keepalive"); + set_tcp_keepalive(&socket, ka)?; + } + Ok(socket.into()) + } + Err(e) => { + let c = format!("Fail to connect to {peer}"); + match e.etype() { + SocketError | BindError => Error::e_because(InternalError, c, e), + _ => Err(e.more_context(c)), + } + } + } + } + SocketAddr::Unix(addr) => { + let connect_future = connect_uds( + addr.as_pathname() + .expect("non-pathname unix sockets not supported as peer"), + ); + let conn_res = match peer.connection_timeout() { + Some(t) => pingora_timeout::timeout(t, connect_future) + .await + .explain_err(ConnectTimedout, |_| { + format!("timeout {t:?} connecting to server {peer}") + })?, + None => connect_future.await, + }; + match conn_res { + Ok(socket) => { + debug!("connected to new server: {}", peer.address()); + // no SO_KEEPALIVE for UDS + Ok(socket.into()) + } + Err(e) => { + let c = format!("Fail to connect to {peer}"); + match e.etype() { + SocketError | BindError => Error::e_because(InternalError, c, e), + _ => Err(e.more_context(c)), + } + } + } + } + }?; + let tracer = peer.get_tracer(); + if let Some(t) = tracer { + t.0.on_connected(); + stream.tracer = Some(t); + } + + stream.set_nodelay()?; + Ok(stream) +} + +pub(crate) fn bind_to_random( + peer: &P, + v4_list: &[InetSocketAddr], + v6_list: &[InetSocketAddr], +) -> Option { + let selected = peer.get_peer_options().and_then(|o| o.bind_to); + if selected.is_some() { + return selected; + } + + fn bind_to_ips(ips: &[InetSocketAddr]) -> Option { + match ips.len() { + 0 => None, + 1 => Some(ips[0]), + _ => { + // pick a random bind ip + ips.choose(&mut rand::thread_rng()).copied() + } + } + } + + match peer.address() { + SocketAddr::Inet(sockaddr) => match sockaddr { + InetSocketAddr::V4(_) => bind_to_ips(v4_list), + InetSocketAddr::V6(_) => bind_to_ips(v6_list), + }, + SocketAddr::Unix(_) => None, + } +} + +use crate::protocols::raw_connect; + +async fn proxy_connect(peer: &P) -> Result { + // safe to unwrap + let proxy = peer.get_proxy().unwrap(); + let options = peer.get_peer_options().unwrap(); + + // combine required and optional headers + let mut headers = proxy + .headers + .iter() + .chain(options.extra_proxy_headers.iter()); + + // not likely to timeout during connect() to UDS + let stream: Box = Box::new( + connect_uds(&proxy.next_hop) + .await + .or_err_with(ConnectError, || { + format!("CONNECT proxy connect() error to {:?}", &proxy.next_hop) + })? + .into(), + ); + + let req_header = raw_connect::generate_connect_header(&proxy.host, proxy.port, &mut headers)?; + let fut = raw_connect::connect(stream, &req_header); + let (mut stream, digest) = match peer.connection_timeout() { + Some(t) => pingora_timeout::timeout(t, fut) + .await + .explain_err(ConnectTimedout, |_| "establishing CONNECT proxy")?, + None => fut.await, + } + .map_err(|mut e| { + // http protocol may ask to retry if reused client + e.retry.decide_reuse(false); + e + })?; + debug!("CONNECT proxy established: {:?}", proxy); + stream.set_proxy_digest(digest); + let stream = stream.into_any().downcast::().unwrap(); // safe, it is Stream from above + Ok(*stream) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::upstreams::peer::{BasicPeer, HttpPeer, Proxy}; + use std::collections::BTreeMap; + use std::path::PathBuf; + use tokio::io::AsyncWriteExt; + use tokio::net::UnixListener; + + #[tokio::test] + async fn test_conn_error_refused() { + let peer = BasicPeer::new("127.0.0.1:79"); // hopefully port 79 is not used + let new_session = connect(&peer, None).await; + assert_eq!(new_session.unwrap_err().etype(), &ConnectRefused) + } + + // TODO broken on arm64 + #[ignore] + #[tokio::test] + async fn test_conn_error_no_route() { + let peer = BasicPeer::new("[::3]:79"); // no route + let new_session = connect(&peer, None).await; + assert_eq!(new_session.unwrap_err().etype(), &ConnectNoRoute) + } + + #[tokio::test] + async fn test_conn_error_addr_not_avail() { + let peer = HttpPeer::new("127.0.0.1:121".to_string(), false, "".to_string()); + let new_session = connect(&peer, Some("192.0.2.2:0".parse().unwrap())).await; + assert_eq!(new_session.unwrap_err().etype(), &InternalError) + } + + #[tokio::test] + async fn test_conn_error_other() { + let peer = HttpPeer::new("240.0.0.1:80".to_string(), false, "".to_string()); // non localhost + + // create an error: cannot send from src addr: localhost to dst addr: a public IP + let new_session = connect(&peer, Some("127.0.0.1:0".parse().unwrap())).await; + let error = new_session.unwrap_err(); + // XXX: some system will allow the socket to bind and connect without error, only to timeout + assert!(error.etype() == &ConnectError || error.etype() == &ConnectTimedout) + } + + #[tokio::test] + async fn test_conn_timeout() { + // 192.0.2.1 is effectively a blackhole + let mut peer = BasicPeer::new("192.0.2.1:79"); + peer.options.connection_timeout = Some(std::time::Duration::from_millis(1)); //1ms + let new_session = connect(&peer, None).await; + assert_eq!(new_session.unwrap_err().etype(), &ConnectTimedout) + } + + #[tokio::test] + async fn test_connect_proxy_fail() { + let mut peer = HttpPeer::new("1.1.1.1:80".to_string(), false, "".to_string()); + let mut path = PathBuf::new(); + path.push("/tmp/123"); + peer.proxy = Some(Proxy { + next_hop: path.into(), + host: "1.1.1.1".into(), + port: 80, + headers: BTreeMap::new(), + }); + let new_session = connect(&peer, None).await; + let e = new_session.unwrap_err(); + assert_eq!(e.etype(), &ConnectError); + assert!(!e.retry()); + } + + const MOCK_UDS_PATH: &str = "/tmp/test_unix_connect_proxy.sock"; + + // one-off mock server + async fn mock_connect_server() { + let _ = std::fs::remove_file(MOCK_UDS_PATH); + let listener = UnixListener::bind(MOCK_UDS_PATH).unwrap(); + if let Ok((mut stream, _addr)) = listener.accept().await { + stream.write_all(b"HTTP/1.1 200 OK\r\n\r\n").await.unwrap(); + // wait a bit so that the client can read + tokio::time::sleep(std::time::Duration::from_millis(100)).await; + } + let _ = std::fs::remove_file(MOCK_UDS_PATH); + } + + #[tokio::test(flavor = "multi_thread")] + async fn test_connect_proxy_work() { + tokio::spawn(async { + mock_connect_server().await; + }); + // wait for the server to start + tokio::time::sleep(std::time::Duration::from_millis(100)).await; + let mut peer = HttpPeer::new("1.1.1.1:80".to_string(), false, "".to_string()); + let mut path = PathBuf::new(); + path.push(MOCK_UDS_PATH); + peer.proxy = Some(Proxy { + next_hop: path.into(), + host: "1.1.1.1".into(), + port: 80, + headers: BTreeMap::new(), + }); + let new_session = connect(&peer, None).await; + assert!(new_session.is_ok()); + } + + const MOCK_BAD_UDS_PATH: &str = "/tmp/test_unix_bad_connect_proxy.sock"; + + // one-off mock bad proxy + // closes connection upon accepting + async fn mock_connect_bad_server() { + let _ = std::fs::remove_file(MOCK_BAD_UDS_PATH); + let listener = UnixListener::bind(MOCK_BAD_UDS_PATH).unwrap(); + if let Ok((mut stream, _addr)) = listener.accept().await { + stream.shutdown().await.unwrap(); + tokio::time::sleep(std::time::Duration::from_millis(100)).await; + } + let _ = std::fs::remove_file(MOCK_BAD_UDS_PATH); + } + + #[tokio::test(flavor = "multi_thread")] + async fn test_connect_proxy_conn_closed() { + tokio::spawn(async { + mock_connect_bad_server().await; + }); + // wait for the server to start + tokio::time::sleep(std::time::Duration::from_millis(100)).await; + let mut peer = HttpPeer::new("1.1.1.1:80".to_string(), false, "".to_string()); + let mut path = PathBuf::new(); + path.push(MOCK_BAD_UDS_PATH); + peer.proxy = Some(Proxy { + next_hop: path.into(), + host: "1.1.1.1".into(), + port: 80, + headers: BTreeMap::new(), + }); + let new_session = connect(&peer, None).await; + let err = new_session.unwrap_err(); + assert_eq!(err.etype(), &ConnectionClosed); + assert!(!err.retry()); + } +} diff --git a/pingora-core/src/connectors/mod.rs b/pingora-core/src/connectors/mod.rs new file mode 100644 index 0000000..ad9fbc4 --- /dev/null +++ b/pingora-core/src/connectors/mod.rs @@ -0,0 +1,477 @@ +// 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. + +//! Connecting to servers + +pub mod http; +mod l4; +mod offload; +mod tls; + +use crate::protocols::Stream; +use crate::server::configuration::ServerConf; +use crate::tls::ssl::SslConnector; +use crate::upstreams::peer::{Peer, ALPN}; + +use l4::connect as l4_connect; +use log::{debug, error, warn}; +use offload::OffloadRuntime; +use parking_lot::RwLock; +use pingora_error::{Error, ErrorType::*, OrErr, Result}; +use pingora_pool::{ConnectionMeta, ConnectionPool}; +use std::collections::HashMap; +use std::net::SocketAddr; +use std::sync::Arc; +use tokio::sync::Mutex; + +/// The options to configure a [TransportConnector] +#[derive(Clone)] +pub struct ConnectorOptions { + /// Path to the CA file used to validate server certs. + /// + /// If `None`, the CA in the [default](https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_default_verify_paths.html) + /// locations will be loaded + pub ca_file: Option, + /// The default client cert and key to use for mTLS + /// + /// Each individual connection can use their own cert key to override this. + pub cert_key_file: Option<(String, String)>, + /// How many connections to keepalive + pub keepalive_pool_size: usize, + /// Optionally offload the connection establishment to dedicated thread pools + /// + /// TCP and TLS connection establishment can be CPU intensive. Sometimes such tasks can slow + /// down the entire service, which causes timeouts which leads to more connections which + /// snowballs the issue. Use this option to isolate these CPU intensive tasks from impacting + /// other traffic. + /// + /// Syntax: (#pools, #thread in each pool) + pub offload_threadpool: Option<(usize, usize)>, + /// Bind to any of the given source IPv6 addresses + pub bind_to_v4: Vec, + /// Bind to any of the given source IPv4 addresses + pub bind_to_v6: Vec, +} + +impl ConnectorOptions { + /// Derive the [ConnectorOptions] from a [ServerConf] + pub fn from_server_conf(server_conf: &ServerConf) -> Self { + // if both pools and threads are Some(>0) + let offload_threadpool = server_conf + .upstream_connect_offload_threadpools + .zip(server_conf.upstream_connect_offload_thread_per_pool) + .filter(|(pools, threads)| *pools > 0 && *threads > 0); + + // create SocketAddrs with port 0 for src addr bind + + let bind_to_v4 = server_conf + .client_bind_to_ipv4 + .iter() + .map(|v4| { + let ip = v4.parse().unwrap(); + SocketAddr::new(ip, 0) + }) + .collect(); + + let bind_to_v6 = server_conf + .client_bind_to_ipv6 + .iter() + .map(|v6| { + let ip = v6.parse().unwrap(); + SocketAddr::new(ip, 0) + }) + .collect(); + ConnectorOptions { + ca_file: server_conf.ca_file.clone(), + cert_key_file: None, // TODO: use it + keepalive_pool_size: server_conf.upstream_keepalive_pool_size, + offload_threadpool, + bind_to_v4, + bind_to_v6, + } + } + + /// Create a new [ConnectorOptions] with the given keepalive pool size + pub fn new(keepalive_pool_size: usize) -> Self { + ConnectorOptions { + ca_file: None, + cert_key_file: None, + keepalive_pool_size, + offload_threadpool: None, + bind_to_v4: vec![], + bind_to_v6: vec![], + } + } +} + +/// [TransportConnector] provides APIs to connect to servers via TCP or TLS with connection reuse +pub struct TransportConnector { + tls_ctx: tls::Connector, + connection_pool: Arc>>>, + offload: Option, + bind_to_v4: Vec, + bind_to_v6: Vec, + preferred_http_version: PreferredHttpVersion, +} + +const DEFAULT_POOL_SIZE: usize = 128; + +impl TransportConnector { + /// Create a new [TransportConnector] with the given [ConnectorOptions] + pub fn new(mut options: Option) -> Self { + let pool_size = options + .as_ref() + .map_or(DEFAULT_POOL_SIZE, |c| c.keepalive_pool_size); + // Take the offloading setting there because this layer has implement offloading, + // so no need for stacks at lower layer to offload again. + let offload = options.as_mut().and_then(|o| o.offload_threadpool.take()); + let bind_to_v4 = options + .as_ref() + .map_or_else(Vec::new, |o| o.bind_to_v4.clone()); + let bind_to_v6 = options + .as_ref() + .map_or_else(Vec::new, |o| o.bind_to_v6.clone()); + TransportConnector { + tls_ctx: tls::Connector::new(options), + connection_pool: Arc::new(ConnectionPool::new(pool_size)), + offload: offload.map(|v| OffloadRuntime::new(v.0, v.1)), + bind_to_v4, + bind_to_v6, + preferred_http_version: PreferredHttpVersion::new(), + } + } + + /// Connect to the given server [Peer] + /// + /// No connection is reused. + pub async fn new_stream(&self, peer: &P) -> Result { + let rt = self + .offload + .as_ref() + .map(|o| o.get_runtime(peer.reuse_hash())); + let bind_to = l4::bind_to_random(peer, &self.bind_to_v4, &self.bind_to_v6); + let alpn_override = self.preferred_http_version.get(peer); + let stream = if let Some(rt) = rt { + let peer = peer.clone(); + let tls_ctx = self.tls_ctx.clone(); + rt.spawn(async move { do_connect(&peer, bind_to, alpn_override, &tls_ctx.ctx).await }) + .await + .or_err(InternalError, "offload runtime failure")?? + } else { + do_connect(peer, bind_to, alpn_override, &self.tls_ctx.ctx).await? + }; + + Ok(stream) + } + + /// Try to find a reusable connection to the given server [Peer] + pub async fn reused_stream(&self, peer: &P) -> Option { + match self.connection_pool.get(&peer.reuse_hash()) { + Some(s) => { + debug!("find reusable stream, trying to acquire it"); + { + let _ = s.lock().await; + } // wait for the idle poll to release it + match Arc::try_unwrap(s) { + Ok(l) => { + let mut stream = l.into_inner(); + // test_reusable_stream: we assume server would never actively send data + // first on an idle stream. + if peer.matches_fd(stream.id()) && test_reusable_stream(&mut stream) { + Some(stream) + } else { + None + } + } + Err(_) => { + error!("failed to acquire reusable stream"); + None + } + } + } + None => { + debug!("No reusable connection found for {peer}"); + None + } + } + } + + /// Return the [Stream] to the [TransportConnector] for connection reuse. + /// + /// Not all TCP/TLS connection can be reused. It is the caller's responsibility to make sure + /// that protocol over the [Stream] supports connection reuse and the [Stream] itself is ready + /// to be reused. + /// + /// If a [Stream] is dropped instead of being returned via this function. it will be closed. + pub fn release_stream( + &self, + mut stream: Stream, + key: u64, // usually peer.reuse_hash() + idle_timeout: Option, + ) { + if !test_reusable_stream(&mut stream) { + return; + } + let id = stream.id(); + let meta = ConnectionMeta::new(key, id); + debug!("Try to keepalive client session"); + let stream = Arc::new(Mutex::new(stream)); + let locked_stream = stream.clone().try_lock_owned().unwrap(); // safe as we just created it + let (notify_close, watch_use) = self.connection_pool.put(&meta, stream); + let pool = self.connection_pool.clone(); //clone the arc + let rt = pingora_runtime::current_handle(); + rt.spawn(async move { + pool.idle_poll(locked_stream, &meta, idle_timeout, notify_close, watch_use) + .await; + }); + } + + /// Get a stream to the given server [Peer] + /// + /// This function will try to find a reusable [Stream] first. If there is none, a new connection + /// will be made to the server. + /// + /// The returned boolean will indicate whether the stream is reused. + pub async fn get_stream( + &self, + peer: &P, + ) -> Result<(Stream, bool)> { + let reused_stream = self.reused_stream(peer).await; + if let Some(s) = reused_stream { + Ok((s, true)) + } else { + let s = self.new_stream(peer).await?; + Ok((s, false)) + } + } + + /// Tell the connector to always send h1 for ALPN for the given peer in the future. + pub fn prefer_h1(&self, peer: &impl Peer) { + self.preferred_http_version.add(peer, 1); + } +} + +// Perform the actual L4 and tls connection steps while respecting the peer's +// connection timeout if there one +async fn do_connect( + peer: &P, + bind_to: Option, + alpn_override: Option, + tls_ctx: &SslConnector, +) -> Result { + // Create the future that does the connections, but don't evaluate it until + // we decide if we need a timeout or not + let connect_future = do_connect_inner(peer, bind_to, alpn_override, tls_ctx); + + match peer.total_connection_timeout() { + Some(t) => match pingora_timeout::timeout(t, connect_future).await { + Ok(res) => res, + Err(_) => Error::e_explain( + ConnectTimedout, + format!("connecting to server {peer}, total-connection timeout {t:?}"), + ), + }, + None => connect_future.await, + } +} + +// Perform the actual L4 and tls connection steps with no timeout +async fn do_connect_inner( + peer: &P, + bind_to: Option, + alpn_override: Option, + tls_ctx: &SslConnector, +) -> Result { + let stream = l4_connect(peer, bind_to).await?; + if peer.tls() { + let tls_stream = tls::connect(stream, peer, alpn_override, tls_ctx).await?; + Ok(Box::new(tls_stream)) + } else { + Ok(Box::new(stream)) + } +} + +struct PreferredHttpVersion { + // TODO: shard to avoid the global lock + versions: RwLock>, // +} + +// TODO: limit the size of this + +impl PreferredHttpVersion { + pub fn new() -> Self { + PreferredHttpVersion { + versions: RwLock::default(), + } + } + + pub fn add(&self, peer: &impl Peer, version: u8) { + let key = peer.reuse_hash(); + let mut v = self.versions.write(); + v.insert(key, version); + } + + pub fn get(&self, peer: &impl Peer) -> Option { + let key = peer.reuse_hash(); + let v = self.versions.read(); + v.get(&key) + .copied() + .map(|v| if v == 1 { ALPN::H1 } else { ALPN::H2H1 }) + } +} + +use futures::future::FutureExt; +use tokio::io::AsyncReadExt; + +/// Test whether a stream is already closed or not reusable (server sent unexpected data) +fn test_reusable_stream(stream: &mut Stream) -> bool { + let mut buf = [0; 1]; + let result = stream.read(&mut buf[..]).now_or_never(); + if let Some(data_result) = result { + match data_result { + Ok(n) => { + if n == 0 { + debug!("Idle connection is closed"); + } else { + warn!("Unexpected data read in idle connection"); + } + } + Err(e) => { + debug!("Idle connection is broken: {e:?}"); + } + } + false + } else { + true + } +} + +#[cfg(test)] +mod tests { + use pingora_error::ErrorType; + use pingora_openssl::ssl::SslMethod; + + use super::*; + use crate::upstreams::peer::BasicPeer; + + // 192.0.2.1 is effectively a black hole + const BLACK_HOLE: &str = "192.0.2.1:79"; + + #[tokio::test] + async fn test_connect() { + let connector = TransportConnector::new(None); + let peer = BasicPeer::new("1.1.1.1:80"); + // make a new connection to 1.1.1.1 + let stream = connector.new_stream(&peer).await.unwrap(); + connector.release_stream(stream, peer.reuse_hash(), None); + + let (_, reused) = connector.get_stream(&peer).await.unwrap(); + assert!(reused); + } + + #[tokio::test] + async fn test_connect_tls() { + let connector = TransportConnector::new(None); + let mut peer = BasicPeer::new("1.1.1.1:443"); + // BasicPeer will use tls when SNI is set + peer.sni = "one.one.one.one".to_string(); + // make a new connection to https://1.1.1.1 + let stream = connector.new_stream(&peer).await.unwrap(); + connector.release_stream(stream, peer.reuse_hash(), None); + + let (_, reused) = connector.get_stream(&peer).await.unwrap(); + assert!(reused); + } + + async fn do_test_conn_timeout(conf: Option) { + let connector = TransportConnector::new(conf); + let mut peer = BasicPeer::new(BLACK_HOLE); + peer.options.connection_timeout = Some(std::time::Duration::from_millis(1)); + let stream = connector.new_stream(&peer).await; + match stream { + Ok(_) => panic!("should throw an error"), + Err(e) => assert_eq!(e.etype(), &ConnectTimedout), + } + } + + #[tokio::test] + async fn test_conn_timeout() { + do_test_conn_timeout(None).await; + } + + #[tokio::test] + async fn test_conn_timeout_with_offload() { + let mut conf = ConnectorOptions::new(8); + conf.offload_threadpool = Some((2, 2)); + do_test_conn_timeout(Some(conf)).await; + } + + #[tokio::test] + async fn test_connector_bind_to() { + // connect to remote while bind to localhost will fail + let peer = BasicPeer::new("240.0.0.1:80"); + let mut conf = ConnectorOptions::new(1); + conf.bind_to_v4.push("127.0.0.1:0".parse().unwrap()); + let connector = TransportConnector::new(Some(conf)); + + let stream = connector.new_stream(&peer).await; + let error = stream.unwrap_err(); + // XXX: some system will allow the socket to bind and connect without error, only to timeout + assert!(error.etype() == &ConnectError || error.etype() == &ConnectTimedout) + } + + /// Helper function for testing error handling in the `do_connect` function. + /// This assumes that the connection will fail to on the peer and returns + /// the decomposed error type and message + async fn get_do_connect_failure_with_peer(peer: &BasicPeer) -> (ErrorType, String) { + let ssl_connector = SslConnector::builder(SslMethod::tls()).unwrap().build(); + let stream = do_connect(peer, None, None, &ssl_connector).await; + match stream { + Ok(_) => panic!("should throw an error"), + Err(e) => ( + e.etype().clone(), + e.context + .as_ref() + .map(|ctx| ctx.as_str().to_owned()) + .unwrap_or_default(), + ), + } + } + + #[tokio::test] + async fn test_do_connect_with_total_timeout() { + let mut peer = BasicPeer::new(BLACK_HOLE); + peer.options.total_connection_timeout = Some(std::time::Duration::from_millis(1)); + let (etype, context) = get_do_connect_failure_with_peer(&peer).await; + assert_eq!(etype, ConnectTimedout); + assert!(context.contains("total-connection timeout")); + } + + #[tokio::test] + async fn test_tls_connect_timeout_supersedes_total() { + let mut peer = BasicPeer::new(BLACK_HOLE); + peer.options.total_connection_timeout = Some(std::time::Duration::from_millis(10)); + peer.options.connection_timeout = Some(std::time::Duration::from_millis(1)); + let (etype, context) = get_do_connect_failure_with_peer(&peer).await; + assert_eq!(etype, ConnectTimedout); + assert!(!context.contains("total-connection timeout")); + } + + #[tokio::test] + async fn test_do_connect_without_total_timeout() { + let peer = BasicPeer::new(BLACK_HOLE); + let (etype, context) = get_do_connect_failure_with_peer(&peer).await; + assert!(etype != ConnectTimedout || !context.contains("total-connection timeout")); + } +} diff --git a/pingora-core/src/connectors/offload.rs b/pingora-core/src/connectors/offload.rs new file mode 100644 index 0000000..17334b3 --- /dev/null +++ b/pingora-core/src/connectors/offload.rs @@ -0,0 +1,77 @@ +// 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 log::debug; +use once_cell::sync::OnceCell; +use rand::Rng; +use tokio::runtime::{Builder, Handle}; +use tokio::sync::oneshot::{channel, Sender}; + +// TODO: use pingora_runtime +// a shared runtime (thread pools) +pub(crate) struct OffloadRuntime { + shards: usize, + thread_per_shard: usize, + // Lazily init the runtimes so that they are created after pingora + // daemonize itself. Otherwise the runtime threads are lost. + pools: OnceCell)]>>, +} + +impl OffloadRuntime { + pub fn new(shards: usize, thread_per_shard: usize) -> Self { + assert!(shards != 0); + assert!(thread_per_shard != 0); + OffloadRuntime { + shards, + thread_per_shard, + pools: OnceCell::new(), + } + } + + fn init_pools(&self) -> Box<[(Handle, Sender<()>)]> { + let threads = self.shards * self.thread_per_shard; + let mut pools = Vec::with_capacity(threads); + for _ in 0..threads { + // We use single thread runtimes to reduce the scheduling overhead of multithread + // tokio runtime, which can be 50% of the on CPU time of the runtimes + let rt = Builder::new_current_thread().enable_all().build().unwrap(); + let handler = rt.handle().clone(); + let (tx, rx) = channel::<()>(); + std::thread::Builder::new() + .name("Offload thread".to_string()) + .spawn(move || { + debug!("Offload thread started"); + // the thread that calls block_on() will drive the runtime + // rx will return when tx is dropped so this runtime and thread will exit + rt.block_on(rx) + }) + .unwrap(); + pools.push((handler, tx)); + } + + pools.into_boxed_slice() + } + + pub fn get_runtime(&self, hash: u64) -> &Handle { + let mut rng = rand::thread_rng(); + + // choose a shard based on hash and a random thread with in that shard + // e.g. say thread_per_shard=2, shard 1 thread 1 is 1 * 2 + 1 = 3 + // [[th0, th1], [th2, th3], ...] + let shard = hash as usize % self.shards; + let thread_in_shard = rng.gen_range(0..self.thread_per_shard); + let pools = self.pools.get_or_init(|| self.init_pools()); + &pools[shard * self.thread_per_shard + thread_in_shard].0 + } +} diff --git a/pingora-core/src/connectors/tls.rs b/pingora-core/src/connectors/tls.rs new file mode 100644 index 0000000..e8eb37e --- /dev/null +++ b/pingora-core/src/connectors/tls.rs @@ -0,0 +1,309 @@ +// 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 log::debug; +use pingora_error::{Error, ErrorType::*, OrErr, Result}; +use std::sync::{Arc, Once}; + +use super::ConnectorOptions; +use crate::protocols::ssl::client::handshake; +use crate::protocols::ssl::SslStream; +use crate::protocols::IO; +use crate::tls::ext::{ + add_host, clear_error_stack, ssl_add_chain_cert, ssl_set_groups_list, + ssl_set_renegotiate_mode_freely, ssl_set_verify_cert_store, ssl_use_certificate, + ssl_use_private_key, ssl_use_second_key_share, +}; +#[cfg(feature = "boringssl")] +use crate::tls::ssl::SslCurve; +use crate::tls::ssl::{SslConnector, SslFiletype, SslMethod, SslVerifyMode, SslVersion}; +use crate::tls::x509::store::X509StoreBuilder; +use crate::upstreams::peer::{Peer, ALPN}; + +const CIPHER_LIST: &str = "AES-128-GCM-SHA256\ + :AES-256-GCM-SHA384\ + :CHACHA20-POLY1305-SHA256\ + :ECDHE-ECDSA-AES128-GCM-SHA256\ + :ECDHE-ECDSA-AES256-GCM-SHA384\ + :ECDHE-RSA-AES128-GCM-SHA256\ + :ECDHE-RSA-AES256-GCM-SHA384\ + :ECDHE-RSA-AES128-SHA\ + :ECDHE-RSA-AES256-SHA384\ + :AES128-GCM-SHA256\ + :AES256-GCM-SHA384\ + :AES128-SHA\ + :AES256-SHA\ + :DES-CBC3-SHA"; + +/** + * Enabled signature algorithms for signing/verification (ECDSA). + * As of 4/10/2023, the only addition to boringssl's defaults is ECDSA_SECP521R1_SHA512. + */ +const SIGALG_LIST: &str = "ECDSA_SECP256R1_SHA256\ + :RSA_PSS_RSAE_SHA256\ + :RSA_PKCS1_SHA256\ + :ECDSA_SECP384R1_SHA384\ + :RSA_PSS_RSAE_SHA384\ + :RSA_PKCS1_SHA384\ + :RSA_PSS_RSAE_SHA512\ + :RSA_PKCS1_SHA512\ + :RSA_PKCS1_SHA1\ + :ECDSA_SECP521R1_SHA512"; +/** + * Enabled curves for ECDHE (signature key exchange). + * As of 4/10/2023, the only addition to boringssl's defaults is SECP521R1. + * + * N.B. The ordering of these curves is important. The boringssl library will select the first one + * as a guess when negotiating a handshake with a server using TLSv1.3. We should opt for curves + * that are both computationally cheaper and more supported. + */ +#[cfg(feature = "boringssl")] +const BORINGSSL_CURVE_LIST: &[SslCurve] = &[ + SslCurve::X25519, + SslCurve::SECP256R1, + SslCurve::SECP384R1, + SslCurve::SECP521R1, +]; + +static INIT_CA_ENV: Once = Once::new(); +fn init_ssl_cert_env_vars() { + // this sets env vars to pick up the root certs + // it is universal across openssl and boringssl + INIT_CA_ENV.call_once(openssl_probe::init_ssl_cert_env_vars); +} + +#[derive(Clone)] +pub struct Connector { + pub(crate) ctx: Arc, // Arc to support clone +} + +impl Connector { + pub fn new(options: Option) -> Self { + let mut builder = SslConnector::builder(SslMethod::tls()).unwrap(); + // TODO: make these conf + // Set supported ciphers. + builder.set_cipher_list(CIPHER_LIST).unwrap(); + // Set supported signature algorithms and ECDH (key exchange) curves. + builder + .set_sigalgs_list(&SIGALG_LIST.to_lowercase()) + .unwrap(); + #[cfg(feature = "boringssl")] + builder.set_curves(BORINGSSL_CURVE_LIST).unwrap(); + builder + .set_max_proto_version(Some(SslVersion::TLS1_3)) + .unwrap(); + builder + .set_min_proto_version(Some(SslVersion::TLS1)) + .unwrap(); + if let Some(conf) = options.as_ref() { + if let Some(ca_file_path) = conf.ca_file.as_ref() { + builder.set_ca_file(ca_file_path).unwrap(); + } else { + init_ssl_cert_env_vars(); + // load from default system wide trust location. (the name is misleading) + builder.set_default_verify_paths().unwrap(); + } + if let Some((cert, key)) = conf.cert_key_file.as_ref() { + builder + .set_certificate_file(cert, SslFiletype::PEM) + .unwrap(); + + builder.set_private_key_file(key, SslFiletype::PEM).unwrap(); + } + } else { + init_ssl_cert_env_vars(); + builder.set_default_verify_paths().unwrap(); + } + + Connector { + ctx: Arc::new(builder.build()), + } + } +} + +/* + OpenSSL considers underscores in hostnames non-compliant. + We replace the underscore in the leftmost label as we must support these + hostnames for wildcard matches and we have not patched OpenSSL. + + https://github.com/openssl/openssl/issues/12566 + + > The labels must follow the rules for ARPANET host names. They must + > start with a letter, end with a letter or digit, and have as interior + > characters only letters, digits, and hyphen. There are also some + > restrictions on the length. Labels must be 63 characters or less. + - https://datatracker.ietf.org/doc/html/rfc1034#section-3.5 +*/ +fn replace_leftmost_underscore(sni: &str) -> Option { + // wildcard is only leftmost label + let mut s = sni.splitn(2, '.'); + if let (Some(leftmost), Some(rest)) = (s.next(), s.next()) { + // if not a subdomain or leftmost does not contain underscore return + if !rest.contains('.') || !leftmost.contains('_') { + return None; + } + // we have a subdomain, replace underscores + let leftmost = leftmost.replace('_', "-"); + return Some(format!("{leftmost}.{rest}")); + } + None +} + +pub(crate) async fn connect( + stream: T, + peer: &P, + alpn_override: Option, + tls_ctx: &SslConnector, +) -> Result> +where + T: IO, + P: Peer + Send + Sync, +{ + let mut ssl_conf = tls_ctx.configure().unwrap(); + + ssl_set_renegotiate_mode_freely(&mut ssl_conf); + + // Set up CA/verify cert store + // TODO: store X509Store in the peer directly + if let Some(ca_list) = peer.get_ca() { + let mut store_builder = X509StoreBuilder::new().unwrap(); + for ca in &***ca_list { + store_builder.add_cert(ca.clone()).unwrap(); + } + ssl_set_verify_cert_store(&mut ssl_conf, &store_builder.build()) + .or_err(InternalError, "failed to load cert store")?; + } + + // Set up client cert/key + if let Some(key_pair) = peer.get_client_cert_key() { + debug!("setting client cert and key"); + ssl_use_certificate(&mut ssl_conf, key_pair.leaf()) + .or_err(InternalError, "invalid client cert")?; + ssl_use_private_key(&mut ssl_conf, key_pair.key()) + .or_err(InternalError, "invalid client key")?; + + let intermediates = key_pair.intermediates(); + if !intermediates.is_empty() { + debug!("adding intermediate certificates for mTLS chain"); + for int in intermediates { + ssl_add_chain_cert(&mut ssl_conf, int) + .or_err(InternalError, "invalid intermediate client cert")?; + } + } + } + + if let Some(curve) = peer.get_peer_options().and_then(|o| o.curves) { + ssl_set_groups_list(&mut ssl_conf, curve).or_err(InternalError, "invalid curves")?; + } + + // second_keyshare is default true + if !peer.get_peer_options().map_or(true, |o| o.second_keyshare) { + ssl_use_second_key_share(&mut ssl_conf, false); + } + + // disable verification if sni does not exist + // XXX: verify on empty string cause null string seg fault + if peer.sni().is_empty() { + ssl_conf.set_use_server_name_indication(false); + /* NOTE: technically we can still verify who signs the cert but turn it off to be + consistant with nginx's behavior */ + ssl_conf.set_verify(SslVerifyMode::NONE); + } else if peer.verify_cert() { + if peer.verify_hostname() { + let verify_param = ssl_conf.param_mut(); + add_host(verify_param, peer.sni()).or_err(InternalError, "failed to add host")?; + // if sni had underscores in leftmost label replace and add + if let Some(sni_s) = replace_leftmost_underscore(peer.sni()) { + add_host(verify_param, sni_s.as_ref()).unwrap(); + } + if let Some(alt_cn) = peer.alternative_cn() { + if !alt_cn.is_empty() { + add_host(verify_param, alt_cn).unwrap(); + // if alt_cn had underscores in leftmost label replace and add + if let Some(alt_cn_s) = replace_leftmost_underscore(alt_cn) { + add_host(verify_param, alt_cn_s.as_ref()).unwrap(); + } + } + } + } + ssl_conf.set_verify(SslVerifyMode::PEER); + } else { + ssl_conf.set_verify(SslVerifyMode::NONE); + } + + /* + We always set set_verify_hostname(false) here because: + - verify case.) otherwise ssl.connect calls X509_VERIFY_PARAM_set1_host + which overrides the names added by add_host. Verify is + essentially on as long as the names are added. + - off case.) the non verify hostname case should have it disabled + */ + ssl_conf.set_verify_hostname(false); + + if let Some(alpn) = alpn_override.as_ref().or(peer.get_alpn()) { + ssl_conf.set_alpn_protos(alpn.to_wire_preference()).unwrap(); + } + + clear_error_stack(); + let connect_future = handshake(ssl_conf, peer.sni(), stream); + + match peer.connection_timeout() { + Some(t) => match pingora_timeout::timeout(t, connect_future).await { + Ok(res) => res, + Err(_) => Error::e_explain( + ConnectTimedout, + format!("connecting to server {}, timeout {:?}", peer, t), + ), + }, + None => connect_future.await, + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_replace_leftmost_underscore() { + let none_cases = [ + "", + "some", + "some.com", + "1.1.1.1:5050", + "dog.dot.com", + "dog.d_t.com", + "dog.dot.c_m", + "d_g.com", + "_", + "dog.c_m", + ]; + + for case in none_cases { + assert!(replace_leftmost_underscore(case).is_none(), "{}", case); + } + + assert_eq!( + Some("bb-b.some.com".to_string()), + replace_leftmost_underscore("bb_b.some.com") + ); + assert_eq!( + Some("a-a-a.some.com".to_string()), + replace_leftmost_underscore("a_a_a.some.com") + ); + assert_eq!( + Some("-.some.com".to_string()), + replace_leftmost_underscore("_.some.com") + ); + } +} diff --git a/pingora-core/src/lib.rs b/pingora-core/src/lib.rs new file mode 100644 index 0000000..cdeff85 --- /dev/null +++ b/pingora-core/src/lib.rs @@ -0,0 +1,69 @@ +// 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. + +#![warn(clippy::all)] +#![allow(clippy::new_without_default)] +#![allow(clippy::type_complexity)] +#![allow(clippy::match_wild_err_arm)] +#![allow(clippy::missing_safety_doc)] +#![allow(clippy::upper_case_acronyms)] +// enable nightly feature async trait so that the docs are cleaner +#![cfg_attr(doc_async_trait, feature(async_fn_in_trait))] + +//! # Pingora +//! +//! Pingora is a collection of service frameworks and network libraries battle-tested by the Internet. +//! It is to build robust, scalable and secure network infrastructures and services at Internet scale. +//! +//! # Features +//! - Http 1.x and Http 2 +//! - Modern TLS with OpenSSL or BoringSSL (FIPS compatible) +//! - Zero downtime upgrade +//! +//! # Usage +//! This crate provides low level service and protocol implementation and abstraction. +//! +//! If looking to build a (reverse) proxy, see `pingora-proxy` crate. +//! +//! # Optional features +//! `boringssl`: Switch the internal TLS library from OpenSSL to BoringSSL. + +pub mod apps; +pub mod connectors; +pub mod listeners; +pub mod modules; +pub mod protocols; +pub mod server; +pub mod services; +pub mod upstreams; +pub mod utils; + +pub use pingora_error::{ErrorType::*, *}; + +// If both openssl and boringssl are enabled, prefer boringssl. +// This is to make sure that boringssl can override the default openssl feature +// when this crate is used indirectly by other crates. +#[cfg(feature = "boringssl")] +pub use pingora_boringssl as tls; + +#[cfg(all(not(feature = "boringssl"), feature = "openssl"))] +pub use pingora_openssl as tls; + +pub mod prelude { + pub use crate::server::configuration::Opt; + pub use crate::server::Server; + pub use crate::services::background::background_service; + pub use crate::upstreams::peer::HttpPeer; + pub use pingora_error::{ErrorType::*, *}; +} diff --git a/pingora-core/src/listeners/l4.rs b/pingora-core/src/listeners/l4.rs new file mode 100644 index 0000000..1bec6c6 --- /dev/null +++ b/pingora-core/src/listeners/l4.rs @@ -0,0 +1,311 @@ +// 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 log::warn; +use pingora_error::{ + ErrorType::{AcceptError, BindError}, + OrErr, Result, +}; +use std::fs::Permissions; +use std::io::ErrorKind; +use std::net::{SocketAddr, ToSocketAddrs}; +use std::os::unix::io::{AsRawFd, FromRawFd}; +use std::os::unix::net::UnixListener as StdUnixListener; +use std::time::Duration; +use tokio::net::TcpSocket; + +use crate::protocols::l4::listener::Listener; +pub use crate::protocols::l4::stream::Stream; +use crate::server::ListenFds; + +const TCP_LISTENER_MAX_TRY: usize = 30; +const TCP_LISTENER_TRY_STEP: Duration = Duration::from_secs(1); +// TODO: configurable backlog +const LISTENER_BACKLOG: u32 = 65535; + +/// Address for listening server, either TCP/UDS socket. +#[derive(Clone, Debug)] +pub enum ServerAddress { + Tcp(String, Option), + Uds(String, Option), +} + +impl AsRef for ServerAddress { + fn as_ref(&self) -> &str { + match &self { + Self::Tcp(l, _) => l, + Self::Uds(l, _) => l, + } + } +} + +/// TCP socket configuration options. +#[derive(Clone, Debug)] +pub struct TcpSocketOptions { + /// IPV6_V6ONLY flag (if true, limit socket to IPv6 communication only). + /// This is mostly useful when binding to `[::]`, which on most Unix distributions + /// will bind to both IPv4 and IPv6 addresses by default. + pub ipv6_only: bool, + // TODO: allow configuring reuseaddr, backlog, etc. from here? +} + +mod uds { + use super::{OrErr, Result}; + use crate::protocols::l4::listener::Listener; + use log::{debug, error}; + use pingora_error::ErrorType::BindError; + use std::fs::{self, Permissions}; + use std::io::ErrorKind; + use std::os::unix::fs::PermissionsExt; + use std::os::unix::net::UnixListener as StdUnixListener; + use tokio::net::UnixListener; + + use super::LISTENER_BACKLOG; + + pub(super) fn set_perms(path: &str, perms: Option) -> Result<()> { + // set read/write permissions for all users on the socket by default + let perms = perms.unwrap_or(Permissions::from_mode(0o666)); + fs::set_permissions(path, perms).or_err_with(BindError, || { + format!("Fail to bind to {path}, could not set permissions") + }) + } + + pub(super) fn set_backlog(l: StdUnixListener, backlog: u32) -> Result { + let socket: socket2::Socket = l.into(); + // Note that we call listen on an already listening socket + // POSIX undefined but on Linux it will update the backlog size + socket + .listen(backlog as i32) + .or_err_with(BindError, || format!("listen() failed on {socket:?}"))?; + UnixListener::from_std(socket.into()).or_err(BindError, "Failed to convert to tokio socket") + } + + pub(super) fn bind(addr: &str, perms: Option) -> Result { + /* + We remove the filename/address in case there is a dangling reference. + + "Binding to a socket with a filename creates a socket in the + filesystem that must be deleted by the caller when it is no + longer needed (using unlink(2))" + */ + match std::fs::remove_file(addr) { + Ok(()) => { + debug!("unlink {addr} done"); + } + Err(e) => match e.kind() { + ErrorKind::NotFound => debug!("unlink {addr} not found: {e}"), + _ => error!("unlink {addr} failed: {e}"), + }, + } + let listener_socket = UnixListener::bind(addr) + .or_err_with(BindError, || format!("Bind() failed on {addr}"))?; + set_perms(addr, perms)?; + let std_listener = listener_socket.into_std().unwrap(); + Ok(set_backlog(std_listener, LISTENER_BACKLOG)?.into()) + } +} + +// currently, these options can only apply on sockets prior to calling bind() +fn apply_tcp_socket_options(sock: &TcpSocket, opt: Option<&TcpSocketOptions>) -> Result<()> { + let Some(opt) = opt else { + return Ok(()); + }; + let socket_ref = socket2::SockRef::from(sock); + socket_ref + .set_only_v6(opt.ipv6_only) + .or_err(BindError, "failed to set IPV6_V6ONLY") +} + +fn from_raw_fd(address: &ServerAddress, fd: i32) -> Result { + match address { + ServerAddress::Uds(addr, perm) => { + let std_listener = unsafe { StdUnixListener::from_raw_fd(fd) }; + // set permissions just in case + uds::set_perms(addr, perm.clone())?; + Ok(uds::set_backlog(std_listener, LISTENER_BACKLOG)?.into()) + } + ServerAddress::Tcp(_, _) => { + let std_listener_socket = unsafe { std::net::TcpStream::from_raw_fd(fd) }; + let listener_socket = TcpSocket::from_std_stream(std_listener_socket); + // Note that we call listen on an already listening socket + // POSIX undefined but on Linux it will update the backlog size + Ok(listener_socket + .listen(LISTENER_BACKLOG) + .or_err_with(BindError, || format!("Listen() failed on {address:?}"))? + .into()) + } + } +} + +async fn bind_tcp(addr: &str, opt: Option) -> Result { + let mut try_count = 0; + loop { + let sock_addr = addr + .to_socket_addrs() // NOTE: this could invoke a blocking network lookup + .or_err_with(BindError, || format!("Invalid listen address {addr}"))? + .next() // take the first one for now + .unwrap(); // assume there is always at least one + + let listener_socket = match sock_addr { + SocketAddr::V4(_) => TcpSocket::new_v4(), + SocketAddr::V6(_) => TcpSocket::new_v6(), + } + .or_err_with(BindError, || format!("fail to create address {sock_addr}"))?; + + // NOTE: this is to preserve the current TcpListener::bind() behavior. + // We have a few test relying on this behavior to allow multiple identical + // test servers to coexist. + listener_socket + .set_reuseaddr(true) + .or_err(BindError, "fail to set_reuseaddr(true)")?; + + apply_tcp_socket_options(&listener_socket, opt.as_ref())?; + + match listener_socket.bind(sock_addr) { + Ok(()) => { + break Ok(listener_socket + .listen(LISTENER_BACKLOG) + .or_err(BindError, "bind() failed")? + .into()) + } + Err(e) => { + if e.kind() != ErrorKind::AddrInUse { + break Err(e).or_err_with(BindError, || format!("bind() failed on {addr}")); + } + try_count += 1; + if try_count >= TCP_LISTENER_MAX_TRY { + break Err(e).or_err_with(BindError, || { + format!("bind() failed, after retries, {addr} still in use") + }); + } + warn!("{addr} is in use, will try again"); + tokio::time::sleep(TCP_LISTENER_TRY_STEP).await; + } + } + } +} + +async fn bind(addr: &ServerAddress) -> Result { + match addr { + ServerAddress::Uds(l, perm) => uds::bind(l, perm.clone()), + ServerAddress::Tcp(l, opt) => bind_tcp(l, opt.clone()).await, + } +} + +pub struct ListenerEndpoint { + listen_addr: ServerAddress, + listener: Option, +} + +impl ListenerEndpoint { + pub fn new(listen_addr: ServerAddress) -> Self { + ListenerEndpoint { + listen_addr, + listener: None, + } + } + + pub fn as_str(&self) -> &str { + self.listen_addr.as_ref() + } + + pub async fn listen(&mut self, fds: Option) -> Result<()> { + if self.listener.is_some() { + return Ok(()); + } + + let listener = if let Some(fds_table) = fds { + let addr = self.listen_addr.as_ref(); + // consider make this mutex std::sync::Mutex or OnceCell + let mut table = fds_table.lock().await; + if let Some(fd) = table.get(addr.as_ref()) { + from_raw_fd(&self.listen_addr, *fd)? + } else { + // not found + let listener = bind(&self.listen_addr).await?; + table.add(addr.to_string(), listener.as_raw_fd()); + listener + } + } else { + // not found, no fd table + bind(&self.listen_addr).await? + }; + self.listener = Some(listener); + Ok(()) + } + + pub async fn accept(&mut self) -> Result { + let Some(listener) = self.listener.as_mut() else { + // panic otherwise this thing dead loop + panic!("Need to call listen() first"); + }; + let mut stream = listener + .accept() + .await + .or_err(AcceptError, "Fail to accept()")?; + stream.set_nodelay()?; + Ok(stream) + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[tokio::test] + async fn test_listen_tcp() { + let addr = "127.0.0.1:7100"; + let mut listener = ListenerEndpoint::new(ServerAddress::Tcp(addr.into(), None)); + listener.listen(None).await.unwrap(); + tokio::spawn(async move { + // just try to accept once + listener.accept().await.unwrap(); + }); + tokio::net::TcpStream::connect(addr) + .await + .expect("can connect to TCP listener"); + } + + #[tokio::test] + async fn test_listen_tcp_ipv6_only() { + let sock_opt = Some(TcpSocketOptions { ipv6_only: true }); + let mut listener = ListenerEndpoint::new(ServerAddress::Tcp("[::]:7101".into(), sock_opt)); + listener.listen(None).await.unwrap(); + tokio::spawn(async move { + // just try to accept twice + listener.accept().await.unwrap(); + listener.accept().await.unwrap(); + }); + tokio::net::TcpStream::connect("127.0.0.1:7101") + .await + .expect_err("cannot connect to v4 addr"); + tokio::net::TcpStream::connect("[::1]:7101") + .await + .expect("can connect to v6 addr"); + } + + #[tokio::test] + async fn test_listen_uds() { + let addr = "/tmp/test_listen_uds"; + let mut listener = ListenerEndpoint::new(ServerAddress::Uds(addr.into(), None)); + listener.listen(None).await.unwrap(); + tokio::spawn(async move { + // just try to accept once + listener.accept().await.unwrap(); + }); + tokio::net::UnixStream::connect(addr) + .await + .expect("can connect to UDS listener"); + } +} diff --git a/pingora-core/src/listeners/mod.rs b/pingora-core/src/listeners/mod.rs new file mode 100644 index 0000000..9d08f14 --- /dev/null +++ b/pingora-core/src/listeners/mod.rs @@ -0,0 +1,248 @@ +// 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. + +//! The listening endpoints (TCP and TLS) and their configurations. + +mod l4; +mod tls; + +use crate::protocols::Stream; +use crate::server::ListenFds; + +use pingora_error::Result; +use std::{fs::Permissions, sync::Arc}; + +use l4::{ListenerEndpoint, Stream as L4Stream}; +use tls::Acceptor; + +pub use crate::protocols::ssl::server::TlsAccept; +pub use l4::{ServerAddress, TcpSocketOptions}; +pub use tls::{TlsSettings, ALPN}; + +struct TransportStackBuilder { + l4: ServerAddress, + tls: Option, +} + +impl TransportStackBuilder { + pub fn build(&mut self, upgrade_listeners: Option) -> TransportStack { + TransportStack { + l4: ListenerEndpoint::new(self.l4.clone()), + tls: self.tls.take().map(|tls| Arc::new(tls.build())), + upgrade_listeners, + } + } +} + +pub(crate) struct TransportStack { + l4: ListenerEndpoint, + tls: Option>, + // listeners sent from the old process for graceful upgrade + upgrade_listeners: Option, +} + +impl TransportStack { + pub fn as_str(&self) -> &str { + self.l4.as_str() + } + + pub async fn listen(&mut self) -> Result<()> { + self.l4.listen(self.upgrade_listeners.take()).await + } + + pub async fn accept(&mut self) -> Result { + let stream = self.l4.accept().await?; + Ok(UninitializedStream { + l4: stream, + tls: self.tls.clone(), + }) + } + + pub fn cleanup(&mut self) { + // placeholder + } +} + +pub(crate) struct UninitializedStream { + l4: L4Stream, + tls: Option>, +} + +impl UninitializedStream { + pub async fn handshake(self) -> Result { + if let Some(tls) = self.tls { + let tls_stream = tls.tls_handshake(self.l4).await?; + Ok(Box::new(tls_stream)) + } else { + Ok(Box::new(self.l4)) + } + } +} + +/// The struct to hold one more multiple listening endpoints +pub struct Listeners { + stacks: Vec, +} + +impl Listeners { + /// Create a new [`Listeners`] with no listening endpoints. + pub fn new() -> Self { + Listeners { stacks: vec![] } + } + + /// Create a new [`Listeners`] with a TCP server endpoint from the given string. + pub fn tcp(addr: &str) -> Self { + let mut listeners = Self::new(); + listeners.add_tcp(addr); + listeners + } + + /// Create a new [`Listeners`] with a Unix domain socket endpoint from the given string. + pub fn uds(addr: &str, perm: Option) -> Self { + let mut listeners = Self::new(); + listeners.add_uds(addr, perm); + listeners + } + + /// Create a new [`Listeners`] with with a TLS (TCP) endpoint with the given address string, + /// and path to the certificate/private key pairs. + /// This endpoint will adopt the [Mozilla Intermediate](https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28recommended.29) + /// server side TLS settings. + pub fn tls(addr: &str, cert_path: &str, key_path: &str) -> Result { + let mut listeners = Self::new(); + listeners.add_tls(addr, cert_path, key_path)?; + Ok(listeners) + } + + /// Add a TCP endpoint to `self`. + pub fn add_tcp(&mut self, addr: &str) { + self.add_address(ServerAddress::Tcp(addr.into(), None)); + } + + /// Add a TCP endpoint to `self`, with the given [`TcpSocketOptions`]. + pub fn add_tcp_with_settings(&mut self, addr: &str, sock_opt: TcpSocketOptions) { + self.add_address(ServerAddress::Tcp(addr.into(), Some(sock_opt))); + } + + /// Add a Unix domain socket endpoint to `self`. + pub fn add_uds(&mut self, addr: &str, perm: Option) { + self.add_address(ServerAddress::Uds(addr.into(), perm)); + } + + /// Add a TLS endpoint to `self` with the [Mozilla Intermediate](https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28recommended.29) + /// server side TLS settings. + pub fn add_tls(&mut self, addr: &str, cert_path: &str, key_path: &str) -> Result<()> { + self.add_tls_with_settings(addr, None, TlsSettings::intermediate(cert_path, key_path)?); + Ok(()) + } + + /// Add a TLS endpoint to `self` with the given socket and server side TLS settings. + /// See [`TlsSettings`] and [`TcpSocketOptions`] for more details. + pub fn add_tls_with_settings( + &mut self, + addr: &str, + sock_opt: Option, + settings: TlsSettings, + ) { + self.add_endpoint(ServerAddress::Tcp(addr.into(), sock_opt), Some(settings)); + } + + /// Add the given [`ServerAddress`] to `self`. + pub fn add_address(&mut self, addr: ServerAddress) { + self.add_endpoint(addr, None); + } + + /// Add the given [`ServerAddress`] to `self` with the given [`TlsSettings`] if provided + pub fn add_endpoint(&mut self, l4: ServerAddress, tls: Option) { + self.stacks.push(TransportStackBuilder { l4, tls }) + } + + pub(crate) fn build(&mut self, upgrade_listeners: Option) -> Vec { + self.stacks + .iter_mut() + .map(|b| b.build(upgrade_listeners.clone())) + .collect() + } + + pub(crate) fn cleanup(&self) { + // placeholder + } +} + +#[cfg(test)] +mod test { + use super::*; + use tokio::io::AsyncWriteExt; + use tokio::net::TcpStream; + use tokio::time::{sleep, Duration}; + + #[tokio::test] + async fn test_listen_tcp() { + let addr1 = "127.0.0.1:7101"; + let addr2 = "127.0.0.1:7102"; + let mut listeners = Listeners::tcp(addr1); + listeners.add_tcp(addr2); + + let listeners = listeners.build(None); + assert_eq!(listeners.len(), 2); + for mut listener in listeners { + tokio::spawn(async move { + listener.listen().await.unwrap(); + // just try to accept once + let stream = listener.accept().await.unwrap(); + stream.handshake().await.unwrap(); + }); + } + + // make sure the above starts before the lines below + sleep(Duration::from_millis(10)).await; + + TcpStream::connect(addr1).await.unwrap(); + TcpStream::connect(addr2).await.unwrap(); + } + + #[tokio::test] + async fn test_listen_tls() { + use tokio::io::AsyncReadExt; + + let addr = "127.0.0.1:7103"; + 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 listeners = Listeners::tls(addr, &cert_path, &key_path).unwrap(); + let mut listener = listeners.build(None).pop().unwrap(); + + tokio::spawn(async move { + listener.listen().await.unwrap(); + // just try to accept once + let stream = listener.accept().await.unwrap(); + let mut stream = stream.handshake().await.unwrap(); + let mut buf = [0; 1024]; + let _ = stream.read(&mut buf).await.unwrap(); + stream + .write_all(b"HTTP/1.1 200 OK\r\nContent-Length: 1\r\n\r\na") + .await + .unwrap(); + }); + // make sure the above starts before the lines below + sleep(Duration::from_millis(10)).await; + + let client = reqwest::Client::builder() + .danger_accept_invalid_certs(true) + .build() + .unwrap(); + + let res = client.get(format!("https://{addr}")).send().await.unwrap(); + assert_eq!(res.status(), reqwest::StatusCode::OK); + } +} diff --git a/pingora-core/src/listeners/tls.rs b/pingora-core/src/listeners/tls.rs new file mode 100644 index 0000000..ec53551 --- /dev/null +++ b/pingora-core/src/listeners/tls.rs @@ -0,0 +1,152 @@ +// 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 log::debug; +use pingora_error::{ErrorType, OrErr, Result}; +use std::ops::{Deref, DerefMut}; + +use crate::protocols::ssl::{ + server::{handshake, handshake_with_callback, TlsAcceptCallbacks}, + SslStream, +}; +use crate::protocols::IO; +use crate::tls::ssl::{SslAcceptor, SslAcceptorBuilder, SslFiletype, SslMethod}; + +pub use crate::protocols::ssl::ALPN; + +pub const TLS_CONF_ERR: ErrorType = ErrorType::Custom("TLSConfigError"); + +pub(crate) struct Acceptor { + ssl_acceptor: SslAcceptor, + callbacks: Option, +} + +/// The TLS settings of a listening endpoint +pub struct TlsSettings { + accept_builder: SslAcceptorBuilder, + callbacks: Option, +} + +impl Deref for TlsSettings { + type Target = SslAcceptorBuilder; + + fn deref(&self) -> &Self::Target { + &self.accept_builder + } +} + +impl DerefMut for TlsSettings { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.accept_builder + } +} + +impl TlsSettings { + /// Create a new [`TlsSettings`] with the the [Mozilla Intermediate](https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28recommended.29). + /// server side TLS settings. Users can adjust the TLS settings after this object is created. + /// Return error if the provided certificate and private key are invalid or not found. + pub fn intermediate(cert_path: &str, key_path: &str) -> Result { + let mut accept_builder = SslAcceptor::mozilla_intermediate_v5(SslMethod::tls()).or_err( + TLS_CONF_ERR, + "fail to create mozilla_intermediate_v5 Acceptor", + )?; + accept_builder + .set_private_key_file(key_path, SslFiletype::PEM) + .or_err(TLS_CONF_ERR, "fail to read key file {key_path}")?; + accept_builder + .set_certificate_chain_file(cert_path) + .or_err(TLS_CONF_ERR, "fail to read cert file {cert_path}")?; + Ok(TlsSettings { + accept_builder, + callbacks: None, + }) + } + + /// Create a new [`TlsSettings`] similar to [TlsSettings::intermediate()]. A struct that implements [TlsAcceptCallbacks] + /// is needed to provide the certificate during the TLS handshake. + pub fn with_callbacks(callbacks: TlsAcceptCallbacks) -> Result { + let accept_builder = SslAcceptor::mozilla_intermediate_v5(SslMethod::tls()).or_err( + TLS_CONF_ERR, + "fail to create mozilla_intermediate_v5 Acceptor", + )?; + Ok(TlsSettings { + accept_builder, + callbacks: Some(callbacks), + }) + } + + /// Enable HTTP/2 support for this endpoint, which is default off. + /// This effectively sets the ALPN to prefer HTTP/2 with HTTP/1.1 allowed + pub fn enable_h2(&mut self) { + self.set_alpn(ALPN::H2H1); + } + + /// Set the ALPN preference of this endpoint. See [`ALPN`] for more details + pub fn set_alpn(&mut self, alpn: ALPN) { + match alpn { + ALPN::H2H1 => self + .accept_builder + .set_alpn_select_callback(alpn::prefer_h2), + ALPN::H1 => self.accept_builder.set_alpn_select_callback(alpn::h1_only), + ALPN::H2 => self.accept_builder.set_alpn_select_callback(alpn::h2_only), + } + } + + pub(crate) fn build(self) -> Acceptor { + Acceptor { + ssl_acceptor: self.accept_builder.build(), + callbacks: self.callbacks, + } + } +} + +impl Acceptor { + pub async fn tls_handshake(&self, stream: S) -> Result> { + debug!("new ssl session"); + // TODO: be able to offload this handshake in a thread pool + if let Some(cb) = self.callbacks.as_ref() { + handshake_with_callback(&self.ssl_acceptor, stream, cb).await + } else { + handshake(&self.ssl_acceptor, stream).await + } + } +} + +mod alpn { + use super::*; + use crate::tls::ssl::{select_next_proto, AlpnError, SslRef}; + + // A standard implementation provided by the SSL lib is used below + + pub fn prefer_h2<'a>(_ssl: &mut SslRef, alpn_in: &'a [u8]) -> Result<&'a [u8], AlpnError> { + match select_next_proto(ALPN::H2H1.to_wire_preference(), alpn_in) { + Some(p) => Ok(p), + _ => Err(AlpnError::NOACK), // unknown ALPN, just ignore it. Most clients will fallback to h1 + } + } + + pub fn h1_only<'a>(_ssl: &mut SslRef, alpn_in: &'a [u8]) -> Result<&'a [u8], AlpnError> { + match select_next_proto(ALPN::H1.to_wire_preference(), alpn_in) { + Some(p) => Ok(p), + _ => Err(AlpnError::NOACK), // unknown ALPN, just ignore it. Most clients will fallback to h1 + } + } + + pub fn h2_only<'a>(_ssl: &mut SslRef, alpn_in: &'a [u8]) -> Result<&'a [u8], AlpnError> { + match select_next_proto(ALPN::H2.to_wire_preference(), alpn_in) { + Some(p) => Ok(p), + _ => Err(AlpnError::ALERT_FATAL), // cannot agree + } + } +} diff --git a/pingora-core/src/modules/http/compression.rs b/pingora-core/src/modules/http/compression.rs new file mode 100644 index 0000000..b07e1c7 --- /dev/null +++ b/pingora-core/src/modules/http/compression.rs @@ -0,0 +1,65 @@ +// 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. + +//! HTTP compression filter + +use super::*; +use crate::protocols::http::compression::ResponseCompressionCtx; + +/// HTTP response compression module +pub struct ResponseCompression(ResponseCompressionCtx); + +impl HttpModule for ResponseCompression { + fn as_any(&self) -> &dyn std::any::Any { + self + } + fn as_any_mut(&mut self) -> &mut dyn std::any::Any { + self + } + + fn request_header_filter(&mut self, req: &mut RequestHeader) -> Result<()> { + self.0.request_filter(req); + Ok(()) + } + + fn response_filter(&mut self, t: &mut HttpTask) -> Result<()> { + self.0.response_filter(t); + Ok(()) + } +} + +/// The builder for HTTP response compression module +pub struct ResponseCompressionBuilder { + level: u32, +} + +impl ResponseCompressionBuilder { + /// Return a [ModuleBuilder] for [ResponseCompression] with the given compression level + pub fn enable(level: u32) -> ModuleBuilder { + Box::new(ResponseCompressionBuilder { level }) + } +} + +impl HttpModuleBuilder for ResponseCompressionBuilder { + fn init(&self) -> Module { + Box::new(ResponseCompression(ResponseCompressionCtx::new( + self.level, false, + ))) + } + + fn order(&self) -> i16 { + // run the response filter later than most others filters + i16::MIN / 2 + } +} diff --git a/pingora-core/src/modules/http/mod.rs b/pingora-core/src/modules/http/mod.rs new file mode 100644 index 0000000..9c446b1 --- /dev/null +++ b/pingora-core/src/modules/http/mod.rs @@ -0,0 +1,277 @@ +// 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. + +//! Modules for HTTP traffic. +//! +//! [HttpModule]s define request and response filters to use while running an [HttpServer] +//! application. +//! See the [ResponseCompression] module for an example of how to implement a basic module. + +pub mod compression; + +use crate::protocols::http::HttpTask; +use bytes::Bytes; +use once_cell::sync::OnceCell; +use pingora_error::Result; +use pingora_http::RequestHeader; +use std::any::Any; +use std::any::TypeId; +use std::collections::HashMap; +use std::sync::Arc; + +/// The trait a HTTP traffic module needs to implement +// TODO: * async filters for, e.g., 3rd party auth server; * access the connection for, e.g., GeoIP +pub trait HttpModule { + fn request_header_filter(&mut self, _req: &mut RequestHeader) -> Result<()> { + Ok(()) + } + + fn request_body_filter(&mut self, body: Option) -> Result> { + Ok(body) + } + + fn response_filter(&mut self, _t: &mut HttpTask) -> Result<()> { + Ok(()) + } + + fn as_any(&self) -> &dyn Any; + fn as_any_mut(&mut self) -> &mut dyn Any; +} + +type Module = Box; + +/// Trait to init the http module ctx for each request +pub trait HttpModuleBuilder { + /// The order the module will run + /// + /// The lower the value, the later it runs relative to other filters. + /// If the order of the filter is not important, leave it to the default 0. + fn order(&self) -> i16 { + 0 + } + + /// Initialize and return the per request module context + fn init(&self) -> Module; +} + +pub type ModuleBuilder = Box; + +/// The object to hold multiple http modules +pub struct HttpModules { + modules: Vec, + module_index: OnceCell>>, +} + +impl HttpModules { + /// Create a new [HttpModules] + pub fn new() -> Self { + HttpModules { + modules: vec![], + module_index: OnceCell::new(), + } + } + + /// Add a new [ModuleBuilder] to [HttpModules] + /// + /// Each type of [HttpModule] can be only added once. + /// # Panic + /// Panic if any [HttpModule] is added more tha once. + pub fn add_module(&mut self, builder: ModuleBuilder) { + if self.module_index.get().is_some() { + // We use a shared module_index the index would be out of sync if we + // add more modules. + panic!("cannot add module after ctx is already built") + } + self.modules.push(builder); + // not the most efficient way but should be fine + // largest order first + self.modules.sort_by_key(|m| -m.order()); + } + + /// Build the contexts of all the modules added to this [HttpModules] + pub fn build_ctx(&self) -> HttpModuleCtx { + let module_ctx: Vec<_> = self.modules.iter().map(|b| b.init()).collect(); + let module_index = self + .module_index + .get_or_init(|| { + let mut module_index = HashMap::with_capacity(self.modules.len()); + for (i, c) in module_ctx.iter().enumerate() { + let exist = module_index.insert(c.as_any().type_id(), i); + if exist.is_some() { + panic!("duplicated filters found") + } + } + Arc::new(module_index) + }) + .clone(); + + HttpModuleCtx { + module_ctx, + module_index, + } + } +} + +/// The Contexts of multiple modules +/// +/// This is the object that will apply all the included modules to a certain HTTP request. +/// The modules are ordered according to their `order()`. +pub struct HttpModuleCtx { + // the modules in the order of execution + module_ctx: Vec, + // find the module in the vec with its type ID + module_index: Arc>, +} + +impl HttpModuleCtx { + /// Create an placeholder empty [HttpModuleCtx]. + /// + /// [HttpModules] should be used to create nonempty [HttpModuleCtx]. + pub fn empty() -> Self { + HttpModuleCtx { + module_ctx: vec![], + module_index: Arc::new(HashMap::new()), + } + } + + /// Get a ref to [HttpModule] if any. + pub fn get(&self) -> Option<&T> { + let idx = self.module_index.get(&TypeId::of::())?; + let ctx = &self.module_ctx[*idx]; + Some( + ctx.as_any() + .downcast_ref::() + .expect("type should always match"), + ) + } + + /// Get a mut ref to [HttpModule] if any. + pub fn get_mut(&mut self) -> Option<&mut T> { + let idx = self.module_index.get(&TypeId::of::())?; + let ctx = &mut self.module_ctx[*idx]; + Some( + ctx.as_any_mut() + .downcast_mut::() + .expect("type should always match"), + ) + } + + /// Run the `request_header_filter` for all the modules according to their orders. + pub fn request_header_filter(&mut self, req: &mut RequestHeader) -> Result<()> { + for filter in self.module_ctx.iter_mut() { + filter.request_header_filter(req)?; + } + Ok(()) + } + + /// Run the `request_body_filter` for all the modules according to their orders. + pub fn request_body_filter(&mut self, mut body: Option) -> Result> { + for filter in self.module_ctx.iter_mut() { + body = filter.request_body_filter(body)?; + } + Ok(body) + } + + /// Run the `response_filter` for all the modules according to their orders. + pub fn response_filter(&mut self, t: &mut HttpTask) -> Result<()> { + for filter in self.module_ctx.iter_mut() { + filter.response_filter(t)?; + } + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + struct MyModule; + impl HttpModule for MyModule { + fn as_any(&self) -> &dyn Any { + self + } + fn as_any_mut(&mut self) -> &mut dyn Any { + self + } + fn request_header_filter(&mut self, req: &mut RequestHeader) -> Result<()> { + req.insert_header("my-filter", "1") + } + } + struct MyModuleBuilder; + impl HttpModuleBuilder for MyModuleBuilder { + fn order(&self) -> i16 { + 1 + } + + fn init(&self) -> Module { + Box::new(MyModule) + } + } + + struct MyOtherModule; + impl HttpModule for MyOtherModule { + fn as_any(&self) -> &dyn Any { + self + } + fn as_any_mut(&mut self) -> &mut dyn Any { + self + } + fn request_header_filter(&mut self, req: &mut RequestHeader) -> Result<()> { + if req.headers.get("my-filter").is_some() { + // if this MyOtherModule runs after MyModule + req.insert_header("my-filter", "2") + } else { + // if this MyOtherModule runs before MyModule + req.insert_header("my-other-filter", "1") + } + } + } + struct MyOtherModuleBuilder; + impl HttpModuleBuilder for MyOtherModuleBuilder { + fn order(&self) -> i16 { + -1 + } + + fn init(&self) -> Module { + Box::new(MyOtherModule) + } + } + + #[test] + fn test_module_get() { + let mut http_module = HttpModules::new(); + http_module.add_module(Box::new(MyModuleBuilder)); + http_module.add_module(Box::new(MyOtherModuleBuilder)); + let mut ctx = http_module.build_ctx(); + assert!(ctx.get::().is_some()); + assert!(ctx.get::().is_some()); + assert!(ctx.get::().is_none()); + assert!(ctx.get_mut::().is_some()); + assert!(ctx.get_mut::().is_some()); + assert!(ctx.get_mut::().is_none()); + } + + #[test] + fn test_module_filter() { + let mut http_module = HttpModules::new(); + http_module.add_module(Box::new(MyOtherModuleBuilder)); + http_module.add_module(Box::new(MyModuleBuilder)); + let mut ctx = http_module.build_ctx(); + let mut req = RequestHeader::build("Get", b"/", None).unwrap(); + ctx.request_header_filter(&mut req).unwrap(); + // MyModule runs before MyOtherModule + assert_eq!(req.headers.get("my-filter").unwrap(), "2"); + assert!(req.headers.get("my-other-filter").is_none()); + } +} diff --git a/pingora-core/src/modules/mod.rs b/pingora-core/src/modules/mod.rs new file mode 100644 index 0000000..385b124 --- /dev/null +++ b/pingora-core/src/modules/mod.rs @@ -0,0 +1,16 @@ +// 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. + +//! Modules to extend the functionalities of pingora services. +pub mod http; diff --git a/pingora-core/src/protocols/digest.rs b/pingora-core/src/protocols/digest.rs new file mode 100644 index 0000000..13ce35c --- /dev/null +++ b/pingora-core/src/protocols/digest.rs @@ -0,0 +1,66 @@ +// 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. + +//! Extra information about the connection + +use std::sync::Arc; +use std::time::SystemTime; + +use super::raw_connect::ProxyDigest; +use super::ssl::digest::SslDigest; + +/// The information can be extracted from a connection +#[derive(Clone, Debug)] +pub struct Digest { + /// Information regarding the TLS of this connection if any + pub ssl_digest: Option>, + /// Timing information + pub timing_digest: Vec>, + /// information regarding the CONNECT proxy this connection uses. + pub proxy_digest: Option>, +} + +/// The interface to return protocol related information +pub trait ProtoDigest { + fn get_digest(&self) -> Option<&Digest> { + None + } +} + +/// The timing information of the connection +#[derive(Clone, Debug)] +pub struct TimingDigest { + /// When this connection was established + pub established_ts: SystemTime, +} + +impl Default for TimingDigest { + fn default() -> Self { + TimingDigest { + established_ts: SystemTime::UNIX_EPOCH, + } + } +} + +/// The interface to return timing information +pub trait GetTimingDigest { + /// Return the timing for each layer from the lowest layer to upper + fn get_timing_digest(&self) -> Vec>; +} + +/// The interface to set or return proxy information +pub trait GetProxyDigest { + fn get_proxy_digest(&self) -> Option>; + fn set_proxy_digest(&mut self, _digest: ProxyDigest) {} +} diff --git a/pingora-core/src/protocols/http/body_buffer.rs b/pingora-core/src/protocols/http/body_buffer.rs new file mode 100644 index 0000000..f3d7cdf --- /dev/null +++ b/pingora-core/src/protocols/http/body_buffer.rs @@ -0,0 +1,61 @@ +// 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 bytes::{Bytes, BytesMut}; + +/// A buffer with size limit. When the total amount of data written to the buffer is below the limit +/// all the data will be held in the buffer. Otherwise, the buffer will report to be truncated. +pub(crate) struct FixedBuffer { + buffer: BytesMut, + capacity: usize, + truncated: bool, +} + +impl FixedBuffer { + pub fn new(capacity: usize) -> Self { + FixedBuffer { + buffer: BytesMut::new(), + capacity, + truncated: false, + } + } + + // TODO: maybe store a Vec of Bytes for zero-copy + pub fn write_to_buffer(&mut self, data: &Bytes) { + if !self.truncated && (self.buffer.len() + data.len() <= self.capacity) { + self.buffer.extend_from_slice(data); + } else { + // TODO: clear data because the data held here is useless anyway? + self.truncated = true; + } + } + pub fn clear(&mut self) { + self.truncated = false; + self.buffer.clear(); + } + pub fn is_empty(&self) -> bool { + self.buffer.len() == 0 + } + pub fn is_truncated(&self) -> bool { + self.truncated + } + pub fn get_buffer(&self) -> Option { + // TODO: return None if truncated? + if !self.is_empty() { + Some(self.buffer.clone().freeze()) + } else { + None + } + } +} diff --git a/pingora-core/src/protocols/http/client.rs b/pingora-core/src/protocols/http/client.rs new file mode 100644 index 0000000..0fe6c90 --- /dev/null +++ b/pingora-core/src/protocols/http/client.rs @@ -0,0 +1,161 @@ +// 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 bytes::Bytes; +use pingora_error::Result; +use pingora_http::{RequestHeader, ResponseHeader}; +use std::time::Duration; + +use super::v1::client::HttpSession as Http1Session; +use super::v2::client::Http2Session; +use crate::protocols::Digest; + +/// A type for Http client session. It can be either an Http1 connection or an Http2 stream. +pub enum HttpSession { + H1(Http1Session), + H2(Http2Session), +} + +impl HttpSession { + pub fn as_http1(&self) -> Option<&Http1Session> { + match self { + Self::H1(s) => Some(s), + Self::H2(_) => None, + } + } + + pub fn as_http2(&self) -> Option<&Http2Session> { + match self { + Self::H1(_) => None, + Self::H2(s) => Some(s), + } + } + /// Write the request header to the server + /// After the request header is sent. The caller can either start reading the response or + /// sending request body if any. + pub async fn write_request_header(&mut self, req: Box) -> Result<()> { + match self { + HttpSession::H1(h1) => { + h1.write_request_header(req).await?; + Ok(()) + } + HttpSession::H2(h2) => h2.write_request_header(req, false), + } + } + + /// Write a chunk of the request body. + pub async fn write_request_body(&mut self, data: Bytes, end: bool) -> Result<()> { + match self { + HttpSession::H1(h1) => { + // TODO: maybe h1 should also have the concept of `end` + h1.write_body(&data).await?; + Ok(()) + } + HttpSession::H2(h2) => h2.write_request_body(data, end), + } + } + + /// Signal that the request body has ended + pub async fn finish_request_body(&mut self) -> Result<()> { + match self { + HttpSession::H1(h1) => { + h1.finish_body().await?; + Ok(()) + } + HttpSession::H2(h2) => h2.finish_request_body(), + } + } + + /// Set the read timeout for reading header and body. + /// + /// The timeout is per read operation, not on the overall time reading the entire response + pub fn set_read_timeout(&mut self, timeout: Duration) { + match self { + HttpSession::H1(h1) => h1.read_timeout = Some(timeout), + HttpSession::H2(h2) => h2.read_timeout = Some(timeout), + } + } + + /// Set the write timeout for writing header and body. + /// + /// The timeout is per write operation, not on the overall time writing the entire request + pub fn set_write_timeout(&mut self, timeout: Duration) { + match self { + HttpSession::H1(h1) => h1.write_timeout = Some(timeout), + HttpSession::H2(_) => { /* no write timeout because the actual write happens async*/ } + } + } + + /// Read the response header from the server + /// For http1, this function can be called multiple times, if the headers received are just + /// informational headers. + pub async fn read_response_header(&mut self) -> Result<()> { + match self { + HttpSession::H1(h1) => { + h1.read_response().await?; + Ok(()) + } + HttpSession::H2(h2) => h2.read_response_header().await, + } + } + + /// Read response body + /// + /// `None` when no more body to read. + pub async fn read_response_body(&mut self) -> Result> { + match self { + HttpSession::H1(h1) => h1.read_body_bytes().await, + HttpSession::H2(h2) => h2.read_response_body().await, + } + } + + /// No (more) body to read + pub fn response_done(&mut self) -> bool { + match self { + HttpSession::H1(h1) => h1.is_body_done(), + HttpSession::H2(h2) => h2.response_finished(), + } + } + + /// Give up the http session abruptly. + /// For H1 this will close the underlying connection + /// For H2 this will send RST_STREAM frame to end this stream if the stream has not ended at all + pub async fn shutdown(&mut self) { + match self { + Self::H1(s) => s.shutdown().await, + Self::H2(s) => s.shutdown(), + } + } + + /// Get the response header of the server + /// + /// `None` if the response header is not read yet. + pub fn response_header(&self) -> Option<&ResponseHeader> { + match self { + Self::H1(s) => s.resp_header(), + Self::H2(s) => s.response_header(), + } + } + + /// Return the [Digest] of the connection + /// + /// For reused connection, the timing in the digest will reflect its initial handshakes + /// The caller should check if the connection is reused to avoid misuse the timing field + pub fn digest(&self) -> Option<&Digest> { + match self { + Self::H1(s) => Some(s.digest()), + Self::H2(s) => s.digest(), + } + } +} diff --git a/pingora-core/src/protocols/http/compression/brotli.rs b/pingora-core/src/protocols/http/compression/brotli.rs new file mode 100644 index 0000000..956f87d --- /dev/null +++ b/pingora-core/src/protocols/http/compression/brotli.rs @@ -0,0 +1,161 @@ +// 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 super::Encode; +use super::COMPRESSION_ERROR; + +use brotli::{CompressorWriter, DecompressorWriter}; +use bytes::Bytes; +use pingora_error::{OrErr, Result}; +use std::io::Write; +use std::time::{Duration, Instant}; + +pub struct Decompressor { + decompress: DecompressorWriter>, + total_in: usize, + total_out: usize, + duration: Duration, +} + +impl Decompressor { + pub fn new() -> Self { + Decompressor { + // default buf is 4096 if 0 is used, TODO: figure out the significance of this value + decompress: DecompressorWriter::new(vec![], 0), + total_in: 0, + total_out: 0, + duration: Duration::new(0, 0), + } + } +} + +impl Encode for Decompressor { + fn encode(&mut self, input: &[u8], end: bool) -> Result { + // reserve at most 16k + const MAX_INIT_COMPRESSED_SIZE_CAP: usize = 4 * 1024; + // Brotli compress ratio can be 3.5 to 4.5 + const ESTIMATED_COMPRESSION_RATIO: usize = 4; + let start = Instant::now(); + self.total_in += input.len(); + // cap the buf size amplification, there is a DoS risk of always allocate + // 4x the memory of the input buffer + let reserve_size = if input.len() < MAX_INIT_COMPRESSED_SIZE_CAP { + input.len() * ESTIMATED_COMPRESSION_RATIO + } else { + input.len() + }; + self.decompress.get_mut().reserve(reserve_size); + self.decompress + .write_all(input) + .or_err(COMPRESSION_ERROR, "while decompress Brotli")?; + // write to vec will never fail. The only possible error is that the input data + // is invalid (not brotli compressed) + if end { + self.decompress + .flush() + .or_err(COMPRESSION_ERROR, "while decompress Brotli")?; + } + self.total_out += self.decompress.get_ref().len(); + self.duration += start.elapsed(); + Ok(std::mem::take(self.decompress.get_mut()).into()) // into() Bytes will drop excess capacity + } + + fn stat(&self) -> (&'static str, usize, usize, Duration) { + ("de-brotli", self.total_in, self.total_out, self.duration) + } +} + +pub struct Compressor { + compress: CompressorWriter>, + total_in: usize, + total_out: usize, + duration: Duration, +} + +impl Compressor { + pub fn new(level: u32) -> Self { + Compressor { + // buf_size:4096 , lgwin:19 TODO: fine tune these + compress: CompressorWriter::new(vec![], 4096, level, 19), + total_in: 0, + total_out: 0, + duration: Duration::new(0, 0), + } + } +} + +impl Encode for Compressor { + fn encode(&mut self, input: &[u8], end: bool) -> Result { + // reserve at most 16k + const MAX_INIT_COMPRESSED_BUF_SIZE: usize = 16 * 1024; + let start = Instant::now(); + self.total_in += input.len(); + + // reserve at most input size, cap at 16k, compressed output should be smaller + self.compress + .get_mut() + .reserve(std::cmp::min(MAX_INIT_COMPRESSED_BUF_SIZE, input.len())); + self.compress + .write_all(input) + .or_err(COMPRESSION_ERROR, "while compress Brotli")?; + // write to vec will never fail. + if end { + self.compress + .flush() + .or_err(COMPRESSION_ERROR, "while compress Brotli")?; + } + self.total_out += self.compress.get_ref().len(); + self.duration += start.elapsed(); + Ok(std::mem::take(self.compress.get_mut()).into()) // into() Bytes will drop excess capacity + } + + fn stat(&self) -> (&'static str, usize, usize, Duration) { + ("brotli", self.total_in, self.total_out, self.duration) + } +} + +#[cfg(test)] +mod tests_stream { + use super::*; + + #[test] + fn decompress_brotli_data() { + let mut compressor = Decompressor::new(); + let decompressed = compressor + .encode( + &[ + 0x1f, 0x0f, 0x00, 0xf8, 0x45, 0x07, 0x87, 0x3e, 0x10, 0xfb, 0x55, 0x92, 0xec, + 0x12, 0x09, 0xcc, 0x38, 0xdd, 0x51, 0x1e, + ], + true, + ) + .unwrap(); + + assert_eq!(&decompressed[..], &b"adcdefgabcdefgh\n"[..]); + } + + #[test] + fn compress_brotli_data() { + let mut compressor = Compressor::new(11); + let compressed = compressor.encode(&b"adcdefgabcdefgh\n"[..], true).unwrap(); + + assert_eq!( + &compressed[..], + &[ + 0x85, 0x07, 0x00, 0xf8, 0x45, 0x07, 0x87, 0x3e, 0x10, 0xfb, 0x55, 0x92, 0xec, 0x12, + 0x09, 0xcc, 0x38, 0xdd, 0x51, 0x1e, + ], + ); + } +} diff --git a/pingora-core/src/protocols/http/compression/gzip.rs b/pingora-core/src/protocols/http/compression/gzip.rs new file mode 100644 index 0000000..d64c961 --- /dev/null +++ b/pingora-core/src/protocols/http/compression/gzip.rs @@ -0,0 +1,103 @@ +// 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 super::Encode; + +use bytes::Bytes; +use flate2::write::GzEncoder; +use pingora_error::Result; +use std::io::Write; +use std::time::{Duration, Instant}; + +// TODO: unzip + +pub struct Compressor { + // TODO: enum for other compression algorithms + compress: GzEncoder>, + total_in: usize, + total_out: usize, + duration: Duration, +} + +impl Compressor { + pub fn new(level: u32) -> Compressor { + Compressor { + compress: GzEncoder::new(vec![], flate2::Compression::new(level)), + total_in: 0, + total_out: 0, + duration: Duration::new(0, 0), + } + } +} + +impl Encode for Compressor { + // infallible because compression can take any data + fn encode(&mut self, input: &[u8], end: bool) -> Result { + // reserve at most 16k + const MAX_INIT_COMPRESSED_BUF_SIZE: usize = 16 * 1024; + let start = Instant::now(); + self.total_in += input.len(); + self.compress + .get_mut() + .reserve(std::cmp::min(MAX_INIT_COMPRESSED_BUF_SIZE, input.len())); + self.write_all(input).unwrap(); // write to vec, should never fail + if end { + self.try_finish().unwrap(); // write to vec, should never fail + } + self.total_out += self.compress.get_ref().len(); + self.duration += start.elapsed(); + Ok(std::mem::take(self.compress.get_mut()).into()) // into() Bytes will drop excess capacity + } + + fn stat(&self) -> (&'static str, usize, usize, Duration) { + ("gzip", self.total_in, self.total_out, self.duration) + } +} + +use std::ops::{Deref, DerefMut}; +impl Deref for Compressor { + type Target = GzEncoder>; + + fn deref(&self) -> &Self::Target { + &self.compress + } +} + +impl DerefMut for Compressor { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.compress + } +} + +#[cfg(test)] +mod tests_stream { + use super::*; + + #[test] + fn gzip_data() { + let mut compressor = Compressor::new(6); + let compressed = compressor.encode(b"abcdefg", true).unwrap(); + // gzip magic headers + assert_eq!(&compressed[..3], &[0x1f, 0x8b, 0x08]); + // check the crc32 footer + assert_eq!( + &compressed[compressed.len() - 9..], + &[0, 166, 106, 42, 49, 7, 0, 0, 0] + ); + assert_eq!(compressor.total_in, 7); + assert_eq!(compressor.total_out, compressed.len()); + + assert!(compressor.get_ref().is_empty()); + } +} diff --git a/pingora-core/src/protocols/http/compression/mod.rs b/pingora-core/src/protocols/http/compression/mod.rs new file mode 100644 index 0000000..a16c774 --- /dev/null +++ b/pingora-core/src/protocols/http/compression/mod.rs @@ -0,0 +1,612 @@ +// 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. + +//! HTTP response (de)compression libraries +//! +//! Brotli and Gzip and partially supported. + +use super::HttpTask; + +use bytes::Bytes; +use log::warn; +use pingora_error::{ErrorType, Result}; +use pingora_http::{RequestHeader, ResponseHeader}; +use std::time::Duration; + +mod brotli; +mod gzip; +mod zstd; + +/// The type of error to return when (de)compression fails +pub const COMPRESSION_ERROR: ErrorType = ErrorType::new("CompressionError"); + +/// The trait for both compress and decompress because the interface and syntax are the same: +/// encode some bytes to other bytes +pub trait Encode { + /// Encode the input bytes. The `end` flag signals the end of the entire input. The `end` flag + /// helps the encoder to flush out the remaining buffered encoded data because certain compression + /// algorithms prefer to collect large enough data to compress all together. + fn encode(&mut self, input: &[u8], end: bool) -> Result; + /// Return the Encoder's name, the total input bytes, the total output bytes and the total + /// duration spent on encoding the data. + fn stat(&self) -> (&'static str, usize, usize, Duration); +} + +/// The response compression object. Currently support gzip compression and brotli decompression. +/// +/// To use it, the caller should create a [`ResponseCompressionCtx`] per HTTP session. +/// The caller should call the corresponding filters for the request header, response header and +/// response body. If the algorithms are supported, the output response body will be encoded. +/// The response header will be adjusted accordingly as well. If the algorithm is not supported +/// or no encoding needed, the response is untouched. +/// +/// If configured and if the request's `accept-encoding` header contains the algorithm supported and the +/// incoming response doesn't have that encoding, the filter will compress the response. +/// If configured and supported, and if the incoming response's `content-encoding` isn't one of the +/// request's `accept-encoding` supported algorithm, the ctx will decompress the response. +/// +/// # Currently supported algorithms and actions +/// - Brotli decompression: if the response is br compressed, this ctx can decompress it +/// - Gzip compression: if the response is uncompressed, this ctx can compress it with gzip +pub struct ResponseCompressionCtx(CtxInner); + +enum CtxInner { + HeaderPhase { + compression_level: u32, + decompress_enable: bool, + // Store the preferred list to compare with content-encoding + accept_encoding: Vec, + }, + BodyPhase(Option>), +} + +impl ResponseCompressionCtx { + /// Create a new [`ResponseCompressionCtx`] with the expected compression level. `0` will disable + /// the compression. + /// The `decompress_enable` flag will tell the ctx to decompress if needed. + pub fn new(compression_level: u32, decompress_enable: bool) -> Self { + Self(CtxInner::HeaderPhase { + compression_level, + decompress_enable, + accept_encoding: Vec::new(), + }) + } + + /// Whether the encoder is enabled. + /// The enablement will change according to the request and response filter by this ctx. + pub fn is_enabled(&self) -> bool { + match &self.0 { + CtxInner::HeaderPhase { + compression_level, + decompress_enable, + accept_encoding: _, + } => *compression_level != 0 || *decompress_enable, + CtxInner::BodyPhase(c) => c.is_some(), + } + } + + /// Return the stat of this ctx: + /// algorithm name, in bytes, out bytes, time took for the compression + pub fn get_info(&self) -> Option<(&'static str, usize, usize, Duration)> { + match &self.0 { + CtxInner::HeaderPhase { + compression_level: _, + decompress_enable: _, + accept_encoding: _, + } => None, + CtxInner::BodyPhase(c) => c.as_ref().map(|c| c.stat()), + } + } + + /// Adjust the compression level. + /// # Panic + /// This function will panic if it has already started encoding the response body. + pub fn adjust_level(&mut self, new_level: u32) { + match &mut self.0 { + CtxInner::HeaderPhase { + compression_level, + decompress_enable: _, + accept_encoding: _, + } => { + *compression_level = new_level; + } + CtxInner::BodyPhase(_) => panic!("Wrong phase: BodyPhase"), + } + } + + /// Adjust the decompression flag. + /// # Panic + /// This function will panic if it has already started encoding the response body. + pub fn adjust_decompression(&mut self, enabled: bool) { + match &mut self.0 { + CtxInner::HeaderPhase { + compression_level: _, + decompress_enable, + accept_encoding: _, + } => { + *decompress_enable = enabled; + } + CtxInner::BodyPhase(_) => panic!("Wrong phase: BodyPhase"), + } + } + + /// Feed the request header into this ctx. + pub fn request_filter(&mut self, req: &RequestHeader) { + if !self.is_enabled() { + return; + } + match &mut self.0 { + CtxInner::HeaderPhase { + compression_level: _, + decompress_enable: _, + accept_encoding, + } => parse_accept_encoding( + req.headers.get(http::header::ACCEPT_ENCODING), + accept_encoding, + ), + CtxInner::BodyPhase(_) => panic!("Wrong phase: BodyPhase"), + } + } + + fn response_header_filter(&mut self, resp: &mut ResponseHeader, end: bool) { + match &self.0 { + CtxInner::HeaderPhase { + compression_level, + decompress_enable, + accept_encoding, + } => { + if resp.status.is_informational() { + if resp.status == http::status::StatusCode::SWITCHING_PROTOCOLS { + // no transformation for websocket (TODO: cite RFC) + self.0 = CtxInner::BodyPhase(None); + } + // else, wait for the final response header for decision + return; + } + // do nothing if no body + if end { + self.0 = CtxInner::BodyPhase(None); + return; + } + + let action = decide_action(resp, accept_encoding); + let encoder = match action { + Action::Noop => None, + Action::Compress(algorithm) => algorithm.compressor(*compression_level), + Action::Decompress(algorithm) => algorithm.decompressor(*decompress_enable), + }; + if encoder.is_some() { + adjust_response_header(resp, &action); + } + self.0 = CtxInner::BodyPhase(encoder); + } + CtxInner::BodyPhase(_) => panic!("Wrong phase: BodyPhase"), + } + } + + fn response_body_filter(&mut self, data: Option<&Bytes>, end: bool) -> Option { + match &mut self.0 { + CtxInner::HeaderPhase { + compression_level: _, + decompress_enable: _, + accept_encoding: _, + } => panic!("Wrong phase: HeaderPhase"), + CtxInner::BodyPhase(compressor) => { + let result = compressor + .as_mut() + .map(|c| { + // Feed even empty slice to compressor because it might yield data + // when `end` is true + let data = if let Some(b) = data { b.as_ref() } else { &[] }; + c.encode(data, end) + }) + .transpose(); + result.unwrap_or_else(|e| { + warn!("Failed to compress, compression disabled, {}", e); + // no point to transcode further data because bad data is already seen + self.0 = CtxInner::BodyPhase(None); + None + }) + } + } + } + + /// Feed the response into this ctx. + /// This filter will mutate the response accordingly if encoding is needed. + pub fn response_filter(&mut self, t: &mut HttpTask) { + if !self.is_enabled() { + return; + } + match t { + HttpTask::Header(resp, end) => self.response_header_filter(resp, *end), + HttpTask::Body(data, end) => { + let compressed = self.response_body_filter(data.as_ref(), *end); + if compressed.is_some() { + *t = HttpTask::Body(compressed, *end); + } + } + HttpTask::Done => { + // try to finish/flush compression + let compressed = self.response_body_filter(None, true); + if compressed.is_some() { + // compressor has more data to flush + *t = HttpTask::Body(compressed, true); + } + } + _ => { /* Trailer, Failed: do nothing? */ } + } + } +} + +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +enum Algorithm { + Any, // the "*" + Gzip, + Brotli, + Zstd, + // TODO: Identify, + // TODO: Deflate + Other, // anyting unknown +} + +impl Algorithm { + pub fn as_str(&self) -> &'static str { + match self { + Algorithm::Gzip => "gzip", + Algorithm::Brotli => "br", + Algorithm::Zstd => "zstd", + Algorithm::Any => "*", + Algorithm::Other => "other", + } + } + + pub fn compressor(&self, level: u32) -> Option> { + if level == 0 { + None + } else { + match self { + Self::Gzip => Some(Box::new(gzip::Compressor::new(level))), + Self::Brotli => Some(Box::new(brotli::Compressor::new(level))), + Self::Zstd => Some(Box::new(zstd::Compressor::new(level))), + _ => None, // not implemented + } + } + } + + pub fn decompressor(&self, enabled: bool) -> Option> { + if !enabled { + None + } else { + match self { + Self::Brotli => Some(Box::new(brotli::Decompressor::new())), + _ => None, // not implemented + } + } + } +} + +impl From<&str> for Algorithm { + fn from(s: &str) -> Self { + use unicase::UniCase; + + let coding = UniCase::new(s); + if coding == UniCase::ascii("gzip") { + Algorithm::Gzip + } else if coding == UniCase::ascii("br") { + Algorithm::Brotli + } else if coding == UniCase::ascii("zstd") { + Algorithm::Zstd + } else if s.is_empty() { + Algorithm::Any + } else { + Algorithm::Other + } + } +} + +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +enum Action { + Noop, // do nothing, e.g. when the input is already gzip + Compress(Algorithm), + Decompress(Algorithm), +} + +// parse Accpet-Encoding header and put it to the list +fn parse_accept_encoding(accept_encoding: Option<&http::HeaderValue>, list: &mut Vec) { + // https://www.rfc-editor.org/rfc/rfc9110#name-accept-encoding + if let Some(ac) = accept_encoding { + // fast path + if ac.as_bytes() == b"gzip" { + list.push(Algorithm::Gzip); + return; + } + // properly parse AC header + match sfv::Parser::parse_list(ac.as_bytes()) { + Ok(parsed) => { + for item in parsed { + if let sfv::ListEntry::Item(i) = item { + if let Some(s) = i.bare_item.as_token() { + // TODO: support q value + let algorithm = Algorithm::from(s); + // ignore algorithms that we don't understand ingore + if algorithm != Algorithm::Other { + list.push(Algorithm::from(s)); + } + } + } + } + } + Err(e) => { + warn!("Failed to parse accept-encoding {ac:?}, {e}") + } + } + } else { + // "If no Accept-Encoding header, any content coding is acceptable" + // keep the list empty + } +} + +#[test] +fn test_accept_encoding_req_header() { + let mut header = RequestHeader::build("GET", b"/", None).unwrap(); + let mut ac_list = Vec::new(); + parse_accept_encoding( + header.headers.get(http::header::ACCEPT_ENCODING), + &mut ac_list, + ); + assert!(ac_list.is_empty()); + + let mut ac_list = Vec::new(); + header.insert_header("accept-encoding", "gzip").unwrap(); + parse_accept_encoding( + header.headers.get(http::header::ACCEPT_ENCODING), + &mut ac_list, + ); + assert_eq!(ac_list[0], Algorithm::Gzip); + + let mut ac_list = Vec::new(); + header + .insert_header("accept-encoding", "what, br, gzip") + .unwrap(); + parse_accept_encoding( + header.headers.get(http::header::ACCEPT_ENCODING), + &mut ac_list, + ); + assert_eq!(ac_list[0], Algorithm::Brotli); + assert_eq!(ac_list[1], Algorithm::Gzip); +} + +// filter response header to see if (de)compression is needed +fn decide_action(resp: &ResponseHeader, accept_encoding: &[Algorithm]) -> Action { + use http::header::CONTENT_ENCODING; + + let content_encoding = if let Some(ce) = resp.headers.get(CONTENT_ENCODING) { + // https://www.rfc-editor.org/rfc/rfc9110#name-content-encoding + if let Ok(ce_str) = std::str::from_utf8(ce.as_bytes()) { + Some(Algorithm::from(ce_str)) + } else { + // not utf-8, treat it as unknown encoding to leave it untouched + Some(Algorithm::Other) + } + } else { + // no Accpet-encoding + None + }; + + if let Some(ce) = content_encoding { + if accept_encoding.contains(&ce) { + // downstream can accept this encoding, nothing to do + Action::Noop + } else { + // always decompress because uncompressed is always acceptable + // https://www.rfc-editor.org/rfc/rfc9110#field.accept-encoding + // "If the representation has no content coding, then it is acceptable by default + // unless specifically excluded..." TODO: check the exclude case + // TODO: we could also transcode it to a preferred encoding, e.g. br->gzip + Action::Decompress(ce) + } + } else if accept_encoding.is_empty() // both CE and AE are empty + || !compressible(resp) // the type is not compressible + || accept_encoding[0] == Algorithm::Any + { + Action::Noop + } else { + // try to compress with the first AC + // TODO: support to configure preferred encoding + Action::Compress(accept_encoding[0]) + } +} + +#[test] +fn test_decide_action() { + use Action::*; + use Algorithm::*; + + let header = ResponseHeader::build(200, None).unwrap(); + // no compression asked, no compression needed + assert_eq!(decide_action(&header, &[]), Noop); + + // already gzip, no compression needed + let mut header = ResponseHeader::build(200, None).unwrap(); + header.insert_header("content-type", "text/html").unwrap(); + header.insert_header("content-encoding", "gzip").unwrap(); + assert_eq!(decide_action(&header, &[Gzip]), Noop); + + // already gzip, no compression needed, upper case + let mut header = ResponseHeader::build(200, None).unwrap(); + header.insert_header("content-encoding", "GzIp").unwrap(); + header.insert_header("content-type", "text/html").unwrap(); + assert_eq!(decide_action(&header, &[Gzip]), Noop); + + // no encoding, compression needed, accepted content-type, large enough + // Will compress + let mut header = ResponseHeader::build(200, None).unwrap(); + header.insert_header("content-length", "20").unwrap(); + header.insert_header("content-type", "text/html").unwrap(); + assert_eq!(decide_action(&header, &[Gzip]), Compress(Gzip)); + + // too small + let mut header = ResponseHeader::build(200, None).unwrap(); + header.insert_header("content-length", "19").unwrap(); + header.insert_header("content-type", "text/html").unwrap(); + assert_eq!(decide_action(&header, &[Gzip]), Noop); + + // already compressed MIME + let mut header = ResponseHeader::build(200, None).unwrap(); + header.insert_header("content-length", "20").unwrap(); + header + .insert_header("content-type", "text/html+zip") + .unwrap(); + assert_eq!(decide_action(&header, &[Gzip]), Noop); + + // unsupported MIME + let mut header = ResponseHeader::build(200, None).unwrap(); + header.insert_header("content-length", "20").unwrap(); + header.insert_header("content-type", "image/jpg").unwrap(); + assert_eq!(decide_action(&header, &[Gzip]), Noop); + + // compressed, need decompress + let mut header = ResponseHeader::build(200, None).unwrap(); + header.insert_header("content-encoding", "gzip").unwrap(); + assert_eq!(decide_action(&header, &[]), Decompress(Gzip)); + + // accept-encoding different, need decompress + let mut header = ResponseHeader::build(200, None).unwrap(); + header.insert_header("content-encoding", "gzip").unwrap(); + assert_eq!(decide_action(&header, &[Brotli]), Decompress(Gzip)); + + // less preferred but no need to decompress + let mut header = ResponseHeader::build(200, None).unwrap(); + header.insert_header("content-encoding", "gzip").unwrap(); + assert_eq!(decide_action(&header, &[Brotli, Gzip]), Noop); +} + +use once_cell::sync::Lazy; +use regex::Regex; + +// Allow text, application, font, a few image/ MIME types and binary/octet-stream +// TODO: fine tune this list +static MIME_CHECK: Lazy = Lazy::new(|| { + Regex::new(r"^(?:text/|application/|font/|image/(?:x-icon|svg\+xml|nd\.microsoft\.icon)|binary/octet-stream)") + .unwrap() +}); + +// check if the response mime type is compressible +fn compressible(resp: &ResponseHeader) -> bool { + // arbitrary size limit, things to consider + // 1. too short body may have little redundancy to compress + // 2. gzip header and footer overhead + // 3. latency is the same as long as data fits in a TCP congestion window regardless of size + const MIN_COMPRESS_LEN: usize = 20; + + // check if response is too small to compress + if let Some(cl) = resp.headers.get(http::header::CONTENT_LENGTH) { + if let Some(cl_num) = std::str::from_utf8(cl.as_bytes()) + .ok() + .and_then(|v| v.parse::().ok()) + { + if cl_num < MIN_COMPRESS_LEN { + return false; + } + } + } + // no Content-Length or large enough, check content-type next + if let Some(ct) = resp.headers.get(http::header::CONTENT_TYPE) { + if let Ok(ct_str) = std::str::from_utf8(ct.as_bytes()) { + if ct_str.contains("zip") { + // heuristic: don't compress mime type that has zip in it + false + } else { + // check if mime type in allow list + MIME_CHECK.find(ct_str).is_some() + } + } else { + false // invalid CT header, don't compress + } + } else { + false // don't compress empty content-type + } +} + +fn adjust_response_header(resp: &mut ResponseHeader, action: &Action) { + use http::header::{HeaderValue, CONTENT_ENCODING, CONTENT_LENGTH, TRANSFER_ENCODING}; + + fn set_stream_headers(resp: &mut ResponseHeader) { + // because the transcoding is streamed, content length is not known ahead + resp.remove_header(&CONTENT_LENGTH); + // we stream body now TODO: chunked is for h1 only + resp.insert_header(&TRANSFER_ENCODING, HeaderValue::from_static("chunked")) + .unwrap(); + } + + match action { + Action::Noop => { /* do nothing */ } + Action::Decompress(_) => { + resp.remove_header(&CONTENT_ENCODING); + set_stream_headers(resp) + } + Action::Compress(a) => { + resp.insert_header(&CONTENT_ENCODING, HeaderValue::from_static(a.as_str())) + .unwrap(); + set_stream_headers(resp) + } + } +} + +#[test] +fn test_adjust_response_header() { + use Action::*; + use Algorithm::*; + + // noop + let mut header = ResponseHeader::build(200, None).unwrap(); + header.insert_header("content-length", "20").unwrap(); + header.insert_header("content-encoding", "gzip").unwrap(); + adjust_response_header(&mut header, &Noop); + assert_eq!( + header.headers.get("content-encoding").unwrap().as_bytes(), + b"gzip" + ); + assert_eq!( + header.headers.get("content-length").unwrap().as_bytes(), + b"20" + ); + assert!(header.headers.get("transfor-encoding").is_none()); + + // decompress gzip + let mut header = ResponseHeader::build(200, None).unwrap(); + header.insert_header("content-length", "20").unwrap(); + header.insert_header("content-encoding", "gzip").unwrap(); + adjust_response_header(&mut header, &Decompress(Gzip)); + assert!(header.headers.get("content-encoding").is_none()); + assert!(header.headers.get("content-length").is_none()); + assert_eq!( + header.headers.get("transfer-encoding").unwrap().as_bytes(), + b"chunked" + ); + + // compress + let mut header = ResponseHeader::build(200, None).unwrap(); + header.insert_header("content-length", "20").unwrap(); + adjust_response_header(&mut header, &Compress(Gzip)); + assert_eq!( + header.headers.get("content-encoding").unwrap().as_bytes(), + b"gzip" + ); + assert!(header.headers.get("content-length").is_none()); + assert_eq!( + header.headers.get("transfer-encoding").unwrap().as_bytes(), + b"chunked" + ); +} diff --git a/pingora-core/src/protocols/http/compression/zstd.rs b/pingora-core/src/protocols/http/compression/zstd.rs new file mode 100644 index 0000000..88a2bfc --- /dev/null +++ b/pingora-core/src/protocols/http/compression/zstd.rs @@ -0,0 +1,91 @@ +// 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 super::{Encode, COMPRESSION_ERROR}; +use bytes::Bytes; +use parking_lot::Mutex; +use pingora_error::{OrErr, Result}; +use std::io::Write; +use std::time::{Duration, Instant}; +use zstd::stream::write::Encoder; + +pub struct Compressor { + compress: Mutex>>, + total_in: usize, + total_out: usize, + duration: Duration, +} + +impl Compressor { + pub fn new(level: u32) -> Self { + Compressor { + // Mutex because Encoder is not Sync + // https://github.com/gyscos/zstd-rs/issues/186 + compress: Mutex::new(Encoder::new(vec![], level as i32).unwrap()), + total_in: 0, + total_out: 0, + duration: Duration::new(0, 0), + } + } +} + +impl Encode for Compressor { + fn encode(&mut self, input: &[u8], end: bool) -> Result { + // reserve at most 16k + const MAX_INIT_COMPRESSED_BUF_SIZE: usize = 16 * 1024; + let start = Instant::now(); + self.total_in += input.len(); + let mut compress = self.compress.lock(); + // reserve at most input size, cap at 16k, compressed output should be smaller + compress + .get_mut() + .reserve(std::cmp::min(MAX_INIT_COMPRESSED_BUF_SIZE, input.len())); + compress + .write_all(input) + .or_err(COMPRESSION_ERROR, "while compress zstd")?; + // write to vec will never fail. + if end { + compress + .do_finish() + .or_err(COMPRESSION_ERROR, "while compress zstd")?; + } + self.total_out += compress.get_ref().len(); + self.duration += start.elapsed(); + Ok(std::mem::take(compress.get_mut()).into()) // into() Bytes will drop excess capacity + } + + fn stat(&self) -> (&'static str, usize, usize, Duration) { + ("zstd", self.total_in, self.total_out, self.duration) + } +} + +#[cfg(test)] +mod tests_stream { + use super::*; + + #[test] + fn compress_zstd_data() { + let mut compressor = Compressor::new(11); + let input = b"adcdefgabcdefghadcdefgabcdefghadcdefgabcdefghadcdefgabcdefgh\n"; + let compressed = compressor.encode(&input[..], false).unwrap(); + // waiting for more data + assert!(compressed.is_empty()); + + let compressed = compressor.encode(&input[..], true).unwrap(); + + // the zstd Magic_Number + assert_eq!(&compressed[..4], &[0x28, 0xB5, 0x2F, 0xFD]); + assert!(compressed.len() < input.len()); + } +} diff --git a/pingora-core/src/protocols/http/date.rs b/pingora-core/src/protocols/http/date.rs new file mode 100644 index 0000000..4b15c4e --- /dev/null +++ b/pingora-core/src/protocols/http/date.rs @@ -0,0 +1,90 @@ +// 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 chrono::NaiveDateTime; +use http::header::HeaderValue; +use std::cell::RefCell; +use std::time::{Duration, SystemTime}; + +fn to_date_string(epoch_sec: i64) -> String { + let dt = NaiveDateTime::from_timestamp_opt(epoch_sec, 0).unwrap(); + dt.format("%a, %d %b %Y %H:%M:%S GMT").to_string() +} + +struct CacheableDate { + h1_date: HeaderValue, + epoch: Duration, +} + +impl CacheableDate { + pub fn new() -> Self { + let d = SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .unwrap(); + CacheableDate { + h1_date: HeaderValue::from_str(&to_date_string(d.as_secs() as i64)).unwrap(), + epoch: d, + } + } + + pub fn update(&mut self, d_now: Duration) { + if d_now.as_secs() != self.epoch.as_secs() { + self.epoch = d_now; + self.h1_date = HeaderValue::from_str(&to_date_string(d_now.as_secs() as i64)).unwrap(); + } + } + + pub fn get_date(&mut self) -> HeaderValue { + let d = SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .unwrap(); + self.update(d); + self.h1_date.clone() + } +} + +thread_local! { + static CACHED_DATE: RefCell + = RefCell::new(CacheableDate::new()); +} + +pub fn get_cached_date() -> HeaderValue { + CACHED_DATE.with(|cache_date| (*cache_date.borrow_mut()).get_date()) +} + +#[cfg(test)] +mod test { + use super::*; + + fn now_date_header() -> HeaderValue { + HeaderValue::from_str(&to_date_string( + SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .unwrap() + .as_secs() as i64, + )) + .unwrap() + } + + #[test] + fn test_date_string() { + let date_str = to_date_string(1); + assert_eq!("Thu, 01 Jan 1970 00:00:01 GMT", date_str); + } + + #[test] + fn test_date_cached() { + assert_eq!(get_cached_date(), now_date_header()); + } +} diff --git a/pingora-core/src/protocols/http/error_resp.rs b/pingora-core/src/protocols/http/error_resp.rs new file mode 100644 index 0000000..acf5d2e --- /dev/null +++ b/pingora-core/src/protocols/http/error_resp.rs @@ -0,0 +1,41 @@ +// 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. + +//! Error response generating utilities. + +use http::header; +use once_cell::sync::Lazy; +use pingora_http::ResponseHeader; + +use super::SERVER_NAME; + +/// Generate an error response with the given status code. +/// +/// This error response has a zero `Content-Length` and `Cache-Control: private, no-store`. +pub fn gen_error_response(code: u16) -> ResponseHeader { + let mut resp = ResponseHeader::build(code, Some(4)).unwrap(); + resp.insert_header(header::SERVER, &SERVER_NAME[..]) + .unwrap(); + resp.insert_header(header::DATE, "Sun, 06 Nov 1994 08:49:37 GMT") + .unwrap(); // placeholder + resp.insert_header(header::CONTENT_LENGTH, "0").unwrap(); + resp.insert_header(header::CACHE_CONTROL, "private, no-store") + .unwrap(); + resp +} + +/// Pre-generated 502 response +pub static HTTP_502_RESPONSE: Lazy = Lazy::new(|| gen_error_response(502)); +/// Pre-generated 400 response +pub static HTTP_400_RESPONSE: Lazy = Lazy::new(|| gen_error_response(400)); diff --git a/pingora-core/src/protocols/http/mod.rs b/pingora-core/src/protocols/http/mod.rs new file mode 100644 index 0000000..d5e8ee9 --- /dev/null +++ b/pingora-core/src/protocols/http/mod.rs @@ -0,0 +1,57 @@ +// 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. + +//! HTTP/1.x and HTTP/2 implementation APIs + +mod body_buffer; +pub mod client; +pub mod compression; +pub(crate) mod date; +pub mod error_resp; +pub mod server; +pub mod v1; +pub mod v2; + +pub use server::Session as ServerSession; + +/// The Pingora server name string +pub const SERVER_NAME: &[u8; 7] = b"Pingora"; + +/// An enum to hold all possible HTTP response events. +#[derive(Debug)] +pub enum HttpTask { + /// the response header and the boolean end of response flag + Header(Box, bool), + /// A piece of response header and the end of response boolean flag + Body(Option, bool), + /// HTTP response trailer + Trailer(Option>), + /// Signal that the response is already finished + Done, + /// Signal that the reading of the response encounters errors. + Failed(pingora_error::BError), +} + +impl HttpTask { + /// Whether this [`HttpTask`] means the end of the response + pub fn is_end(&self) -> bool { + match self { + HttpTask::Header(_, end) => *end, + HttpTask::Body(_, end) => *end, + HttpTask::Trailer(_) => true, + HttpTask::Done => true, + HttpTask::Failed(_) => true, + } + } +} diff --git a/pingora-core/src/protocols/http/server.rs b/pingora-core/src/protocols/http/server.rs new file mode 100644 index 0000000..1f84997 --- /dev/null +++ b/pingora-core/src/protocols/http/server.rs @@ -0,0 +1,333 @@ +// 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. + +//! HTTP server session APIs + +use super::error_resp; +use super::v1::server::HttpSession as SessionV1; +use super::v2::server::HttpSession as SessionV2; +use super::HttpTask; +use crate::protocols::Stream; +use bytes::Bytes; +use http::header::AsHeaderName; +use http::HeaderValue; +use log::error; +use pingora_error::Result; +use pingora_http::{RequestHeader, ResponseHeader}; + +/// HTTP server session object for both HTTP/1.x and HTTP/2 +pub enum Session { + H1(SessionV1), + H2(SessionV2), +} + +impl Session { + /// Create a new [`Session`] from an established connection for HTTP/1.x + pub fn new_http1(stream: Stream) -> Self { + Self::H1(SessionV1::new(stream)) + } + + /// Create a new [`Session`] from an established HTTP/2 stream + pub fn new_http2(session: SessionV2) -> Self { + Self::H2(session) + } + + /// Whether the session is HTTP/2. If not it is HTTP/1.x + pub fn is_http2(&self) -> bool { + matches!(self, Self::H2(_)) + } + + /// Read the request header. This method is required to be called first before doing anything + /// else with the session. + /// - `Ok(true)`: successful + /// - `Ok(false)`: client exit without sending any bytes. This is normal on reused connection. + /// In this case the user should give up this session. + pub async fn read_request(&mut self) -> Result { + match self { + Self::H1(s) => { + let read = s.read_request().await?; + Ok(read.is_some()) + } + // This call will always return `Ok(true)` for Http2 because the request is already read + Self::H2(_) => Ok(true), + } + } + + /// Return the request header it just read. + /// # Panic + /// This function will panic if [`Self::read_request()`] is not called. + pub fn req_header(&self) -> &RequestHeader { + match self { + Self::H1(s) => s.req_header(), + Self::H2(s) => s.req_header(), + } + } + + /// Return a mutable reference to request header it just read. + /// # Panic + /// This function will panic if [`Self::read_request()`] is not called. + pub fn req_header_mut(&mut self) -> &mut RequestHeader { + match self { + Self::H1(s) => s.req_header_mut(), + Self::H2(s) => s.req_header_mut(), + } + } + + /// Return the header by name. None if the header doesn't exist. + /// + /// In case there are multiple headers under the same name, the first one will be returned. To + /// get all the headers: use `self.req_header().headers.get_all()`. + pub fn get_header(&self, key: K) -> Option<&HeaderValue> { + self.req_header().headers.get(key) + } + + /// Get the header value in its raw format. + /// If the header doesn't exist, return an empty slice. + pub fn get_header_bytes(&self, key: K) -> &[u8] { + self.get_header(key).map_or(b"", |v| v.as_bytes()) + } + + /// Read the request body. Ok(None) if no (more) body to read + pub async fn read_request_body(&mut self) -> Result> { + match self { + Self::H1(s) => s.read_body_bytes().await, + Self::H2(s) => s.read_body_bytes().await, + } + } + + /// Write the response header to client + /// Informational headers (status code 100-199, excluding 101) can be written multiple times the final + /// response header (status code 200+ or 101) is written. + pub async fn write_response_header(&mut self, resp: Box) -> Result<()> { + match self { + Self::H1(s) => { + s.write_response_header(resp).await?; + Ok(()) + } + Self::H2(s) => s.write_response_header(resp, false), + } + } + + /// Similar to `write_response_header()`, this fn will clone the `resp` internally + pub async fn write_response_header_ref(&mut self, resp: &ResponseHeader) -> Result<()> { + match self { + Self::H1(s) => { + s.write_response_header_ref(resp).await?; + Ok(()) + } + Self::H2(s) => s.write_response_header_ref(resp, false), + } + } + + /// Write the response body to client + pub async fn write_response_body(&mut self, data: Bytes) -> Result<()> { + match self { + Self::H1(s) => { + s.write_body(&data).await?; + Ok(()) + } + Self::H2(s) => s.write_body(data, false), + } + } + + /// Finish the life of this request. + /// For H1, if connection reuse is supported, a Some(Stream) will be returned, otherwise None. + /// For H2, always return None because H2 stream is not reusable. + pub async fn finish(self) -> Result> { + match self { + Self::H1(mut s) => { + // need to flush body due to buffering + s.finish_body().await?; + Ok(s.reuse().await) + } + Self::H2(mut s) => { + s.finish()?; + Ok(None) + } + } + } + + pub async fn response_duplex_vec(&mut self, tasks: Vec) -> Result { + match self { + Self::H1(s) => s.response_duplex_vec(tasks).await, + Self::H2(s) => s.response_duplex_vec(tasks), + } + } + + /// Set connection reuse. `duration` defines how long the connection is kept open for the next + /// request to reuse. Noop for h2 + pub fn set_keepalive(&mut self, duration: Option) { + match self { + Self::H1(s) => s.set_server_keepalive(duration), + Self::H2(_) => {} + } + } + + /// Return a digest of the request including the method, path and Host header + // TODO: make this use a `Formatter` + pub fn request_summary(&self) -> String { + match self { + Self::H1(s) => s.request_summary(), + Self::H2(s) => s.request_summary(), + } + } + + /// Return the written response header. `None` if it is not written yet. + /// Only the final (status code >= 200 or 101) response header will be returned + pub fn response_written(&self) -> Option<&ResponseHeader> { + match self { + Self::H1(s) => s.response_written(), + Self::H2(s) => s.response_written(), + } + } + + /// Give up the http session abruptly. + /// For H1 this will close the underlying connection + /// For H2 this will send RESET frame to end this stream without impacting the connection + pub async fn shutdown(&mut self) { + match self { + Self::H1(s) => s.shutdown().await, + Self::H2(s) => s.shutdown(), + } + } + + pub fn to_h1_raw(&self) -> Bytes { + match self { + Self::H1(s) => s.get_headers_raw_bytes(), + Self::H2(s) => s.pseudo_raw_h1_request_header(), + } + } + + /// Whether the whole request body is sent + pub fn is_body_done(&mut self) -> bool { + match self { + Self::H1(s) => s.is_body_done(), + Self::H2(s) => s.is_body_done(), + } + } + + /// Notify the client that the entire body is sent + /// for H1 chunked encoding, this will end the last empty chunk + /// for H1 content-length, this has no effect. + /// for H2, this will send an empty DATA frame with END_STREAM flag + pub async fn finish_body(&mut self) -> Result<()> { + match self { + Self::H1(s) => s.finish_body().await.map(|_| ()), + Self::H2(s) => s.finish(), + } + } + + /// Send error response to client + pub async fn respond_error(&mut self, error: u16) { + let resp = match error { + /* commmon error responses are pre-generated */ + 502 => error_resp::HTTP_502_RESPONSE.clone(), + 400 => error_resp::HTTP_400_RESPONSE.clone(), + _ => error_resp::gen_error_response(error), + }; + + // TODO: we shouldn't be closing downstream connections on internally generated errors + // and possibly other upstream connect() errors (connection refused, timeout, etc) + // + // This change is only here because we DO NOT re-use downstream connections + // today on these errors and we should signal to the client that pingora is dropping it + // rather than a misleading the client with 'keep-alive' + self.set_keepalive(None); + + self.write_response_header(Box::new(resp)) + .await + .unwrap_or_else(|e| { + error!("failed to send error response to downstream: {e}"); + }); + } + + /// Whether there is no request body + pub fn is_body_empty(&mut self) -> bool { + match self { + Self::H1(s) => s.is_body_empty(), + Self::H2(s) => s.is_body_empty(), + } + } + + pub fn retry_buffer_truncated(&self) -> bool { + match self { + Self::H1(s) => s.retry_buffer_truncated(), + Self::H2(s) => s.retry_buffer_truncated(), + } + } + + pub fn enable_retry_buffering(&mut self) { + match self { + Self::H1(s) => s.enable_retry_buffering(), + Self::H2(s) => s.enable_retry_buffering(), + } + } + + pub fn get_retry_buffer(&self) -> Option { + match self { + Self::H1(s) => s.get_retry_buffer(), + Self::H2(s) => s.get_retry_buffer(), + } + } + + /// Read body (same as `read_request_body()`) or pending forever until downstream + /// terminates the session. + pub async fn read_body_or_idle(&mut self, no_body_expected: bool) -> Result> { + match self { + Self::H1(s) => s.read_body_or_idle(no_body_expected).await, + Self::H2(s) => s.read_body_or_idle(no_body_expected).await, + } + } + + pub fn as_http1(&self) -> Option<&SessionV1> { + match self { + Self::H1(s) => Some(s), + Self::H2(_) => None, + } + } + + pub fn as_http2(&self) -> Option<&SessionV2> { + match self { + Self::H1(_) => None, + Self::H2(s) => Some(s), + } + } + + /// Write a 100 Continue response to the client. + pub async fn write_continue_response(&mut self) -> Result<()> { + match self { + Self::H1(s) => s.write_continue_response().await, + Self::H2(s) => s.write_response_header( + Box::new(ResponseHeader::build(100, Some(0)).unwrap()), + false, + ), + } + } + + /// Whether this request is for upgrade (e.g., websocket) + pub fn is_upgrade_req(&self) -> bool { + match self { + Self::H1(s) => s.is_upgrade_req(), + Self::H2(_) => false, + } + } + + /// How many response body bytes already sent + pub fn body_bytes_sent(&self) -> usize { + match self { + Self::H1(s) => s.body_bytes_sent(), + Self::H2(s) => s.body_bytes_sent(), + } + } +} diff --git a/pingora-core/src/protocols/http/v1/body.rs b/pingora-core/src/protocols/http/v1/body.rs new file mode 100644 index 0000000..81c8b22 --- /dev/null +++ b/pingora-core/src/protocols/http/v1/body.rs @@ -0,0 +1,1015 @@ +// 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 bytes::{Buf, BufMut, Bytes, BytesMut}; +use log::{debug, trace, warn}; +use pingora_error::{ + Error, + ErrorType::{self, *}, + OrErr, Result, +}; +use std::fmt::Debug; +use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}; + +use crate::protocols::l4::stream::AsyncWriteVec; +use crate::utils::BufRef; + +// TODO: make this dynamically adjusted +const BODY_BUFFER_SIZE: usize = 1024 * 64; +// limit how much incomplete chunk-size and chunk-ext to buffer +const PARTIAL_CHUNK_HEAD_LIMIT: usize = 1024 * 8; + +const LAST_CHUNK: &[u8; 5] = b"0\r\n\r\n"; + +pub const INVALID_CHUNK: ErrorType = ErrorType::new("InvalidChunk"); +pub const PREMATURE_BODY_END: ErrorType = ErrorType::new("PrematureBodyEnd"); + +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum ParseState { + ToStart, + Complete(usize), // total size + Partial(usize, usize), // size read, remaining size + Chunked(usize, usize, usize, usize), // size read, next to read in current buf start, read in current buf start, remaining chucked size to read from IO + Done(usize), // done but there is error, size read + HTTP1_0(usize), // read until connection closed, size read +} + +type PS = ParseState; + +impl ParseState { + pub fn finish(&self, additional_bytes: usize) -> Self { + match self { + PS::Partial(read, to_read) => PS::Complete(read + to_read), + PS::Chunked(read, _, _, _) => PS::Complete(read + additional_bytes), + PS::HTTP1_0(read) => PS::Complete(read + additional_bytes), + _ => self.clone(), /* invalid transaction */ + } + } + + pub fn done(&self, additional_bytes: usize) -> Self { + match self { + PS::Partial(read, _) => PS::Done(read + additional_bytes), + PS::Chunked(read, _, _, _) => PS::Done(read + additional_bytes), + PS::HTTP1_0(read) => PS::Done(read + additional_bytes), + _ => self.clone(), /* invalid transaction */ + } + } + + pub fn partial_chunk(&self, bytes_read: usize, bytes_to_read: usize) -> Self { + match self { + PS::Chunked(read, _, _, _) => PS::Chunked(read + bytes_read, 0, 0, bytes_to_read), + _ => self.clone(), /* invalid transaction */ + } + } + + pub fn multi_chunk(&self, bytes_read: usize, buf_start_index: usize) -> Self { + match self { + PS::Chunked(read, _, buf_end, _) => { + PS::Chunked(read + bytes_read, buf_start_index, *buf_end, 0) + } + _ => self.clone(), /* invalid transaction */ + } + } + + pub fn partial_chunk_head(&self, head_end: usize, head_size: usize) -> Self { + match self { + /* inform reader to read more to form a legal chunk */ + PS::Chunked(read, _, _, _) => PS::Chunked(*read, 0, head_end, head_size), + _ => self.clone(), /* invalid transaction */ + } + } + + pub fn new_buf(&self, buf_end: usize) -> Self { + match self { + PS::Chunked(read, _, _, _) => PS::Chunked(*read, 0, buf_end, 0), + _ => self.clone(), /* invalid transaction */ + } + } +} + +pub struct BodyReader { + pub body_state: ParseState, + pub body_buf: Option, + pub body_buf_size: usize, + rewind_buf_len: usize, +} + +impl BodyReader { + pub fn new() -> Self { + BodyReader { + body_state: PS::ToStart, + body_buf: None, + body_buf_size: BODY_BUFFER_SIZE, + rewind_buf_len: 0, + } + } + + pub fn need_init(&self) -> bool { + matches!(self.body_state, PS::ToStart) + } + + pub fn reinit(&mut self) { + self.body_state = PS::ToStart; + } + + fn prepare_buf(&mut self, buf_to_rewind: &[u8]) { + let mut body_buf = BytesMut::with_capacity(self.body_buf_size); + if !buf_to_rewind.is_empty() { + self.rewind_buf_len = buf_to_rewind.len(); + // TODO: this is still 1 copy. Make it zero + body_buf.put_slice(buf_to_rewind); + } + if self.body_buf_size > buf_to_rewind.len() { + //body_buf.resize(self.body_buf_size, 0); + unsafe { + body_buf.set_len(self.body_buf_size); + } + } + self.body_buf = Some(body_buf); + } + + pub fn init_chunked(&mut self, buf_to_rewind: &[u8]) { + self.body_state = PS::Chunked(0, 0, 0, 0); + self.prepare_buf(buf_to_rewind); + } + + pub fn init_content_length(&mut self, cl: usize, buf_to_rewind: &[u8]) { + match cl { + 0 => self.body_state = PS::Complete(0), + _ => { + self.prepare_buf(buf_to_rewind); + self.body_state = PS::Partial(0, cl); + } + } + } + + pub fn init_http10(&mut self, buf_to_rewind: &[u8]) { + self.prepare_buf(buf_to_rewind); + self.body_state = PS::HTTP1_0(0); + } + + pub fn get_body(&self, buf_ref: &BufRef) -> &[u8] { + // TODO: these get_*() could panic. handle them better + buf_ref.get(self.body_buf.as_ref().unwrap()) + } + + pub fn body_done(&self) -> bool { + matches!(self.body_state, PS::Complete(_) | PS::Done(_)) + } + + pub fn body_empty(&self) -> bool { + self.body_state == PS::Complete(0) + } + + pub async fn read_body(&mut self, stream: &mut S) -> Result> + where + S: AsyncRead + Unpin + Send, + { + match self.body_state { + PS::Complete(_) => Ok(None), + PS::Done(_) => Ok(None), + PS::Partial(_, _) => self.do_read_body(stream).await, + PS::Chunked(_, _, _, _) => self.do_read_chunked_body(stream).await, + PS::HTTP1_0(_) => self.do_read_body_until_closed(stream).await, + PS::ToStart => panic!("need to init BodyReader first"), + } + } + + pub async fn do_read_body(&mut self, stream: &mut S) -> Result> + where + S: AsyncRead + Unpin + Send, + { + let body_buf = self.body_buf.as_deref_mut().unwrap(); + let mut n = self.rewind_buf_len; + self.rewind_buf_len = 0; // we only need to read rewind data once + if n == 0 { + /* Need to actually read */ + n = stream + .read(body_buf) + .await + .or_err(ReadError, "when reading body")?; + } + match self.body_state { + PS::Partial(read, to_read) => { + debug!( + "BodyReader body_state: {:?}, read data from IO: {n}", + self.body_state + ); + if n == 0 { + self.body_state = PS::Done(read); + Error::e_explain(ConnectionClosed, format!( + "Peer prematurely closed connection with {} bytes of body remaining to read", + to_read + )) + } else if n >= to_read { + if n > to_read { + warn!( + "Peer sent more data then expected: extra {}\ + bytes, discarding them", + n - to_read + ) + } + self.body_state = PS::Complete(read + to_read); + Ok(Some(BufRef::new(0, to_read))) + } else { + self.body_state = PS::Partial(read + n, to_read - n); + Ok(Some(BufRef::new(0, n))) + } + } + _ => panic!("wrong body state: {:?}", self.body_state), + } + } + + pub async fn do_read_body_until_closed(&mut self, stream: &mut S) -> Result> + where + S: AsyncRead + Unpin + Send, + { + let body_buf = self.body_buf.as_deref_mut().unwrap(); + let mut n = self.rewind_buf_len; + self.rewind_buf_len = 0; // we only need to read rewind data once + if n == 0 { + /* Need to actually read */ + n = stream + .read(body_buf) + .await + .or_err(ReadError, "when reading body")?; + } + match self.body_state { + PS::HTTP1_0(read) => { + if n == 0 { + self.body_state = PS::Complete(read); + Ok(None) + } else { + self.body_state = PS::HTTP1_0(read + n); + Ok(Some(BufRef::new(0, n))) + } + } + _ => panic!("wrong body state: {:?}", self.body_state), + } + } + + pub async fn do_read_chunked_body(&mut self, stream: &mut S) -> Result> + where + S: AsyncRead + Unpin + Send, + { + match self.body_state { + PS::Chunked( + total_read, + existing_buf_start, + mut existing_buf_end, + mut expecting_from_io, + ) => { + if existing_buf_start == 0 { + // read a new buf from IO + let body_buf = self.body_buf.as_deref_mut().unwrap(); + if existing_buf_end == 0 { + existing_buf_end = self.rewind_buf_len; + self.rewind_buf_len = 0; // we only need to read rewind data once + if existing_buf_end == 0 { + existing_buf_end = stream + .read(body_buf) + .await + .or_err(ReadError, "when reading body")?; + } + } else { + /* existing_buf_end != 0 this is partial chunk head */ + /* copy the #expecting_from_io bytes until index existing_buf_end + * to the front and read more to form a valid chunk head. + * existing_buf_end is the end of the partial head and + * expecting_from_io is the len of it */ + body_buf + .copy_within(existing_buf_end - expecting_from_io..existing_buf_end, 0); + let new_bytes = stream + .read(&mut body_buf[expecting_from_io..]) + .await + .or_err(ReadError, "when reading body")?; + /* more data is read, extend the buffer */ + existing_buf_end = expecting_from_io + new_bytes; + expecting_from_io = 0; + } + self.body_state = self.body_state.new_buf(existing_buf_end); + } + if existing_buf_end == 0 { + self.body_state = self.body_state.done(0); + Error::e_explain( + ConnectionClosed, + format!( + "Connection prematurely closed without the termination chunk, \ + read {total_read} bytes" + ), + ) + } else { + if expecting_from_io > 0 { + trace!( + "parital chunk playload, expecting_from_io: {}, \ + existing_buf_end {}, buf: {:?}", + expecting_from_io, + existing_buf_end, + String::from_utf8_lossy( + &self.body_buf.as_ref().unwrap()[..existing_buf_end] + ) + ); + // partial chunk payload, will read more + if expecting_from_io >= existing_buf_end + 2 { + // not enough + self.body_state = self.body_state.partial_chunk( + existing_buf_end, + expecting_from_io - existing_buf_end, + ); + return Ok(Some(BufRef::new(0, existing_buf_end))); + } + /* could be expecting DATA + CRLF or just CRLF */ + let payload_size = if expecting_from_io > 2 { + expecting_from_io - 2 + } else { + 0 + }; + /* expecting_from_io < existing_buf_end + 2 */ + if expecting_from_io >= existing_buf_end { + self.body_state = self + .body_state + .partial_chunk(payload_size, expecting_from_io - existing_buf_end); + return Ok(Some(BufRef::new(0, payload_size))); + } + + /* expecting_from_io < existing_buf_end */ + self.body_state = + self.body_state.multi_chunk(payload_size, expecting_from_io); + return Ok(Some(BufRef::new(0, payload_size))); + } + self.parse_chunked_buf(existing_buf_start, existing_buf_end) + } + } + _ => panic!("wrong body state: {:?}", self.body_state), + } + } + + fn parse_chunked_buf( + &mut self, + buf_index_start: usize, + buf_index_end: usize, + ) -> Result> { + let buf = &self.body_buf.as_ref().unwrap()[buf_index_start..buf_index_end]; + let chunk_status = httparse::parse_chunk_size(buf); + match chunk_status { + Ok(status) => { + match status { + httparse::Status::Complete((payload_index, chunk_size)) => { + // TODO: Check chunk_size overflow + trace!( + "Got size {chunk_size}, payload_index: {payload_index}, chunk: {:?}", + String::from_utf8_lossy(buf) + ); + let chunk_size = chunk_size as usize; + if chunk_size == 0 { + /* terminating chunk. TODO: trailer */ + self.body_state = self.body_state.finish(0); + return Ok(None); + } + // chunk-size CRLF [payload_index] byte*[chunk_size] CRLF + let data_end_index = payload_index + chunk_size; + let chunk_end_index = data_end_index + 2; + if chunk_end_index >= buf.len() { + // no multi chunk in this buf + let actual_size = if data_end_index > buf.len() { + buf.len() - payload_index + } else { + chunk_size + }; + self.body_state = self + .body_state + .partial_chunk(actual_size, chunk_end_index - buf.len()); + return Ok(Some(BufRef::new( + buf_index_start + payload_index, + actual_size, + ))); + } + /* got multiple chunks, return the first */ + self.body_state = self + .body_state + .multi_chunk(chunk_size, buf_index_start + chunk_end_index); + Ok(Some(BufRef::new( + buf_index_start + payload_index, + chunk_size, + ))) + } + httparse::Status::Partial => { + if buf.len() > PARTIAL_CHUNK_HEAD_LIMIT { + // https://datatracker.ietf.org/doc/html/rfc9112#name-chunk-extensions + // "A server ought to limit the total length of chunk extensions received" + // The buf.len() here is the total length of chunk-size + chunk-ext seen + // so far. This check applies to both server and client + self.body_state = self.body_state.done(0); + Error::e_explain(INVALID_CHUNK, "Chunk ext over limit") + } else { + self.body_state = + self.body_state.partial_chunk_head(buf_index_end, buf.len()); + Ok(Some(BufRef::new(0, 0))) + } + } + } + } + Err(e) => { + let context = format!("Invalid chucked encoding: {e:?}"); + debug!("{context}, {:?}", String::from_utf8_lossy(buf)); + self.body_state = self.body_state.done(0); + Error::e_explain(INVALID_CHUNK, context) + } + } + } +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum BodyMode { + ToSelect, + ContentLength(usize, usize), // total length to write, bytes already written + ChunkedEncoding(usize), //bytes written + HTTP1_0(usize), //bytes written + Complete(usize), //bytes written +} + +type BM = BodyMode; + +pub struct BodyWriter { + pub body_mode: BodyMode, +} + +impl BodyWriter { + pub fn new() -> Self { + BodyWriter { + body_mode: BM::ToSelect, + } + } + + pub fn init_chunked(&mut self) { + self.body_mode = BM::ChunkedEncoding(0); + } + + pub fn init_http10(&mut self) { + self.body_mode = BM::HTTP1_0(0); + } + + pub fn init_content_length(&mut self, cl: usize) { + self.body_mode = BM::ContentLength(cl, 0); + } + + // NOTE on buffering/flush stream when writing the body + // Buffering writes can reduce the syscalls hence improves efficiency of the system + // But it hurts real time communication + // So we only allow buffering when the body size is known ahead, which is less likely + // to be real time interaction + + pub async fn write_body(&mut self, stream: &mut S, buf: &[u8]) -> Result> + where + S: AsyncWrite + Unpin + Send, + { + trace!("Writing Body, size: {}", buf.len()); + match self.body_mode { + BM::Complete(_) => Ok(None), + BM::ContentLength(_, _) => self.do_write_body(stream, buf).await, + BM::ChunkedEncoding(_) => self.do_write_chunked_body(stream, buf).await, + BM::HTTP1_0(_) => self.do_write_http1_0_body(stream, buf).await, + BM::ToSelect => Ok(None), // Error here? + } + } + + pub fn finished(&self) -> bool { + match self.body_mode { + BM::Complete(_) => true, + BM::ContentLength(total, written) => written >= total, + _ => false, + } + } + + async fn do_write_body(&mut self, stream: &mut S, buf: &[u8]) -> Result> + where + S: AsyncWrite + Unpin + Send, + { + match self.body_mode { + BM::ContentLength(total, written) => { + if written >= total { + // already written full length + return Ok(None); + } + let mut to_write = total - written; + if to_write < buf.len() { + warn!("Trying to write data over content-length: {total}"); + } else { + to_write = buf.len(); + } + let res = stream.write_all(&buf[..to_write]).await; + match res { + Ok(()) => { + self.body_mode = BM::ContentLength(total, written + to_write); + if self.finished() { + stream.flush().await.or_err(WriteError, "flushing body")?; + } + Ok(Some(to_write)) + } + Err(e) => Error::e_because(WriteError, "while writing body", e), + } + } + _ => panic!("wrong body mode: {:?}", self.body_mode), + } + } + + async fn do_write_chunked_body( + &mut self, + stream: &mut S, + buf: &[u8], + ) -> Result> + where + S: AsyncWrite + Unpin + Send, + { + match self.body_mode { + BM::ChunkedEncoding(written) => { + let chunk_size = buf.len(); + + let chuck_size_buf = format!("{:X}\r\n", chunk_size); + let mut output_buf = Bytes::from(chuck_size_buf).chain(buf).chain(&b"\r\n"[..]); + + while output_buf.has_remaining() { + let res = stream.write_vec(&mut output_buf).await; + match res { + Ok(n) => { + if n == 0 { + return Error::e_explain(ConnectionClosed, "while writing body"); + } + } + Err(e) => { + return Error::e_because(WriteError, "while writing body", e); + } + } + } + stream.flush().await.or_err(WriteError, "flushing body")?; + self.body_mode = BM::ChunkedEncoding(written + chunk_size); + Ok(Some(chunk_size)) + } + _ => panic!("wrong body mode: {:?}", self.body_mode), + } + } + + async fn do_write_http1_0_body( + &mut self, + stream: &mut S, + buf: &[u8], + ) -> Result> + where + S: AsyncWrite + Unpin + Send, + { + match self.body_mode { + BM::HTTP1_0(written) => { + let res = stream.write_all(buf).await; + match res { + Ok(()) => { + self.body_mode = BM::HTTP1_0(written + buf.len()); + stream.flush().await.or_err(WriteError, "flushing body")?; + Ok(Some(buf.len())) + } + Err(e) => Error::e_because(WriteError, "while writing body", e), + } + } + _ => panic!("wrong body mode: {:?}", self.body_mode), + } + } + + pub async fn finish(&mut self, stream: &mut S) -> Result> + where + S: AsyncWrite + Unpin + Send, + { + match self.body_mode { + BM::Complete(_) => Ok(None), + BM::ContentLength(_, _) => self.do_finish_body(stream), + BM::ChunkedEncoding(_) => self.do_finish_chunked_body(stream).await, + BM::HTTP1_0(_) => self.do_finish_http1_0_body(stream), + BM::ToSelect => Ok(None), + } + } + + fn do_finish_body(&mut self, _stream: S) -> Result> { + match self.body_mode { + BM::ContentLength(total, written) => { + self.body_mode = BM::Complete(written); + if written < total { + return Error::e_explain( + PREMATURE_BODY_END, + format!("Content-length: {total} bytes written: {written}"), + ); + } + Ok(Some(written)) + } + _ => panic!("wrong body mode: {:?}", self.body_mode), + } + } + + async fn do_finish_chunked_body(&mut self, stream: &mut S) -> Result> + where + S: AsyncWrite + Unpin + Send, + { + match self.body_mode { + BM::ChunkedEncoding(written) => { + let res = stream.write_all(&LAST_CHUNK[..]).await; + self.body_mode = BM::Complete(written); + match res { + Ok(()) => Ok(Some(written)), + Err(e) => Error::e_because(WriteError, "while writing body", e), + } + } + _ => panic!("wrong body mode: {:?}", self.body_mode), + } + } + + fn do_finish_http1_0_body(&mut self, _stream: &mut S) -> Result> { + match self.body_mode { + BM::HTTP1_0(written) => { + self.body_mode = BM::Complete(written); + Ok(Some(written)) + } + _ => panic!("wrong body mode: {:?}", self.body_mode), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::utils::BufRef; + use tokio_test::io::Builder; + + fn init_log() { + let _ = env_logger::builder().is_test(true).try_init(); + } + + #[tokio::test] + async fn read_with_body_content_length() { + init_log(); + let input = b"abc"; + let mut mock_io = Builder::new().read(&input[..]).build(); + let mut body_reader = BodyReader::new(); + body_reader.init_content_length(3, b""); + let res = body_reader.read_body(&mut mock_io).await.unwrap().unwrap(); + assert_eq!(res, BufRef::new(0, 3)); + assert_eq!(body_reader.body_state, ParseState::Complete(3)); + assert_eq!(input, body_reader.get_body(&res)); + } + + #[tokio::test] + async fn read_with_body_content_length_2() { + init_log(); + let input1 = b"a"; + let input2 = b"bc"; + let mut mock_io = Builder::new().read(&input1[..]).read(&input2[..]).build(); + let mut body_reader = BodyReader::new(); + body_reader.init_content_length(3, b""); + let res = body_reader.read_body(&mut mock_io).await.unwrap().unwrap(); + assert_eq!(res, BufRef::new(0, 1)); + assert_eq!(body_reader.body_state, ParseState::Partial(1, 2)); + assert_eq!(input1, body_reader.get_body(&res)); + let res = body_reader.read_body(&mut mock_io).await.unwrap().unwrap(); + assert_eq!(res, BufRef::new(0, 2)); + assert_eq!(body_reader.body_state, ParseState::Complete(3)); + assert_eq!(input2, body_reader.get_body(&res)); + } + + #[tokio::test] + async fn read_with_body_content_length_less() { + init_log(); + let input1 = b"a"; + let input2 = b""; // simulating close + let mut mock_io = Builder::new().read(&input1[..]).read(&input2[..]).build(); + let mut body_reader = BodyReader::new(); + body_reader.init_content_length(3, b""); + let res = body_reader.read_body(&mut mock_io).await.unwrap().unwrap(); + assert_eq!(res, BufRef::new(0, 1)); + assert_eq!(body_reader.body_state, ParseState::Partial(1, 2)); + assert_eq!(input1, body_reader.get_body(&res)); + let res = body_reader.read_body(&mut mock_io).await.unwrap_err(); + assert_eq!(&ConnectionClosed, res.etype()); + assert_eq!(body_reader.body_state, ParseState::Done(1)); + } + + #[tokio::test] + async fn read_with_body_content_length_more() { + init_log(); + let input1 = b"a"; + let input2 = b"bcd"; + let mut mock_io = Builder::new().read(&input1[..]).read(&input2[..]).build(); + let mut body_reader = BodyReader::new(); + body_reader.init_content_length(3, b""); + let res = body_reader.read_body(&mut mock_io).await.unwrap().unwrap(); + assert_eq!(res, BufRef::new(0, 1)); + assert_eq!(body_reader.body_state, ParseState::Partial(1, 2)); + assert_eq!(input1, body_reader.get_body(&res)); + let res = body_reader.read_body(&mut mock_io).await.unwrap().unwrap(); + assert_eq!(res, BufRef::new(0, 2)); + assert_eq!(body_reader.body_state, ParseState::Complete(3)); + assert_eq!(&input2[0..2], body_reader.get_body(&res)); + } + + #[tokio::test] + async fn read_with_body_content_length_rewind() { + init_log(); + let rewind = b"ab"; + let input = b"c"; + let mut mock_io = Builder::new().read(&input[..]).build(); + let mut body_reader = BodyReader::new(); + body_reader.init_content_length(3, rewind); + let res = body_reader.read_body(&mut mock_io).await.unwrap().unwrap(); + assert_eq!(res, BufRef::new(0, 2)); + assert_eq!(body_reader.body_state, ParseState::Partial(2, 1)); + assert_eq!(rewind, body_reader.get_body(&res)); + let res = body_reader.read_body(&mut mock_io).await.unwrap().unwrap(); + assert_eq!(res, BufRef::new(0, 1)); + assert_eq!(body_reader.body_state, ParseState::Complete(3)); + assert_eq!(input, body_reader.get_body(&res)); + } + + #[tokio::test] + async fn read_with_body_http10() { + init_log(); + let input1 = b"a"; + let input2 = b""; // simulating close + let mut mock_io = Builder::new().read(&input1[..]).read(&input2[..]).build(); + let mut body_reader = BodyReader::new(); + body_reader.init_http10(b""); + let res = body_reader.read_body(&mut mock_io).await.unwrap().unwrap(); + assert_eq!(res, BufRef::new(0, 1)); + assert_eq!(body_reader.body_state, ParseState::HTTP1_0(1)); + assert_eq!(input1, body_reader.get_body(&res)); + let res = body_reader.read_body(&mut mock_io).await.unwrap(); + assert_eq!(res, None); + assert_eq!(body_reader.body_state, ParseState::Complete(1)); + } + + #[tokio::test] + async fn read_with_body_http10_rewind() { + init_log(); + let rewind = b"ab"; + let input1 = b"c"; + let input2 = b""; // simulating close + let mut mock_io = Builder::new().read(&input1[..]).read(&input2[..]).build(); + let mut body_reader = BodyReader::new(); + body_reader.init_http10(rewind); + let res = body_reader.read_body(&mut mock_io).await.unwrap().unwrap(); + assert_eq!(res, BufRef::new(0, 2)); + assert_eq!(body_reader.body_state, ParseState::HTTP1_0(2)); + assert_eq!(rewind, body_reader.get_body(&res)); + let res = body_reader.read_body(&mut mock_io).await.unwrap().unwrap(); + assert_eq!(res, BufRef::new(0, 1)); + assert_eq!(body_reader.body_state, ParseState::HTTP1_0(3)); + assert_eq!(input1, body_reader.get_body(&res)); + let res = body_reader.read_body(&mut mock_io).await.unwrap(); + assert_eq!(res, None); + assert_eq!(body_reader.body_state, ParseState::Complete(3)); + } + + #[tokio::test] + async fn read_with_body_zero_chunk() { + init_log(); + let input = b"0\r\n\r\n"; + let mut mock_io = Builder::new().read(&input[..]).build(); + let mut body_reader = BodyReader::new(); + body_reader.init_chunked(b""); + let res = body_reader.read_body(&mut mock_io).await.unwrap(); + assert_eq!(res, None); + assert_eq!(body_reader.body_state, ParseState::Complete(0)); + } + + #[tokio::test] + async fn read_with_body_chunk_ext() { + init_log(); + let input = b"0;aaaa\r\n\r\n"; + let mut mock_io = Builder::new().read(&input[..]).build(); + let mut body_reader = BodyReader::new(); + body_reader.init_chunked(b""); + let res = body_reader.read_body(&mut mock_io).await.unwrap(); + assert_eq!(res, None); + assert_eq!(body_reader.body_state, ParseState::Complete(0)); + } + + #[tokio::test] + async fn read_with_body_chunk_ext_oversize() { + init_log(); + let chunk_size = b"0;"; + let ext1 = [b'a'; 1024 * 5]; + let ext2 = [b'a'; 1024 * 3]; + let mut mock_io = Builder::new() + .read(&chunk_size[..]) + .read(&ext1[..]) + .read(&ext2[..]) + .build(); + let mut body_reader = BodyReader::new(); + body_reader.init_chunked(b""); + // read chunk-size, chunk incomplete + let res = body_reader.read_body(&mut mock_io).await.unwrap(); + assert_eq!(res, Some(BufRef::new(0, 0))); + // read ext1, chunk incomplete + let res = body_reader.read_body(&mut mock_io).await.unwrap(); + assert_eq!(res, Some(BufRef::new(0, 0))); + // read ext2, now oversized + let res = body_reader.read_body(&mut mock_io).await; + assert!(res.is_err()); + assert_eq!(body_reader.body_state, ParseState::Done(0)); + } + + #[tokio::test] + async fn read_with_body_1_chunk() { + init_log(); + let input1 = b"1\r\na\r\n"; + let input2 = b"0\r\n\r\n"; + let mut mock_io = Builder::new().read(&input1[..]).read(&input2[..]).build(); + let mut body_reader = BodyReader::new(); + body_reader.init_chunked(b""); + let res = body_reader.read_body(&mut mock_io).await.unwrap().unwrap(); + assert_eq!(res, BufRef::new(3, 1)); + assert_eq!(&input1[3..4], body_reader.get_body(&res)); + assert_eq!(body_reader.body_state, ParseState::Chunked(1, 0, 0, 0)); + let res = body_reader.read_body(&mut mock_io).await.unwrap(); + assert_eq!(res, None); + assert_eq!(body_reader.body_state, ParseState::Complete(1)); + } + + #[tokio::test] + async fn read_with_body_1_chunk_rewind() { + init_log(); + let rewind = b"1\r\nx\r\n"; + let input1 = b"1\r\na\r\n"; + let input2 = b"0\r\n\r\n"; + let mut mock_io = Builder::new().read(&input1[..]).read(&input2[..]).build(); + let mut body_reader = BodyReader::new(); + body_reader.init_chunked(rewind); + let res = body_reader.read_body(&mut mock_io).await.unwrap().unwrap(); + assert_eq!(res, BufRef::new(3, 1)); + assert_eq!(&rewind[3..4], body_reader.get_body(&res)); + assert_eq!(body_reader.body_state, ParseState::Chunked(1, 0, 0, 0)); + let res = body_reader.read_body(&mut mock_io).await.unwrap().unwrap(); + assert_eq!(res, BufRef::new(3, 1)); + assert_eq!(&input1[3..4], body_reader.get_body(&res)); + assert_eq!(body_reader.body_state, ParseState::Chunked(2, 0, 0, 0)); + let res = body_reader.read_body(&mut mock_io).await.unwrap(); + assert_eq!(res, None); + assert_eq!(body_reader.body_state, ParseState::Complete(2)); + } + + #[tokio::test] + async fn read_with_body_multi_chunk() { + init_log(); + let input1 = b"1\r\na\r\n2\r\nbc\r\n"; + let input2 = b"0\r\n\r\n"; + let mut mock_io = Builder::new().read(&input1[..]).read(&input2[..]).build(); + let mut body_reader = BodyReader::new(); + body_reader.init_chunked(b""); + let res = body_reader.read_body(&mut mock_io).await.unwrap().unwrap(); + assert_eq!(res, BufRef::new(3, 1)); + assert_eq!(&input1[3..4], body_reader.get_body(&res)); + assert_eq!(body_reader.body_state, ParseState::Chunked(1, 6, 13, 0)); + let res = body_reader.read_body(&mut mock_io).await.unwrap().unwrap(); + assert_eq!(res, BufRef::new(9, 2)); + assert_eq!(&input1[9..11], body_reader.get_body(&res)); + assert_eq!(body_reader.body_state, ParseState::Chunked(3, 0, 0, 0)); + let res = body_reader.read_body(&mut mock_io).await.unwrap(); + assert_eq!(res, None); + assert_eq!(body_reader.body_state, ParseState::Complete(3)); + } + + #[tokio::test] + async fn read_with_body_partial_chunk() { + init_log(); + let input1 = b"3\r\na"; + let input2 = b"bc\r\n0\r\n\r\n"; + let mut mock_io = Builder::new().read(&input1[..]).read(&input2[..]).build(); + let mut body_reader = BodyReader::new(); + body_reader.init_chunked(b""); + let res = body_reader.read_body(&mut mock_io).await.unwrap().unwrap(); + assert_eq!(res, BufRef::new(3, 1)); + assert_eq!(&input1[3..4], body_reader.get_body(&res)); + assert_eq!(body_reader.body_state, ParseState::Chunked(1, 0, 0, 4)); + let res = body_reader.read_body(&mut mock_io).await.unwrap().unwrap(); + assert_eq!(res, BufRef::new(0, 2)); + assert_eq!(&input2[0..2], body_reader.get_body(&res)); + assert_eq!(body_reader.body_state, ParseState::Chunked(3, 4, 9, 0)); + let res = body_reader.read_body(&mut mock_io).await.unwrap(); + assert_eq!(res, None); + assert_eq!(body_reader.body_state, ParseState::Complete(3)); + } + + #[tokio::test] + async fn read_with_body_partial_head_chunk() { + init_log(); + let input1 = b"1\r"; + let input2 = b"\na\r\n0\r\n\r\n"; + let mut mock_io = Builder::new().read(&input1[..]).read(&input2[..]).build(); + let mut body_reader = BodyReader::new(); + body_reader.init_chunked(b""); + let res = body_reader.read_body(&mut mock_io).await.unwrap().unwrap(); + assert_eq!(res, BufRef::new(0, 0)); + assert_eq!(body_reader.body_state, ParseState::Chunked(0, 0, 2, 2)); + let res = body_reader.read_body(&mut mock_io).await.unwrap().unwrap(); + assert_eq!(res, BufRef::new(3, 1)); // input1 concat input2 + assert_eq!(&input2[1..2], body_reader.get_body(&res)); + assert_eq!(body_reader.body_state, ParseState::Chunked(1, 6, 11, 0)); + let res = body_reader.read_body(&mut mock_io).await.unwrap(); + assert_eq!(res, None); + assert_eq!(body_reader.body_state, ParseState::Complete(1)); + } + + #[tokio::test] + async fn write_body_cl() { + init_log(); + let output = b"a"; + let mut mock_io = Builder::new().write(&output[..]).build(); + let mut body_writer = BodyWriter::new(); + body_writer.init_content_length(1); + assert_eq!(body_writer.body_mode, BodyMode::ContentLength(1, 0)); + let res = body_writer + .write_body(&mut mock_io, &output[..]) + .await + .unwrap() + .unwrap(); + assert_eq!(res, 1); + assert_eq!(body_writer.body_mode, BodyMode::ContentLength(1, 1)); + // write again, over the limit + let res = body_writer + .write_body(&mut mock_io, &output[..]) + .await + .unwrap(); + assert_eq!(res, None); + assert_eq!(body_writer.body_mode, BodyMode::ContentLength(1, 1)); + let res = body_writer.finish(&mut mock_io).await.unwrap().unwrap(); + assert_eq!(res, 1); + assert_eq!(body_writer.body_mode, BodyMode::Complete(1)); + } + + #[tokio::test] + async fn write_body_chunked() { + init_log(); + let data = b"abcdefghij"; + let output = b"A\r\nabcdefghij\r\n"; + let mut mock_io = Builder::new() + .write(&output[..]) + .write(&output[..]) + .write(&LAST_CHUNK[..]) + .build(); + let mut body_writer = BodyWriter::new(); + body_writer.init_chunked(); + assert_eq!(body_writer.body_mode, BodyMode::ChunkedEncoding(0)); + let res = body_writer + .write_body(&mut mock_io, &data[..]) + .await + .unwrap() + .unwrap(); + assert_eq!(res, data.len()); + assert_eq!(body_writer.body_mode, BodyMode::ChunkedEncoding(data.len())); + let res = body_writer + .write_body(&mut mock_io, &data[..]) + .await + .unwrap() + .unwrap(); + assert_eq!(res, data.len()); + assert_eq!( + body_writer.body_mode, + BodyMode::ChunkedEncoding(data.len() * 2) + ); + let res = body_writer.finish(&mut mock_io).await.unwrap().unwrap(); + assert_eq!(res, data.len() * 2); + assert_eq!(body_writer.body_mode, BodyMode::Complete(data.len() * 2)); + } + + #[tokio::test] + async fn write_body_http10() { + init_log(); + let data = b"a"; + let mut mock_io = Builder::new().write(&data[..]).write(&data[..]).build(); + let mut body_writer = BodyWriter::new(); + body_writer.init_http10(); + assert_eq!(body_writer.body_mode, BodyMode::HTTP1_0(0)); + let res = body_writer + .write_body(&mut mock_io, &data[..]) + .await + .unwrap() + .unwrap(); + assert_eq!(res, 1); + assert_eq!(body_writer.body_mode, BodyMode::HTTP1_0(1)); + let res = body_writer + .write_body(&mut mock_io, &data[..]) + .await + .unwrap() + .unwrap(); + assert_eq!(res, 1); + assert_eq!(body_writer.body_mode, BodyMode::HTTP1_0(2)); + let res = body_writer.finish(&mut mock_io).await.unwrap().unwrap(); + assert_eq!(res, 2); + assert_eq!(body_writer.body_mode, BodyMode::Complete(2)); + } +} diff --git a/pingora-core/src/protocols/http/v1/client.rs b/pingora-core/src/protocols/http/v1/client.rs new file mode 100644 index 0000000..1d970d7 --- /dev/null +++ b/pingora-core/src/protocols/http/v1/client.rs @@ -0,0 +1,1085 @@ +// 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. + +//! HTTP/1.x client session + +use bytes::{BufMut, Bytes, BytesMut}; +use http::{header, header::AsHeaderName, HeaderValue, StatusCode, Version}; +use log::{debug, trace}; +use pingora_error::{Error, ErrorType::*, OrErr, Result, RetryType}; +use pingora_http::{HMap, IntoCaseHeaderName, RequestHeader, ResponseHeader}; +use pingora_timeout::timeout; +use std::io::ErrorKind; +use std::str; +use std::time::Duration; +use tokio::io::{AsyncReadExt, AsyncWriteExt}; + +use super::body::{BodyReader, BodyWriter}; +use super::common::*; +use crate::protocols::http::HttpTask; +use crate::protocols::{Digest, Stream, UniqueID}; +use crate::utils::{BufRef, KVRef}; + +/// The HTTP 1.x client session +pub struct HttpSession { + buf: Bytes, + pub(crate) underlying_stream: Stream, + raw_header: Option, + preread_body: Option, + body_reader: BodyReader, + body_writer: BodyWriter, + // timeouts: + /// The read timeout, which will be applied to both reading the header and the body. + /// The timeout is reset on every read. This is not a timeout on the overall duration of the + /// response. + pub read_timeout: Option, + /// The write timeout which will be applied to both writing request header and body. + /// The timeout is reset on every write. This is not a timeout on the overall duration of the + /// request. + pub write_timeout: Option, + keepalive_timeout: KeepaliveStatus, + pub(crate) digest: Box, + response_header: Option>, + request_written: Option>, + bytes_sent: usize, + upgraded: bool, +} + +/// HTTP 1.x client session +impl HttpSession { + /// Create a new http client session from an established (TCP or TLS) [`Stream`]. + pub fn new(stream: Stream) -> Self { + // TODO: maybe we should put digest in the connection itself + let digest = Box::new(Digest { + ssl_digest: stream.get_ssl_digest(), + timing_digest: stream.get_timing_digest(), + proxy_digest: stream.get_proxy_digest(), + }); + HttpSession { + underlying_stream: stream, + buf: Bytes::new(), // zero size, will be replaced by parsed header later + raw_header: None, + preread_body: None, + body_reader: BodyReader::new(), + body_writer: BodyWriter::new(), + keepalive_timeout: KeepaliveStatus::Off, + response_header: None, + request_written: None, + read_timeout: None, + write_timeout: None, + digest, + bytes_sent: 0, + upgraded: false, + } + } + /// Write the request header to the server + /// After the request header is sent. The caller can either start reading the response or + /// sending request body if any. + pub async fn write_request_header(&mut self, req: Box) -> Result { + // TODO: make sure this can only be called once + // init body writer + self.init_req_body_writer(&req); + + let to_wire = http_req_header_to_wire(&req).unwrap(); + trace!("Writing request header: {to_wire:?}"); + + let write_fut = self.underlying_stream.write_all(to_wire.as_ref()); + match self.write_timeout { + Some(t) => match timeout(t, write_fut).await { + Ok(res) => res, + Err(_) => Err(std::io::Error::from(ErrorKind::TimedOut)), + }, + None => write_fut.await, + } + .map_err(|e| match e.kind() { + ErrorKind::TimedOut => { + Error::because(WriteTimedout, "while writing request headers (timeout)", e) + } + _ => Error::because(WriteError, "while writing request headers", e), + })?; + + self.underlying_stream + .flush() + .await + .or_err(WriteError, "flushing request header")?; + + // write was successful + self.request_written = Some(req); + Ok(to_wire.len()) + } + + async fn do_write_body(&mut self, buf: &[u8]) -> Result> { + let written = self + .body_writer + .write_body(&mut self.underlying_stream, buf) + .await; + + if let Ok(Some(num_bytes)) = written { + self.bytes_sent += num_bytes; + } + + written + } + + /// Write request body. Return Ok(None) if no more body should be written, either due to + /// Content-Length or the last chunk is already sent + pub async fn write_body(&mut self, buf: &[u8]) -> Result> { + // TODO: verify that request header is sent already + match self.write_timeout { + Some(t) => match timeout(t, self.do_write_body(buf)).await { + Ok(res) => res, + Err(_) => Error::e_explain(WriteTimedout, format!("writing body, timeout: {t:?}")), + }, + None => self.do_write_body(buf).await, + } + } + + fn maybe_force_close_body_reader(&mut self) { + if self.upgraded && !self.body_reader.body_done() { + // request is done, reset the response body to close + self.body_reader.init_content_length(0, b""); + } + } + + /// Flush local buffer and notify the server by sending the last chunk if chunked encoding is + /// used. + pub async fn finish_body(&mut self) -> Result> { + let res = self.body_writer.finish(&mut self.underlying_stream).await?; + self.underlying_stream + .flush() + .await + .or_err(WriteError, "flushing body")?; + + self.maybe_force_close_body_reader(); + Ok(res) + } + + /// Read the response header from the server + /// This function can be called multiple times, if the headers received are just informational + /// headers. + pub async fn read_response(&mut self) -> Result { + self.buf.clear(); + let mut buf = BytesMut::with_capacity(INIT_HEADER_BUF_SIZE); + let mut already_read: usize = 0; + loop { + if already_read > MAX_HEADER_SIZE { + /* NOTE: this check only blocks second read. The first large read is allowed + since the buf is already allocated. The goal is to avoid slowly bloating + this buffer */ + return Error::e_explain( + InvalidHTTPHeader, + format!("Response header larger than {MAX_HEADER_SIZE}"), + ); + } + + let read_fut = self.underlying_stream.read_buf(&mut buf); + let read_result = match self.read_timeout { + Some(t) => match timeout(t, read_fut).await { + Ok(res) => res, + Err(_) => Err(std::io::Error::from(ErrorKind::TimedOut)), + }, + None => read_fut.await, + }; + let n = match read_result { + Ok(n) => match n { + 0 => { + let mut e = Error::explain( + ConnectionClosed, + format!( + "while reading response headers, bytes already read: {already_read}", + ), + ); + e.retry = RetryType::ReusedOnly; + return Err(e); + } + _ => { + n /* read n bytes, continue */ + } + }, + Err(e) => { + return match e.kind() { + ErrorKind::TimedOut => { + Error::e_explain(ReadTimedout, "while reading response headers") + } + _ => { + let true_io_error = e.raw_os_error().is_some(); + let mut e = Error::because( + ReadError, + format!( + "while reading response headers, bytes already read: {already_read}", + ), + e, + ); + // Likely OSError, typical if a previously reused connection drops it + if true_io_error { + e.retry = RetryType::ReusedOnly; + } // else: not safe to retry TLS error + Err(e) + } + }; + } + }; + already_read += n; + let mut headers = [httparse::EMPTY_HEADER; MAX_HEADERS]; + let mut resp = httparse::Response::new(&mut headers); + let parsed = parse_resp_buffer(&mut resp, &buf); + match parsed { + HeaderParseState::Complete(s) => { + self.raw_header = Some(BufRef(0, s)); + self.preread_body = Some(BufRef(s, already_read)); + let base = buf.as_ptr() as usize; + let mut header_refs = Vec::::with_capacity(resp.headers.len()); + + // Note: resp.headers has the correct number of headers + // while header_refs doesn't as it is still empty + let _num_headers = populate_headers(base, &mut header_refs, resp.headers); + + let mut response_header = Box::new(ResponseHeader::build( + resp.code.unwrap(), + Some(resp.headers.len()), + )?); + + response_header.set_version(match resp.version { + Some(1) => Version::HTTP_11, + Some(0) => Version::HTTP_10, + _ => Version::HTTP_09, + }); + + let buf = buf.freeze(); + + for header in header_refs { + let header_name = header.get_name_bytes(&buf); + let header_name = header_name.into_case_header_name(); + let value_bytes = header.get_value_bytes(&buf); + let header_value = if cfg!(debug_assertions) { + // from_maybe_shared_unchecked() in debug mode still checks whether + // the header value is valid, which breaks the _obsolete_multiline + // support. To work around this, in debug mode, we replace CRLF with + // whitespace + if let Some(p) = value_bytes.windows(CRLF.len()).position(|w| w == CRLF) + { + let mut new_header = Vec::from_iter(value_bytes); + new_header[p] = b' '; + new_header[p + 1] = b' '; + unsafe { + http::HeaderValue::from_maybe_shared_unchecked(new_header) + } + } else { + unsafe { + http::HeaderValue::from_maybe_shared_unchecked(value_bytes) + } + } + } else { + // safe because this is from what we parsed + unsafe { http::HeaderValue::from_maybe_shared_unchecked(value_bytes) } + }; + response_header + .append_header(header_name, header_value) + .or_err(InvalidHTTPHeader, "while parsing request header")?; + } + + self.buf = buf; + self.upgraded = self.is_upgrade(&response_header).unwrap_or(false); + self.response_header = Some(response_header); + return Ok(s); + } + HeaderParseState::Partial => { /* continue the loop */ } + HeaderParseState::Invalid(e) => { + return Error::e_because( + InvalidHTTPHeader, + format!("buf: {:?}", String::from_utf8_lossy(&buf)), + e, + ) + } + } + } + } + + /// Similar to [`Self::read_response()`], read the response header and then return a copy of it. + pub async fn read_resp_header_parts(&mut self) -> Result> { + self.read_response().await?; + // safe to unwrap because it is just read + Ok(Box::new(self.resp_header().unwrap().clone())) + } + + /// Return a reference of the [`ResponseHeader`] if the response is read + pub fn resp_header(&self) -> Option<&ResponseHeader> { + self.response_header.as_deref() + } + + /// Get the header value for the given header name from the response header + /// If there are multiple headers under the same name, the first one will be returned + /// Use `self.resp_header().header.get_all(name)` to get all the headers under the same name + /// Always return `None` if the response is not read yet. + pub fn get_header(&self, name: impl AsHeaderName) -> Option<&HeaderValue> { + self.response_header + .as_ref() + .and_then(|h| h.headers.get(name)) + } + + /// Get the request header as raw bytes, `b""` when the header doesn't exist or response not read + pub fn get_header_bytes(&self, name: impl AsHeaderName) -> &[u8] { + self.get_header(name).map_or(b"", |v| v.as_bytes()) + } + + /// Return the status code of the response if read + pub fn get_status(&self) -> Option { + self.response_header.as_ref().map(|h| h.status) + } + + async fn do_read_body(&mut self) -> Result> { + self.init_body_reader(); + self.body_reader + .read_body(&mut self.underlying_stream) + .await + } + + /// Read the response body into the internal buffer. + /// Return `Ok(Some(ref)) after a successful read. + /// Return `Ok(None)` if there is no more body to read. + pub async fn read_body_ref(&mut self) -> Result> { + let result = match self.read_timeout { + Some(t) => match timeout(t, self.do_read_body()).await { + Ok(res) => res, + Err(_) => Error::e_explain(ReadTimedout, format!("reading body, timeout: {t:?}")), + }, + None => self.do_read_body().await, + }; + + result.map(|maybe_body| maybe_body.map(|body_ref| self.body_reader.get_body(&body_ref))) + } + + /// Similar to [`Self::read_body_ref`] but return `Bytes` instead of a slice reference. + pub async fn read_body_bytes(&mut self) -> Result> { + let read = self.read_body_ref().await?; + Ok(read.map(Bytes::copy_from_slice)) + } + + /// Whether there is no more body to read. + pub fn is_body_done(&mut self) -> bool { + self.init_body_reader(); + self.body_reader.body_done() + } + + pub(super) fn get_headers_raw(&self) -> &[u8] { + // TODO: these get_*() could panic. handle them better + self.raw_header.as_ref().unwrap().get(&self.buf[..]) + } + + /// Get the raw response header bytes + pub fn get_headers_raw_bytes(&self) -> Bytes { + self.raw_header.as_ref().unwrap().get_bytes(&self.buf) + } + + fn set_keepalive(&mut self, seconds: Option) { + match seconds { + Some(sec) => { + if sec > 0 { + self.keepalive_timeout = KeepaliveStatus::Timeout(Duration::from_secs(sec)); + } else { + self.keepalive_timeout = KeepaliveStatus::Infinite; + } + } + None => { + self.keepalive_timeout = KeepaliveStatus::Off; + } + } + } + + /// Apply keepalive settings according to the server's response + /// For HTTP 1.1, assume keepalive as long as there is no `Connection: Close` request header. + /// For HTTP 1.0, only keepalive if there is an explicit header `Connection: keep-alive`. + pub fn respect_keepalive(&mut self) { + if self.get_status() == Some(StatusCode::SWITCHING_PROTOCOLS) { + // make sure the connection is closed at the end when 101/upgrade is used + self.set_keepalive(None); + return; + } + if let Some(keepalive) = self.is_connection_keepalive() { + if keepalive { + let (timeout, _max_use) = self.get_keepalive_values(); + // TODO: respect max_use + match timeout { + Some(d) => self.set_keepalive(Some(d)), + None => self.set_keepalive(Some(0)), // infinite + } + } else { + self.set_keepalive(None); + } + } else if self.resp_header().map(|h| h.version) == Some(Version::HTTP_11) { + self.set_keepalive(Some(0)); // on by default for http 1.1 + } else { + self.set_keepalive(None); // off by default for http 1.0 + } + } + + // Whether this session will be kept alive + pub fn will_keepalive(&self) -> bool { + // TODO: check self.body_writer. If it is http1.0 type then keepalive + // cannot be used because the connection close is the signal of end body + !matches!(self.keepalive_timeout, KeepaliveStatus::Off) + } + + fn is_connection_keepalive(&self) -> Option { + is_buf_keepalive(self.get_header(header::CONNECTION).map(|v| v.as_bytes())) + } + + // `Keep-Alive: timeout=5, max=1000` => 5, 1000 + fn get_keepalive_values(&self) -> (Option, Option) { + // TODO: implement this parsing + (None, None) + } + + /// Close the connection abruptly. This allows to signal the server that the connection is closed + /// before dropping [`HttpSession`] + pub async fn shutdown(&mut self) { + let _ = self.underlying_stream.shutdown().await; + } + + /// Consume `self`, if the connection can be reused, the underlying stream will be returned. + /// The returned connection can be kept in a connection pool so that next time the same + /// server is being contacted. A new client session can be created via [`Self::new()`]. + /// If the connection cannot be reused, the underlying stream will be closed and `None` will be + /// returned. + pub async fn reuse(mut self) -> Option { + // TODO: this function is unnecessarily slow for keepalive case + // because that case does not need async + match self.keepalive_timeout { + KeepaliveStatus::Off => { + debug!("HTTP shutdown connection"); + self.shutdown().await; + None + } + _ => Some(self.underlying_stream), + } + } + + fn init_body_reader(&mut self) { + if self.body_reader.need_init() { + /* follow https://tools.ietf.org/html/rfc7230#section-3.3.3 */ + let preread_body = self.preread_body.as_ref().unwrap().get(&self.buf[..]); + + if let Some(req) = self.request_written.as_ref() { + if req.method == http::method::Method::HEAD { + self.body_reader.init_content_length(0, preread_body); + return; + } + } + + let upgraded = if let Some(code) = self.get_status() { + match code.as_u16() { + 101 => self.is_upgrade_req(), + 100..=199 => { + // informational headers, not enough to init body reader + return; + } + 204 | 304 => { + // no body by definition + self.body_reader.init_content_length(0, preread_body); + return; + } + _ => false, + } + } else { + false + }; + + if upgraded { + self.body_reader.init_http10(preread_body); + } else if self.is_chunked_encoding() { + // if chunked encoding, content-length should be ignored + self.body_reader.init_chunked(preread_body); + } else if let Some(cl) = self.get_content_length() { + self.body_reader.init_content_length(cl, preread_body); + } else { + self.body_reader.init_http10(preread_body); + } + } + } + + /// Whether this request is for upgrade + pub fn is_upgrade_req(&self) -> bool { + match self.request_written.as_deref() { + Some(req) => is_upgrade_req(req), + None => false, + } + } + + /// `Some(true)` if the this is a successful upgrade + /// `Some(false)` if the request is an upgrade but the response refuses it + /// `None` if the request is not an upgrade. + fn is_upgrade(&self, header: &ResponseHeader) -> Option { + if self.is_upgrade_req() { + Some(is_upgrade_resp(header)) + } else { + None + } + } + + fn get_content_length(&self) -> Option { + buf_to_content_length( + self.get_header(header::CONTENT_LENGTH) + .map(|v| v.as_bytes()), + ) + } + + fn is_chunked_encoding(&self) -> bool { + is_header_value_chunked_encoding(self.get_header(header::TRANSFER_ENCODING)) + } + + fn init_req_body_writer(&mut self, header: &RequestHeader) { + if self.is_upgrade_req() { + self.body_writer.init_http10(); + } else { + self.init_body_writer_comm(&header.headers) + } + } + + fn init_body_writer_comm(&mut self, headers: &HMap) { + let te_value = headers.get(http::header::TRANSFER_ENCODING); + if is_header_value_chunked_encoding(te_value) { + // transfer-encoding takes priority over content-length + self.body_writer.init_chunked(); + } else { + let content_length = + header_value_content_length(headers.get(http::header::CONTENT_LENGTH)); + match content_length { + Some(length) => { + self.body_writer.init_content_length(length); + } + None => { + /* TODO: 1. connection: keepalive cannot be used, + 2. mark connection must be closed */ + self.body_writer.init_http10(); + } + } + } + } + + // should (continue to) try to read response header or start reading response body + fn should_read_resp_header(&self) -> bool { + match self.get_status().map(|s| s.as_u16()) { + Some(101) => false, // switching protocol successful, no more header to read + Some(100..=199) => true, // only informational header read + Some(_) => false, + None => true, // no response code, no header read yet + } + } + + pub async fn read_response_task(&mut self) -> Result { + if self.should_read_resp_header() { + let resp_header = self.read_resp_header_parts().await?; + let end_of_body = self.is_body_done(); + debug!("Response header: {:?}", resp_header); + trace!( + "Raw Response header: {:?}", + str::from_utf8(self.get_headers_raw()).unwrap() + ); + Ok(HttpTask::Header(resp_header, end_of_body)) + } else if self.is_body_done() { + debug!("Response is done"); + Ok(HttpTask::Done) + } else { + /* need to read body */ + let data = self.read_body_bytes().await?; + let end_of_body = self.is_body_done(); + if let Some(body) = data { + debug!("Response body: {} bytes", body.len()); + trace!("Response body: {:?}", body); + Ok(HttpTask::Body(Some(body), end_of_body)) + } else { + debug!("Response is done"); + Ok(HttpTask::Done) + } + } + // TODO: support h1 trailer + } + + pub fn digest(&self) -> &Digest { + &self.digest + } +} + +#[inline] +fn parse_resp_buffer<'buf>( + resp: &mut httparse::Response<'_, 'buf>, + buf: &'buf [u8], +) -> HeaderParseState { + let mut parser = httparse::ParserConfig::default(); + parser.allow_spaces_after_header_name_in_responses(true); + parser.allow_obsolete_multiline_headers_in_responses(true); + let res = match parser.parse_response(resp, buf) { + Ok(s) => s, + Err(e) => { + return HeaderParseState::Invalid(e); + } + }; + match res { + httparse::Status::Complete(s) => HeaderParseState::Complete(s), + _ => HeaderParseState::Partial, + } +} + +// TODO: change it to to_buf +#[inline] +pub(crate) fn http_req_header_to_wire(req: &RequestHeader) -> Option { + let mut buf = BytesMut::with_capacity(512); + + // Request-Line + let method = req.method.as_str().as_bytes(); + buf.put_slice(method); + buf.put_u8(b' '); + buf.put_slice(req.raw_path()); + buf.put_u8(b' '); + + let version = match req.version { + Version::HTTP_09 => "HTTP/0.9", + Version::HTTP_10 => "HTTP/1.0", + Version::HTTP_11 => "HTTP/1.1", + Version::HTTP_2 => "HTTP/2", + _ => { + return None; /*TODO: unsupported version */ + } + }; + buf.put_slice(version.as_bytes()); + buf.put_slice(CRLF); + + // headers + req.header_to_h1_wire(&mut buf); + buf.put_slice(CRLF); + Some(buf) +} + +impl UniqueID for HttpSession { + fn id(&self) -> i32 { + self.underlying_stream.id() + } +} + +#[cfg(test)] +mod tests_stream { + use super::*; + use crate::protocols::http::v1::body::ParseState; + use crate::ErrorType; + use std::str; + use std::time::Duration; + use tokio_test::io::Builder; + + fn init_log() { + let _ = env_logger::builder().is_test(true).try_init(); + } + + #[tokio::test] + async fn read_basic_response() { + init_log(); + let input = b"HTTP/1.1 200 OK\r\n\r\n"; + let mock_io = Builder::new().read(&input[..]).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + let res = http_stream.read_response().await; + assert_eq!(input.len(), res.unwrap()); + assert_eq!(0, http_stream.resp_header().unwrap().headers.len()); + } + + #[tokio::test] + async fn read_response_default() { + init_log(); + let input_header = b"HTTP/1.1 200 OK\r\n\r\n"; + let input_body = b"abc"; + let input_close = b""; // simulating close + let mock_io = Builder::new() + .read(&input_header[..]) + .read(&input_body[..]) + .read(&input_close[..]) + .build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + let res = http_stream.read_response().await; + assert_eq!(input_header.len(), res.unwrap()); + let res = http_stream.read_body_ref().await.unwrap(); + assert_eq!(res.unwrap(), input_body); + assert_eq!(http_stream.body_reader.body_state, ParseState::HTTP1_0(3)); + let res = http_stream.read_body_ref().await.unwrap(); + assert_eq!(res, None); + assert_eq!(http_stream.body_reader.body_state, ParseState::Complete(3)); + } + + #[tokio::test] + async fn read_resp_header_with_space() { + init_log(); + let input = b"HTTP/1.1 200 OK\r\nServer : pingora\r\n\r\n"; + let mock_io = Builder::new().read(&input[..]).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + let res = http_stream.read_response().await; + assert_eq!(input.len(), res.unwrap()); + assert_eq!(1, http_stream.resp_header().unwrap().headers.len()); + assert_eq!(http_stream.get_header("Server").unwrap(), "pingora"); + } + + #[cfg(feature = "patched_http1")] + #[tokio::test] + async fn read_resp_header_with_utf8() { + init_log(); + let input = "HTTP/1.1 200 OK\r\nServer👍: pingora\r\n\r\n".as_bytes(); + let mock_io = Builder::new().read(input).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + let resp = http_stream.read_resp_header_parts().await.unwrap(); + assert_eq!(1, http_stream.resp_header().unwrap().headers.len()); + assert_eq!(http_stream.get_header("Server👍").unwrap(), "pingora"); + assert_eq!(resp.headers.get("Server👍").unwrap(), "pingora"); + } + + #[tokio::test] + #[should_panic(expected = "There is still data left to read.")] + async fn read_timeout() { + init_log(); + let input = b"HTTP/1.1 200 OK\r\n\r\n"; + let mock_io = Builder::new() + .wait(Duration::from_secs(2)) + .read(&input[..]) + .build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + http_stream.read_timeout = Some(Duration::from_secs(1)); + let res = http_stream.read_response().await; + assert_eq!(res.unwrap_err().etype(), &ErrorType::ReadTimedout); + } + + #[tokio::test] + async fn read_2_buf() { + init_log(); + let input1 = b"HTTP/1.1 200 OK\r\n"; + let input2 = b"Server: pingora\r\n\r\n"; + let mock_io = Builder::new().read(&input1[..]).read(&input2[..]).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + let res = http_stream.read_response().await; + assert_eq!(input1.len() + input2.len(), res.unwrap()); + assert_eq!( + input1.len() + input2.len(), + http_stream.get_headers_raw().len() + ); + assert_eq!(1, http_stream.resp_header().unwrap().headers.len()); + assert_eq!(http_stream.get_header("Server").unwrap(), "pingora"); + + assert_eq!(Some(StatusCode::OK), http_stream.get_status()); + assert_eq!(Version::HTTP_11, http_stream.resp_header().unwrap().version); + } + + #[tokio::test] + #[should_panic(expected = "There is still data left to read.")] + async fn read_invalid() { + let input1 = b"HTP/1.1 200 OK\r\n"; + let input2 = b"Server: pingora\r\n\r\n"; + let mock_io = Builder::new().read(&input1[..]).read(&input2[..]).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + let res = http_stream.read_response().await; + assert_eq!(&ErrorType::InvalidHTTPHeader, res.unwrap_err().etype()); + } + + #[tokio::test] + async fn write() { + let wire = b"GET /test HTTP/1.1\r\nFoo: Bar\r\n\r\n"; + let mock_io = Builder::new().write(wire).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + let mut new_request = RequestHeader::build("GET", b"/test", None).unwrap(); + new_request.insert_header("Foo", "Bar").unwrap(); + let n = http_stream + .write_request_header(Box::new(new_request)) + .await + .unwrap(); + assert_eq!(wire.len(), n); + } + + #[tokio::test] + #[should_panic(expected = "There is still data left to write.")] + async fn write_timeout() { + let wire = b"GET /test HTTP/1.1\r\nFoo: Bar\r\n\r\n"; + let mock_io = Builder::new() + .wait(Duration::from_secs(2)) + .write(wire) + .build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + http_stream.write_timeout = Some(Duration::from_secs(1)); + let mut new_request = RequestHeader::build("GET", b"/test", None).unwrap(); + new_request.insert_header("Foo", "Bar").unwrap(); + let res = http_stream + .write_request_header(Box::new(new_request)) + .await; + assert_eq!(res.unwrap_err().etype(), &ErrorType::WriteTimedout); + } + + #[tokio::test] + #[should_panic(expected = "There is still data left to write.")] + async fn write_body_timeout() { + let header = b"POST /test HTTP/1.1\r\n\r\n"; + let body = b"abc"; + let mock_io = Builder::new() + .write(&header[..]) + .wait(Duration::from_secs(2)) + .write(&body[..]) + .build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + http_stream.write_timeout = Some(Duration::from_secs(1)); + + let new_request = RequestHeader::build("POST", b"/test", None).unwrap(); + http_stream + .write_request_header(Box::new(new_request)) + .await + .unwrap(); + let res = http_stream.write_body(body).await; + assert_eq!(res.unwrap_err().etype(), &WriteTimedout); + } + + #[cfg(feature = "patched_http1")] + #[tokio::test] + async fn write_invalid_path() { + let wire = b"GET /\x01\xF0\x90\x80 HTTP/1.1\r\nFoo: Bar\r\n\r\n"; + let mock_io = Builder::new().write(wire).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + let mut new_request = RequestHeader::build("GET", b"/\x01\xF0\x90\x80", None).unwrap(); + new_request.insert_header("Foo", "Bar").unwrap(); + let n = http_stream + .write_request_header(Box::new(new_request)) + .await + .unwrap(); + assert_eq!(wire.len(), n); + } + + #[tokio::test] + async fn read_informational() { + init_log(); + let input1 = b"HTTP/1.1 100 Continue\r\n\r\n"; + let input2 = b"HTTP/1.1 204 OK\r\nServer: pingora\r\n\r\n"; + let mock_io = Builder::new().read(&input1[..]).read(&input2[..]).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + + // read 100 header first + let task = http_stream.read_response_task().await.unwrap(); + match task { + HttpTask::Header(h, eob) => { + assert_eq!(h.status, 100); + assert!(!eob); + } + _ => { + panic!("task should be header") + } + } + // read 200 header next + let task = http_stream.read_response_task().await.unwrap(); + match task { + HttpTask::Header(h, eob) => { + assert_eq!(h.status, 204); + assert!(eob); + } + _ => { + panic!("task should be header") + } + } + } + + #[tokio::test] + async fn read_switching_protocol() { + init_log(); + let input1 = b"HTTP/1.1 101 Continue\r\n\r\n"; + let input2 = b"PAYLOAD"; + let mock_io = Builder::new().read(&input1[..]).read(&input2[..]).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + + // read 100 header first + let task = http_stream.read_response_task().await.unwrap(); + match task { + HttpTask::Header(h, eob) => { + assert_eq!(h.status, 101); + assert!(!eob); + } + _ => { + panic!("task should be header") + } + } + // read body + let task = http_stream.read_response_task().await.unwrap(); + match task { + HttpTask::Body(b, eob) => { + assert_eq!(b.unwrap(), &input2[..]); + assert!(!eob); + } + _ => { + panic!("task should be body") + } + } + // read body + let task = http_stream.read_response_task().await.unwrap(); + match task { + HttpTask::Done => {} + _ => { + panic!("task should be Done") + } + } + } + + // Note: in debug mode, due to from_maybe_shared_unchecked() still tries to validate headers + // values, so the code has to replace CRLF with whitespaces. In release mode, the CRLF is + // reserved + #[tokio::test] + async fn read_obsolete_multiline_headers() { + init_log(); + let input = b"HTTP/1.1 200 OK\r\nServer : pingora\r\n Foo: Bar\r\n\r\n"; + let mock_io = Builder::new().read(&input[..]).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + let res = http_stream.read_response().await; + assert_eq!(input.len(), res.unwrap()); + + assert_eq!(1, http_stream.resp_header().unwrap().headers.len()); + assert_eq!( + http_stream.get_header("Server").unwrap(), + "pingora Foo: Bar" + ); + + let input = b"HTTP/1.1 200 OK\r\nServer : pingora\r\n\t Fizz: Buzz\r\n\r\n"; + let mock_io = Builder::new().read(&input[..]).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + let res = http_stream.read_response().await; + assert_eq!(input.len(), res.unwrap()); + assert_eq!(1, http_stream.resp_header().unwrap().headers.len()); + assert_eq!( + http_stream.get_header("Server").unwrap(), + "pingora \t Fizz: Buzz" + ); + } + + #[cfg(feature = "patched_http1")] + #[tokio::test] + async fn read_headers_skip_invalid_line() { + init_log(); + let input = b"HTTP/1.1 200 OK\r\n;\r\nFoo: Bar\r\n\r\n"; + let mock_io = Builder::new().read(&input[..]).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + let res = http_stream.read_response().await; + assert_eq!(input.len(), res.unwrap()); + assert_eq!(1, http_stream.resp_header().unwrap().headers.len()); + assert_eq!(http_stream.get_header("Foo").unwrap(), "Bar"); + } + + #[tokio::test] + async fn read_keepalive_headers() { + init_log(); + + async fn build_resp_with_keepalive(conn: &str) -> HttpSession { + let input = format!("HTTP/1.1 200 OK\r\nConnection: {conn}\r\n\r\n"); + let mock_io = Builder::new().read(input.as_bytes()).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + let res = http_stream.read_response().await; + assert_eq!(input.len(), res.unwrap()); + http_stream.respect_keepalive(); + http_stream + } + + assert_eq!( + build_resp_with_keepalive("close").await.keepalive_timeout, + KeepaliveStatus::Off + ); + + assert_eq!( + build_resp_with_keepalive("keep-alive") + .await + .keepalive_timeout, + KeepaliveStatus::Infinite + ); + + assert_eq!( + build_resp_with_keepalive("foo").await.keepalive_timeout, + KeepaliveStatus::Infinite + ); + + assert_eq!( + build_resp_with_keepalive("upgrade,close") + .await + .keepalive_timeout, + KeepaliveStatus::Off + ); + + assert_eq!( + build_resp_with_keepalive("upgrade, close") + .await + .keepalive_timeout, + KeepaliveStatus::Off + ); + + assert_eq!( + build_resp_with_keepalive("Upgrade, close") + .await + .keepalive_timeout, + KeepaliveStatus::Off + ); + + assert_eq!( + build_resp_with_keepalive("Upgrade,close") + .await + .keepalive_timeout, + KeepaliveStatus::Off + ); + + assert_eq!( + build_resp_with_keepalive("close,upgrade") + .await + .keepalive_timeout, + KeepaliveStatus::Off + ); + + assert_eq!( + build_resp_with_keepalive("close, upgrade") + .await + .keepalive_timeout, + KeepaliveStatus::Off + ); + + assert_eq!( + build_resp_with_keepalive("close,Upgrade") + .await + .keepalive_timeout, + KeepaliveStatus::Off + ); + + assert_eq!( + build_resp_with_keepalive("close, Upgrade") + .await + .keepalive_timeout, + KeepaliveStatus::Off + ); + } + + /* Note: body tests are covered in server.rs */ +} + +#[cfg(test)] +mod test_sync { + use super::*; + use log::error; + + #[test] + fn test_request_to_wire() { + let mut new_request = RequestHeader::build("GET", b"/", None).unwrap(); + new_request.insert_header("Foo", "Bar").unwrap(); + let wire = http_req_header_to_wire(&new_request).unwrap(); + let mut headers = [httparse::EMPTY_HEADER; 128]; + let mut req = httparse::Request::new(&mut headers); + let result = req.parse(wire.as_ref()); + match result { + Ok(_) => {} + Err(e) => error!("{:?}", e), + } + assert!(result.unwrap().is_complete()); + // FIXME: the order is not guaranteed + assert_eq!("/", req.path.unwrap()); + assert_eq!(b"Foo", headers[0].name.as_bytes()); + assert_eq!(b"Bar", headers[0].value); + } +} diff --git a/pingora-core/src/protocols/http/v1/common.rs b/pingora-core/src/protocols/http/v1/common.rs new file mode 100644 index 0000000..9ea2cf3 --- /dev/null +++ b/pingora-core/src/protocols/http/v1/common.rs @@ -0,0 +1,237 @@ +// 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. + +//! Common functions and constants + +use http::header; +use log::warn; +use pingora_http::{HMap, RequestHeader, ResponseHeader}; +use std::str; +use std::time::Duration; + +use super::body::BodyWriter; +use crate::utils::KVRef; + +pub(super) const MAX_HEADERS: usize = 256; + +pub(super) const INIT_HEADER_BUF_SIZE: usize = 4096; +pub(super) const MAX_HEADER_SIZE: usize = 1048575; + +pub(super) const BODY_BUF_LIMIT: usize = 1024 * 64; + +pub const CRLF: &[u8; 2] = b"\r\n"; +pub const HEADER_KV_DELIMITER: &[u8; 2] = b": "; + +pub(super) enum HeaderParseState { + Complete(usize), + Partial, + Invalid(httparse::Error), +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub(super) enum KeepaliveStatus { + Timeout(Duration), + Infinite, + Off, +} + +struct ConnectionValue { + keep_alive: bool, + upgrade: bool, + close: bool, +} + +impl ConnectionValue { + fn new() -> Self { + ConnectionValue { + keep_alive: false, + upgrade: false, + close: false, + } + } + + fn close(mut self) -> Self { + self.close = true; + self + } + fn upgrade(mut self) -> Self { + self.upgrade = true; + self + } + fn keep_alive(mut self) -> Self { + self.keep_alive = true; + self + } +} + +fn parse_connection_header(value: &[u8]) -> ConnectionValue { + // only parse keep-alive, close, and upgrade tokens + // https://www.rfc-editor.org/rfc/rfc9110.html#section-7.6.1 + + const KEEP_ALIVE: &str = "keep-alive"; + const CLOSE: &str = "close"; + const UPGRADE: &str = "upgrade"; + + // fast path + if value.eq_ignore_ascii_case(CLOSE.as_bytes()) { + ConnectionValue::new().close() + } else if value.eq_ignore_ascii_case(KEEP_ALIVE.as_bytes()) { + ConnectionValue::new().keep_alive() + } else if value.eq_ignore_ascii_case(UPGRADE.as_bytes()) { + ConnectionValue::new().upgrade() + } else { + // slow path, parse the connection value + let mut close = false; + let mut upgrade = false; + let value = str::from_utf8(value).unwrap_or(""); + for token in value + .split(',') + .map(|s| s.trim()) + .filter(|&x| !x.is_empty()) + { + if token.eq_ignore_ascii_case(CLOSE) { + close = true; + } else if token.eq_ignore_ascii_case(UPGRADE) { + upgrade = true; + } + if upgrade && close { + return ConnectionValue::new().upgrade().close(); + } + } + if close { + ConnectionValue::new().close() + } else if upgrade { + ConnectionValue::new().upgrade() + } else { + ConnectionValue::new() + } + } +} + +pub(crate) fn init_body_writer_comm(body_writer: &mut BodyWriter, headers: &HMap) { + let te_value = headers.get(http::header::TRANSFER_ENCODING); + if is_header_value_chunked_encoding(te_value) { + // transfer-encoding takes priority over content-length + body_writer.init_chunked(); + } else { + let content_length = header_value_content_length(headers.get(http::header::CONTENT_LENGTH)); + match content_length { + Some(length) => { + body_writer.init_content_length(length); + } + None => { + /* TODO: 1. connection: keepalive cannot be used, + 2. mark connection must be closed */ + body_writer.init_http10(); + } + } + } +} + +#[inline] +pub(super) fn is_header_value_chunked_encoding( + header_value: Option<&http::header::HeaderValue>, +) -> bool { + match header_value { + Some(value) => value.as_bytes().eq_ignore_ascii_case(b"chunked"), + None => false, + } +} + +pub(super) fn is_upgrade_req(req: &RequestHeader) -> bool { + req.version == http::Version::HTTP_11 && req.headers.get(header::UPGRADE).is_some() +} + +// Unlike the upgrade check on request, this function doesn't check the Upgrade or Connection header +// because when seeing 101, we assume the server accepts to switch protocol. +// In reality it is not common that some servers don't send all the required headers to establish +// websocket connections. +pub(super) fn is_upgrade_resp(header: &ResponseHeader) -> bool { + header.status == 101 && header.version == http::Version::HTTP_11 +} + +#[inline] +pub fn header_value_content_length( + header_value: Option<&http::header::HeaderValue>, +) -> Option { + match header_value { + Some(value) => buf_to_content_length(Some(value.as_bytes())), + None => None, + } +} + +#[inline] +pub(super) fn buf_to_content_length(header_value: Option<&[u8]>) -> Option { + match header_value { + Some(buf) => { + match str::from_utf8(buf) { + // check valid string + Ok(str_cl_value) => match str_cl_value.parse::() { + Ok(cl_length) => { + if cl_length >= 0 { + Some(cl_length as usize) + } else { + warn!("negative content-length header value {cl_length}"); + None + } + } + Err(_) => { + warn!("invalid content-length header value {str_cl_value}"); + None + } + }, + Err(_) => { + warn!("invalid content-length header encoding"); + None + } + } + } + None => None, + } +} + +#[inline] +pub(super) fn is_buf_keepalive(header_value: Option<&[u8]>) -> Option { + header_value.and_then(|value| { + let value = parse_connection_header(value); + if value.keep_alive { + Some(true) + } else if value.close { + Some(false) + } else { + None + } + }) +} + +#[inline] +pub(super) fn populate_headers( + base: usize, + header_ref: &mut Vec, + headers: &[httparse::Header], +) -> usize { + let mut used_header_index = 0; + for header in headers.iter() { + if !header.name.is_empty() { + header_ref.push(KVRef::new( + header.name.as_ptr() as usize - base, + header.name.as_bytes().len(), + header.value.as_ptr() as usize - base, + header.value.len(), + )); + used_header_index += 1; + } + } + used_header_index +} diff --git a/pingora-core/src/protocols/http/v1/mod.rs b/pingora-core/src/protocols/http/v1/mod.rs new file mode 100644 index 0000000..2604357 --- /dev/null +++ b/pingora-core/src/protocols/http/v1/mod.rs @@ -0,0 +1,20 @@ +// 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. + +//! HTTP/1.x implementation + +pub(crate) mod body; +pub mod client; +pub mod common; +pub mod server; diff --git a/pingora-core/src/protocols/http/v1/server.rs b/pingora-core/src/protocols/http/v1/server.rs new file mode 100644 index 0000000..5b3a111 --- /dev/null +++ b/pingora-core/src/protocols/http/v1/server.rs @@ -0,0 +1,1566 @@ +// 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. + +//! HTTP/1.x server session + +use bytes::Bytes; +use bytes::{BufMut, BytesMut}; +use http::HeaderValue; +use http::{header, header::AsHeaderName, Method, Version}; +use log::{debug, error, warn}; +use once_cell::sync::Lazy; +use percent_encoding::{percent_encode, AsciiSet, CONTROLS}; +use pingora_error::{Error, ErrorType::*, OrErr, Result}; +use pingora_http::{IntoCaseHeaderName, RequestHeader, ResponseHeader}; +use pingora_timeout::timeout; +use regex::bytes::Regex; +use std::time::Duration; +use tokio::io::{AsyncReadExt, AsyncWriteExt}; + +use super::body::{BodyReader, BodyWriter}; +use super::common::*; +use crate::protocols::http::{body_buffer::FixedBuffer, date, error_resp, HttpTask}; +use crate::protocols::Stream; +use crate::utils::{BufRef, KVRef}; + +/// The HTTP 1.x server session +pub struct HttpSession { + underlying_stream: Stream, + /// The buf that holds the raw request header + possibly a portion of request body + /// Request body can appear here because they could arrive with the same read() that + /// sends the request header. + buf: Bytes, + /// A slice reference to `buf` which points to the exact range of request header + raw_header: Option, + /// A slice reference to `buf` which points to the range of a portion of request body if any + preread_body: Option, + /// A state machine to track how to read the request body + body_reader: BodyReader, + /// A state machine to track how to write the response body + body_writer: BodyWriter, + /// An internal buffer to buf multiple body writes to reduce the underlying syscalls + body_write_buf: BytesMut, + /// Track how many application (not on the wire) body bytes already sent + body_bytes_sent: usize, + /// Whether to update headers like connection, Date + update_resp_headers: bool, + /// timeouts: + keepalive_timeout: KeepaliveStatus, + read_timeout: Option, + write_timeout: Option, + /// A copy of the response that is already written to the client + response_written: Option>, + /// The parse request header + request_header: Option>, + /// An internal buffer that holds a copy of the request body up to a certain size + retry_buffer: Option, + /// Whether this session is an upgraded session. This flag is calculated when sending the + /// response header to the client. + upgraded: bool, +} + +impl HttpSession { + /// Create a new http server session from an established (TCP or TLS) [`Stream`]. + /// The created session needs to call [`Self::read_request()`] first before performing + /// any other operations. + pub fn new(underlying_stream: Stream) -> Self { + HttpSession { + underlying_stream, + buf: Bytes::new(), // zero size, with be replaced by parsed header later + raw_header: None, + preread_body: None, + body_reader: BodyReader::new(), + body_writer: BodyWriter::new(), + body_write_buf: BytesMut::new(), + keepalive_timeout: KeepaliveStatus::Off, + update_resp_headers: true, + response_written: None, + request_header: None, + read_timeout: None, + write_timeout: None, + body_bytes_sent: 0, + retry_buffer: None, + upgraded: false, + } + } + + /// Read the request header. Return `Ok(Some(n))` where the read and parsing are successful. + /// Return `Ok(None)` when the client closed the connection without sending any data, which + /// is common on a reused connection. + pub async fn read_request(&mut self) -> Result> { + self.buf.clear(); + let mut buf = BytesMut::with_capacity(INIT_HEADER_BUF_SIZE); + let mut already_read: usize = 0; + loop { + if already_read > MAX_HEADER_SIZE { + /* NOTE: this check only blocks second read. The first large read is allowed + since the buf is already allocated. The goal is to avoid slowly bloating + this buffer */ + return Error::e_explain( + InvalidHTTPHeader, + format!("Request header larger than {}", MAX_HEADER_SIZE), + ); + } + + let read_result = { + let read_event = self.underlying_stream.read_buf(&mut buf); + match self.keepalive_timeout { + KeepaliveStatus::Timeout(d) => match timeout(d, read_event).await { + Ok(res) => res, + Err(e) => { + debug!("keepalive timeout {d:?} reached, {e}"); + return Ok(None); + } + }, + _ => read_event.await, + } + }; + let n = match read_result { + Ok(n_read) => { + if n_read == 0 { + if already_read > 0 { + return Error::e_explain( + ConnectionClosed, + format!( + "while reading request headers, bytes already read: {}", + already_read + ), + ); + } else { + /* common when client decides to close a keepalived session */ + debug!("Client prematurely closed connection with 0 byte sent"); + return Ok(None); + } + } + n_read + } + + Err(e) => { + if already_read > 0 { + return Error::e_because(ReadError, "while reading request headers", e); + } + /* nothing harmful since we have not ready any thing yet */ + return Ok(None); + } + }; + already_read += n; + + // Use loop as GOTO to retry escaped request buffer, not a real loop + loop { + let mut headers = [httparse::EMPTY_HEADER; MAX_HEADERS]; + let mut req = httparse::Request::new(&mut headers); + let parsed = parse_req_buffer(&mut req, &buf); + match parsed { + HeaderParseState::Complete(s) => { + self.raw_header = Some(BufRef(0, s)); + self.preread_body = Some(BufRef(s, already_read)); + + // We have the header name and values we parsed to be just 0 copy Bytes + // referencing the original buf. That requires we convert the buf from + // BytesMut to Bytes. But `req` holds a reference to `buf`. So we use the + // `KVRef`s to record the offset of each piece of data, drop `req`, convert + // buf, the do the 0 copy update + let base = buf.as_ptr() as usize; + let mut header_refs = Vec::::with_capacity(req.headers.len()); + // Note: req.headers has the correct number of headers + // while header_refs doesn't as it is still empty + let _num_headers = populate_headers(base, &mut header_refs, req.headers); + + let mut request_header = Box::new(RequestHeader::build( + req.method.unwrap_or(""), + // we path httparse to allow unsafe bytes in the str + req.path.unwrap_or("").as_bytes(), + Some(req.headers.len()), + )?); + + request_header.set_version(match req.version { + Some(1) => Version::HTTP_11, + Some(0) => Version::HTTP_10, + _ => Version::HTTP_09, + }); + + let buf = buf.freeze(); + + for header in header_refs { + let header_name = header.get_name_bytes(&buf); + let header_name = header_name.into_case_header_name(); + let value_bytes = header.get_value_bytes(&buf); + // safe because this is from what we parsed + let header_value = unsafe { + http::HeaderValue::from_maybe_shared_unchecked(value_bytes) + }; + request_header + .append_header(header_name, header_value) + .or_err(InvalidHTTPHeader, "while parsing request header")?; + } + + self.buf = buf; + self.request_header = Some(request_header); + + self.body_reader.reinit(); + self.response_written = None; + self.respect_keepalive(); + + return Ok(Some(s)); + } + HeaderParseState::Partial => { + break; /* continue the read loop */ + } + HeaderParseState::Invalid(e) => match e { + httparse::Error::Token | httparse::Error::Version => { + // try to escape URI + if let Some(new_buf) = escape_illegal_request_line(&buf) { + buf = new_buf; + already_read = buf.len(); + } else { + debug!("Invalid request header from {:?}", self.underlying_stream); + return Error::e_because( + InvalidHTTPHeader, + format!("buf: {:?}", String::from_utf8_lossy(&buf)), + e, + ); + } + } + _ => { + debug!("Invalid request header from {:?}", self.underlying_stream); + return Error::e_because( + InvalidHTTPHeader, + format!("buf: {:?}", String::from_utf8_lossy(&buf)), + e, + ); + } + }, + } + } + } + } + + /// Return a reference of the `RequestHeader` this session read + /// # Panics + /// this function and most other functions will panic if called before [`Self::read_request()`] + pub fn req_header(&self) -> &RequestHeader { + self.request_header + .as_ref() + .expect("Request header is not read yet") + } + + /// Return a mutable reference of the `RequestHeader` this session read + /// # Panics + /// this function and most other functions will panic if called before [`Self::read_request()`] + pub fn req_header_mut(&mut self) -> &mut RequestHeader { + self.request_header + .as_mut() + .expect("Request header is not read yet") + } + + /// Get the header value for the given header name + /// If there are multiple headers under the same name, the first one will be returned + /// Use `self.req_header().header.get_all(name)` to get all the headers under the same name + pub fn get_header(&self, name: impl AsHeaderName) -> Option<&HeaderValue> { + self.request_header + .as_ref() + .and_then(|h| h.headers.get(name)) + } + + /// Return the method of this request. None if the request is not read yet. + pub(super) fn get_method(&self) -> Option<&http::Method> { + self.request_header.as_ref().map(|r| &r.method) + } + + /// Return the path of the request (i.e., the `/hello?1` of `GET /hello?1 HTTP1.1`) + /// An empty slice will be used if there is no path or the request is not read yet + pub(super) fn get_path(&self) -> &[u8] { + self.request_header.as_ref().map_or(b"", |r| r.raw_path()) + } + + /// Return the host header of the request. An empty slice will be used if there is no host header + pub(super) fn get_host(&self) -> &[u8] { + self.request_header + .as_ref() + .and_then(|h| h.headers.get(header::HOST)) + .map_or(b"", |h| h.as_bytes()) + } + + /// Return a string `$METHOD $PATH $HOST`. Mostly for logging and debug purpose + pub fn request_summary(&self) -> String { + format!( + "{} {}, Host: {}", + self.get_method().map_or("-", |r| r.as_str()), + String::from_utf8_lossy(self.get_path()), + String::from_utf8_lossy(self.get_host()) + ) + } + + /// Is the request a upgrade request + pub fn is_upgrade_req(&self) -> bool { + match self.request_header.as_deref() { + Some(req) => is_upgrade_req(req), + None => false, + } + } + + /// Get the request header as raw bytes, `b""` when the header doesn't exist + pub fn get_header_bytes(&self, name: impl AsHeaderName) -> &[u8] { + self.get_header(name).map_or(b"", |v| v.as_bytes()) + } + + /// Read the request body. `Ok(None)` when there is no (more) body to read. + pub async fn read_body_bytes(&mut self) -> Result> { + let read = self.read_body().await?; + Ok(read.map(|b| { + let bytes = Bytes::copy_from_slice(self.get_body(&b)); + if let Some(buffer) = self.retry_buffer.as_mut() { + buffer.write_to_buffer(&bytes); + } + bytes + })) + } + + async fn do_read_body(&mut self) -> Result> { + self.init_body_reader(); + self.body_reader + .read_body(&mut self.underlying_stream) + .await + } + + /// Read the body into the internal buffer + async fn read_body(&mut self) -> Result> { + match self.read_timeout { + Some(t) => match timeout(t, self.do_read_body()).await { + Ok(res) => res, + Err(_) => Error::e_explain(ReadTimedout, format!("reading body, timeout: {t:?}")), + }, + None => self.do_read_body().await, + } + } + + /// Whether there is no (more) body need to be read. + pub fn is_body_done(&mut self) -> bool { + self.init_body_reader(); + self.body_reader.body_done() + } + + /// Whether the request has an empty body + /// Because HTTP 1.1 clients have to send either `Content-Length` or `Transfer-Encoding` in order + /// to signal the server that it will send the body, this function returns accurate results even + /// only when the request header is just read. + pub fn is_body_empty(&mut self) -> bool { + self.init_body_reader(); + self.body_reader.body_empty() + } + + /// Write the response header to the client. + /// This function can be called more than once to send 1xx informational headers excluding 101. + pub async fn write_response_header(&mut self, mut header: Box) -> Result<()> { + if let Some(resp) = self.response_written.as_ref() { + if !resp.status.is_informational() { + warn!("Respond header is already sent, cannot send again"); + return Ok(()); + } + } + + // no need to add these headers to 1xx responses + if !header.status.is_informational() && self.update_resp_headers { + /* update headers */ + header.insert_header(header::DATE, date::get_cached_date())?; + + // TODO: make these lazy static + let connection_value = if self.will_keepalive() { + "keep-alive" + } else { + "close" + }; + header.insert_header(header::CONNECTION, connection_value)?; + } + + if header.status.as_u16() == 101 { + // make sure the connection is closed at the end when 101/upgrade is used + self.set_keepalive(None); + } + + // Allow informational header (excluding 101) to pass through without affecting the state + // of the request + if header.status == 101 || !header.status.is_informational() { + // reset request body to done for incomplete upgrade handshakes + if let Some(upgrade_ok) = self.is_upgrade(&header) { + if upgrade_ok { + debug!("ok upgrade handshake"); + // For ws we use HTTP1_0 do_read_body_until_closed + // + // On ws close the initiator sends a close frame and + // then waits for a response from the peer, once it receives + // a response it closes the conn. After receiving a + // control frame indicating the connection should be closed, + // a peer discards any further data received. + // https://www.rfc-editor.org/rfc/rfc6455#section-1.4 + self.upgraded = true; + } else { + debug!("bad upgrade handshake!"); + // reset request body buf and mark as done + // safe to reset an upgrade because it doesn't have body + self.body_reader.init_content_length(0, b""); + } + } + self.init_body_writer(&header); + } + + // Don't have to flush response with content length because it is less + // likely to be real time communication. So do flush when + // 1.1xx response: client needs to see it before the rest of response + // 2.No content length: the response could be generated in real time + let flush = header.status.is_informational() + || header.headers.get(header::CONTENT_LENGTH).is_none(); + + let mut write_buf = BytesMut::with_capacity(INIT_HEADER_BUF_SIZE); + http_resp_header_to_buf(&header, &mut write_buf).unwrap(); + match self.underlying_stream.write_all(&write_buf).await { + Ok(()) => { + // flush the stream if 1xx header or there is no response body + if flush || self.body_writer.finished() { + self.underlying_stream + .flush() + .await + .or_err(WriteError, "flushing response header")?; + } + self.response_written = Some(header); + self.body_bytes_sent += write_buf.len(); + Ok(()) + } + Err(e) => Error::e_because(WriteError, "writing response header", e), + } + } + + /// Return the response header if it is already sent. + pub fn response_written(&self) -> Option<&ResponseHeader> { + self.response_written.as_deref() + } + + /// `Some(true)` if the this is a successful upgrade + /// `Some(false)` if the request is an upgrade but the response refuses it + /// `None` if the request is not an upgrade. + pub fn is_upgrade(&self, header: &ResponseHeader) -> Option { + if self.is_upgrade_req() { + Some(is_upgrade_resp(header)) + } else { + None + } + } + + fn set_keepalive(&mut self, seconds: Option) { + match seconds { + Some(sec) => { + if sec > 0 { + self.keepalive_timeout = KeepaliveStatus::Timeout(Duration::from_secs(sec)); + } else { + self.keepalive_timeout = KeepaliveStatus::Infinite; + } + } + None => { + self.keepalive_timeout = KeepaliveStatus::Off; + } + } + } + + /// Return whether the session will be keepalived for connection reuse. + pub fn will_keepalive(&self) -> bool { + // TODO: check self.body_writer. If it is http1.0 type then keepalive + // cannot be used because the connection close is the signal of end body + !matches!(self.keepalive_timeout, KeepaliveStatus::Off) + } + + // `Keep-Alive: timeout=5, max=1000` => 5, 1000 + fn get_keepalive_values(&self) -> (Option, Option) { + // TODO: implement this parsing + (None, None) + } + + fn is_connection_keepalive(&self) -> Option { + is_buf_keepalive(self.get_header(header::CONNECTION).map(|v| v.as_bytes())) + } + + /// Apply keepalive settings according to the client + /// For HTTP 1.1, assume keepalive as long as there is no `Connection: Close` request header. + /// For HTTP 1.0, only keepalive if there is an explicit header `Connection: keep-alive`. + pub fn respect_keepalive(&mut self) { + if let Some(keepalive) = self.is_connection_keepalive() { + if keepalive { + let (timeout, _max_use) = self.get_keepalive_values(); + // TODO: respect max_use + match timeout { + Some(d) => self.set_keepalive(Some(d)), + None => self.set_keepalive(Some(0)), // infinite + } + } else { + self.set_keepalive(None); + } + } else if self.req_header().version == Version::HTTP_11 { + self.set_keepalive(Some(0)); // on by default for http 1.1 + } else { + self.set_keepalive(None); // off by default for http 1.0 + } + } + + fn init_body_writer(&mut self, header: &ResponseHeader) { + use http::StatusCode; + /* the following responses don't have body 204, 304, and HEAD */ + if matches!( + header.status, + StatusCode::NO_CONTENT | StatusCode::NOT_MODIFIED + ) || self.get_method() == Some(&Method::HEAD) + { + self.body_writer.init_content_length(0); + return; + } + + if header.status.is_informational() && header.status != StatusCode::SWITCHING_PROTOCOLS { + // 1xx response, not enough to init body + return; + } + + if self.is_upgrade(header) == Some(true) { + self.body_writer.init_http10(); + } else { + init_body_writer_comm(&mut self.body_writer, &header.headers); + } + } + + /// Same as [`Self::write_response_header()`] but takes a reference. + pub async fn write_response_header_ref(&mut self, resp: &ResponseHeader) -> Result<()> { + self.write_response_header(Box::new(resp.clone())).await + } + + async fn do_write_body(&mut self, buf: &[u8]) -> Result> { + let written = self + .body_writer + .write_body(&mut self.underlying_stream, buf) + .await; + + if let Ok(Some(num_bytes)) = written { + self.body_bytes_sent += num_bytes; + } + + written + } + + /// Write response body to the client. Return `Ok(None)` when there shouldn't be more body + /// to be written, e.g., writing more bytes than what the `Content-Length` header suggests + pub async fn write_body(&mut self, buf: &[u8]) -> Result> { + // TODO: check if the response header is written + match self.write_timeout { + Some(t) => match timeout(t, self.do_write_body(buf)).await { + Ok(res) => res, + Err(_) => Error::e_explain(WriteTimedout, format!("writing body, timeout: {t:?}")), + }, + None => self.do_write_body(buf).await, + } + } + + async fn write_body_buf(&mut self) -> Result> { + // Don't flush empty chunks, they are considered end of body for chunks + if self.body_write_buf.is_empty() { + return Ok(None); + } + + let written = self + .body_writer + .write_body(&mut self.underlying_stream, &self.body_write_buf) + .await; + + if let Ok(Some(num_bytes)) = written { + self.body_bytes_sent += num_bytes; + } + + // make sure this buf is safe to reuse + self.body_write_buf.clear(); + + written + } + + fn maybe_force_close_body_reader(&mut self) { + if self.upgraded && !self.body_reader.body_done() { + // response is done, reset the request body to close + self.body_reader.init_content_length(0, b""); + } + } + + /// Signal that there is no more body to write. + /// This call will try to flush the buffer if there is any un-flushed data. + /// For chunked encoding response, this call will also send the last chunk. + /// For upgraded sessions, this call will also close the reading of the client body. + pub async fn finish_body(&mut self) -> Result> { + let res = self.body_writer.finish(&mut self.underlying_stream).await?; + self.underlying_stream + .flush() + .await + .or_err(WriteError, "flushing body")?; + + self.maybe_force_close_body_reader(); + Ok(res) + } + + /// Return how many (application, not wire) body bytes that have been written + pub fn body_bytes_sent(&self) -> usize { + self.body_bytes_sent + } + + fn is_chunked_encoding(&self) -> bool { + is_header_value_chunked_encoding(self.get_header(header::TRANSFER_ENCODING)) + } + + fn get_content_length(&self) -> Option { + buf_to_content_length( + self.get_header(header::CONTENT_LENGTH) + .map(|v| v.as_bytes()), + ) + } + + fn init_body_reader(&mut self) { + if self.body_reader.need_init() { + // reset retry buffer + if let Some(buffer) = self.retry_buffer.as_mut() { + buffer.clear(); + } + + /* follow https://tools.ietf.org/html/rfc7230#section-3.3.3 */ + let preread_body = self.preread_body.as_ref().unwrap().get(&self.buf[..]); + + if self.req_header().version == Version::HTTP_11 && self.is_upgrade_req() { + self.body_reader.init_http10(preread_body); + return; + } + + if self.is_chunked_encoding() { + // if chunked encoding, content-length should be ignored + self.body_reader.init_chunked(preread_body); + } else { + let cl = self.get_content_length(); + match cl { + Some(i) => { + self.body_reader.init_content_length(i, preread_body); + } + None => { + match self.req_header().version { + Version::HTTP_11 => { + // Per RFC assume no body by default in HTTP 1.1 + self.body_reader.init_content_length(0, preread_body); + } + _ => { + self.body_reader.init_http10(preread_body); + } + } + } + } + } + } + } + + pub fn retry_buffer_truncated(&self) -> bool { + self.retry_buffer + .as_ref() + .map_or_else(|| false, |r| r.is_truncated()) + } + + pub fn enable_retry_buffering(&mut self) { + if self.retry_buffer.is_none() { + self.retry_buffer = Some(FixedBuffer::new(BODY_BUF_LIMIT)) + } + } + + pub fn get_retry_buffer(&self) -> Option { + self.retry_buffer.as_ref().and_then(|b| { + if b.is_truncated() { + None + } else { + b.get_buffer() + } + }) + } + + fn get_body(&self, buf_ref: &BufRef) -> &[u8] { + // TODO: these get_*() could panic. handle them better + self.body_reader.get_body(buf_ref) + } + + /// This function will (async) block forever until the client closes the connection. + pub async fn idle(&mut self) -> Result { + // NOTE: this implementation breaks http pipelining, ideally we need poll_error + // NOTE: buf cannot be empty, openssl-rs read() requires none empty buf. + let mut buf: [u8; 1] = [0; 1]; + self.underlying_stream + .read(&mut buf) + .await + .or_err(ReadError, "during HTTP idle state") + } + + /// This function will return body bytes (same as [`Self::read_body_bytes()`]), but after + /// the client body finishes (`Ok(None)` is returned), calling this function again will block + /// forever, same as [`Self::idle()`]. + pub async fn read_body_or_idle(&mut self, no_body_expected: bool) -> Result> { + if no_body_expected || self.is_body_done() { + let read = self.idle().await?; + if read == 0 { + Error::e_explain( + ConnectionClosed, + if self.response_written.is_none() { + "Prematurely before response header is sent" + } else { + "Prematurely before response body is complete" + }, + ) + } else { + Error::e_explain(ConnectError, "Sent data after end of body") + } + } else { + self.read_body_bytes().await + } + } + + /// Return the raw bytes of the request header. + pub fn get_headers_raw_bytes(&self) -> Bytes { + self.raw_header.as_ref().unwrap().get_bytes(&self.buf) + } + + /// Close the connection abruptly. This allows to signal the client that the connection is closed + /// before dropping [`HttpSession`] + pub async fn shutdown(&mut self) { + let _ = self.underlying_stream.shutdown().await; + } + + /// Set the server keepalive timeout. + /// `None`: disable keepalive, this session cannot be reused. + /// `Some(0)`: reusing this session is allowed and there is no timeout. + /// `Some(>0)`: reusing this session is allowed within the given timeout in seconds. + /// If the client disallows connection reuse, then `keepalive` will be ignored. + pub fn set_server_keepalive(&mut self, keepalive: Option) { + if let Some(false) = self.is_connection_keepalive() { + // connection: close is set + self.set_keepalive(None); + } else { + self.set_keepalive(keepalive); + } + } + + /// Consume `self`, if the connection can be reused, the underlying stream will be returned + /// to be fed to the next [`Self::new()`]. The next session can just call [`Self::read_request()`]. + /// If the connection cannot be reused, the underlying stream will be closed and `None` will be + /// returned. + pub async fn reuse(mut self) -> Option { + // TODO: this function is unnecessarily slow for keepalive case + // because that case does not need async + match self.keepalive_timeout { + KeepaliveStatus::Off => { + debug!("HTTP shutdown connection"); + self.shutdown().await; + None + } + _ => Some(self.underlying_stream), + } + } + + /// Return a error response to the client. This default error response comes with `cache-control: private, no-store`. + /// It has no response body. + pub async fn respond_error(&mut self, error_status_code: u16) { + let (resp, resp_tmp) = match error_status_code { + /* commmon error responses are pre-generated */ + 502 => (Some(&*error_resp::HTTP_502_RESPONSE), None), + 400 => (Some(&*error_resp::HTTP_400_RESPONSE), None), + _ => ( + None, + Some(error_resp::gen_error_response(error_status_code)), + ), + }; + + let resp = match resp { + Some(r) => r, + None => resp_tmp.as_ref().unwrap(), + }; + + self.write_response_header_ref(resp) + .await + .unwrap_or_else(|e| { + error!("failed to send error response to downstream: {}", e); + }); + } + + /// Write a `100 Continue` response to the client. + pub async fn write_continue_response(&mut self) -> Result<()> { + // only send if we haven't already + if self.response_written.is_none() { + // size hint Some(0) because default is 8 + return self + .write_response_header(Box::new(ResponseHeader::build(100, Some(0)).unwrap())) + .await; + } + Ok(()) + } + + async fn response_duplex(&mut self, task: HttpTask) -> Result { + match task { + HttpTask::Header(header, end_stream) => { + self.write_response_header(header) + .await + .map_err(|e| e.into_down())?; + Ok(end_stream) + } + HttpTask::Body(data, end_stream) => match data { + Some(d) => { + if !d.is_empty() { + self.write_body(&d).await.map_err(|e| e.into_down())?; + } + Ok(end_stream) + } + None => Ok(end_stream), + }, + HttpTask::Trailer(_) => Ok(true), // h1 trailer is not supported yet + HttpTask::Done => { + self.finish_body().await.map_err(|e| e.into_down())?; + Ok(true) + } + HttpTask::Failed(e) => Err(e), + } + } + + // TODO: use vectored write to avoid copying + pub async fn response_duplex_vec(&mut self, mut tasks: Vec) -> Result { + let n_tasks = tasks.len(); + if n_tasks == 1 { + // fallback to single operation to avoid copy + return self.response_duplex(tasks.pop().unwrap()).await; + } + let mut end_stream = false; + for task in tasks.into_iter() { + end_stream = match task { + HttpTask::Header(header, end_stream) => { + self.write_response_header(header) + .await + .map_err(|e| e.into_down())?; + end_stream + } + HttpTask::Body(data, end_stream) => match data { + Some(d) => { + if !d.is_empty() && !self.body_writer.finished() { + self.body_write_buf.put_slice(&d); + } + end_stream + } + None => end_stream, + }, + HttpTask::Trailer(_) => true, // h1 trailer is not supported yet + HttpTask::Done => { + // flush body first + self.write_body_buf().await.map_err(|e| e.into_down())?; + self.finish_body().await.map_err(|e| e.into_down())?; + return Ok(true); + } + HttpTask::Failed(e) => { + // flush the data we have and quit + self.write_body_buf().await.map_err(|e| e.into_down())?; + self.underlying_stream + .flush() + .await + .or_err(WriteError, "flushing response")?; + return Err(e); + } + } + } + self.write_body_buf().await.map_err(|e| e.into_down())?; + Ok(end_stream) + } +} + +// Regex to parse request line that has illegal chars in it +static REQUEST_LINE_REGEX: Lazy = + Lazy::new(|| Regex::new(r"^\w+ (?P.+) HTTP/\d(?:\.\d)?").unwrap()); + +// the chars httparse considers illegal in URL +// Almost https://url.spec.whatwg.org/#query-percent-encode-set + {} +const URI_ESC_CHARSET: &AsciiSet = &CONTROLS.add(b' ').add(b'<').add(b'>').add(b'"'); + +fn escape_illegal_request_line(buf: &BytesMut) -> Option { + if let Some(captures) = REQUEST_LINE_REGEX.captures(buf) { + // return if nothing matches: not a request line at all + let uri = captures.name("uri")?; + + let escaped_uri = percent_encode(uri.as_bytes(), URI_ESC_CHARSET); + + // rebuild the entire request buf in a new buffer + // TODO: this might be able to be done in place + + // need to be slightly bigger than the current buf; + let mut new_buf = BytesMut::with_capacity(buf.len() + 32); + new_buf.extend_from_slice(&buf[..uri.start()]); + + for s in escaped_uri { + new_buf.extend_from_slice(s.as_bytes()); + } + + if new_buf.len() == uri.end() { + // buf unchanged, nothing is escaped, return None to avoid loop + return None; + } + + new_buf.extend_from_slice(&buf[uri.end()..]); + + Some(new_buf) + } else { + None + } +} + +#[inline] +fn parse_req_buffer<'buf>( + req: &mut httparse::Request<'_, 'buf>, + buf: &'buf [u8], +) -> HeaderParseState { + use httparse::Result; + + #[cfg(feature = "patched_http1")] + fn parse<'buf>(req: &mut httparse::Request<'_, 'buf>, buf: &'buf [u8]) -> Result { + req.parse_unchecked(buf) + } + + #[cfg(not(feature = "patched_http1"))] + fn parse<'buf>(req: &mut httparse::Request<'_, 'buf>, buf: &'buf [u8]) -> Result { + req.parse(buf) + } + + let res = match parse(req, buf) { + Ok(s) => s, + Err(e) => { + return HeaderParseState::Invalid(e); + } + }; + match res { + httparse::Status::Complete(s) => HeaderParseState::Complete(s), + _ => HeaderParseState::Partial, + } +} + +#[inline] +fn http_resp_header_to_buf( + resp: &ResponseHeader, + buf: &mut BytesMut, +) -> std::result::Result<(), ()> { + // Status-Line + let version = match resp.version { + Version::HTTP_09 => "HTTP/0.9 ", + Version::HTTP_10 => "HTTP/1.0 ", + Version::HTTP_11 => "HTTP/1.1 ", + _ => { + return Err(()); /*TODO: unsupported version */ + } + }; + buf.put_slice(version.as_bytes()); + let status = resp.status; + buf.put_slice(status.as_str().as_bytes()); + buf.put_u8(b' '); + let reason = status.canonical_reason(); + if let Some(reason_buf) = reason { + buf.put_slice(reason_buf.as_bytes()); + } + buf.put_slice(CRLF); + + // headers + // TODO: style: make sure Server and Date headers are the first two + resp.header_to_h1_wire(buf); + + buf.put_slice(CRLF); + Ok(()) +} + +#[cfg(test)] +mod tests_stream { + use super::*; + use crate::protocols::http::v1::body::{BodyMode, ParseState}; + use http::{Method, StatusCode}; + use std::str; + use std::time::Duration; + use tokio_test::io::Builder; + + fn init_log() { + let _ = env_logger::builder().is_test(true).try_init(); + } + + #[tokio::test] + async fn read_basic() { + init_log(); + let input = b"GET / HTTP/1.1\r\n\r\n"; + let mock_io = Builder::new().read(&input[..]).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + let res = http_stream.read_request().await; + assert_eq!(input.len(), res.unwrap().unwrap()); + assert_eq!(0, http_stream.req_header().headers.len()); + } + + #[cfg(feature = "patched_http1")] + #[tokio::test] + async fn read_invalid_path() { + init_log(); + let input = b"GET /\x01\xF0\x90\x80 HTTP/1.1\r\n\r\n"; + let mock_io = Builder::new().read(&input[..]).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + let res = http_stream.read_request().await; + assert_eq!(input.len(), res.unwrap().unwrap()); + assert_eq!(0, http_stream.req_header().headers.len()); + assert_eq!(b"/\x01\xF0\x90\x80", http_stream.get_path()); + } + + #[tokio::test] + async fn read_2_buf() { + init_log(); + let input1 = b"GET / HTTP/1.1\r\n"; + let input2 = b"Host: pingora.org\r\n\r\n"; + let mock_io = Builder::new().read(&input1[..]).read(&input2[..]).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + let res = http_stream.read_request().await; + assert_eq!(input1.len() + input2.len(), res.unwrap().unwrap()); + assert_eq!( + input1.len() + input2.len(), + http_stream.raw_header.as_ref().unwrap().len() + ); + assert_eq!(1, http_stream.req_header().headers.len()); + assert_eq!(Some(&Method::GET), http_stream.get_method()); + assert_eq!(b"/", http_stream.get_path()); + assert_eq!(Version::HTTP_11, http_stream.req_header().version); + + assert_eq!(b"pingora.org", http_stream.get_header_bytes("Host")); + } + + #[tokio::test] + async fn read_with_body_content_length() { + init_log(); + let input1 = b"GET / HTTP/1.1\r\n"; + let input2 = b"Host: pingora.org\r\nContent-Length: 3\r\n\r\n"; + let input3 = b"abc"; + let mock_io = Builder::new() + .read(&input1[..]) + .read(&input2[..]) + .read(&input3[..]) + .build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + http_stream.read_request().await.unwrap(); + let res = http_stream.read_body().await.unwrap().unwrap(); + assert_eq!(res, BufRef::new(0, 3)); + assert_eq!(http_stream.body_reader.body_state, ParseState::Complete(3)); + assert_eq!(input3, http_stream.get_body(&res)); + } + + #[tokio::test] + #[should_panic(expected = "There is still data left to read.")] + async fn read_with_body_timeout() { + init_log(); + let input1 = b"GET / HTTP/1.1\r\n"; + let input2 = b"Host: pingora.org\r\nContent-Length: 3\r\n\r\n"; + let input3 = b"abc"; + let mock_io = Builder::new() + .read(&input1[..]) + .read(&input2[..]) + .wait(Duration::from_secs(2)) + .read(&input3[..]) + .build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + http_stream.read_timeout = Some(Duration::from_secs(1)); + http_stream.read_request().await.unwrap(); + let res = http_stream.read_body().await; + assert_eq!(res.unwrap_err().etype(), &ReadTimedout); + } + + #[tokio::test] + async fn read_with_body_content_length_single_read() { + init_log(); + let input1 = b"GET / HTTP/1.1\r\n"; + let input2 = b"Host: pingora.org\r\nContent-Length: 3\r\n\r\nabc"; + let mock_io = Builder::new().read(&input1[..]).read(&input2[..]).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + http_stream.read_request().await.unwrap(); + let res = http_stream.read_body().await.unwrap().unwrap(); + assert_eq!(res, BufRef::new(0, 3)); + assert_eq!(http_stream.body_reader.body_state, ParseState::Complete(3)); + assert_eq!(b"abc", http_stream.get_body(&res)); + } + + #[tokio::test] + async fn read_with_body_http10() { + init_log(); + let input1 = b"GET / HTTP/1.0\r\n"; + let input2 = b"Host: pingora.org\r\n\r\n"; + let input3 = b"a"; + let input4 = b""; // simulating close + let mock_io = Builder::new() + .read(&input1[..]) + .read(&input2[..]) + .read(&input3[..]) + .read(&input4[..]) + .build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + http_stream.read_request().await.unwrap(); + let res = http_stream.read_body().await.unwrap().unwrap(); + assert_eq!(res, BufRef::new(0, 1)); + assert_eq!(http_stream.body_reader.body_state, ParseState::HTTP1_0(1)); + assert_eq!(input3, http_stream.get_body(&res)); + let res = http_stream.read_body().await.unwrap(); + assert_eq!(res, None); + assert_eq!(http_stream.body_reader.body_state, ParseState::Complete(1)); + } + + #[tokio::test] + async fn read_with_body_http10_single_read() { + init_log(); + let input1 = b"GET / HTTP/1.0\r\n"; + let input2 = b"Host: pingora.org\r\n\r\na"; + let input3 = b"b"; + let input4 = b""; // simulating close + let mock_io = Builder::new() + .read(&input1[..]) + .read(&input2[..]) + .read(&input3[..]) + .read(&input4[..]) + .build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + http_stream.read_request().await.unwrap(); + let res = http_stream.read_body().await.unwrap().unwrap(); + assert_eq!(res, BufRef::new(0, 1)); + assert_eq!(http_stream.body_reader.body_state, ParseState::HTTP1_0(1)); + assert_eq!(b"a", http_stream.get_body(&res)); + let res = http_stream.read_body().await.unwrap().unwrap(); + assert_eq!(res, BufRef::new(0, 1)); + assert_eq!(http_stream.body_reader.body_state, ParseState::HTTP1_0(2)); + assert_eq!(input3, http_stream.get_body(&res)); + let res = http_stream.read_body().await.unwrap(); + assert_eq!(res, None); + assert_eq!(http_stream.body_reader.body_state, ParseState::Complete(2)); + } + + #[tokio::test] + async fn read_http11_default_no_body() { + init_log(); + let input1 = b"GET / HTTP/1.1\r\n"; + let input2 = b"Host: pingora.org\r\n\r\n"; + let mock_io = Builder::new().read(&input1[..]).read(&input2[..]).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + http_stream.read_request().await.unwrap(); + let res = http_stream.read_body().await.unwrap(); + assert_eq!(res, None); + assert_eq!(http_stream.body_reader.body_state, ParseState::Complete(0)); + } + + #[tokio::test] + async fn read_with_body_chunked_0() { + init_log(); + let input1 = b"GET / HTTP/1.1\r\n"; + let input2 = b"Host: pingora.org\r\nTransfer-Encoding: chunked\r\n\r\n"; + let input3 = b"0\r\n"; + let mock_io = Builder::new() + .read(&input1[..]) + .read(&input2[..]) + .read(&input3[..]) + .build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + http_stream.read_request().await.unwrap(); + assert!(http_stream.is_chunked_encoding()); + let res = http_stream.read_body().await.unwrap(); + assert_eq!(res, None); + assert_eq!(http_stream.body_reader.body_state, ParseState::Complete(0)); + } + + #[tokio::test] + async fn read_with_body_chunked_single_read() { + init_log(); + let input1 = b"GET / HTTP/1.1\r\n"; + let input2 = b"Host: pingora.org\r\nTransfer-Encoding: chunked\r\n\r\n1\r\na\r\n"; + let input3 = b"0\r\n\r\n"; + let mock_io = Builder::new() + .read(&input1[..]) + .read(&input2[..]) + .read(&input3[..]) + .build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + http_stream.read_request().await.unwrap(); + assert!(http_stream.is_chunked_encoding()); + let res = http_stream.read_body().await.unwrap().unwrap(); + assert_eq!(res, BufRef::new(3, 1)); + assert_eq!( + http_stream.body_reader.body_state, + ParseState::Chunked(1, 0, 0, 0) + ); + let res = http_stream.read_body().await.unwrap(); + assert_eq!(res, None); + assert_eq!(http_stream.body_reader.body_state, ParseState::Complete(1)); + } + + #[tokio::test] + #[should_panic(expected = "There is still data left to read.")] + async fn read_invalid() { + let input1 = b"GET / HTP/1.1\r\n"; + let input2 = b"Host: pingora.org\r\n\r\n"; + let mock_io = Builder::new().read(&input1[..]).read(&input2[..]).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + let res = http_stream.read_request().await; + assert_eq!(&InvalidHTTPHeader, res.unwrap_err().etype()); + } + + async fn build_req(upgrade: &str, conn: &str) -> HttpSession { + let input = format!("GET / HTTP/1.1\r\nHost: pingora.org\r\nUpgrade: {upgrade}\r\nConnection: {conn}\r\n\r\n"); + let mock_io = Builder::new().read(input.as_bytes()).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + http_stream.read_request().await.unwrap(); + http_stream + } + + #[tokio::test] + async fn read_upgrade_req() { + // http 1.0 + let input = b"GET / HTTP/1.0\r\nHost: pingora.org\r\nUpgrade: websocket\r\nConnection: upgrade\r\n\r\n"; + let mock_io = Builder::new().read(&input[..]).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + http_stream.read_request().await.unwrap(); + assert!(!http_stream.is_upgrade_req()); + + // different method + let input = b"POST / HTTP/1.1\r\nHost: pingora.org\r\nUpgrade: websocket\r\nConnection: upgrade\r\n\r\n"; + let mock_io = Builder::new().read(&input[..]).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + http_stream.read_request().await.unwrap(); + assert!(http_stream.is_upgrade_req()); + + // missing upgrade header + let input = b"GET / HTTP/1.1\r\nHost: pingora.org\r\nConnection: upgrade\r\n\r\n"; + let mock_io = Builder::new().read(&input[..]).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + http_stream.read_request().await.unwrap(); + assert!(!http_stream.is_upgrade_req()); + + // no connection header + let input = b"GET / HTTP/1.1\r\nHost: pingora.org\r\nUpgrade: WebSocket\r\n\r\n"; + let mock_io = Builder::new().read(&input[..]).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + http_stream.read_request().await.unwrap(); + assert!(http_stream.is_upgrade_req()); + + assert!(build_req("websocket", "Upgrade").await.is_upgrade_req()); + + // mixed case + assert!(build_req("WebSocket", "Upgrade").await.is_upgrade_req()); + } + + #[tokio::test] + async fn read_upgrade_req_with_1xx_response() { + let input = b"GET / HTTP/1.1\r\nHost: pingora.org\r\nUpgrade: websocket\r\nConnection: upgrade\r\n\r\n"; + let mock_io = Builder::new() + .read(&input[..]) + .write(b"HTTP/1.1 100 Continue\r\n\r\n") + .build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + http_stream.read_request().await.unwrap(); + assert!(http_stream.is_upgrade_req()); + let mut response = ResponseHeader::build(StatusCode::CONTINUE, None).unwrap(); + response.set_version(http::Version::HTTP_11); + http_stream + .write_response_header(Box::new(response)) + .await + .unwrap(); + // 100 won't affect body state + assert!(!http_stream.is_body_done()); + } + + #[tokio::test] + async fn set_server_keepalive() { + // close + let input = b"GET / HTTP/1.1\r\nHost: pingora.org\r\nConnection: close\r\n\r\n"; + let mock_io = Builder::new().read(&input[..]).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + http_stream.read_request().await.unwrap(); + // verify close + assert_eq!(http_stream.keepalive_timeout, KeepaliveStatus::Off); + http_stream.set_server_keepalive(Some(60)); + // verify no change on override + assert_eq!(http_stream.keepalive_timeout, KeepaliveStatus::Off); + + // explicit keep-alive + let input = b"GET / HTTP/1.1\r\nHost: pingora.org\r\nConnection: keep-alive\r\n\r\n"; + let mock_io = Builder::new().read(&input[..]).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + // default is infinite for 1.1 + http_stream.read_request().await.unwrap(); + assert_eq!(http_stream.keepalive_timeout, KeepaliveStatus::Infinite); + http_stream.set_server_keepalive(Some(60)); + // override respected + assert_eq!( + http_stream.keepalive_timeout, + KeepaliveStatus::Timeout(Duration::from_secs(60)) + ); + + // not specified + let input = b"GET / HTTP/1.1\r\nHost: pingora.org\r\n\r\n"; + let mock_io = Builder::new().read(&input[..]).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + http_stream.read_request().await.unwrap(); + // default is infinite for 1.1 + assert_eq!(http_stream.keepalive_timeout, KeepaliveStatus::Infinite); + http_stream.set_server_keepalive(Some(60)); + // override respected + assert_eq!( + http_stream.keepalive_timeout, + KeepaliveStatus::Timeout(Duration::from_secs(60)) + ); + } + + #[tokio::test] + async fn write() { + let wire = b"HTTP/1.1 200 OK\r\nFoo: Bar\r\n\r\n"; + let mock_io = Builder::new().write(wire).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + let mut new_response = ResponseHeader::build(StatusCode::OK, None).unwrap(); + new_response.append_header("Foo", "Bar").unwrap(); + http_stream.update_resp_headers = false; + http_stream + .write_response_header_ref(&new_response) + .await + .unwrap(); + } + + #[tokio::test] + async fn write_informational() { + let wire = b"HTTP/1.1 100 Continue\r\n\r\nHTTP/1.1 200 OK\r\nFoo: Bar\r\n\r\n"; + let mock_io = Builder::new().write(wire).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + let response_100 = ResponseHeader::build(StatusCode::CONTINUE, None).unwrap(); + http_stream + .write_response_header_ref(&response_100) + .await + .unwrap(); + let mut response_200 = ResponseHeader::build(StatusCode::OK, None).unwrap(); + response_200.append_header("Foo", "Bar").unwrap(); + http_stream.update_resp_headers = false; + http_stream + .write_response_header_ref(&response_200) + .await + .unwrap(); + } + + #[tokio::test] + async fn write_101_switching_protocol() { + let wire = b"HTTP/1.1 101 Switching Protocols\r\nFoo: Bar\r\n\r\n"; + let wire_body = b"nPAYLOAD"; + let mock_io = Builder::new().write(wire).write(wire_body).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + let mut response_101 = + ResponseHeader::build(StatusCode::SWITCHING_PROTOCOLS, None).unwrap(); + response_101.append_header("Foo", "Bar").unwrap(); + http_stream + .write_response_header_ref(&response_101) + .await + .unwrap(); + let n = http_stream.write_body(wire_body).await.unwrap().unwrap(); + assert_eq!(wire_body.len(), n); + } + + #[tokio::test] + async fn write_body_cl() { + let wire_header = b"HTTP/1.1 200 OK\r\nContent-Length: 1\r\n\r\n"; + let wire_body = b"a"; + let mock_io = Builder::new().write(wire_header).write(wire_body).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + let mut new_response = ResponseHeader::build(StatusCode::OK, None).unwrap(); + new_response.append_header("Content-Length", "1").unwrap(); + http_stream.update_resp_headers = false; + http_stream + .write_response_header_ref(&new_response) + .await + .unwrap(); + assert_eq!( + http_stream.body_writer.body_mode, + BodyMode::ContentLength(1, 0) + ); + let n = http_stream.write_body(wire_body).await.unwrap().unwrap(); + assert_eq!(wire_body.len(), n); + let n = http_stream.finish_body().await.unwrap().unwrap(); + assert_eq!(wire_body.len(), n); + } + + #[tokio::test] + async fn write_body_http10() { + let wire_header = b"HTTP/1.1 200 OK\r\n\r\n"; + let wire_body = b"a"; + let mock_io = Builder::new().write(wire_header).write(wire_body).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + let new_response = ResponseHeader::build(StatusCode::OK, None).unwrap(); + http_stream.update_resp_headers = false; + http_stream + .write_response_header_ref(&new_response) + .await + .unwrap(); + assert_eq!(http_stream.body_writer.body_mode, BodyMode::HTTP1_0(0)); + let n = http_stream.write_body(wire_body).await.unwrap().unwrap(); + assert_eq!(wire_body.len(), n); + let n = http_stream.finish_body().await.unwrap().unwrap(); + assert_eq!(wire_body.len(), n); + } + + #[tokio::test] + async fn write_body_chunk() { + let wire_header = b"HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"; + let wire_body = b"1\r\na\r\n"; + let wire_end = b"0\r\n\r\n"; + let mock_io = Builder::new() + .write(wire_header) + .write(wire_body) + .write(wire_end) + .build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + let mut new_response = ResponseHeader::build(StatusCode::OK, None).unwrap(); + new_response + .append_header("Transfer-Encoding", "chunked") + .unwrap(); + http_stream.update_resp_headers = false; + http_stream + .write_response_header_ref(&new_response) + .await + .unwrap(); + assert_eq!( + http_stream.body_writer.body_mode, + BodyMode::ChunkedEncoding(0) + ); + let n = http_stream.write_body(b"a").await.unwrap().unwrap(); + assert_eq!(b"a".len(), n); + let n = http_stream.finish_body().await.unwrap().unwrap(); + assert_eq!(b"a".len(), n); + } + + #[tokio::test] + async fn read_with_illegal() { + init_log(); + let input1 = b"GET /a?q=b c HTTP/1.1\r\n"; + let input2 = b"Host: pingora.org\r\nContent-Length: 3\r\n\r\n"; + let input3 = b"abc"; + let mock_io = Builder::new() + .read(&input1[..]) + .read(&input2[..]) + .read(&input3[..]) + .build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + http_stream.read_request().await.unwrap(); + assert_eq!(http_stream.get_path(), &b"/a?q=b%20c"[..]); + let res = http_stream.read_body().await.unwrap().unwrap(); + assert_eq!(res, BufRef::new(0, 3)); + assert_eq!(http_stream.body_reader.body_state, ParseState::Complete(3)); + assert_eq!(input3, http_stream.get_body(&res)); + } + + #[test] + fn escape_illegal() { + init_log(); + // in query string + let input = BytesMut::from( + &b"GET /a?q=<\"b c\"> HTTP/1.1\r\nHost: pingora.org\r\nContent-Length: 3\r\n\r\n"[..], + ); + let output = escape_illegal_request_line(&input).unwrap(); + assert_eq!( + &output, + &b"GET /a?q=%3C%22b%20c%22%3E HTTP/1.1\r\nHost: pingora.org\r\nContent-Length: 3\r\n\r\n"[..] + ); + + // in path + let input = BytesMut::from( + &b"GET /a:\"bc\" HTTP/1.1\r\nHost: pingora.org\r\nContent-Length: 3\r\n\r\n"[..], + ); + let output = escape_illegal_request_line(&input).unwrap(); + assert_eq!( + &output, + &b"GET /a:%22bc%22 HTTP/1.1\r\nHost: pingora.org\r\nContent-Length: 3\r\n\r\n"[..] + ); + + // empty uri, unable to parse + let input = + BytesMut::from(&b"GET HTTP/1.1\r\nHost: pingora.org\r\nContent-Length: 3\r\n\r\n"[..]); + assert!(escape_illegal_request_line(&input).is_none()); + } + + #[tokio::test] + async fn test_write_body_buf() { + let wire = b"HTTP/1.1 200 OK\r\nFoo: Bar\r\n\r\n"; + let mock_io = Builder::new().write(wire).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + let mut new_response = ResponseHeader::build(StatusCode::OK, None).unwrap(); + new_response.append_header("Foo", "Bar").unwrap(); + http_stream.update_resp_headers = false; + http_stream + .write_response_header_ref(&new_response) + .await + .unwrap(); + let written = http_stream.write_body_buf().await.unwrap(); + assert!(written.is_none()); + } + + #[tokio::test] + async fn test_write_continue_resp() { + let wire = b"HTTP/1.1 100 Continue\r\n\r\n"; + let mock_io = Builder::new().write(wire).build(); + let mut http_stream = HttpSession::new(Box::new(mock_io)); + http_stream.write_continue_response().await.unwrap(); + } + + #[test] + fn test_is_upgrade_resp() { + let mut response = ResponseHeader::build(StatusCode::SWITCHING_PROTOCOLS, None).unwrap(); + response.set_version(http::Version::HTTP_11); + response.insert_header("Upgrade", "websocket").unwrap(); + response.insert_header("Connection", "upgrade").unwrap(); + assert!(is_upgrade_resp(&response)); + + // wrong http version + response.set_version(http::Version::HTTP_10); + response.insert_header("Upgrade", "websocket").unwrap(); + response.insert_header("Connection", "upgrade").unwrap(); + assert!(!is_upgrade_resp(&response)); + + // not 101 + response.set_status(http::StatusCode::OK).unwrap(); + response.set_version(http::Version::HTTP_11); + assert!(!is_upgrade_resp(&response)); + } +} + +#[cfg(test)] +mod test_sync { + use super::*; + use http::StatusCode; + use log::{debug, error}; + use std::str; + + fn init_log() { + let _ = env_logger::builder().is_test(true).try_init(); + } + + #[test] + fn test_response_to_wire() { + init_log(); + let mut new_response = ResponseHeader::build(StatusCode::OK, None).unwrap(); + new_response.append_header("Foo", "Bar").unwrap(); + let mut wire = BytesMut::with_capacity(INIT_HEADER_BUF_SIZE); + http_resp_header_to_buf(&new_response, &mut wire).unwrap(); + debug!("{}", str::from_utf8(wire.as_ref()).unwrap()); + let mut headers = [httparse::EMPTY_HEADER; 128]; + let mut resp = httparse::Response::new(&mut headers); + let result = resp.parse(wire.as_ref()); + match result { + Ok(_) => {} + Err(e) => error!("{:?}", e), + } + assert!(result.unwrap().is_complete()); + // FIXME: the order is not guaranteed + assert_eq!(b"Foo", headers[0].name.as_bytes()); + assert_eq!(b"Bar", headers[0].value); + } +} diff --git a/pingora-core/src/protocols/http/v2/client.rs b/pingora-core/src/protocols/http/v2/client.rs new file mode 100644 index 0000000..48551ec --- /dev/null +++ b/pingora-core/src/protocols/http/v2/client.rs @@ -0,0 +1,480 @@ +// 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. + +//! HTTP/2 client session and connection +// TODO: this module needs a refactor + +use bytes::Bytes; +use h2::client::{self, ResponseFuture, SendRequest}; +use h2::{Reason, RecvStream, SendStream}; +use http::HeaderMap; +use log::{debug, error, warn}; +use pingora_error::{Error, ErrorType, ErrorType::*, OrErr, Result, RetryType}; +use pingora_http::{RequestHeader, ResponseHeader}; +use pingora_timeout::timeout; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::Arc; +use std::time::Duration; +use tokio::io::{AsyncRead, AsyncWrite}; +use tokio::sync::watch; + +use crate::connectors::http::v2::ConnectionRef; +use crate::protocols::Digest; + +pub const PING_TIMEDOUT: ErrorType = ErrorType::new("PingTimedout"); + +pub struct Http2Session { + send_req: SendRequest, + send_body: Option>, + resp_fut: Option, + req_sent: Option>, + response_header: Option, + response_body_reader: Option, + /// The read timeout, which will be applied to both reading the header and the body. + /// The timeout is reset on every read. This is not a timeout on the overall duration of the + /// response. + pub read_timeout: Option, + pub(crate) conn: ConnectionRef, + // Indicate that whether a END_STREAM is already sent + ended: bool, +} + +impl Drop for Http2Session { + fn drop(&mut self) { + self.conn.release_stream(); + } +} + +impl Http2Session { + pub(crate) fn new(send_req: SendRequest, conn: ConnectionRef) -> Self { + Http2Session { + send_req, + send_body: None, + resp_fut: None, + req_sent: None, + response_header: None, + response_body_reader: None, + read_timeout: None, + conn, + ended: false, + } + } + + fn sanitize_request_header(req: &mut RequestHeader) -> Result<()> { + req.set_version(http::Version::HTTP_2); + if req.uri.authority().is_some() { + return Ok(()); + } + // use host header to populate :authority field + let Some(authority) = req.headers.get(http::header::HOST).map(|v| v.as_bytes()) else { + return Error::e_explain(InvalidHTTPHeader, "no authority header for h2"); + }; + let uri = http::uri::Builder::new() + .scheme("https") // fixed for now + .authority(authority) + .path_and_query(req.uri.path_and_query().as_ref().unwrap().as_str()) + .build(); + match uri { + Ok(uri) => { + req.set_uri(uri); + Ok(()) + } + Err(_) => Error::e_explain( + InvalidHTTPHeader, + format!("invalid authority from host {authority:?}"), + ), + } + } + + /// Write the request header to the server + pub fn write_request_header(&mut self, mut req: Box, end: bool) -> Result<()> { + if self.req_sent.is_some() { + // cannot send again, TODO: warn + return Ok(()); + } + Self::sanitize_request_header(&mut req)?; + let parts = req.as_owned_parts(); + let request = http::Request::from_parts(parts, ()); + // There is no write timeout for h2 because the actual write happens async from this fn + let (resp_fut, send_body) = self + .send_req + .send_request(request, end) + .or_err(H2Error, "while sending request") + .map_err(|e| self.handle_err(e))?; + self.req_sent = Some(req); + self.send_body = Some(send_body); + self.resp_fut = Some(resp_fut); + self.ended = self.ended || end; + + Ok(()) + } + + /// Write a request body chunk + pub fn write_request_body(&mut self, data: Bytes, end: bool) -> Result<()> { + if self.ended { + warn!("Try to write request body after end of stream, dropping the extra data"); + return Ok(()); + } + + let body_writer = self + .send_body + .as_mut() + .expect("Try to write request body before sending request header"); + + write_body(body_writer, data, end).map_err(|e| self.handle_err(e))?; + self.ended = self.ended || end; + Ok(()) + } + + /// Signal that the request body has ended + pub fn finish_request_body(&mut self) -> Result<()> { + if self.ended { + return Ok(()); + } + + let body_writer = self + .send_body + .as_mut() + .expect("Try to finish request stream before sending request header"); + + // Just send an empty data frame with end of stream set + body_writer + .send_data("".into(), true) + .or_err(WriteError, "while writing empty h2 request body") + .map_err(|e| self.handle_err(e))?; + self.ended = true; + Ok(()) + } + + /// Read the response header + pub async fn read_response_header(&mut self) -> Result<()> { + // TODO: how to read 1xx headers? + // https://github.com/hyperium/h2/issues/167 + + if self.response_header.is_some() { + panic!("H2 response header is already read") + } + + let Some(resp_fut) = self.resp_fut.take() else { + panic!("Try to response header is already read") + }; + + let res = match self.read_timeout { + Some(t) => timeout(t, resp_fut) + .await + .map_err(|_| Error::explain(ReadTimedout, "while reading h2 response header")) + .map_err(|e| self.handle_err(e))?, + None => resp_fut.await, + }; + let (resp, body_reader) = res.map_err(handle_read_header_error)?.into_parts(); + self.response_header = Some(resp.into()); + self.response_body_reader = Some(body_reader); + + Ok(()) + } + + /// Read the response body + /// + /// `None` means, no more body to read + pub async fn read_response_body(&mut self) -> Result> { + let Some(body_reader) = self.response_body_reader.as_mut() else { + // req is not sent or response is already read + // TODO: warn + return Ok(None); + }; + + if body_reader.is_end_stream() { + return Ok(None); + } + + let fut = body_reader.data(); + let res = match self.read_timeout { + Some(t) => timeout(t, fut) + .await + .map_err(|_| Error::explain(ReadTimedout, "while reading h2 response body"))?, + None => fut.await, + }; + let body = res + .transpose() + .or_err(ReadError, "while read h2 response body") + .map_err(|mut e| { + // cannot use handle_err() because of borrow checker + if self.conn.ping_timedout() { + e.etype = PING_TIMEDOUT; + } + e + })?; + + if let Some(data) = body.as_ref() { + body_reader + .flow_control() + .release_capacity(data.len()) + .or_err(ReadError, "while releasing h2 response body capacity")?; + } + + Ok(body) + } + + /// Whether the response has ended + pub fn response_finished(&self) -> bool { + // if response_body_reader doesn't exist, the response is not even read yet + self.response_body_reader + .as_ref() + .map_or(false, |reader| reader.is_end_stream()) + } + + /// Read the optional trailer headers + pub async fn read_trailers(&mut self) -> Result> { + let Some(reader) = self.response_body_reader.as_mut() else { + // response is not even read + // TODO: warn + return Ok(None); + }; + let fut = reader.trailers(); + + let res = match self.read_timeout { + Some(t) => timeout(t, fut) + .await + .map_err(|_| Error::explain(ReadTimedout, "while reading h2 trailer")) + .map_err(|e| self.handle_err(e))?, + None => fut.await, + }; + match res { + Ok(t) => Ok(t), + Err(e) => { + // GOAWAY with no error: this is graceful shutdown, continue as if no trailer + // RESET_STREAM with no error: https://datatracker.ietf.org/doc/html/rfc9113#section-8.1: + // this is to signal client to stop uploading request without breaking the response. + // TODO: should actually stop uploading + // TODO: should we try reading again? + // TODO: handle this when reading headers and body as well + // https://github.com/hyperium/h2/issues/741 + + if (e.is_go_away() || e.is_reset()) + && e.is_remote() + && e.reason() == Some(Reason::NO_ERROR) + { + Ok(None) + } else { + Err(e) + } + } + } + .or_err(ReadError, "while reading h2 trailers") + } + + /// The response header if it is already read + pub fn response_header(&self) -> Option<&ResponseHeader> { + self.response_header.as_ref() + } + + /// Give up the http session abruptly. + pub fn shutdown(&mut self) { + if !self.ended || !self.response_finished() { + if let Some(send_body) = self.send_body.as_mut() { + send_body.send_reset(h2::Reason::INTERNAL_ERROR) + } + } + } + + /// Drop everything in this h2 stream. Return the connection ref. + /// After this function the underlying h2 connection should already notify the closure of this + /// stream so that another stream can be created if needed. + pub(crate) fn conn(&self) -> ConnectionRef { + self.conn.clone() + } + + /// Whether ping timeout occurred. After a ping timeout, the h2 connection will be terminated. + /// Ongoing h2 streams will receive an stream/connection error. The streams should check this + /// flag to tell whether the error is triggered by the timeout. + pub(crate) fn ping_timedout(&self) -> bool { + self.conn.ping_timedout() + } + + /// Return the [Digest] of the connection + /// + /// For reused connection, the timing in the digest will reflect its initial handshakes + /// The caller should check if the connection is reused to avoid misuse the timing field + pub fn digest(&self) -> Option<&Digest> { + Some(self.conn.digest()) + } + + /// the FD of the underlying connection + pub fn fd(&self) -> i32 { + self.conn.id() + } + + /// take the body sender to another task to perform duplex read and write + pub fn take_request_body_writer(&mut self) -> Option> { + self.send_body.take() + } + + fn handle_err(&self, mut e: Box) -> Box { + if self.ping_timedout() { + e.etype = PING_TIMEDOUT; + } + e + } +} + +/// A helper function to write the request body +pub fn write_body(send_body: &mut SendStream, data: Bytes, end: bool) -> Result<()> { + let data_len = data.len(); + send_body.reserve_capacity(data_len); + send_body + .send_data(data, end) + .or_err(WriteError, "while writing h2 request body") +} + +/* helper functions */ + +/* Types of errors during h2 header read + 1. peer requests to downgrade to h1, mostly IIS server for NTLM: we will downgrade and retry + 2. peer sends invalid h2 frames, usually sending h1 only header: we will downgrade and retry + 3. peer sends GO_AWAY(NO_ERROR) on reused conn, usually hit http2_max_requests: we will retry + 4. peer IO error on reused conn, usually firewall kills old conn: we will retry + 5. All other errors will terminate the request +*/ +fn handle_read_header_error(e: h2::Error) -> Box { + if e.is_remote() + && e.reason() + .map_or(false, |r| r == h2::Reason::HTTP_1_1_REQUIRED) + { + let mut err = Error::because(H2Downgrade, "while reading h2 header", e); + err.retry = true.into(); + err + } else if e.is_go_away() + && e.is_library() + && e.reason() + .map_or(false, |r| r == h2::Reason::PROTOCOL_ERROR) + { + // remote send invalid H2 responses + let mut err = Error::because(InvalidH2, "while reading h2 header", e); + err.retry = true.into(); + err + } else if e.is_go_away() + && e.is_remote() + && e.reason().map_or(false, |r| r == h2::Reason::NO_ERROR) + { + // is_go_away: retry via another connection, this connection is being teardown + // only retry if the connection is reused + let mut err = Error::because(H2Error, "while reading h2 header", e); + err.retry = RetryType::ReusedOnly; + err + } else if e.is_io() { + // is_io: typical if a previously reused connection silently drops it + // only retry if the connection is reused + let true_io_error = e.get_io().unwrap().raw_os_error().is_some(); + let mut err = Error::because(ReadError, "while reading h2 header", e); + if true_io_error { + err.retry = RetryType::ReusedOnly; + } // else could be TLS error, which is unsafe to retry + err + } else { + Error::because(H2Error, "while reading h2 header", e) + } +} + +use tokio::sync::oneshot; + +pub async fn drive_connection( + mut c: client::Connection, + id: i32, + closed: watch::Sender, + ping_interval: Option, + ping_timeout_occurred: Arc, +) where + S: AsyncRead + AsyncWrite + Send + Unpin, +{ + let interval = ping_interval.unwrap_or(Duration::ZERO); + if !interval.is_zero() { + // for ping to inform this fn to drop the connection + let (tx, rx) = oneshot::channel::<()>(); + // for this fn to inform ping to give up when it is already dropped + let dropped = Arc::new(AtomicBool::new(false)); + let dropped2 = dropped.clone(); + + if let Some(ping_pong) = c.ping_pong() { + pingora_runtime::current_handle().spawn(async move { + do_ping_pong(ping_pong, interval, tx, dropped2, id).await; + }); + } else { + warn!("Cannot get ping-pong handler from h2 connection"); + } + + tokio::select! { + r = c => match r { + Ok(_) => debug!("H2 connection finished fd: {id}"), + Err(e) => debug!("H2 connection fd: {id} errored: {e:?}"), + }, + r = rx => match r { + Ok(_) => { + ping_timeout_occurred.store(true, Ordering::Relaxed); + warn!("H2 connection Ping timeout/Error fd: {id}, closing conn"); + }, + Err(e) => warn!("H2 connection Ping Rx error {e:?}"), + }, + }; + + dropped.store(true, Ordering::Relaxed); + } else { + match c.await { + Ok(_) => debug!("H2 connection finished fd: {id}"), + Err(e) => debug!("H2 connection fd: {id} errored: {e:?}"), + } + } + let _ = closed.send(true); +} + +const PING_TIMEOUT: Duration = Duration::from_secs(5); + +async fn do_ping_pong( + mut ping_pong: h2::PingPong, + interval: Duration, + tx: oneshot::Sender<()>, + dropped: Arc, + id: i32, +) { + // delay before sending the first ping, no need to race with the first request + tokio::time::sleep(interval).await; + loop { + if dropped.load(Ordering::Relaxed) { + break; + } + let ping_fut = ping_pong.ping(h2::Ping::opaque()); + debug!("H2 fd: {id} ping sent"); + match tokio::time::timeout(PING_TIMEOUT, ping_fut).await { + Err(_) => { + error!("H2 fd: {id} ping timeout"); + let _ = tx.send(()); + break; + } + Ok(r) => match r { + Ok(_) => { + debug!("H2 fd: {} pong received", id); + tokio::time::sleep(interval).await; + } + Err(e) => { + if dropped.load(Ordering::Relaxed) { + // drive_connection() exits first, no need to error again + break; + } + error!("H2 fd: {id} ping error: {e}"); + let _ = tx.send(()); + break; + } + }, + } + } +} diff --git a/pingora-core/src/protocols/http/v2/mod.rs b/pingora-core/src/protocols/http/v2/mod.rs new file mode 100644 index 0000000..8b10430 --- /dev/null +++ b/pingora-core/src/protocols/http/v2/mod.rs @@ -0,0 +1,18 @@ +// 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. + +//! HTTP/2 implementation + +pub mod client; +pub mod server; diff --git a/pingora-core/src/protocols/http/v2/server.rs b/pingora-core/src/protocols/http/v2/server.rs new file mode 100644 index 0000000..6ec75e8 --- /dev/null +++ b/pingora-core/src/protocols/http/v2/server.rs @@ -0,0 +1,488 @@ +// 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. + +//! HTTP/2 server session + +use bytes::Bytes; +use futures::Future; +use h2::server; +use h2::server::SendResponse; +use h2::{RecvStream, SendStream}; +use http::header::HeaderName; +use http::{header, Response}; +use log::{debug, warn}; +use pingora_http::{RequestHeader, ResponseHeader}; + +use crate::protocols::http::body_buffer::FixedBuffer; +use crate::protocols::http::date::get_cached_date; +use crate::protocols::http::v1::client::http_req_header_to_wire; +use crate::protocols::http::HttpTask; +use crate::protocols::Stream; +use crate::{Error, ErrorType, OrErr, Result}; + +const BODY_BUF_LIMIT: usize = 1024 * 64; + +type H2Connection = server::Connection; + +pub use h2::server::Builder as H2Options; + +/// Perform HTTP/2 connection handshake with an established (TLS) connection. +/// +/// The optional `options` allow to adjust certain HTTP/2 parameters and settings. +/// See [`H2Options`] for more details. +pub async fn handshake(io: Stream, options: Option) -> Result> { + let options = options.unwrap_or_default(); + let res = options.handshake(io).await; + match res { + Ok(connection) => { + debug!("H2 handshake done."); + Ok(connection) + } + Err(e) => Error::e_because( + ErrorType::HandshakeError, + "while h2 handshaking with client", + e, + ), + } +} + +use futures::task::Context; +use futures::task::Poll; +use std::pin::Pin; +/// The future to poll for an idle session. +/// +/// Calling `.await` in this object will not return until the client decides to close this stream. +pub struct Idle<'a>(&'a mut HttpSession); + +impl<'a> Future for Idle<'a> { + type Output = Result; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + if let Some(body_writer) = self.0.send_response_body.as_mut() { + body_writer.poll_reset(cx) + } else { + self.0.send_response.poll_reset(cx) + } + .map_err(|e| Error::because(ErrorType::H2Error, "downstream error while idling", e)) + } +} + +/// HTTP/2 server session +pub struct HttpSession { + request_header: RequestHeader, + request_body_reader: RecvStream, + send_response: SendResponse, + send_response_body: Option>, + // Remember what has been written + response_written: Option>, + // Indicate that whether a END_STREAM is already sent + // in order to tell whether needs to send one extra FRAME when this response finishes + ended: bool, + // How many request body bytes have been read so far. + body_read: usize, + // How many response body bytes have been sent so far. + body_sent: usize, + // buffered request body for retry logic + retry_buffer: Option, +} + +impl HttpSession { + /// Create a new [`HttpSession`] from the HTTP/2 connection. + /// This function returns a new HTTP/2 session when the provided HTTP/2 connection, `conn`, + /// establishes a new HTTP/2 stream to this server. + /// + /// Note: in order to handle all **existing** and new HTTP/2 sessions, the server must call + /// this function in a loop until the client decides to close the connection. + /// + /// `None` will be returned when the connection is closing so that the loop can exit. + pub async fn from_h2_conn(conn: &mut H2Connection) -> Result> { + // NOTE: conn.accept().await is what drives the entire connection. + let res = conn.accept().await.transpose().or_err( + ErrorType::H2Error, + "while accepting new downstream requests", + )?; + + Ok(res.map(|(req, send_response)| { + let (request_header, request_body_reader) = req.into_parts(); + HttpSession { + request_header: request_header.into(), + request_body_reader, + send_response, + send_response_body: None, + response_written: None, + ended: false, + body_read: 0, + body_sent: 0, + retry_buffer: None, + } + })) + } + + /// The request sent from the client + /// + /// Different from its HTTP/1.X counterpart, this function never panics as the request is already + /// read when established a new HTTP/2 stream. + pub fn req_header(&self) -> &RequestHeader { + &self.request_header + } + + /// A mutable reference to request sent from the client + /// + /// Different from its HTTP/1.X counterpart, this function never panics as the request is already + /// read when established a new HTTP/2 stream. + pub fn req_header_mut(&mut self) -> &mut RequestHeader { + &mut self.request_header + } + + /// Read request body bytes. `None` when there is no more body to read. + pub async fn read_body_bytes(&mut self) -> Result> { + // TODO: timeout + let data = self.request_body_reader.data().await.transpose().or_err( + ErrorType::ReadError, + "while reading downstream request body", + )?; + if let Some(data) = data.as_ref() { + self.body_read += data.len(); + if let Some(buffer) = self.retry_buffer.as_mut() { + buffer.write_to_buffer(data); + } + let _ = self + .request_body_reader + .flow_control() + .release_capacity(data.len()); + } + Ok(data) + } + + // the write_* don't have timeouts because the actual writing happens on the connection + // not here. + + /// Write the response header to the client. + /// # the `end` flag + /// `end` marks the end of this session. + /// If the `end` flag is set, no more header or body can be sent to the client. + pub fn write_response_header( + &mut self, + mut header: Box, + end: bool, + ) -> Result<()> { + if self.ended { + // TODO: error or warn? + return Ok(()); + } + + // FIXME: we should ignore 1xx header because send_response() can only be called once + // https://github.com/hyperium/h2/issues/167 + + if let Some(resp) = self.response_written.as_ref() { + if !resp.status.is_informational() { + warn!("Respond header is already sent, cannot send again"); + return Ok(()); + } + } + + // no need to add these headers to 1xx responses + if !header.status.is_informational() { + /* update headers */ + header.insert_header(header::DATE, get_cached_date())?; + } + + // remove other h1 hop headers that cannot be present in H2 + // https://httpwg.org/specs/rfc7540.html#n-connection-specific-header-fields + header.remove_header(&header::TRANSFER_ENCODING); + header.remove_header(&header::CONNECTION); + header.remove_header(&header::UPGRADE); + header.remove_header(&HeaderName::from_static("keep-alive")); + header.remove_header(&HeaderName::from_static("proxy-connection")); + + let resp = Response::from_parts(header.as_owned_parts(), ()); + + let body_writer = self.send_response.send_response(resp, end).or_err( + ErrorType::WriteError, + "while writing h2 response to downstream", + )?; + + self.response_written = Some(header); + self.send_response_body = Some(body_writer); + self.ended = self.ended || end; + Ok(()) + } + + /// Write response body to the client. See [Self::write_response_header] for how to use `end`. + pub fn write_body(&mut self, data: Bytes, end: bool) -> Result<()> { + if self.ended { + // NOTE: in h1, we also track to see if content-length matches the data + // We have not tracked that in h2 + warn!("Try to write body after end of stream, dropping the extra data"); + return Ok(()); + } + let Some(writer) = self.send_response_body.as_mut() else { + return Err(Error::explain( + ErrorType::H2Error, + "try to send body before header is sent", + )); + }; + let data_len = data.len(); + writer.reserve_capacity(data_len); + writer.send_data(data, end).or_err( + ErrorType::WriteError, + "while writing h2 response body to downstream", + )?; + self.body_sent += data_len; + self.ended = self.ended || end; + Ok(()) + } + + /// Similar to [Self::write_response_header], this function takes a reference instead + pub fn write_response_header_ref(&mut self, header: &ResponseHeader, end: bool) -> Result<()> { + self.write_response_header(Box::new(header.clone()), end) + } + + // TODO: trailer + + /// Mark the session end. If no `end` flag is already set before this call, this call will + /// signal the client. Otherwise this call does nothing. + /// + /// Dropping this object without sending `end` will cause an error to the client, which will cause + /// the client to treat this session as bad or incomplete. + pub fn finish(&mut self) -> Result<()> { + if self.ended { + // already ended the stream + return Ok(()); + } + if let Some(writer) = self.send_response_body.as_mut() { + // use an empty data frame to signal the end + writer.send_data("".into(), true).or_err( + ErrorType::WriteError, + "while writing h2 response body to downstream", + )?; + self.ended = true; + }; + // else: the response header is not sent, do nothing now. + // When send_response_body is dropped, an RST_STREAM will be sent + + Ok(()) + } + + pub fn response_duplex_vec(&mut self, tasks: Vec) -> Result { + let mut end_stream = false; + for task in tasks.into_iter() { + end_stream = match task { + HttpTask::Header(header, end) => { + self.write_response_header(header, end) + .map_err(|e| e.into_down())?; + end + } + HttpTask::Body(data, end) => match data { + Some(d) => { + if !d.is_empty() { + self.write_body(d, end).map_err(|e| e.into_down())?; + } + end + } + None => end, + }, + HttpTask::Trailer(_) => true, // trailer is not supported yet + HttpTask::Done => { + self.finish().map_err(|e| e.into_down())?; + return Ok(true); + } + HttpTask::Failed(e) => { + return Err(e); + } + } || end_stream // safe guard in case `end` in tasks flips from true to false + } + Ok(end_stream) + } + + /// Return a string `$METHOD $PATH $HOST`. Mostly for logging and debug purpose + pub fn request_summary(&self) -> String { + format!( + "{} {}, Host: {}", + self.request_header.method, + self.request_header.uri, + self.request_header + .headers + .get(header::HOST) + .map(|v| String::from_utf8_lossy(v.as_bytes())) + .unwrap_or_default() + ) + } + + /// Return the written response header. `None` if it is not written yet. + pub fn response_written(&self) -> Option<&ResponseHeader> { + self.response_written.as_deref() + } + + /// Give up the stream abruptly. + /// + /// This will send a `INTERNAL_ERROR` stream error to the client + pub fn shutdown(&mut self) { + if !self.ended { + self.send_response.send_reset(h2::Reason::INTERNAL_ERROR); + } + } + + // This is a hack for pingora-proxy to create subrequests from h2 server session + // TODO: be able to convert from h2 to h1 subrequest + pub fn pseudo_raw_h1_request_header(&self) -> Bytes { + let buf = http_req_header_to_wire(&self.request_header).unwrap(); // safe, None only when version unknown + buf.freeze() + } + + /// Whether there is no more body to read + pub fn is_body_done(&self) -> bool { + self.request_body_reader.is_end_stream() + } + + /// Whether there is any body to read. + pub fn is_body_empty(&self) -> bool { + self.body_read == 0 + && (self.is_body_done() + || self + .request_header + .headers + .get(header::CONTENT_LENGTH) + .map_or(false, |cl| cl.as_bytes() == b"0")) + } + + pub fn retry_buffer_truncated(&self) -> bool { + self.retry_buffer + .as_ref() + .map_or_else(|| false, |r| r.is_truncated()) + } + + pub fn enable_retry_buffering(&mut self) { + if self.retry_buffer.is_none() { + self.retry_buffer = Some(FixedBuffer::new(BODY_BUF_LIMIT)) + } + } + + pub fn get_retry_buffer(&self) -> Option { + self.retry_buffer.as_ref().and_then(|b| { + if b.is_truncated() { + None + } else { + b.get_buffer() + } + }) + } + + /// `async fn idle() -> Result;` + /// This async fn will be pending forever until the client closes the stream/connection + /// This function is used for watching client status so that the server is able to cancel + /// its internal tasks as the client waiting for the tasks goes away + pub fn idle(&mut self) -> Idle { + Idle(self) + } + + /// Similar to `read_body_bytes()` but will be pending after Ok(None) is returned, + /// until the client closes the connection + pub async fn read_body_or_idle(&mut self, no_body_expected: bool) -> Result> { + if no_body_expected || self.is_body_done() { + let reason = self.idle().await?; + Error::e_explain( + ErrorType::H2Error, + format!("Client closed H2, reason: {reason}"), + ) + } else { + self.read_body_bytes().await + } + } + + /// How many response body bytes sent to the client + pub fn body_bytes_sent(&self) -> usize { + self.body_sent + } +} + +#[cfg(test)] +mod test { + use super::*; + use http::{Method, Request}; + use tokio::io::duplex; + + #[tokio::test] + async fn test_server_handshake_accept_request() { + let (client, server) = duplex(65536); + let client_body = "test client body"; + let server_body = "test server body"; + + tokio::spawn(async move { + let (h2, connection) = h2::client::handshake(client).await.unwrap(); + tokio::spawn(async move { + connection.await.unwrap(); + }); + + let mut h2 = h2.ready().await.unwrap(); + + let request = Request::builder() + .method(Method::GET) + .uri("https://www.example.com/") + .body(()) + .unwrap(); + + let (response, mut req_body) = h2.send_request(request, false).unwrap(); + req_body.reserve_capacity(client_body.len()); + req_body.send_data(client_body.into(), true).unwrap(); + + let (head, mut body) = response.await.unwrap().into_parts(); + assert_eq!(head.status, 200); + let data = body.data().await.unwrap().unwrap(); + assert_eq!(data, server_body); + }); + + let mut connection = handshake(Box::new(server), None).await.unwrap(); + + while let Some(mut http) = HttpSession::from_h2_conn(&mut connection).await.unwrap() { + tokio::spawn(async move { + let req = http.req_header(); + assert_eq!(req.method, Method::GET); + assert_eq!(req.uri, "https://www.example.com/"); + + http.enable_retry_buffering(); + + assert!(!http.is_body_empty()); + assert!(!http.is_body_done()); + + let body = http.read_body_or_idle(false).await.unwrap().unwrap(); + assert_eq!(body, client_body); + assert!(http.is_body_done()); + + let retry_body = http.get_retry_buffer().unwrap(); + assert_eq!(retry_body, client_body); + + // test idling before response header is sent + tokio::select! { + _ = http.idle() => {panic!("downstream should be idling")}, + _= tokio::time::sleep(tokio::time::Duration::from_secs(1)) => {} + } + + let response_header = Box::new(ResponseHeader::build(200, None).unwrap()); + http.write_response_header(response_header, false).unwrap(); + + // test idling after response header is sent + tokio::select! { + _ = http.read_body_or_idle(false) => {panic!("downstream should be idling")}, + _= tokio::time::sleep(tokio::time::Duration::from_secs(1)) => {} + } + + // end: false here to verify finish() closes the stream nicely + http.write_body(server_body.into(), false).unwrap(); + + http.finish().unwrap(); + }); + } + } +} diff --git a/pingora-core/src/protocols/l4/ext.rs b/pingora-core/src/protocols/l4/ext.rs new file mode 100644 index 0000000..331a852 --- /dev/null +++ b/pingora-core/src/protocols/l4/ext.rs @@ -0,0 +1,297 @@ +// 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. + +//! Extensions to the regular TCP APIs + +#![allow(non_camel_case_types)] + +use libc::socklen_t; +#[cfg(target_os = "linux")] +use libc::{c_int, c_void}; +use pingora_error::{Error, ErrorType::*, OrErr, Result}; +use std::io::{self, ErrorKind}; +use std::mem; +use std::net::SocketAddr; +use std::os::unix::io::{AsRawFd, RawFd}; +use std::time::Duration; +use tokio::net::{TcpSocket, TcpStream, UnixStream}; + +/// The (copy of) the kernel struct tcp_info returns +#[repr(C)] +#[derive(Copy, Clone, Debug)] +pub struct TCP_INFO { + tcpi_state: u8, + tcpi_ca_state: u8, + tcpi_retransmits: u8, + tcpi_probes: u8, + tcpi_backoff: u8, + tcpi_options: u8, + tcpi_snd_wscale_4_rcv_wscale_4: u8, + tcpi_delivery_rate_app_limited: u8, + tcpi_rto: u32, + tcpi_ato: u32, + tcpi_snd_mss: u32, + tcpi_rcv_mss: u32, + tcpi_unacked: u32, + tcpi_sacked: u32, + tcpi_lost: u32, + tcpi_retrans: u32, + tcpi_fackets: u32, + tcpi_last_data_sent: u32, + tcpi_last_ack_sent: u32, + tcpi_last_data_recv: u32, + tcpi_last_ack_recv: u32, + tcpi_pmtu: u32, + tcpi_rcv_ssthresh: u32, + pub tcpi_rtt: u32, + tcpi_rttvar: u32, + /* uncomment these field if needed + tcpi_snd_ssthresh: u32, + tcpi_snd_cwnd: u32, + tcpi_advmss: u32, + tcpi_reordering: u32, + tcpi_rcv_rtt: u32, + tcpi_rcv_space: u32, + tcpi_total_retrans: u32, + tcpi_pacing_rate: u64, + tcpi_max_pacing_rate: u64, + tcpi_bytes_acked: u64, + tcpi_bytes_received: u64, + tcpi_segs_out: u32, + tcpi_segs_in: u32, + tcpi_notsent_bytes: u32, + tcpi_min_rtt: u32, + tcpi_data_segs_in: u32, + tcpi_data_segs_out: u32, + tcpi_delivery_rate: u64, + */ + /* and more, see include/linux/tcp.h */ +} + +impl TCP_INFO { + /// Create a new zeroed out [`TCP_INFO`] + pub unsafe fn new() -> Self { + mem::zeroed() + } + + /// Return the size of [`TCP_INFO`] + pub fn len() -> socklen_t { + mem::size_of::() as socklen_t + } +} + +#[cfg(target_os = "linux")] +fn set_opt(sock: c_int, opt: c_int, val: c_int, payload: T) -> io::Result<()> { + unsafe { + let payload = &payload as *const T as *const c_void; + cvt_linux_error(libc::setsockopt( + sock, + opt, + val, + payload as *const _, + mem::size_of::() as socklen_t, + ))?; + Ok(()) + } +} + +#[cfg(target_os = "linux")] +fn get_opt( + sock: c_int, + opt: c_int, + val: c_int, + payload: &mut T, + size: &mut socklen_t, +) -> io::Result<()> { + unsafe { + let payload = payload as *mut T as *mut c_void; + cvt_linux_error(libc::getsockopt(sock, opt, val, payload as *mut _, size))?; + Ok(()) + } +} + +#[cfg(target_os = "linux")] +fn cvt_linux_error(t: i32) -> io::Result { + if t == -1 { + Err(io::Error::last_os_error()) + } else { + Ok(t) + } +} + +#[cfg(target_os = "linux")] +fn ip_bind_addr_no_port(fd: RawFd, val: bool) -> io::Result<()> { + const IP_BIND_ADDRESS_NO_PORT: i32 = 24; + + set_opt(fd, libc::IPPROTO_IP, IP_BIND_ADDRESS_NO_PORT, val as c_int) +} + +#[cfg(not(target_os = "linux"))] +fn ip_bind_addr_no_port(_fd: RawFd, _val: bool) -> io::Result<()> { + Ok(()) +} + +#[cfg(target_os = "linux")] +fn set_so_keepalive(fd: RawFd, val: bool) -> io::Result<()> { + set_opt(fd, libc::SOL_SOCKET, libc::SO_KEEPALIVE, val as c_int) +} + +#[cfg(target_os = "linux")] +fn set_so_keepalive_idle(fd: RawFd, val: Duration) -> io::Result<()> { + set_opt( + fd, + libc::IPPROTO_TCP, + libc::TCP_KEEPIDLE, + val.as_secs() as c_int, // only the seconds part of val is used + ) +} + +#[cfg(target_os = "linux")] +fn set_so_keepalive_interval(fd: RawFd, val: Duration) -> io::Result<()> { + set_opt( + fd, + libc::IPPROTO_TCP, + libc::TCP_KEEPINTVL, + val.as_secs() as c_int, // only the seconds part of val is used + ) +} + +#[cfg(target_os = "linux")] +fn set_so_keepalive_count(fd: RawFd, val: usize) -> io::Result<()> { + set_opt(fd, libc::IPPROTO_TCP, libc::TCP_KEEPCNT, val as c_int) +} + +#[cfg(target_os = "linux")] +fn set_keepalive(fd: RawFd, ka: &TcpKeepalive) -> io::Result<()> { + set_so_keepalive(fd, true)?; + set_so_keepalive_idle(fd, ka.idle)?; + set_so_keepalive_interval(fd, ka.interval)?; + set_so_keepalive_count(fd, ka.count) +} + +#[cfg(not(target_os = "linux"))] +fn set_keepalive(_fd: RawFd, _ka: &TcpKeepalive) -> io::Result<()> { + Ok(()) +} + +/// Get the kernel TCP_INFO for the given FD. +#[cfg(target_os = "linux")] +pub fn get_tcp_info(fd: RawFd) -> io::Result { + let mut tcp_info = unsafe { TCP_INFO::new() }; + let mut data_len: socklen_t = TCP_INFO::len(); + get_opt( + fd, + libc::IPPROTO_TCP, + libc::TCP_INFO, + &mut tcp_info, + &mut data_len, + )?; + if data_len != TCP_INFO::len() { + return Err(std::io::Error::new( + std::io::ErrorKind::Other, + "TCP_INFO struct size mismatch", + )); + } + Ok(tcp_info) +} + +#[cfg(not(target_os = "linux"))] +pub fn get_tcp_info(_fd: RawFd) -> io::Result { + Ok(unsafe { TCP_INFO::new() }) +} + +/* + * this extention is needed until the following are addressed + * https://github.com/tokio-rs/tokio/issues/1543 + * https://github.com/tokio-rs/mio/issues/1257 + * https://github.com/tokio-rs/mio/issues/1211 + */ +/// connect() to the given address while optionally bind to the specific source address +/// +/// `IP_BIND_ADDRESS_NO_PORT` is used. +pub async fn connect(addr: &SocketAddr, bind_to: Option<&SocketAddr>) -> Result { + let socket = if addr.is_ipv4() { + TcpSocket::new_v4() + } else { + TcpSocket::new_v6() + } + .or_err(SocketError, "failed to create socket")?; + + if cfg!(target_os = "linux") { + ip_bind_addr_no_port(socket.as_raw_fd(), true) + .or_err(SocketError, "failed to set socket opts")?; + + if let Some(baddr) = bind_to { + socket + .bind(*baddr) + .or_err_with(BindError, || format!("failed to bind to socket {}", *baddr))?; + }; + } + // TODO: add support for bind on other platforms + + socket + .connect(*addr) + .await + .map_err(|e| wrap_os_connect_error(e, format!("Fail to connect to {}", *addr))) +} + +/// connect() to the given Unix domain socket +pub async fn connect_uds(path: &std::path::Path) -> Result { + UnixStream::connect(path) + .await + .map_err(|e| wrap_os_connect_error(e, format!("Fail to connect to {}", path.display()))) +} + +fn wrap_os_connect_error(e: std::io::Error, context: String) -> Box { + match e.kind() { + ErrorKind::ConnectionRefused => Error::because(ConnectRefused, context, e), + ErrorKind::TimedOut => Error::because(ConnectTimedout, context, e), + ErrorKind::PermissionDenied | ErrorKind::AddrInUse | ErrorKind::AddrNotAvailable => { + Error::because(InternalError, context, e) + } + _ => match e.raw_os_error() { + Some(code) => match code { + libc::ENETUNREACH | libc::EHOSTUNREACH => { + Error::because(ConnectNoRoute, context, e) + } + _ => Error::because(ConnectError, context, e), + }, + None => Error::because(ConnectError, context, e), + }, + } +} + +/// The configuration for TCP keepalive +#[derive(Clone, Debug)] +pub struct TcpKeepalive { + /// The time a connection needs to be idle before TCP begins sending out keep-alive probes. + pub idle: Duration, + /// The number of seconds between TCP keep-alive probes. + pub interval: Duration, + /// The maximum number of TCP keep-alive probes to send before giving up and killing the connection + pub count: usize, +} + +impl std::fmt::Display for TcpKeepalive { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{:?}/{:?}/{}", self.idle, self.interval, self.count) + } +} + +/// Apply the given TCP keepalive settings to the given connection +pub fn set_tcp_keepalive(stream: &TcpStream, ka: &TcpKeepalive) -> Result<()> { + let fd = stream.as_raw_fd(); + // TODO: check localhost or if keepalive is already set + set_keepalive(fd, ka).or_err(ConnectError, "failed to set keepalive") +} diff --git a/pingora-core/src/protocols/l4/listener.rs b/pingora-core/src/protocols/l4/listener.rs new file mode 100644 index 0000000..6473fb4 --- /dev/null +++ b/pingora-core/src/protocols/l4/listener.rs @@ -0,0 +1,59 @@ +// 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. + +//! Listeners + +use std::io; +use std::os::unix::io::AsRawFd; +use tokio::net::{TcpListener, UnixListener}; + +use crate::protocols::l4::stream::Stream; + +/// The type for generic listener for both TCP and Unix domain socket +#[derive(Debug)] +pub enum Listener { + Tcp(TcpListener), + Unix(UnixListener), +} + +impl From for Listener { + fn from(s: TcpListener) -> Self { + Self::Tcp(s) + } +} + +impl From for Listener { + fn from(s: UnixListener) -> Self { + Self::Unix(s) + } +} + +impl AsRawFd for Listener { + fn as_raw_fd(&self) -> std::os::unix::prelude::RawFd { + match &self { + Self::Tcp(l) => l.as_raw_fd(), + Self::Unix(l) => l.as_raw_fd(), + } + } +} + +impl Listener { + /// Accept a connection from the listening endpoint + pub async fn accept(&self) -> io::Result { + match &self { + Self::Tcp(l) => l.accept().await.map(|(stream, _)| stream.into()), + Self::Unix(l) => l.accept().await.map(|(stream, _)| stream.into()), + } + } +} diff --git a/pingora-core/src/protocols/l4/mod.rs b/pingora-core/src/protocols/l4/mod.rs new file mode 100644 index 0000000..cfa65e0 --- /dev/null +++ b/pingora-core/src/protocols/l4/mod.rs @@ -0,0 +1,20 @@ +// 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. + +//! Transport layer protocol implementation + +pub mod ext; +pub mod listener; +pub mod socket; +pub mod stream; diff --git a/pingora-core/src/protocols/l4/socket.rs b/pingora-core/src/protocols/l4/socket.rs new file mode 100644 index 0000000..02eab36 --- /dev/null +++ b/pingora-core/src/protocols/l4/socket.rs @@ -0,0 +1,185 @@ +// 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. + +//! Generic socket type + +use crate::{Error, OrErr}; +use std::cmp::Ordering; +use std::hash::{Hash, Hasher}; +use std::net::SocketAddr as StdSockAddr; +use std::os::unix::net::SocketAddr as StdUnixSockAddr; + +/// [`SocketAddr`] is a storage type that contains either a Internet (IP address) +/// socket address or a Unix domain socket address. +#[derive(Debug, Clone)] +pub enum SocketAddr { + Inet(StdSockAddr), + Unix(StdUnixSockAddr), +} + +impl SocketAddr { + /// Get a reference to the IP socket if it is one + pub fn as_inet(&self) -> Option<&StdSockAddr> { + if let SocketAddr::Inet(addr) = self { + Some(addr) + } else { + None + } + } + + /// Get a reference to the Unix domain socket if it is one + pub fn as_unix(&self) -> Option<&StdUnixSockAddr> { + if let SocketAddr::Unix(addr) = self { + Some(addr) + } else { + None + } + } + + /// Set the port if the address is an IP socket. + pub fn set_port(&mut self, port: u16) { + if let SocketAddr::Inet(addr) = self { + addr.set_port(port) + } + } +} + +impl std::fmt::Display for SocketAddr { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + SocketAddr::Inet(addr) => write!(f, "{addr}"), + SocketAddr::Unix(addr) => { + if let Some(path) = addr.as_pathname() { + write!(f, "{}", path.display()) + } else { + write!(f, "{addr:?}") + } + } + } + } +} + +impl Hash for SocketAddr { + fn hash(&self, state: &mut H) { + match self { + Self::Inet(sockaddr) => sockaddr.hash(state), + Self::Unix(sockaddr) => { + if let Some(path) = sockaddr.as_pathname() { + // use the underlying path as the hash + path.hash(state); + } else { + // unnamed or abstract UDS + // abstract UDS name not yet exposed by std API + // panic for now, we can decide on the right way to hash them later + panic!("Unnamed and abstract UDS types not yet supported for hashing") + } + } + } + } +} + +impl PartialEq for SocketAddr { + fn eq(&self, other: &Self) -> bool { + match self { + Self::Inet(addr) => Some(addr) == other.as_inet(), + Self::Unix(addr) => { + let path = addr.as_pathname(); + // can only compare UDS with path, assume false on all unnamed UDS + path.is_some() && path == other.as_unix().and_then(|addr| addr.as_pathname()) + } + } + } +} + +impl PartialOrd for SocketAddr { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for SocketAddr { + fn cmp(&self, other: &Self) -> Ordering { + match self { + Self::Inet(addr) => { + if let Some(o) = other.as_inet() { + addr.cmp(o) + } else { + // always make Inet < Unix "smallest for variants at the top" + Ordering::Less + } + } + Self::Unix(addr) => { + if let Some(o) = other.as_unix() { + // NOTE: unnamed UDS are consider the same + addr.as_pathname().cmp(&o.as_pathname()) + } else { + // always make Inet < Unix "smallest for variants at the top" + Ordering::Greater + } + } + } + } +} + +impl Eq for SocketAddr {} + +impl std::str::FromStr for SocketAddr { + type Err = Box; + + // This is very basic parsing logic, it might treat invalid IP:PORT str as UDS path + // TODO: require UDS to have some prefix + fn from_str(s: &str) -> Result { + match StdSockAddr::from_str(s) { + Ok(addr) => Ok(SocketAddr::Inet(addr)), + Err(_) => { + let uds_socket = StdUnixSockAddr::from_pathname(s) + .or_err(crate::BindError, "invalid UDS path")?; + Ok(SocketAddr::Unix(uds_socket)) + } + } + } +} + +impl std::net::ToSocketAddrs for SocketAddr { + type Iter = std::iter::Once; + + // Error if UDS addr + fn to_socket_addrs(&self) -> std::io::Result { + if let Some(inet) = self.as_inet() { + Ok(std::iter::once(*inet)) + } else { + Err(std::io::Error::new( + std::io::ErrorKind::Other, + "UDS socket cannot be used as inet socket", + )) + } + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn parse_ip() { + let ip: SocketAddr = "127.0.0.1:80".parse().unwrap(); + assert!(ip.as_inet().is_some()); + } + + #[test] + fn parse_uds() { + let uds: SocketAddr = "/tmp/my.sock".parse().unwrap(); + assert!(uds.as_unix().is_some()); + } +} diff --git a/pingora-core/src/protocols/l4/stream.rs b/pingora-core/src/protocols/l4/stream.rs new file mode 100644 index 0000000..ebe4f67 --- /dev/null +++ b/pingora-core/src/protocols/l4/stream.rs @@ -0,0 +1,378 @@ +// 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. + +//! Transport layer connection + +use async_trait::async_trait; +use futures::FutureExt; +use log::{debug, error}; +use pingora_error::{ErrorType::*, OrErr, Result}; +use std::os::unix::io::AsRawFd; +use std::pin::Pin; +use std::sync::Arc; +use std::task::{Context, Poll}; +use std::time::SystemTime; +use tokio::io::{self, AsyncRead, AsyncWrite, AsyncWriteExt, BufStream, ReadBuf}; +use tokio::net::{TcpStream, UnixStream}; + +use crate::protocols::raw_connect::ProxyDigest; +use crate::protocols::{GetProxyDigest, GetTimingDigest, Shutdown, Ssl, TimingDigest, UniqueID}; +use crate::upstreams::peer::Tracer; + +#[derive(Debug)] +enum RawStream { + Tcp(TcpStream), + Unix(UnixStream), +} + +impl AsyncRead for RawStream { + fn poll_read( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut ReadBuf<'_>, + ) -> Poll> { + // Safety: Basic enum pin projection + unsafe { + match &mut Pin::get_unchecked_mut(self) { + RawStream::Tcp(s) => Pin::new_unchecked(s).poll_read(cx, buf), + RawStream::Unix(s) => Pin::new_unchecked(s).poll_read(cx, buf), + } + } + } +} + +impl AsyncWrite for RawStream { + fn poll_write(self: Pin<&mut Self>, cx: &mut Context, buf: &[u8]) -> Poll> { + // Safety: Basic enum pin projection + unsafe { + match &mut Pin::get_unchecked_mut(self) { + RawStream::Tcp(s) => Pin::new_unchecked(s).poll_write(cx, buf), + RawStream::Unix(s) => Pin::new_unchecked(s).poll_write(cx, buf), + } + } + } + + fn poll_flush(self: Pin<&mut Self>, cx: &mut Context) -> Poll> { + // Safety: Basic enum pin projection + unsafe { + match &mut Pin::get_unchecked_mut(self) { + RawStream::Tcp(s) => Pin::new_unchecked(s).poll_flush(cx), + RawStream::Unix(s) => Pin::new_unchecked(s).poll_flush(cx), + } + } + } + + fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context) -> Poll> { + // Safety: Basic enum pin projection + unsafe { + match &mut Pin::get_unchecked_mut(self) { + RawStream::Tcp(s) => Pin::new_unchecked(s).poll_shutdown(cx), + RawStream::Unix(s) => Pin::new_unchecked(s).poll_shutdown(cx), + } + } + } + + fn poll_write_vectored( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &[std::io::IoSlice<'_>], + ) -> Poll> { + // Safety: Basic enum pin projection + unsafe { + match &mut Pin::get_unchecked_mut(self) { + RawStream::Tcp(s) => Pin::new_unchecked(s).poll_write_vectored(cx, bufs), + RawStream::Unix(s) => Pin::new_unchecked(s).poll_write_vectored(cx, bufs), + } + } + } + + fn is_write_vectored(&self) -> bool { + match self { + RawStream::Tcp(s) => s.is_write_vectored(), + RawStream::Unix(s) => s.is_write_vectored(), + } + } +} + +// Large read buffering helps reducing syscalls with little trade-off +// Ssl layer always does "small" reads in 16k (TLS record size) so L4 read buffer helps a lot. +const BUF_READ_SIZE: usize = 64 * 1024; +// Small write buf to match MSS. Too large write buf delays real time communication. +// This buffering effectively implements something similar to Nagle's algorithm. +// The benefit is that user space can control when to flush, where Nagle's can't be controlled. +// And userspace buffering reduce both syscalls and small packets. +const BUF_WRITE_SIZE: usize = 1460; + +// NOTE: with writer buffering, users need to call flush() to make sure the data is actually +// sent. Otherwise data could be stuck in the buffer forever or get lost when stream is closed. + +/// A concrete type for transport layer connection + extra fields for logging +#[derive(Debug)] +pub struct Stream { + stream: BufStream, + buffer_write: bool, + proxy_digest: Option>, + /// When this connection is established + pub established_ts: SystemTime, + /// The distributed tracing object for this stream + pub tracer: Option, +} + +impl Stream { + /// set TCP nodelay for this connection if `self` is TCP + pub fn set_nodelay(&mut self) -> Result<()> { + if let RawStream::Tcp(s) = &self.stream.get_ref() { + s.set_nodelay(true) + .or_err(ConnectError, "failed to set_nodelay")?; + } + Ok(()) + } +} + +impl From for Stream { + fn from(s: TcpStream) -> Self { + Stream { + stream: BufStream::with_capacity(BUF_READ_SIZE, BUF_WRITE_SIZE, RawStream::Tcp(s)), + buffer_write: true, + established_ts: SystemTime::now(), + proxy_digest: None, + tracer: None, + } + } +} + +impl From for Stream { + fn from(s: UnixStream) -> Self { + Stream { + stream: BufStream::with_capacity(BUF_READ_SIZE, BUF_WRITE_SIZE, RawStream::Unix(s)), + buffer_write: true, + established_ts: SystemTime::now(), + proxy_digest: None, + tracer: None, + } + } +} + +impl UniqueID for Stream { + fn id(&self) -> i32 { + match &self.stream.get_ref() { + RawStream::Tcp(s) => s.as_raw_fd(), + RawStream::Unix(s) => s.as_raw_fd(), + } + } +} + +impl Ssl for Stream {} + +#[async_trait] +impl Shutdown for Stream { + async fn shutdown(&mut self) { + AsyncWriteExt::shutdown(self).await.unwrap_or_else(|e| { + debug!("Failed to shutdown connection: {:?}", e); + }); + } +} + +impl GetTimingDigest for Stream { + fn get_timing_digest(&self) -> Vec> { + let mut digest = Vec::with_capacity(2); // expect to have both L4 stream and TLS layer + digest.push(Some(TimingDigest { + established_ts: self.established_ts, + })); + digest + } +} + +impl GetProxyDigest for Stream { + fn get_proxy_digest(&self) -> Option> { + self.proxy_digest.clone() + } + + fn set_proxy_digest(&mut self, digest: ProxyDigest) { + self.proxy_digest = Some(Arc::new(digest)); + } +} + +impl Drop for Stream { + fn drop(&mut self) { + if let Some(t) = self.tracer.as_ref() { + t.0.on_disconnected(); + } + /* use nodelay/local_addr function to detect socket status */ + let ret = match &self.stream.get_ref() { + RawStream::Tcp(s) => s.nodelay().err(), + RawStream::Unix(s) => s.local_addr().err(), + }; + if let Some(e) = ret { + match e.kind() { + tokio::io::ErrorKind::Other => { + if let Some(ecode) = e.raw_os_error() { + if ecode == 9 { + // Or we could panic here + error!("Crit: socket {:?} is being double closed", self.stream); + } + } + } + _ => { + debug!("Socket is already broken {:?}", e); + } + } + } else { + // try flush the write buffer. We use now_or_never() because + // 1. Drop cannot be async + // 2. write should usually be ready, unless the buf is full. + let _ = self.flush().now_or_never(); + } + debug!("Dropping socket {:?}", self.stream); + } +} + +impl AsyncRead for Stream { + fn poll_read( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut ReadBuf<'_>, + ) -> Poll> { + Pin::new(&mut self.stream).poll_read(cx, buf) + } +} + +impl AsyncWrite for Stream { + fn poll_write( + mut self: Pin<&mut Self>, + cx: &mut Context, + buf: &[u8], + ) -> Poll> { + if self.buffer_write { + Pin::new(&mut self.stream).poll_write(cx, buf) + } else { + Pin::new(&mut self.stream.get_mut()).poll_write(cx, buf) + } + } + + fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll> { + Pin::new(&mut self.stream).poll_flush(cx) + } + + fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll> { + Pin::new(&mut self.stream).poll_shutdown(cx) + } + + fn poll_write_vectored( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &[std::io::IoSlice<'_>], + ) -> Poll> { + if self.buffer_write { + Pin::new(&mut self.stream).poll_write_vectored(cx, bufs) + } else { + Pin::new(&mut self.stream.get_mut()).poll_write_vectored(cx, bufs) + } + } + + fn is_write_vectored(&self) -> bool { + if self.buffer_write { + self.stream.is_write_vectored() // it is true + } else { + self.stream.get_ref().is_write_vectored() + } + } +} + +pub mod async_write_vec { + use bytes::Buf; + use futures::ready; + use std::future::Future; + use std::io::IoSlice; + use std::pin::Pin; + use std::task::{Context, Poll}; + use tokio::io; + use tokio::io::AsyncWrite; + + /* + the missing write_buf https://github.com/tokio-rs/tokio/pull/3156#issuecomment-738207409 + https://github.com/tokio-rs/tokio/issues/2610 + In general vectored write is lost when accessing the trait object: Box + */ + + #[must_use = "futures do nothing unless you `.await` or poll them"] + pub struct WriteVec<'a, W, B> { + writer: &'a mut W, + buf: &'a mut B, + } + + pub trait AsyncWriteVec { + fn poll_write_vec( + self: Pin<&mut Self>, + _cx: &mut Context<'_>, + _buf: &mut B, + ) -> Poll>; + + fn write_vec<'a, B>(&'a mut self, src: &'a mut B) -> WriteVec<'a, Self, B> + where + Self: Sized, + B: Buf, + { + WriteVec { + writer: self, + buf: src, + } + } + } + + impl Future for WriteVec<'_, W, B> + where + W: AsyncWriteVec + Unpin, + B: Buf, + { + type Output = io::Result; + + fn poll(mut self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll> { + let me = &mut *self; + Pin::new(&mut *me.writer).poll_write_vec(ctx, me.buf) + } + } + + /* from https://github.com/tokio-rs/tokio/blob/master/tokio-util/src/lib.rs#L177 */ + impl AsyncWriteVec for T + where + T: AsyncWrite, + { + fn poll_write_vec( + self: Pin<&mut Self>, + ctx: &mut Context, + buf: &mut B, + ) -> Poll> { + const MAX_BUFS: usize = 64; + + if !buf.has_remaining() { + return Poll::Ready(Ok(0)); + } + + let n = if self.is_write_vectored() { + let mut slices = [IoSlice::new(&[]); MAX_BUFS]; + let cnt = buf.chunks_vectored(&mut slices); + ready!(self.poll_write_vectored(ctx, &slices[..cnt]))? + } else { + ready!(self.poll_write(ctx, buf.chunk()))? + }; + + buf.advance(n); + + Poll::Ready(Ok(n)) + } + } +} + +pub use async_write_vec::AsyncWriteVec; diff --git a/pingora-core/src/protocols/mod.rs b/pingora-core/src/protocols/mod.rs new file mode 100644 index 0000000..4df6da8 --- /dev/null +++ b/pingora-core/src/protocols/mod.rs @@ -0,0 +1,253 @@ +// 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. + +//! Abstractions and implementations for protocols including TCP, TLS and HTTP + +mod digest; +pub mod http; +pub mod l4; +pub mod raw_connect; +pub mod ssl; + +pub use digest::{Digest, GetProxyDigest, GetTimingDigest, ProtoDigest, TimingDigest}; +pub use ssl::ALPN; + +use async_trait::async_trait; +use std::fmt::Debug; +use std::sync::Arc; + +/// Define how a protocol should shutdown its connection. +#[async_trait] +pub trait Shutdown { + async fn shutdown(&mut self) -> (); +} + +/// Define how a given session/connection identifies itself. +pub trait UniqueID { + /// The ID returned should be unique among all existing connections of the same type. + /// But ID can be recycled after a connection is shutdown. + fn id(&self) -> i32; +} + +/// Interface to get TLS info +pub trait Ssl { + /// Return the TLS info if the connection is over TLS + fn get_ssl(&self) -> Option<&crate::tls::ssl::SslRef> { + None + } + + /// Return the [`ssl::SslDigest`] for logging + fn get_ssl_digest(&self) -> Option> { + None + } + + /// Return selected ALPN if any + fn selected_alpn_proto(&self) -> Option { + let ssl = self.get_ssl()?; + ALPN::from_wire_selected(ssl.selected_alpn_protocol()?) + } +} + +use std::any::Any; +use tokio::io::{AsyncRead, AsyncWrite}; + +/// The abstraction of transport layer IO +pub trait IO: + AsyncRead + + AsyncWrite + + Shutdown + + UniqueID + + Ssl + + GetTimingDigest + + GetProxyDigest + + Unpin + + Debug + + Send + + Sync +{ + /// helper to cast as the reference of the concrete type + fn as_any(&self) -> &dyn Any; + /// helper to cast back of the concrete type + fn into_any(self: Box) -> Box; +} + +impl< + T: AsyncRead + + AsyncWrite + + Shutdown + + UniqueID + + Ssl + + GetTimingDigest + + GetProxyDigest + + Unpin + + Debug + + Send + + Sync, + > IO for T +where + T: 'static, +{ + fn as_any(&self) -> &dyn Any { + self + } + fn into_any(self: Box) -> Box { + self + } +} + +/// The type of any established transport layer connection +pub type Stream = Box; + +// Implement IO trait for 3rd party types, mostly for testing +mod ext_io_impl { + use super::*; + use tokio_test::io::Mock; + + #[async_trait] + impl Shutdown for Mock { + async fn shutdown(&mut self) -> () {} + } + impl UniqueID for Mock { + fn id(&self) -> i32 { + 0 + } + } + impl Ssl for Mock {} + impl GetTimingDigest for Mock { + fn get_timing_digest(&self) -> Vec> { + vec![] + } + } + impl GetProxyDigest for Mock { + fn get_proxy_digest(&self) -> Option> { + None + } + } + + use std::io::Cursor; + + #[async_trait] + impl Shutdown for Cursor { + async fn shutdown(&mut self) -> () {} + } + impl UniqueID for Cursor { + fn id(&self) -> i32 { + 0 + } + } + impl Ssl for Cursor {} + impl GetTimingDigest for Cursor { + fn get_timing_digest(&self) -> Vec> { + vec![] + } + } + impl GetProxyDigest for Cursor { + fn get_proxy_digest(&self) -> Option> { + None + } + } + + use tokio::io::DuplexStream; + + #[async_trait] + impl Shutdown for DuplexStream { + async fn shutdown(&mut self) -> () {} + } + impl UniqueID for DuplexStream { + fn id(&self) -> i32 { + 0 + } + } + impl Ssl for DuplexStream {} + impl GetTimingDigest for DuplexStream { + fn get_timing_digest(&self) -> Vec> { + vec![] + } + } + impl GetProxyDigest for DuplexStream { + fn get_proxy_digest(&self) -> Option> { + None + } + } +} + +pub(crate) trait ConnFdReusable { + fn check_fd_match(&self, fd: V) -> bool; +} + +use l4::socket::SocketAddr; +use log::{debug, error}; +use nix::sys::socket::{getpeername, SockaddrStorage, UnixAddr}; +use std::{net::SocketAddr as InetSocketAddr, os::unix::prelude::AsRawFd, path::Path}; + +impl ConnFdReusable for SocketAddr { + fn check_fd_match(&self, fd: V) -> bool { + match self { + SocketAddr::Inet(addr) => addr.check_fd_match(fd), + SocketAddr::Unix(addr) => addr + .as_pathname() + .expect("non-pathname unix sockets not supported as peer") + .check_fd_match(fd), + } + } +} + +impl ConnFdReusable for Path { + fn check_fd_match(&self, fd: V) -> bool { + let fd = fd.as_raw_fd(); + match getpeername::(fd) { + Ok(peer) => match UnixAddr::new(self) { + Ok(addr) => { + if addr == peer { + debug!("Unix FD to: {peer:?} is reusable"); + true + } else { + error!("Crit: unix FD mismatch: fd: {fd:?}, peer: {peer:?}, addr: {addr}",); + false + } + } + Err(e) => { + error!("Bad addr: {self:?}, error: {e:?}"); + false + } + }, + Err(e) => { + error!("Idle unix connection is broken: {e:?}"); + false + } + } + } +} + +impl ConnFdReusable for InetSocketAddr { + fn check_fd_match(&self, fd: V) -> bool { + let fd = fd.as_raw_fd(); + match getpeername::(fd) { + Ok(peer) => { + let addr = SockaddrStorage::from(*self); + if addr == peer { + debug!("Inet FD to: {peer:?} is reusable"); + true + } else { + error!("Crit: FD mismatch: fd: {fd:?}, addr: {addr:?}, peer: {peer:?}",); + false + } + } + Err(e) => { + debug!("Idle connection is broken: {e:?}"); + false + } + } + } +} diff --git a/pingora-core/src/protocols/raw_connect.rs b/pingora-core/src/protocols/raw_connect.rs new file mode 100644 index 0000000..08fdc9a --- /dev/null +++ b/pingora-core/src/protocols/raw_connect.rs @@ -0,0 +1,271 @@ +// 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. + +//! CONNECT protocol over http 1.1 via raw Unix domain socket +//! +//! This mod implements the most rudimentary CONNECT client over raw stream. +//! The idea is to yield raw stream once the CONNECT handshake is complete +//! so that the protocol encapsulated can use the stream directly. +//! this idea only works for CONNECT over HTTP 1.1 and localhost (or where the server is close by). + +use super::http::v1::client::HttpSession; +use super::http::v1::common::*; +use super::Stream; + +use bytes::{BufMut, BytesMut}; +use http::request::Parts as ReqHeader; +use http::Version; +use pingora_error::{Error, ErrorType::*, OrErr, Result}; +use pingora_http::ResponseHeader; +use tokio::io::AsyncWriteExt; + +/// Try to establish a CONNECT proxy via the given `stream`. +/// +/// `request_header` should include the necessary request headers for the CONNECT protocol. +/// +/// When successful, a [`Stream`] will be returned which is the established CONNECT proxy connection. +pub async fn connect(stream: Stream, request_header: &ReqHeader) -> Result<(Stream, ProxyDigest)> { + let mut http = HttpSession::new(stream); + + // We write to stream directly because HttpSession doesn't write req header in auth form + let to_wire = http_req_header_to_wire_auth_form(request_header); + http.underlying_stream + .write_all(to_wire.as_ref()) + .await + .or_err(WriteError, "while writing request headers")?; + http.underlying_stream + .flush() + .await + .or_err(WriteError, "while flushing request headers")?; + + // TODO: set http.read_timeout + let resp_header = http.read_resp_header_parts().await?; + Ok(( + http.underlying_stream, + validate_connect_response(resp_header)?, + )) +} + +/// Generate the CONNECT header for the given destination +pub fn generate_connect_header<'a, H, S>( + host: &str, + port: u16, + headers: H, +) -> Result> +where + S: AsRef<[u8]>, + H: Iterator)>, +{ + // TODO: valid that host doesn't have port + // TODO: support adding ad-hoc headers + + let authority = format!("{host}:{port}"); + let req = http::request::Builder::new() + .version(http::Version::HTTP_11) + .method(http::method::Method::CONNECT) + .uri(format!("https://{authority}/")) // scheme doesn't matter + .header(http::header::HOST, &authority); + + let (mut req, _) = match req.body(()) { + Ok(r) => r.into_parts(), + Err(e) => { + return Err(e).or_err(InvalidHTTPHeader, "Invalid CONNECT request"); + } + }; + + for (k, v) in headers { + let header_name = http::header::HeaderName::from_bytes(k.as_ref()) + .or_err(InvalidHTTPHeader, "Invalid CONNECT request")?; + let header_value = http::header::HeaderValue::from_bytes(v.as_slice()) + .or_err(InvalidHTTPHeader, "Invalid CONNECT request")?; + req.headers.insert(header_name, header_value); + } + + Ok(Box::new(req)) +} + +/// The information about the CONNECT proxy. +#[derive(Debug)] +pub struct ProxyDigest { + /// The response header the proxy returns + pub response: Box, +} + +impl ProxyDigest { + pub fn new(response: Box) -> Self { + ProxyDigest { response } + } +} + +/// The error returned when the CONNECT proxy fails to establish. +#[derive(Debug)] +pub struct ConnectProxyError { + /// The response header the proxy returns + pub response: Box, +} + +impl ConnectProxyError { + pub fn boxed_new(response: Box) -> Box { + Box::new(ConnectProxyError { response }) + } +} + +impl std::fmt::Display for ConnectProxyError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + const PROXY_STATUS: &str = "proxy-status"; + + let reason = self + .response + .headers + .get(PROXY_STATUS) + .and_then(|s| s.to_str().ok()) + .unwrap_or("missing proxy-status header value"); + write!( + f, + "Failed CONNECT Response: status {}, proxy-status {reason}", + &self.response.status + ) + } +} + +impl std::error::Error for ConnectProxyError {} + +#[inline] +fn http_req_header_to_wire_auth_form(req: &ReqHeader) -> BytesMut { + let mut buf = BytesMut::with_capacity(512); + + // Request-Line + let method = req.method.as_str().as_bytes(); + buf.put_slice(method); + buf.put_u8(b' '); + // NOTE: CONNECT doesn't need URI path so we just skip that + if let Some(path) = req.uri.authority() { + buf.put_slice(path.as_str().as_bytes()); + } + buf.put_u8(b' '); + + let version = match req.version { + Version::HTTP_09 => "HTTP/0.9", + Version::HTTP_10 => "HTTP/1.0", + Version::HTTP_11 => "HTTP/1.1", + _ => "HTTP/0.9", + }; + buf.put_slice(version.as_bytes()); + buf.put_slice(CRLF); + + // headers + let headers = &req.headers; + for (key, value) in headers.iter() { + buf.put_slice(key.as_ref()); + buf.put_slice(HEADER_KV_DELIMITER); + buf.put_slice(value.as_ref()); + buf.put_slice(CRLF); + } + + buf.put_slice(CRLF); + buf +} + +#[inline] +fn validate_connect_response(resp: Box) -> Result { + if !resp.status.is_success() { + return Error::e_because( + ConnectProxyFailure, + "None 2xx code", + ConnectProxyError::boxed_new(resp), + ); + } + + // Checking Content-Length and Transfer-Encoding is optional because we already ignore them. + // We choose to do so because we want to be strict for internal use of CONNECT. + // Ignore Content-Length header because our internal CONNECT server is coded to send it. + if resp.headers.get(http::header::TRANSFER_ENCODING).is_some() { + return Error::e_because( + ConnectProxyFailure, + "Invalid Transfer-Encoding presents", + ConnectProxyError::boxed_new(resp), + ); + } + Ok(ProxyDigest::new(resp)) +} + +#[cfg(test)] +mod test_sync { + use super::*; + use std::collections::BTreeMap; + use tokio_test::io::Builder; + + #[test] + fn test_generate_connect_header() { + let mut headers = BTreeMap::new(); + headers.insert(String::from("foo"), b"bar".to_vec()); + let req = generate_connect_header("pingora.org", 123, headers.iter()).unwrap(); + + assert_eq!(req.method, http::method::Method::CONNECT); + assert_eq!(req.uri.authority().unwrap(), "pingora.org:123"); + assert_eq!(req.headers.get("Host").unwrap(), "pingora.org:123"); + assert_eq!(req.headers.get("foo").unwrap(), "bar"); + } + #[test] + fn test_request_to_wire_auth_form() { + let new_request = http::Request::builder() + .method("CONNECT") + .uri("https://pingora.org:123/") + .header("Foo", "Bar") + .body(()) + .unwrap(); + let (new_request, _) = new_request.into_parts(); + let wire = http_req_header_to_wire_auth_form(&new_request); + assert_eq!( + &b"CONNECT pingora.org:123 HTTP/1.1\r\nfoo: Bar\r\n\r\n"[..], + &wire + ); + } + + #[test] + fn test_validate_connect_response() { + let resp = ResponseHeader::build(200, None).unwrap(); + validate_connect_response(Box::new(resp)).unwrap(); + + let resp = ResponseHeader::build(404, None).unwrap(); + assert!(validate_connect_response(Box::new(resp)).is_err()); + + let mut resp = ResponseHeader::build(200, None).unwrap(); + resp.append_header("content-length", 0).unwrap(); + assert!(validate_connect_response(Box::new(resp)).is_ok()); + + let mut resp = ResponseHeader::build(200, None).unwrap(); + resp.append_header("transfer-encoding", 0).unwrap(); + assert!(validate_connect_response(Box::new(resp)).is_err()); + } + + #[tokio::test] + async fn test_connect_write_request() { + let wire = b"CONNECT pingora.org:123 HTTP/1.1\r\nhost: pingora.org:123\r\n\r\n"; + let mock_io = Box::new(Builder::new().write(wire).build()); + + let headers: BTreeMap> = BTreeMap::new(); + let req = generate_connect_header("pingora.org", 123, headers.iter()).unwrap(); + // ConnectionClosed + assert!(connect(mock_io, &req).await.is_err()); + + let to_wire = b"CONNECT pingora.org:123 HTTP/1.1\r\nhost: pingora.org:123\r\n\r\n"; + let from_wire = b"HTTP/1.1 200 OK\r\n\r\n"; + let mock_io = Box::new(Builder::new().write(to_wire).read(from_wire).build()); + + let req = generate_connect_header("pingora.org", 123, headers.iter()).unwrap(); + let result = connect(mock_io, &req).await; + assert!(result.is_ok()); + } +} diff --git a/pingora-core/src/protocols/ssl/client.rs b/pingora-core/src/protocols/ssl/client.rs new file mode 100644 index 0000000..abb6da6 --- /dev/null +++ b/pingora-core/src/protocols/ssl/client.rs @@ -0,0 +1,78 @@ +// 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. + +//! TLS client specific implementation + +use super::SslStream; +use crate::protocols::raw_connect::ProxyDigest; +use crate::protocols::{GetProxyDigest, GetTimingDigest, TimingDigest, IO}; +use crate::tls::{ + ssl, + ssl::ConnectConfiguration, + ssl_sys::{X509_V_ERR_INVALID_CALL, X509_V_OK}, +}; + +use pingora_error::{Error, ErrorType::*, OrErr, Result}; +use std::sync::Arc; + +/// Perform the TLS handshake for the given connection with the given configuration +pub async fn handshake( + conn_config: ConnectConfiguration, + domain: &str, + io: S, +) -> Result> { + let ssl = conn_config + .into_ssl(domain) + .explain_err(TLSHandshakeFailure, |e| format!("ssl config error: {e}"))?; + let mut stream = SslStream::new(ssl, io) + .explain_err(TLSHandshakeFailure, |e| format!("ssl stream error: {e}"))?; + let handshake_result = stream.connect().await; + match handshake_result { + Ok(()) => Ok(stream), + Err(e) => { + let context = format!("TLS connect() failed: {e}, SNI: {domain}"); + match e.code() { + ssl::ErrorCode::SSL => match stream.ssl().verify_result().as_raw() { + // X509_V_ERR_INVALID_CALL in case verify result was never set + X509_V_OK | X509_V_ERR_INVALID_CALL => { + Error::e_explain(TLSHandshakeFailure, context) + } + _ => Error::e_explain(InvalidCert, context), + }, + /* likely network error, but still mark as TLS error */ + _ => Error::e_explain(TLSHandshakeFailure, context), + } + } + } +} + +impl GetTimingDigest for SslStream +where + S: GetTimingDigest, +{ + fn get_timing_digest(&self) -> Vec> { + let mut ts_vec = self.get_ref().get_timing_digest(); + ts_vec.push(Some(self.timing.clone())); + ts_vec + } +} + +impl GetProxyDigest for SslStream +where + S: GetProxyDigest, +{ + fn get_proxy_digest(&self) -> Option> { + self.get_ref().get_proxy_digest() + } +} diff --git a/pingora-core/src/protocols/ssl/digest.rs b/pingora-core/src/protocols/ssl/digest.rs new file mode 100644 index 0000000..3cdb7aa --- /dev/null +++ b/pingora-core/src/protocols/ssl/digest.rs @@ -0,0 +1,65 @@ +// 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. + +//! TLS information from the TLS connection + +use crate::tls::{hash::MessageDigest, ssl::SslRef}; +use crate::utils; + +/// The TLS connection information +#[derive(Clone, Debug)] +pub struct SslDigest { + /// The cipher used + pub cipher: &'static str, + /// The TLS version of this connection + pub version: &'static str, + /// The organization of the peer's certificate + pub organization: Option, + /// The serial number of the peer's certificate + pub serial_number: Option, + /// The digest of the peer's certificate + pub cert_digest: Vec, +} + +impl SslDigest { + pub fn from_ssl(ssl: &SslRef) -> Self { + let cipher = match ssl.current_cipher() { + Some(c) => c.name(), + None => "", + }; + + let (cert_digest, org, sn) = match ssl.peer_certificate() { + Some(cert) => { + let cert_digest = match cert.digest(MessageDigest::sha256()) { + Ok(c) => c.as_ref().to_vec(), + Err(_) => Vec::new(), + }; + ( + cert_digest, + utils::get_organization(&cert), + utils::get_serial(&cert).ok(), + ) + } + None => (Vec::new(), None, None), + }; + + SslDigest { + cipher, + version: ssl.version_str(), + organization: org, + serial_number: sn, + cert_digest, + } + } +} diff --git a/pingora-core/src/protocols/ssl/mod.rs b/pingora-core/src/protocols/ssl/mod.rs new file mode 100644 index 0000000..f1ce8b9 --- /dev/null +++ b/pingora-core/src/protocols/ssl/mod.rs @@ -0,0 +1,246 @@ +// 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. + +//! The TLS layer implementations + +pub mod client; +pub mod digest; +pub mod server; + +use crate::protocols::digest::TimingDigest; +use crate::protocols::{Ssl, UniqueID}; +use crate::tls::{self, ssl, tokio_ssl::SslStream as InnerSsl}; +use log::warn; +use pingora_error::{ErrorType::*, OrErr, Result}; +use std::pin::Pin; +use std::sync::Arc; +use std::task::{Context, Poll}; +use std::time::SystemTime; +use tokio::io::{self, AsyncRead, AsyncWrite, ReadBuf}; + +pub use digest::SslDigest; + +/// The TLS connection +#[derive(Debug)] +pub struct SslStream { + ssl: InnerSsl, + digest: Option>, + timing: TimingDigest, +} + +impl SslStream +where + T: AsyncRead + AsyncWrite + std::marker::Unpin, +{ + /// Create a new TLS connection from the given `stream` + /// + /// The caller needs to perform [`Self::connect()`] or [`Self::accept()`] to perform TLS + /// handshake after. + pub fn new(ssl: ssl::Ssl, stream: T) -> Result { + let ssl = InnerSsl::new(ssl, stream) + .explain_err(TLSHandshakeFailure, |e| format!("ssl stream error: {e}"))?; + + Ok(SslStream { + ssl, + digest: None, + timing: Default::default(), + }) + } + + /// Connect to the remote TLS server as a client + pub async fn connect(&mut self) -> Result<(), ssl::Error> { + Self::clear_error(); + Pin::new(&mut self.ssl).connect().await?; + self.timing.established_ts = SystemTime::now(); + self.digest = Some(Arc::new(SslDigest::from_ssl(self.ssl()))); + Ok(()) + } + + /// Finish the TLS handshake from client as a server + pub async fn accept(&mut self) -> Result<(), ssl::Error> { + Self::clear_error(); + Pin::new(&mut self.ssl).accept().await?; + self.timing.established_ts = SystemTime::now(); + self.digest = Some(Arc::new(SslDigest::from_ssl(self.ssl()))); + Ok(()) + } + + #[inline] + fn clear_error() { + let errs = tls::error::ErrorStack::get(); + if !errs.errors().is_empty() { + warn!("Clearing dirty TLS error stack: {}", errs); + } + } +} + +impl SslStream { + pub fn ssl_digest(&self) -> Option> { + self.digest.clone() + } +} + +use std::ops::{Deref, DerefMut}; + +impl Deref for SslStream { + type Target = InnerSsl; + + fn deref(&self) -> &Self::Target { + &self.ssl + } +} + +impl DerefMut for SslStream { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.ssl + } +} + +impl AsyncRead for SslStream +where + T: AsyncRead + AsyncWrite + Unpin, +{ + fn poll_read( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut ReadBuf<'_>, + ) -> Poll> { + Self::clear_error(); + Pin::new(&mut self.ssl).poll_read(cx, buf) + } +} + +impl AsyncWrite for SslStream +where + T: AsyncRead + AsyncWrite + Unpin, +{ + fn poll_write( + mut self: Pin<&mut Self>, + cx: &mut Context, + buf: &[u8], + ) -> Poll> { + Self::clear_error(); + Pin::new(&mut self.ssl).poll_write(cx, buf) + } + + fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll> { + Self::clear_error(); + Pin::new(&mut self.ssl).poll_flush(cx) + } + + fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll> { + Self::clear_error(); + Pin::new(&mut self.ssl).poll_shutdown(cx) + } + + fn poll_write_vectored( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &[std::io::IoSlice<'_>], + ) -> Poll> { + Self::clear_error(); + Pin::new(&mut self.ssl).poll_write_vectored(cx, bufs) + } + + fn is_write_vectored(&self) -> bool { + true + } +} + +impl UniqueID for SslStream +where + T: UniqueID, +{ + fn id(&self) -> i32 { + self.ssl.get_ref().id() + } +} + +impl Ssl for SslStream { + fn get_ssl(&self) -> Option<&ssl::SslRef> { + Some(self.ssl()) + } + + fn get_ssl_digest(&self) -> Option> { + self.ssl_digest() + } +} + +/// The protocol for Application-Layer Protocol Negotiation +#[derive(Hash, Clone, Debug)] +pub enum ALPN { + /// Prefer HTTP/1.1 only + H1, + /// Prefer HTTP/2 only + H2, + /// Prefer HTTP/2 over HTTP/1.1 + H2H1, +} + +impl std::fmt::Display for ALPN { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ALPN::H1 => write!(f, "H1"), + ALPN::H2 => write!(f, "H2"), + ALPN::H2H1 => write!(f, "H2H1"), + } + } +} + +impl ALPN { + /// Create a new ALPN according to the `max` and `min` version constraints + pub fn new(max: u8, min: u8) -> Self { + if max == 1 { + ALPN::H1 + } else if min == 2 { + ALPN::H2 + } else { + ALPN::H2H1 + } + } + + /// Return the max http version this [`ALPN`] allows + pub fn get_max_http_version(&self) -> u8 { + match self { + ALPN::H1 => 1, + _ => 2, + } + } + + /// Return the min http version this [`ALPN`] allows + pub fn get_min_http_version(&self) -> u8 { + match self { + ALPN::H2 => 2, + _ => 1, + } + } + + pub(crate) fn to_wire_preference(&self) -> &[u8] { + // https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_alpn_select_cb.html + // "vector of nonempty, 8-bit length-prefixed, byte strings" + match self { + Self::H1 => b"\x08http/1.1", + Self::H2 => b"\x02h2", + Self::H2H1 => b"\x02h2\x08http/1.1", + } + } + + pub(crate) fn from_wire_selected(raw: &[u8]) -> Option { + match raw { + b"http/1.1" => Some(Self::H1), + b"h2" => Some(Self::H2), + _ => None, + } + } +} diff --git a/pingora-core/src/protocols/ssl/server.rs b/pingora-core/src/protocols/ssl/server.rs new file mode 100644 index 0000000..98dc2f1 --- /dev/null +++ b/pingora-core/src/protocols/ssl/server.rs @@ -0,0 +1,193 @@ +// 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. + +//! TLS server specific implementation + +use super::SslStream; +use crate::protocols::{Shutdown, IO}; +use crate::tls::ext; +use crate::tls::ext::ssl_from_acceptor; +use crate::tls::ssl; +use crate::tls::ssl::{SslAcceptor, SslRef}; + +use async_trait::async_trait; +use log::warn; +use pingora_error::{ErrorType::*, OrErr, Result}; +use std::pin::Pin; +use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt}; + +/// Prepare a TLS stream for handshake +pub fn prepare_tls_stream(ssl_acceptor: &SslAcceptor, io: S) -> Result> { + let ssl = ssl_from_acceptor(ssl_acceptor) + .explain_err(TLSHandshakeFailure, |e| format!("ssl_acceptor error: {e}"))?; + SslStream::new(ssl, io).explain_err(TLSHandshakeFailure, |e| format!("ssl stream error: {e}")) +} + +/// Perform TLS handshake for the given connection with the given configuration +pub async fn handshake(ssl_acceptor: &SslAcceptor, io: S) -> Result> { + let mut stream = prepare_tls_stream(ssl_acceptor, io)?; + stream + .accept() + .await + .explain_err(TLSHandshakeFailure, |e| format!("TLS accept() failed: {e}"))?; + Ok(stream) +} + +/// Perform TLS handshake for the given connection with the given configuration and callbacks +pub async fn handshake_with_callback( + ssl_acceptor: &SslAcceptor, + io: S, + callbacks: &TlsAcceptCallbacks, +) -> Result> { + let mut tls_stream = prepare_tls_stream(ssl_acceptor, io)?; + let done = Pin::new(&mut tls_stream) + .start_accept() + .await + .explain_err(TLSHandshakeFailure, |e| format!("TLS accept() failed: {e}"))?; + if !done { + // safety: we do hold a mut ref of tls_stream + let ssl_mut = unsafe { ext::ssl_mut(tls_stream.ssl()) }; + callbacks.certificate_callback(ssl_mut).await; + Pin::new(&mut tls_stream) + .resume_accept() + .await + .explain_err(TLSHandshakeFailure, |e| format!("TLS accept() failed: {e}"))?; + Ok(tls_stream) + } else { + Ok(tls_stream) + } +} + +/// The APIs to customize things like certificate during TLS server side handshake +#[async_trait] +pub trait TlsAccept { + // TODO: return error? + /// This function is called in the middle of a TLS handshake. Structs who implements this function + /// should provide tls certificate and key to the [SslRef] via [ext::ssl_use_certificate] and [ext::ssl_use_private_key]. + async fn certificate_callback(&self, _ssl: &mut SslRef) -> () { + // does nothing by default + } +} + +pub type TlsAcceptCallbacks = Box; + +#[async_trait] +impl Shutdown for SslStream +where + S: AsyncRead + AsyncWrite + Sync + Unpin + Send, +{ + async fn shutdown(&mut self) { + match ::shutdown(self).await { + Ok(()) => {} + Err(e) => { + warn!("TLS shutdown failed, {e}"); + } + } + } +} + +/// Resumable TLS server side handshake. +#[async_trait] +pub trait ResumableAccept { + /// Start a resumable TLS accept handshake. + /// + /// * `Ok(true)` when the handshake is finished + /// * `Ok(false)`` when the handshake is paused midway + /// + /// For now, the accept will only pause when a certificate is needed. + async fn start_accept(self: Pin<&mut Self>) -> Result; + + /// Continue the TLS handshake + /// + /// This function should be called after the certificate is provided. + async fn resume_accept(self: Pin<&mut Self>) -> Result<(), ssl::Error>; +} + +#[async_trait] +impl ResumableAccept for SslStream { + async fn start_accept(mut self: Pin<&mut Self>) -> Result { + // safety: &mut self + let ssl_mut = unsafe { ext::ssl_mut(self.ssl()) }; + ext::suspend_when_need_ssl_cert(ssl_mut); + let res = self.accept().await; + + match res { + Ok(()) => Ok(true), + Err(e) => { + if ext::is_suspended_for_cert(&e) { + Ok(false) + } else { + Err(e) + } + } + } + } + + async fn resume_accept(mut self: Pin<&mut Self>) -> Result<(), ssl::Error> { + // safety: &mut ssl + let ssl_mut = unsafe { ext::ssl_mut(self.ssl()) }; + ext::unblock_ssl_cert(ssl_mut); + self.accept().await + } +} + +#[tokio::test] +async fn test_async_cert() { + use tokio::io::AsyncReadExt; + let acceptor = ssl::SslAcceptor::mozilla_intermediate_v5(ssl::SslMethod::tls()) + .unwrap() + .build(); + + struct Callback; + #[async_trait] + impl TlsAccept for Callback { + async fn certificate_callback(&self, ssl: &mut SslRef) -> () { + assert_eq!( + ssl.servername(ssl::NameType::HOST_NAME).unwrap(), + "pingora.org" + ); + let cert = format!("{}/tests/keys/server.crt", env!("CARGO_MANIFEST_DIR")); + let key = format!("{}/tests/keys/key.pem", env!("CARGO_MANIFEST_DIR")); + + let cert_bytes = std::fs::read(cert).unwrap(); + let cert = crate::tls::x509::X509::from_pem(&cert_bytes).unwrap(); + + let key_bytes = std::fs::read(key).unwrap(); + let key = crate::tls::pkey::PKey::private_key_from_pem(&key_bytes).unwrap(); + ext::ssl_use_certificate(ssl, &cert).unwrap(); + ext::ssl_use_private_key(ssl, &key).unwrap(); + } + } + + let cb: TlsAcceptCallbacks = Box::new(Callback); + + let (client, server) = tokio::io::duplex(1024); + + tokio::spawn(async move { + let ssl_context = ssl::SslContext::builder(ssl::SslMethod::tls()) + .unwrap() + .build(); + let mut ssl = ssl::Ssl::new(&ssl_context).unwrap(); + ssl.set_hostname("pingora.org").unwrap(); + ssl.set_verify(ssl::SslVerifyMode::NONE); // we don have a valid cert + let mut stream = SslStream::new(ssl, client).unwrap(); + Pin::new(&mut stream).connect().await.unwrap(); + let mut buf = [0; 1]; + let _ = stream.read(&mut buf).await; + }); + + handshake_with_callback(&acceptor, server, &cb) + .await + .unwrap(); +} diff --git a/pingora-core/src/server/configuration/mod.rs b/pingora-core/src/server/configuration/mod.rs new file mode 100644 index 0000000..19db553 --- /dev/null +++ b/pingora-core/src/server/configuration/mod.rs @@ -0,0 +1,267 @@ +// 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. + +//! Server configurations +//! +//! Server configurations define startup settings such as: +//! * User and group to run as after daemonization +//! * Number of threads per service +//! * Error log file path + +use log::{debug, trace}; +use pingora_error::{Error, ErrorType::*, OrErr, Result}; +use serde::{Deserialize, Serialize}; +use std::fs; +use structopt::StructOpt; + +/// The configuration file +/// +/// Pingora configuration files are by default YAML files but any key value format can potentially +/// be used. +/// +/// # Extension +/// New keys can be added to the configuration files which this configuration object will ignore. +/// Then, users can parse these key-values to pass to their code to use. +#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] +#[serde(default)] +pub struct ServerConf { + version: usize, + /// Whether to run this process in the background. + pub daemon: bool, + /// When configured, error log will be written to the given file. Otherwise StdErr will be used. + pub error_log: Option, + /// The pid (process ID) file of this server + pub pid_file: String, + /// the path to the upgrade socket + /// + /// In order to perform zero downtime restart, both the new and old process need to agree on the + /// path to this sock in order to coordinate the upgrade. + pub upgrade_sock: String, + /// If configured, after daemonization, this process will switch to the given user before + /// starting to serve traffic. + pub user: Option, + /// Similar to `user`, the group this process should switch to. + pub group: Option, + /// How many threads **each** service should get. The threads are not shared across services. + pub threads: usize, + /// Allow work stealing between threads of the same service. Default `true`. + pub work_stealing: bool, + /// The path to CA file the SSL library should use. If empty, the default trust store location + /// defined by the SSL library will be used. + pub ca_file: Option, + // These options don't belong here as they are specific to certain services + pub(crate) client_bind_to_ipv4: Vec, + pub(crate) client_bind_to_ipv6: Vec, + pub(crate) upstream_keepalive_pool_size: usize, + pub(crate) upstream_connect_offload_threadpools: Option, + pub(crate) upstream_connect_offload_thread_per_pool: Option, +} + +impl Default for ServerConf { + fn default() -> Self { + ServerConf { + version: 0, + client_bind_to_ipv4: vec![], + client_bind_to_ipv6: vec![], + ca_file: None, + daemon: false, + error_log: None, + pid_file: "/tmp/pingora.pid".to_string(), + upgrade_sock: "/tmp/pingora_upgrade.sock".to_string(), + user: None, + group: None, + threads: 1, + work_stealing: true, + upstream_keepalive_pool_size: 128, + upstream_connect_offload_threadpools: None, + upstream_connect_offload_thread_per_pool: None, + } + } +} + +/// Commandline options +/// +/// Call `Opt::from_args()` to build this object from the process's command line arguments. +#[derive(StructOpt, Debug)] +#[structopt(name = "basic")] +pub struct Opt { + /// Whether this server should try to upgrade from an running old server + /// + /// `-u` or `--upgrade` can be used + #[structopt(short, long)] + pub upgrade: bool, + /// Whether should run this server in the background + /// + /// `-d` or `--daemon` can be used + #[structopt(short, long)] + pub daemon: bool, + /// Not actually used. This flag is there so that the server is not upset seeing this flag + /// passed from `cargo test` sometimes + #[structopt(long)] + pub nocapture: bool, + /// Test the configuration and exit + /// + /// When this flag is set, calling `server.bootstrap()` will exit the process without errors + /// + /// This flag is useful for upgrading service where the user wants to make sure the new + /// service can start before shutting down the old server process. + /// + /// `-t` or `--test` can be used + #[structopt(short, long)] + pub test: bool, + /// The path to the configuration file. + /// + /// See [`ServerConf`] for more details of the configuration file. + /// + /// `-c` or `--conf` can be used + #[structopt(short, long)] + pub conf: Option, +} + +/// Create the default instance of Opt based on the current command-line args. +/// This is equivalent to running `Opt::from_args` but does not require the +/// caller to have included the `structopt::StructOpt` +impl Default for Opt { + fn default() -> Self { + Opt::from_args() + } +} + +impl ServerConf { + // Does not has to be async until we want runtime reload + pub fn load_from_yaml

(path: P) -> Result + where + P: AsRef + std::fmt::Display, + { + let conf_str = fs::read_to_string(&path).or_err_with(ReadError, || { + format!("Unable to read conf file from {path}") + })?; + debug!("Conf file read from {path}"); + Self::from_yaml(&conf_str) + } + + pub fn load_yaml_with_opt_override(opt: &Opt) -> Result { + if let Some(path) = &opt.conf { + let mut conf = Self::load_from_yaml(path)?; + if opt.daemon { + conf.daemon = true; + } + Ok(conf) + } else { + Error::e_explain(ReadError, "No path specified") + } + } + + pub fn new() -> Option { + Self::from_yaml("---\nversion: 1").ok() + } + + pub fn new_with_opt_override(opt: &Opt) -> Option { + let conf = Self::new(); + match conf { + Some(mut c) => { + if opt.daemon { + c.daemon = true; + } + Some(c) + } + None => None, + } + } + + pub fn from_yaml(conf_str: &str) -> Result { + trace!("Read conf file: {conf_str}"); + let conf: ServerConf = serde_yaml::from_str(conf_str).or_err_with(ReadError, || { + format!("Unable to parse yaml conf {conf_str}") + })?; + + trace!("Loaded conf: {conf:?}"); + conf.validate() + } + + pub fn to_yaml(&self) -> String { + serde_yaml::to_string(self).unwrap() + } + + pub fn validate(self) -> Result { + // TODO: do the validation + Ok(self) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + fn init_log() { + let _ = env_logger::builder().is_test(true).try_init(); + } + + #[test] + fn not_a_test_i_cannot_write_yaml_by_hand() { + init_log(); + let conf = ServerConf { + version: 1, + client_bind_to_ipv4: vec!["1.2.3.4".to_string(), "5.6.7.8".to_string()], + client_bind_to_ipv6: vec![], + ca_file: None, + daemon: false, + error_log: None, + pid_file: "".to_string(), + upgrade_sock: "".to_string(), + user: None, + group: None, + threads: 1, + work_stealing: true, + upstream_keepalive_pool_size: 4, + upstream_connect_offload_threadpools: None, + upstream_connect_offload_thread_per_pool: None, + }; + // cargo test -- --nocapture not_a_test_i_cannot_write_yaml_by_hand + println!("{}", conf.to_yaml()); + } + + #[test] + fn test_load_file() { + init_log(); + let conf_str = r#" +--- +version: 1 +client_bind_to_ipv4: + - 1.2.3.4 + - 5.6.7.8 +client_bind_to_ipv6: [] + "# + .to_string(); + let conf = ServerConf::from_yaml(&conf_str).unwrap(); + assert_eq!(2, conf.client_bind_to_ipv4.len()); + assert_eq!(0, conf.client_bind_to_ipv6.len()); + assert_eq!(1, conf.version); + } + + #[test] + fn test_default() { + init_log(); + let conf_str = r#" +--- +version: 1 + "# + .to_string(); + let conf = ServerConf::from_yaml(&conf_str).unwrap(); + assert_eq!(0, conf.client_bind_to_ipv4.len()); + assert_eq!(0, conf.client_bind_to_ipv6.len()); + assert_eq!(1, conf.version); + assert_eq!("/tmp/pingora.pid", conf.pid_file); + } +} diff --git a/pingora-core/src/server/daemon.rs b/pingora-core/src/server/daemon.rs new file mode 100644 index 0000000..fa0f9d1 --- /dev/null +++ b/pingora-core/src/server/daemon.rs @@ -0,0 +1,112 @@ +// 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 daemonize::Daemonize; +use log::{debug, error}; +use std::ffi::CString; +use std::fs::{self, OpenOptions}; +use std::os::unix::prelude::OpenOptionsExt; +use std::path::Path; + +use crate::server::configuration::ServerConf; + +// Utilities to daemonize a pingora server, i.e. run the process in the background, possibly +// under a different running user and/or group. + +// XXX: this operation should have been done when the old service is exiting. +// Now the new pid file just kick the old one out of the way +fn move_old_pid(path: &str) { + if !Path::new(path).exists() { + debug!("Old pid file does not exist"); + return; + } + let new_path = format!("{path}.old"); + match fs::rename(path, &new_path) { + Ok(()) => { + debug!("Old pid file renamed"); + } + Err(e) => { + error!( + "failed to rename pid file from {} to {}: {}", + path, new_path, e + ); + } + } +} + +unsafe fn gid_for_username(name: &CString) -> Option { + let passwd = libc::getpwnam(name.as_ptr() as *const libc::c_char); + if !passwd.is_null() { + return Some((*passwd).pw_gid); + } + None +} + +/// Start a server instance as a daemon. +pub fn daemonize(conf: &ServerConf) { + // TODO: customize working dir + + let daemonize = Daemonize::new() + .umask(0o007) // allow same group to access files but not everyone else + .pid_file(&conf.pid_file); + + let daemonize = if let Some(error_log) = conf.error_log.as_ref() { + let err = OpenOptions::new() + .append(true) + .create(true) + // open read() in case there are no readers + // available otherwise we will panic with + // an ENXIO since O_NONBLOCK is set + .read(true) + .custom_flags(libc::O_NONBLOCK) + .open(error_log) + .unwrap(); + daemonize.stderr(err) + } else { + daemonize + }; + + let daemonize = match conf.user.as_ref() { + Some(user) => { + let user_cstr = CString::new(user.as_str()).unwrap(); + + #[cfg(target_os = "macos")] + let group_id = unsafe { gid_for_username(&user_cstr).map(|gid| gid as i32) }; + #[cfg(target_os = "linux")] + let group_id = unsafe { gid_for_username(&user_cstr) }; + + daemonize + .privileged_action(move || { + if let Some(gid) = group_id { + // Set the supplemental group privileges for the child process. + unsafe { + libc::initgroups(user_cstr.as_ptr() as *const libc::c_char, gid); + } + } + }) + .user(user.as_str()) + .chown_pid_file(true) + } + None => daemonize, + }; + + let daemonize = match conf.group.as_ref() { + Some(group) => daemonize.group(group.as_str()), + None => daemonize, + }; + + move_old_pid(&conf.pid_file); + + daemonize.start().unwrap(); // hard crash when fail +} diff --git a/pingora-core/src/server/mod.rs b/pingora-core/src/server/mod.rs new file mode 100644 index 0000000..4273550 --- /dev/null +++ b/pingora-core/src/server/mod.rs @@ -0,0 +1,341 @@ +// 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. + +//! Server process and configuration management + +pub mod configuration; +mod daemon; +pub(crate) mod transfer_fd; + +use daemon::daemonize; +use log::{debug, error, info}; +use pingora_runtime::Runtime; +use pingora_timeout::fast_timeout; +use std::clone::Clone; +use std::sync::Arc; +use std::thread; +use tokio::signal::unix; +use tokio::sync::{watch, Mutex}; +use tokio::time::{sleep, Duration}; + +use crate::services::Service; +use configuration::{Opt, ServerConf}; +use transfer_fd::Fds; + +use pingora_error::{Error, ErrorType, Result}; + +/* time to wait before exiting the program +this is the graceful period for all existing session to finish */ +const EXIT_TIMEOUT: u64 = 60 * 5; +/* time to wait before shutting down listening sockets +this is the graceful period for the new service to get ready */ +const CLOSE_TIMEOUT: u64 = 5; + +enum ShutdownType { + Graceful, + Quick, +} + +/// The receiver for server's shutdown event. The value will turn to true once the server starts +/// to shutdown +pub type ShutdownWatch = watch::Receiver; +pub(crate) type ListenFds = Arc>; + +/// The server object +/// +/// This object represents an entire pingora server process which may have multiple independent +/// services (see [crate::services]). The server object handles signals, reading configuration, +/// zero downtime upgrade and error reporting. +pub struct Server { + services: Vec>, + listen_fds: Option, + shutdown_watch: watch::Sender, + // TODO: we many want to drop this copy to let sender call closed() + shutdown_recv: ShutdownWatch, + /// the parsed server configuration + pub configuration: Arc, + /// the parser command line options + pub options: Option, + /// the Sentry DSN + /// + /// Panics and other events sentry captures will send to this DSN **only in release mode** + pub sentry: Option, +} + +// TODO: delete the pid when exit + +impl Server { + async fn main_loop(&self) -> ShutdownType { + // waiting for exit signal + // TODO: there should be a signal handling function + let mut graceful_upgrade_signal = unix::signal(unix::SignalKind::quit()).unwrap(); + let mut graceful_terminate_signal = unix::signal(unix::SignalKind::terminate()).unwrap(); + let mut fast_shutdown_signal = unix::signal(unix::SignalKind::interrupt()).unwrap(); + tokio::select! { + _ = fast_shutdown_signal.recv() => { + info!("SIGINT received, exiting"); + ShutdownType::Quick + }, + _ = graceful_terminate_signal.recv() => { + // we receive a graceful terminate, all instances are instructed to stop + info!("SIGTERM received, gracefully exiting"); + // graceful shutdown if there are listening sockets + info!("Broadcasting graceful shutdown"); + match self.shutdown_watch.send(true) { + Ok(_) => { info!("Graceful shutdown started!"); } + Err(e) => { + error!("Graceful shutdown broadcast failed: {e}"); + } + } + info!("Broadcast graceful shutdown complete"); + ShutdownType::Graceful + } + _ = graceful_upgrade_signal.recv() => { + // TODO: still need to select! on signals in case a fast shutdown is needed + // aka: move below to another task and only kick it off here + info!("SIGQUIT received, sending socks and gracefully exiting"); + if let Some(fds) = &self.listen_fds { + let fds = fds.lock().await; + info!("Trying to send socks"); + // XXX: this is blocking IO + match fds.send_to_sock( + self.configuration.as_ref().upgrade_sock.as_str()) + { + Ok(_) => {info!("listener sockets sent");}, + Err(e) => { + error!("Unable to send listener sockets to new process: {e}"); + // sentry log error on fd send failure + #[cfg(not(debug_assertions))] + sentry::capture_error(&e); + } + } + sleep(Duration::from_secs(CLOSE_TIMEOUT)).await; + info!("Broadcasting graceful shutdown"); + // gracefully exiting + match self.shutdown_watch.send(true) { + Ok(_) => { info!("Graceful shutdown started!"); } + Err(e) => { + error!("Graceful shutdown broadcast failed: {e}"); + // switch to fast shutdown + return ShutdownType::Graceful; + } + } + info!("Broadcast graceful shutdown complete"); + ShutdownType::Graceful + } else { + info!("No socks to send, shutting down."); + ShutdownType::Graceful + } + }, + } + } + + fn run_service( + mut service: Box, + fds: Option, + shutdown: ShutdownWatch, + threads: usize, + work_stealing: bool, + ) -> Runtime +// NOTE: we need to keep the runtime outside async since + // otherwise the runtime will be dropped. + { + let service_runtime = Server::create_runtime(service.name(), threads, work_stealing); + service_runtime.get_handle().spawn(async move { + service.start_service(fds, shutdown).await; + info!("service exited.") + }); + service_runtime + } + + fn load_fds(&mut self, upgrade: bool) -> Result<(), nix::Error> { + let mut fds = Fds::new(); + if upgrade { + debug!("Trying to receive socks"); + fds.get_from_sock(self.configuration.as_ref().upgrade_sock.as_str())? + } + self.listen_fds = Some(Arc::new(Mutex::new(fds))); + Ok(()) + } + + /// Create a new [`Server`]. + /// + /// Only one [`Server`] needs to be created for a process. A [`Server`] can hold multiple + /// independent services. + /// + /// Command line options can either be passed by parsing the command line arguments via + /// `Opt::from_args()`, or be generated by other means. + pub fn new(opt: Option) -> Result { + let (tx, rx) = watch::channel(false); + + let conf = if let Some(opt) = opt.as_ref() { + opt.conf.as_ref().map_or_else( + || { + // options, no conf, generated + ServerConf::new_with_opt_override(opt).ok_or_else(|| { + Error::explain(ErrorType::ReadError, "Conf generation failed") + }) + }, + |_| { + // options and conf loaded + ServerConf::load_yaml_with_opt_override(opt) + }, + ) + } else { + ServerConf::new() + .ok_or_else(|| Error::explain(ErrorType::ReadError, "Conf generation failed")) + }?; + + Ok(Server { + services: vec![], + listen_fds: None, + shutdown_watch: tx, + shutdown_recv: rx, + configuration: Arc::new(conf), + options: opt, + sentry: None, + }) + } + + /// Add a service to this server. + /// + /// A service is anything that implements [`Service`]. + pub fn add_service(&mut self, service: impl Service + 'static) { + self.services.push(Box::new(service)); + } + + /// Similar to [`Self::add_service()`], but take a list of services + pub fn add_services(&mut self, services: Vec>) { + self.services.extend(services); + } + + /// Prepare the server to start + /// + /// When trying to zero downtime upgrade from an older version of the server which is already + /// running, this function will try to get all its listening sockets in order to take them over. + pub fn bootstrap(&mut self) { + info!("Bootstrap starting"); + debug!("{:#?}", self.options); + + /* only init sentry in release builds */ + #[cfg(not(debug_assertions))] + let _guard = match self.sentry.as_ref() { + Some(uri) => Some(sentry::init(uri.as_str())), + None => None, + }; + + if self.options.as_ref().map_or(false, |o| o.test) { + info!("Server Test passed, exiting"); + std::process::exit(0); + } + + // load fds + match self.load_fds(self.options.as_ref().map_or(false, |o| o.upgrade)) { + Ok(_) => { + info!("Bootstrap done"); + } + Err(e) => { + // sentry log error on fd load failure + #[cfg(not(debug_assertions))] + sentry::capture_error(&e); + + error!("Bootstrap failed on error: {:?}, exiting.", e); + std::process::exit(1); + } + } + } + + /// Start the server + /// + /// This function will block forever until the server needs to quit. So this would be the last + /// function to call for this object. + /// + /// Note: this function may fork the process for daemonization, so any additional threads created + /// before this function will be lost to any service logic once this function is called. + pub fn run_forever(&mut self) { + info!("Server starting"); + + let conf = self.configuration.as_ref(); + + if conf.daemon { + info!("Daemonizing the server"); + fast_timeout::pause_for_fork(); + daemonize(&self.configuration); + fast_timeout::unpause(); + } + + /* only init sentry in release builds */ + #[cfg(not(debug_assertions))] + let _guard = match self.sentry.as_ref() { + Some(uri) => Some(sentry::init(uri.as_str())), + None => None, + }; + + let mut runtimes: Vec = Vec::new(); + + while let Some(service) = self.services.pop() { + let threads = service.threads().unwrap_or(conf.threads); + let runtime = Server::run_service( + service, + self.listen_fds.clone(), + self.shutdown_recv.clone(), + threads, + conf.work_stealing, + ); + runtimes.push(runtime); + } + + // blocked on main loop so that it runs forever + // Only work steal runtime can use block_on() + let server_runtime = Server::create_runtime("Server", 1, true); + let shutdown_type = server_runtime.get_handle().block_on(self.main_loop()); + + if matches!(shutdown_type, ShutdownType::Graceful) { + info!("Graceful shutdown: grace period {}s starts", EXIT_TIMEOUT); + thread::sleep(Duration::from_secs(EXIT_TIMEOUT)); + info!("Graceful shutdown: grace period ends"); + } + + // Give tokio runtimes time to exit + let shutdown_timeout = match shutdown_type { + ShutdownType::Quick => Duration::from_secs(0), + ShutdownType::Graceful => Duration::from_secs(5), + }; + let shutdowns: Vec<_> = runtimes + .into_iter() + .map(|rt| { + info!("Waiting for runtimes to exit!"); + thread::spawn(move || { + rt.shutdown_timeout(shutdown_timeout); + thread::sleep(shutdown_timeout) + }) + }) + .collect(); + for shutdown in shutdowns { + if let Err(e) = shutdown.join() { + error!("Failed to shutdown runtime: {:?}", e); + } + } + info!("All runtimes exited, exiting now"); + std::process::exit(0); + } + + fn create_runtime(name: &str, threads: usize, work_steal: bool) -> Runtime { + if work_steal { + Runtime::new_steal(threads, name) + } else { + Runtime::new_no_steal(threads, name) + } + } +} diff --git a/pingora-core/src/server/transfer_fd/mod.rs b/pingora-core/src/server/transfer_fd/mod.rs new file mode 100644 index 0000000..ae07e33 --- /dev/null +++ b/pingora-core/src/server/transfer_fd/mod.rs @@ -0,0 +1,461 @@ +// 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. + +#[cfg(target_os = "linux")] +use log::{debug, error, warn}; +use nix::errno::Errno; +#[cfg(target_os = "linux")] +use nix::sys::socket::{self, AddressFamily, RecvMsg, SockFlag, SockType, UnixAddr}; +#[cfg(target_os = "linux")] +use nix::sys::stat; +use nix::{Error, NixPath}; +use std::collections::HashMap; +use std::io::Write; +#[cfg(target_os = "linux")] +use std::io::{IoSlice, IoSliceMut}; +use std::os::unix::io::RawFd; +#[cfg(target_os = "linux")] +use std::{thread, time}; + +// Utilities to transfer file descriptors between sockets, e.g. during graceful upgrades. + +/// Container for open file descriptors and their associated bind addresses. +pub struct Fds { + map: HashMap, +} + +impl Fds { + pub fn new() -> Self { + Fds { + map: HashMap::new(), + } + } + + pub fn add(&mut self, bind: String, fd: RawFd) { + self.map.insert(bind, fd); + } + + pub fn get(&self, bind: &str) -> Option<&RawFd> { + self.map.get(bind) + } + + pub fn serialize(&self) -> (Vec, Vec) { + let serialized: Vec<(String, RawFd)> = self + .map + .iter() + .map(|(key, value)| (key.clone(), *value)) + .collect(); + + ( + serialized.iter().map(|v| v.0.clone()).collect(), + serialized.iter().map(|v| v.1).collect(), + ) + // Surely there is a better way of doing this + } + + pub fn deserialize(&mut self, binds: Vec, fds: Vec) { + assert!(binds.len() == fds.len()); + // TODO: use zip() + for i in 0..binds.len() { + self.map.insert(binds[i].clone(), fds[i]); + } + } + + pub fn send_to_sock

(&self, path: &P) -> Result + where + P: ?Sized + NixPath + std::fmt::Display, + { + let (vec_key, vec_fds) = self.serialize(); + let mut ser_buf: [u8; 2048] = [0; 2048]; + let ser_key_size = serialize_vec_string(&vec_key, &mut ser_buf); + send_fds_to(vec_fds, &ser_buf[..ser_key_size], path) + } + + pub fn get_from_sock

(&mut self, path: &P) -> Result<(), Error> + where + P: ?Sized + NixPath + std::fmt::Display, + { + let mut de_buf: [u8; 2048] = [0; 2048]; + let (fds, bytes) = get_fds_from(path, &mut de_buf)?; + let keys = deserialize_vec_string(&de_buf[..bytes]); + self.deserialize(keys, fds); + Ok(()) + } +} + +fn serialize_vec_string(vec_string: &[String], mut buf: &mut [u8]) -> usize { + // There are many way to do this. serde is probably the way to go + // But let's start with something simple: space separated strings + let joined = vec_string.join(" "); + // TODO: check the buf is large enough + buf.write(joined.as_bytes()).unwrap() +} + +fn deserialize_vec_string(buf: &[u8]) -> Vec { + let joined = std::str::from_utf8(buf).unwrap(); // TODO: handle error + let mut results: Vec = Vec::new(); + for iter in joined.split_ascii_whitespace() { + results.push(String::from(iter)); + } + results +} + +#[cfg(target_os = "linux")] +pub fn get_fds_from

(path: &P, payload: &mut [u8]) -> Result<(Vec, usize), Error> +where + P: ?Sized + NixPath + std::fmt::Display, +{ + const MAX_FDS: usize = 32; + + let listen_fd = socket::socket( + AddressFamily::Unix, + SockType::Stream, + SockFlag::SOCK_NONBLOCK, + None, + ) + .unwrap(); + let unix_addr = UnixAddr::new(path).unwrap(); + // clean up old sock + match nix::unistd::unlink(path) { + Ok(()) => { + debug!("unlink {} done", path); + } + Err(e) => { + // Normal if file does not exist + debug!("unlink {} failed: {}", path, e); + // TODO: warn if exist but not able to unlink + } + }; + socket::bind(listen_fd, &unix_addr).unwrap(); + + /* sock is created before we change user, need to give permission to all */ + stat::fchmodat( + None, + path, + stat::Mode::all(), + stat::FchmodatFlags::FollowSymlink, + ) + .unwrap(); + + socket::listen(listen_fd, 8).unwrap(); + + let fd = match accept_with_retry(listen_fd) { + Ok(fd) => fd, + Err(e) => { + error!("Giving up reading socket from: {path}, error: {e:?}"); + //cleanup + if nix::unistd::close(listen_fd).is_ok() { + nix::unistd::unlink(path).unwrap(); + } + return Err(e); + } + }; + + let mut io_vec = [IoSliceMut::new(payload); 1]; + let mut cmsg_buf = nix::cmsg_space!([RawFd; MAX_FDS]); + let msg: RecvMsg = socket::recvmsg( + fd, + &mut io_vec, + Some(&mut cmsg_buf), + socket::MsgFlags::empty(), + ) + .unwrap(); + + let mut fds: Vec = Vec::new(); + for cmsg in msg.cmsgs() { + if let socket::ControlMessageOwned::ScmRights(mut vec_fds) = cmsg { + fds.append(&mut vec_fds) + } else { + warn!("Unexpected control messages: {cmsg:?}") + } + } + + //cleanup + if nix::unistd::close(listen_fd).is_ok() { + nix::unistd::unlink(path).unwrap(); + } + + Ok((fds, msg.bytes)) +} + +#[cfg(not(target_os = "linux"))] +pub fn get_fds_from

(_path: &P, _payload: &mut [u8]) -> Result<(Vec, usize), Error> +where + P: ?Sized + NixPath + std::fmt::Display, +{ + Err(Errno::ECONNREFUSED) +} + +#[cfg(target_os = "linux")] +const MAX_RETRY: usize = 5; +#[cfg(target_os = "linux")] +const RETRY_INTERVAL: time::Duration = time::Duration::from_secs(1); + +#[cfg(target_os = "linux")] +fn accept_with_retry(listen_fd: i32) -> Result { + let mut retried = 0; + loop { + match socket::accept(listen_fd) { + Ok(fd) => return Ok(fd), + Err(e) => { + if retried > MAX_RETRY { + return Err(e); + } + match e { + Errno::EAGAIN => { + error!( + "No incoming socket transfer, sleep {RETRY_INTERVAL:?} and try again" + ); + retried += 1; + thread::sleep(RETRY_INTERVAL); + } + _ => { + error!("Error accepting socket transfer: {e}"); + return Err(e); + } + } + } + } + } +} + +#[cfg(target_os = "linux")] +pub fn send_fds_to

(fds: Vec, payload: &[u8], path: &P) -> Result +where + P: ?Sized + NixPath + std::fmt::Display, +{ + const MAX_NONBLOCKING_POLLS: usize = 20; + const NONBLOCKING_POLL_INTERVAL: time::Duration = time::Duration::from_millis(500); + + let send_fd = socket::socket( + AddressFamily::Unix, + SockType::Stream, + SockFlag::SOCK_NONBLOCK, + None, + )?; + let unix_addr = UnixAddr::new(path)?; + let mut retried = 0; + let mut nonblocking_polls = 0; + + let conn_result: Result = loop { + match socket::connect(send_fd, &unix_addr) { + Ok(_) => break Ok(0), + Err(e) => match e { + /* If the new process hasn't created the upgrade sock we'll get an ENOENT. + ECONNREFUSED may happen if the sock wasn't cleaned up + and the old process tries sending before the new one is listening. + EACCES may happen if connect() happen before the correct permission is set */ + Errno::ENOENT | Errno::ECONNREFUSED | Errno::EACCES => { + /*the server is not ready yet*/ + retried += 1; + if retried > MAX_RETRY { + error!( + "Max retry: {} reached. Giving up sending socket to: {}, error: {:?}", + MAX_RETRY, path, e + ); + break Err(e); + } + warn!("server not ready, will try again in {RETRY_INTERVAL:?}"); + thread::sleep(RETRY_INTERVAL); + } + /* handle nonblocking IO */ + Errno::EINPROGRESS => { + nonblocking_polls += 1; + if nonblocking_polls >= MAX_NONBLOCKING_POLLS { + error!("Connect() not ready after retries when sending socket to: {path}",); + break Err(e); + } + warn!("Connect() not ready, will try again in {NONBLOCKING_POLL_INTERVAL:?}",); + thread::sleep(NONBLOCKING_POLL_INTERVAL); + } + _ => { + error!("Error sending socket to: {path}, error: {e:?}"); + break Err(e); + } + }, + } + }; + + let result = match conn_result { + Ok(_) => { + let io_vec = [IoSlice::new(payload); 1]; + let scm = socket::ControlMessage::ScmRights(fds.as_slice()); + let cmsg = [scm; 1]; + loop { + match socket::sendmsg( + send_fd, + &io_vec, + &cmsg, + socket::MsgFlags::empty(), + None::<&UnixAddr>, + ) { + Ok(result) => break Ok(result), + Err(e) => match e { + /* handle nonblocking IO */ + Errno::EAGAIN => { + nonblocking_polls += 1; + if nonblocking_polls >= MAX_NONBLOCKING_POLLS { + error!( + "Sendmsg() not ready after retries when sending socket to: {}", + path + ); + break Err(e); + } + warn!( + "Sendmsg() not ready, will try again in {:?}", + NONBLOCKING_POLL_INTERVAL + ); + thread::sleep(NONBLOCKING_POLL_INTERVAL); + } + _ => break Err(e), + }, + } + } + } + Err(_) => conn_result, + }; + + nix::unistd::close(send_fd).unwrap(); + result +} + +#[cfg(not(target_os = "linux"))] +pub fn send_fds_to

(_fds: Vec, _payload: &[u8], _path: &P) -> Result +where + P: ?Sized + NixPath + std::fmt::Display, +{ + Ok(0) +} + +#[cfg(test)] +#[cfg(target_os = "linux")] +mod tests { + use super::*; + use log::{debug, error}; + use std::thread; + + fn init_log() { + let _ = env_logger::builder().is_test(true).try_init(); + } + + #[test] + fn test_add_get() { + init_log(); + let mut fds = Fds::new(); + let key = "1.1.1.1:80".to_string(); + fds.add(key.clone(), 128); + assert_eq!(128, *fds.get(&key).unwrap()); + } + + #[test] + fn test_table_serde() { + init_log(); + let mut fds = Fds::new(); + let key1 = "1.1.1.1:80".to_string(); + fds.add(key1.clone(), 128); + let key2 = "1.1.1.1:443".to_string(); + fds.add(key2.clone(), 129); + + let (k, v) = fds.serialize(); + let mut fds2 = Fds::new(); + fds2.deserialize(k, v); + + assert_eq!(128, *fds2.get(&key1).unwrap()); + assert_eq!(129, *fds2.get(&key2).unwrap()); + } + + #[test] + fn test_vec_string_serde() { + init_log(); + let vec_str: Vec = vec!["aaaa".to_string(), "bbb".to_string()]; + let mut ser_buf: [u8; 1024] = [0; 1024]; + let size = serialize_vec_string(&vec_str, &mut ser_buf); + let de_vec_string = deserialize_vec_string(&ser_buf[..size]); + assert_eq!(de_vec_string.len(), 2); + assert_eq!(de_vec_string[0], "aaaa"); + assert_eq!(de_vec_string[1], "bbb"); + } + + #[test] + fn test_send_receive_fds() { + init_log(); + let dumb_fd = socket::socket( + AddressFamily::Unix, + SockType::Stream, + SockFlag::empty(), + None, + ) + .unwrap(); + + // receiver need to start in another thread since it is blocking + let child = thread::spawn(move || { + let mut buf: [u8; 32] = [0; 32]; + let (fds, bytes) = get_fds_from("/tmp/pingora_fds_receive.sock", &mut buf).unwrap(); + debug!("{:?}", fds); + assert_eq!(1, fds.len()); + assert_eq!(32, bytes); + assert_eq!(1, buf[0]); + assert_eq!(1, buf[31]); + }); + + let fds = vec![dumb_fd]; + let buf: [u8; 128] = [1; 128]; + match send_fds_to(fds, &buf, "/tmp/pingora_fds_receive.sock") { + Ok(sent) => { + assert!(sent > 0); + } + Err(e) => { + error!("{:?}", e); + panic!() + } + } + + child.join().unwrap(); + } + + #[test] + fn test_serde_via_socket() { + init_log(); + let mut fds = Fds::new(); + let key1 = "1.1.1.1:80".to_string(); + let dumb_fd1 = socket::socket( + AddressFamily::Unix, + SockType::Stream, + SockFlag::empty(), + None, + ) + .unwrap(); + fds.add(key1.clone(), dumb_fd1); + let key2 = "1.1.1.1:443".to_string(); + let dumb_fd2 = socket::socket( + AddressFamily::Unix, + SockType::Stream, + SockFlag::empty(), + None, + ) + .unwrap(); + fds.add(key2.clone(), dumb_fd2); + + let child = thread::spawn(move || { + let mut fds2 = Fds::new(); + fds2.get_from_sock("/tmp/pingora_fds_receive2.sock") + .unwrap(); + assert!(*fds2.get(&key1).unwrap() > 0); + assert!(*fds2.get(&key2).unwrap() > 0); + }); + + fds.send_to_sock("/tmp/pingora_fds_receive2.sock").unwrap(); + child.join().unwrap(); + } +} diff --git a/pingora-core/src/services/background.rs b/pingora-core/src/services/background.rs new file mode 100644 index 0000000..4eec577 --- /dev/null +++ b/pingora-core/src/services/background.rs @@ -0,0 +1,84 @@ +// 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. + +//! The background service +//! +//! A [BackgroundService] can be run as part of a Pingora application to add supporting logic that +//! exists outside of the request/response lifecycle. +//! Examples might include service discovery (load balancing) and background updates such as +//! push-style metrics. + +use async_trait::async_trait; +use std::sync::Arc; + +use super::Service; +use crate::server::{ListenFds, ShutdownWatch}; + +/// The background service interface +#[cfg_attr(not(doc_async_trait), async_trait)] +pub trait BackgroundService { + /// This function is called when the pingora server tries to start all the + /// services. The background service can return at anytime or wait for the + /// `shutdown` signal. + async fn start(&self, mut shutdown: ShutdownWatch); +} + +/// A generic type of background service +pub struct GenBackgroundService { + // Name of the service + name: String, + // Task the service will execute + task: Arc, + /// The number of threads. Default is 1 + pub threads: Option, +} + +impl GenBackgroundService { + /// Generates a background service that can run in the pingora runtime + pub fn new(name: String, task: Arc) -> Self { + Self { + name, + task, + threads: Some(1), + } + } + + /// Return the task behind [Arc] to be shared other logic. + pub fn task(&self) -> Arc { + self.task.clone() + } +} + +#[async_trait] +impl Service for GenBackgroundService +where + A: BackgroundService + Send + Sync + 'static, +{ + async fn start_service(&mut self, _fds: Option, shutdown: ShutdownWatch) { + self.task.start(shutdown).await; + } + + fn name(&self) -> &str { + &self.name + } + + fn threads(&self) -> Option { + self.threads + } +} + +// Helper function to create a background service with a human readable name +pub fn background_service(name: &str, task: SV) -> GenBackgroundService { + GenBackgroundService::new(format!("BG {name}"), Arc::new(task)) +} diff --git a/pingora-core/src/services/listening.rs b/pingora-core/src/services/listening.rs new file mode 100644 index 0000000..6960034 --- /dev/null +++ b/pingora-core/src/services/listening.rs @@ -0,0 +1,232 @@ +// 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. + +//! The listening service +//! +//! A [Service] (listening service) responds to incoming requests on its endpoints. +//! Each [Service] can be configured with custom application logic (e.g. an `HTTPProxy`) and one or +//! more endpoints to listen to. + +use crate::apps::ServerApp; +use crate::listeners::{Listeners, ServerAddress, TcpSocketOptions, TlsSettings, TransportStack}; +use crate::protocols::Stream; +use crate::server::{ListenFds, ShutdownWatch}; +use crate::services::Service as ServiceTrait; + +use async_trait::async_trait; +use log::{debug, error, info}; +use pingora_error::Result; +use pingora_runtime::current_handle; +use std::fs::Permissions; +use std::sync::Arc; + +/// The type of service that is associated with a list of listening endpoints and a particular application +pub struct Service { + name: String, + listeners: Listeners, + app_logic: Arc, + /// The number of preferred threads. `None` to follow global setting. + pub threads: Option, +} + +impl Service { + /// Create a new [`Service`] with the given application (see [`crate::apps`]). + pub fn new(name: String, app_logic: Arc) -> Self { + Service { + name, + listeners: Listeners::new(), + app_logic, + threads: None, + } + } + + /// Create a new [`Service`] with the given application (see [`crate::apps`]) and the given + /// [`Listeners`]. + pub fn with_listeners(name: String, listeners: Listeners, app_logic: Arc) -> Self { + Service { + name, + listeners, + app_logic, + threads: None, + } + } + + /// Get the [`Listeners`], mostly to add more endpoints. + pub fn endpoints(&mut self) -> &mut Listeners { + &mut self.listeners + } + + // the follow add* function has no effect if the server is already started + + /// Add a TCP listening endpoint with the given address (e.g., `127.0.0.1:8000`). + pub fn add_tcp(&mut self, addr: &str) { + self.listeners.add_tcp(addr); + } + + /// Add a TCP listening endpoint with the given [`TcpSocketOptions`]. + pub fn add_tcp_with_settings(&mut self, addr: &str, sock_opt: TcpSocketOptions) { + self.listeners.add_tcp_with_settings(addr, sock_opt); + } + + /// Add an Unix domain socket listening endpoint with the given path. + /// + /// Optionally take a permission of the socket file. The default is read and write access for + /// everyone (0o666). + pub fn add_uds(&mut self, addr: &str, perm: Option) { + self.listeners.add_uds(addr, perm); + } + + /// Add a TLS listening endpoint with the given certificate and key paths. + pub fn add_tls(&mut self, addr: &str, cert_path: &str, key_path: &str) -> Result<()> { + self.listeners.add_tls(addr, cert_path, key_path) + } + + /// Add a TLS listening endpoint with the given [`TlsSettings`] and [`TcpSocketOptions`]. + pub fn add_tls_with_settings( + &mut self, + addr: &str, + sock_opt: Option, + settings: TlsSettings, + ) { + self.listeners + .add_tls_with_settings(addr, sock_opt, settings) + } + + /// Add an endpoint according to the given [`ServerAddress`] + pub fn add_address(&mut self, addr: ServerAddress) { + self.listeners.add_address(addr); + } +} + +impl Service { + pub async fn handle_event(event: Stream, app_logic: Arc, shutdown: ShutdownWatch) { + debug!("new event!"); + let mut reuse_event = app_logic.process_new(event, &shutdown).await; + while let Some(event) = reuse_event { + // TODO: with no steal runtime, consider spawn() the next event on + // another thread for more evenly load balancing + debug!("new reusable event!"); + reuse_event = app_logic.process_new(event, &shutdown).await; + } + } + + async fn run_endpoint( + app_logic: Arc, + mut stack: TransportStack, + mut shutdown: ShutdownWatch, + ) { + if let Err(e) = stack.listen().await { + error!("Listen() failed: {e}"); + return; + } + + // the accept loop, until the system is shutting down + loop { + let new_io = tokio::select! { // TODO: consider biased for perf reason? + new_io = stack.accept() => new_io, + shutdown_signal = shutdown.changed() => { + match shutdown_signal { + Ok(()) => { + if !*shutdown.borrow() { + // happen in the initial read + continue; + } + info!("Shutting down {}", stack.as_str()); + break; + } + Err(e) => { + error!("shutdown_signal error {e}"); + break; + } + } + } + }; + match new_io { + Ok(io) => { + let app = app_logic.clone(); + let shutdown = shutdown.clone(); + current_handle().spawn(async move { + match io.handshake().await { + Ok(io) => Self::handle_event(io, app, shutdown).await, + Err(e) => { + // TODO: Maybe IOApp trait needs a fn to handle/filter our this error + error!("Downstream handshake error {e}"); + } + } + }); + } + Err(e) => { + error!("Accept() failed {e}"); + if let Some(io_error) = e + .root_cause() + .downcast_ref::() + .and_then(|e| e.raw_os_error()) + { + // 24: too many open files. In this case accept() will continue return this + // error without blocking, which could use up all the resources + if io_error == 24 { + // call sleep to calm the thread down and wait for others to release + // some resources + tokio::time::sleep(std::time::Duration::from_secs(1)).await; + } + } + } + } + } + + stack.cleanup(); + } +} + +#[async_trait] +impl ServiceTrait for Service { + async fn start_service(&mut self, fds: Option, shutdown: ShutdownWatch) { + let runtime = current_handle(); + let endpoints = self.listeners.build(fds); + + let handlers = endpoints.into_iter().map(|endpoint| { + let app_logic = self.app_logic.clone(); + let shutdown = shutdown.clone(); + runtime.spawn(async move { + Self::run_endpoint(app_logic, endpoint, shutdown).await; + }) + }); + + futures::future::join_all(handlers).await; + self.listeners.cleanup(); + self.app_logic.cleanup(); + } + + fn name(&self) -> &str { + &self.name + } + + fn threads(&self) -> Option { + self.threads + } +} + +use crate::apps::prometheus_http_app::PrometheusServer; + +impl Service { + /// The Prometheus HTTP server + /// + /// The HTTP server endpoint that reports Prometheus metrics collected in the entire service + pub fn prometheus_http_service() -> Self { + Service::new( + "Prometheus metric HTTP".to_string(), + Arc::new(PrometheusServer::new()), + ) + } +} diff --git a/pingora-core/src/services/mod.rs b/pingora-core/src/services/mod.rs new file mode 100644 index 0000000..67e72dc --- /dev/null +++ b/pingora-core/src/services/mod.rs @@ -0,0 +1,55 @@ +// 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. + +//! The service interface +//! +//! A service to the pingora server is just something runs forever until the server is shutting +//! down. +//! +//! Two types of services are particularly useful +//! - services that are listening to some (TCP) endpoints +//! - services that are just running in the background. + +use async_trait::async_trait; + +use crate::server::{ListenFds, ShutdownWatch}; + +pub mod background; +pub mod listening; + +/// The service interface +#[async_trait] +pub trait Service: Sync + Send { + /// This function will be called when the server is ready to start the service. + /// + /// - `fds`: a collection of listening file descriptors. During zero downtime restart + /// the `fds` would contain the listening sockets passed from the old service, services should + /// take the sockets they need to use then. If the sockets the service looks for don't appear in + /// the collection, the service should create its own listening sockets and then put them into + /// the collection in order for them to be passed to the next server. + /// - `shutdown`: the shutdown signal this server would receive. + async fn start_service(&mut self, fds: Option, mut shutdown: ShutdownWatch); + + /// The name of the service, just for logging and naming the threads assigned to this service + /// + /// Note that due to the limit of the underlying system, only the first 16 chars will be used + fn name(&self) -> &str; + + /// The preferred number of threads to run this service + /// + /// If `None`, the global setting will be used + fn threads(&self) -> Option { + None + } +} diff --git a/pingora-core/src/upstreams/mod.rs b/pingora-core/src/upstreams/mod.rs new file mode 100644 index 0000000..7352b61 --- /dev/null +++ b/pingora-core/src/upstreams/mod.rs @@ -0,0 +1,17 @@ +// 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. + +//! The interface to connect to a remote server + +pub mod peer; diff --git a/pingora-core/src/upstreams/peer.rs b/pingora-core/src/upstreams/peer.rs new file mode 100644 index 0000000..a36418b --- /dev/null +++ b/pingora-core/src/upstreams/peer.rs @@ -0,0 +1,537 @@ +// 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. + +//! Defines where to connect to and how to connect to a remote server + +use ahash::AHasher; +use std::collections::BTreeMap; +use std::fmt::{Display, Formatter, Result as FmtResult}; +use std::hash::{Hash, Hasher}; +use std::net::{IpAddr, SocketAddr as InetSocketAddr, ToSocketAddrs as ToInetSocketAddrs}; +use std::os::unix::net::SocketAddr as UnixSocketAddr; +use std::os::unix::prelude::AsRawFd; +use std::path::{Path, PathBuf}; +use std::sync::Arc; +use std::time::Duration; + +pub use crate::protocols::l4::ext::TcpKeepalive; +use crate::protocols::l4::socket::SocketAddr; +use crate::protocols::ConnFdReusable; +use crate::tls::x509::X509; +use crate::utils::{get_organization_unit, CertKey}; + +pub use crate::protocols::ssl::ALPN; + +/// The interface to trace the connection +pub trait Tracing: Send + Sync + std::fmt::Debug { + /// This method is called when successfully connected to a remote server + fn on_connected(&self); + /// This method is called when the connection is disconnected. + fn on_disconnected(&self); + /// A way to clone itself + fn boxed_clone(&self) -> Box; +} + +/// An object-safe version of Tracing object that can use Clone +#[derive(Debug)] +pub struct Tracer(pub Box); + +impl Clone for Tracer { + fn clone(&self) -> Self { + Tracer(self.0.boxed_clone()) + } +} + +/// [`Peer`] defines the interface to communicate with the [`crate::connectors`] regarding where to +/// connect to and how to connect to it. +pub trait Peer: Display + Clone { + /// The remote address to connect to + fn address(&self) -> &SocketAddr; + /// If TLS should be used; + fn tls(&self) -> bool; + /// The SNI to send, if TLS is used + fn sni(&self) -> &str; + /// To decide whether a [`Peer`] can use the connection established by another [`Peer`]. + /// + /// The connection to two peers are considered reusable to each other if their reuse hashes are + /// the same + fn reuse_hash(&self) -> u64; + /// Get the proxy setting to connect to the remote server + fn get_proxy(&self) -> Option<&Proxy> { + None + } + /// Get the additional options to connect to the peer. + /// + /// See [`PeerOptions`] for more details + fn get_peer_options(&self) -> Option<&PeerOptions> { + None + } + /// Get the additional options for modification. + fn get_mut_peer_options(&mut self) -> Option<&mut PeerOptions> { + None + } + /// Whether the TLS handshake should validate the cert of the server. + fn verify_cert(&self) -> bool { + match self.get_peer_options() { + Some(opt) => opt.verify_cert, + None => false, + } + } + /// Whether the TLS handshake should verify that the server cert matches the SNI. + fn verify_hostname(&self) -> bool { + match self.get_peer_options() { + Some(opt) => opt.verify_hostname, + None => false, + } + } + /// The alternative common name to use to verify the server cert. + /// + /// If the server cert doesn't match the SNI, this name will be used to + /// verify the cert. + fn alternative_cn(&self) -> Option<&String> { + match self.get_peer_options() { + Some(opt) => opt.alternative_cn.as_ref(), + None => None, + } + } + /// Which local source address this connection should be bind to. + fn bind_to(&self) -> Option<&InetSocketAddr> { + match self.get_peer_options() { + Some(opt) => opt.bind_to.as_ref(), + None => None, + } + } + /// How long connect() call should be wait before it returns a timeout error. + fn connection_timeout(&self) -> Option { + match self.get_peer_options() { + Some(opt) => opt.connection_timeout, + None => None, + } + } + /// How long the overall connection establishment should take before a timeout error is returned. + fn total_connection_timeout(&self) -> Option { + match self.get_peer_options() { + Some(opt) => opt.total_connection_timeout, + None => None, + } + } + /// If the connection can be reused, how long the connection should wait to be reused before it + /// shuts down. + fn idle_timeout(&self) -> Option { + self.get_peer_options().and_then(|o| o.idle_timeout) + } + + /// Get the ALPN preference. + fn get_alpn(&self) -> Option<&ALPN> { + self.get_peer_options().map(|opt| &opt.alpn) + } + + /// Get the CA cert to use to validate the server cert. + /// + /// If not set, the default CAs will be used. + fn get_ca(&self) -> Option<&Arc>> { + match self.get_peer_options() { + Some(opt) => opt.ca.as_ref(), + None => None, + } + } + + /// Get the client cert and key for mutual TLS if any + fn get_client_cert_key(&self) -> Option<&Arc> { + None + } + + /// The TCP keepalive setting that should be applied to this connection + fn tcp_keepalive(&self) -> Option<&TcpKeepalive> { + self.get_peer_options() + .and_then(|o| o.tcp_keepalive.as_ref()) + } + + /// The interval H2 pings to send to the server if any + fn h2_ping_interval(&self) -> Option { + self.get_peer_options().and_then(|o| o.h2_ping_interval) + } + + fn matches_fd(&self, fd: V) -> bool { + self.address().check_fd_match(fd) + } + + fn get_tracer(&self) -> Option { + None + } +} + +/// A simple TCP or TLS peer without many complicated settings. +#[derive(Debug, Clone)] +pub struct BasicPeer { + pub _address: SocketAddr, + pub sni: String, + pub options: PeerOptions, +} + +impl BasicPeer { + /// Create a new [`BasicPeer`] + pub fn new(address: &str) -> Self { + BasicPeer { + _address: SocketAddr::Inet(address.parse().unwrap()), // TODO: check error, add support + // for UDS + sni: "".to_string(), // TODO: add support for SNI + options: PeerOptions::new(), + } + } +} + +impl Display for BasicPeer { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!(f, "{:?}", self) + } +} + +impl Peer for BasicPeer { + fn address(&self) -> &SocketAddr { + &self._address + } + + fn tls(&self) -> bool { + !self.sni.is_empty() + } + + fn bind_to(&self) -> Option<&InetSocketAddr> { + None + } + + fn sni(&self) -> &str { + &self.sni + } + + // TODO: change connection pool to accept u64 instead of String + fn reuse_hash(&self) -> u64 { + let mut hasher = AHasher::default(); + self._address.hash(&mut hasher); + hasher.finish() + } + + fn get_peer_options(&self) -> Option<&PeerOptions> { + Some(&self.options) + } +} + +/// Define whether to connect via http or https +#[derive(Hash, Clone, Debug, PartialEq)] +pub enum Scheme { + HTTP, + HTTPS, +} + +impl Display for Scheme { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + match self { + Scheme::HTTP => write!(f, "HTTP"), + Scheme::HTTPS => write!(f, "HTTPS"), + } + } +} + +impl Scheme { + pub fn from_tls_bool(tls: bool) -> Self { + if tls { + Self::HTTPS + } else { + Self::HTTP + } + } +} + +/// The preferences to connect to a remote server +/// +/// See [`Peer`] for the meaning of the fields +#[derive(Clone, Debug)] +pub struct PeerOptions { + pub bind_to: Option, + pub connection_timeout: Option, + pub total_connection_timeout: Option, + pub read_timeout: Option, + pub idle_timeout: Option, + pub write_timeout: Option, + pub verify_cert: bool, + pub verify_hostname: bool, + /* accept the cert if it's CN matches the SNI or this name */ + pub alternative_cn: Option, + pub alpn: ALPN, + pub ca: Option>>, + pub tcp_keepalive: Option, + pub no_header_eos: bool, + pub h2_ping_interval: Option, + // how many concurrent h2 stream are allowed in the same connection + pub max_h2_streams: usize, + pub extra_proxy_headers: BTreeMap>, + // The list of curve the tls connection should advertise + // if `None`, the default curves will be used + pub curves: Option<&'static str>, + // see ssl_use_second_key_share + pub second_keyshare: bool, + // use Arc because Clone is required but not allowed in trait object + pub tracer: Option, +} + +impl PeerOptions { + /// Create a new [`PeerOptions`] + pub fn new() -> Self { + PeerOptions { + bind_to: None, + connection_timeout: None, + total_connection_timeout: None, + read_timeout: None, + idle_timeout: None, + write_timeout: None, + verify_cert: true, + verify_hostname: true, + alternative_cn: None, + alpn: ALPN::H1, + ca: None, + tcp_keepalive: None, + no_header_eos: false, + h2_ping_interval: None, + max_h2_streams: 1, + extra_proxy_headers: BTreeMap::new(), + curves: None, + second_keyshare: true, // default true and noop when not using PQ curves + tracer: None, + } + } + + /// Set the ALPN according to the `max` and `min` constrains. + pub fn set_http_version(&mut self, max: u8, min: u8) { + self.alpn = ALPN::new(max, min); + } +} + +impl Display for PeerOptions { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + if let Some(b) = self.bind_to { + write!(f, "bind_to: {:?},", b)?; + } + if let Some(t) = self.connection_timeout { + write!(f, "conn_timeout: {:?},", t)?; + } + if let Some(t) = self.total_connection_timeout { + write!(f, "total_conn_timeout: {:?},", t)?; + } + if self.verify_cert { + write!(f, "verify_cert: true,")?; + } + if self.verify_hostname { + write!(f, "verify_hostname: true,")?; + } + if let Some(cn) = &self.alternative_cn { + write!(f, "alt_cn: {},", cn)?; + } + write!(f, "alpn: {},", self.alpn)?; + if let Some(cas) = &self.ca { + for ca in cas.iter() { + write!( + f, + "CA: {}, expire: {},", + get_organization_unit(ca).unwrap_or_default(), + ca.not_after() + )?; + } + } + if let Some(tcp_keepalive) = &self.tcp_keepalive { + write!(f, "tcp_keepalive: {},", tcp_keepalive)?; + } + if self.no_header_eos { + write!(f, "no_header_eos: true,")?; + } + if let Some(h2_ping_interval) = self.h2_ping_interval { + write!(f, "h2_ping_interval: {:?},", h2_ping_interval)?; + } + Ok(()) + } +} + +/// A peer representing the remote HTTP server to connect to +#[derive(Debug, Clone)] +pub struct HttpPeer { + pub _address: SocketAddr, + pub scheme: Scheme, + pub sni: String, + pub proxy: Option, + pub client_cert_key: Option>, + pub options: PeerOptions, +} + +impl HttpPeer { + // These methods are pretty ad-hoc + pub fn is_tls(&self) -> bool { + match self.scheme { + Scheme::HTTP => false, + Scheme::HTTPS => true, + } + } + + fn new_from_sockaddr(address: SocketAddr, tls: bool, sni: String) -> Self { + HttpPeer { + _address: address, + scheme: Scheme::from_tls_bool(tls), + sni, + proxy: None, + client_cert_key: None, + options: PeerOptions::new(), + } + } + + /// Create a new [`HttpPeer`] with the given socket address and TLS settings. + pub fn new(address: A, tls: bool, sni: String) -> Self { + let mut addrs_iter = address.to_socket_addrs().unwrap(); //TODO: handle error + let addr = addrs_iter.next().unwrap(); + Self::new_from_sockaddr(SocketAddr::Inet(addr), tls, sni) + } + + /// Create a new [`HttpPeer`] with the given path to Unix domain socket and TLS settings. + pub fn new_uds(path: &str, tls: bool, sni: String) -> Self { + let addr = SocketAddr::Unix(UnixSocketAddr::from_pathname(Path::new(path)).unwrap()); //TODO: handle error + Self::new_from_sockaddr(addr, tls, sni) + } + + /// Create a new [`HttpPeer`] that uses a proxy to connect to the upstream IP and port + /// combination. + pub fn new_proxy( + next_hop: &str, + ip_addr: IpAddr, + port: u16, + tls: bool, + sni: &str, + headers: BTreeMap>, + ) -> Self { + HttpPeer { + _address: SocketAddr::Inet(InetSocketAddr::new(ip_addr, port)), + scheme: Scheme::from_tls_bool(tls), + sni: sni.to_string(), + proxy: Some(Proxy { + next_hop: PathBuf::from(next_hop).into(), + host: ip_addr.to_string(), + port, + headers, + }), + client_cert_key: None, + options: PeerOptions::new(), + } + } + + fn peer_hash(&self) -> u64 { + let mut hasher = AHasher::default(); + self.hash(&mut hasher); + hasher.finish() + } +} + +impl Hash for HttpPeer { + fn hash(&self, state: &mut H) { + self._address.hash(state); + self.scheme.hash(state); + self.proxy.hash(state); + self.sni.hash(state); + // client cert serial + self.client_cert_key.hash(state); + // origin server cert verification + self.verify_cert().hash(state); + self.verify_hostname().hash(state); + self.alternative_cn().hash(state); + } +} + +impl Display for HttpPeer { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!(f, "addr: {}, scheme: {},", self._address, self.scheme)?; + if !self.sni.is_empty() { + write!(f, "sni: {},", self.sni)?; + } + if let Some(p) = self.proxy.as_ref() { + write!(f, "proxy: {p},")?; + } + if let Some(cert) = &self.client_cert_key { + write!(f, "client cert: {},", cert)?; + } + Ok(()) + } +} + +impl Peer for HttpPeer { + fn address(&self) -> &SocketAddr { + &self._address + } + + fn tls(&self) -> bool { + self.is_tls() + } + + fn sni(&self) -> &str { + &self.sni + } + + // TODO: change connection pool to accept u64 instead of String + fn reuse_hash(&self) -> u64 { + self.peer_hash() + } + + fn get_peer_options(&self) -> Option<&PeerOptions> { + Some(&self.options) + } + + fn get_mut_peer_options(&mut self) -> Option<&mut PeerOptions> { + Some(&mut self.options) + } + + fn get_proxy(&self) -> Option<&Proxy> { + self.proxy.as_ref() + } + + fn matches_fd(&self, fd: V) -> bool { + if let Some(proxy) = self.get_proxy() { + proxy.next_hop.check_fd_match(fd) + } else { + self.address().check_fd_match(fd) + } + } + + fn get_client_cert_key(&self) -> Option<&Arc> { + self.client_cert_key.as_ref() + } + + fn get_tracer(&self) -> Option { + self.options.tracer.clone() + } +} + +/// The proxy settings to connect to the remote server, CONNECT only for now +#[derive(Debug, Hash, Clone)] +pub struct Proxy { + pub next_hop: Box, // for now this will be the path to the UDS + pub host: String, // the proxied host. Could be either IP addr or hostname. + pub port: u16, // the port to proxy to + pub headers: BTreeMap>, // the additional headers to add to CONNECT +} + +impl Display for Proxy { + fn fmt(&self, f: &mut Formatter) -> FmtResult { + write!( + f, + "next_hop: {}, host: {}, port: {}", + self.next_hop.display(), + self.host, + self.port + ) + } +} diff --git a/pingora-core/src/utils/mod.rs b/pingora-core/src/utils/mod.rs new file mode 100644 index 0000000..c36f7c8 --- /dev/null +++ b/pingora-core/src/utils/mod.rs @@ -0,0 +1,232 @@ +// 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. + +//! This module contains various types that make it easier to work with bytes and X509 +//! certificates. + +// TODO: move below to its own mod +use crate::tls::{nid::Nid, pkey::PKey, pkey::Private, x509::X509}; +use crate::Result; +use bytes::Bytes; +use pingora_error::{ErrorType::*, OrErr}; +use std::hash::{Hash, Hasher}; + +/// A `BufRef` is a reference to a buffer of bytes. It removes the need for self-referential data +/// structures. It is safe to use as long as the underlying buffer does not get mutated. +/// +/// # Panics +/// +/// This will panic if an index is out of bounds. +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct BufRef(pub usize, pub usize); + +impl BufRef { + /// Return a sub-slice of `buf`. + pub fn get<'a>(&self, buf: &'a [u8]) -> &'a [u8] { + &buf[self.0..self.1] + } + + /// Return a slice of `buf`. This operation is O(1) and increases the reference count of `buf`. + pub fn get_bytes(&self, buf: &Bytes) -> Bytes { + buf.slice(self.0..self.1) + } + + /// Return the size of the slice reference. + pub fn len(&self) -> usize { + self.1 - self.0 + } + + /// Return true if the length is zero. + pub fn is_empty(&self) -> bool { + self.1 == self.0 + } +} + +impl BufRef { + /// Initialize a `BufRef` that can reference a slice beginning at index `start` and has a + /// length of `len`. + pub fn new(start: usize, len: usize) -> Self { + BufRef(start, start + len) + } +} + +/// A `KVRef` contains a key name and value pair, stored as two [BufRef] types. +#[derive(Clone)] +pub struct KVRef { + name: BufRef, + value: BufRef, +} + +impl KVRef { + /// Like [BufRef::get] for the name. + pub fn get_name<'a>(&self, buf: &'a [u8]) -> &'a [u8] { + self.name.get(buf) + } + + /// Like [BufRef::get] for the value. + pub fn get_value<'a>(&self, buf: &'a [u8]) -> &'a [u8] { + self.value.get(buf) + } + + /// Like [BufRef::get_bytes] for the name. + pub fn get_name_bytes(&self, buf: &Bytes) -> Bytes { + self.name.get_bytes(buf) + } + + /// Like [BufRef::get_bytes] for the value. + pub fn get_value_bytes(&self, buf: &Bytes) -> Bytes { + self.value.get_bytes(buf) + } + + /// Return a new `KVRef` with name and value start indices and lengths. + pub fn new(name_s: usize, name_len: usize, value_s: usize, value_len: usize) -> Self { + KVRef { + name: BufRef(name_s, name_s + name_len), + value: BufRef(value_s, value_s + value_len), + } + } + + /// Return a reference to the value. + pub fn value(&self) -> &BufRef { + &self.value + } +} + +/// A [KVRef] which contains empty sub-slices. +pub const EMPTY_KV_REF: KVRef = KVRef { + name: BufRef(0, 0), + value: BufRef(0, 0), +}; + +fn get_subject_name(cert: &X509, name_type: Nid) -> Option { + cert.subject_name() + .entries_by_nid(name_type) + .next() + .map(|name| { + name.data() + .as_utf8() + .map(|s| s.to_string()) + .unwrap_or_default() + }) +} + +/// Return the organization associated with the X509 certificate. +pub fn get_organization(cert: &X509) -> Option { + get_subject_name(cert, Nid::ORGANIZATIONNAME) +} + +/// Return the common name associated with the X509 certificate. +pub fn get_common_name(cert: &X509) -> Option { + get_subject_name(cert, Nid::COMMONNAME) +} + +/// Return the common name associated with the X509 certificate. +pub fn get_organization_unit(cert: &X509) -> Option { + get_subject_name(cert, Nid::ORGANIZATIONALUNITNAME) +} + +/// Return the serial number associated with the X509 certificate as a hexadecimal value. +pub fn get_serial(cert: &X509) -> Result { + let bn = cert + .serial_number() + .to_bn() + .or_err(InvalidCert, "Invalid serial")?; + let hex = bn.to_hex_str().or_err(InvalidCert, "Invalid serial")?; + + let hex_str: &str = hex.as_ref(); + Ok(hex_str.to_owned()) +} + +/// This type contains a list of one or more certificates and an associated private key. The leaf +/// certificate should always be first. +#[derive(Clone)] +pub struct CertKey { + certificates: Vec, + key: PKey, +} + +impl CertKey { + /// Create a new `CertKey` given a list of certificates and a private key. + pub fn new(certificates: Vec, key: PKey) -> CertKey { + assert!( + !certificates.is_empty(), + "expected a non-empty vector of certificates in CertKey::new" + ); + + CertKey { certificates, key } + } + + /// Peek at the leaf certificate. + pub fn leaf(&self) -> &X509 { + // This is safe due to the assertion above. + &self.certificates[0] + } + + /// Return the key. + pub fn key(&self) -> &PKey { + &self.key + } + + /// Return a slice of intermediate certificates. An empty slice means there are none. + pub fn intermediates(&self) -> &[X509] { + if self.certificates.len() <= 1 { + return &[]; + } + &self.certificates[1..] + } + + /// Return the organization from the leaf certificate. + pub fn organization(&self) -> Option { + get_organization(self.leaf()) + } + + /// Return the serial from the leaf certificate. + pub fn serial(&self) -> Result { + get_serial(self.leaf()) + } +} + +impl Hash for CertKey { + fn hash(&self, state: &mut H) { + for certificate in &self.certificates { + if let Ok(serial) = get_serial(certificate) { + serial.hash(state) + } + } + } +} + +// hide private key +impl std::fmt::Debug for CertKey { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("CertKey") + .field("X509", &self.leaf()) + .finish() + } +} + +impl std::fmt::Display for CertKey { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let leaf = self.leaf(); + if let Some(cn) = get_common_name(leaf) { + // Write CN if it exists + write!(f, "CN: {cn},")?; + } else if let Some(org_unit) = get_organization_unit(leaf) { + // CA cert might not have CN, so print its unit name instead + write!(f, "Org Unit: {org_unit},")?; + } + write!(f, ", expire: {}", leaf.not_after()) + // ignore the details of the private key + } +} 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> { + // 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 { + Arc::new(EchoApp {}) +} + +pub struct MyServer { + pub handle: thread::JoinHandle<()>, +} + +fn entry_point(opt: Option) { + 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 = 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 = Lazy::new(MyServer::start); + +pub fn init() { + let _ = *TEST_SERVER; +} diff --git a/pingora-error/Cargo.toml b/pingora-error/Cargo.toml new file mode 100644 index 0000000..cdbc619 --- /dev/null +++ b/pingora-error/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "pingora-error" +version = "0.1.0" +authors = ["Yuchen Wu "] +license = "Apache-2.0" +edition = "2021" +repository = "https://github.com/cloudflare/pingora" +categories = ["rust-patterns"] +keywords = ["error", "error-handling", "pingora"] +description = """ +Error types and error handling APIs for Pingora. +""" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +name = "pingora_error" +path = "src/lib.rs" diff --git a/pingora-error/LICENSE b/pingora-error/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/pingora-error/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/pingora-error/src/immut_str.rs b/pingora-error/src/immut_str.rs new file mode 100644 index 0000000..e131b63 --- /dev/null +++ b/pingora-error/src/immut_str.rs @@ -0,0 +1,71 @@ +// 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 std::fmt; + +/// A data struct that holds either immutable string or reference to static str. +/// Compared to String or `Box`, it avoids memory allocation on static str. +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum ImmutStr { + Static(&'static str), + Owned(Box), +} + +impl ImmutStr { + #[inline] + pub fn as_str(&self) -> &str { + match self { + ImmutStr::Static(s) => s, + ImmutStr::Owned(s) => s.as_ref(), + } + } + + pub fn is_owned(&self) -> bool { + match self { + ImmutStr::Static(_) => false, + ImmutStr::Owned(_) => true, + } + } +} + +impl fmt::Display for ImmutStr { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.as_str()) + } +} + +impl From<&'static str> for ImmutStr { + fn from(s: &'static str) -> Self { + ImmutStr::Static(s) + } +} + +impl From for ImmutStr { + fn from(s: String) -> Self { + ImmutStr::Owned(s.into_boxed_str()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_static_vs_owned() { + let s: ImmutStr = "test".into(); + assert!(!s.is_owned()); + let s: ImmutStr = "test".to_string().into(); + assert!(s.is_owned()); + } +} diff --git a/pingora-error/src/lib.rs b/pingora-error/src/lib.rs new file mode 100644 index 0000000..6bd6702 --- /dev/null +++ b/pingora-error/src/lib.rs @@ -0,0 +1,589 @@ +// 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. + +#![warn(clippy::all)] +//! The library to provide the struct to represent errors in pingora. + +pub use std::error::Error as ErrorTrait; +use std::fmt; +use std::fmt::Debug; +use std::result::Result as StdResult; + +mod immut_str; +pub use immut_str::ImmutStr; + +/// The boxed [Error], the desired way to pass [Error] +pub type BError = Box; +/// Syntax sugar for `std::Result` +pub type Result = StdResult; + +/// The struct that represents an error +#[derive(Debug)] +pub struct Error { + /// the type of error + pub etype: ErrorType, + /// the source of error: from upstream, downstream or internal + pub esource: ErrorSource, + /// if the error is retry-able + pub retry: RetryType, + /// chain to the cause of this error + pub cause: Option>, + /// an arbitrary string that explains the context when the error happens + pub context: Option, +} + +/// The source of the error +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum ErrorSource { + /// The error is caused by the remote server + Upstream, + /// The error is caused by the remote client + Downstream, + /// The error is caused by the internal logic + Internal, + /// Error source unknown or to be set + Unset, +} + +/// Whether the request can be retried after encountering this error +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +pub enum RetryType { + Decided(bool), + ReusedOnly, // only retry when the error is from a reused connection +} + +impl RetryType { + pub fn decide_reuse(&mut self, reused: bool) { + if matches!(self, RetryType::ReusedOnly) { + *self = RetryType::Decided(reused); + } + } + + pub fn retry(&self) -> bool { + match self { + RetryType::Decided(b) => *b, + RetryType::ReusedOnly => { + panic!("Retry is not decided") + } + } + } +} + +impl From for RetryType { + fn from(b: bool) -> Self { + RetryType::Decided(b) + } +} + +impl ErrorSource { + /// for displaying the error source + pub fn as_str(&self) -> &str { + match self { + Self::Upstream => "Upstream", + Self::Downstream => "Downstream", + Self::Internal => "Internal", + Self::Unset => "", + } + } +} + +/// Predefined type of errors +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum ErrorType { + // connect errors + ConnectTimedout, + ConnectRefused, + ConnectNoRoute, + TLSHandshakeFailure, + TLSHandshakeTimedout, + InvalidCert, + HandshakeError, // other handhshake + ConnectError, // catch all + BindError, + AcceptError, + SocketError, + ConnectProxyFailure, + // protocol errors + InvalidHTTPHeader, + H1Error, // catch all + H2Error, // catch all + H2Downgrade, // Peer over h2 requests to downgrade to h1 + InvalidH2, // Peer sends invalid h2 frames to us + // IO error on established connections + ReadError, + WriteError, + ReadTimedout, + WriteTimedout, + ConnectionClosed, + // application error, will return HTTP status code + HTTPStatus(u16), + // file related + FileOpenError, + FileCreateError, + FileReadError, + FileWriteError, + // other errors + InternalError, + // catch all + UnknownError, + /// Custom error with static string. + /// this field is to allow users to extend the types of errors. If runtime generated string + /// is needed, it is more likely to be treated as "context" rather than "type". + Custom(&'static str), + /// Custom error with static string and code. + /// this field allows users to extend error further with error codes. + CustomCode(&'static str, u16), +} + +impl ErrorType { + /// create a new type of error. Users should try to make `name` unique. + pub const fn new(name: &'static str) -> Self { + ErrorType::Custom(name) + } + + /// create a new type of error. Users should try to make `name` unique. + pub const fn new_code(name: &'static str, code: u16) -> Self { + ErrorType::CustomCode(name, code) + } + + /// for displaying the error type + pub fn as_str(&self) -> &str { + match self { + ErrorType::ConnectTimedout => "ConnectTimedout", + ErrorType::ConnectRefused => "ConnectRefused", + ErrorType::ConnectNoRoute => "ConnectNoRoute", + ErrorType::ConnectProxyFailure => "ConnectProxyFailure", + ErrorType::TLSHandshakeFailure => "TLSHandshakeFailure", + ErrorType::TLSHandshakeTimedout => "TLSHandshakeTimedout", + ErrorType::InvalidCert => "InvalidCert", + ErrorType::HandshakeError => "HandshakeError", + ErrorType::ConnectError => "ConnectError", + ErrorType::BindError => "BindError", + ErrorType::AcceptError => "AcceptError", + ErrorType::SocketError => "SocketError", + ErrorType::InvalidHTTPHeader => "InvalidHTTPHeader", + ErrorType::H1Error => "H1Error", + ErrorType::H2Error => "H2Error", + ErrorType::InvalidH2 => "InvalidH2", + ErrorType::H2Downgrade => "H2Downgrade", + ErrorType::ReadError => "ReadError", + ErrorType::WriteError => "WriteError", + ErrorType::ReadTimedout => "ReadTimedout", + ErrorType::WriteTimedout => "WriteTimedout", + ErrorType::ConnectionClosed => "ConnectionClosed", + ErrorType::FileOpenError => "FileOpenError", + ErrorType::FileCreateError => "FileCreateError", + ErrorType::FileReadError => "FileReadError", + ErrorType::FileWriteError => "FileWriteError", + ErrorType::HTTPStatus(_) => "HTTPStatus", + ErrorType::InternalError => "InternalError", + ErrorType::UnknownError => "UnknownError", + ErrorType::Custom(s) => s, + ErrorType::CustomCode(s, _) => s, + } + } +} + +impl Error { + /// Simply create the error. See other functions that provide less verbose interfaces. + #[inline] + pub fn create( + etype: ErrorType, + esource: ErrorSource, + context: Option, + cause: Option>, + ) -> BError { + let retry = if let Some(c) = cause.as_ref() { + if let Some(e) = c.downcast_ref::() { + e.retry + } else { + false.into() + } + } else { + false.into() + }; + Box::new(Error { + etype, + esource, + retry, + cause, + context, + }) + } + + #[inline] + fn do_new(e: ErrorType, s: ErrorSource) -> BError { + Self::create(e, s, None, None) + } + + /// Create an error with the given type + #[inline] + pub fn new(e: ErrorType) -> BError { + Self::do_new(e, ErrorSource::Unset) + } + + /// Create an error with the given type, a context string and the causing error. + /// This method is usually used when there the error is caused by another error. + /// ``` + /// use pingora_error::{Error, ErrorType, Result}; + /// + /// fn b() -> Result<()> { + /// // ... + /// Ok(()) + /// } + /// fn do_something() -> Result<()> { + /// // a()?; + /// b().map_err(|e| Error::because(ErrorType::InternalError, "b failed after a", e)) + /// } + /// ``` + /// Choose carefully between simply surfacing the causing error versus Because() here. + /// Only use Because() when there is extra context that is not capture by + /// the causing error itself. + #[inline] + pub fn because, E: Into>>( + e: ErrorType, + context: S, + cause: E, + ) -> BError { + Self::create( + e, + ErrorSource::Unset, + Some(context.into()), + Some(cause.into()), + ) + } + + /// Short for Err(Self::because) + #[inline] + pub fn e_because, E: Into>>( + e: ErrorType, + context: S, + cause: E, + ) -> Result { + Err(Self::because(e, context, cause)) + } + + /// Create an error with context but no direct causing error + #[inline] + pub fn explain>(e: ErrorType, context: S) -> BError { + Self::create(e, ErrorSource::Unset, Some(context.into()), None) + } + + /// Short for Err(Self::explain) + #[inline] + pub fn e_explain>(e: ErrorType, context: S) -> Result { + Err(Self::explain(e, context)) + } + + /// The new_{up, down, in} functions are to create new errors with source + /// {upstream, downstream, internal} + #[inline] + pub fn new_up(e: ErrorType) -> BError { + Self::do_new(e, ErrorSource::Upstream) + } + + #[inline] + pub fn new_down(e: ErrorType) -> BError { + Self::do_new(e, ErrorSource::Downstream) + } + + #[inline] + pub fn new_in(e: ErrorType) -> BError { + Self::do_new(e, ErrorSource::Internal) + } + + /// Create a new custom error with the static string + #[inline] + pub fn new_str(s: &'static str) -> BError { + Self::do_new(ErrorType::Custom(s), ErrorSource::Unset) + } + + // the err_* functions are the same as new_* but return a Result + #[inline] + pub fn err(e: ErrorType) -> Result { + Err(Self::new(e)) + } + + #[inline] + pub fn err_up(e: ErrorType) -> Result { + Err(Self::new_up(e)) + } + + #[inline] + pub fn err_down(e: ErrorType) -> Result { + Err(Self::new_down(e)) + } + + #[inline] + pub fn err_in(e: ErrorType) -> Result { + Err(Self::new_in(e)) + } + + pub fn etype(&self) -> &ErrorType { + &self.etype + } + + pub fn esource(&self) -> &ErrorSource { + &self.esource + } + + pub fn retry(&self) -> bool { + self.retry.retry() + } + + pub fn set_retry(&mut self, retry: bool) { + self.retry = retry.into(); + } + + pub fn reason_str(&self) -> &str { + self.etype.as_str() + } + + pub fn source_str(&self) -> &str { + self.esource.as_str() + } + + /// The as_{up, down, in} functions are to change the current errors with source + /// {upstream, downstream, internal} + pub fn as_up(&mut self) { + self.esource = ErrorSource::Upstream; + } + + pub fn as_down(&mut self) { + self.esource = ErrorSource::Downstream; + } + + pub fn as_in(&mut self) { + self.esource = ErrorSource::Internal; + } + + /// The into_{up, down, in} are the same as as_* but takes `self` and also return `self` + pub fn into_up(mut self: BError) -> BError { + self.as_up(); + self + } + + pub fn into_down(mut self: BError) -> BError { + self.as_down(); + self + } + + pub fn into_in(mut self: BError) -> BError { + self.as_in(); + self + } + + pub fn into_err(self: BError) -> Result { + Err(self) + } + + pub fn set_cause>>(&mut self, cause: C) { + self.cause = Some(cause.into()); + } + + pub fn set_context>(&mut self, context: T) { + self.context = Some(context.into()); + } + + /// Create a new error from self, with the same type and source and put self as the cause + /// ``` + /// use pingora_error::Result; + /// + /// fn b() -> Result<()> { + /// // ... + /// Ok(()) + /// } + /// + /// fn do_something() -> Result<()> { + /// // a()?; + /// b().map_err(|e| e.more_context("b failed after a")) + /// } + /// ``` + /// This function is less verbose than `Because`. But it only work for [Error] while + /// `Because` works for all types of errors who implement [std::error::Error] trait. + pub fn more_context>(self: BError, context: T) -> BError { + let esource = self.esource.clone(); + let retry = self.retry; + let mut e = Self::because(self.etype.clone(), context, self); + e.esource = esource; + e.retry = retry; + e + } + + // Display error but skip the duplicate elements from the error in previous hop + fn chain_display(&self, previous: Option<&Error>, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if previous.map(|p| p.esource != self.esource).unwrap_or(true) { + write!(f, "{}", self.esource.as_str())? + } + if previous.map(|p| p.etype != self.etype).unwrap_or(true) { + write!(f, " {}", self.etype.as_str())? + } + + if let Some(c) = self.context.as_ref() { + write!(f, " context: {}", c)?; + } + if let Some(c) = self.cause.as_ref() { + if let Some(e) = c.downcast_ref::() { + write!(f, " cause: ")?; + e.chain_display(Some(self), f) + } else { + write!(f, " cause: {}", c) + } + } else { + Ok(()) + } + } + + /// Return the ErrorType of the root Error + pub fn root_etype(&self) -> &ErrorType { + self.cause.as_ref().map_or(&self.etype, |c| { + // Stop the recursion if the cause is not Error + c.downcast_ref::() + .map_or(&self.etype, |e| e.root_etype()) + }) + } + + pub fn root_cause(&self) -> &(dyn ErrorTrait + Send + Sync + 'static) { + self.cause.as_deref().map_or(self, |c| { + c.downcast_ref::().map_or(c, |e| e.root_cause()) + }) + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.chain_display(None, f) + } +} + +impl ErrorTrait for Error {} + +/// Helper trait to add more context to a given error +pub trait Context { + /// Wrap the `Err(E)` in [Result] with more context, the existing E will be the cause. + /// + /// This is a shortcut for map_err() + more_context() + fn err_context, F: FnOnce() -> C>(self, context: F) -> Result; +} + +impl Context for Result { + fn err_context, F: FnOnce() -> C>(self, context: F) -> Result { + self.map_err(|e| e.more_context(context())) + } +} + +/// Helper trait to chain errors with context +pub trait OrErr { + /// Wrap the E in [Result] with new [ErrorType] and context, the existing E will be the cause. + /// + /// This is a shortcut for map_err() + because() + fn or_err(self, et: ErrorType, context: &'static str) -> Result + where + E: Into>; + + /// Similar to or_err(), but takes a closure, which is useful for constructing String. + fn or_err_with, F: FnOnce() -> C>( + self, + et: ErrorType, + context: F, + ) -> Result + where + E: Into>; + + /// Replace the E in [Result] with a new [Error] generated from the current error + /// + /// This is useful when the current error cannot move out of scope. This is a shortcut for map_err() + explain(). + fn explain_err, F: FnOnce(E) -> C>( + self, + et: ErrorType, + context: F, + ) -> Result; +} + +impl OrErr for Result { + fn or_err(self, et: ErrorType, context: &'static str) -> Result + where + E: Into>, + { + self.map_err(|e| Error::because(et, context, e)) + } + + fn or_err_with, F: FnOnce() -> C>( + self, + et: ErrorType, + context: F, + ) -> Result + where + E: Into>, + { + self.map_err(|e| Error::because(et, context(), e)) + } + + fn explain_err, F: FnOnce(E) -> C>( + self, + et: ErrorType, + exp: F, + ) -> Result { + self.map_err(|e| Error::explain(et, exp(e))) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_chain_of_error() { + let e1 = Error::new(ErrorType::InternalError); + let mut e2 = Error::new(ErrorType::HTTPStatus(400)); + e2.set_cause(e1); + assert_eq!(format!("{}", e2), " HTTPStatus cause: InternalError"); + assert_eq!(e2.root_etype().as_str(), "InternalError"); + + let e3 = Error::new(ErrorType::InternalError); + let e4 = Error::because(ErrorType::HTTPStatus(400), "test", e3); + assert_eq!( + format!("{}", e4), + " HTTPStatus context: test cause: InternalError" + ); + assert_eq!(e4.root_etype().as_str(), "InternalError"); + } + + #[test] + fn test_error_context() { + let mut e1 = Error::new(ErrorType::InternalError); + e1.set_context(format!("{} {}", "my", "context")); + assert_eq!(format!("{}", e1), " InternalError context: my context"); + } + + #[test] + fn test_context_trait() { + let e1: Result<(), BError> = Err(Error::new(ErrorType::InternalError)); + let e2 = e1.err_context(|| "another"); + assert_eq!( + format!("{}", e2.unwrap_err()), + " InternalError context: another cause: " + ); + } + + #[test] + fn test_cause_trait() { + let e1: Result<(), BError> = Err(Error::new(ErrorType::InternalError)); + let e2 = e1.or_err(ErrorType::HTTPStatus(400), "another"); + assert_eq!( + format!("{}", e2.unwrap_err()), + " HTTPStatus context: another cause: InternalError" + ); + } +} diff --git a/pingora-header-serde/Cargo.toml b/pingora-header-serde/Cargo.toml new file mode 100644 index 0000000..2968cae --- /dev/null +++ b/pingora-header-serde/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "pingora-header-serde" +version = "0.1.0" +authors = ["Yuchen Wu "] +license = "Apache-2.0" +edition = "2021" +repository = "https://github.com/cloudflare/pingora" +categories = ["compression"] +keywords = ["http", "compression", "pingora"] +exclude = ["samples/*"] +description = """ +HTTP header (de)serialization and compression for Pingora. +""" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +name = "pingora_header_serde" +path = "src/lib.rs" + +[[bin]] +name = "trainer" +path = "src/trainer.rs" + +[dependencies] +zstd = "0.9.0" +zstd-safe = "4.1.1" +http = { workspace = true } +bytes = { workspace = true } +httparse = { workspace = true } +pingora-error = { version = "0.1.0", path = "../pingora-error" } +pingora-http = { version = "0.1.0", path = "../pingora-http" } +thread_local = "1.0" diff --git a/pingora-header-serde/LICENSE b/pingora-header-serde/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/pingora-header-serde/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/pingora-header-serde/samples/test/1 b/pingora-header-serde/samples/test/1 new file mode 100644 index 0000000..9d4c680 --- /dev/null +++ b/pingora-header-serde/samples/test/1 @@ -0,0 +1,15 @@ +HTTP/1.1 200 OK +Server: nginx +Date: Wed, 22 Dec 2021 06:30:29 GMT +Content-Type: application/javascript +Last-Modified: Mon, 29 Nov 2021 10:13:32 GMT +Transfer-Encoding: chunked +Connection: keep-alive +Vary: Accept-Encoding +ETag: W/"61a4a7cc-21df8" +Access-Control-Allow-Origin: * +Access-Control-Allow-Credentials: true +Access-Control-Expose-Headers: Content-Length,Content-Range +Access-Control-Allow-Headers: Range +Content-Encoding: gzip + diff --git a/pingora-header-serde/samples/test/2 b/pingora-header-serde/samples/test/2 new file mode 100644 index 0000000..5cd4026 --- /dev/null +++ b/pingora-header-serde/samples/test/2 @@ -0,0 +1,15 @@ +HTTP/1.1 200 OK +Server: nginx +Date: Thu, 23 Dec 2021 15:12:32 GMT +Content-Type: application/javascript +Last-Modified: Mon, 09 Sep 2019 12:47:14 GMT +Transfer-Encoding: chunked +Connection: keep-alive +Vary: Accept-Encoding +ETag: W/"5d7649d2-16ec64" +Access-Control-Allow-Origin: * +Access-Control-Allow-Credentials: true +Access-Control-Expose-Headers: Content-Length,Content-Range +Access-Control-Allow-Headers: Range +Content-Encoding: gzip + diff --git a/pingora-header-serde/samples/test/3 b/pingora-header-serde/samples/test/3 new file mode 100644 index 0000000..b02aadd --- /dev/null +++ b/pingora-header-serde/samples/test/3 @@ -0,0 +1,15 @@ +HTTP/1.1 200 OK +Server: nginx +Date: Wed, 22 Dec 2021 12:29:00 GMT +Content-Type: application/javascript +Last-Modified: Mon, 09 Sep 2019 07:47:37 GMT +Transfer-Encoding: chunked +Connection: keep-alive +Vary: Accept-Encoding +ETag: W/"5d760399-52868" +Access-Control-Allow-Origin: * +Access-Control-Allow-Credentials: true +Access-Control-Expose-Headers: Content-Length,Content-Range +Access-Control-Allow-Headers: Range +Content-Encoding: gzip + diff --git a/pingora-header-serde/samples/test/4 b/pingora-header-serde/samples/test/4 new file mode 100644 index 0000000..8215d6e --- /dev/null +++ b/pingora-header-serde/samples/test/4 @@ -0,0 +1,15 @@ +HTTP/1.1 200 OK +Server: nginx +Date: Wed, 22 Dec 2021 06:11:09 GMT +Content-Type: application/javascript +Last-Modified: Mon, 20 Dec 2021 01:23:10 GMT +Transfer-Encoding: chunked +Connection: keep-alive +Vary: Accept-Encoding +ETag: W/"61bfdafe-21bc4" +Access-Control-Allow-Origin: * +Access-Control-Allow-Credentials: true +Access-Control-Expose-Headers: Content-Length,Content-Range +Access-Control-Allow-Headers: Range +Content-Encoding: gzip + diff --git a/pingora-header-serde/samples/test/5 b/pingora-header-serde/samples/test/5 new file mode 100644 index 0000000..4bae598 --- /dev/null +++ b/pingora-header-serde/samples/test/5 @@ -0,0 +1,15 @@ +HTTP/1.1 200 OK +Server: nginx +Date: Thu, 23 Dec 2021 15:23:29 GMT +Content-Type: application/javascript +Last-Modified: Sat, 09 Oct 2021 23:41:34 GMT +Transfer-Encoding: chunked +Connection: keep-alive +Vary: Accept-Encoding +ETag: W/"616228ae-52054" +Access-Control-Allow-Origin: * +Access-Control-Allow-Credentials: true +Access-Control-Expose-Headers: Content-Length,Content-Range +Access-Control-Allow-Headers: Range +Content-Encoding: gzip + diff --git a/pingora-header-serde/samples/test/6 b/pingora-header-serde/samples/test/6 new file mode 100644 index 0000000..9d4c680 --- /dev/null +++ b/pingora-header-serde/samples/test/6 @@ -0,0 +1,15 @@ +HTTP/1.1 200 OK +Server: nginx +Date: Wed, 22 Dec 2021 06:30:29 GMT +Content-Type: application/javascript +Last-Modified: Mon, 29 Nov 2021 10:13:32 GMT +Transfer-Encoding: chunked +Connection: keep-alive +Vary: Accept-Encoding +ETag: W/"61a4a7cc-21df8" +Access-Control-Allow-Origin: * +Access-Control-Allow-Credentials: true +Access-Control-Expose-Headers: Content-Length,Content-Range +Access-Control-Allow-Headers: Range +Content-Encoding: gzip + diff --git a/pingora-header-serde/samples/test/7 b/pingora-header-serde/samples/test/7 new file mode 100644 index 0000000..b57e5c0 --- /dev/null +++ b/pingora-header-serde/samples/test/7 @@ -0,0 +1,14 @@ +HTTP/1.1 200 OK +server: nginx +date: Sat, 25 Dec 2021 03:05:35 GMT +content-type: application/javascript +last-modified: Fri, 24 Dec 2021 04:20:01 GMT +transfer-encoding: chunked +connection: keep-alive +vary: Accept-Encoding +etag: W/"61c54a71-2d590" +access-control-allow-origin: * +access-control-allow-credentials: true +access-control-expose-headers: Content-Length,Content-Range +access-control-allow-headers: Range +content-encoding: gzip diff --git a/pingora-header-serde/src/dict.rs b/pingora-header-serde/src/dict.rs new file mode 100644 index 0000000..bc50ada --- /dev/null +++ b/pingora-header-serde/src/dict.rs @@ -0,0 +1,88 @@ +// 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. + +//! Training to generate the zstd dictionary. + +use std::fs; +use zstd::dict; + +/// Train the zstd dictionary from all the files under the given `dir_path` +/// +/// The output will be the trained dictionary +pub fn train>(dir_path: P) -> Vec { + // TODO: check f is file, it can be dir + let files = fs::read_dir(dir_path) + .unwrap() + .filter_map(|entry| entry.ok().map(|f| f.path())); + dict::from_files(files, 64 * 1024 * 1024).unwrap() +} + +#[cfg(test)] +mod test { + use super::*; + use crate::resp_header_to_buf; + use pingora_http::ResponseHeader; + + fn gen_test_dict() -> Vec { + let mut path = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")); + path.push("samples/test"); + train(path) + } + + fn gen_test_header() -> ResponseHeader { + let mut header = ResponseHeader::build(200, None).unwrap(); + header + .append_header("Date", "Thu, 23 Dec 2021 11:23:29 GMT") + .unwrap(); + header + .append_header("Last-Modified", "Sat, 09 Oct 2021 22:41:34 GMT") + .unwrap(); + header.append_header("Connection", "keep-alive").unwrap(); + header.append_header("Vary", "Accept-encoding").unwrap(); + header.append_header("Content-Encoding", "gzip").unwrap(); + header + .append_header("Access-Control-Allow-Origin", "*") + .unwrap(); + header + } + + #[test] + fn test_ser_with_dict() { + let dict = gen_test_dict(); + let serde = crate::HeaderSerde::new(Some(dict)); + let serde_no_dict = crate::HeaderSerde::new(None); + let header = gen_test_header(); + + let compressed = serde.serialize(&header).unwrap(); + let compressed_no_dict = serde_no_dict.serialize(&header).unwrap(); + let mut buf = vec![]; + let uncompressed = resp_header_to_buf(&header, &mut buf); + + assert!(compressed.len() < uncompressed); + assert!(compressed.len() < compressed_no_dict.len()); + } + + #[test] + fn test_ser_de_with_dict() { + let dict = gen_test_dict(); + let serde = crate::HeaderSerde::new(Some(dict)); + let header = gen_test_header(); + + let compressed = serde.serialize(&header).unwrap(); + let header2 = serde.deserialize(&compressed).unwrap(); + + assert_eq!(header.status, header2.status); + assert_eq!(header.headers, header2.headers); + } +} diff --git a/pingora-header-serde/src/lib.rs b/pingora-header-serde/src/lib.rs new file mode 100644 index 0000000..73b9b29 --- /dev/null +++ b/pingora-header-serde/src/lib.rs @@ -0,0 +1,203 @@ +// 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. + +//! HTTP Response header serialization with compression +//! +//! This crate is able to serialize http response header to about 1/3 of its original size (HTTP/1.1 wire format) +//! with trained dictionary. + +#![warn(clippy::all)] +#![allow(clippy::new_without_default)] +#![allow(clippy::type_complexity)] + +pub mod dict; +mod thread_zstd; + +use bytes::BufMut; +use http::Version; +use pingora_error::{Error, ErrorType, Result}; +use pingora_http::ResponseHeader; +use std::cell::RefCell; +use std::ops::DerefMut; +use thread_local::ThreadLocal; + +/// HTTP Response header serialization +/// +/// This struct provides the APIs to convert HTTP response header into compressed wired format for +/// storage. +pub struct HeaderSerde { + compression: thread_zstd::Compression, + level: i32, + // internal buffer for uncompressed data to be compressed and vice versa + buf: ThreadLocal>>, +} + +const MAX_HEADER_SIZE: usize = 64 * 1024; +const COMPRESS_LEVEL: i32 = 3; + +impl HeaderSerde { + /// Create a new [HeaderSerde] + /// + /// An optional zstd compression dictionary can be provided to improve the compression ratio + /// and speed. See [dict] for more details. + pub fn new(dict: Option>) -> Self { + if let Some(dict) = dict { + HeaderSerde { + compression: thread_zstd::Compression::with_dict(dict), + level: COMPRESS_LEVEL, + buf: ThreadLocal::new(), + } + } else { + HeaderSerde { + compression: thread_zstd::Compression::new(), + level: COMPRESS_LEVEL, + buf: ThreadLocal::new(), + } + } + } + + /// Serialize the given response header + pub fn serialize(&self, header: &ResponseHeader) -> Result> { + // for now we use HTTP 1.1 wire format for that + // TODO: should convert to h1 if the incoming header is for h2 + let mut buf = self + .buf + .get_or(|| RefCell::new(Vec::with_capacity(MAX_HEADER_SIZE))) + .borrow_mut(); + buf.clear(); // reset the buf + resp_header_to_buf(header, &mut buf); + self.compression + .compress(&buf, self.level) + .map_err(|e| into_error(e, "compress header")) + } + + /// Deserialize the given response header + pub fn deserialize(&self, data: &[u8]) -> Result { + let mut buf = self + .buf + .get_or(|| RefCell::new(Vec::with_capacity(MAX_HEADER_SIZE))) + .borrow_mut(); + buf.clear(); // reset the buf + self.compression + .decompress_to_buffer(data, buf.deref_mut()) + .map_err(|e| into_error(e, "decompress header"))?; + buf_to_http_header(&buf) + } +} + +#[inline] +fn into_error(e: &'static str, context: &'static str) -> Box { + Error::because(ErrorType::InternalError, context, e) +} + +const CRLF: &[u8; 2] = b"\r\n"; + +// Borrowed from pingora http1 +#[inline] +fn resp_header_to_buf(resp: &ResponseHeader, buf: &mut Vec) -> usize { + // Status-Line + let version = match resp.version { + Version::HTTP_10 => "HTTP/1.0 ", + Version::HTTP_11 => "HTTP/1.1 ", + _ => "HTTP/1.1 ", // store everything else (including h2) in http 1.1 format + }; + buf.put_slice(version.as_bytes()); + let status = resp.status; + buf.put_slice(status.as_str().as_bytes()); + buf.put_u8(b' '); + let reason = status.canonical_reason(); + if let Some(reason_buf) = reason { + buf.put_slice(reason_buf.as_bytes()); + } + buf.put_slice(CRLF); + + // headers + resp.header_to_h1_wire(buf); + + buf.put_slice(CRLF); + + buf.len() +} + +// Should match pingora http1 setting +const MAX_HEADERS: usize = 160; + +#[inline] +fn buf_to_http_header(buf: &[u8]) -> Result { + let mut headers = vec![httparse::EMPTY_HEADER; MAX_HEADERS]; + let mut resp = httparse::Response::new(&mut headers); + + match resp.parse(buf) { + Ok(s) => match s { + httparse::Status::Complete(_size) => parsed_to_header(&resp), + // we always feed the but that contains the entire header to parse + _ => Error::e_explain(ErrorType::InternalError, "incomplete uncompressed header"), + }, + Err(e) => Error::e_because( + ErrorType::InternalError, + format!( + "parsing failed on uncompressed header, {}", + String::from_utf8_lossy(buf) + ), + e, + ), + } +} + +#[inline] +fn parsed_to_header(parsed: &httparse::Response) -> Result { + // code should always be there + let mut resp = ResponseHeader::build(parsed.code.unwrap(), Some(parsed.headers.len()))?; + + for header in parsed.headers.iter() { + resp.append_header(header.name.to_string(), header.value)?; + } + + Ok(resp) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_ser_wo_dict() { + let serde = HeaderSerde::new(None); + let mut header = ResponseHeader::build(200, None).unwrap(); + header.append_header("foo", "bar").unwrap(); + header.append_header("foo", "barbar").unwrap(); + header.append_header("foo", "barbarbar").unwrap(); + header.append_header("Server", "Pingora").unwrap(); + + let compressed = serde.serialize(&header).unwrap(); + let mut buf = vec![]; + let uncompressed = resp_header_to_buf(&header, &mut buf); + assert!(compressed.len() < uncompressed); + } + + #[test] + fn test_ser_de_no_dict() { + let serde = HeaderSerde::new(None); + let mut header = ResponseHeader::build(200, None).unwrap(); + header.append_header("foo1", "bar1").unwrap(); + header.append_header("foo2", "barbar2").unwrap(); + header.append_header("foo3", "barbarbar3").unwrap(); + header.append_header("Server", "Pingora").unwrap(); + + let compressed = serde.serialize(&header).unwrap(); + let header2 = serde.deserialize(&compressed).unwrap(); + assert_eq!(header.status, header2.status); + assert_eq!(header.headers, header2.headers); + } +} diff --git a/pingora-header-serde/src/thread_zstd.rs b/pingora-header-serde/src/thread_zstd.rs new file mode 100644 index 0000000..5c6406e --- /dev/null +++ b/pingora-header-serde/src/thread_zstd.rs @@ -0,0 +1,79 @@ +// 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 std::cell::RefCell; +use thread_local::ThreadLocal; + +/// Each thread will own its compression and decompression CTXes, and they share a single dict +/// https://facebook.github.io/zstd/zstd_manual.html recommends to reuse ctx per thread + +#[derive(Default)] +pub struct Compression { + com_context: ThreadLocal>>, + de_context: ThreadLocal>>, + dict: Vec, +} + +// these codes are inspired by zstd crate + +impl Compression { + pub fn new() -> Self { + Compression { + com_context: ThreadLocal::new(), + de_context: ThreadLocal::new(), + dict: vec![], + } + } + pub fn with_dict(dict: Vec) -> Self { + Compression { + com_context: ThreadLocal::new(), + de_context: ThreadLocal::new(), + dict, + } + } + + pub fn compress_to_buffer( + &self, + source: &[u8], + destination: &mut C, + level: i32, + ) -> Result { + self.com_context + .get_or(|| RefCell::new(zstd_safe::create_cctx())) + .borrow_mut() + .compress_using_dict(destination, source, &self.dict[..], level) + .map_err(zstd_safe::get_error_name) + } + + pub fn compress(&self, data: &[u8], level: i32) -> Result, &'static str> { + let buffer_len = zstd_safe::compress_bound(data.len()); + let mut buffer = Vec::with_capacity(buffer_len); + + self.compress_to_buffer(data, &mut buffer, level)?; + + Ok(buffer) + } + + pub fn decompress_to_buffer( + &self, + source: &[u8], + destination: &mut C, + ) -> Result { + self.de_context + .get_or(|| RefCell::new(zstd_safe::create_dctx())) + .borrow_mut() + .decompress_using_dict(destination, source, &self.dict) + .map_err(zstd_safe::get_error_name) + } +} diff --git a/pingora-header-serde/src/trainer.rs b/pingora-header-serde/src/trainer.rs new file mode 100644 index 0000000..36308e5 --- /dev/null +++ b/pingora-header-serde/src/trainer.rs @@ -0,0 +1,23 @@ +// 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 pingora_header_serde::dict::train; +use std::env; +use std::io::{self, Write}; + +pub fn main() { + let args: Vec = env::args().collect(); + let dict = train(&args[1]); + io::stdout().write_all(&dict).unwrap(); +} diff --git a/pingora-http/Cargo.toml b/pingora-http/Cargo.toml new file mode 100644 index 0000000..6cf7f97 --- /dev/null +++ b/pingora-http/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "pingora-http" +version = "0.1.0" +authors = ["Yuchen Wu "] +license = "Apache-2.0" +edition = "2021" +repository = "https://github.com/cloudflare/pingora" +categories = ["web-programming"] +keywords = ["http", "pingora"] +description = """ +HTTP request and response header types for Pingora. +""" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +name = "pingora_http" +path = "src/lib.rs" + +[dependencies] +http = { workspace = true } +bytes = { workspace = true } +pingora-error = { version = "0.1.0", path = "../pingora-error" } + +[features] +default = [] +patched_http1 = [] diff --git a/pingora-http/LICENSE b/pingora-http/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/pingora-http/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/pingora-http/src/case_header_name.rs b/pingora-http/src/case_header_name.rs new file mode 100644 index 0000000..4b6c133 --- /dev/null +++ b/pingora-http/src/case_header_name.rs @@ -0,0 +1,116 @@ +// 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 crate::*; +use bytes::Bytes; +use http::header; + +#[derive(Debug, Clone)] +pub struct CaseHeaderName(Bytes); + +impl CaseHeaderName { + pub fn new(name: String) -> Self { + CaseHeaderName(name.into()) + } +} + +impl CaseHeaderName { + pub fn as_slice(&self) -> &[u8] { + &self.0 + } + + pub fn from_slice(buf: &[u8]) -> Self { + CaseHeaderName(Bytes::copy_from_slice(buf)) + } +} + +/// A trait that converts into case sensitive header names. +pub trait IntoCaseHeaderName { + fn into_case_header_name(self) -> CaseHeaderName; +} + +impl IntoCaseHeaderName for CaseHeaderName { + fn into_case_header_name(self) -> CaseHeaderName { + self + } +} + +impl IntoCaseHeaderName for String { + fn into_case_header_name(self) -> CaseHeaderName { + CaseHeaderName(self.into()) + } +} + +impl IntoCaseHeaderName for &'static str { + fn into_case_header_name(self) -> CaseHeaderName { + CaseHeaderName(self.into()) + } +} + +impl IntoCaseHeaderName for HeaderName { + fn into_case_header_name(self) -> CaseHeaderName { + CaseHeaderName(titled_header_name(&self)) + } +} + +impl IntoCaseHeaderName for &HeaderName { + fn into_case_header_name(self) -> CaseHeaderName { + CaseHeaderName(titled_header_name(self)) + } +} + +impl IntoCaseHeaderName for Bytes { + fn into_case_header_name(self) -> CaseHeaderName { + CaseHeaderName(self) + } +} + +fn titled_header_name(header_name: &HeaderName) -> Bytes { + titled_header_name_str(header_name).map_or_else( + || Bytes::copy_from_slice(header_name.as_str().as_bytes()), + |s| Bytes::from_static(s.as_bytes()), + ) +} + +pub(crate) fn titled_header_name_str(header_name: &HeaderName) -> Option<&'static str> { + Some(match *header_name { + header::AGE => "Age", + header::CACHE_CONTROL => "Cache-Control", + header::CONNECTION => "Connection", + header::CONTENT_TYPE => "Content-Type", + header::CONTENT_ENCODING => "Content-Encoding", + header::CONTENT_LENGTH => "Content-Length", + header::DATE => "Date", + header::TRANSFER_ENCODING => "Transfer-Encoding", + header::HOST => "Host", + header::SERVER => "Server", + // TODO: add more const header here to map to their titled case + // TODO: automatically upper case the first letter? + _ => { + return None; + } + }) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_case_header_name() { + assert_eq!("FoO".into_case_header_name().as_slice(), b"FoO"); + assert_eq!("FoO".to_string().into_case_header_name().as_slice(), b"FoO"); + assert_eq!(header::SERVER.into_case_header_name().as_slice(), b"Server"); + } +} diff --git a/pingora-http/src/lib.rs b/pingora-http/src/lib.rs new file mode 100644 index 0000000..f310308 --- /dev/null +++ b/pingora-http/src/lib.rs @@ -0,0 +1,672 @@ +// 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. + +//! HTTP header objects that preserve http header cases +//! +//! Although HTTP header names are supposed to be case-insensitive for compatibility, proxies +//! ideally shouldn't alter the HTTP traffic, especially the headers they don't need to read. +//! +//! This crate provide structs and methods to preserve the headers in order to build a transparent +//! proxy. + +#![allow(clippy::new_without_default)] + +use bytes::BufMut; +use http::header::{AsHeaderName, HeaderName, HeaderValue}; +use http::request::Builder as ReqBuilder; +use http::request::Parts as ReqParts; +use http::response::Builder as RespBuilder; +use http::response::Parts as RespParts; +use http::uri::Uri; +use pingora_error::{ErrorType::*, OrErr, Result}; +use std::convert::TryInto; +use std::ops::Deref; + +pub use http::method::Method; +pub use http::status::StatusCode; +pub use http::version::Version; +pub use http::HeaderMap as HMap; + +mod case_header_name; +use case_header_name::CaseHeaderName; +pub use case_header_name::IntoCaseHeaderName; + +pub mod prelude { + pub use crate::RequestHeader; +} + +/* an ordered header map to store the original case of each header name +HMap({ + "foo": ["Foo", "foO", "FoO"] +}) +The order how HeaderMap iter over its items is "arbitrary, but consistent". +Hopefully this property makes sure this map of header names always iterates in the +same order of the map of header values. +This idea is inspaired by hyper @nox +*/ +type CaseMap = HMap; + +/// The HTTP request header type. +/// +/// This type is similar to [http::request::Parts] but preserves header name case. +/// It also preserves request path even if it is not UTF-8. +/// +/// [RequestHeader] implements [Deref] for [http::request::Parts] so it can be used as it in most +/// places. +#[derive(Debug)] +pub struct RequestHeader { + base: ReqParts, + header_name_map: Option, + // store the raw path bytes only if it is invalid utf-8 + raw_path_fallback: Vec, // can also be Box<[u8]> +} + +impl AsRef for RequestHeader { + fn as_ref(&self) -> &ReqParts { + &self.base + } +} + +impl Deref for RequestHeader { + type Target = ReqParts; + + fn deref(&self) -> &Self::Target { + &self.base + } +} + +impl RequestHeader { + fn new_no_case(size_hint: Option) -> Self { + let mut base = ReqBuilder::new().body(()).unwrap().into_parts().0; + base.headers.reserve(http_header_map_upper_bound(size_hint)); + RequestHeader { + base, + header_name_map: None, + raw_path_fallback: vec![], + } + } + + /// Create a new [RequestHeader] with the given method and path. + /// + /// The `path` can be non UTF-8. + pub fn build( + method: impl TryInto, + path: &[u8], + size_hint: Option, + ) -> Result { + let mut req = Self::build_no_case(method, path, size_hint)?; + req.header_name_map = Some(CaseMap::with_capacity(http_header_map_upper_bound( + size_hint, + ))); + Ok(req) + } + + /// Create a new [RequestHeader] with the given method and path without preserving header case. + /// + /// A [RequestHeader] created from this type is more space efficient than those from [Self::build()]. + /// + /// Use this method if reading from or writing to HTTP/2 sessions where header case doesn't matter anyway. + pub fn build_no_case( + method: impl TryInto, + path: &[u8], + size_hint: Option, + ) -> Result { + let mut req = Self::new_no_case(size_hint); + req.base.method = method + .try_into() + .explain_err(InvalidHTTPHeader, |_| "invalid method")?; + if let Ok(p) = std::str::from_utf8(path) { + let uri = Uri::builder() + .path_and_query(p) + .build() + .explain_err(InvalidHTTPHeader, |_| format!("invalid uri {}", p))?; + req.base.uri = uri; + // keep raw_path empty, no need to store twice + } else { + // put a valid utf-8 path into base for read only access + let lossy_str = String::from_utf8_lossy(path); + let uri = Uri::builder() + .path_and_query(lossy_str.as_ref()) + .build() + .explain_err(InvalidHTTPHeader, |_| format!("invalid uri {}", lossy_str))?; + req.base.uri = uri; + req.raw_path_fallback = path.to_vec(); + } + + Ok(req) + } + + /// Append the header name and value to `self`. + /// + /// If there are already some header under the same name, a new value will be added without + /// any others being removed. + pub fn append_header( + &mut self, + name: impl IntoCaseHeaderName, + value: impl TryInto, + ) -> Result { + let header_value = value + .try_into() + .explain_err(InvalidHTTPHeader, |_| "invalid value while append")?; + append_header_value( + self.header_name_map.as_mut(), + &mut self.base.headers, + name, + header_value, + ) + } + + /// Insert the header name and value to `self`. + /// + /// Different from [Self::append_header()], this method will replace all other existing headers + /// under the same name (case insensitive). + pub fn insert_header( + &mut self, + name: impl IntoCaseHeaderName, + value: impl TryInto, + ) -> Result<()> { + let header_value = value + .try_into() + .explain_err(InvalidHTTPHeader, |_| "invalid value while insert")?; + insert_header_value( + self.header_name_map.as_mut(), + &mut self.base.headers, + name, + header_value, + ) + } + + /// Remove all headers under the name + pub fn remove_header<'a, N: ?Sized>(&mut self, name: &'a N) -> Option + where + &'a N: 'a + AsHeaderName, + { + remove_header(self.header_name_map.as_mut(), &mut self.base.headers, name) + } + + /// Write the header to the `buf` in HTTP/1.1 wire format. + /// + /// The header case will be preserved. + pub fn header_to_h1_wire(&self, buf: &mut impl BufMut) { + header_to_h1_wire(self.header_name_map.as_ref(), &self.base.headers, buf) + } + + /// Set the request method + pub fn set_method(&mut self, method: Method) { + self.base.method = method; + } + + /// Set the request URI + pub fn set_uri(&mut self, uri: http::Uri) { + self.base.uri = uri; + } + + /// Return the request path in its raw format + /// + /// Non-UTF8 is supported. + pub fn raw_path(&self) -> &[u8] { + if !self.raw_path_fallback.is_empty() { + &self.raw_path_fallback + } else { + // Url should always be set + self.base + .uri + .path_and_query() + .as_ref() + .unwrap() + .as_str() + .as_bytes() + } + } + + /// Return the file extension of the path + pub fn uri_file_extension(&self) -> Option<&str> { + // get everything after the last '.' in path + let (_, ext) = self + .uri + .path_and_query() + .and_then(|pq| pq.path().rsplit_once('.'))?; + Some(ext) + } + + /// Set http version + pub fn set_version(&mut self, version: Version) { + self.base.version = version; + } + + /// Clone `self` into [http::request::Parts]. + pub fn as_owned_parts(&self) -> ReqParts { + clone_req_parts(&self.base) + } +} + +impl Clone for RequestHeader { + fn clone(&self) -> Self { + Self { + base: self.as_owned_parts(), + header_name_map: self.header_name_map.clone(), + raw_path_fallback: self.raw_path_fallback.clone(), + } + } +} + +// The `RequestHeader` will be the no case variant, because `ReqParts` keeps no header case +impl From for RequestHeader { + fn from(parts: ReqParts) -> RequestHeader { + Self { + base: parts, + header_name_map: None, + // no illegal path + raw_path_fallback: vec![], + } + } +} + +impl From for ReqParts { + fn from(resp: RequestHeader) -> ReqParts { + resp.base + } +} + +/// The HTTP response header type. +/// +/// This type is similar to [http::response::Parts] but preserves header name case. +/// [ResponseHeader] implements [Deref] for [http::response::Parts] so it can be used as it in most +/// places. +#[derive(Debug)] +pub struct ResponseHeader { + base: RespParts, + // an ordered header map to store the original case of each header name + header_name_map: Option, +} + +impl AsRef for ResponseHeader { + fn as_ref(&self) -> &RespParts { + &self.base + } +} + +impl Deref for ResponseHeader { + type Target = RespParts; + + fn deref(&self) -> &Self::Target { + &self.base + } +} + +impl Clone for ResponseHeader { + fn clone(&self) -> Self { + Self { + base: self.as_owned_parts(), + header_name_map: self.header_name_map.clone(), + } + } +} + +// The `ResponseHeader` will be the no case variant, because `RespParts` keeps no header case +impl From for ResponseHeader { + fn from(parts: RespParts) -> ResponseHeader { + Self { + base: parts, + header_name_map: None, + } + } +} + +impl From for RespParts { + fn from(resp: ResponseHeader) -> RespParts { + resp.base + } +} + +impl From> for Box { + fn from(resp: Box) -> Box { + Box::new(resp.base) + } +} + +impl ResponseHeader { + fn new(size_hint: Option) -> Self { + let mut resp_header = Self::new_no_case(size_hint); + resp_header.header_name_map = Some(CaseMap::with_capacity(http_header_map_upper_bound( + size_hint, + ))); + resp_header + } + + fn new_no_case(size_hint: Option) -> Self { + let mut base = RespBuilder::new().body(()).unwrap().into_parts().0; + base.headers.reserve(http_header_map_upper_bound(size_hint)); + ResponseHeader { + base, + header_name_map: None, + } + } + + /// Create a new [ResponseHeader] with the given status code. + pub fn build(code: impl TryInto, size_hint: Option) -> Result { + let mut resp = Self::new(size_hint); + resp.base.status = code + .try_into() + .explain_err(InvalidHTTPHeader, |_| "invalid status")?; + Ok(resp) + } + + /// Create a new [ResponseHeader] with the given status code without preserving header case. + /// + /// A [ResponseHeader] created from this type is more space efficient than those from [Self::build()]. + /// + /// Use this method if reading from or writing to HTTP/2 sessions where header case doesn't matter anyway. + pub fn build_no_case(code: impl TryInto, size_hint: Option) -> Result { + let mut resp = Self::new_no_case(size_hint); + resp.base.status = code + .try_into() + .explain_err(InvalidHTTPHeader, |_| "invalid status")?; + Ok(resp) + } + + /// Append the header name and value to `self`. + /// + /// If there are already some header under the same name, a new value will be added without + /// any others being removed. + pub fn append_header( + &mut self, + name: impl IntoCaseHeaderName, + value: impl TryInto, + ) -> Result { + let header_value = value + .try_into() + .explain_err(InvalidHTTPHeader, |_| "invalid value while append")?; + append_header_value( + self.header_name_map.as_mut(), + &mut self.base.headers, + name, + header_value, + ) + } + + /// Insert the header name and value to `self`. + /// + /// Different from [Self::append_header()], this method will replace all other existing headers + /// under the same name (case insensitive). + pub fn insert_header( + &mut self, + name: impl IntoCaseHeaderName, + value: impl TryInto, + ) -> Result<()> { + let header_value = value + .try_into() + .explain_err(InvalidHTTPHeader, |_| "invalid value while insert")?; + insert_header_value( + self.header_name_map.as_mut(), + &mut self.base.headers, + name, + header_value, + ) + } + + /// Remove all headers under the name + pub fn remove_header<'a, N: ?Sized>(&mut self, name: &'a N) -> Option + where + &'a N: 'a + AsHeaderName, + { + remove_header(self.header_name_map.as_mut(), &mut self.base.headers, name) + } + + /// Write the header to the `buf` in HTTP/1.1 wire format. + /// + /// The header case will be preserved. + pub fn header_to_h1_wire(&self, buf: &mut impl BufMut) { + header_to_h1_wire(self.header_name_map.as_ref(), &self.base.headers, buf) + } + + /// Set the status code + pub fn set_status(&mut self, status: impl TryInto) -> Result<()> { + self.base.status = status + .try_into() + .explain_err(InvalidHTTPHeader, |_| "invalid status")?; + Ok(()) + } + + /// Set the HTTP version + pub fn set_version(&mut self, version: Version) { + self.base.version = version + } + + /// Clone `self` into [http::response::Parts]. + pub fn as_owned_parts(&self) -> RespParts { + clone_resp_parts(&self.base) + } +} + +fn clone_req_parts(me: &ReqParts) -> ReqParts { + let mut parts = ReqBuilder::new() + .method(me.method.clone()) + .uri(me.uri.clone()) + .version(me.version) + .body(()) + .unwrap() + .into_parts() + .0; + parts.headers = me.headers.clone(); + parts +} + +fn clone_resp_parts(me: &RespParts) -> RespParts { + let mut parts = RespBuilder::new() + .status(me.status) + .version(me.version) + .body(()) + .unwrap() + .into_parts() + .0; + parts.headers = me.headers.clone(); + parts +} + +// This function returns an upper bound on the size of the header map used inside the http crate. +// As of version 0.2, there is a limit of 1 << 15 (32,768) items inside the map. There is an +// assertion against this size inside the crate so we want to avoid panicking by not exceeding this +// upper bound. +fn http_header_map_upper_bound(size_hint: Option) -> usize { + // Even though the crate has 1 << 15 as the max size, calls to `with_capacity` invoke a + // function that returns the size + size / 3. + // + // See https://github.com/hyperium/http/blob/34a9d6bdab027948d6dea3b36d994f9cbaf96f75/src/header/map.rs#L3220 + // + // Therefore we set our max size to be even lower so we guarantee ourselves we won't hit that + // upper bound in the crate. Any way you cut it, 4,096 headers is insane. + const PINGORA_MAX_HEADER_COUNT: usize = 4096; + const INIT_HEADER_SIZE: usize = 8; + + // We select the size hint or the max size here such that we pick a value substantially lower + // 1 << 15 with room to grow the header map. + std::cmp::min( + size_hint.unwrap_or(INIT_HEADER_SIZE), + PINGORA_MAX_HEADER_COUNT, + ) +} + +#[inline] +fn append_header_value( + name_map: Option<&mut CaseMap>, + value_map: &mut HMap, + name: impl IntoCaseHeaderName, + value: T, +) -> Result { + let case_header_name = name.into_case_header_name(); + let header_name: HeaderName = case_header_name + .as_slice() + .try_into() + .or_err(InvalidHTTPHeader, "invalid header name")?; + // storage the original case in the map + if let Some(name_map) = name_map { + name_map.append(header_name.clone(), case_header_name); + } + + Ok(value_map.append(header_name, value)) +} + +#[inline] +fn insert_header_value( + name_map: Option<&mut CaseMap>, + value_map: &mut HMap, + name: impl IntoCaseHeaderName, + value: T, +) -> Result<()> { + let case_header_name = name.into_case_header_name(); + let header_name: HeaderName = case_header_name + .as_slice() + .try_into() + .or_err(InvalidHTTPHeader, "invalid header name")?; + if let Some(name_map) = name_map { + // storage the original case in the map + name_map.insert(header_name.clone(), case_header_name); + } + value_map.insert(header_name, value); + Ok(()) +} + +// the &N here is to avoid clone(). None Copy type like String can impl AsHeaderName +#[inline] +fn remove_header<'a, T, N: ?Sized>( + name_map: Option<&mut CaseMap>, + value_map: &mut HMap, + name: &'a N, +) -> Option +where + &'a N: 'a + AsHeaderName, +{ + if let Some(name_map) = name_map { + name_map.remove(name); + } + value_map.remove(name) +} + +#[inline] +fn header_to_h1_wire(key_map: Option<&CaseMap>, value_map: &HMap, buf: &mut impl BufMut) { + const CRLF: &[u8; 2] = b"\r\n"; + const HEADER_KV_DELIMITER: &[u8; 2] = b": "; + + if let Some(key_map) = key_map { + let iter = key_map.iter().zip(value_map.iter()); + for ((header, case_header), (header2, val)) in iter { + if header != header2 { + // in case the header iter order changes in further version of HMap + panic!("header iter mismatch {}, {}", header, header2) + } + buf.put_slice(case_header.as_slice()); + buf.put_slice(HEADER_KV_DELIMITER); + buf.put_slice(val.as_ref()); + buf.put_slice(CRLF); + } + } else { + for (header, value) in value_map { + let titled_header = + case_header_name::titled_header_name_str(header).unwrap_or(header.as_str()); + buf.put_slice(titled_header.as_bytes()); + buf.put_slice(HEADER_KV_DELIMITER); + buf.put_slice(value.as_ref()); + buf.put_slice(CRLF); + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn header_map_upper_bound() { + assert_eq!(8, http_header_map_upper_bound(None)); + assert_eq!(16, http_header_map_upper_bound(Some(16))); + assert_eq!(4096, http_header_map_upper_bound(Some(7777))); + } + + #[test] + fn test_single_header() { + let mut req = RequestHeader::build("GET", b"\\", None).unwrap(); + req.insert_header("foo", "bar").unwrap(); + req.insert_header("FoO", "Bar").unwrap(); + let mut buf: Vec = vec![]; + req.header_to_h1_wire(&mut buf); + assert_eq!(buf, b"FoO: Bar\r\n"); + + let mut resp = ResponseHeader::new(None); + req.insert_header("foo", "bar").unwrap(); + resp.insert_header("FoO", "Bar").unwrap(); + let mut buf: Vec = vec![]; + resp.header_to_h1_wire(&mut buf); + assert_eq!(buf, b"FoO: Bar\r\n"); + } + + #[test] + fn test_single_header_no_case() { + let mut req = RequestHeader::new_no_case(None); + req.insert_header("foo", "bar").unwrap(); + req.insert_header("FoO", "Bar").unwrap(); + let mut buf: Vec = vec![]; + req.header_to_h1_wire(&mut buf); + assert_eq!(buf, b"foo: Bar\r\n"); + + let mut resp = ResponseHeader::new_no_case(None); + req.insert_header("foo", "bar").unwrap(); + resp.insert_header("FoO", "Bar").unwrap(); + let mut buf: Vec = vec![]; + resp.header_to_h1_wire(&mut buf); + assert_eq!(buf, b"foo: Bar\r\n"); + } + + #[test] + fn test_multiple_header() { + let mut req = RequestHeader::build("GET", b"\\", None).unwrap(); + req.append_header("FoO", "Bar").unwrap(); + req.append_header("fOO", "bar").unwrap(); + req.append_header("BAZ", "baR").unwrap(); + req.append_header(http::header::CONTENT_LENGTH, "0") + .unwrap(); + req.append_header("a", "b").unwrap(); + req.remove_header("a"); + let mut buf: Vec = vec![]; + req.header_to_h1_wire(&mut buf); + assert_eq!( + buf, + b"FoO: Bar\r\nfOO: bar\r\nBAZ: baR\r\nContent-Length: 0\r\n" + ); + + let mut resp = ResponseHeader::new(None); + resp.append_header("FoO", "Bar").unwrap(); + resp.append_header("fOO", "bar").unwrap(); + resp.append_header("BAZ", "baR").unwrap(); + resp.append_header(http::header::CONTENT_LENGTH, "0") + .unwrap(); + resp.append_header("a", "b").unwrap(); + resp.remove_header("a"); + let mut buf: Vec = vec![]; + resp.header_to_h1_wire(&mut buf); + assert_eq!( + buf, + b"FoO: Bar\r\nfOO: bar\r\nBAZ: baR\r\nContent-Length: 0\r\n" + ); + } + + #[cfg(feature = "patched_http1")] + #[test] + fn test_invalid_path() { + let raw_path = b"Hello\xF0\x90\x80World"; + let req = RequestHeader::build("GET", &raw_path[..], None).unwrap(); + assert_eq!("Hello�World", req.uri.path_and_query().unwrap()); + assert_eq!(raw_path, req.raw_path()); + } +} diff --git a/pingora-ketama/Cargo.toml b/pingora-ketama/Cargo.toml new file mode 100644 index 0000000..1e467b5 --- /dev/null +++ b/pingora-ketama/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "pingora-ketama" +version = "0.1.0" +description = "Rust port of the nginx consistent hash function" +authors = ["Pingora Team "] +license = "Apache-2.0" +edition = "2021" +repository = "https://github.com/cloudflare/pingora" +categories = ["caching", "algorithms"] +keywords = ["hash", "hashing", "consistent", "pingora"] + +[dependencies] +crc32fast = "1.3" + +[dev-dependencies] +criterion = "0.4" +csv = "1.2" +dhat = "0.3" +env_logger = "0.9" +log = { workspace = true } +rand = "0.8" + +[[bench]] +name = "simple" +harness = false + +[[bench]] +name = "memory" +harness = false + +[features] +heap-prof = [] diff --git a/pingora-ketama/LICENSE b/pingora-ketama/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/pingora-ketama/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/pingora-ketama/benches/memory.rs b/pingora-ketama/benches/memory.rs new file mode 100644 index 0000000..ac12de4 --- /dev/null +++ b/pingora-ketama/benches/memory.rs @@ -0,0 +1,22 @@ +use pingora_ketama::{Bucket, Continuum}; + +#[global_allocator] +static ALLOC: dhat::Alloc = dhat::Alloc; + +fn buckets() -> Vec { + let mut b = Vec::new(); + + for i in 1..254 { + b.push(Bucket::new( + format!("127.0.0.{i}:6443").parse().unwrap(), + 10, + )); + } + + b +} + +pub fn main() { + let _profiler = dhat::Profiler::new_heap(); + let _c = Continuum::new(&buckets()); +} diff --git a/pingora-ketama/benches/simple.rs b/pingora-ketama/benches/simple.rs new file mode 100644 index 0000000..253cf33 --- /dev/null +++ b/pingora-ketama/benches/simple.rs @@ -0,0 +1,45 @@ +use pingora_ketama::{Bucket, Continuum}; + +use criterion::{criterion_group, criterion_main, Criterion}; +use rand::distributions::Alphanumeric; +use rand::{thread_rng, Rng}; + +#[cfg(feature = "heap-prof")] +#[global_allocator] +static ALLOC: dhat::Alloc = dhat::Alloc; + +fn buckets() -> Vec { + let mut b = Vec::new(); + + for i in 1..101 { + b.push(Bucket::new(format!("127.0.0.{i}:6443").parse().unwrap(), 1)); + } + + b +} + +fn random_string() -> String { + thread_rng() + .sample_iter(&Alphanumeric) + .take(30) + .map(char::from) + .collect() +} + +pub fn criterion_benchmark(c: &mut Criterion) { + #[cfg(feature = "heap-prof")] + let _profiler = dhat::Profiler::new_heap(); + + c.bench_function("create_continuum", |b| { + b.iter(|| Continuum::new(&buckets())) + }); + + c.bench_function("continuum_hash", |b| { + let continuum = Continuum::new(&buckets()); + + b.iter(|| continuum.node(random_string().as_bytes())) + }); +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); diff --git a/pingora-ketama/examples/health_aware_selector.rs b/pingora-ketama/examples/health_aware_selector.rs new file mode 100644 index 0000000..938c7d7 --- /dev/null +++ b/pingora-ketama/examples/health_aware_selector.rs @@ -0,0 +1,94 @@ +use log::info; +use pingora_ketama::{Bucket, Continuum}; +use std::collections::HashMap; +use std::net::SocketAddr; + +// A repository for node healthiness, emulating a health checker. +struct NodeHealthRepository { + nodes: HashMap, +} + +impl NodeHealthRepository { + fn new() -> Self { + NodeHealthRepository { + nodes: HashMap::new(), + } + } + + fn set_node_health(&mut self, node: SocketAddr, is_healthy: bool) { + self.nodes.insert(node, is_healthy); + } + + fn node_is_healthy(&self, node: &SocketAddr) -> bool { + self.nodes.get(node).cloned().unwrap_or(false) + } +} + +// A health-aware node selector, which relies on the above health repository. +struct HealthAwareNodeSelector<'a> { + ring: Continuum, + max_tries: usize, + node_health_repo: &'a NodeHealthRepository, +} + +impl<'a> HealthAwareNodeSelector<'a> { + fn new(r: Continuum, tries: usize, nhr: &NodeHealthRepository) -> HealthAwareNodeSelector { + HealthAwareNodeSelector { + ring: r, + max_tries: tries, + node_health_repo: nhr, + } + } + + // Try to select a node within attempts. + fn try_select(&self, key: &str) -> Option { + let node_iter = self.ring.node_iter(key.as_bytes()); + + for (tries, node) in node_iter.enumerate() { + if tries >= self.max_tries { + break; + } + + if self.node_health_repo.node_is_healthy(node) { + return Some(*node); + } + } + + None + } +} + +// RUST_LOG=INFO cargo run --example health_aware_selector +fn main() { + env_logger::init(); + + // Set up some nodes. + let buckets: Vec<_> = (1..=10) + .map(|i| Bucket::new(format!("127.0.0.{i}:6443").parse().unwrap(), 1)) + .collect(); + + // Mark the 1-5th nodes healthy, the 6-10th nodes unhealthy. + let mut health_repo = NodeHealthRepository::new(); + (1..=10) + .map(|i| (i, format!("127.0.0.{i}:6443").parse().unwrap())) + .for_each(|(i, n)| { + health_repo.set_node_health(n, i < 6); + }); + + // Create a health-aware selector with up to 3 tries. + let health_aware_selector = + HealthAwareNodeSelector::new(Continuum::new(&buckets), 3, &health_repo); + + // Let's try the selector on a few keys. + for i in 0..5 { + let key = format!("key_{i}"); + match health_aware_selector.try_select(&key) { + Some(node) => { + info!("{key}: {}:{}", node.ip(), node.port()); + } + None => { + info!("{key}: no healthy node found!"); + } + } + } +} diff --git a/pingora-ketama/src/lib.rs b/pingora-ketama/src/lib.rs new file mode 100644 index 0000000..0917056 --- /dev/null +++ b/pingora-ketama/src/lib.rs @@ -0,0 +1,447 @@ +// 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. + +//! # pingora-ketama +//! A Rust port of the nginx consistent hashing algorithm. +//! +//! This crate provides a consistent hashing algorithm which is identical in +//! behavior to [nginx consistent hashing](https://www.nginx.com/resources/wiki/modules/consistent_hash/). +//! +//! Using a consistent hash strategy like this is useful when one wants to +//! minimize the amount of requests that need to be rehashed to different nodes +//! when a node is added or removed. +//! +//! Here's a simple example of how one might use it: +//! +//! ``` +//! use pingora_ketama::{Bucket, Continuum}; +//! +//! # #[allow(clippy::needless_doctest_main)] +//! fn main() { +//! // Set up a continuum with a few nodes of various weight. +//! let mut buckets = vec![]; +//! buckets.push(Bucket::new("127.0.0.1:12345".parse().unwrap(), 1)); +//! buckets.push(Bucket::new("127.0.0.2:12345".parse().unwrap(), 2)); +//! buckets.push(Bucket::new("127.0.0.3:12345".parse().unwrap(), 3)); +//! let ring = Continuum::new(&buckets); +//! +//! // Let's see what the result is for a few keys: +//! for key in &["some_key", "another_key", "last_key"] { +//! let node = ring.node(key.as_bytes()).unwrap(); +//! println!("{}: {}:{}", key, node.ip(), node.port()); +//! } +//! } +//! ``` +//! +//! ```bash +//! # Output: +//! some_key: 127.0.0.3:12345 +//! another_key: 127.0.0.3:12345 +//! last_key: 127.0.0.2:12345 +//! ``` +//! +//! We've provided a health-aware example in +//! `pingora-ketama/examples/health_aware_selector.rs`. +//! +//! For a carefully crafted real-world example, see the pingora-load-balancer +//! crate. + +use std::cmp::Ordering; +use std::io::Write; +use std::net::SocketAddr; +use std::usize; + +use crc32fast::Hasher; + +/// A [Bucket] represents a server for consistent hashing +/// +/// A [Bucket] contains a [SocketAddr] to the server and a weight associated with it. +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd)] +pub struct Bucket { + // The node name. + // TODO: UDS + node: SocketAddr, + + // The weight associated with a node. A higher weight indicates that this node should + // receive more requests. + weight: u32, +} + +impl Bucket { + /// Return a new bucket with the given node and weight. + /// + /// The chance that a [Bucket] is selected is proportional to the relative weight of all [Bucket]s. + /// + /// # Panics + /// + /// This will panic if the weight is zero. + pub fn new(node: SocketAddr, weight: u32) -> Self { + assert!(weight != 0, "weight must be at least one"); + + Bucket { node, weight } + } +} + +// A point on the continuum. +#[derive(Clone, Debug, Eq, PartialEq)] +struct Point { + // the index to the actual address + node: u32, + hash: u32, +} + +// We only want to compare the hash when sorting so we implement these traits by hand. +impl Ord for Point { + fn cmp(&self, other: &Self) -> Ordering { + self.hash.cmp(&other.hash) + } +} + +impl PartialOrd for Point { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Point { + fn new(node: u32, hash: u32) -> Self { + Point { node, hash } + } +} + +/// The consistent hashing ring +/// +/// A [Continuum] represents a ring of buckets where a node is associated with various points on +/// the ring. +pub struct Continuum { + ring: Box<[Point]>, + addrs: Box<[SocketAddr]>, +} + +impl Continuum { + /// Create a new [Continuum] with the given list of buckets. + pub fn new(buckets: &[Bucket]) -> Self { + // This constant is copied from nginx. It will create 160 points per weight unit. For + // example, a weight of 2 will create 320 points on the ring. + const POINT_MULTIPLE: u32 = 160; + + if buckets.is_empty() { + return Continuum { + ring: Box::new([]), + addrs: Box::new([]), + }; + } + + // The total weight is multiplied by the factor of points to create many points per node. + let total_weight: u32 = buckets.iter().fold(0, |sum, b| sum + b.weight); + let mut ring = Vec::with_capacity((total_weight * POINT_MULTIPLE) as usize); + let mut addrs = Vec::with_capacity(buckets.len()); + + for bucket in buckets { + let mut hasher = Hasher::new(); + + // We only do the following for backwards compatibility with nginx/memcache: + // - Convert SocketAddr to string + // - The hash input is as follows "HOST EMPTY PORT PREVIOUS_HASH". Spaces are only added + // for readability. + // TODO: remove this logic and hash the literal SocketAddr once we no longer + // need backwards compatibility + + // with_capacity = max_len(ipv6)(39) + len(null)(1) + max_len(port)(5) + let mut hash_bytes = Vec::with_capacity(39 + 1 + 5); + write!(&mut hash_bytes, "{}", bucket.node.ip()).unwrap(); + write!(&mut hash_bytes, "\0").unwrap(); + write!(&mut hash_bytes, "{}", bucket.node.port()).unwrap(); + hasher.update(hash_bytes.as_ref()); + + // A higher weight will add more points for this node. + let num_points = bucket.weight * POINT_MULTIPLE; + + // This is appended to the crc32 hash for each point. + let mut prev_hash: u32 = 0; + addrs.push(bucket.node); + let node = addrs.len() - 1; + for _ in 0..num_points { + let mut hasher = hasher.clone(); + hasher.update(&prev_hash.to_le_bytes()); + + let hash = hasher.finalize(); + ring.push(Point::new(node as u32, hash)); + prev_hash = hash; + } + } + + // Sort and remove any duplicates. + ring.sort(); + ring.dedup_by(|a, b| a.hash == b.hash); + + Continuum { + ring: ring.into_boxed_slice(), + addrs: addrs.into_boxed_slice(), + } + } + + /// Find the associated index for the given input. + pub fn node_idx(&self, input: &[u8]) -> usize { + let hash = crc32fast::hash(input); + + // The `Result` returned here is either a match or the error variant returns where the + // value would be inserted. + match self.ring.binary_search_by(|p| p.hash.cmp(&hash)) { + Ok(i) => i, + Err(i) => { + // We wrap around to the front if this value would be inserted at the end. + if i == self.ring.len() { + 0 + } else { + i + } + } + } + } + + /// Hash the given `hash_key` to the server address. + pub fn node(&self, hash_key: &[u8]) -> Option { + self.ring + .get(self.node_idx(hash_key)) // should we unwrap here? + .map(|p| self.addrs[p.node as usize]) + } + + /// Get an iterator of nodes starting at the original hashed node of the `hash_key`. + /// + /// This function is useful to find failover servers if the original ones are offline, which is + /// cheaper than rebuilding the entire hash ring. + pub fn node_iter(&self, hash_key: &[u8]) -> NodeIterator { + NodeIterator { + idx: self.node_idx(hash_key), + continuum: self, + } + } + + pub fn get_addr(&self, idx: &mut usize) -> Option<&SocketAddr> { + let point = self.ring.get(*idx); + if point.is_some() { + // only update idx for non-empty ring otherwise we will panic on modulo 0 + *idx = (*idx + 1) % self.ring.len(); + } + point.map(|p| &self.addrs[p.node as usize]) + } +} + +/// Iterator over a Continuum +pub struct NodeIterator<'a> { + idx: usize, + continuum: &'a Continuum, +} + +impl<'a> Iterator for NodeIterator<'a> { + type Item = &'a SocketAddr; + + fn next(&mut self) -> Option { + self.continuum.get_addr(&mut self.idx) + } +} + +#[cfg(test)] +mod tests { + use std::net::SocketAddr; + use std::path::Path; + + use super::{Bucket, Continuum}; + + fn get_sockaddr(ip: &str) -> SocketAddr { + ip.parse().unwrap() + } + + #[test] + fn consistency_after_adding_host() { + fn assert_hosts(c: &Continuum) { + assert_eq!(c.node(b"a"), Some(get_sockaddr("127.0.0.10:6443"))); + assert_eq!(c.node(b"b"), Some(get_sockaddr("127.0.0.5:6443"))); + } + + let buckets: Vec<_> = (1..11) + .map(|u| Bucket::new(get_sockaddr(&format!("127.0.0.{u}:6443")), 1)) + .collect(); + let c = Continuum::new(&buckets); + assert_hosts(&c); + + // Now add a new host and ensure that the hosts don't get shuffled. + let buckets: Vec<_> = (1..12) + .map(|u| Bucket::new(get_sockaddr(&format!("127.0.0.{u}:6443")), 1)) + .collect(); + + let c = Continuum::new(&buckets); + assert_hosts(&c); + } + + #[test] + fn matches_nginx_sample() { + let upstream_hosts = ["127.0.0.1:7777", "127.0.0.1:7778"]; + let upstream_hosts = upstream_hosts.iter().map(|i| get_sockaddr(i)); + + let mut buckets = Vec::new(); + for upstream in upstream_hosts { + buckets.push(Bucket::new(upstream, 1)); + } + + let c = Continuum::new(&buckets); + + assert_eq!(c.node(b"/some/path"), Some(get_sockaddr("127.0.0.1:7778"))); + assert_eq!( + c.node(b"/some/longer/path"), + Some(get_sockaddr("127.0.0.1:7777")) + ); + assert_eq!( + c.node(b"/sad/zaidoon"), + Some(get_sockaddr("127.0.0.1:7778")) + ); + assert_eq!(c.node(b"/g"), Some(get_sockaddr("127.0.0.1:7777"))); + assert_eq!( + c.node(b"/pingora/team/is/cool/and/this/is/a/long/uri"), + Some(get_sockaddr("127.0.0.1:7778")) + ); + assert_eq!( + c.node(b"/i/am/not/confident/in/this/code"), + Some(get_sockaddr("127.0.0.1:7777")) + ); + } + + #[test] + fn matches_nginx_sample_data() { + let upstream_hosts = [ + "10.0.0.1:443", + "10.0.0.2:443", + "10.0.0.3:443", + "10.0.0.4:443", + "10.0.0.5:443", + "10.0.0.6:443", + "10.0.0.7:443", + "10.0.0.8:443", + "10.0.0.9:443", + ]; + let upstream_hosts = upstream_hosts.iter().map(|i| get_sockaddr(i)); + + let mut buckets = Vec::new(); + for upstream in upstream_hosts { + buckets.push(Bucket::new(upstream, 100)); + } + + let c = Continuum::new(&buckets); + + let path = Path::new(env!("CARGO_MANIFEST_DIR")) + .join("test-data") + .join("sample-nginx-upstream.csv"); + + let mut rdr = csv::ReaderBuilder::new() + .has_headers(false) + .from_path(path) + .unwrap(); + + for pair in rdr.records() { + let pair = pair.unwrap(); + let uri = pair.get(0).unwrap(); + let upstream = pair.get(1).unwrap(); + + let got = c.node(uri.as_bytes()).unwrap(); + assert_eq!(got, get_sockaddr(upstream)); + } + } + + #[test] + fn node_iter() { + let upstream_hosts = ["127.0.0.1:7777", "127.0.0.1:7778", "127.0.0.1:7779"]; + let upstream_hosts = upstream_hosts.iter().map(|i| get_sockaddr(i)); + + let mut buckets = Vec::new(); + for upstream in upstream_hosts { + buckets.push(Bucket::new(upstream, 1)); + } + + let c = Continuum::new(&buckets); + let mut iter = c.node_iter(b"doghash"); + assert_eq!(iter.next(), Some(&get_sockaddr("127.0.0.1:7778"))); + assert_eq!(iter.next(), Some(&get_sockaddr("127.0.0.1:7779"))); + assert_eq!(iter.next(), Some(&get_sockaddr("127.0.0.1:7779"))); + assert_eq!(iter.next(), Some(&get_sockaddr("127.0.0.1:7777"))); + assert_eq!(iter.next(), Some(&get_sockaddr("127.0.0.1:7777"))); + assert_eq!(iter.next(), Some(&get_sockaddr("127.0.0.1:7778"))); + assert_eq!(iter.next(), Some(&get_sockaddr("127.0.0.1:7778"))); + assert_eq!(iter.next(), Some(&get_sockaddr("127.0.0.1:7779"))); + + // drop 127.0.0.1:7777 + let upstream_hosts = ["127.0.0.1:7777", "127.0.0.1:7779"]; + let upstream_hosts = upstream_hosts.iter().map(|i| get_sockaddr(i)); + + let mut buckets = Vec::new(); + for upstream in upstream_hosts { + buckets.push(Bucket::new(upstream, 1)); + } + + let c = Continuum::new(&buckets); + let mut iter = c.node_iter(b"doghash"); + // 127.0.0.1:7778 nodes are gone now + // assert_eq!(iter.next(), Some("127.0.0.1:7778")); + assert_eq!(iter.next(), Some(&get_sockaddr("127.0.0.1:7779"))); + assert_eq!(iter.next(), Some(&get_sockaddr("127.0.0.1:7779"))); + assert_eq!(iter.next(), Some(&get_sockaddr("127.0.0.1:7777"))); + assert_eq!(iter.next(), Some(&get_sockaddr("127.0.0.1:7777"))); + // assert_eq!(iter.next(), Some("127.0.0.1:7778")); + // assert_eq!(iter.next(), Some("127.0.0.1:7778")); + assert_eq!(iter.next(), Some(&get_sockaddr("127.0.0.1:7779"))); + + // assert infinite cycle + let c = Continuum::new(&[Bucket::new(get_sockaddr("127.0.0.1:7777"), 1)]); + let mut iter = c.node_iter(b"doghash"); + + let start_idx = iter.idx; + for _ in 0..c.ring.len() { + assert!(iter.next().is_some()); + } + // assert wrap around + assert_eq!(start_idx, iter.idx); + } + + #[test] + fn test_empty() { + let c = Continuum::new(&[]); + assert!(c.node(b"doghash").is_none()); + + let mut iter = c.node_iter(b"doghash"); + assert!(iter.next().is_none()); + assert!(iter.next().is_none()); + assert!(iter.next().is_none()); + } + + #[test] + fn test_ipv6_ring() { + let upstream_hosts = ["[::1]:7777", "[::1]:7778", "[::1]:7779"]; + let upstream_hosts = upstream_hosts.iter().map(|i| get_sockaddr(i)); + + let mut buckets = Vec::new(); + for upstream in upstream_hosts { + buckets.push(Bucket::new(upstream, 1)); + } + + let c = Continuum::new(&buckets); + let mut iter = c.node_iter(b"doghash"); + assert_eq!(iter.next(), Some(&get_sockaddr("[::1]:7777"))); + assert_eq!(iter.next(), Some(&get_sockaddr("[::1]:7778"))); + assert_eq!(iter.next(), Some(&get_sockaddr("[::1]:7777"))); + assert_eq!(iter.next(), Some(&get_sockaddr("[::1]:7778"))); + assert_eq!(iter.next(), Some(&get_sockaddr("[::1]:7778"))); + assert_eq!(iter.next(), Some(&get_sockaddr("[::1]:7777"))); + assert_eq!(iter.next(), Some(&get_sockaddr("[::1]:7779"))); + } +} diff --git a/pingora-ketama/test-data/README.md b/pingora-ketama/test-data/README.md new file mode 100644 index 0000000..f44bac8 --- /dev/null +++ b/pingora-ketama/test-data/README.md @@ -0,0 +1,18 @@ +# Steps to generate nginx upstream ketama hash logs + +1. Prepare nginx conf +``` +mkdir -p /tmp/nginx-ketama/logs +cp nginx.conf /tmp/nginx-ketama +nginx -t -c nginx.conf -p /tmp/nginx-ketama +``` + +2. Generate trace +``` +./trace.sh +``` + +3. Collect trace +``` + cp /tmp/nginx-ketama/logs/access.log ./sample-nginx-upstream.csv +``` \ No newline at end of file diff --git a/pingora-ketama/test-data/nginx.conf b/pingora-ketama/test-data/nginx.conf new file mode 100644 index 0000000..7b30a3a --- /dev/null +++ b/pingora-ketama/test-data/nginx.conf @@ -0,0 +1,29 @@ +events {} +http { + log_format upper '$request_uri,$upstream_addr'; + + upstream uppers { + hash $request_uri consistent; + + server 10.0.0.1:443 weight=100 max_fails=0; + server 10.0.0.2:443 weight=100 max_fails=0; + server 10.0.0.3:443 weight=100 max_fails=0; + server 10.0.0.4:443 weight=100 max_fails=0; + server 10.0.0.5:443 weight=100 max_fails=0; + server 10.0.0.6:443 weight=100 max_fails=0; + server 10.0.0.7:443 weight=100 max_fails=0; + server 10.0.0.8:443 weight=100 max_fails=0; + server 10.0.0.9:443 weight=100 max_fails=0; + } + + server { + listen 127.0.0.1:8080; + + location / { + access_log /tmp/nginx-ketama/logs/access.log upper; + proxy_connect_timeout 5ms; + proxy_next_upstream off; + proxy_pass http://uppers; + } + } +} \ No newline at end of file diff --git a/pingora-ketama/test-data/sample-nginx-upstream.csv b/pingora-ketama/test-data/sample-nginx-upstream.csv new file mode 100644 index 0000000..1b0c113 --- /dev/null +++ b/pingora-ketama/test-data/sample-nginx-upstream.csv @@ -0,0 +1,1001 @@ +/81fa1d251d605775d647b5b55565e71526d4cef6,10.0.0.7:443 +/2fec328e6ccdda6a7edf329f9f780e546ea183b4,10.0.0.5:443 +/19fb835d90883a6263ec4279c6da184e3f1a79b2,10.0.0.4:443 +/da7a88e542f7aaddc074f988164b9df7e5f7fea6,10.0.0.4:443 +/8f87cfd8005306643b6528b3d4125cf005139a7e,10.0.0.5:443 +/26d2769eab098458bc3e4e641a4b7d8abffd0aea,10.0.0.6:443 +/aa5b5323980f2d3e21246212ebd820c3949c1e88,10.0.0.7:443 +/d9c4bc3cc4517c629e8f4c911c2fd8baf260ae65,10.0.0.1:443 +/28c1c069a2904bb3b3e0f9731b1ff8de9ab7a76d,10.0.0.4:443 +/fe5199bdfeee5cd431ae7e9f77f178164f9995a0,10.0.0.9:443 +/43992eee187920c5e8695332f71ca6e23ef6ac4b,10.0.0.3:443 +/38528aab753a6f32de86b5a7acdbb0c885137a81,10.0.0.9:443 +/12d4b9155ff599c0ac554226796b58a2278b450f,10.0.0.7:443 +/9c34c9a4f9009997dd29c6e6a627b0aca7beb6e5,10.0.0.5:443 +/eb5a2ab55796afd673874fd7560f1329be5540bd,10.0.0.9:443 +/ad7b5395766b77098c3f212043650a805b622ffe,10.0.0.3:443 +/c72fedf4177499635302849496898fe4f3409cc1,10.0.0.9:443 +/77766138aaf0c016bdd1f6b996177fc8ca1d2204,10.0.0.8:443 +/860c86b94e04f2648fb164c87fd6166707fd08ff,10.0.0.6:443 +/1b419454e4eb63ef915e8e06cc11110a3ccd607e,10.0.0.7:443 +/a8762dc488e1a1af31e53af8ddb887d4f3cca990,10.0.0.8:443 +/2e8e8e8fdeada0bbd33ba57d20209b4d9343f965,10.0.0.4:443 +/0220fa8b9a256e7fcf823097759aa3c44e6390e3,10.0.0.6:443 +/418c1c554186b78c11de89227fbc24ef128bce54,10.0.0.8:443 +/bc86e565b76f8e6f560064b02ab26529b6064571,10.0.0.3:443 +/5c6a9b50df69956bd2b937ce7871ba6d67678db6,10.0.0.5:443 +/5726f95dd0b1b145ad1a06755580f42fea41ac2a,10.0.0.9:443 +/db601a7f7e24504b820e5ef5276b2653ec6c17d9,10.0.0.4:443 +/f428a38a0d3dbbb12d475aa8f5be917147175eaf,10.0.0.6:443 +/b815ca5871d52098946eded8a3382d086747818f,10.0.0.1:443 +/fc61e21e21c6c0a9e03807a2cad7c1e79a104786,10.0.0.1:443 +/8278c52b97c1e805c1c7c1a62123ca0a87e2ea2a,10.0.0.8:443 +/668fd6d99bfb50b85b0928a8915761be2ca19089,10.0.0.2:443 +/fefbfb22035c938b44d305dbb71b11d531257af8,10.0.0.2:443 +/c30b287269464a75cf76a603145a7e44b83c8bde,10.0.0.5:443 +/7584dbc60619230cb5a315cfdd3760fe2e2980c3,10.0.0.9:443 +/399b3bdce88319bdba1b6b310cfcbd9db9cec234,10.0.0.6:443 +/5edc91979f6f38dbbe00544d97d617b92b3df93d,10.0.0.9:443 +/ac740e2450803d9b6042a3a98e5fe16eaad536e6,10.0.0.1:443 +/46013f26dbbde9c25de5fcbb92ff331d5614bae8,10.0.0.5:443 +/f109862c7c78e8ce087aeff9f2368d54d91fd3be,10.0.0.5:443 +/fdc13a7011bbcf36b232adde4c610f0f35e9147e,10.0.0.3:443 +/8387a3c076e525cae448c6a3b22988a2f37a98fc,10.0.0.1:443 +/b4739e36d8e7eba1a400925c928caf0741b1a92a,10.0.0.1:443 +/d92612bb3f678d8b181fa176e0af7227bf5f7e42,10.0.0.9:443 +/89ec56b1d8d72c888b044e8cd7fa51b9ac726a41,10.0.0.2:443 +/7cf921d8181af6912676f20c3d961d3f2ffbad20,10.0.0.3:443 +/9181876c839cf16fd7c8c858b7afdc0178fb9500,10.0.0.3:443 +/1034a4394566c826888f813af75c396fe8082b43,10.0.0.3:443 +/81ac831667e89c2c6b3c6098b598d99eb1ce2b20,10.0.0.2:443 +/d9dbae8a03a430b8d9cbffcf622b4e379bc89bf6,10.0.0.7:443 +/c67776793fdcf7553fe0cb6414bb9dafe0216911,10.0.0.6:443 +/1ee25559aa4aaa11ec1b3d2cc8645ed05ec001b3,10.0.0.9:443 +/580180a2b85efff1a393ea2449ae271148ca2770,10.0.0.2:443 +/84e1a1904a52e43ace344346032daca4e1bb69d6,10.0.0.8:443 +/9cd06ffa608a252a30d935d2ebf10eceda06ba2e,10.0.0.6:443 +/cf85a0000f38ac5346ddddd8cc0c28a054bbe60c,10.0.0.5:443 +/c31f22b05514e380dd4430086486dc3ba4e36ed4,10.0.0.6:443 +/336fdd336fde2bde2e0132d4be65088953036175,10.0.0.7:443 +/cb1e7e2c425607defdd725e81ca3121340dbc8bb,10.0.0.8:443 +/7bd85bb6826eeb30a67a999bfdeb6f6368954a3d,10.0.0.5:443 +/bb542ca4f154437b0fa394b3be8d45350efc4955,10.0.0.8:443 +/53e425848829e3aeb1c6991512e1951145b2ce46,10.0.0.6:443 +/a6ad65c1bcacb876b76165e741f35c98a09cbbf3,10.0.0.3:443 +/1fca16e96a89623e2ef7a93fccd767c4ef2a7905,10.0.0.9:443 +/b9ad129954c11aa1491552845199c2fb4bbff25e,10.0.0.2:443 +/9c0380f918aeb44664929447077ee992894cb754,10.0.0.9:443 +/a9aeb4e3fb0b2358f70a6d9c2ad62409a7c24574,10.0.0.5:443 +/8d563416df0c167343d295f889d64dd9ff213a9e,10.0.0.7:443 +/71ddc6cc8f25f63ad7df9ad963beb9a14ca6b76f,10.0.0.2:443 +/1dd61ea19da5970147129b0ba635338bc93c7aba,10.0.0.7:443 +/2c019dd0aebfdf9d94fb1201b25f443c91c034f8,10.0.0.8:443 +/636b620e6d548492a0fac32e895fa64ab48fa70d,10.0.0.1:443 +/e26420a446174c0bcbc008f3d8ce97570d55619e,10.0.0.7:443 +/2522d660a63527ab2f74c7a167366bbb0bc46cb1,10.0.0.6:443 +/6e585c3e88aeb95554f5c00730c70d71189a12c6,10.0.0.1:443 +/0bc50da77b7cf3959612950d97564e91e5a0f3fa,10.0.0.9:443 +/167872e2688593c6544c0855b76a99fd0f96bb69,10.0.0.8:443 +/7842aa002d2416c4587d779bbea40f5983883a9d,10.0.0.1:443 +/b3cdb310440af5a8a9788534e2a44e1df75fc0aa,10.0.0.2:443 +/7c17fc177496c13dd1207388087ae1979603c886,10.0.0.5:443 +/28865c3daa92ec1e3784c51e9aa70c78b902dfa6,10.0.0.3:443 +/4b990fc439195c5e05cfea65a2453f23fc5bbf1a,10.0.0.5:443 +/7261021a69a6478b0620315c231c4aa26fda2638,10.0.0.2:443 +/d5caa3e251ad2dd28ba82c3dcb99bff6d368e2a0,10.0.0.1:443 +/a8606508d178e519aa53f989ef60db8a0f3a2c2c,10.0.0.2:443 +/eb797fcf3e5954c884b78360247e38566f7f674a,10.0.0.9:443 +/289ced7bea19beee166cf4b07d31c8461975d4e4,10.0.0.6:443 +/e563ce7e72b68097a6432f68f86ed6f40d040ac3,10.0.0.3:443 +/ba22b6f2657746d3b8f802ab2303ffd4b040a73f,10.0.0.7:443 +/5dbda23f45eb02ecc74e57905b9dc6eab6d9770c,10.0.0.9:443 +/637691e12da247452c3a614f560001e263a9f85e,10.0.0.5:443 +/b2e491e1528813c17dfc888c5039c9e3f40f9040,10.0.0.8:443 +/a4575d09e2fcb4d42e214c33be25c2f1c10e8323,10.0.0.5:443 +/d655e051b4f82c459b20afbd2ccca058e16ad3fa,10.0.0.2:443 +/cdca39ce5deb7022702e18e0c6b61010ba931e54,10.0.0.9:443 +/58b31129208a29d2435258dc9f24a6b851ed1ac0,10.0.0.6:443 +/019930f0699b20a72a091c1042dfe33ac568b190,10.0.0.5:443 +/f00117302e2daca8c81e68cb33cf445b72c45895,10.0.0.9:443 +/da90cf74593ee181693910a40142bc79479c354e,10.0.0.5:443 +/87654ba6f96f359e4418b3368ae2256a3c2dad51,10.0.0.2:443 +/e85d0e6a90433b5a64257469c2cb4e441f39d07c,10.0.0.3:443 +/8527e42c8677b3f8264a2a647c00eb3acc5d0207,10.0.0.1:443 +/3adbb76ad6ae8a5342a5458e5f41ac4bdddb45fb,10.0.0.5:443 +/96e7ecedc6c60f0b52869a98f9d192af1e72d329,10.0.0.9:443 +/430095d6c47a7d2a8073e73df1c694fc9065e8f3,10.0.0.4:443 +/475ce23ca92e83ebfbc781aa337063c6b034bfb6,10.0.0.3:443 +/3a2cd1836406244cf08a552f60734872cfabfa1d,10.0.0.4:443 +/47372a5cf6b640c32681f094dd588fa204839637,10.0.0.1:443 +/74d7ecd706817756952727e82a5933549d582f68,10.0.0.4:443 +/0c1ab68f17265ddc9a58577f2a3443b523508d2a,10.0.0.3:443 +/e72871b3b2e08e87443995810c8fc542ec0c3b88,10.0.0.7:443 +/20ffdb8b43d521aee3c81cbb668b94828bf3f86d,10.0.0.9:443 +/b9a4b7d390a4fb62ea6252287351954ce6935fd2,10.0.0.9:443 +/71f52570d9fa32e2df99088e44850fa9097804ec,10.0.0.6:443 +/9533af016368e423dc90b4e249002233fa3fcd06,10.0.0.8:443 +/23992435c60a48db0188097fb2f15826d99be05f,10.0.0.1:443 +/bc351d376bcd7338aca33255199bfa3ced51d66b,10.0.0.5:443 +/bc5a14bccb994f346069886be05ba91dc4cefacd,10.0.0.4:443 +/6a29ff380492b77fe69f9ec0851cbbf7228d62f3,10.0.0.8:443 +/99bbb0675c38e292e979110ac88fc7711edc92a2,10.0.0.7:443 +/786105dc60dfffc8e2ea58679a14fd4428570d10,10.0.0.4:443 +/d983235f5af78dc9b13a5d177a44c6a76c8fbb2c,10.0.0.8:443 +/55163e01bc026cab4cf6985c8c2583876680aa80,10.0.0.2:443 +/eb68e3145c8a531198ea2a60e7a4fe6cb1a2b78f,10.0.0.6:443 +/7996a420a8e08545583a8ca0941c1a0c9ddc875c,10.0.0.9:443 +/d8d3509e8df61eff246be4faa6630d5f11b81172,10.0.0.4:443 +/ecd74f84dadcbb5e7ab90430ba424a996a5ec50f,10.0.0.7:443 +/566ca8a48b0875bdf60d224188b0d952da6c8dc7,10.0.0.5:443 +/0497f891fd6d35ffc0ed28dd3ba17eeba1301fa0,10.0.0.2:443 +/6a406d220cbda7fad4facc04632fd0c12dc6d998,10.0.0.4:443 +/3a54c0bfc41cd0942d0e479430cdbc551e33fb99,10.0.0.9:443 +/a7a224cf1e0d9b4e5493b2f61fa53ad72de58b94,10.0.0.6:443 +/4121200fe9e4e7c2126c5d71d108e5119f37783a,10.0.0.4:443 +/caf4c4b46875bbfa63b9ab35a4bce5646ebd55b4,10.0.0.3:443 +/90ad2be0a253536ab7c3e961443a91ded0e66e61,10.0.0.1:443 +/caf569f41f3556f588fefc887d6ec0d454bfef8c,10.0.0.9:443 +/0e3c3e157ffefdfa94e785d4a55f4eb6fca4dc70,10.0.0.2:443 +/b0b8ba29e45725715f7982a05edac1ff999a7899,10.0.0.3:443 +/cc5430ac1220fe146e68e9cf6f174269d403224d,10.0.0.7:443 +/508445e1be7b2b4495f2eb5907530bb095e98ea7,10.0.0.5:443 +/d6169d6f2495da4842a67163dcc0e5f31acb1a0c,10.0.0.3:443 +/8d85ea8d983c0e35836b8a203660c6c919da645d,10.0.0.8:443 +/ee5128bf7f95196d6569af52c9d99c4d60f132c6,10.0.0.7:443 +/461d5e76ae9d26244e546eed7038efe6cf7d9bbd,10.0.0.2:443 +/9f97615d8e9dea23c4c4e841838404fcd8698d8e,10.0.0.6:443 +/c01e055c153b1d34d51c6598e2e1c3fc362d812e,10.0.0.8:443 +/7c087772081d068f5fd86960e4d89901f3c06afe,10.0.0.2:443 +/37e6e5c96c2661d244cbd243151f9c90119d5f4a,10.0.0.4:443 +/663e532894288bb97751dda93f151d85f6c16813,10.0.0.7:443 +/2b3904fd38fc96f184226c842f0643cd0596d865,10.0.0.3:443 +/14cb69e56f7f17a26f0bdfce16dec5baf539dba0,10.0.0.8:443 +/adbe42c7ca6dd63d976f49262cf3d1a27a5f7bb0,10.0.0.2:443 +/70b58e27d6eb735c3c82d9aec1f6608f2f32195f,10.0.0.3:443 +/e7d3683cca1dcc45d8e3fdfb54eddc9b34141d65,10.0.0.3:443 +/407e3958ae8b94172af71487050ef5dc0aeab2ac,10.0.0.6:443 +/4c5af9e573fc3e0120d322a950fcbb792074d670,10.0.0.7:443 +/fe92a691ba1d11d6f49e5144be9baee390cc27e6,10.0.0.9:443 +/298835604d35f371a68e93047c699a7c41375f97,10.0.0.6:443 +/2155470425069f357851ba81346b879a8193aebb,10.0.0.3:443 +/f55d45d265ec44be7ded0db1252281348fab75f0,10.0.0.4:443 +/798f665aa334e5eb9a49669785e94da933d81f32,10.0.0.8:443 +/ad8bf2624e7fc687b0130b61fdee9db2a2d865fd,10.0.0.7:443 +/d2002a4943563ca4c4fc66b4ad65aac4e1410b2e,10.0.0.2:443 +/a025e91fc9b3fcdc0491d0e4b4b0f09e322e53eb,10.0.0.6:443 +/b4a46e8f0ca5698b4f6dd201b87e88125b153ece,10.0.0.4:443 +/ff2a4976667b127ca1e3bb5027e8a836e56fd358,10.0.0.2:443 +/307086130cdefaa3d899fca3dd9e77047fff1cf7,10.0.0.5:443 +/558d5eeb99c6f1cfd6367fb101392072e5140c44,10.0.0.7:443 +/a1a3799079c1ef01be067c4c6a1db5b7fe6515b1,10.0.0.4:443 +/5b66932db9324bb9f8d6fc1f7be819c1c1ff43bd,10.0.0.5:443 +/1d69b12d308183c0d6432fb4cb8bacbc86193830,10.0.0.8:443 +/eef4c8b2ded3656c9d6174a72ffc487f0c769492,10.0.0.2:443 +/eb439a2cd0e4c9fdd95d8c0f657a81ce20f96a0e,10.0.0.2:443 +/b6f64c4a87c0d38417ce3dcc7a553a185df7f384,10.0.0.8:443 +/393d62711ecc6309a19a96ea73cffae546922f64,10.0.0.8:443 +/aa18663a595f369e048e33505f82d21ebbfe354d,10.0.0.9:443 +/759754a69ee3e4449bacd21a5866b8434b743cfe,10.0.0.1:443 +/c01e96c10fd69b430cf67edcc3fd2fec7ba30097,10.0.0.4:443 +/284e0c7dbb8e7da2a1fd7180f8d542fbf2410767,10.0.0.3:443 +/6f360332b72940cc117999224b5be35551a1790a,10.0.0.5:443 +/a83eee32d7132975d5d2d2848bc7881345e63735,10.0.0.6:443 +/9d8bfc97428dee1b1495d2568e5ac68b8ec7973d,10.0.0.1:443 +/9e09d80d5653ac55445b42c091ada230ed96cf67,10.0.0.4:443 +/6ca8d4fd764a20ca1b766f9d2a14b81011d80da4,10.0.0.5:443 +/fb89be9d12828716f95a60d092f2a028c876259a,10.0.0.1:443 +/29ffb1d20ace9afed20ce8613a2b636dae70638f,10.0.0.6:443 +/b569fa1c31949a8ab05a60939d44b1132534556d,10.0.0.7:443 +/71a89db0bb322607a2557b089a5d160fa574fc7d,10.0.0.1:443 +/4449e3e6404cecdc9a36ecff54babedc84619b1c,10.0.0.2:443 +/b26294352e342bd6e953264f9e14393413bb371d,10.0.0.2:443 +/a72621f8691cf08ffdc5884556d5512a5ecd1f6e,10.0.0.4:443 +/dc4732cfa991632b719def815b228ded96abaa1e,10.0.0.5:443 +/b908128cca7c859493155441660eaaa09b2fae80,10.0.0.1:443 +/d93c9304c07c8f1d2b6f6c89c882fc2cfad3fefe,10.0.0.4:443 +/8a0db29dc8df0b7845a9ab213d4bd8ac59a121e8,10.0.0.7:443 +/49559040bdef5e1a5dc8ee89f897b79115ef1bfe,10.0.0.7:443 +/23428c6b465b7c43629bc28fa1a7431c6e541778,10.0.0.9:443 +/9db1610e40a3197a5b8c2d0dee2b2ccfe4cabb92,10.0.0.3:443 +/1c6cf23cac024d126066771bae7af48ba141dfd9,10.0.0.1:443 +/5e89a982f7f165b47fef959e10c32afa1e01783e,10.0.0.1:443 +/52644098601b604c9e9e5e3d1150f13e81240fc8,10.0.0.8:443 +/1771afea4cf491711aa3b608fbd8b470306d7bc9,10.0.0.4:443 +/825cb4d51b986eef44d3cba31dd87c4ce3d9c159,10.0.0.4:443 +/83a6211a968db8d62e17525ce593c144ed7fbb4c,10.0.0.4:443 +/6a9abd46a919eed40be39b9d53bd73cb74acf540,10.0.0.6:443 +/12db006d907a255f8d61e5070d1a41defdae27ba,10.0.0.2:443 +/0cf51c79b9d115d7be8fcc104e2f51fee1a3caa6,10.0.0.5:443 +/6bbab5e098876a84c403ef8cbe9864c21f9bb0aa,10.0.0.4:443 +/5fc725bf869cf190f8ce82814d5e8e749030c8cf,10.0.0.1:443 +/859d96b17c00e528c07fe1696fc7ddfdb34c4875,10.0.0.7:443 +/a55638df8b2ceca37d24bb78826833deb633c79d,10.0.0.2:443 +/70ed2f73f55d4d00f9cf694a7f669c3ba11f89ed,10.0.0.3:443 +/b5c910057d813197f8353c31d233de719212455a,10.0.0.5:443 +/b602d274d7d8ff89505fb3ba364b6ccbeeb561ab,10.0.0.6:443 +/50ba092d17178b78c2643e798138ff5514d2d0a2,10.0.0.1:443 +/bf3244d6cec5c60aa29ccca799415354607b7803,10.0.0.9:443 +/7f4ddcc20818c0db3cdd8b440c269e33ef22a7c7,10.0.0.4:443 +/9dc2eaaf3539a7c0a5b97be1f722f544539c6257,10.0.0.2:443 +/c5359e50f3c202f5cd5c096bd15d757ba659e815,10.0.0.5:443 +/038366c13ffa60a0d9ef4bef212e6e7354a6bbfa,10.0.0.8:443 +/9e40dac2f57fe43878519a83af3b75fc2e590217,10.0.0.6:443 +/9b2c05c1d561f86cf9682673628dfef2160650a8,10.0.0.5:443 +/78a2ea21a979d1d0c8e07f0185f358fe58393c12,10.0.0.5:443 +/83d46e2ff9cd7bb557c1b00533a0e4f1733df84b,10.0.0.1:443 +/29bf196e578a83824c55b0f78ceab36b1eb9c82b,10.0.0.4:443 +/61249cd3d39f4dae802db5f0a875a5a4a8ad191d,10.0.0.1:443 +/c7c7dfdf8e9e68d5540aae13b2cbb5fe86c1b965,10.0.0.6:443 +/4be4e8d7897f7d9dfa210bd236e9bb45454fea20,10.0.0.9:443 +/cb5ed875dedef2013fab5b051a8636d10fef56dc,10.0.0.6:443 +/e12ec1f2b657ad0f7988db38254652e153525ad9,10.0.0.7:443 +/9ec5a64e415451efcc8aa7648b284774361e03eb,10.0.0.7:443 +/3a6afe9c8e8f041a59695055cb7733ae254632bd,10.0.0.7:443 +/e3393950cb37481a7b00cbefc3298d14aeda0807,10.0.0.3:443 +/7c6e41537748edb49cfc56ee505256f40935a99e,10.0.0.3:443 +/6bbc445ff57bc9c54407f31616f1b23bf5ee27ce,10.0.0.5:443 +/99ba1e8f21532dab31caf0731f1c5edc8455550b,10.0.0.5:443 +/725fbb619d38c436bb88e28d5219e720989ab6db,10.0.0.4:443 +/7b519ba8928f440bf01ac1d6b98611fb59bb1c89,10.0.0.8:443 +/2ff8d8dd2a37ff1cb34692a00c7fb7d1c155b419,10.0.0.3:443 +/f76abffc1a71b95e7969cceaad57429672beaf68,10.0.0.3:443 +/fe58d58e116026db4cf106ef57732e1b629caade,10.0.0.6:443 +/45549ca0d7c95e97c299b58b03ecf1939e140c9c,10.0.0.1:443 +/93695453157442d799a007d1710f7dbf968be8f1,10.0.0.9:443 +/ebe69b2ea9db3e66a2157021a17f852695eab8be,10.0.0.4:443 +/a885aecaaf297eaac5c98ed708fe6a73fc9273b8,10.0.0.2:443 +/2859256b987358b8d2ee0c81b5494cde3a98d602,10.0.0.1:443 +/d19ae90e456730d2db6b36c1ed1a45335b368fc1,10.0.0.1:443 +/f16f2e87bee62b1523dbb5824b5dfe338ec67704,10.0.0.8:443 +/fcd5f91888014decb190a9dac5fe9fca7ed8d70f,10.0.0.9:443 +/3ee610b32554b5f7c27d40a52bb982378ceb4fb6,10.0.0.7:443 +/21cc5cb90ba59b6b743bc437f0f93c45d21aaea9,10.0.0.7:443 +/8d2bffec729dd863e6dcdaeaefca22d6e29403bb,10.0.0.2:443 +/2ce6b015ea081b69a3867f7b09b753f83fbd4b77,10.0.0.9:443 +/64fcc9606275d6a259a084696318ab704a81932b,10.0.0.5:443 +/0984409349566b9bda3f5ff3b0dae93c6979969c,10.0.0.6:443 +/2b3775815cd0064c1603ec6dfe62b9ff54180638,10.0.0.5:443 +/563ff0fa8762400c92ccb700adb6ea6a7bfb0d33,10.0.0.6:443 +/901f7c9eca3f038ecf6a684a2c46b827c24e8ee6,10.0.0.5:443 +/3dbd852fb7f851fda48f742488e51dfd8d4a472e,10.0.0.9:443 +/a50ef8903707c1c5d7158a851d636ef65e198e7a,10.0.0.7:443 +/92603aec7e7f7a5847f523c336bd80d786667d6f,10.0.0.4:443 +/a941b070f313629549a2874fef17b29b25069214,10.0.0.1:443 +/9a80624738b37b3a3d6b0749feae2bb82d0672c0,10.0.0.5:443 +/f863b682f5f260f4762a14831d949c5dc9bd5f28,10.0.0.7:443 +/d41f6919aa10ee037b4a69df874de03ccfc6432a,10.0.0.4:443 +/e995303d36162db8650a2802ce0d52263c29ec0c,10.0.0.1:443 +/7823ceab6e649edbb4f99d62282fe00edbe3acca,10.0.0.2:443 +/bfd84f41dfe1d4470730d0aa41eb73b9d7461503,10.0.0.1:443 +/53f7534ee600e63d0b32bbc1f2f9e4794373c4bb,10.0.0.7:443 +/26f4c39897fdec0b453bc15860a45137064c4ef8,10.0.0.8:443 +/7345179e10fa47e31faf60e165e7802f31315c56,10.0.0.8:443 +/d47e4a2590ff8d5dd916d826adc3c20b9224a3de,10.0.0.8:443 +/8ebb8b58c53468143f882b186fb64ef14e962c0a,10.0.0.4:443 +/7fa7b9821ce360682b88b07fa27158af8d4b10bd,10.0.0.8:443 +/7d3b908d960f61cf4944ac52164eaf9890c17c47,10.0.0.3:443 +/3900dbeff282a20a6dc0b450581ae27f44230f75,10.0.0.7:443 +/327a041d0576f11ba4c0fc677a8b1fa7cdd5b215,10.0.0.6:443 +/20450e190c6b829846d1a67e43b2e57cf7e5b472,10.0.0.4:443 +/d6d97ddf81c5a8f4f11b87198a3f8e75814d09ae,10.0.0.9:443 +/48a468d706a7cc4b07c0e74695a9c2f64012b02a,10.0.0.2:443 +/35903e2f79bf054b45d9f342642d488b85ec086f,10.0.0.2:443 +/4198c731ac8a3638a955ae891498ea4071b2be10,10.0.0.7:443 +/575be0ba8f57b2650f53499ab19fcf10aca1a467,10.0.0.9:443 +/c211460d038ae3aeb286e759dbe99b9084c56fc1,10.0.0.6:443 +/7d5071d6ed21ce66d8887ee6f88bf8b3145d417d,10.0.0.4:443 +/77435459761c415127dac0d314fe73b728e93816,10.0.0.2:443 +/16a401100431531a7cd8528d6ea8f957df584e4f,10.0.0.4:443 +/9b9af306b3fb801bc4cb127118aee22f4678c6d0,10.0.0.2:443 +/4902696d40151e903ec5bf810f2b82af7bf92799,10.0.0.3:443 +/3207830ce45f38a326cba44a2bbed7ea7009e7f1,10.0.0.8:443 +/002655dd3e576dd2be046915f365ee7947c77553,10.0.0.7:443 +/8a316dc9861784929ae9283ff9edf50fcf2abb77,10.0.0.7:443 +/8b2639c2cf4f75723ae219f9c8a60779e93b3a50,10.0.0.2:443 +/d135a3f32a0eaec83386f9b8167c8b351fa0f9cd,10.0.0.5:443 +/3cb5d50669030262c50b916b5e5f0ff112a23f87,10.0.0.5:443 +/791d86b7b2c2860da849c6e20006b3f5f92714a1,10.0.0.3:443 +/de08fde7bd93bfd844407842d09bc163675fbcbb,10.0.0.2:443 +/0576ce89f317cf54673e20eb664bb8992c975a71,10.0.0.9:443 +/fd7244f5203e2985e6c65ee07686cbd2a489e21c,10.0.0.6:443 +/233de62d4ed3f6e6a8d847500ed8be500970bd0e,10.0.0.8:443 +/8b8ec68415a7a9cbc426c23ba98ad165a434fa1c,10.0.0.6:443 +/ec4230ec3e8fa6600907e777c94f2e59382b4542,10.0.0.7:443 +/bd220769eedf9c7efa641de459810048891e3dc6,10.0.0.3:443 +/9165254e59f4fad93b93a02210b25dbcaac4e0be,10.0.0.1:443 +/0adb6ec07cfcd61534a065db496c7042e97391fe,10.0.0.5:443 +/39a5c89484e21a243c7061d39dbd236c80d4ede3,10.0.0.3:443 +/dc560955b3b817db3e79e37255cd18bd66a39a22,10.0.0.9:443 +/9d433be2cca7907dae1b8c24900edc5adb6065bf,10.0.0.2:443 +/2531e51eda6b68cc2faa7a09ad032387b2676523,10.0.0.9:443 +/d591b928b7f89b00458ea30ef6f4fd20cd7e41c2,10.0.0.7:443 +/9720475f8d148f70245ade435243bfba5a1ba559,10.0.0.4:443 +/2544d73a3c1b0f04829284a5b425607f4f61ced7,10.0.0.2:443 +/e3af59332ba621011d98fbf2a38c8a0b69b9ca79,10.0.0.5:443 +/d8f4c58c0db28d7368f453d41abd59f6999b3ccc,10.0.0.8:443 +/8a6180a589aec21a274a3f47781ccb1311b0833f,10.0.0.6:443 +/83aca0a94c4883adb8e7ff795c1008ed59052691,10.0.0.7:443 +/adc1ab7741effd4ece0e832c41d1fe69f5e1805c,10.0.0.6:443 +/35a50236b60e680d3d968ad3857525a8649fd6a7,10.0.0.1:443 +/30495b101ac5318458d74b3a286527e164efac53,10.0.0.9:443 +/e2067038a82745a65406516f15817b63e328a825,10.0.0.2:443 +/754c3e717cf1640d11ee1ca113571fd0ae55a0c2,10.0.0.9:443 +/c4462289d891b8b0c0783041044908bd347a27a7,10.0.0.1:443 +/68129869b04bc2255d2a17ce01afb14f1be73032,10.0.0.3:443 +/683a4f8e369c5c3eeb85f0779aced10809bbdbb8,10.0.0.8:443 +/8da89d7686976482713413835c889a7f289174a7,10.0.0.3:443 +/511bef26cd42422c6f0c9bd33714a07b06dbb3e1,10.0.0.1:443 +/b871c4e41b3eababead2aa4dbea87fef7161affa,10.0.0.8:443 +/808da0dc7d4025a0858eec92ac72e9ffbff233c4,10.0.0.2:443 +/6fee636398f916c4ba0074fc327f7b3dbf683a8b,10.0.0.2:443 +/03ce09b1a7c7ae719f66f489841d0ff11635ffc5,10.0.0.3:443 +/8653f568fca5173d6d274060692912676709981f,10.0.0.9:443 +/8f8402b8bba56124ec6de0552c1844bd76bf72ea,10.0.0.4:443 +/2c89ed1b71a52c9b0a9fa7909dc87d4d06237216,10.0.0.1:443 +/5279a73f9dcfa562f13180791932598ed8a067f1,10.0.0.9:443 +/456482cc45669a59fe8af5e49648a8079bc35c06,10.0.0.4:443 +/90350e060dff6a507e69bd80c38629a2d9bf12b9,10.0.0.1:443 +/2d5c624c50ba3ae06782861bba176e9b2f45f529,10.0.0.8:443 +/67077af97e65ae301e88c6cd0e87c7ddb68fa9ef,10.0.0.6:443 +/f017e954321efbfe4046942be0a1122d9be81d52,10.0.0.9:443 +/0b74a181ce4b4f43023e4bc0acd7770f2867572f,10.0.0.5:443 +/f40f8509ac9f73516224825e88a220ca02db2d81,10.0.0.7:443 +/c2f12ede0ced03c9357a4fc5e05e9af5652433c4,10.0.0.9:443 +/d3ec86f1dde7e9c416c88ddbabf854e21decec2d,10.0.0.7:443 +/ea29487fa7e1c9e79ff0f257bfd8241736ddab9f,10.0.0.7:443 +/b8f4ec5dee59a8693710cb95e1734900d7b6b076,10.0.0.4:443 +/d0be164540802b86de0762ea266e03c8859ff70d,10.0.0.8:443 +/cab9ed312a56db577bc36e4c2f52e84f8abb09ce,10.0.0.7:443 +/62dfa34389964b03792842c09adce33e7decc837,10.0.0.5:443 +/f653827f1289ae68efd5a0d057fbc172f8352842,10.0.0.8:443 +/dbd9b9cf5affa501ddcd1a19eefa4240e311f94a,10.0.0.5:443 +/3e74e167ef6393b6544b4e75da97f30f6c2e6477,10.0.0.6:443 +/d004b31247c668c439fc8e491f71a69dfd35a55b,10.0.0.6:443 +/17e79540d401ae73e7d666444feececf64602d23,10.0.0.8:443 +/06c9cb78908d623842c4a7c7baae3d55009ffc43,10.0.0.1:443 +/64427a2e50196a34670b9de8a4aebe44cbb26cc5,10.0.0.2:443 +/802741e276f10186ee9b63d47af006e8bc3de516,10.0.0.1:443 +/10cea480539356be3f2a2f14c05f057a60ef9b10,10.0.0.5:443 +/17d5b6820d78727b781be06cbc7cd2a9be650794,10.0.0.8:443 +/1c0f7ec3d8919ffd2ccb3312fb7d6d2e15cd3133,10.0.0.2:443 +/ef3afb81312d46b826f033d9adf0c730996e7992,10.0.0.7:443 +/080e45e7955e797bdc906af2fabeb8fbf2ac48e1,10.0.0.1:443 +/c043b1a590f09716da25328fe0573c8e2e9c0bdc,10.0.0.9:443 +/df604b478f31f11b4cb291b1a393749ce4e72ef3,10.0.0.7:443 +/32a8a7a0678c834e2cc7ec0584cd193fd1fd91e5,10.0.0.5:443 +/8303fbffee5f38f8eb4a51f3c1255de830abce34,10.0.0.5:443 +/24c16585ac0791c7aa1d8a16bea2fae9e7008cc5,10.0.0.5:443 +/0059d4d899d1e961f249a060d91e932a89bc9b4e,10.0.0.4:443 +/f1edc74510b17b10cdff8801776d4eaf72a1cf0c,10.0.0.2:443 +/faaec2162ff441c490fd2dc0640bf2c941438995,10.0.0.3:443 +/1159fc0cd3e683f92fc649aad3a4bcc34564c3a3,10.0.0.3:443 +/2ade445523d26c3b1519e699590939011036217c,10.0.0.7:443 +/cc6b2c1b20ef1a63adf2afaf1207ecf446fb5719,10.0.0.6:443 +/8cb65496c9ebd858fb1101d85cf35467c4a0be17,10.0.0.8:443 +/38a5bad44dfc1ee47585be27cbd9598959ea6caf,10.0.0.2:443 +/c651109ffc0f2270596065009642fe3fe0529e60,10.0.0.5:443 +/b71ae7d9c9d4b67677fec2e630313cd01cd130e5,10.0.0.2:443 +/088d49f180d9a2211708c95d5e9d6986705c8d7e,10.0.0.4:443 +/8e44a5bd8519aa7b6d85f01e7b01e1a2ca236b6c,10.0.0.6:443 +/2526eec4890f03477261584646a0ed6def65f8f4,10.0.0.8:443 +/3a70dff8627a20ee109fa8241d7da762a02e02b3,10.0.0.4:443 +/eb999a0198002b52abca1fd424a44013989e1403,10.0.0.4:443 +/22a12a10268929d77ef8dcdea96f8aa69ab92d8a,10.0.0.7:443 +/b467e43c88f0e69b52e3d341fcee52198f90cf77,10.0.0.1:443 +/c5245921b3f6a21adafd6598046957086edfbeea,10.0.0.7:443 +/6229b444f64a7529dd956877c24b2d149a1debf7,10.0.0.8:443 +/4f8b5505d9e817b39e0b68e196c62240acd07306,10.0.0.7:443 +/8699dc12aa122266013234df69eb5e14d6282174,10.0.0.5:443 +/094dc8a3111d132d294030b358c23e63ff2ad680,10.0.0.5:443 +/3ecdf7b29e567a94e1548f0884f414af6539f974,10.0.0.4:443 +/abb4e33382452c2f5c5d3d0b89f11cc2d497a3a9,10.0.0.9:443 +/696adbeedd54670bdcca6356597b580dd9c4c42c,10.0.0.8:443 +/940b2a895c5540f5dd079f7ba930962980bf4e77,10.0.0.7:443 +/e3ad3f730ef0f82530373e966fc35e7521ba0fae,10.0.0.5:443 +/e68f238fe1b9f3ebffb102e98ee2d958194f0c3e,10.0.0.2:443 +/9e09afd63284f764392213c9f282e59c859ccc2a,10.0.0.3:443 +/40d1f0a5f73460d07f777d16ce0edb5215e0af5b,10.0.0.5:443 +/e641c93505fff2131a1bd6a2bcdeccc7ef56e108,10.0.0.5:443 +/51f5ef58442e9176bf4ab0e3d2a31e3919314467,10.0.0.1:443 +/5c752e882a791057babbc7c9d0fcd6f98249a90c,10.0.0.3:443 +/1a93e7ac8192b94e62372c526a858203ab55f82c,10.0.0.9:443 +/4f00d996e102527cfd906afe596b1fd20b9587e2,10.0.0.7:443 +/cb33e35ff6809c1d9e87af168853c8779949df28,10.0.0.1:443 +/8238f15b1556e4c5a2cfd3024ca22ca0cc38cf75,10.0.0.7:443 +/4d9af33ca789f5675e0b3b7db89277d9f07fe487,10.0.0.9:443 +/31f11a12c1729fbf56e7924ddeaef596d9246ffb,10.0.0.2:443 +/dc5b466b915a7eb13aa3c28a6df11201defc4776,10.0.0.1:443 +/a83dcc91951b9b9bfc86dd414ab2378dcb74bdb8,10.0.0.8:443 +/68dcee7d8e5b5bf81c1acdec7dd97891ce3aca1c,10.0.0.3:443 +/661f218fa06f2b92f22e0ab81731ac4029f4adc2,10.0.0.7:443 +/cd29f2138dc83eeb5d4f16d7b13d0c81483959a2,10.0.0.9:443 +/d34d0b880b1e7499c2133f06e9373f5ea4e841ce,10.0.0.6:443 +/1fb666f29371b67fef8e44a9322c9e387261fa18,10.0.0.2:443 +/808b776dc196d1759afc93646bbfca2c3e8074b3,10.0.0.2:443 +/20888fbf1def43e3123b0a9e4eba7fd7d5f2a410,10.0.0.4:443 +/d7cd6d38cbd5b94c432e15cd2f7502dbb306d757,10.0.0.9:443 +/fc018aa6e4835271d8cd024ec3943115cf4e94b0,10.0.0.5:443 +/27dc43e54f5d904746a36b482123346f44293b51,10.0.0.5:443 +/ed60ccb18540ad211073c281aee0dfc31ccc942e,10.0.0.4:443 +/5fe5f6c1b4d13ba7200d6a89c456f60eb36690f3,10.0.0.2:443 +/e2e2680aff762da702475c5307a31779cab5595a,10.0.0.4:443 +/b9a3d570d0f60b98af06bb2bb8f20bfefa8bc4f6,10.0.0.2:443 +/6b476c8bb82dcf0a32e3999826a788c48fe83e7d,10.0.0.2:443 +/80a371eb8a4a18395199455f8bde883ee548e4ba,10.0.0.3:443 +/de87fa6ef77299db61ac048fc87ce6e3e39934bc,10.0.0.3:443 +/52c42c3136fef68070d143e62366e47b5de255cf,10.0.0.4:443 +/ce7ea948d35ff4f7409eb507cfd3fc6e3b7cf30a,10.0.0.6:443 +/53e772cf7a78bda717c98a08b9081a40a03392da,10.0.0.7:443 +/9bcb6eeb362e0f6c8c04325848cd93f1a4fb75b0,10.0.0.4:443 +/2ef946b7546ba83f528e4af5f60a585fa22cd5e9,10.0.0.8:443 +/a964b047adfe079bd4f39c5d79daac5317611bb2,10.0.0.2:443 +/2cfad7113f585441f4fd054df57e08aa3f7d3441,10.0.0.8:443 +/f5352d8e5f1e080bc70c241a8e65cb48690bf44d,10.0.0.8:443 +/7108e1b4b2a8d73f6a892bf394d6db68eab4b06b,10.0.0.8:443 +/5ce086abaaa907ea06ad20e029375d0a469f6688,10.0.0.3:443 +/e8c9dabb0ae5ff95db4dc58d5e5ad8f49dbe1467,10.0.0.8:443 +/3ea868d97d0f366875936dee5944d30f133a11ee,10.0.0.3:443 +/4c34d28c12494292d3eb30c70e2ee5158ae45bcf,10.0.0.3:443 +/b1367bfef3363e82dce33834cccd1b6178dd4e01,10.0.0.5:443 +/e563665cf03942d218f963ac225b9f65f6f47e44,10.0.0.4:443 +/ae4a64bd0638678f1f19b31f1610e800510308a8,10.0.0.3:443 +/581ee1ca9a6cad9786fe37cba35c4809410a902f,10.0.0.2:443 +/d8065f52a7d18810daaeef95f724c63a843f9354,10.0.0.7:443 +/461f1d57aab6fa3c1bf72f5aa724ed264647c4d3,10.0.0.9:443 +/70335780553fc4499c3d7b903b7e6fb6f06bc47b,10.0.0.5:443 +/9733a49859bbd9b971475bd40e4a2bf7d9bfd203,10.0.0.3:443 +/d3d04d2aa72354af7b52b344a07dcd22dca462b8,10.0.0.2:443 +/c5ea5378e9a319cc2a455d6e296dd3ca5aa12477,10.0.0.6:443 +/f20e309d5d7d97489cc0d5ad3737af32008968cb,10.0.0.6:443 +/33d387521125b7825c8480755efce6e298e936a1,10.0.0.7:443 +/a99b72b250bfb58ddf9d6fa9f805e2873ce0c229,10.0.0.8:443 +/c8997a1855b1b4d8c6fd0a9dc21c01ffd7a1aa0d,10.0.0.4:443 +/43b0d060a125208528829cbace2759c05655c8b2,10.0.0.5:443 +/e609d51a78b4e83d2b778fef69d00f07a66e586c,10.0.0.4:443 +/e62b9cead57079d3290ac764079b6466f7340c9f,10.0.0.2:443 +/d31c487a361be7abb28a0b872d87fb41a907dd2b,10.0.0.9:443 +/b17261bb106af0ee0cc6c710439eb26135dd5f5d,10.0.0.6:443 +/14d92585f8702ef9ff0fd000907f00ca1f6a458c,10.0.0.6:443 +/fe79953554bb5aaf34adc6928060af206e8fa993,10.0.0.2:443 +/cefd63669258fb86a920a65d6fd1d511c508d954,10.0.0.6:443 +/143c0259d1759575c859b902f4e56ef478624989,10.0.0.3:443 +/50315f90fc6f82d29d925e3947ba7c32f19b5611,10.0.0.2:443 +/95428f6c4dcfbb2a0c17a5de4861de01bd3f325f,10.0.0.7:443 +/5ae459d770c6446c4d33104734b7a0293b48ce32,10.0.0.1:443 +/7078c3416e5b78c65c318b3916b5be6d92896c88,10.0.0.4:443 +/a489b81fdc1b4020b4bd3af8b759466c9023cbe2,10.0.0.4:443 +/6a6b490f616c8b52c4548b3c7f46d527662bcb5e,10.0.0.4:443 +/a607e4a8ef834a9ba7575729460fb697f5247cf8,10.0.0.2:443 +/0ea9ba29578fd164f5942d037366c3c6768bdda2,10.0.0.4:443 +/d9ba5006e81ac5128c20823155f4cfe991598179,10.0.0.4:443 +/b691e1e01b2f64c9c584bcec928345657b95d293,10.0.0.7:443 +/44710040aaa84b18986e3f16bc18e3c6ae63169b,10.0.0.7:443 +/9ffc3d11bf5b67e6e316646e64f1b703dd79bd94,10.0.0.1:443 +/1e2905288bed5c9b4c3f03cd6daeede56c2ffada,10.0.0.1:443 +/1d54d79aa491a886dfda64a7780b04161d1481a0,10.0.0.4:443 +/318d2d5e7b7347704e8a0552cbcb01adaef758a9,10.0.0.7:443 +/22b7965fa39aba2195e1fdc1e845e01f378c3d51,10.0.0.8:443 +/3cb017f3b5edf03f68ba84c5e8671e959273dd69,10.0.0.5:443 +/60c48c28f0ffdbe1225b02ef2fabd26364126d73,10.0.0.9:443 +/50330c984bb2167761149c43868e27401c678dd8,10.0.0.7:443 +/ee359ac7b7e76cbc38f5a70cfb4a7323161e8519,10.0.0.9:443 +/6dc489dc87cb4c097812bcbffa666f1d3a06920b,10.0.0.6:443 +/b084378cffd7ba654dd33d13ae00915abddb5acb,10.0.0.8:443 +/de8d58cf5b06da64685d35ea3d85692dd98443ba,10.0.0.2:443 +/926ad3a9d1411e8f959f8a99270e534c2fcc60e7,10.0.0.1:443 +/6f5efb290d2fc1f49af390123a8d45242535ba6c,10.0.0.1:443 +/be0651f76c2d6b3fea26840eb42ff84603fdeb91,10.0.0.2:443 +/664dfe003d4a68cd9502992896f6698ac2930b2f,10.0.0.2:443 +/d5c1076ec326bbbf73e06d110ddec314bab4901e,10.0.0.6:443 +/12bb31b94377990b52936138e755d30e1df5c4ad,10.0.0.9:443 +/e4e3d4a7766b7ef0038e05c72d7c60c853902d78,10.0.0.6:443 +/f1ace48a0bd8b225c5b05a4f310ad6146caab520,10.0.0.4:443 +/d6f4e19fb0dd901454337ea0a62a671f7e731b1f,10.0.0.8:443 +/e7e149ae5cc3b8d3432a74d2a5eff884304f149a,10.0.0.8:443 +/55f9309e65ad34333635e2392170a2d9e8e80f62,10.0.0.4:443 +/90cc256a42fe5c65d3b1c261b6713aac2d668405,10.0.0.1:443 +/b9530da73b2c2287f52955290ec2dbc0e2cd197d,10.0.0.3:443 +/45a8ce0efc2197c63f1b0feddd1d0ea3fb62cb62,10.0.0.3:443 +/af5eb18f6287ead6b0d8d9d4f740916eef27b921,10.0.0.9:443 +/7d4c22a4d647cfc95bc563ce3f0d56217623ea40,10.0.0.8:443 +/6f6d1b8ccb3515ea7a4dfbba821b7e24f0af890e,10.0.0.8:443 +/448153aa0816ea4c11fd433e4011279a9e911319,10.0.0.9:443 +/e1db3b77b5891866a1bb0f136e9a3b6f1a8fd7ac,10.0.0.4:443 +/8e5ddebd1bc756119aaa55d408583bf07c6947f4,10.0.0.1:443 +/cb7c13c7fd7c12a0226dca64d01f154380b26ad5,10.0.0.1:443 +/5b5987f50249480e48251ab6f848580d4dc69372,10.0.0.6:443 +/a81f2d7b7e3640837acc6d0532aa52974371215d,10.0.0.6:443 +/4fb00e1ae798e403dee221592d1b63d8a23ec7ee,10.0.0.4:443 +/06ecb7c80ee19fc3dcdde75659cbf0fc1d03d5f7,10.0.0.1:443 +/4c3644f13f8b64a3919d4c8a53387f102f8efbf1,10.0.0.1:443 +/82d78d0be6134b4da73a81a442ce4c5277d23d8c,10.0.0.3:443 +/968765803dd3e6461c0ff78f95342c0c113e4991,10.0.0.5:443 +/b49bd6e5e66970eb7378c37dde945cf542601636,10.0.0.6:443 +/7789c5109794ebfb0fe72e3bdc2fc29baa58e537,10.0.0.8:443 +/29857840ad23d55c82c93cbf7971b416e118985b,10.0.0.7:443 +/9aab0c35922eadd6e1cf5512af5272b20ff87638,10.0.0.6:443 +/094cd8c29e8621928b163ba64c52752f9dfe5ce2,10.0.0.5:443 +/f56b7ae1b06eff812326334a68cee675f3bf390b,10.0.0.5:443 +/a5a029d6c0f758aab2eb8fb56594a0e2e118a8a4,10.0.0.4:443 +/fe56c1fc75e419f220ea6bf06af6f5321c895f6d,10.0.0.6:443 +/0d5b4bab87051120251a86b92db52e12582ffdd1,10.0.0.1:443 +/34f43611722818ef7baa47b8d07067658765aab7,10.0.0.4:443 +/e70ae66289144a1adae07ea70f507767d57e08d2,10.0.0.9:443 +/3f10a40788eb0581f47d1f7ba7c57cdd6beef74f,10.0.0.5:443 +/2d58723eabb6c5adfb1fa239e34c30da32f117a3,10.0.0.6:443 +/efc167a6366a437ba465c1fc71ec28341082ce94,10.0.0.3:443 +/0bfb80585b1a0fa49c2c863ab39dbe06599681b0,10.0.0.5:443 +/57febded047c2a5455d7662d4967ac0666fb58bf,10.0.0.8:443 +/f06e91822c1eb12e9c560453b2947d45c961ebd5,10.0.0.5:443 +/2292f8823bd4364769bfdd6ef106c6186082a345,10.0.0.1:443 +/dd37a086d19829dfff28195b3b63a197193f154c,10.0.0.1:443 +/74f336292ef253b07abdce03a0f0d47ac6482062,10.0.0.8:443 +/22eb9772d6538887bfc57bad65ef8a72d7ede1d6,10.0.0.7:443 +/a1df865f8909812c4a83e29efe67460c6756bc17,10.0.0.5:443 +/82f35bed949dc360e05c3a60f8d30970f9f30fcd,10.0.0.7:443 +/e6d5dc89bb8d677be8c2dc6cc1f164a254e4436d,10.0.0.3:443 +/dc64f2b2db6cbfb3129d83d0a5ca4d18d45ac35b,10.0.0.9:443 +/d7b8e1a5f574730502d6328885ffbe76a93726cb,10.0.0.5:443 +/e98e4eec7b294b9be385e3f87f5a5a86c4b202fd,10.0.0.7:443 +/7c78c7e886c0a735c2043ceffd442e7a3df6de18,10.0.0.7:443 +/53fcdac505c2e9d61d3df43336fbed32d4d52274,10.0.0.1:443 +/e4e48c52272aeb71e75533c0447168a17dd0a8ac,10.0.0.2:443 +/ea3361f8b5124bc65fe4273df0c03177066e8f1a,10.0.0.1:443 +/7db8dcb86856a592128f019df1696d1bd8f0729f,10.0.0.9:443 +/b8b33e4984ab558303db0b2481d8b6ab52bbeba6,10.0.0.1:443 +/a61755fc46e10c87e457c3fe06a46ca261624b33,10.0.0.1:443 +/74e9e54ea37b089a100561e9c89852a47d738657,10.0.0.1:443 +/7daddba4e4b97331ab3e47976295aa522c7622bf,10.0.0.6:443 +/9a4a68b8ccea854a22b1064b2b647270161df2b3,10.0.0.2:443 +/5b42f6b8ac65a644c8203a0e1f44d452653d24c4,10.0.0.3:443 +/2ae53235a7dd1ee0ae2e0187969e33daae6466e1,10.0.0.5:443 +/cedffeffa4fedb95411a03e7abd3e7771982e5b8,10.0.0.6:443 +/56a5eb3af8c0de47c03da5850dd5a41bca391bf4,10.0.0.9:443 +/8770f96efc90e2c044835618c1fbc21f784148fb,10.0.0.4:443 +/77b4bb2780a93a397dc469fd804b05a3fe6443a3,10.0.0.3:443 +/666b5de9ea6b7768dc6638f1426b5292465de061,10.0.0.1:443 +/793233793175f196f861bbd781cffedc1dfe1649,10.0.0.8:443 +/6e6c4ca7b99531e8ed151f023d3f54dbc1aa72b9,10.0.0.1:443 +/a144b632b672fed3d6d3cdc98d4b664993ae2c3d,10.0.0.7:443 +/074d306725d881f0acd57ed9f08ab85976adef84,10.0.0.3:443 +/c9c04880224d2977fa60a0eef06d1c795fe6a423,10.0.0.9:443 +/d20ffc4abee9257d5dc1fca42c53f6db63a2a664,10.0.0.6:443 +/316bdd0350db3c95c148e66a291f23d382251f92,10.0.0.3:443 +/a91ec91455f9c64ff666f271a7697c41b6777c40,10.0.0.5:443 +/ebaa896e268efc129dfb87e51c06b69c0d3d10b5,10.0.0.9:443 +/baa5d67516c1a6346ab05f10821c7ad25d297cdf,10.0.0.7:443 +/e8a049830e420d8502891a00eb55982ba0e9fd8a,10.0.0.2:443 +/2885644f1735ca86b002e623d2ea6824977b3386,10.0.0.7:443 +/85a0370ec94aca8895951954ca810d3b06b1f7af,10.0.0.4:443 +/4eda15a4a13e529b2aea970a1b3591e537b8c906,10.0.0.3:443 +/bfa3f4f77e6f65a87448d260eb7647b6e02cc8ca,10.0.0.5:443 +/599ca6d3012a3aa53854fb5e0d25c303d622e8d3,10.0.0.6:443 +/2332508d304442b6a6b4cebe557be963e31aa07b,10.0.0.3:443 +/0c32f97e9ca195ab9eba167702fb7af9f9809bc2,10.0.0.6:443 +/0c4ad0a80bdb18e6a82233a8ebf2103e72cda899,10.0.0.1:443 +/56e0aaba9e15a92b4ef584d3e8ebe091c52e2f60,10.0.0.4:443 +/0adf617e084382c2a23249aa985cd8b8acdaa65b,10.0.0.3:443 +/ed18addfd26398806fca2a8a2fe14bbe090fe0e0,10.0.0.5:443 +/d1a2ba53f3b93e000e644d5b1ad8c6854ea9f65d,10.0.0.6:443 +/7107620d6a0be698aac43ffc25f86eae6f53a2e1,10.0.0.8:443 +/3e4ae6d93c0251c47b243273c3cfa6a8e75561f1,10.0.0.8:443 +/d4c0a3bd89b4dddf0a6ea0b0527290ea09eb5a9c,10.0.0.1:443 +/152e9ed59081b05a44434e96acb10841a6ac4913,10.0.0.9:443 +/37165697fc6ef78a2f77de34e332378708c645b8,10.0.0.6:443 +/a4e2739e0c203344e3243ecd1085ae55c3e80e7a,10.0.0.8:443 +/23795bea08d22a82aeb2fdde5cf561d439358287,10.0.0.8:443 +/dfec4908e467ca09908796e4adaa92aa9483b5c3,10.0.0.3:443 +/ee0b2b4442cf36ae3c29d01c815bfa6cfe48fdfc,10.0.0.1:443 +/cb78173624dc4cb41a7b0237d17f7af6a083ea18,10.0.0.2:443 +/d739f678a0da873018a2c748a92ee4719fce3a0f,10.0.0.4:443 +/2323b27ff2ca01083ac32f731fbcd4d100e93e19,10.0.0.4:443 +/d499e2ec08b34a0bf998c14c887b383265034c9f,10.0.0.9:443 +/143084dfd65a8bdcd57fb64651f96008b040087b,10.0.0.6:443 +/97eaf99e3029d498617ea5154d783a7eb5c70c48,10.0.0.4:443 +/33a3ea00c963b4f990846722d410b76a95b8de58,10.0.0.7:443 +/74102b50e78c7af16e679839dcbda2e0372b6007,10.0.0.7:443 +/98e74ce3d20c7897ba902ddb716d77ccc12d7184,10.0.0.5:443 +/04675a8dc4351a5aefbd2ca04b6fc110d396a968,10.0.0.6:443 +/fc9d0c65157c42a6e4faaaaeeed021e97eba2829,10.0.0.1:443 +/e79898b6d8400872a5e147b49e9a639756cbe950,10.0.0.4:443 +/383d327d7129f3b712ff73766f8ce42c74e53b15,10.0.0.3:443 +/210ecfe8a674dc8a5ce6e0ff2cecca5f78769a23,10.0.0.8:443 +/0ceddf293af83e1c0b20a2f951c249dae970dac7,10.0.0.1:443 +/35f0c2c9af248df96020a501f0cd01c35750cbc0,10.0.0.8:443 +/52bc55a205fa328543f03294d9ed5417820fa601,10.0.0.6:443 +/3e4431ffbb010af04dd776032e7ac6f59a3b104c,10.0.0.8:443 +/4d9b2f4f469f2b2b5f3962306f97e75859c8d936,10.0.0.8:443 +/56f073a5a58f509bd491f8884fb340a935f40308,10.0.0.4:443 +/3c2b58f0da1000a8a78a3277b7fb5b1cfcd849a6,10.0.0.8:443 +/928720a69173cbfedccbcfc04b198414b5164f00,10.0.0.6:443 +/d87b50fec3d063f2a71d17c82d042c2abdcb7017,10.0.0.1:443 +/3f56709086bde9189226f4c98d6debd284176644,10.0.0.2:443 +/cdb098b71941c131bdafe7123c569453e08875b4,10.0.0.4:443 +/75dc829b5562bf143582d8ebed2766892438fdf6,10.0.0.5:443 +/e92003125b6bf378ea6279b52c744bbfa947c7ff,10.0.0.9:443 +/43601fdc2b42ea10e6eddf5ad078d9959591b054,10.0.0.1:443 +/4de1baf0df9a5653c30ba33552d107c8050ba65a,10.0.0.4:443 +/d8d7b30cd8c473d9dfccf65626bdcaf093524fab,10.0.0.9:443 +/44486486ce00b0c97d44bdaa8e9ad0cd4cef2f24,10.0.0.4:443 +/2f2b76cd6ceb9d1942d5e9ef0f887e2447426de1,10.0.0.3:443 +/0f4b330a57a82f31e00455ef74555b31f5bed5a5,10.0.0.3:443 +/1ac2f42face0e1b71f40775e804816f562f5046b,10.0.0.4:443 +/09d09a595f2bf13257e07133ac78186f35555584,10.0.0.5:443 +/0110e2fe94b7def844f20606e2c8456d3502bccf,10.0.0.3:443 +/e3b4ef341806cc37ca73c853f7fb946e1f5f6e8e,10.0.0.7:443 +/38e28374b1a9f41bc73cdfce491eb2bb0bce6fbd,10.0.0.3:443 +/d1713989a361ca1eed0f5f68fee5c50f91854b5f,10.0.0.3:443 +/f23af6f472102edef6de9491f9a844070ba3029d,10.0.0.9:443 +/f196a713839baae0bc51f4b1436927d36f2ff7d3,10.0.0.1:443 +/7598e8238744d04076326a8e3597578f9ecc8c09,10.0.0.1:443 +/59a02561ca435d78ab8aa7422feabf8773dec410,10.0.0.7:443 +/ca62f7298625dc574326a50ad33a4538559fc47a,10.0.0.5:443 +/04bb8594fabb6dab24d9913b98cf38d0563f83b7,10.0.0.6:443 +/8841711058feec5187329165955a9c60407f83fc,10.0.0.4:443 +/4d884355dd150df67499ef203c01635a229ba6c7,10.0.0.2:443 +/071866a73e91187306c1e407f0115a4d4151aeb6,10.0.0.2:443 +/afd57a92e88c0328fb968edd941b4100c6c9fb61,10.0.0.5:443 +/531c345d706cd574388c37ad61ba205c406b1d59,10.0.0.3:443 +/4502d8a61fb1a981fab9999a469dbac6e25e7f05,10.0.0.1:443 +/e230fc4ffa3bc256581c8eadd173e1cbc73b0cfe,10.0.0.1:443 +/05f427fdba3ff5f8d3039d3630772f161b8c9f14,10.0.0.3:443 +/911e4045fe7a9e356c9a4a83edb7675844e71e1d,10.0.0.1:443 +/6e23a5865d2058af3619068245ead5e51618e0c7,10.0.0.4:443 +/d1a0e473ffe13801ea65171346ad99201c498078,10.0.0.3:443 +/815a0974398d76788a4b3da7d0cca31f126d7de4,10.0.0.9:443 +/4b5e04ef7002bbde1ab4076a838dec1de1d26f39,10.0.0.1:443 +/524cccc30582e8a63d8312af6635e22baae5cc6c,10.0.0.6:443 +/96b6e633b7128d91860de1ac281c3080fc3abafa,10.0.0.9:443 +/bd9d0ab3293f97f2d0723f68fd28f15bd536c156,10.0.0.8:443 +/47e8509e8d7eb07744a7bbb065e51a64af82fa8e,10.0.0.3:443 +/7186ce2f19770360dfb9ecd97b89e16efac316d1,10.0.0.9:443 +/eed6c4e6883b62cdc3a7b196d99273557b071dd2,10.0.0.2:443 +/b96d9c4be72a2b9492c2d7317b95e9e8126b5c22,10.0.0.3:443 +/548f0aba642aad540d75ba5179b4c4e0769d3f1c,10.0.0.9:443 +/26584bcf23d47c9d064c9f80f8e428b694aca25d,10.0.0.9:443 +/e2037c8f1d790b8c725d9b2935056043ecbd8e93,10.0.0.2:443 +/7eba0adbc91b2e122b190de42e4560a2157b112d,10.0.0.8:443 +/9146d10cd7ab98d06cd0f4b4197602778d6e4140,10.0.0.8:443 +/9fa77d555984524b0361fb3072036e91cc6ea3f3,10.0.0.8:443 +/52f48dffdc8736b0c0e71df9a3c0f80e88770725,10.0.0.3:443 +/2265098f5d88d6d99acdb58cdcc1259d928625cc,10.0.0.9:443 +/d6192927efab74c222d087ad8dc2e820dcb7f6ea,10.0.0.4:443 +/18d1d3a2d5ed8d726aef5302787d369b79781866,10.0.0.4:443 +/19c735d6358604129199dcd752ff41f4221fa57e,10.0.0.5:443 +/b351359d0d09616a3fac0e66ae77e26357781753,10.0.0.6:443 +/6dd6111dd3ca9ad06569393e50484d3347035fa0,10.0.0.6:443 +/93e3738859d55cbde6df33ff6cb633a9f80dc0fa,10.0.0.9:443 +/eedde9fe113eb083a5d3c2508057360ddc18686b,10.0.0.7:443 +/62a3e2d15c1c66eb816f3dc13b5827984b9f699b,10.0.0.9:443 +/f1b4e2ea07bb5ed2f47433b75d1f7c8ef5bbf7d8,10.0.0.9:443 +/fa62a18b60e7385df8024532e7aeef87cc1df239,10.0.0.4:443 +/7d1aa3efc0114d39a9f010b900e1db11151e639d,10.0.0.6:443 +/f0468f9ae142e357977988238dd0688c49773aa0,10.0.0.4:443 +/d8b5c9789b2aab6444a2ef1d8cef7ae774458ab8,10.0.0.4:443 +/0a85a262365cc25072bfafe6136a7ba369566112,10.0.0.6:443 +/4dded059c42653a7c1beaa541e63645bf551ad08,10.0.0.2:443 +/49bd739af1ec870702c3847e967e8c6b435c5329,10.0.0.2:443 +/8d95d2e2928f6c92b660ec1c1fa7df8ff813aec6,10.0.0.4:443 +/93bf75656856b0a55da0773071dc39089dad6c98,10.0.0.3:443 +/e3390ff69032d41cc118b525049af3a5b802fae7,10.0.0.2:443 +/3150a053fd0dbbb2d248eebe951137ca8078f1d2,10.0.0.2:443 +/3f9d225fb79822a7b27f99d8d201ca1a45bb2ab6,10.0.0.2:443 +/452402b171258fcd3a5b107c1c939518102d2470,10.0.0.4:443 +/08317e0decede1f945dc9e1fe173bb4f6fb8cfd6,10.0.0.3:443 +/2cb847f4fbc26879a7b38289fb9add3bdc92a61b,10.0.0.4:443 +/42ba7f638d09315bd314f1ecb6cbaba154074a68,10.0.0.5:443 +/c0370eebe06344737bd403540f6adb13609b884f,10.0.0.8:443 +/9c71526d82a2a81ac13581c5f93125202f95aff2,10.0.0.3:443 +/e334fd8fafc2cb8809436c3e95e285d8c6079a94,10.0.0.7:443 +/c396727f862d04377b9b67299231d1d64d3d208a,10.0.0.3:443 +/6e51035a8d1f3bdd7f1732fd749ef13732a95944,10.0.0.8:443 +/785266cb2e5abbf8e8d68ed6944c44bc8784e83d,10.0.0.7:443 +/212094a923c2cc9abba620361a83ed32ffc89562,10.0.0.4:443 +/139a4d3ff8c15c8bbe453dc8b51a4369a9761129,10.0.0.8:443 +/990a8cbd6640ba4c5002b6e139b1ddc0784f687d,10.0.0.9:443 +/a6fb42bfd3197c44719ed46faf9d90cb06548ad8,10.0.0.7:443 +/000c6423f358a2c3d3f495b13d62c0d2c39f50bf,10.0.0.1:443 +/1cec05fac01fdaacba7ce488edd944661542c006,10.0.0.3:443 +/271f90733f7434e025ebc1f28267e53433857e1a,10.0.0.7:443 +/39e38084ed794b098342c8e73c50eb6e8a473451,10.0.0.3:443 +/391aed0b4c3552fe6045ee9e9fa5b1d749dad8f8,10.0.0.5:443 +/6f08ffaed414be3b69721e7f6d32cdbf708af3b3,10.0.0.9:443 +/e70ea65e0acabc146426f773ee43d27693b291cb,10.0.0.3:443 +/b4e2cf556861071282564ee2f08e188fac4c5253,10.0.0.6:443 +/6e68bc22256a8e097ae14c5309b968eac3ff115b,10.0.0.9:443 +/47960ff89fcae7481243ffa5164fd694546f238a,10.0.0.3:443 +/f574bef3f84ad106c19f59e9e9e02b531545144b,10.0.0.2:443 +/4c3e44af33a9121771dfc8ec0f9315ac44133350,10.0.0.9:443 +/b15cfc1da87f56a87bd209364583cb5ab32236dc,10.0.0.4:443 +/40fa370749b2451bea54a014f1424acf8f26689f,10.0.0.5:443 +/2b427b399d5020c4422e0795378c785ddb7294c2,10.0.0.1:443 +/bc6adfe886d10fe6eafb996229582b4bfc8d222a,10.0.0.8:443 +/f7b4e0538be13ab1bf2d07e6811a503a9017d9f3,10.0.0.2:443 +/5e89704df5e29e7cf5d66780e8c21ee43976a437,10.0.0.4:443 +/7b83fa2b9257a4c2d3130dca607ec04fb042a867,10.0.0.6:443 +/a3b86bc98a2d6f3ffa6572d699127b0bddedfed8,10.0.0.8:443 +/e4d0162d0642d1b8c48d405df85e19a38f0feeb3,10.0.0.7:443 +/4d485cce05cbc8a437c1c0935d481a7bea42fca5,10.0.0.2:443 +/845b67ac4a0134e07b0a024cc4e23712b6e6aa9b,10.0.0.2:443 +/b79bb4986238b94afdd2cb060f5552eef7ff54e6,10.0.0.3:443 +/af07fafd8a759a1cf5a609d578639be03caea26d,10.0.0.2:443 +/81af00d61c1ef5b0613ad4beb2dd25f89efc6182,10.0.0.8:443 +/593136c41899f34390c6d37d16edbbb9cfff7abf,10.0.0.7:443 +/cf81d9fb40a3fc64d11770126f3a699d70eb0feb,10.0.0.7:443 +/63c546d9b325c23c3861555b1e605cc203079992,10.0.0.7:443 +/4ca3fa4d44be023ccfa77e4f77f68fa0b8ea7710,10.0.0.5:443 +/e701444e1b1d9f079e9c879d8f999d88b56d68e4,10.0.0.5:443 +/f6c473391fa230f190cdda902f793977ce7de8ad,10.0.0.4:443 +/7bc73bd36bbd732b25e146e2f1b01003eb159775,10.0.0.6:443 +/5f287e6957a09c1be550752505a5c1420ec8d3bc,10.0.0.1:443 +/bebd964d7ca6eddee7de35715ebd96afa29fc8e2,10.0.0.2:443 +/db7a5038c8f2d930653563a2e523683c0a93bc88,10.0.0.1:443 +/47a642c6b0895911ca70f994f506c415505d75e1,10.0.0.9:443 +/8c5554e66fa04d50fb84d5f49ace6de0852a34da,10.0.0.6:443 +/89923f03ca432e5969fd0cdf5c15bb70b98efe2c,10.0.0.3:443 +/7a0aa569021d8b2b2ce9bfcb07310c1ebfad5151,10.0.0.1:443 +/0937e417478b8173a2bb86dc7b8b9454e059de4d,10.0.0.3:443 +/188c99ab8d7267ee33a9a5acc8de76bd58898b45,10.0.0.2:443 +/c4a8f4fb2483266c7166285df63f3640fa2319ae,10.0.0.8:443 +/4b0d34f033113d93ecf921c6a0feb0b2d45fb126,10.0.0.9:443 +/fb42de2cd7c51cacd89d7575bccd67f7ec25e451,10.0.0.4:443 +/028a4c7b547864a379e75c95c587ce64202181dc,10.0.0.8:443 +/cc5a526f4da916ea0a13b85e0c6e98b3d7437cc2,10.0.0.3:443 +/9113f453c2c434907b4ff773fe5b86f21e382416,10.0.0.1:443 +/830245306057d4c72845188ee1bcd3faec480fa2,10.0.0.1:443 +/81d4b64d141924bb939f5379c79f68c8f73f6861,10.0.0.5:443 +/be650948e3ec4fb93c66085f4ccf5b03ab52da7d,10.0.0.3:443 +/dbf7fb2f6d1c71680d904a7982c255d38d9cb66d,10.0.0.6:443 +/df2fd0964b001d47e7d7d8f704997f8b2c188e2b,10.0.0.3:443 +/52599e6c628d3713b5a86776e7bf4e8eba08096b,10.0.0.8:443 +/9a8dfa9f83cddf2f78d3dfaf2977d373250d08bc,10.0.0.6:443 +/f6fff2fc64e81812c1fd6f44b17c0fca8f4d9b21,10.0.0.7:443 +/c74b67ef81c0f0159ebf55bdb7cec7edbb49ef01,10.0.0.7:443 +/1d489c78f83a538058f88a86d5d3b784a4c8c15b,10.0.0.3:443 +/c19e2d12a05580a32ed36959def7a94542f3e4b2,10.0.0.2:443 +/0ee2827f11b4ec40f5b9461cafbafc67c9bb19a4,10.0.0.6:443 +/6fb7e55aa135073aafdaee252c0d41711f0012cf,10.0.0.2:443 +/c31f4f1035ecf919c2a8ad9aaba8f34787b6dbfc,10.0.0.5:443 +/da600775aba95b86e525802936ee1080854c9171,10.0.0.7:443 +/713544fa205d177ae8892dcf355b3d9099d36346,10.0.0.9:443 +/7c838304cffcd5141ea13dc98ebe74d3c9fb0b68,10.0.0.5:443 +/1dfa23ab97268feb6b3fd019ff226fbcd628995c,10.0.0.2:443 +/525a23553d91d72be5ae26127029e9e3bdfdb6d7,10.0.0.9:443 +/963f18f8446ec2ab1921e0579c7af87477ef3592,10.0.0.3:443 +/64b104d6efe390c5e8a008312e16772cc76632e8,10.0.0.2:443 +/de3125db331f2c903e96f273a649f782abde3250,10.0.0.7:443 +/fb2452ca4688e9fa8177919d72032717ac19d692,10.0.0.4:443 +/76e8bbc123c7346c3398619f12d9888fee50811e,10.0.0.8:443 +/d6f9d8096fe75dd35f317b7d1ce0bc02306f6121,10.0.0.3:443 +/1e543c13b6af55fc60e9ba216790bccda9c2c3d1,10.0.0.2:443 +/5f5831dbaeba200adb52eefeb26d792cf996a01f,10.0.0.3:443 +/60ac99dd1fe31198399c6b447438e8ac62a35036,10.0.0.4:443 +/579077bb8a893f47c1b1eca7d8cd2d62c8a3b774,10.0.0.2:443 +/86590bffd69757efb277e2b6db69385bbb6ebba3,10.0.0.7:443 +/f829ea6c46b59cde7ba3c6745b58c3ea170bc73b,10.0.0.3:443 +/27f54b7138336175705207561c6a0a123049ab66,10.0.0.7:443 +/fab8ba44a38c657d3b8f9066daac9f3222e3fd50,10.0.0.3:443 +/03540d372c8e6621cf57ecb910cf872164f9c53a,10.0.0.9:443 +/be320aecabb73286f782df249b53ef4f7c816b72,10.0.0.1:443 +/7e383ecf09c026dec3eb9c77ca35274f209748a3,10.0.0.2:443 +/749dd7577081e9d47a3bf9ef091b6e5b8daa5786,10.0.0.3:443 +/9507f34faa73988fb0d35f65141b2e1b0f407cd7,10.0.0.3:443 +/a2188b80856ef974da6eac0238a35afef2e1c30c,10.0.0.6:443 +/1ca972ed159b7e8c838752ce60186262a923d057,10.0.0.4:443 +/57e7abe6d05fe0443800929dcf46315bc5135519,10.0.0.4:443 +/075a1e1426a5d210fd5501249809b1e20c793c92,10.0.0.2:443 +/36c50cfcf56f7e15f91844b9f3201efa4cc26fc8,10.0.0.5:443 +/f824965edace119738da671b1e3cba0e44be224d,10.0.0.5:443 +/ba49bc86400cd3970ea82550b493ac21a5bf750c,10.0.0.6:443 +/2dbc4c595e56af88a175811e715d908d04223c2b,10.0.0.1:443 +/e322f439382552e76fb5672448c2fc6beb56e32f,10.0.0.8:443 +/e86b62c9f240c97f1503be26f97fbd412b846e2d,10.0.0.3:443 +/e15c58a856824298802fed4151234e2a4812697a,10.0.0.7:443 +/e7b5cbc5701beadb3c8dc04361cdd1de8f8b0d1d,10.0.0.3:443 +/bf317994d21c8731f4afdebb4d77e8eb997a962b,10.0.0.5:443 +/cabb2f8ffcd78c654c2eb0bbecd32a4a5523c165,10.0.0.8:443 +/17e54d3b00f5b989798846b7729789343df86d56,10.0.0.2:443 +/334fcdca67212b01973f946729a2cb569adec510,10.0.0.3:443 +/a5d301755197c85985ee48ec53b4c3a1b6bfd9fe,10.0.0.1:443 +/f2b98e19ef44d81d16fce5e9e3b51c3be2a8c713,10.0.0.2:443 +/6a69c385697c7ed6b85ced626d993b02216c2186,10.0.0.6:443 +/7d269fcf2722875d9d75eb2e3a7e0fae6ae69a98,10.0.0.5:443 +/126e39e079fa7f2b254146466e9ab79dc4347be6,10.0.0.6:443 +/8a4aa1d8a6d6a2938ecf7a42814723e282a90af7,10.0.0.1:443 +/b9d9fabb46dbe2db5f5e0164c98002114c96006e,10.0.0.2:443 +/d50477758d2f8e99392ae9d51ecef57484c97c5c,10.0.0.1:443 +/09ac262b5b37a5b19fa989e5ac75722fdb8e17fa,10.0.0.1:443 +/e1a322b3fc40fbc296f9ed8dc86d6e91c6dc8edb,10.0.0.7:443 +/1c08ea2a0c42f17d99acbcb2b0ffd33ba1fb34be,10.0.0.8:443 +/6aeefd631b7ddc01936b7fc11f1e8aa5a892bec0,10.0.0.4:443 +/f579e4e7a050029dd9f21a38104c1f1b65e201e5,10.0.0.3:443 +/9764ed5aff70cac5a5859415251c0b78dfd37909,10.0.0.7:443 +/42d5cfb85dba89806546ac382f61fd909cdd40e9,10.0.0.2:443 +/4cf6e01e948d9cd30032b5ce77d2d8b2daaf21c8,10.0.0.2:443 +/e0367d6d11e81aaed084aceac24b327abf053c0f,10.0.0.2:443 +/28b88a8f6ce2d2b9bd5867f89555f2e43dc96c96,10.0.0.8:443 +/56b207c041ede2daa065d56b03173663eb6a1f2b,10.0.0.9:443 +/6aa844c78eb0fb44bd506a920360377163eb7150,10.0.0.9:443 +/327dabc969eb616dc10e4ba33f45d0cc97bf79d9,10.0.0.4:443 +/7352ac0a60c2f2bedb0d80b0249db5aa59e0c876,10.0.0.4:443 +/70a2d83045053301afcd56deb30bf9095a9ad9d6,10.0.0.6:443 +/cbd05a3e43fb4b1aa98283c8d460571c43144391,10.0.0.9:443 +/0c903f04b7f6d4a59a97c4ae212a41ad579e5a1f,10.0.0.1:443 +/3dc7749f4a1f30ab1da8b4e2722d3228b0e8b33d,10.0.0.7:443 +/b502f7505431f9b895c9fe04de74250f27f96f7f,10.0.0.7:443 +/14aa1d4b3ddf14d7f5cba9de1f08213a8a104131,10.0.0.9:443 +/cce74a90b51c414ffbb28ad26794bf589c1eaf82,10.0.0.2:443 +/a86f00b80c039be1e4fad0b5508bd1710ba08ae1,10.0.0.4:443 +/055b3843846da3e34606dc209c9b30192e6119da,10.0.0.4:443 +/f05c831872443fb183c6c19d1a9dbe45315f0205,10.0.0.4:443 +/d974f0525fca48f3fae6d6cbd0b394e4324ad422,10.0.0.3:443 +/00ef799f7c152055a4163c41bb9bcd37fa375f77,10.0.0.8:443 +/7d876337b6f86b9873ccc49f7efaae91d180a06d,10.0.0.4:443 +/93e9efe1dba728a9a51d68024eddf764903cac1f,10.0.0.3:443 +/891d1f6116aec61df9dce652743ae159861e9160,10.0.0.5:443 +/eec92486c171c84f0dcf3db001ce9b32615166f3,10.0.0.2:443 +/363f23c9bea6cac01f85f7ec7142110363110c83,10.0.0.7:443 +/51c699024eca637817d2bdad512b9c1d19fafec4,10.0.0.6:443 +/b7aaa2cd36505f55bb047799649acadc5e20e499,10.0.0.8:443 +/b17b2a0be4fa445a0f762a92dee8b8d83e992eae,10.0.0.8:443 +/e4c7719fd87bd86bf5c818a7aa38af4d50691d51,10.0.0.6:443 +/edf7c0e6f7c1bbdc7bc67912607a32ff5ea786fc,10.0.0.7:443 +/62d1fb98dbf4825ae9db6f919233f32391ce1e63,10.0.0.8:443 +/e0214b5cf9fb6464dfd37a84fd41a759e571a531,10.0.0.7:443 +/bf7e606b9858081dd5f7f2346f70e314238809e3,10.0.0.9:443 +/f4907d05ffb94d07ea2a1eb8dc187268cd386f0e,10.0.0.2:443 +/cdfc8d53ae78926694e5d1ebe872d30f7e57b324,10.0.0.5:443 +/0de8c668d5445e80ca5d0ece0e653fc664b494e8,10.0.0.3:443 +/fafc8ecbe6fc726999a249b9a2bfcb52371dec5b,10.0.0.2:443 +/ec395c49cff03d52796f59fabdabd045eac000c2,10.0.0.3:443 +/0bfbcb5addb0f60e28504de36a10abb80d253011,10.0.0.3:443 +/6bfbff0669887fbad3bc871771c62f9c5d723740,10.0.0.3:443 +/d0b0e5ce39dbfd7a3b46542c1088e0231295be11,10.0.0.9:443 +/79dc5f7b75fb82ed6dc0be947434d924ade41bc0,10.0.0.6:443 +/f729ac665760539349f1c808bee81b70d58537d2,10.0.0.8:443 +/fc97f5ede259d60ba9f28888ac3b2155b5490df6,10.0.0.1:443 +/0c5cb1e0dfed034af7c893de52841686a762f6aa,10.0.0.2:443 +/accc74f350aa74842630517d6abfed728d5da084,10.0.0.8:443 +/1c2e760244036ee1f0539288d446830a0fa38457,10.0.0.7:443 +/0f60c86359a38087105591e609f90b962b02b74d,10.0.0.4:443 +/9e26cafc4562d086fadce9cdf56c049e9cfd93b8,10.0.0.5:443 +/bce221dd780f255f84e159f1097ada3461ff5ab6,10.0.0.2:443 +/c918871122a23989009073c879ff5c6d3add13c9,10.0.0.2:443 +/50735adf2192b44d672b99cacf66e650582f9088,10.0.0.1:443 +/fb763e843db495284a217b2ec5027d7698bd49ca,10.0.0.1:443 +/ae068dab9d1784aa098085b9f62e168c79bb75cc,10.0.0.9:443 +/6b989c5c0af97c2acd640cb2f05dc4b4fe7c9323,10.0.0.4:443 +/fd81185d074101b22059f022b174d058b8d84a6e,10.0.0.8:443 +/20277b4366206f795ed97f4631baa755636ddc1e,10.0.0.6:443 +/c9199750bcb6c7b916958bee64f562547d6b1209,10.0.0.3:443 +/9ea2e79813eb3a6d7b710affe1b15f7da29c1800,10.0.0.2:443 +/2de1269fec587f989b911e4780eb056c310d2f38,10.0.0.3:443 +/6869b9dc65fbfb56fbe828c0ac57da2bc7c0f460,10.0.0.6:443 +/aab69be5e6c02f972e8a5e0e4c9716b84d91e667,10.0.0.6:443 +/f8bb7d358e7c5e58b5d68a29a2d1ca4cb1a4af61,10.0.0.6:443 +/441f8eab7ac90bb4022d35aca197b5765ecb7dbd,10.0.0.6:443 +/36bad018c5b41a8f3731267f364cbe74cee32a81,10.0.0.4:443 +/8d31a4ecc03b0d8680ccef099ed528f07a5e8aa0,10.0.0.8:443 +/2e8ee9b09986f2e9435dc2b3b05d9353a8edfd3b,10.0.0.2:443 +/950dedb075f2e3b2bc485659e0158fa0c26511ee,10.0.0.7:443 +/2bff636db028f497c8d26cce0c138a5049e69db7,10.0.0.4:443 +/33353d31c296876c1267ae7793d0c03caea2a387,10.0.0.6:443 +/bf5e822a05f799f153c648ccad9987396c9350cd,10.0.0.8:443 +/92a14cc304c5fce82d3e4999fb1a819c92cfe2fb,10.0.0.9:443 +/06c1a1908f37b4cdacd7098b7304ced839f8412b,10.0.0.3:443 +/de42c498d10e019fad348d4e2e512afd8981a7b9,10.0.0.3:443 +/42fda236e32757240063ecb99681a30121629ab3,10.0.0.8:443 +/b93d832939ca288351cb707d8332ff7aade5c6d0,10.0.0.1:443 +/2fac7e24ec806b0b5b9f7bf99587e50357d9db04,10.0.0.9:443 +/8750e04a953b8d6a5922ccd6172d59052671207a,10.0.0.5:443 +/c5128cc73e48a0270a27e6e2b89f563dd756f987,10.0.0.6:443 +/4f798881963c3638cd89168511eccdc8f6ecc62f,10.0.0.9:443 +/330116fb139c1313bc78bf314a211d98dad8093e,10.0.0.1:443 +/d2ff19c61e6be34733295d7c2f81b18c81a687bb,10.0.0.5:443 +/5ff80f927eb571aa8cc006e0b7c237d8f571ffce,10.0.0.6:443 +/b2ec40a643fd05a9f0d52b180893c9837a824060,10.0.0.8:443 +/9445a32fc9ea94e27622826699123272ca5bb38a,10.0.0.8:443 +/7b12433171a2a61d85b95d8ffd9ddd7e8ba1f0d2,10.0.0.5:443 +/8f1cdae5a092253771e8d07f66ef45d6cc540c5e,10.0.0.6:443 +/7b70d96ff0b14c53aaf134e16cb0ac8394b9ec93,10.0.0.7:443 +/1c91cb4395964c049653b422be092ecc6957ccb1,10.0.0.3:443 +/1680013d16baaadb8cffb6838dcaacfa9ddf815b,10.0.0.5:443 +/a6cd614c3f4c92608f176ecbbd24d4d3e980c18e,10.0.0.5:443 +/5f1ad23d97b5effe56b07770e1b1e3eb9302ce32,10.0.0.9:443 +/4014ea7ccfafddaa137d536e55a4fcd04f4acd23,10.0.0.7:443 +/4fe5c55f2b57b57de6773d70b788f2950f98aedb,10.0.0.4:443 +/a5e42b24f4d2b631529dc5e693f0f44bec25d917,10.0.0.4:443 +/605b3c16dde75dde0ed96aa420121d491043b868,10.0.0.5:443 +/a44dfbc27a6071c7fc05ec6c9bcf08a80059d9fa,10.0.0.1:443 +/376db7678f97b6614c81a967ac480d2af1ec0494,10.0.0.9:443 +/7ab905b17ac0f3dabc9e73654f7108a60382b4bc,10.0.0.9:443 +/7e15729b3688eac3a344b412fb66660812e51f5a,10.0.0.9:443 +/fbe2e0d0d220635295397028926abcab95eae6f3,10.0.0.9:443 +/68c054186128694496e7e34307333f0ee0fcdd83,10.0.0.5:443 +/1539ed321544c684ffec1d533551c8ca3b814bed,10.0.0.2:443 +/52239e8766c814c60a588320ff4e55dc9fed5345,10.0.0.9:443 +/7dbfc596b9cf0c5fada4c6521d67d7e8d42f6fea,10.0.0.2:443 +/d04621fb5f44305c3532899899c6f53b6afd5a0e,10.0.0.9:443 +/581c7d2014ef9aa2a30e54ac748164ba66a534d1,10.0.0.8:443 +/d6c7154f9d5d3dadd5e890c8f7a1b178c4992eea,10.0.0.2:443 +/bbf232fd8d3a7f781b378f160e3fb629ce09ad59,10.0.0.5:443 +/5290410ff6812f651bac427d10fae8ec7a40af1f,10.0.0.9:443 +/41cfbbdf14643164ccb783e93eb123f23f2f32bc,10.0.0.8:443 +/9259ff15fbb6d028166e31434d4e2dc335c390c1,10.0.0.2:443 +/20258376b3bf0e3221118d0b5af2c4b8fa99fef6,10.0.0.6:443 +/7e34ebb4b42eafe0d92fb748745416bdcdb67bb6,10.0.0.2:443 +/2fe398814da4f25bf0f9f6982b43d955b93c9c4b,10.0.0.1:443 +/6bcc489d911d7e972b2decd5827d4eb628111a84,10.0.0.4:443 +/87c70ef625901e6ba2c9dd6951efa9964bebe528,10.0.0.1:443 +/3b79cc56f47bc4487a12e940caff6f4c294b633d,10.0.0.1:443 +/bc5e3f9cfd2ca035467321a7280dd2bf1250259c,10.0.0.4:443 +/260555bb77d941f8761b6a8b81267b6884da79d0,10.0.0.5:443 +/e77e4992d06c6b662602f32bf8a52b1567eb2f48,10.0.0.6:443 +/0923bd0601bf7c074d173268cbf94cff7b39045b,10.0.0.6:443 +/d7d8f74a97ab8b8f0df34c447e2ba2bf19a8a142,10.0.0.2:443 +/1151eda28cedf93b701b4ae0f47b35c488d493af,10.0.0.3:443 +/e4b07856919718e9c7cd00154fbb12c343bf5b55,10.0.0.6:443 +/d5751616b55b115bb0260fee64eef350e83cf080,10.0.0.1:443 +/83bcc3183e99dcba798f17ac6340722b1431ed0d,10.0.0.5:443 +/2e84b809ca1744c2abfe7d8ec18dc80adbddc0bc,10.0.0.2:443 +/782631660d3fd29586a00922d9e1885c30615bbf,10.0.0.2:443 +/0b43b69669114bc2ef38ad7e03fae7a82ac22f29,10.0.0.5:443 +/59bb4679fc26333daec10a9a06ebe185ab252628,10.0.0.4:443 +/26b7bd3eae9d48dae1677893dc7efb7d7d9386ac,10.0.0.6:443 +/1842eded9ad6f8e951f4e788bbedd8ad9b5d2289,10.0.0.8:443 +/c0b818cdd2005b05932a6369a80d47993cf1982b,10.0.0.9:443 +/6f3b0ed59323086c2557c6ba6aeb433bd82509bb,10.0.0.1:443 +/bbe9eabb406b05b3b13ce634caf88123d095de39,10.0.0.3:443 +/fad30adc6c95657b9be1a490b338798fa08504c4,10.0.0.3:443 +/56a66dd5081af7ed9d9307374606245a751cceb7,10.0.0.4:443 +/356beada6689aaba95fafc526101a982acb007ae,10.0.0.9:443 +/c9917bb9de0eea13e66c71c88c35a03f3567bae2,10.0.0.1:443 +/495d1913174caaaae68eda040e329cf9ab6b807c,10.0.0.2:443 +/f89a11728d36429756ea52ed934a853ae2cf62a5,10.0.0.2:443 +/3263ba8199377065aafe566132716c2bf4fa300d,10.0.0.9:443 +/cf44e7fe43a615a8b58cf5c3b7486e95acf95904,10.0.0.5:443 +/2a055e911545b3eb8ca31202c16a916a061eb35c,10.0.0.7:443 +/120600f104f1305c96642a7382c7074386dc9f08,10.0.0.3:443 +/05690a98a3b475aed24b300bd1d8303c5f0ed93c,10.0.0.8:443 +/648371cafaf32c90a7c48ec2c6d57f84d4f81346,10.0.0.1:443 +/c346dd5aae927ff513fe5a8ece05ec7c2d5674d1,10.0.0.9:443 +/531b748b3a7ba01687e3eb6bff2df8951daaf1f4,10.0.0.5:443 +/c0935bb5ad0fad0b3f9ff4b924c01971116eac7a,10.0.0.7:443 +/2bf19d2be50af6207c977fa502caa8a6dd6722da,10.0.0.8:443 +/afc63845c577fb67edb01f2f4faa19415f36420d,10.0.0.2:443 +/efaa738ada05c233a8f0d57b3064d6ccd86b1a14,10.0.0.5:443 +/b1d708f56428e8c5e9ae6f8a2a492c75271b8a45,10.0.0.5:443 +/5b9abc512a9b5ee9083d0feec592002f5f31dad3,10.0.0.7:443 +/55289a755e9560c48aa164f357598a47603badbd,10.0.0.2:443 +/472ecb69a8ca3b590d1dd3153928d7bb09f43799,10.0.0.4:443 +/072d33b67d2137d961ff8ee5a5c0d024196e4c91,10.0.0.7:443 +/ca285c1755e98e6a8080cbe45f54e91f7d466c2a,10.0.0.2:443 +/13661ad2ef4c48f7e99825bce7efc3833d0bb1d4,10.0.0.3:443 +/b093d7e4f7588296fb1b02b38f20effb4c193571,10.0.0.1:443 +/dc82252b61b41f0760eb44be138b6bca8a22b804,10.0.0.9:443 +/1cddee843b564a0ef0acb8ca9d7dff0d7df3dcfd,10.0.0.2:443 +/560e227e16cb133b6fe840bf9ef03e8aee0dad66,10.0.0.8:443 +/55b1bd74ae0aea31731589550b7610ed00c1e616,10.0.0.9:443 +/87f0d8ea3eaa758b41763fd06d2fa52d2fcff7a7,10.0.0.7:443 +/e669bc52f256862c9ae2e0a7748ee3786a2abcf8,10.0.0.9:443 +/3fca3907c98117eb1920bd03179a35aee3cf1939,10.0.0.3:443 +/3d2582fcdf65814ef32ceb3ca30a38aba02020d2,10.0.0.7:443 +/2628fbf7ed1e6f3f2152a57e1b7c440895088534,10.0.0.6:443 +/37f57ab1100409e62e4ca9532dd245a2e84eab7a,10.0.0.8:443 +/1558c2abe0ba2f4d83172d32ee9489a5f2469174,10.0.0.2:443 +/8e2dc4336eb4fb16deebee7c3157b2a4ddc040d8,10.0.0.5:443 +/016a870bfd0d09832a50ca14d666e7ef21978f5a,10.0.0.3:443 +/f3d2b5c0cad02f1507f1a5c21b4cd8704f32ac11,10.0.0.6:443 +/1ded786d6cc703eda6a20bb7388114a6b74cb17b,10.0.0.1:443 +/de0132cb6cdc9aeba721296519d0b64bdb752855,10.0.0.6:443 +/30f11551b9d666c96604d01526eb001c9cd7524c,10.0.0.9:443 +/eb8bc43a527ac9f8088010954c78fff7a75f1bca,10.0.0.9:443 +/30803c02cdc19bccba32ad9fc2e77a4d20eac091,10.0.0.5:443 +/7281a18bbbb2dfb089b3039f516792e6b0c67714,10.0.0.2:443 +/8787a462e8890da32babea287e4874d3da54246e,10.0.0.6:443 +/2b76b52f43b204a6353a1f999ff40a221602199b,10.0.0.3:443 +/56e71d678f5482e4dfe45ae83993e9e1c9fe2731,10.0.0.1:443 +/08d820998361440ed076fa803e05d3c983383920,10.0.0.2:443 +/cc449cf6cee8ce83f646097ac3d3287becacfe41,10.0.0.4:443 +/2da713a30a3333b7895b3d65a320fe6c20bf670a,10.0.0.8:443 +/658e0cefd2b9a97b2dd840c2a243afc0dbf06cf1,10.0.0.9:443 \ No newline at end of file diff --git a/pingora-ketama/test-data/trace.sh b/pingora-ketama/test-data/trace.sh new file mode 100755 index 0000000..1c309bb --- /dev/null +++ b/pingora-ketama/test-data/trace.sh @@ -0,0 +1,6 @@ +#!/bin/bash +set -eu +for i in {0..1000}; do + URI=$(openssl rand -hex 20) + curl http://localhost:8080/$URI -so /dev/null || true +done \ No newline at end of file diff --git a/pingora-limits/Cargo.toml b/pingora-limits/Cargo.toml index 88ee11d..0a0ef99 100644 --- a/pingora-limits/Cargo.toml +++ b/pingora-limits/Cargo.toml @@ -4,14 +4,18 @@ version = "0.1.0" authors = ["Yuchen Wu "] license = "Apache-2.0" description = "A library for rate limiting and event frequency estimation" -edition = "2018" +edition = "2021" +repository = "https://github.com/cloudflare/pingora" +categories = ["algorithms"] +keywords = ["rate-limit", "pingora"] +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [lib] name = "pingora_limits" path = "src/lib.rs" [dependencies] -ahash = "0" +ahash = { workspace = true } [dev-dependencies] rand = "0" diff --git a/pingora-limits/benches/benchmark.rs b/pingora-limits/benches/benchmark.rs index bf84a10..1cc4b96 100644 --- a/pingora-limits/benches/benchmark.rs +++ b/pingora-limits/benches/benchmark.rs @@ -1,4 +1,4 @@ -// Copyright 2023 Cloudflare, Inc. +// 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. diff --git a/pingora-limits/src/estimator.rs b/pingora-limits/src/estimator.rs index 45f1592..2e98ad4 100644 --- a/pingora-limits/src/estimator.rs +++ b/pingora-limits/src/estimator.rs @@ -1,4 +1,4 @@ -// Copyright 2023 Cloudflare, Inc. +// 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. diff --git a/pingora-limits/src/inflight.rs b/pingora-limits/src/inflight.rs index 68d78d2..9c8814d 100644 --- a/pingora-limits/src/inflight.rs +++ b/pingora-limits/src/inflight.rs @@ -1,4 +1,4 @@ -// Copyright 2023 Cloudflare, Inc. +// 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. diff --git a/pingora-limits/src/lib.rs b/pingora-limits/src/lib.rs index 5a396e0..33012c4 100644 --- a/pingora-limits/src/lib.rs +++ b/pingora-limits/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2023 Cloudflare, Inc. +// 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. @@ -24,11 +24,9 @@ pub mod inflight; pub mod rate; use ahash::RandomState; -use std::hash::{BuildHasher, Hash, Hasher}; +use std::hash::Hash; #[inline] fn hash(key: T, hasher: &RandomState) -> u64 { - let mut hasher = hasher.build_hasher(); - key.hash(&mut hasher); - hasher.finish() + hasher.hash_one(key) } diff --git a/pingora-limits/src/rate.rs b/pingora-limits/src/rate.rs index dd05cec..40f7605 100644 --- a/pingora-limits/src/rate.rs +++ b/pingora-limits/src/rate.rs @@ -1,4 +1,4 @@ -// Copyright 2023 Cloudflare, Inc. +// 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. diff --git a/pingora-load-balancing/Cargo.toml b/pingora-load-balancing/Cargo.toml new file mode 100644 index 0000000..7d2cc62 --- /dev/null +++ b/pingora-load-balancing/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "pingora-load-balancing" +version = "0.1.0" +authors = ["Yuchen Wu "] +license = "Apache-2.0" +edition = "2021" +repository = "https://github.com/cloudflare/pingora" +categories = ["network-programming"] +keywords = ["proxy", "pingora"] +description = """ +Common load balancing features for Pingora proxy. +""" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +name = "pingora_load_balancing" +path = "src/lib.rs" + +[dependencies] +async-trait = { workspace = true } +pingora-http = { version = "0.1.0", path = "../pingora-http" } +pingora-error = { version = "0.1.0", path = "../pingora-error" } +pingora-core = { version = "0.1.0", path = "../pingora-core" } +pingora-ketama = { version = "0.1.0", path = "../pingora-ketama" } +pingora-runtime = { version = "0.1.0", path = "../pingora-runtime" } +arc-swap = "1" +fnv = "1" +rand = "0" +tokio = { workspace = true } +futures = "0" +log = { workspace = true } + +[dev-dependencies] diff --git a/pingora-load-balancing/LICENSE b/pingora-load-balancing/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/pingora-load-balancing/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/pingora-load-balancing/src/background.rs b/pingora-load-balancing/src/background.rs new file mode 100644 index 0000000..3d3a1f7 --- /dev/null +++ b/pingora-load-balancing/src/background.rs @@ -0,0 +1,61 @@ +// 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. + +//! Implement [BackgroundService] for [LoadBalancer] + +use std::time::{Duration, Instant}; + +use super::{BackendIter, BackendSelection, LoadBalancer}; +use async_trait::async_trait; +use pingora_core::services::background::BackgroundService; + +#[async_trait] +impl BackgroundService for LoadBalancer +where + S::Iter: BackendIter, +{ + async fn start(&self, shutdown: pingora_core::server::ShutdownWatch) -> () { + // 136 years + const NEVER: Duration = Duration::from_secs(u32::MAX as u64); + let mut now = Instant::now(); + // run update and health check once + let mut next_update = now; + let mut next_health_check = now; + loop { + if *shutdown.borrow() { + return; + } + + if next_update <= now { + // TODO: log err + let _ = self.update().await; + next_update = now + self.update_frequency.unwrap_or(NEVER); + } + + if next_health_check <= now { + self.backends + .run_health_check(self.parallel_health_check) + .await; + next_health_check = now + self.health_check_frequency.unwrap_or(NEVER); + } + + if self.update_frequency.is_none() && self.health_check_frequency.is_none() { + return; + } + let to_wake = std::cmp::min(next_update, next_health_check); + tokio::time::sleep_until(to_wake.into()).await; + now = Instant::now(); + } + } +} diff --git a/pingora-load-balancing/src/discovery.rs b/pingora-load-balancing/src/discovery.rs new file mode 100644 index 0000000..5a38c2f --- /dev/null +++ b/pingora-load-balancing/src/discovery.rs @@ -0,0 +1,107 @@ +// 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. + +//! Service discovery interface and implementations + +use arc_swap::ArcSwap; +use async_trait::async_trait; +use pingora_core::protocols::l4::socket::SocketAddr; +use pingora_error::Result; +use std::io::Result as IoResult; +use std::net::ToSocketAddrs; +use std::{ + collections::{BTreeSet, HashMap}, + sync::Arc, +}; + +use crate::Backend; + +/// [ServiceDiscovery] is the interface to discover [Backend]s. +#[async_trait] +pub trait ServiceDiscovery { + /// Return the discovered collection of backends. + /// And *optionally* whether these backends are enabled to serve or not in a `HashMap`. Any backend + /// that is not explicitly in the set is considered enabled. + async fn discover(&self) -> Result<(BTreeSet, HashMap)>; +} + +// TODO: add DNS base discovery + +/// A static collection of [Backend]s for service discovery. +#[derive(Default)] +pub struct Static { + backends: ArcSwap>, +} + +impl Static { + /// Create a new boxed [Static] service discovery with the given backends. + pub fn new(backends: BTreeSet) -> Box { + Box::new(Static { + backends: ArcSwap::new(Arc::new(backends)), + }) + } + + /// Create a new boxed [Static] from a given iterator of items that implements [ToSocketAddrs]. + pub fn try_from_iter>(iter: T) -> IoResult> + where + A: ToSocketAddrs, + { + let mut upstreams = BTreeSet::new(); + for addrs in iter.into_iter() { + let addrs = addrs.to_socket_addrs()?.map(|addr| Backend { + addr: SocketAddr::Inet(addr), + weight: 1, + }); + upstreams.extend(addrs); + } + Ok(Self::new(upstreams)) + } + + /// return the collection to backends + pub fn get(&self) -> BTreeSet { + BTreeSet::clone(&self.backends.load()) + } + + // Concurrent set/add/remove might race with each other + // TODO: use a queue to avoid racing + + // TODO: take an impl iter + #[allow(dead_code)] + pub(crate) fn set(&self, backends: BTreeSet) { + self.backends.store(backends.into()) + } + + #[allow(dead_code)] + pub(crate) fn add(&self, backend: Backend) { + let mut new = self.get(); + new.insert(backend); + self.set(new) + } + + #[allow(dead_code)] + pub(crate) fn remove(&self, backend: &Backend) { + let mut new = self.get(); + new.remove(backend); + self.set(new) + } +} + +#[async_trait] +impl ServiceDiscovery for Static { + async fn discover(&self) -> Result<(BTreeSet, HashMap)> { + // no readiness + let health = HashMap::new(); + Ok((self.get(), health)) + } +} diff --git a/pingora-load-balancing/src/health_check.rs b/pingora-load-balancing/src/health_check.rs new file mode 100644 index 0000000..adb0c4f --- /dev/null +++ b/pingora-load-balancing/src/health_check.rs @@ -0,0 +1,384 @@ +// 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. + +//! Health Check interface and methods. + +use crate::Backend; +use arc_swap::ArcSwap; +use async_trait::async_trait; +use pingora_core::connectors::{http::Connector as HttpConnector, TransportConnector}; +use pingora_core::upstreams::peer::{BasicPeer, HttpPeer, Peer}; +use pingora_error::{Error, ErrorType::CustomCode, Result}; +use pingora_http::{RequestHeader, ResponseHeader}; +use std::sync::Arc; +use std::time::Duration; + +/// [HealthCheck] is the interface to implement health check for backends +#[async_trait] +pub trait HealthCheck { + /// Check the given backend. + /// + /// `Ok(())`` if the check passes, otherwise the check fails. + async fn check(&self, target: &Backend) -> Result<()>; + /// This function defines how many *consecutive* checks should flip the health of a backend. + /// + /// For example: with `success``: `true`: this function should return the + /// number of check need to to flip from unhealthy to healthy. + fn health_threshold(&self, success: bool) -> usize; +} + +/// TCP health check +/// +/// This health check checks if a TCP (or TLS) connection can be established to a given backend. +pub struct TcpHealthCheck { + /// Number of successful check to flip from unhealthy to healthy. + pub consecutive_success: usize, + /// Number of failed check to flip from healthy to unhealthy. + pub consecutive_failure: usize, + /// How to connect to the backend. + /// + /// This field defines settings like the connect timeout and src IP to bind. + /// The SocketAddr of `peer_template` is just a placeholder which will be replaced by the + /// actual address of the backend when the health check runs. + /// + /// By default this check will try to establish a TCP connection. When the the `sni` field is + /// set, it will also try to establish a TLS connection on top of the TCP connection. + pub peer_template: BasicPeer, + connector: TransportConnector, +} + +impl Default for TcpHealthCheck { + fn default() -> Self { + let mut peer_template = BasicPeer::new("0.0.0.0:1"); + peer_template.options.connection_timeout = Some(Duration::from_secs(1)); + TcpHealthCheck { + consecutive_success: 1, + consecutive_failure: 1, + peer_template, + connector: TransportConnector::new(None), + } + } +} + +impl TcpHealthCheck { + /// Create a new [TcpHealthCheck] with the following default values + /// * connect timeout: 1 second + /// * consecutive_success: 1 + /// * consecutive_failure: 1 + pub fn new() -> Box { + Box::::default() + } + + /// Create a new [TcpHealthCheck] that tries to establish a TLS connection. + /// + /// The default values are the same as [Self::new()]. + pub fn new_tls(sni: &str) -> Box { + let mut new = Self::default(); + new.peer_template.sni = sni.into(); + Box::new(new) + } + + /// Replace the internal tcp connector with the given [TransportConnector] + pub fn set_connector(&mut self, connector: TransportConnector) { + self.connector = connector; + } +} + +#[async_trait] +impl HealthCheck for TcpHealthCheck { + fn health_threshold(&self, success: bool) -> usize { + if success { + self.consecutive_success + } else { + self.consecutive_failure + } + } + + async fn check(&self, target: &Backend) -> Result<()> { + let mut peer = self.peer_template.clone(); + peer._address = target.addr.clone(); + self.connector.get_stream(&peer).await.map(|_| {}) + } +} + +type Validator = Box Result<()> + Send + Sync>; + +/// HTTP health check +/// +/// This health check checks if it can receive the expected HTTP(s) response from the given backend. +pub struct HttpHealthCheck { + /// Number of successful check to flip from unhealthy to healthy. + pub consecutive_success: usize, + /// Number of failed check to flip from healthy to unhealthy. + pub consecutive_failure: usize, + /// How to connect to the backend. + /// + /// This field defines settings like the connect timeout and src IP to bind. + /// The SocketAddr of `peer_template` is just a placeholder which will be replaced by the + /// actual address of the backend when the health check runs. + /// + /// Set the `scheme` field to use HTTPs. + pub peer_template: HttpPeer, + /// Whether the underlying TCP/TLS connection can be reused across checks. + /// + /// * `false` will make sure that every health check goes through TCP (and TLS) handshakes. + /// Established connections sometimes hide the issue of firewalls and L4 LB. + /// * `true` will try to reuse connections across checks, this is the more efficient and fast way + /// to perform health checks. + pub reuse_connection: bool, + /// The request header to send to the backend + pub req: RequestHeader, + connector: HttpConnector, + /// Optional field to define how to validate the response from the server. + /// + /// If not set, any response with a `200 OK` is considered a successful check. + pub validator: Option, + /// Sometimes the health check endpoint lives one a different port than the actual backend. + /// Setting this option allows the health check to perform on the given port of the backend IP. + pub port_override: Option, +} + +impl HttpHealthCheck { + /// Create a new [HttpHealthCheck] with the following default settings + /// * connect timeout: 1 second + /// * read timeout: 1 second + /// * req: a GET to the `/` of the given host name + /// * consecutive_success: 1 + /// * consecutive_failure: 1 + /// * reuse_connection: false + /// * validator: `None`, any 200 response is consider successful + pub fn new(host: &str, tls: bool) -> Self { + let mut req = RequestHeader::build("GET", b"/", None).unwrap(); + req.append_header("Host", host).unwrap(); + let sni = if tls { host.into() } else { String::new() }; + let mut peer_template = HttpPeer::new("0.0.0.0:1", tls, sni); + peer_template.options.connection_timeout = Some(Duration::from_secs(1)); + peer_template.options.read_timeout = Some(Duration::from_secs(1)); + HttpHealthCheck { + consecutive_success: 1, + consecutive_failure: 1, + peer_template, + connector: HttpConnector::new(None), + reuse_connection: false, + req, + validator: None, + port_override: None, + } + } + + /// Replace the internal http connector with the given [HttpConnector] + pub fn set_connector(&mut self, connector: HttpConnector) { + self.connector = connector; + } +} + +#[async_trait] +impl HealthCheck for HttpHealthCheck { + fn health_threshold(&self, success: bool) -> usize { + if success { + self.consecutive_success + } else { + self.consecutive_failure + } + } + + async fn check(&self, target: &Backend) -> Result<()> { + let mut peer = self.peer_template.clone(); + peer._address = target.addr.clone(); + if let Some(port) = self.port_override { + peer._address.set_port(port); + } + let session = self.connector.get_http_session(&peer).await?; + + let mut session = session.0; + let req = Box::new(self.req.clone()); + session.write_request_header(req).await?; + + if let Some(read_timeout) = peer.options.read_timeout { + session.set_read_timeout(read_timeout); + } + + session.read_response_header().await?; + + let resp = session.response_header().expect("just read"); + + if let Some(validator) = self.validator.as_ref() { + validator(resp)?; + } else if resp.status != 200 { + return Error::e_explain( + CustomCode("non 200 code", resp.status.as_u16()), + "during http healthcheck", + ); + }; + + while session.read_response_body().await?.is_some() { + // drain the body if any + } + + if self.reuse_connection { + let idle_timeout = peer.idle_timeout(); + self.connector + .release_http_session(session, &peer, idle_timeout) + .await; + } + + Ok(()) + } +} + +#[derive(Clone)] +struct HealthInner { + /// Whether the endpoint is healthy to serve traffic + healthy: bool, + /// Whether the endpoint is allowed to serve traffic independent from its health + enabled: bool, + /// The counter for stateful transition between healthy and unhealthy. + /// When [healthy] is true, this counts the number of consecutive health check failures + /// so that the caller can flip the healthy when a certain threshold is met, and vise versa. + consecutive_counter: usize, +} + +/// Health of backends that can be updated atomically +pub(crate) struct Health(ArcSwap); + +impl Default for Health { + fn default() -> Self { + Health(ArcSwap::new(Arc::new(HealthInner { + healthy: true, // TODO: allow to start with unhealthy + enabled: true, + consecutive_counter: 0, + }))) + } +} + +impl Clone for Health { + fn clone(&self) -> Self { + let inner = self.0.load_full(); + Health(ArcSwap::new(inner)) + } +} + +impl Health { + pub fn ready(&self) -> bool { + let h = self.0.load(); + h.healthy && h.enabled + } + + pub fn enable(&self, enabled: bool) { + let h = self.0.load(); + if h.enabled != enabled { + // clone the inner + let mut new_health = (**h).clone(); + new_health.enabled = enabled; + self.0.store(Arc::new(new_health)); + }; + } + + // return true when the health is flipped + pub fn observe_health(&self, health: bool, flip_threshold: usize) -> bool { + let h = self.0.load(); + let mut flipped = false; + if h.healthy != health { + // opposite health observed, ready to increase the counter + // clone the inner + let mut new_health = (**h).clone(); + new_health.consecutive_counter += 1; + if new_health.consecutive_counter >= flip_threshold { + new_health.healthy = health; + new_health.consecutive_counter = 0; + flipped = true; + } + self.0.store(Arc::new(new_health)); + } else if h.consecutive_counter > 0 { + // observing the same health as the current state. + // reset the counter, if it is non-zero, because it is no longer consecutive + let mut new_health = (**h).clone(); + new_health.consecutive_counter = 0; + self.0.store(Arc::new(new_health)); + } + flipped + } +} + +#[cfg(test)] +mod test { + use super::*; + use crate::SocketAddr; + + #[tokio::test] + async fn test_tcp_check() { + let tcp_check = TcpHealthCheck::default(); + + let backend = Backend { + addr: SocketAddr::Inet("1.1.1.1:80".parse().unwrap()), + weight: 1, + }; + + assert!(tcp_check.check(&backend).await.is_ok()); + + let backend = Backend { + addr: SocketAddr::Inet("1.1.1.1:79".parse().unwrap()), + weight: 1, + }; + + assert!(tcp_check.check(&backend).await.is_err()); + } + + #[tokio::test] + async fn test_tls_check() { + let tls_check = TcpHealthCheck::new_tls("one.one.one.one"); + let backend = Backend { + addr: SocketAddr::Inet("1.1.1.1:443".parse().unwrap()), + weight: 1, + }; + + assert!(tls_check.check(&backend).await.is_ok()); + } + + #[tokio::test] + async fn test_https_check() { + let https_check = HttpHealthCheck::new("one.one.one.one", true); + + let backend = Backend { + addr: SocketAddr::Inet("1.1.1.1:443".parse().unwrap()), + weight: 1, + }; + + assert!(https_check.check(&backend).await.is_ok()); + } + + #[tokio::test] + async fn test_http_custom_check() { + let mut http_check = HttpHealthCheck::new("one.one.one.one", false); + http_check.validator = Some(Box::new(|resp: &ResponseHeader| { + if resp.status == 301 { + Ok(()) + } else { + Error::e_explain( + CustomCode("non 301 code", resp.status.as_u16()), + "during http healthcheck", + ) + } + })); + + let backend = Backend { + addr: SocketAddr::Inet("1.1.1.1:80".parse().unwrap()), + weight: 1, + }; + + http_check.check(&backend).await.unwrap(); + + assert!(http_check.check(&backend).await.is_ok()); + } +} diff --git a/pingora-load-balancing/src/lib.rs b/pingora-load-balancing/src/lib.rs new file mode 100644 index 0000000..60e30ed --- /dev/null +++ b/pingora-load-balancing/src/lib.rs @@ -0,0 +1,487 @@ +// 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. + +//! # Pingora Load Balancing utilities +//! This crate provides common service discovery, health check and load balancing +//! algorithms for proxies to use. + +use arc_swap::ArcSwap; +use futures::FutureExt; +use pingora_core::protocols::l4::socket::SocketAddr; +use pingora_error::{ErrorType, OrErr, Result}; +use std::collections::hash_map::DefaultHasher; +use std::collections::{BTreeSet, HashMap}; +use std::hash::{Hash, Hasher}; +use std::io::Result as IoResult; +use std::net::ToSocketAddrs; +use std::sync::Arc; +use std::time::Duration; + +mod background; +pub mod discovery; +pub mod health_check; +pub mod selection; + +use discovery::ServiceDiscovery; +use health_check::Health; +use selection::UniqueIterator; +use selection::{BackendIter, BackendSelection}; + +pub mod prelude { + pub use crate::health_check::TcpHealthCheck; + pub use crate::selection::RoundRobin; + pub use crate::LoadBalancer; +} + +/// [Backend] represents a server to proxy or connect to. +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug)] +pub struct Backend { + /// The address to the backend server. + pub addr: SocketAddr, + /// The relative weight of the server. Load balancing algorithms will + /// proportionally distributed traffic according to this value. + pub weight: usize, +} + +impl Backend { + /// Create a new [Backend] with `weight` 1. The function will try to parse + /// `addr` into a [std::net::SocketAddr]. + pub fn new(addr: &str) -> Result { + let addr = addr + .parse() + .or_err(ErrorType::InternalError, "invalid socket addr")?; + Ok(Backend { + addr: SocketAddr::Inet(addr), + weight: 1, + }) + // TODO: UDS + } + + pub(crate) fn hash_key(&self) -> u64 { + let mut hasher = DefaultHasher::new(); + self.hash(&mut hasher); + hasher.finish() + } +} + +impl std::ops::Deref for Backend { + type Target = SocketAddr; + + fn deref(&self) -> &Self::Target { + &self.addr + } +} + +impl std::ops::DerefMut for Backend { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.addr + } +} + +impl std::net::ToSocketAddrs for Backend { + type Iter = std::iter::Once; + + fn to_socket_addrs(&self) -> std::io::Result { + self.addr.to_socket_addrs() + } +} + +/// [Backends] is a collection of [Backend]s. +/// +/// It includes a service discovery method (static or dynamic) to discover all +/// the available backends as well as an optionally health check method to probe the liveness +/// of each backend. +pub struct Backends { + discovery: Box, + health_check: Option>, + backends: ArcSwap>, + health: ArcSwap>, +} + +impl Backends { + /// Create a new [Backends] with the given [ServiceDiscovery] implementation. + /// + /// The health check method is by default empty. + pub fn new(discovery: Box) -> Self { + Self { + discovery, + health_check: None, + backends: Default::default(), + health: Default::default(), + } + } + + /// Set the health check method. See [health_check] for the methods provided. + pub fn set_health_check( + &mut self, + hc: Box, + ) { + self.health_check = Some(hc.into()) + } + + /// Return true when the new is different from the current set of backends + fn do_update(&self, new_backends: BTreeSet, enablement: HashMap) -> bool { + if (**self.backends.load()) != new_backends { + let old_health = self.health.load(); + let mut health = HashMap::with_capacity(new_backends.len()); + for backend in new_backends.iter() { + let hash_key = backend.hash_key(); + // use the default health if the backend is new + let backend_health = old_health.get(&hash_key).cloned().unwrap_or_default(); + + // override enablement + if let Some(backend_enabled) = enablement.get(&hash_key) { + backend_health.enable(*backend_enabled); + } + health.insert(hash_key, backend_health); + } + + // TODO: put backend and health under 1 ArcSwap so that this update is atomic + self.backends.store(Arc::new(new_backends)); + self.health.store(Arc::new(health)); + true + } else { + // no backend change, just check enablement + for (hash_key, backend_enabled) in enablement.iter() { + // override enablement if set + // this get should always be Some(_) because we already populate `health`` for all known backends + if let Some(backend_health) = self.health.load().get(hash_key) { + backend_health.enable(*backend_enabled); + } + } + false + } + } + + /// Whether a certain [Backend] is ready to serve traffic. + /// + /// This function returns true when the backend is both healthy and enabled. + /// This function returns true when the health check is unset but the backend is enabled. + /// When the health check is set, this function will return false for the `backend` it + /// doesn't know. + pub fn ready(&self, backend: &Backend) -> bool { + self.health + .load() + .get(&backend.hash_key()) + // Racing: return `None` when this function is called between the + // backend store and the health store + .map_or(self.health_check.is_none(), |h| h.ready()) + } + + /// Manually set if a [Backend] is ready to serve traffic. + /// + /// This method does not override the health of the backend. It is meant to be used + /// to stop a backend from accepting traffic when it is still healthy. + /// + /// This method is noop when the given backend doesn't exist in the service discovery. + pub fn set_enable(&self, backend: &Backend, enabled: bool) { + // this should always be Some(_) because health is always populated during update + if let Some(h) = self.health.load().get(&backend.hash_key()) { + h.enable(enabled) + }; + } + + /// Return the collection of the backends. + pub fn get_backend(&self) -> Arc> { + self.backends.load_full() + } + + /// Call the service discovery method to update the collection of backends. + /// + /// Return `true` when the new collection is different from the current set of backends. + /// This return value is useful to tell the caller when to rebuild things that are expensive to + /// update, such as consistent hashing rings. + pub async fn update(&self) -> Result { + let (new_backends, enablement) = self.discovery.discover().await?; + Ok(self.do_update(new_backends, enablement)) + } + + /// Run health check on all the backend if it is set. + /// + /// When `parallel: true`, all the backends are checked in parallel instead of sequentially + pub async fn run_health_check(&self, parallel: bool) { + use crate::health_check::HealthCheck; + use log::{info, warn}; + use pingora_runtime::current_handle; + + async fn check_and_report( + backend: &Backend, + check: &Arc, + health_table: &HashMap, + ) { + let errored = check.check(backend).await.err(); + if let Some(h) = health_table.get(&backend.hash_key()) { + let flipped = + h.observe_health(errored.is_none(), check.health_threshold(errored.is_none())); + if flipped { + if let Some(e) = errored { + warn!("{backend:?} becomes unhealthy, {e}"); + } else { + info!("{backend:?} becomes healthy"); + } + } + } + } + + let Some(health_check) = self.health_check.as_ref() else { + return; + }; + + let backends = self.backends.load(); + if parallel { + let health_table = self.health.load_full(); + let runtime = current_handle(); + let jobs = backends.iter().map(|backend| { + let backend = backend.clone(); + let check = health_check.clone(); + let ht = health_table.clone(); + runtime.spawn(async move { + check_and_report(&backend, &check, &ht).await; + }) + }); + + futures::future::join_all(jobs).await; + } else { + for backend in backends.iter() { + check_and_report(backend, health_check, &self.health.load()).await; + } + } + } +} + +/// A [LoadBalancer] instance contains the service discovery, health check and backend selection +/// all together. +/// +/// In order to run service discovery and health check at the designated frequencies, the [LoadBalancer] +/// needs to be run as a [pingora_core::services::background::BackgroundService]. +pub struct LoadBalancer { + backends: Backends, + selector: ArcSwap, + /// How frequent the health check logic (if set) should run. + /// + /// If `None`, the health check logic will only run once at the beginning. + pub health_check_frequency: Option, + /// How frequent the service discovery should run. + /// + /// If `None`, the service discovery will only run once at the beginning. + pub update_frequency: Option, + /// Whether to run health check to all backends in parallel. Default is false. + pub parallel_health_check: bool, +} + +impl<'a, S: BackendSelection> LoadBalancer +where + S: BackendSelection + 'static, + S::Iter: BackendIter, +{ + /// Build a [LoadBalancer] with static backends created from the iter. + /// + /// Note: [ToSocketAddrs] will invoke blocking network IO for DNS lookup if + /// the input cannot be directly parsed as [SocketAddr]. + pub fn try_from_iter>(iter: T) -> IoResult + where + A: ToSocketAddrs, + { + let discovery = discovery::Static::try_from_iter(iter)?; + let backends = Backends::new(discovery); + let lb = Self::from_backends(backends); + lb.update() + .now_or_never() + .expect("static should not block") + .expect("static should not error"); + Ok(lb) + } + + /// Build a [LoadBalancer] with the given [Backends]. + pub fn from_backends(backends: Backends) -> Self { + let selector = ArcSwap::new(Arc::new(S::build(&backends.get_backend()))); + LoadBalancer { + backends, + selector, + health_check_frequency: None, + update_frequency: None, + parallel_health_check: false, + } + } + + /// Run the service discovery and update the selection algorithm. + /// + /// This function will be called every `update_frequency` if this [LoadBalancer] instance + /// is running as a background service. + pub async fn update(&self) -> Result<()> { + if self.backends.update().await? { + self.selector + .store(Arc::new(S::build(&self.backends.get_backend()))) + } + Ok(()) + } + + /// Return the first healthy [Backend] according to the selection algorithm and the + /// health check results. + /// + /// The `key` is used for hash based selection and is ignored if the selection is random or + /// round robin. + /// + /// the `max_iterations` is there to bound the search time for the next Backend. In certain + /// algorithm like Ketama hashing, the search for the next backend is linear and could take + /// a lot steps. + // TODO: consider remove `max_iterations` as users have no idea how to set it. + pub fn select(&self, key: &[u8], max_iterations: usize) -> Option { + self.select_with(key, max_iterations, |_, health| health) + } + + /// Similar to [Self::select], return the first healthy [Backend] according to the selection algorithm + /// and the user defined `accept` function. + /// + /// The `accept` function takes two inputs, the backend being selected and the internal health of that + /// backend. The function can do things like ignoring the internal health checks or skipping this backend + /// because it failed before. The `accept` function is called multiple times iterating over backends + /// until it returns `true`. + pub fn select_with(&self, key: &[u8], max_iterations: usize, accept: F) -> Option + where + F: Fn(&Backend, bool) -> bool, + { + let selection = self.selector.load(); + let mut iter = UniqueIterator::new(selection.iter(key), max_iterations); + while let Some(b) = iter.get_next() { + if accept(&b, self.backends.ready(&b)) { + return Some(b); + } + } + None + } + + /// Set the health check method. See [health_check]. + pub fn set_health_check( + &mut self, + hc: Box, + ) { + self.backends.set_health_check(hc); + } + + /// Access the [Backends] of this [LoadBalancer] + pub fn backends(&self) -> &Backends { + &self.backends + } +} + +#[cfg(test)] +mod test { + use super::*; + use async_trait::async_trait; + + #[tokio::test] + async fn test_static_backends() { + let backends: LoadBalancer = + LoadBalancer::try_from_iter(["1.1.1.1:80", "1.0.0.1:80"]).unwrap(); + + let backend1 = Backend::new("1.1.1.1:80").unwrap(); + let backend2 = Backend::new("1.0.0.1:80").unwrap(); + let backend = backends.backends().get_backend(); + assert!(backend.contains(&backend1)); + assert!(backend.contains(&backend2)); + } + + #[tokio::test] + async fn test_backends() { + let discovery = discovery::Static::default(); + let good1 = Backend::new("1.1.1.1:80").unwrap(); + discovery.add(good1.clone()); + let good2 = Backend::new("1.0.0.1:80").unwrap(); + discovery.add(good2.clone()); + let bad = Backend::new("127.0.0.1:79").unwrap(); + discovery.add(bad.clone()); + + let mut backends = Backends::new(Box::new(discovery)); + let check = health_check::TcpHealthCheck::new(); + backends.set_health_check(check); + + // true: new backend discovered + assert!(backends.update().await.unwrap()); + + // false: no new backend discovered + assert!(!backends.update().await.unwrap()); + + backends.run_health_check(false).await; + + let backend = backends.get_backend(); + assert!(backend.contains(&good1)); + assert!(backend.contains(&good2)); + assert!(backend.contains(&bad)); + + assert!(backends.ready(&good1)); + assert!(backends.ready(&good2)); + assert!(!backends.ready(&bad)); + } + + #[tokio::test] + async fn test_discovery_readiness() { + use discovery::Static; + + struct TestDiscovery(Static); + #[async_trait] + impl ServiceDiscovery for TestDiscovery { + async fn discover(&self) -> Result<(BTreeSet, HashMap)> { + let bad = Backend::new("127.0.0.1:79").unwrap(); + let (backends, mut readiness) = self.0.discover().await?; + readiness.insert(bad.hash_key(), false); + Ok((backends, readiness)) + } + } + let discovery = Static::default(); + let good1 = Backend::new("1.1.1.1:80").unwrap(); + discovery.add(good1.clone()); + let good2 = Backend::new("1.0.0.1:80").unwrap(); + discovery.add(good2.clone()); + let bad = Backend::new("127.0.0.1:79").unwrap(); + discovery.add(bad.clone()); + let discovery = TestDiscovery(discovery); + + let backends = Backends::new(Box::new(discovery)); + assert!(backends.update().await.unwrap()); + + let backend = backends.get_backend(); + assert!(backend.contains(&good1)); + assert!(backend.contains(&good2)); + assert!(backend.contains(&bad)); + + assert!(backends.ready(&good1)); + assert!(backends.ready(&good2)); + assert!(!backends.ready(&bad)); + } + + #[tokio::test] + async fn test_parallel_health_check() { + let discovery = discovery::Static::default(); + let good1 = Backend::new("1.1.1.1:80").unwrap(); + discovery.add(good1.clone()); + let good2 = Backend::new("1.0.0.1:80").unwrap(); + discovery.add(good2.clone()); + let bad = Backend::new("127.0.0.1:79").unwrap(); + discovery.add(bad.clone()); + + let mut backends = Backends::new(Box::new(discovery)); + let check = health_check::TcpHealthCheck::new(); + backends.set_health_check(check); + + // true: new backend discovered + assert!(backends.update().await.unwrap()); + + backends.run_health_check(true).await; + + assert!(backends.ready(&good1)); + assert!(backends.ready(&good2)); + assert!(!backends.ready(&bad)); + } +} diff --git a/pingora-load-balancing/src/selection/algorithms.rs b/pingora-load-balancing/src/selection/algorithms.rs new file mode 100644 index 0000000..b17d973 --- /dev/null +++ b/pingora-load-balancing/src/selection/algorithms.rs @@ -0,0 +1,61 @@ +// 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. + +//! Implementation of algorithms for weighted selection +//! +//! All [std::hash::Hasher] + [Default] can be used directly as a selection algorithm. + +use super::*; +use std::hash::Hasher; +use std::sync::atomic::{AtomicUsize, Ordering}; + +impl SelectionAlgorithm for H +where + H: Default + Hasher, +{ + fn new() -> Self { + H::default() + } + fn next(&self, key: &[u8]) -> u64 { + let mut hasher = H::default(); + hasher.write(key); + hasher.finish() + } +} + +/// Round Robin selection +pub struct RoundRobin(AtomicUsize); + +impl SelectionAlgorithm for RoundRobin { + fn new() -> Self { + Self(AtomicUsize::new(0)) + } + fn next(&self, _key: &[u8]) -> u64 { + self.0.fetch_add(1, Ordering::Relaxed) as u64 + } +} + +/// Random selection +pub struct Random; + +impl SelectionAlgorithm for Random { + fn new() -> Self { + Self + } + fn next(&self, _key: &[u8]) -> u64 { + use rand::Rng; + let mut rng = rand::thread_rng(); + rng.gen() + } +} diff --git a/pingora-load-balancing/src/selection/consistent.rs b/pingora-load-balancing/src/selection/consistent.rs new file mode 100644 index 0000000..60c7b9f --- /dev/null +++ b/pingora-load-balancing/src/selection/consistent.rs @@ -0,0 +1,135 @@ +// 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. + +//! Consistent Hashing + +use super::*; +use pingora_core::protocols::l4::socket::SocketAddr; +use pingora_ketama::{Bucket, Continuum}; +use std::collections::HashMap; +use std::sync::Arc; + +/// Weighted Ketama consistent hashing +pub struct KetamaHashing { + ring: Continuum, + // TODO: update Ketama to just store this + backends: HashMap, +} + +impl BackendSelection for KetamaHashing { + type Iter = OwnedNodeIterator; + + fn build(backends: &BTreeSet) -> Self { + let buckets: Vec<_> = backends + .iter() + .filter_map(|b| { + // FIXME: ketama only supports Inet addr, UDS addrs are ignored here + if let SocketAddr::Inet(addr) = b.addr { + Some(Bucket::new(addr, b.weight as u32)) + } else { + None + } + }) + .collect(); + let new_backends = backends + .iter() + .map(|b| (b.addr.clone(), b.clone())) + .collect(); + KetamaHashing { + ring: Continuum::new(&buckets), + backends: new_backends, + } + } + + fn iter(self: &Arc, key: &[u8]) -> Self::Iter { + OwnedNodeIterator { + idx: self.ring.node_idx(key), + ring: self.clone(), + } + } +} + +/// Iterator over a Continuum +pub struct OwnedNodeIterator { + idx: usize, + ring: Arc, +} + +impl BackendIter for OwnedNodeIterator { + fn next(&mut self) -> Option<&Backend> { + self.ring.ring.get_addr(&mut self.idx).and_then(|addr| { + let addr = SocketAddr::Inet(*addr); + self.ring.backends.get(&addr) + }) + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_ketama() { + let b1 = Backend::new("1.1.1.1:80").unwrap(); + let b2 = Backend::new("1.0.0.1:80").unwrap(); + let b3 = Backend::new("1.0.0.255:80").unwrap(); + let backends = BTreeSet::from_iter([b1.clone(), b2.clone(), b3.clone()]); + let hash = Arc::new(KetamaHashing::build(&backends)); + + let mut iter = hash.iter(b"test0"); + assert_eq!(iter.next(), Some(&b2)); + let mut iter = hash.iter(b"test1"); + assert_eq!(iter.next(), Some(&b1)); + let mut iter = hash.iter(b"test2"); + assert_eq!(iter.next(), Some(&b1)); + let mut iter = hash.iter(b"test3"); + assert_eq!(iter.next(), Some(&b1)); + let mut iter = hash.iter(b"test4"); + assert_eq!(iter.next(), Some(&b1)); + let mut iter = hash.iter(b"test5"); + assert_eq!(iter.next(), Some(&b3)); + let mut iter = hash.iter(b"test6"); + assert_eq!(iter.next(), Some(&b1)); + let mut iter = hash.iter(b"test7"); + assert_eq!(iter.next(), Some(&b3)); + let mut iter = hash.iter(b"test8"); + assert_eq!(iter.next(), Some(&b1)); + let mut iter = hash.iter(b"test9"); + assert_eq!(iter.next(), Some(&b2)); + + // remove b3 + let backends = BTreeSet::from_iter([b1.clone(), b2.clone()]); + let hash = Arc::new(KetamaHashing::build(&backends)); + let mut iter = hash.iter(b"test0"); + assert_eq!(iter.next(), Some(&b2)); + let mut iter = hash.iter(b"test1"); + assert_eq!(iter.next(), Some(&b1)); + let mut iter = hash.iter(b"test2"); + assert_eq!(iter.next(), Some(&b1)); + let mut iter = hash.iter(b"test3"); + assert_eq!(iter.next(), Some(&b1)); + let mut iter = hash.iter(b"test4"); + assert_eq!(iter.next(), Some(&b1)); + let mut iter = hash.iter(b"test5"); + assert_eq!(iter.next(), Some(&b2)); // changed + let mut iter = hash.iter(b"test6"); + assert_eq!(iter.next(), Some(&b1)); + let mut iter = hash.iter(b"test7"); + assert_eq!(iter.next(), Some(&b1)); // changed + let mut iter = hash.iter(b"test8"); + assert_eq!(iter.next(), Some(&b1)); + let mut iter = hash.iter(b"test9"); + assert_eq!(iter.next(), Some(&b2)); + } +} diff --git a/pingora-load-balancing/src/selection/mod.rs b/pingora-load-balancing/src/selection/mod.rs new file mode 100644 index 0000000..6320a8e --- /dev/null +++ b/pingora-load-balancing/src/selection/mod.rs @@ -0,0 +1,171 @@ +// 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. + +//! Backend selection interfaces and algorithms + +pub mod algorithms; +pub mod consistent; +pub mod weighted; + +use super::Backend; +use std::collections::{BTreeSet, HashSet}; +use std::sync::Arc; +use weighted::Weighted; + +/// [BackendSelection] is the interface to implement backend selection mechanisms. +pub trait BackendSelection { + /// The [BackendIter] returned from iter() below. + type Iter; + /// The function to create a [BackendSelection] implementation. + fn build(backends: &BTreeSet) -> Self; + /// Select backends for a given key. + /// + /// An [BackendIter] should be returned. The first item in the iter is the first + /// choice backend. The user should continue iterate over it if the first backend + /// cannot be used due to its health or other reasons. + fn iter(self: &Arc, key: &[u8]) -> Self::Iter + where + Self::Iter: BackendIter; +} + +/// An iterator to find the suitable backend +/// +/// Similar to [Iterator] but allow self referencing. +pub trait BackendIter { + /// Return `Some(&Backend)` when there are more backends left to choose from. + fn next(&mut self) -> Option<&Backend>; +} + +/// [SelectionAlgorithm] is the interface to implement selection algorithms. +/// +/// All [std::hash::Hasher] + [Default] can be used directly as a selection algorithm. +pub trait SelectionAlgorithm { + /// Create a new implementation + fn new() -> Self; + /// Return the next index of backend. The caller should perform modulo to get + /// the valid index of the backend. + fn next(&self, key: &[u8]) -> u64; +} + +/// [FVN](https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function) hashing +/// on weighted backends +pub type FVNHash = Weighted; +/// Random selection on weighted backends +pub type Random = Weighted; +/// Round robin selection on weighted backends +pub type RoundRobin = Weighted; +/// Consistent Ketama hashing on weighted backends +pub type Consistent = consistent::KetamaHashing; + +// TODO: least conn + +/// An iterator which wraps another iterator and yields unique items. It optionally takes a max +/// number of iterations if the wrapped iterator never returns. +pub struct UniqueIterator +where + I: BackendIter, +{ + iter: I, + seen: HashSet, + max_iterations: usize, + steps: usize, +} + +impl UniqueIterator +where + I: BackendIter, +{ + /// Wrap a new iterator and specify the maximum number of times we want to iterate. + pub fn new(iter: I, max_iterations: usize) -> Self { + Self { + iter, + max_iterations, + seen: HashSet::new(), + steps: 0, + } + } + + pub fn get_next(&mut self) -> Option { + while let Some(item) = self.iter.next() { + if self.steps >= self.max_iterations { + return None; + } + self.steps += 1; + + let hash_key = item.hash_key(); + if !self.seen.contains(&hash_key) { + self.seen.insert(hash_key); + return Some(item.clone()); + } + } + + None + } +} + +#[cfg(test)] +mod tests { + use super::*; + + struct TestIter { + seq: Vec, + idx: usize, + } + impl TestIter { + fn new(input: &[&Backend]) -> Self { + Self { + seq: input.iter().cloned().cloned().collect(), + idx: 0, + } + } + } + impl BackendIter for TestIter { + fn next(&mut self) -> Option<&Backend> { + let idx = self.idx; + self.idx += 1; + self.seq.get(idx) + } + } + + #[test] + fn unique_iter_max_iterations_is_correct() { + let b1 = Backend::new("1.1.1.1:80").unwrap(); + let b2 = Backend::new("1.0.0.1:80").unwrap(); + let b3 = Backend::new("1.0.0.255:80").unwrap(); + let items = [&b1, &b2, &b3]; + + let mut all = UniqueIterator::new(TestIter::new(&items), 3); + assert_eq!(all.get_next(), Some(b1.clone())); + assert_eq!(all.get_next(), Some(b2.clone())); + assert_eq!(all.get_next(), Some(b3.clone())); + assert_eq!(all.get_next(), None); + + let mut stop = UniqueIterator::new(TestIter::new(&items), 1); + assert_eq!(stop.get_next(), Some(b1)); + assert_eq!(stop.get_next(), None); + } + + #[test] + fn unique_iter_duplicate_items_are_filtered() { + let b1 = Backend::new("1.1.1.1:80").unwrap(); + let b2 = Backend::new("1.0.0.1:80").unwrap(); + let b3 = Backend::new("1.0.0.255:80").unwrap(); + let items = [&b1, &b1, &b2, &b2, &b2, &b3]; + + let mut uniq = UniqueIterator::new(TestIter::new(&items), 10); + assert_eq!(uniq.get_next(), Some(b1)); + assert_eq!(uniq.get_next(), Some(b2)); + assert_eq!(uniq.get_next(), Some(b3)); + } +} diff --git a/pingora-load-balancing/src/selection/weighted.rs b/pingora-load-balancing/src/selection/weighted.rs new file mode 100644 index 0000000..3f37de6 --- /dev/null +++ b/pingora-load-balancing/src/selection/weighted.rs @@ -0,0 +1,208 @@ +// 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. + +//! Weighted Selection + +use super::{Backend, BackendIter, BackendSelection, SelectionAlgorithm}; +use fnv::FnvHasher; +use std::collections::BTreeSet; +use std::sync::Arc; + +/// Weighted selection with a given selection algorithm +/// +/// The default algorithm is [FnvHasher]. See [super::algorithms] for more choices. +pub struct Weighted { + backends: Box<[Backend]>, + // each item is an index to the `backends`, use u16 to save memory, support up to 2^16 backends + weighted: Box<[u16]>, + algorithm: H, +} + +impl BackendSelection for Weighted { + type Iter = WeightedIterator; + + fn build(backends: &BTreeSet) -> Self { + assert!( + backends.len() <= u16::MAX as usize, + "support up to 2^16 backends" + ); + let backends = Vec::from_iter(backends.iter().cloned()).into_boxed_slice(); + let mut weighted = Vec::with_capacity(backends.len()); + for (index, b) in backends.iter().enumerate() { + for _ in 0..b.weight { + weighted.push(index as u16); + } + } + Weighted { + backends, + weighted: weighted.into_boxed_slice(), + algorithm: H::new(), + } + } + + fn iter(self: &Arc, key: &[u8]) -> Self::Iter { + WeightedIterator::new(key, self.clone()) + } +} + +/// An iterator over the backends of a [Weighted] selection. +/// +/// See [super::BackendSelection] for more information. +pub struct WeightedIterator { + // the unbounded index seed + index: u64, + backend: Arc>, + first: bool, +} + +impl WeightedIterator { + /// Constructs a new [WeightedIterator]. + fn new(input: &[u8], backend: Arc>) -> Self { + Self { + index: backend.algorithm.next(input), + backend, + first: true, + } + } +} + +impl BackendIter for WeightedIterator { + fn next(&mut self) -> Option<&Backend> { + if self.backend.backends.is_empty() { + // short circuit if empty + return None; + } + + if self.first { + // initial hash, select from the weighted list + self.first = false; + let len = self.backend.weighted.len(); + let index = self.backend.weighted[self.index as usize % len]; + Some(&self.backend.backends[index as usize]) + } else { + // fallback, select from the unique list + // deterministically select the next item + self.index = self.backend.algorithm.next(&self.index.to_le_bytes()); + let len = self.backend.backends.len(); + Some(&self.backend.backends[self.index as usize % len]) + } + } +} + +#[cfg(test)] +mod test { + use super::super::algorithms::*; + use super::*; + use std::collections::HashMap; + + #[test] + fn test_fnv() { + let b1 = Backend::new("1.1.1.1:80").unwrap(); + let mut b2 = Backend::new("1.0.0.1:80").unwrap(); + b2.weight = 10; // 10x than the rest + let b3 = Backend::new("1.0.0.255:80").unwrap(); + let backends = BTreeSet::from_iter([b1.clone(), b2.clone(), b3.clone()]); + let hash: Arc = Arc::new(Weighted::build(&backends)); + + // same hash iter over + let mut iter = hash.iter(b"test"); + // first, should be weighted + assert_eq!(iter.next(), Some(&b2)); + // fallbacks, should be uniform, not weighted + assert_eq!(iter.next(), Some(&b2)); + assert_eq!(iter.next(), Some(&b2)); + assert_eq!(iter.next(), Some(&b1)); + assert_eq!(iter.next(), Some(&b3)); + assert_eq!(iter.next(), Some(&b2)); + assert_eq!(iter.next(), Some(&b2)); + assert_eq!(iter.next(), Some(&b1)); + assert_eq!(iter.next(), Some(&b2)); + assert_eq!(iter.next(), Some(&b3)); + assert_eq!(iter.next(), Some(&b1)); + + // different hashes, the first selection should be weighted + let mut iter = hash.iter(b"test1"); + assert_eq!(iter.next(), Some(&b2)); + let mut iter = hash.iter(b"test2"); + assert_eq!(iter.next(), Some(&b2)); + let mut iter = hash.iter(b"test3"); + assert_eq!(iter.next(), Some(&b3)); + let mut iter = hash.iter(b"test4"); + assert_eq!(iter.next(), Some(&b1)); + let mut iter = hash.iter(b"test5"); + assert_eq!(iter.next(), Some(&b2)); + let mut iter = hash.iter(b"test6"); + assert_eq!(iter.next(), Some(&b2)); + let mut iter = hash.iter(b"test7"); + assert_eq!(iter.next(), Some(&b2)); + } + + #[test] + fn test_round_robin() { + let b1 = Backend::new("1.1.1.1:80").unwrap(); + let mut b2 = Backend::new("1.0.0.1:80").unwrap(); + b2.weight = 8; // 8x than the rest + let b3 = Backend::new("1.0.0.255:80").unwrap(); + let backends = BTreeSet::from_iter([b1.clone(), b2.clone(), b3.clone()]); + let hash: Arc> = Arc::new(Weighted::build(&backends)); + + // same hash iter over + let mut iter = hash.iter(b"test"); + // first, should be weighted + assert_eq!(iter.next(), Some(&b2)); + // fallbacks, should be round robin + assert_eq!(iter.next(), Some(&b3)); + assert_eq!(iter.next(), Some(&b1)); + assert_eq!(iter.next(), Some(&b2)); + assert_eq!(iter.next(), Some(&b3)); + + // round robin, ignoring the hash key + let mut iter = hash.iter(b"test1"); + assert_eq!(iter.next(), Some(&b2)); + let mut iter = hash.iter(b"test1"); + assert_eq!(iter.next(), Some(&b2)); + let mut iter = hash.iter(b"test1"); + assert_eq!(iter.next(), Some(&b2)); + let mut iter = hash.iter(b"test1"); + assert_eq!(iter.next(), Some(&b3)); + let mut iter = hash.iter(b"test1"); + assert_eq!(iter.next(), Some(&b1)); + let mut iter = hash.iter(b"test1"); + assert_eq!(iter.next(), Some(&b2)); + let mut iter = hash.iter(b"test1"); + assert_eq!(iter.next(), Some(&b2)); + } + + #[test] + fn test_random() { + let b1 = Backend::new("1.1.1.1:80").unwrap(); + let mut b2 = Backend::new("1.0.0.1:80").unwrap(); + b2.weight = 8; // 8x than the rest + let b3 = Backend::new("1.0.0.255:80").unwrap(); + let backends = BTreeSet::from_iter([b1.clone(), b2.clone(), b3.clone()]); + let hash: Arc> = Arc::new(Weighted::build(&backends)); + + let mut count = HashMap::new(); + count.insert(b1.clone(), 0); + count.insert(b2.clone(), 0); + count.insert(b3.clone(), 0); + + for _ in 0..100 { + let mut iter = hash.iter(b"test"); + *count.get_mut(iter.next().unwrap()).unwrap() += 1; + } + let b2_count = *count.get(&b2).unwrap(); + assert!((70..=90).contains(&b2_count)); + } +} diff --git a/pingora-lru/Cargo.toml b/pingora-lru/Cargo.toml new file mode 100644 index 0000000..69851c3 --- /dev/null +++ b/pingora-lru/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "pingora-lru" +version = "0.1.0" +authors = ["Yuchen Wu "] +license = "Apache-2.0" +edition = "2021" +repository = "https://github.com/cloudflare/pingora" +categories = ["algorithms", "caching"] +keywords = ["lru", "cache", "pingora"] +description = """ +LRU cache that focuses on memory efficiency, concurrency and persistence. +""" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +name = "pingora_lru" +path = "src/lib.rs" + +[dependencies] +hashbrown = "0" +parking_lot = "0" +arrayvec = "0" +rand = "0" + +[dev-dependencies] +lru = { workspace = true } + +[[bench]] +name = "bench_linked_list" +harness = false + +[[bench]] +name = "bench_lru" +harness = false diff --git a/pingora-lru/LICENSE b/pingora-lru/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/pingora-lru/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/pingora-lru/benches/bench_linked_list.rs b/pingora-lru/benches/bench_linked_list.rs new file mode 100644 index 0000000..7d90da9 --- /dev/null +++ b/pingora-lru/benches/bench_linked_list.rs @@ -0,0 +1,144 @@ +// 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 std::time::Instant; + +fn main() { + const ITEMS: usize = 5_000_000; + + // push bench + + let mut std_list = std::collections::LinkedList::::new(); + let before = Instant::now(); + for _ in 0..ITEMS { + std_list.push_front(0); + } + let elapsed = before.elapsed(); + println!( + "std linked list push_front total {elapsed:?}, {:?} avg per operation", + elapsed / ITEMS as u32 + ); + + let mut list = pingora_lru::linked_list::LinkedList::with_capacity(ITEMS); + let before = Instant::now(); + for _ in 0..ITEMS { + list.push_head(0); + } + let elapsed = before.elapsed(); + println!( + "pingora linked list push_head total {elapsed:?}, {:?} avg per operation", + elapsed / ITEMS as u32 + ); + + // iter bench + + let mut count = 0; + let before = Instant::now(); + for _ in std_list.iter() { + count += 1; + } + let elapsed = before.elapsed(); + println!( + "std linked list iter total {count} {elapsed:?}, {:?} avg per operation", + elapsed / count as u32 + ); + + let mut count = 0; + let before = Instant::now(); + for _ in list.iter() { + count += 1; + } + let elapsed = before.elapsed(); + println!( + "pingora linked list iter total {count} {elapsed:?}, {:?} avg per operation", + elapsed / count as u32 + ); + + // search bench + + let before = Instant::now(); + for _ in 0..ITEMS { + assert!(!std_list.iter().take(10).any(|v| *v == 1)); + } + let elapsed = before.elapsed(); + println!( + "std linked search first 10 items total {elapsed:?}, {:?} avg per operation", + elapsed / ITEMS as u32 + ); + + let before = Instant::now(); + for _ in 0..ITEMS { + assert!(!list.iter().take(10).any(|v| *v == 1)); + } + let elapsed = before.elapsed(); + println!( + "pingora linked search first 10 items total {elapsed:?}, {:?} avg per operation", + elapsed / ITEMS as u32 + ); + + let before = Instant::now(); + for _ in 0..ITEMS { + assert!(!list.exist_near_head(1, 10)); + } + let elapsed = before.elapsed(); + println!( + "pingora linked optimized search first 10 items total {elapsed:?}, {:?} avg per operation", + elapsed / ITEMS as u32 + ); + + // move node bench + let before = Instant::now(); + for _ in 0..ITEMS { + let value = std_list.pop_back().unwrap(); + std_list.push_front(value); + } + let elapsed = before.elapsed(); + println!( + "std linked list move back to front total {elapsed:?}, {:?} avg per operation", + elapsed / ITEMS as u32 + ); + + let before = Instant::now(); + for _ in 0..ITEMS { + let index = list.tail().unwrap(); + list.promote(index); + } + let elapsed = before.elapsed(); + println!( + "pingora linked list move tail to head total {elapsed:?}, {:?} avg per operation", + elapsed / ITEMS as u32 + ); + + // pop bench + + let before = Instant::now(); + for _ in 0..ITEMS { + std_list.pop_back(); + } + let elapsed = before.elapsed(); + println!( + "std linked list pop_back {elapsed:?}, {:?} avg per operation", + elapsed / ITEMS as u32 + ); + + let before = Instant::now(); + for _ in 0..ITEMS { + list.pop_tail(); + } + let elapsed = before.elapsed(); + println!( + "pingora linked list pop_tail total {elapsed:?}, {:?} avg per operation", + elapsed / ITEMS as u32 + ); +} diff --git a/pingora-lru/benches/bench_lru.rs b/pingora-lru/benches/bench_lru.rs new file mode 100644 index 0000000..25d8bbb --- /dev/null +++ b/pingora-lru/benches/bench_lru.rs @@ -0,0 +1,148 @@ +// 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 rand::distributions::WeightedIndex; +use rand::prelude::*; +use std::sync::Arc; +use std::thread; +use std::time::Instant; + +// Non-uniform distributions, 100 items, 10 of them are 100x more likely to appear +const WEIGHTS: &[usize] = &[ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 100, 100, 100, + 100, 100, 100, 100, 100, 100, 100, +]; + +const ITERATIONS: usize = 5_000_000; +const THREADS: usize = 8; + +fn main() { + let lru = parking_lot::Mutex::new(lru::LruCache::::unbounded()); + + let plru = pingora_lru::Lru::<(), 10>::with_capacity(1000, 100); + // populate first, then we bench access/promotion + for i in 0..WEIGHTS.len() { + lru.lock().put(i as u64, ()); + } + for i in 0..WEIGHTS.len() { + plru.admit(i as u64, (), 1); + } + + // single thread + let mut rng = thread_rng(); + let dist = WeightedIndex::new(WEIGHTS).unwrap(); + + let before = Instant::now(); + for _ in 0..ITERATIONS { + lru.lock().get(&(dist.sample(&mut rng) as u64)); + } + let elapsed = before.elapsed(); + println!( + "lru promote total {elapsed:?}, {:?} avg per operation", + elapsed / ITERATIONS as u32 + ); + + let before = Instant::now(); + for _ in 0..ITERATIONS { + plru.promote(dist.sample(&mut rng) as u64); + } + let elapsed = before.elapsed(); + println!( + "pingora lru promote total {elapsed:?}, {:?} avg per operation", + elapsed / ITERATIONS as u32 + ); + + let before = Instant::now(); + for _ in 0..ITERATIONS { + plru.promote_top_n(dist.sample(&mut rng) as u64, 10); + } + let elapsed = before.elapsed(); + println!( + "pingora lru promote_top_10 total {elapsed:?}, {:?} avg per operation", + elapsed / ITERATIONS as u32 + ); + + // concurrent + + let lru = Arc::new(lru); + let mut handlers = vec![]; + for i in 0..THREADS { + let lru = lru.clone(); + let handler = thread::spawn(move || { + let mut rng = thread_rng(); + let dist = WeightedIndex::new(WEIGHTS).unwrap(); + let before = Instant::now(); + for _ in 0..ITERATIONS { + lru.lock().get(&(dist.sample(&mut rng) as u64)); + } + let elapsed = before.elapsed(); + println!( + "lru promote total {elapsed:?}, {:?} avg per operation thread {i}", + elapsed / ITERATIONS as u32 + ); + }); + handlers.push(handler); + } + for thread in handlers { + thread.join().unwrap(); + } + + let plru = Arc::new(plru); + + let mut handlers = vec![]; + for i in 0..THREADS { + let plru = plru.clone(); + let handler = thread::spawn(move || { + let mut rng = thread_rng(); + let dist = WeightedIndex::new(WEIGHTS).unwrap(); + let before = Instant::now(); + for _ in 0..ITERATIONS { + plru.promote(dist.sample(&mut rng) as u64); + } + let elapsed = before.elapsed(); + println!( + "pingora lru promote total {elapsed:?}, {:?} avg per operation thread {i}", + elapsed / ITERATIONS as u32 + ); + }); + handlers.push(handler); + } + for thread in handlers { + thread.join().unwrap(); + } + + let mut handlers = vec![]; + for i in 0..THREADS { + let plru = plru.clone(); + let handler = thread::spawn(move || { + let mut rng = thread_rng(); + let dist = WeightedIndex::new(WEIGHTS).unwrap(); + let before = Instant::now(); + for _ in 0..ITERATIONS { + plru.promote_top_n(dist.sample(&mut rng) as u64, 10); + } + let elapsed = before.elapsed(); + println!( + "pingora lru promote_top_10 total {elapsed:?}, {:?} avg per operation thread {i}", + elapsed / ITERATIONS as u32 + ); + }); + handlers.push(handler); + } + for thread in handlers { + thread.join().unwrap(); + } +} diff --git a/pingora-lru/src/lib.rs b/pingora-lru/src/lib.rs new file mode 100644 index 0000000..a2ddf40 --- /dev/null +++ b/pingora-lru/src/lib.rs @@ -0,0 +1,661 @@ +// 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. + +//! An implementation of a LRU that focuses on memory efficiency, concurrency and persistence +//! +//! Features +//! - keys can have different sizes +//! - LRUs are sharded to avoid global locks. +//! - Memory layout and usage are optimized: small and no memory fragmentation + +pub mod linked_list; + +use linked_list::{LinkedList, LinkedListIter}; + +use hashbrown::HashMap; +use parking_lot::RwLock; +use std::sync::atomic::{AtomicUsize, Ordering}; + +/// The LRU with `N` shards +pub struct Lru { + units: [RwLock>; N], + weight: AtomicUsize, + weight_limit: usize, + len: AtomicUsize, + evicted_weight: AtomicUsize, + evicted_len: AtomicUsize, +} + +impl Lru { + /// Create an [Lru] with the given weight limit and predicted capacity. + /// + /// The capacity is per shard (for simplicity). So the total capacity = capacity * N + pub fn with_capacity(weight_limit: usize, capacity: usize) -> Self { + // use the unsafe code from ArrayVec just to init the array + let mut units = arrayvec::ArrayVec::<_, N>::new(); + for _ in 0..N { + units.push(RwLock::new(LruUnit::with_capacity(capacity))); + } + Lru { + // we did init all N elements so safe to unwrap + // map_err because unwrap() requires LruUnit to TODO: impl Debug + units: units.into_inner().map_err(|_| "").unwrap(), + weight: AtomicUsize::new(0), + weight_limit, + len: AtomicUsize::new(0), + evicted_weight: AtomicUsize::new(0), + evicted_len: AtomicUsize::new(0), + } + } + + /// Admit the key value to the [Lru] + /// + /// Return the shard index which the asset is added to + pub fn admit(&self, key: u64, data: T, weight: usize) -> usize { + let shard = get_shard(key, N); + let unit = &mut self.units[shard].write(); + + // Make sure weight is positive otherwise eviction won't work + // TODO: Probably should use NonZeroUsize instead + let weight = if weight == 0 { 1 } else { weight }; + + let old_weight = unit.admit(key, data, weight); + if old_weight != weight { + self.weight.fetch_add(weight, Ordering::Relaxed); + if old_weight > 0 { + self.weight.fetch_sub(old_weight, Ordering::Relaxed); + } else { + // Assume old_weight == 0 means a new item is admitted + self.len.fetch_add(1, Ordering::Relaxed); + } + } + shard + } + + /// Promote the key to the head of the LRU + /// + /// Return `true` if the key exist. + pub fn promote(&self, key: u64) -> bool { + self.units[get_shard(key, N)].write().access(key) + } + + /// Promote to the top n of the LRU + /// + /// This function is a bit more efficient in terms of reducing lock contention because it + /// will acquire a write lock only if the key is outside top n but only acquires a read lock + /// when the key is already in the top n. + /// + /// Return false if the item doesn't exist + pub fn promote_top_n(&self, key: u64, top: usize) -> bool { + let unit = &self.units[get_shard(key, N)]; + if !unit.read().need_promote(key, top) { + return true; + } + unit.write().access(key) + } + + /// Evict at most one item from the given shard + /// + /// Return the evicted asset and its size if there is anything to evict + pub fn evict_shard(&self, shard: u64) -> Option<(T, usize)> { + let evicted = self.units[get_shard(shard, N)].write().evict(); + if let Some((_, weight)) = evicted.as_ref() { + self.weight.fetch_sub(*weight, Ordering::Relaxed); + self.len.fetch_sub(1, Ordering::Relaxed); + self.evicted_weight.fetch_add(*weight, Ordering::Relaxed); + self.evicted_len.fetch_add(1, Ordering::Relaxed); + } + evicted + } + + /// Evict the [Lru] until the overall weight is below the limit. + /// + /// Return a list of evicted items. + /// + /// The evicted items are randomly selected from all the shards. + pub fn evict_to_limit(&self) -> Vec<(T, usize)> { + let mut evicted = vec![]; + let mut initial_weight = self.weight(); + let mut shard_seed = rand::random(); // start from a random shard + let mut empty_shard = 0; + + // Entries can be admitted or removed from the LRU by others during the loop below + // Track initial_weight not to over evict due to entries admitted after the loop starts + // self.weight() is also used not to over evict due to some entries are removed by others + while initial_weight > self.weight_limit + && self.weight() > self.weight_limit + && empty_shard < N + { + if let Some(i) = self.evict_shard(shard_seed) { + initial_weight -= i.1; + evicted.push(i) + } else { + empty_shard += 1; + } + // move on to the next shard + shard_seed += 1; + } + evicted + } + + /// Remove the given asset + pub fn remove(&self, key: u64) -> Option<(T, usize)> { + let removed = self.units[get_shard(key, N)].write().remove(key); + if let Some((_, weight)) = removed.as_ref() { + self.weight.fetch_sub(*weight, Ordering::Relaxed); + self.len.fetch_sub(1, Ordering::Relaxed); + } + removed + } + + /// Insert the item to the tail of this LRU + /// + /// Useful to recreate an LRU in most-to-least order + pub fn insert_tail(&self, key: u64, data: T, weight: usize) -> bool { + if self.units[get_shard(key, N)] + .write() + .insert_tail(key, data, weight) + { + self.weight.fetch_add(weight, Ordering::Relaxed); + self.len.fetch_add(1, Ordering::Relaxed); + true + } else { + false + } + } + + /// Check existence of a key without changing the order in LRU + pub fn peek(&self, key: u64) -> bool { + self.units[get_shard(key, N)].read().peek(key).is_some() + } + + /// Return the current total weight + pub fn weight(&self) -> usize { + self.weight.load(Ordering::Relaxed) + } + + /// Return the total weight of items evicted from this [Lru]. + pub fn evicted_weight(&self) -> usize { + self.evicted_weight.load(Ordering::Relaxed) + } + + /// Return the total count of items evicted from this [Lru]. + pub fn evicted_len(&self) -> usize { + self.evicted_len.load(Ordering::Relaxed) + } + + /// The number of items inside this [Lru]. + #[allow(clippy::len_without_is_empty)] + pub fn len(&self) -> usize { + self.len.load(Ordering::Relaxed) + } + + /// Scan a shard with the given function F + pub fn iter_for_each(&self, shard: usize, f: F) + where + F: FnMut((&T, usize)), + { + assert!(shard < N); + self.units[shard].read().iter().for_each(f); + } + + /// Get the total number of shards + pub const fn shards(&self) -> usize { + N + } + + /// Get the number of items inside a shard + pub fn shard_len(&self, shard: usize) -> usize { + self.units[shard].read().len() + } +} + +#[inline] +fn get_shard(key: u64, n_shards: usize) -> usize { + (key % n_shards as u64) as usize +} + +struct LruNode { + data: T, + list_index: usize, + weight: usize, +} + +struct LruUnit { + lookup_table: HashMap>>, + order: LinkedList, + used_weight: usize, +} + +impl LruUnit { + fn with_capacity(capacity: usize) -> Self { + LruUnit { + lookup_table: HashMap::with_capacity(capacity), + order: LinkedList::with_capacity(capacity), + used_weight: 0, + } + } + + pub fn peek(&self, key: u64) -> Option<&T> { + self.lookup_table.get(&key).map(|n| &n.data) + } + + // admin into LRU, return old weight if there was any + pub fn admit(&mut self, key: u64, data: T, weight: usize) -> usize { + if let Some(node) = self.lookup_table.get_mut(&key) { + let old_weight = node.weight; + if weight != old_weight { + self.used_weight += weight; + self.used_weight -= old_weight; + node.weight = weight; + } + node.data = data; + self.order.promote(node.list_index); + return old_weight; + } + self.used_weight += weight; + let list_index = self.order.push_head(key); + let node = Box::new(LruNode { + data, + list_index, + weight, + }); + self.lookup_table.insert(key, node); + 0 + } + + pub fn access(&mut self, key: u64) -> bool { + if let Some(node) = self.lookup_table.get(&key) { + self.order.promote(node.list_index); + true + } else { + false + } + } + + // Check if a key is already in the top n most recently used nodes. + // this is a heuristic to reduce write, which requires exclusive locks, for promotion, + // especially on very populate nodes + // NOTE: O(n) search here so limit needs to be small + pub fn need_promote(&self, key: u64, limit: usize) -> bool { + !self.order.exist_near_head(key, limit) + } + + // try to evict 1 node + pub fn evict(&mut self) -> Option<(T, usize)> { + self.order.pop_tail().map(|key| { + // unwrap is safe because we always insert in both the hashtable and the list + let node = self.lookup_table.remove(&key).unwrap(); + self.used_weight -= node.weight; + (node.data, node.weight) + }) + } + // TODO: scan the tail up to K elements to decide which ones to evict + + pub fn remove(&mut self, key: u64) -> Option<(T, usize)> { + self.lookup_table.remove(&key).map(|node| { + let list_key = self.order.remove(node.list_index); + assert_eq!(key, list_key); + (node.data, node.weight) + }) + } + + pub fn insert_tail(&mut self, key: u64, data: T, weight: usize) -> bool { + if self.lookup_table.contains_key(&key) { + return false; + } + let list_index = self.order.push_tail(key); + let node = Box::new(LruNode { + data, + list_index, + weight, + }); + self.lookup_table.insert(key, node); + true + } + + pub fn len(&self) -> usize { + assert_eq!(self.lookup_table.len(), self.order.len()); + self.lookup_table.len() + } + + #[cfg(test)] + pub fn used_weight(&self) -> usize { + self.used_weight + } + + pub fn iter(&self) -> LruUnitIter<'_, T> { + LruUnitIter { + unit: self, + iter: self.order.iter(), + } + } +} + +struct LruUnitIter<'a, T> { + unit: &'a LruUnit, + iter: LinkedListIter<'a>, +} + +impl<'a, T> Iterator for LruUnitIter<'a, T> { + type Item = (&'a T, usize); + + fn next(&mut self) -> Option { + self.iter.next().map(|key| { + // safe because we always items in table and list are always 1:1 + let node = self.unit.lookup_table.get(key).unwrap(); + (&node.data, node.weight) + }) + } + + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() + } +} + +impl<'a, T> DoubleEndedIterator for LruUnitIter<'a, T> { + fn next_back(&mut self) -> Option { + self.iter.next_back().map(|key| { + // safe because we always items in table and list are always 1:1 + let node = self.unit.lookup_table.get(key).unwrap(); + (&node.data, node.weight) + }) + } +} + +#[cfg(test)] +mod test_lru { + use super::*; + + fn assert_lru( + lru: &Lru, + values: &[T], + shard: usize, + ) { + let mut list_values = vec![]; + lru.iter_for_each(shard, |(v, _)| list_values.push(*v)); + assert_eq!(values, &list_values) + } + + #[test] + fn test_admit() { + let lru = Lru::<_, 2>::with_capacity(30, 10); + assert_eq!(lru.len(), 0); + + lru.admit(2, 2, 3); + assert_eq!(lru.len(), 1); + assert_eq!(lru.weight(), 3); + + lru.admit(2, 2, 1); + assert_eq!(lru.len(), 1); + assert_eq!(lru.weight(), 1); + + lru.admit(2, 2, 2); // admit again with different weight + assert_eq!(lru.len(), 1); + assert_eq!(lru.weight(), 2); + + lru.admit(3, 3, 3); + lru.admit(4, 4, 4); + + assert_eq!(lru.weight(), 2 + 3 + 4); + assert_eq!(lru.len(), 3); + } + + #[test] + fn test_promote() { + let lru = Lru::<_, 2>::with_capacity(30, 10); + + lru.admit(2, 2, 2); + lru.admit(3, 3, 3); + lru.admit(4, 4, 4); + lru.admit(5, 5, 5); + lru.admit(6, 6, 6); + assert_lru(&lru, &[6, 4, 2], 0); + assert_lru(&lru, &[5, 3], 1); + + assert!(lru.promote(3)); + assert_lru(&lru, &[3, 5], 1); + assert!(lru.promote(3)); + assert_lru(&lru, &[3, 5], 1); + + assert!(lru.promote(2)); + assert_lru(&lru, &[2, 6, 4], 0); + + assert!(!lru.promote(7)); // 7 doesn't exist + assert_lru(&lru, &[2, 6, 4], 0); + assert_lru(&lru, &[3, 5], 1); + + // promote 2 to top 1, already there + assert!(lru.promote_top_n(2, 1)); + assert_lru(&lru, &[2, 6, 4], 0); + + // promote 4 to top 3, already there + assert!(lru.promote_top_n(4, 3)); + assert_lru(&lru, &[2, 6, 4], 0); + + // promote 4 to top 2 + assert!(lru.promote_top_n(4, 2)); + assert_lru(&lru, &[4, 2, 6], 0); + + // promote 2 to top 1 + assert!(lru.promote_top_n(2, 1)); + assert_lru(&lru, &[2, 4, 6], 0); + + assert!(!lru.promote_top_n(7, 1)); // 7 doesn't exist + } + + #[test] + fn test_evict() { + let lru = Lru::<_, 2>::with_capacity(14, 10); + + // same weight to make the random eviction less random + lru.admit(2, 2, 2); + lru.admit(3, 3, 2); + lru.admit(4, 4, 4); + lru.admit(5, 5, 4); + lru.admit(6, 6, 2); + lru.admit(7, 7, 2); + + assert_lru(&lru, &[6, 4, 2], 0); + assert_lru(&lru, &[7, 5, 3], 1); + + assert_eq!(lru.weight(), 16); + assert_eq!(lru.len(), 6); + + let evicted = lru.evict_to_limit(); + assert_eq!(lru.weight(), 14); + assert_eq!(lru.len(), 5); + assert_eq!(lru.evicted_weight(), 2); + assert_eq!(lru.evicted_len(), 1); + assert_eq!(evicted.len(), 1); + assert_eq!(evicted[0].1, 2); //weight + assert!(evicted[0].0 == 2 || evicted[0].0 == 3); //either 2 or 3 are evicted + + let lru = Lru::<_, 2>::with_capacity(6, 10); + + // same weight random eviction less random + lru.admit(2, 2, 2); + lru.admit(3, 3, 2); + lru.admit(4, 4, 2); + lru.admit(5, 5, 2); + lru.admit(6, 6, 2); + lru.admit(7, 7, 2); + assert_eq!(lru.weight(), 12); + assert_eq!(lru.len(), 6); + + let evicted = lru.evict_to_limit(); + // NOTE: there is a low chance this test would fail see the TODO in evict_to_limit + assert_eq!(lru.weight(), 6); + assert_eq!(lru.len(), 3); + assert_eq!(lru.evicted_weight(), 6); + assert_eq!(lru.evicted_len(), 3); + assert_eq!(evicted.len(), 3); + } + + #[test] + fn test_remove() { + let lru = Lru::<_, 2>::with_capacity(30, 10); + lru.admit(2, 2, 2); + lru.admit(3, 3, 3); + lru.admit(4, 4, 4); + lru.admit(5, 5, 5); + lru.admit(6, 6, 6); + + assert_eq!(lru.weight(), 2 + 3 + 4 + 5 + 6); + assert_eq!(lru.len(), 5); + assert_lru(&lru, &[6, 4, 2], 0); + assert_lru(&lru, &[5, 3], 1); + + let node = lru.remove(6).unwrap(); + assert_eq!(node.0, 6); // data + assert_eq!(node.1, 6); // weight + assert_eq!(lru.weight(), 2 + 3 + 4 + 5); + assert_eq!(lru.len(), 4); + assert_lru(&lru, &[4, 2], 0); + + let node = lru.remove(3).unwrap(); + assert_eq!(node.0, 3); // data + assert_eq!(node.1, 3); // weight + assert_eq!(lru.weight(), 2 + 4 + 5); + assert_eq!(lru.len(), 3); + assert_lru(&lru, &[5], 1); + + assert!(lru.remove(7).is_none()); + } + + #[test] + fn test_peek() { + let lru = Lru::<_, 2>::with_capacity(30, 10); + lru.admit(2, 2, 2); + lru.admit(3, 3, 3); + lru.admit(4, 4, 4); + + assert!(lru.peek(4)); + assert!(lru.peek(3)); + assert!(lru.peek(2)); + + assert_lru(&lru, &[4, 2], 0); + assert_lru(&lru, &[3], 1); + } + + #[test] + fn test_insert_tail() { + let lru = Lru::<_, 2>::with_capacity(30, 10); + lru.admit(2, 2, 2); + lru.admit(3, 3, 3); + lru.admit(4, 4, 4); + lru.admit(5, 5, 5); + lru.admit(6, 6, 6); + + assert_eq!(lru.weight(), 2 + 3 + 4 + 5 + 6); + assert_eq!(lru.len(), 5); + assert_lru(&lru, &[6, 4, 2], 0); + assert_lru(&lru, &[5, 3], 1); + + assert!(lru.insert_tail(7, 7, 7)); + assert_eq!(lru.weight(), 2 + 3 + 4 + 5 + 6 + 7); + assert_eq!(lru.len(), 6); + assert_lru(&lru, &[5, 3, 7], 1); + + // ignore existing ones + assert!(!lru.insert_tail(6, 6, 7)); + } +} + +#[cfg(test)] +mod test_lru_unit { + use super::*; + + fn assert_lru(lru: &LruUnit, values: &[T]) { + let list_values: Vec<_> = lru.iter().map(|(v, _)| *v).collect(); + assert_eq!(values, &list_values) + } + + #[test] + fn test_admit() { + let mut lru = LruUnit::with_capacity(10); + assert_eq!(lru.len(), 0); + assert!(lru.peek(0).is_none()); + + lru.admit(2, 2, 1); + assert_eq!(lru.len(), 1); + assert_eq!(lru.peek(2).unwrap(), &2); + assert_eq!(lru.used_weight(), 1); + + lru.admit(2, 2, 2); // admit again with different weight + assert_eq!(lru.used_weight(), 2); + + lru.admit(3, 3, 3); + lru.admit(4, 4, 4); + + assert_eq!(lru.used_weight(), 2 + 3 + 4); + assert_lru(&lru, &[4, 3, 2]); + } + + #[test] + fn test_access() { + let mut lru = LruUnit::with_capacity(10); + + lru.admit(2, 2, 2); + lru.admit(3, 3, 3); + lru.admit(4, 4, 4); + assert_lru(&lru, &[4, 3, 2]); + + assert!(lru.access(3)); + assert_lru(&lru, &[3, 4, 2]); + assert!(lru.access(3)); + assert_lru(&lru, &[3, 4, 2]); + assert!(lru.access(2)); + assert_lru(&lru, &[2, 3, 4]); + + assert!(!lru.access(5)); // 5 doesn't exist + assert_lru(&lru, &[2, 3, 4]); + + assert!(!lru.need_promote(2, 1)); + assert!(lru.need_promote(3, 1)); + assert!(!lru.need_promote(4, 9999)); + } + + #[test] + fn test_evict() { + let mut lru = LruUnit::with_capacity(10); + + lru.admit(2, 2, 2); + lru.admit(3, 3, 3); + lru.admit(4, 4, 4); + assert_lru(&lru, &[4, 3, 2]); + + assert!(lru.access(3)); + assert!(lru.access(3)); + assert!(lru.access(2)); + assert_lru(&lru, &[2, 3, 4]); + + assert_eq!(lru.used_weight(), 2 + 3 + 4); + assert_eq!(lru.evict(), Some((4, 4))); + assert_eq!(lru.used_weight(), 2 + 3); + assert_lru(&lru, &[2, 3]); + + assert_eq!(lru.evict(), Some((3, 3))); + assert_eq!(lru.used_weight(), 2); + assert_lru(&lru, &[2]); + + assert_eq!(lru.evict(), Some((2, 2))); + assert_eq!(lru.used_weight(), 0); + assert_lru(&lru, &[]); + + assert_eq!(lru.evict(), None); + assert_eq!(lru.used_weight(), 0); + assert_lru(&lru, &[]); + } +} diff --git a/pingora-lru/src/linked_list.rs b/pingora-lru/src/linked_list.rs new file mode 100644 index 0000000..7664aaf --- /dev/null +++ b/pingora-lru/src/linked_list.rs @@ -0,0 +1,439 @@ +// 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. + +// Can't tell people you know Rust until you write a (doubly) linked list + +//! Doubly linked list +//! +//! Features +//! - Preallocate consecutive memory, no memory fragmentation. +//! - No shrink function: for Lru cache that grows to a certain size but never shrink. +//! - Relatively fast and efficient. + +// inspired by clru::FixedSizeList (Élie!) + +use std::mem::replace; + +type Index = usize; +const NULL: Index = usize::MAX; +const HEAD: Index = 0; +const TAIL: Index = 1; +const OFFSET: usize = 2; + +#[derive(Debug)] +struct Node { + pub(crate) prev: Index, + pub(crate) next: Index, + pub(crate) data: u64, +} + +// Functionally the same as vec![head, tail, data_nodes...] where head & tail are fixed and +// the rest data nodes can expand. Both head and tail can be accessed faster than using index +struct Nodes { + // we use these sentinel nodes to guard the head and tail of the list so that list + // manipulation is simpler (fewer if-else) + head: Node, + tail: Node, + data_nodes: Vec, +} + +impl Nodes { + fn with_capacity(capacity: usize) -> Self { + Nodes { + head: Node { + prev: NULL, + next: TAIL, + data: 0, + }, + tail: Node { + prev: HEAD, + next: NULL, + data: 0, + }, + data_nodes: Vec::with_capacity(capacity), + } + } + + fn new_node(&mut self, data: u64) -> Index { + const VEC_EXP_GROWTH_CAP: usize = 65536; + let node = Node { + prev: NULL, + next: NULL, + data, + }; + // Constrain the growth of vec: vec always double its capacity when it needs to grow + // It could waste too much memory when it is already very large. + // Here we limit the memory waste to 10% onces it grows beyond the cap. + // The amortized growth cost is O(n) beyond the max of the initial reserved capacity and + // the cap. But this list is for limited sized LRU and we recycle released node, so + // hopefully insertions are rare beyond certain sizes + if self.data_nodes.capacity() > VEC_EXP_GROWTH_CAP + && self.data_nodes.capacity() - self.data_nodes.len() < 2 + { + self.data_nodes + .reserve_exact(self.data_nodes.capacity() / 10) + } + self.data_nodes.push(node); + self.data_nodes.len() - 1 + OFFSET + } + + fn len(&self) -> usize { + self.data_nodes.len() + } + + fn head(&self) -> &Node { + &self.head + } + + fn tail(&self) -> &Node { + &self.tail + } +} + +impl std::ops::Index for Nodes { + type Output = Node; + + fn index(&self, index: usize) -> &Self::Output { + match index { + HEAD => &self.head, + TAIL => &self.tail, + _ => &self.data_nodes[index - OFFSET], + } + } +} + +impl std::ops::IndexMut for Nodes { + fn index_mut(&mut self, index: usize) -> &mut Self::Output { + match index { + HEAD => &mut self.head, + TAIL => &mut self.tail, + _ => &mut self.data_nodes[index - OFFSET], + } + } +} + +/// Doubly linked list +pub struct LinkedList { + nodes: Nodes, + free: Vec, // to keep track of freed node to be used again +} +// Panic when index used as parameters are invalid +// Index returned by push_* are always valid. +impl LinkedList { + /// Create a [LinkedList] with the given predicted capacity. + pub fn with_capacity(capacity: usize) -> Self { + LinkedList { + nodes: Nodes::with_capacity(capacity), + free: vec![], + } + } + + // Allocate a new node and return its index + // NOTE: this node is leaked if not used by caller + fn new_node(&mut self, data: u64) -> Index { + if let Some(index) = self.free.pop() { + // have a free node, update its payload and return its index + self.nodes[index].data = data; + index + } else { + // create a new node + self.nodes.new_node(data) + } + } + + /// How many nodes in the list + #[allow(clippy::len_without_is_empty)] + pub fn len(&self) -> usize { + // exclude the 2 sentinels + self.nodes.len() - self.free.len() + } + + fn valid_index(&self, index: Index) -> bool { + index != HEAD && index != TAIL && index < self.nodes.len() + OFFSET + // TODO: check node prev/next not NULL + // TODO: debug_check index not in self.free + } + + fn node(&self, index: Index) -> Option<&Node> { + if self.valid_index(index) { + Some(&self.nodes[index]) + } else { + None + } + } + + /// Peek into the list + pub fn peek(&self, index: Index) -> Option { + self.node(index).map(|n| n.data) + } + + // safe because index still needs to be in the range of the vec + fn peek_unchecked(&self, index: Index) -> &u64 { + &self.nodes[index].data + } + + /// Whether the value exists closed (up to search_limit nodes) to the head of the list + // It can be done via iter().take().find() but this is cheaper + pub fn exist_near_head(&self, value: u64, search_limit: usize) -> bool { + let mut current_node = HEAD; + for _ in 0..search_limit { + current_node = self.nodes[current_node].next; + if current_node == TAIL { + return false; + } + if self.nodes[current_node].data == value { + return true; + } + } + false + } + + // put a node right after the node at `at` + fn insert_after(&mut self, node_index: Index, at: Index) { + assert!(at != TAIL && at != node_index); // can't insert after tail or to itself + + let next = replace(&mut self.nodes[at].next, node_index); + + let node = &mut self.nodes[node_index]; + node.next = next; + node.prev = at; + + self.nodes[next].prev = node_index; + } + + /// Put the data at the head of the list. + pub fn push_head(&mut self, data: u64) -> Index { + let new_node_index = self.new_node(data); + self.insert_after(new_node_index, HEAD); + new_node_index + } + + /// Put the data at the tail of the list. + pub fn push_tail(&mut self, data: u64) -> Index { + let new_node_index = self.new_node(data); + self.insert_after(new_node_index, self.nodes.tail().prev); + new_node_index + } + + // lift the node out of the linked list, to either delete it or insert to another place + // NOTE: the node is leaked if not used by the caller + fn lift(&mut self, index: Index) -> u64 { + // can't touch the sentinels + assert!(index != HEAD && index != TAIL); + + let node = &mut self.nodes[index]; + + // zero out the pointers, useful in case we try to access a freed node + let prev = replace(&mut node.prev, NULL); + let next = replace(&mut node.next, NULL); + let data = node.data; + + // make sure we are accessing a node in the list, not freed already + assert!(prev != NULL && next != NULL); + + self.nodes[prev].next = next; + self.nodes[next].prev = prev; + + data + } + + /// Remove the node at the index, and return the value + pub fn remove(&mut self, index: Index) -> u64 { + self.free.push(index); + self.lift(index) + } + + /// Remove the tail of the list + pub fn pop_tail(&mut self) -> Option { + let data_tail = self.nodes.tail().prev; + if data_tail == HEAD { + None // empty list + } else { + Some(self.remove(data_tail)) + } + } + + /// Put the node at the index to the head + pub fn promote(&mut self, index: Index) { + if self.nodes.head().next == index { + return; // already head + } + self.lift(index); + self.insert_after(index, HEAD); + } + + fn next(&self, index: Index) -> Index { + self.nodes[index].next + } + + fn prev(&self, index: Index) -> Index { + self.nodes[index].prev + } + + /// Get the head of the list + pub fn head(&self) -> Option { + let data_head = self.nodes.head().next; + if data_head == TAIL { + None + } else { + Some(data_head) + } + } + + /// Get the tail of the list + pub fn tail(&self) -> Option { + let data_tail = self.nodes.tail().prev; + if data_tail == HEAD { + None + } else { + Some(data_tail) + } + } + + /// Iterate over the list + pub fn iter(&self) -> LinkedListIter<'_> { + LinkedListIter { + list: self, + head: HEAD, + tail: TAIL, + len: self.len(), + } + } +} + +/// The iter over the list +pub struct LinkedListIter<'a> { + list: &'a LinkedList, + head: Index, + tail: Index, + len: usize, +} + +impl<'a> Iterator for LinkedListIter<'a> { + type Item = &'a u64; + + fn next(&mut self) -> Option { + let next_index = self.list.next(self.head); + if next_index == TAIL || next_index == NULL { + None + } else { + self.head = next_index; + self.len -= 1; + Some(self.list.peek_unchecked(next_index)) + } + } + + fn size_hint(&self) -> (usize, Option) { + (self.len, Some(self.len)) + } +} + +impl<'a> DoubleEndedIterator for LinkedListIter<'a> { + fn next_back(&mut self) -> Option { + let prev_index = self.list.prev(self.tail); + if prev_index == HEAD || prev_index == NULL { + None + } else { + self.tail = prev_index; + self.len -= 1; + Some(self.list.peek_unchecked(prev_index)) + } + } +} + +#[cfg(test)] +mod test { + use super::*; + + // assert the list is the same as `values` + fn assert_list(list: &LinkedList, values: &[u64]) { + let list_values: Vec<_> = list.iter().copied().collect(); + assert_eq!(values, &list_values) + } + + fn assert_list_reverse(list: &LinkedList, values: &[u64]) { + let list_values: Vec<_> = list.iter().rev().copied().collect(); + assert_eq!(values, &list_values) + } + + #[test] + fn test_insert() { + let mut list = LinkedList::with_capacity(10); + assert_eq!(list.len(), 0); + assert!(list.node(2).is_none()); + assert_eq!(list.head(), None); + assert_eq!(list.tail(), None); + + let index1 = list.push_head(2); + assert_eq!(list.len(), 1); + assert_eq!(list.peek(index1).unwrap(), 2); + + let index2 = list.push_head(3); + assert_eq!(list.head(), Some(index2)); + assert_eq!(list.tail(), Some(index1)); + + let index3 = list.push_tail(4); + assert_eq!(list.head(), Some(index2)); + assert_eq!(list.tail(), Some(index3)); + + assert_list(&list, &[3, 2, 4]); + assert_list_reverse(&list, &[4, 2, 3]); + } + + #[test] + fn test_pop() { + let mut list = LinkedList::with_capacity(10); + list.push_head(2); + list.push_head(3); + list.push_tail(4); + assert_list(&list, &[3, 2, 4]); + assert_eq!(list.pop_tail(), Some(4)); + assert_eq!(list.pop_tail(), Some(2)); + assert_eq!(list.pop_tail(), Some(3)); + assert_eq!(list.pop_tail(), None); + } + + #[test] + fn test_promote() { + let mut list = LinkedList::with_capacity(10); + let index2 = list.push_head(2); + let index3 = list.push_head(3); + let index4 = list.push_tail(4); + assert_list(&list, &[3, 2, 4]); + + list.promote(index3); + assert_list(&list, &[3, 2, 4]); + + list.promote(index2); + assert_list(&list, &[2, 3, 4]); + + list.promote(index4); + assert_list(&list, &[4, 2, 3]); + } + + #[test] + fn test_exist_near_head() { + let mut list = LinkedList::with_capacity(10); + list.push_head(2); + list.push_head(3); + list.push_tail(4); + assert_list(&list, &[3, 2, 4]); + + assert!(!list.exist_near_head(4, 1)); + assert!(!list.exist_near_head(4, 2)); + assert!(list.exist_near_head(4, 3)); + assert!(list.exist_near_head(4, 4)); + assert!(list.exist_near_head(4, 99999)); + } +} diff --git a/pingora-memory-cache/Cargo.toml b/pingora-memory-cache/Cargo.toml new file mode 100644 index 0000000..d51268b --- /dev/null +++ b/pingora-memory-cache/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "pingora-memory-cache" +version = "0.1.0" +authors = ["Yuchen Wu "] +license = "Apache-2.0" +edition = "2021" +repository = "https://github.com/cloudflare/pingora" +categories = ["algorithms", "caching"] +keywords = ["async", "cache", "pingora"] +description = """ +An async in-memory cache with cache stampede protection. +""" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +name = "pingora_memory_cache" +path = "src/lib.rs" + +[dependencies] +TinyUFO = { version = "0.1.0", path = "../tinyufo" } +ahash = { workspace = true } +tokio = { workspace = true, features = ["sync"] } +async-trait = { workspace = true } +pingora-error = { version = "0.1.0", path = "../pingora-error" } +log = { workspace = true } +parking_lot = "0" +pingora-timeout = { version = "0.1.0", path = "../pingora-timeout" } diff --git a/pingora-memory-cache/LICENSE b/pingora-memory-cache/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/pingora-memory-cache/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/pingora-memory-cache/src/lib.rs b/pingora-memory-cache/src/lib.rs new file mode 100644 index 0000000..f5c037c --- /dev/null +++ b/pingora-memory-cache/src/lib.rs @@ -0,0 +1,249 @@ +// 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 ahash::RandomState; +use std::hash::Hash; +use std::marker::PhantomData; +use std::time::{Duration, Instant}; + +use tinyufo::TinyUfo; + +mod read_through; +pub use read_through::{Lookup, MultiLookup, RTCache}; + +#[derive(Debug, PartialEq, Eq)] +/// [CacheStatus] indicates the response type for a query. +pub enum CacheStatus { + /// The key was found in cache + Hit, + /// The key was not found. + Miss, + /// The key was found but it was expired. + Expired, + /// The key was not initially found but was found after awaiting a lock. + LockHit, +} + +impl CacheStatus { + /// Return the string representation for [CacheStatus]. + pub fn as_str(&self) -> &str { + match self { + Self::Hit => "hit", + Self::Miss => "miss", + Self::Expired => "expired", + Self::LockHit => "lock_hit", + } + } +} + +#[derive(Debug, Clone)] +struct Node { + pub value: T, + expire_on: Option, +} + +impl Node { + fn new(value: T, ttl: Option) -> Self { + let expire_on = match ttl { + Some(t) => Instant::now().checked_add(t), + None => None, + }; + Node { value, expire_on } + } + + fn will_expire_at(&self, time: &Instant) -> bool { + match self.expire_on.as_ref() { + Some(t) => t <= time, + None => false, + } + } + + fn is_expired(&self) -> bool { + self.will_expire_at(&Instant::now()) + } +} + +/// A high performant in-memory cache with S3-FIFO + TinyLFU +pub struct MemoryCache { + store: TinyUfo>, + _key_type: PhantomData, + pub(crate) hasher: RandomState, +} + +impl MemoryCache { + /// Create a new [MemoryCache] with the given size. + pub fn new(size: usize) -> Self { + MemoryCache { + store: TinyUfo::new(size, size), + _key_type: PhantomData, + hasher: RandomState::new(), + } + } + + /// Fetch the key and return its value in addition to a [CacheStatus]. + pub fn get(&self, key: &K) -> (Option, CacheStatus) { + let hashed_key = self.hasher.hash_one(key); + + if let Some(n) = self.store.get(&hashed_key) { + if !n.is_expired() { + (Some(n.value), CacheStatus::Hit) + } else { + // TODO: consider returning the staled value + (None, CacheStatus::Expired) + } + } else { + (None, CacheStatus::Miss) + } + } + + /// Insert a key and value pair with an optional TTL into the cache. + /// + /// An item with zero TTL of zero not inserted. + pub fn put(&self, key: &K, value: T, ttl: Option) { + if let Some(t) = ttl { + if t.is_zero() { + return; + } + } + let hashed_key = self.hasher.hash_one(key); + let node = Node::new(value, ttl); + // weight is always 1 for now + self.store.put(hashed_key, node, 1); + } + + pub(crate) fn force_put(&self, key: &K, value: T, ttl: Option) { + if let Some(t) = ttl { + if t.is_zero() { + return; + } + } + let hashed_key = self.hasher.hash_one(key); + let node = Node::new(value, ttl); + // weight is always 1 for now + self.store.force_put(hashed_key, node, 1); + } + + /// This is equivalent to [MemoryCache::get] but for an arbitrary amount of keys. + pub fn multi_get<'a, I>(&self, keys: I) -> Vec<(Option, CacheStatus)> + where + I: Iterator, + K: 'a, + { + let mut resp = Vec::with_capacity(keys.size_hint().0); + for key in keys { + resp.push(self.get(key)); + } + resp + } + + /// Same as [MemoryCache::multi_get] but returns the keys that are missing from the cache. + pub fn multi_get_with_miss<'a, I>(&self, keys: I) -> (Vec<(Option, CacheStatus)>, Vec<&'a K>) + where + I: Iterator, + K: 'a, + { + let mut resp = Vec::with_capacity(keys.size_hint().0); + let mut missed = Vec::with_capacity(keys.size_hint().0 / 2); + for key in keys { + let (lookup, cache_status) = self.get(key); + if lookup.is_none() { + missed.push(key); + } + resp.push((lookup, cache_status)); + } + (resp, missed) + } + + // TODO: evict expired first +} + +#[cfg(test)] +mod tests { + use super::*; + use std::thread::sleep; + + #[test] + fn test_get() { + let cache: MemoryCache = MemoryCache::new(10); + let (res, hit) = cache.get(&1); + assert_eq!(res, None); + assert_eq!(hit, CacheStatus::Miss); + } + + #[test] + fn test_put_get() { + let cache: MemoryCache = MemoryCache::new(10); + let (res, hit) = cache.get(&1); + assert_eq!(res, None); + assert_eq!(hit, CacheStatus::Miss); + cache.put(&1, 2, None); + let (res, hit) = cache.get(&1); + assert_eq!(res.unwrap(), 2); + assert_eq!(hit, CacheStatus::Hit); + } + + #[test] + fn test_get_expired() { + let cache: MemoryCache = MemoryCache::new(10); + let (res, hit) = cache.get(&1); + assert_eq!(res, None); + assert_eq!(hit, CacheStatus::Miss); + cache.put(&1, 2, Some(Duration::from_secs(1))); + sleep(Duration::from_millis(1100)); + let (res, hit) = cache.get(&1); + assert_eq!(res, None); + assert_eq!(hit, CacheStatus::Expired); + } + + #[test] + fn test_eviction() { + let cache: MemoryCache = MemoryCache::new(2); + cache.put(&1, 2, None); + cache.put(&2, 4, None); + cache.put(&3, 6, None); + let (res, hit) = cache.get(&1); + assert_eq!(res, None); + assert_eq!(hit, CacheStatus::Miss); + let (res, hit) = cache.get(&2); + assert_eq!(res.unwrap(), 4); + assert_eq!(hit, CacheStatus::Hit); + let (res, hit) = cache.get(&3); + assert_eq!(res.unwrap(), 6); + assert_eq!(hit, CacheStatus::Hit); + } + + #[test] + fn test_multi_get() { + let cache: MemoryCache = MemoryCache::new(10); + cache.put(&2, -2, None); + let keys: Vec = vec![1, 2, 3]; + let resp = cache.multi_get(keys.iter()); + assert_eq!(resp[0].0, None); + assert_eq!(resp[0].1, CacheStatus::Miss); + assert_eq!(resp[1].0.unwrap(), -2); + assert_eq!(resp[1].1, CacheStatus::Hit); + assert_eq!(resp[2].0, None); + assert_eq!(resp[2].1, CacheStatus::Miss); + + let (resp, missed) = cache.multi_get_with_miss(keys.iter()); + assert_eq!(resp[0].0, None); + assert_eq!(resp[0].1, CacheStatus::Miss); + assert_eq!(resp[1].0.unwrap(), -2); + assert_eq!(resp[1].1, CacheStatus::Hit); + assert_eq!(resp[2].0, None); + assert_eq!(resp[2].1, CacheStatus::Miss); + assert_eq!(missed[0], &1); + assert_eq!(missed[1], &3); + } +} diff --git a/pingora-memory-cache/src/read_through.rs b/pingora-memory-cache/src/read_through.rs new file mode 100644 index 0000000..05a8d89 --- /dev/null +++ b/pingora-memory-cache/src/read_through.rs @@ -0,0 +1,689 @@ +// 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. + +//! An async read through cache where cache miss are populated via the provided +//! async callback. + +use super::{CacheStatus, MemoryCache}; + +use async_trait::async_trait; +use log::warn; +use parking_lot::RwLock; +use pingora_error::{Error, ErrorTrait}; +use std::collections::HashMap; +use std::hash::Hash; +use std::marker::PhantomData; +use std::sync::Arc; +use std::time::{Duration, Instant}; +use tokio::sync::Semaphore; + +struct CacheLock { + pub lock_start: Instant, + pub lock: Semaphore, +} + +impl CacheLock { + pub fn new_arc() -> Arc { + Arc::new(CacheLock { + lock: Semaphore::new(0), + lock_start: Instant::now(), + }) + } + + pub fn too_old(&self, age: Option<&Duration>) -> bool { + match age { + Some(t) => Instant::now() - self.lock_start > *t, + None => false, + } + } +} + +#[async_trait] +/// [Lookup] defines the caching behavior that the implementor needs. The `extra` field can be used +/// to define any additional metadata that the implementor uses to determine cache eligibility. +/// +/// # Examples +/// +/// ```ignore +/// use pingora_error::{ErrorTrait, Result}; +/// use std::time::Duration; +/// +/// struct MyLookup; +/// +/// impl Lookup for MyLookup { +/// async fn lookup( +/// &self, +/// _key: &usize, +/// extra: Option<&()>, +/// ) -> Result<(usize, Option), Box> { +/// // Define your business logic here. +/// Ok(1, None) +/// } +/// } +/// ``` +pub trait Lookup { + /// Return a value and an optional TTL for the given key. + async fn lookup( + key: &K, + extra: Option<&S>, + ) -> Result<(T, Option), Box> + where + K: 'async_trait, + S: 'async_trait; +} + +#[async_trait] +/// [MultiLookup] is similar to [Lookup]. Implement this trait if the system being queried support +/// looking up multiple keys in a single API call. +pub trait MultiLookup { + /// Like [Lookup::lookup] but for an arbitrary amount of keys. + async fn multi_lookup( + keys: &[&K], + extra: Option<&S>, + ) -> Result)>, Box> + where + K: 'async_trait, + S: 'async_trait; +} + +const LOOKUP_ERR_MSG: &str = "RTCache: lookup error"; + +/// A read-through in-memory cache on top of [MemoryCache] +/// +/// Instead of providing a `put` function, [RTCache] requires a type which implements [Lookup] to +/// be automatically called during cache miss to populate the cache. This is useful when trying to +/// cache queries to external system such as DNS or databases. +/// +/// Lookup coalescing is provided so that multiple concurrent lookups for the same key results +/// only in one lookup callback. +pub struct RTCache +where + K: Hash + Send, + T: Clone + Send, +{ + inner: MemoryCache, + _callback: PhantomData, + lockers: RwLock>>, + lock_age: Option, + lock_timeout: Option, + phantom: PhantomData, +} + +impl RTCache +where + K: Hash + Send, + T: Clone + Send + Sync, +{ + /// Create a new [RTCache] of given size. `lock_age` defines how long a lock is valid for. + /// `lock_timeout` is used to stop a lookup from holding on to the key for too long. + pub fn new(size: usize, lock_age: Option, lock_timeout: Option) -> Self { + RTCache { + inner: MemoryCache::new(size), + lockers: RwLock::new(HashMap::new()), + _callback: PhantomData, + lock_age, + lock_timeout, + phantom: PhantomData, + } + } +} + +impl RTCache +where + K: Hash + Send, + T: Clone + Send + Sync, + CB: Lookup, +{ + /// Query the cache for a given value. If it exists and no TTL is configured initially, it will + /// use the `ttl` value given. + pub async fn get( + &self, + key: &K, + ttl: Option, + extra: Option<&S>, + ) -> (Result>, CacheStatus) { + let (result, cache_state) = self.inner.get(key); + if let Some(result) = result { + /* cache hit */ + return (Ok(result), cache_state); + } + + let hashed_key = self.inner.hasher.hash_one(key); + + /* Cache miss, try to lock the lookup. Check if there is already a lookup */ + let my_lock = { + let lockers = self.lockers.read(); + /* clone the Arc */ + lockers.get(&hashed_key).cloned() + }; // read lock dropped + + /* try insert a cache lock into locker */ + let (my_write, my_read) = match my_lock { + // TODO: use a union + Some(lock) => { + /* There is an ongoing lookup to the same key */ + if lock.too_old(self.lock_age.as_ref()) { + (None, None) + } else { + (None, Some(lock)) + } + } + None => { + let mut lockers = self.lockers.write(); + match lockers.get(&hashed_key) { + Some(lock) => { + /* another lookup to the same key got the write lock to locker first */ + if lock.too_old(self.lock_age.as_ref()) { + (None, None) + } else { + (None, Some(lock.clone())) + } + } + None => { + let new_lock = CacheLock::new_arc(); + let new_lock2 = new_lock.clone(); + lockers.insert(hashed_key, new_lock2); + (Some(new_lock), None) + } + } // write lock dropped + } + }; + + if my_read.is_some() { + /* another task will do the lookup */ + + let my_lock = my_read.unwrap(); + /* if available_permits > 0, writer is done */ + if my_lock.lock.available_permits() == 0 { + /* block here to wait for writer to finish lookup */ + let lock_fut = my_lock.lock.acquire(); + let timed_out = match self.lock_timeout { + Some(t) => pingora_timeout::timeout(t, lock_fut).await.is_err(), + None => { + let _ = lock_fut.await; + false + } + }; + if timed_out { + let value = CB::lookup(key, extra).await; + return match value { + Ok((v, _ttl)) => (Ok(v), cache_state), + Err(e) => { + let mut err = Error::new_str(LOOKUP_ERR_MSG); + err.set_cause(e); + (Err(err), cache_state) + } + }; + } + } // permit returned here + + let (result, cache_state) = self.inner.get(key); + if let Some(result) = result { + /* cache lock hit, slow as a miss */ + (Ok(result), CacheStatus::LockHit) + } else { + /* probably error happen during the actual lookup */ + warn!( + "RTCache: no result after read lock, cache status: {:?}", + cache_state + ); + match CB::lookup(key, extra).await { + Ok((v, new_ttl)) => { + self.inner.force_put(key, v.clone(), new_ttl.or(ttl)); + (Ok(v), cache_state) + } + Err(e) => { + let mut err = Error::new_str(LOOKUP_ERR_MSG); + err.set_cause(e); + (Err(err), cache_state) + } + } + } + } else { + /* this one will do the look up, either because it gets the write lock or the read + * lock age is reached */ + let value = CB::lookup(key, extra).await; + let ret = match value { + Ok((v, new_ttl)) => { + /* Don't put() if lock ago too old, to avoid too many concurrent writes */ + if my_write.is_some() { + self.inner.force_put(key, v.clone(), new_ttl.or(ttl)); + } + (Ok(v), cache_state) // the original cache_state: Miss or Expired + } + Err(e) => { + let mut err = Error::new_str(LOOKUP_ERR_MSG); + err.set_cause(e); + (Err(err), cache_state) + } + }; + if my_write.is_some() { + /* add permit so that reader can start. Any number of permits will do, + * since readers will return permits right away. */ + my_write.unwrap().lock.add_permits(10); + + { + // remove the lock from locker + let mut lockers = self.lockers.write(); + lockers.remove(&hashed_key); + } // write lock dropped here + } + + ret + } + } +} + +impl RTCache +where + K: Hash + Send, + T: Clone + Send + Sync, + CB: MultiLookup, +{ + /// Same behavior as [RTCache::get] but for an arbitrary amount of keys. + /// + /// If there are keys that are missing from cache, `multi_lookup` is invoked to populate the + /// cache before returning the final results. This is useful if your type supports batch + /// queries. + /// + /// To avoid dead lock for the same key across concurrent `multi_get` calls, + /// this function does not provide lookup coalescing. + pub async fn multi_get<'a, I>( + &self, + keys: I, + ttl: Option, + extra: Option<&S>, + ) -> Result, Box> + where + I: Iterator, + K: 'a, + { + let size = keys.size_hint().0; + let (hits, misses) = self.inner.multi_get_with_miss(keys); + let mut final_results = Vec::with_capacity(size); + let miss_results = if !misses.is_empty() { + match CB::multi_lookup(&misses, extra).await { + Ok(miss_results) => { + // assert! here to prevent index panic when building results, + // final_results has full list of misses but miss_results might not + assert!( + miss_results.len() == misses.len(), + "multi_lookup() failed to return the matching number of results" + ); + /* put the misses into cache */ + for item in misses.iter().zip(miss_results.iter()) { + self.inner + .force_put(item.0, (item.1).0.clone(), (item.1).1.or(ttl)); + } + miss_results + } + Err(e) => { + /* NOTE: we give up the hits when encounter lookup error */ + let mut err = Error::new_str(LOOKUP_ERR_MSG); + err.set_cause(e); + return Err(err); + } + } + } else { + vec![] // to make the rest code simple, allocating one unused empty vec should be fine + }; + /* fill in final_result */ + let mut n_miss = 0; + for item in hits { + match item.0 { + Some(v) => final_results.push((v, item.1)), + None => { + final_results // miss_results.len() === #None in result (asserted above) + .push((miss_results[n_miss].0.clone(), CacheStatus::Miss)); + n_miss += 1; + } + } + } + Ok(final_results) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use atomic::AtomicI32; + use std::sync::atomic; + + #[derive(Clone, Debug)] + struct ExtraOpt { + error: bool, + empty: bool, + delay_for: Option, + used: Arc, + } + + struct TestCB(); + + #[async_trait] + impl Lookup for TestCB { + async fn lookup( + _key: &i32, + extra: Option<&ExtraOpt>, + ) -> Result<(i32, Option), Box> { + // this function returns #lookup_times + let mut used = 0; + if let Some(e) = extra { + used = e.used.fetch_add(1, atomic::Ordering::Relaxed) + 1; + if e.error { + return Err(Error::new_str("test error")); + } + if let Some(delay_for) = e.delay_for { + tokio::time::sleep(delay_for).await; + } + } + Ok((used, None)) + } + } + + #[async_trait] + impl MultiLookup for TestCB { + async fn multi_lookup( + keys: &[&i32], + extra: Option<&ExtraOpt>, + ) -> Result)>, Box> { + let mut resp = vec![]; + if let Some(extra) = extra { + if extra.empty { + return Ok(resp); + } + } + for key in keys { + resp.push((**key, None)); + } + Ok(resp) + } + } + + #[tokio::test] + async fn test_basic_get() { + let cache: RTCache = RTCache::new(10, None, None); + let opt = Some(ExtraOpt { + error: false, + empty: false, + delay_for: None, + used: Arc::new(AtomicI32::new(0)), + }); + let (res, hit) = cache.get(&1, None, opt.as_ref()).await; + assert_eq!(res.unwrap(), 1); + assert_eq!(hit, CacheStatus::Miss); + let (res, hit) = cache.get(&1, None, opt.as_ref()).await; + assert_eq!(res.unwrap(), 1); + assert_eq!(hit, CacheStatus::Hit); + } + + #[tokio::test] + async fn test_basic_get_error() { + let cache: RTCache = RTCache::new(10, None, None); + let opt1 = Some(ExtraOpt { + error: true, + empty: false, + delay_for: None, + used: Arc::new(AtomicI32::new(0)), + }); + let (res, hit) = cache.get(&-1, None, opt1.as_ref()).await; + assert!(res.is_err()); + assert_eq!(hit, CacheStatus::Miss); + } + + #[tokio::test] + async fn test_concurrent_get() { + let cache: RTCache = RTCache::new(10, None, None); + let cache = Arc::new(cache); + let opt = Some(ExtraOpt { + error: false, + empty: false, + delay_for: None, + used: Arc::new(AtomicI32::new(0)), + }); + let cache_c = cache.clone(); + let opt1 = opt.clone(); + // concurrent gets, only 1 will call the callback + let t1 = tokio::spawn(async move { + let (res, _hit) = cache_c.get(&1, None, opt1.as_ref()).await; + res.unwrap() + }); + let cache_c = cache.clone(); + let opt2 = opt.clone(); + let t2 = tokio::spawn(async move { + let (res, _hit) = cache_c.get(&1, None, opt2.as_ref()).await; + res.unwrap() + }); + let opt3 = opt.clone(); + let cache_c = cache.clone(); + let t3 = tokio::spawn(async move { + let (res, _hit) = cache_c.get(&1, None, opt3.as_ref()).await; + res.unwrap() + }); + let (r1, r2, r3) = tokio::join!(t1, t2, t3); + assert_eq!(r1.unwrap(), 1); + assert_eq!(r2.unwrap(), 1); + assert_eq!(r3.unwrap(), 1); + } + + #[tokio::test] + async fn test_concurrent_get_error() { + let cache: RTCache = RTCache::new(10, None, None); + let cache = Arc::new(cache); + let cache_c = cache.clone(); + let opt1 = Some(ExtraOpt { + error: true, + empty: false, + delay_for: None, + used: Arc::new(AtomicI32::new(0)), + }); + let opt2 = opt1.clone(); + let opt3 = opt1.clone(); + // concurrent gets, only 1 will call the callback + let t1 = tokio::spawn(async move { + let (res, _hit) = cache_c.get(&-1, None, opt1.as_ref()).await; + res.is_err() + }); + let cache_c = cache.clone(); + let t2 = tokio::spawn(async move { + let (res, _hit) = cache_c.get(&-1, None, opt2.as_ref()).await; + res.is_err() + }); + let cache_c = cache.clone(); + let t3 = tokio::spawn(async move { + let (res, _hit) = cache_c.get(&-1, None, opt3.as_ref()).await; + res.is_err() + }); + let (r1, r2, r3) = tokio::join!(t1, t2, t3); + assert!(r1.unwrap()); + assert!(r2.unwrap()); + assert!(r3.unwrap()); + } + + #[tokio::test] + async fn test_concurrent_get_different_value() { + let cache: RTCache = RTCache::new(10, None, None); + let cache = Arc::new(cache); + let opt1 = Some(ExtraOpt { + error: false, + empty: false, + delay_for: None, + used: Arc::new(AtomicI32::new(0)), + }); + let opt2 = opt1.clone(); + let opt3 = opt1.clone(); + let cache_c = cache.clone(); + // concurrent gets to different keys, no locks, all will call the cb + let t1 = tokio::spawn(async move { + let (res, _hit) = cache_c.get(&1, None, opt1.as_ref()).await; + res.unwrap() + }); + let cache_c = cache.clone(); + let t2 = tokio::spawn(async move { + let (res, _hit) = cache_c.get(&3, None, opt2.as_ref()).await; + res.unwrap() + }); + let cache_c = cache.clone(); + let t3 = tokio::spawn(async move { + let (res, _hit) = cache_c.get(&5, None, opt3.as_ref()).await; + res.unwrap() + }); + let (r1, r2, r3) = tokio::join!(t1, t2, t3); + // 1 lookup + 2 lookups + 3 lookups, order not matter + assert_eq!(r1.unwrap() + r2.unwrap() + r3.unwrap(), 6); + } + + #[tokio::test] + async fn test_get_lock_age() { + // 1 sec lock age + let cache: RTCache = + RTCache::new(10, Some(Duration::from_secs(1)), None); + let cache = Arc::new(cache); + let counter = Arc::new(AtomicI32::new(0)); + let opt1 = Some(ExtraOpt { + error: false, + empty: false, + delay_for: Some(Duration::from_secs(2)), + used: counter.clone(), + }); + + let opt2 = Some(ExtraOpt { + error: false, + empty: false, + delay_for: None, + used: counter.clone(), + }); + let opt3 = opt2.clone(); + let cache_c = cache.clone(); + // t1 will be delay for 2 sec + let t1 = tokio::spawn(async move { + let (res, _hit) = cache_c.get(&1, None, opt1.as_ref()).await; + res.unwrap() + }); + // start t2 and t3 1.5 seconds later, since lock age is 1 sec, there will be no lock + tokio::time::sleep(Duration::from_secs_f32(1.5)).await; + let cache_c = cache.clone(); + let t2 = tokio::spawn(async move { + let (res, _hit) = cache_c.get(&1, None, opt2.as_ref()).await; + res.unwrap() + }); + let cache_c = cache.clone(); + let t3 = tokio::spawn(async move { + let (res, _hit) = cache_c.get(&1, None, opt3.as_ref()).await; + res.unwrap() + }); + let (r1, r2, r3) = tokio::join!(t1, t2, t3); + // 1 lookup + 2 lookups + 3 lookups, order not matter + assert_eq!(r1.unwrap() + r2.unwrap() + r3.unwrap(), 6); + } + + #[tokio::test] + async fn test_get_lock_timeout() { + // 1 sec lock timeout + let cache: RTCache = + RTCache::new(10, None, Some(Duration::from_secs(1))); + let cache = Arc::new(cache); + let counter = Arc::new(AtomicI32::new(0)); + let opt1 = Some(ExtraOpt { + error: false, + empty: false, + delay_for: Some(Duration::from_secs(2)), + used: counter.clone(), + }); + let opt2 = Some(ExtraOpt { + error: false, + empty: false, + delay_for: None, + used: counter.clone(), + }); + let opt3 = opt2.clone(); + let cache_c = cache.clone(); + // t1 will be delay for 2 sec + let t1 = tokio::spawn(async move { + let (res, _hit) = cache_c.get(&1, None, opt1.as_ref()).await; + res.unwrap() + }); + // since lock timeout is 1 sec, t2 and t3 will do their own lookup after 1 sec + let cache_c = cache.clone(); + let t2 = tokio::spawn(async move { + let (res, _hit) = cache_c.get(&1, None, opt2.as_ref()).await; + res.unwrap() + }); + let cache_c = cache.clone(); + let t3 = tokio::spawn(async move { + let (res, _hit) = cache_c.get(&1, None, opt3.as_ref()).await; + res.unwrap() + }); + let (r1, r2, r3) = tokio::join!(t1, t2, t3); + // 1 lookup + 2 lookups + 3 lookups, order not matter + assert_eq!(r1.unwrap() + r2.unwrap() + r3.unwrap(), 6); + } + + #[tokio::test] + async fn test_multi_get() { + let cache: RTCache = RTCache::new(10, None, None); + let counter = Arc::new(AtomicI32::new(0)); + let opt1 = Some(ExtraOpt { + error: false, + empty: false, + delay_for: Some(Duration::from_secs(2)), + used: counter.clone(), + }); + // make 1 a hit first + let (res, hit) = cache.get(&1, None, opt1.as_ref()).await; + assert_eq!(res.unwrap(), 1); + assert_eq!(hit, CacheStatus::Miss); + let (res, hit) = cache.get(&1, None, opt1.as_ref()).await; + assert_eq!(res.unwrap(), 1); + assert_eq!(hit, CacheStatus::Hit); + // 1 hit 2 miss 3 miss + let resp = cache + .multi_get([1, 2, 3].iter(), None, opt1.as_ref()) + .await + .unwrap(); + assert_eq!(resp[0].0, 1); + assert_eq!(resp[0].1, CacheStatus::Hit); + assert_eq!(resp[1].0, 2); + assert_eq!(resp[1].1, CacheStatus::Miss); + assert_eq!(resp[2].0, 3); + assert_eq!(resp[2].1, CacheStatus::Miss); + // all hit after a fetch + let resp = cache + .multi_get([1, 2, 3].iter(), None, opt1.as_ref()) + .await + .unwrap(); + assert_eq!(resp[0].0, 1); + assert_eq!(resp[0].1, CacheStatus::Hit); + assert_eq!(resp[1].0, 2); + assert_eq!(resp[1].1, CacheStatus::Hit); + assert_eq!(resp[2].0, 3); + assert_eq!(resp[2].1, CacheStatus::Hit); + } + + #[tokio::test] + #[should_panic(expected = "multi_lookup() failed to return the matching number of results")] + async fn test_inconsistent_miss_results() { + // force empty result + let opt1 = Some(ExtraOpt { + error: false, + empty: true, + delay_for: None, + used: Arc::new(AtomicI32::new(0)), + }); + let cache: RTCache = RTCache::new(10, None, None); + cache + .multi_get([4, 5, 6].iter(), None, opt1.as_ref()) + .await + .unwrap(); + } +} diff --git a/pingora-openssl/Cargo.toml b/pingora-openssl/Cargo.toml new file mode 100644 index 0000000..19b3349 --- /dev/null +++ b/pingora-openssl/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "pingora-openssl" +version = "0.1.0" +authors = ["Yuchen Wu "] +license = "Apache-2.0" +edition = "2021" +repository = "https://github.com/cloudflare/pingora" +categories = ["asynchronous", "network-programming"] +keywords = ["async", "tls", "ssl", "pingora"] +description = """ +OpenSSL async APIs for Pingora. +""" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +name = "pingora_openssl" +path = "src/lib.rs" + +[dependencies] +openssl-sys = "0.9" +openssl = { version = "0.10", features = ["vendored"] } +openssl-src = { version = "300", features = ["weak-crypto"] } +tokio-openssl = { version = "0.6" } +libc = "0.2.70" +foreign-types = { version = "0.3"} + +[dev-dependencies] +tokio-test = "0.4" +tokio = { workspace = true, features = ["full"] } diff --git a/pingora-openssl/LICENSE b/pingora-openssl/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/pingora-openssl/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/pingora-openssl/src/ext.rs b/pingora-openssl/src/ext.rs new file mode 100644 index 0000000..f8cebb2 --- /dev/null +++ b/pingora-openssl/src/ext.rs @@ -0,0 +1,209 @@ +// 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 foreign_types::ForeignTypeRef; +use libc::*; +use openssl::error::ErrorStack; +use openssl::pkey::{HasPrivate, PKeyRef}; +use openssl::ssl::{Ssl, SslAcceptor, SslRef}; +use openssl::x509::store::X509StoreRef; +use openssl::x509::verify::X509VerifyParamRef; +use openssl::x509::X509Ref; +use openssl_sys::{ + SSL_ctrl, EVP_PKEY, SSL, SSL_CTRL_SET_GROUPS_LIST, SSL_CTRL_SET_VERIFY_CERT_STORE, X509, + X509_VERIFY_PARAM, +}; +use std::ffi::CString; +use std::os::raw; + +fn cvt(r: c_int) -> Result { + if r != 1 { + Err(ErrorStack::get()) + } else { + Ok(r) + } +} + +extern "C" { + pub fn X509_VERIFY_PARAM_add1_host( + param: *mut X509_VERIFY_PARAM, + name: *const c_char, + namelen: size_t, + ) -> c_int; + + pub fn SSL_use_certificate(ssl: *const SSL, cert: *mut X509) -> c_int; + pub fn SSL_use_PrivateKey(ctx: *const SSL, key: *mut EVP_PKEY) -> c_int; + + pub fn SSL_set_cert_cb( + ssl: *mut SSL, + cb: ::std::option::Option< + unsafe extern "C" fn(ssl: *mut SSL, arg: *mut raw::c_void) -> raw::c_int, + >, + arg: *mut raw::c_void, + ); +} + +/// Add name as an additional reference identifier that can match the peer's certificate +/// +/// See [X509_VERIFY_PARAM_set1_host](https://www.openssl.org/docs/man3.1/man3/X509_VERIFY_PARAM_set1_host.html). +pub fn add_host(verify_param: &mut X509VerifyParamRef, host: &str) -> Result<(), ErrorStack> { + if host.is_empty() { + return Ok(()); + } + unsafe { + cvt(X509_VERIFY_PARAM_add1_host( + verify_param.as_ptr(), + host.as_ptr() as *const _, + host.len(), + )) + .map(|_| ()) + } +} + +/// Set the verify cert store of `ssl` +/// +/// See [SSL_set1_verify_cert_store](https://www.openssl.org/docs/man1.1.1/man3/SSL_set1_verify_cert_store.html). +pub fn ssl_set_verify_cert_store( + ssl: &mut SslRef, + cert_store: &X509StoreRef, +) -> Result<(), ErrorStack> { + unsafe { + cvt(SSL_ctrl( + ssl.as_ptr(), + SSL_CTRL_SET_VERIFY_CERT_STORE, + 1, // increase the ref count of X509Store so that ssl_ctx can outlive X509StoreRef + cert_store.as_ptr() as *mut c_void, + ) as i32)?; + } + Ok(()) +} + +/// Load the certificate into `ssl` +/// +/// See [SSL_use_certificate](https://www.openssl.org/docs/man1.1.1/man3/SSL_use_certificate.html). +pub fn ssl_use_certificate(ssl: &mut SslRef, cert: &X509Ref) -> Result<(), ErrorStack> { + unsafe { + cvt(SSL_use_certificate(ssl.as_ptr(), cert.as_ptr()))?; + } + Ok(()) +} + +/// Load the private key into `ssl` +/// +/// See [SSL_use_certificate](https://www.openssl.org/docs/man1.1.1/man3/SSL_use_PrivateKey.html). +pub fn ssl_use_private_key(ssl: &mut SslRef, key: &PKeyRef) -> Result<(), ErrorStack> +where + T: HasPrivate, +{ + unsafe { + cvt(SSL_use_PrivateKey(ssl.as_ptr(), key.as_ptr()))?; + } + Ok(()) +} + +/// Add the certificate into the cert chain of `ssl` +/// +/// See [SSL_add1_chain_cert](https://www.openssl.org/docs/man1.1.1/man3/SSL_add1_chain_cert.html) +pub fn ssl_add_chain_cert(ssl: &mut SslRef, cert: &X509Ref) -> Result<(), ErrorStack> { + const SSL_CTRL_CHAIN_CERT: i32 = 89; + unsafe { + cvt(SSL_ctrl( + ssl.as_ptr(), + SSL_CTRL_CHAIN_CERT, + 1, // increase the ref count of X509 so that ssl can outlive X509StoreRef + cert.as_ptr() as *mut c_void, + ) as i32)?; + } + Ok(()) +} + +/// Set renegotiation +/// +/// This function is specific to BoringSSL. This function is noop for OpenSSL. +pub fn ssl_set_renegotiate_mode_freely(_ssl: &mut SslRef) {} + +/// Set the curves/groups of `ssl` +/// +/// See [set_groups_list](https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set1_curves.html). +pub fn ssl_set_groups_list(ssl: &mut SslRef, groups: &str) -> Result<(), ErrorStack> { + let groups = CString::new(groups).unwrap(); + unsafe { + cvt(SSL_ctrl( + ssl.as_ptr(), + SSL_CTRL_SET_GROUPS_LIST, + 0, + groups.as_ptr() as *mut c_void, + ) as i32)?; + } + Ok(()) +} + +/// Set's whether a second keyshare to be sent in client hello when PQ is used. +/// +/// This function is specific to BoringSSL. This function is noop for OpenSSL. +pub fn ssl_use_second_key_share(_ssl: &mut SslRef, _enabled: bool) {} + +/// Clear the error stack +/// +/// SSL calls should check and clear the OpenSSL error stack. But some calls fail to do so. +/// This causes the next unrelated SSL call to fail due to the leftover errors. This function allow +/// caller to clear the error stack before performing SSL calls to avoid this issue. +pub fn clear_error_stack() { + let _ = ErrorStack::get(); +} + +/// Create a new [Ssl] from &[SslAcceptor] +/// +/// this function is to unify the interface between this crate and `pingora-boringssl` +pub fn ssl_from_acceptor(acceptor: &SslAcceptor) -> Result { + Ssl::new(acceptor.context()) +} + +/// Suspend the TLS handshake when a certificate is needed. +/// +/// This function will cause tls handshake to pause and return the error: SSL_ERROR_WANT_X509_LOOKUP. +/// The caller should set the certificate and then call [unblock_ssl_cert()] before continue the +/// handshake on the tls connection. +pub fn suspend_when_need_ssl_cert(ssl: &mut SslRef) { + unsafe { + SSL_set_cert_cb(ssl.as_ptr(), Some(raw_cert_block), std::ptr::null_mut()); + } +} + +/// Unblock a TLS handshake after the certificate is set. +/// +/// The user should continue to call tls handshake after this function is called. +pub fn unblock_ssl_cert(ssl: &mut SslRef) { + unsafe { + SSL_set_cert_cb(ssl.as_ptr(), None, std::ptr::null_mut()); + } +} + +// Just block the handshake +extern "C" fn raw_cert_block(_ssl: *mut openssl_sys::SSL, _arg: *mut c_void) -> c_int { + -1 +} + +/// Whether the TLS error is SSL_ERROR_WANT_X509_LOOKUP +pub fn is_suspended_for_cert(error: &openssl::ssl::Error) -> bool { + error.code().as_raw() == openssl_sys::SSL_ERROR_WANT_X509_LOOKUP +} + +#[allow(clippy::mut_from_ref)] +/// Get a mutable SslRef ouf of SslRef, which is a missing functionality even when holding &mut SslStream +/// # Safety +/// the caller need to make sure that they hold a &mut SslStream (or other mutable ref to the Ssl) +pub unsafe fn ssl_mut(ssl: &SslRef) -> &mut SslRef { + SslRef::from_ptr_mut(ssl.as_ptr()) +} diff --git a/pingora-openssl/src/lib.rs b/pingora-openssl/src/lib.rs new file mode 100644 index 0000000..b12cee1 --- /dev/null +++ b/pingora-openssl/src/lib.rs @@ -0,0 +1,33 @@ +// 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. + +//! The OpenSSL API compatibility layer. +//! +//! This crate aims at making [openssl] APIs interchangeable with [boring](https://docs.rs/boring/latest/boring/). +//! In other words, this crate and `pingora-boringssl` expose identical rust APIs. + +#![warn(clippy::all)] + +use openssl as ssl_lib; +pub use openssl_sys as ssl_sys; +pub use tokio_openssl as tokio_ssl; +pub mod ext; + +// export commonly used libs +pub use ssl_lib::error; +pub use ssl_lib::hash; +pub use ssl_lib::nid; +pub use ssl_lib::pkey; +pub use ssl_lib::ssl; +pub use ssl_lib::x509; diff --git a/pingora-pool/Cargo.toml b/pingora-pool/Cargo.toml new file mode 100644 index 0000000..170e497 --- /dev/null +++ b/pingora-pool/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "pingora-pool" +version = "0.1.0" +authors = ["Yuchen Wu "] +license = "Apache-2.0" +edition = "2021" +repository = "https://github.com/cloudflare/pingora" +categories = ["network-programming"] +keywords = ["async", "pooling", "pingora"] +description = """ +A connection pool system for connection reuse. +""" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +name = "pingora_pool" +path = "src/lib.rs" + +[dependencies] +tokio = { workspace = true, features = ["sync", "io-util"] } +thread_local = "1.0" +lru = { workspace = true } +log = { workspace = true } +parking_lot = "0.12" +crossbeam-queue = "0.3" +pingora-timeout = { version = "0.1.0", path = "../pingora-timeout" } + +[dev-dependencies] +tokio-test = "0.4" diff --git a/pingora-pool/LICENSE b/pingora-pool/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/pingora-pool/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/pingora-pool/src/connection.rs b/pingora-pool/src/connection.rs new file mode 100644 index 0000000..c8a5e33 --- /dev/null +++ b/pingora-pool/src/connection.rs @@ -0,0 +1,530 @@ +// 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. + +//! Generic connection pooling + +use log::{debug, warn}; +use parking_lot::{Mutex, RwLock}; +use pingora_timeout::{sleep, timeout}; +use std::collections::HashMap; +use std::io; +use std::sync::Arc; +use std::time::Duration; +use tokio::io::{AsyncRead, AsyncReadExt}; +use tokio::sync::{oneshot, watch, Notify, OwnedMutexGuard}; + +use super::lru::Lru; + +type GroupKey = u64; +type ID = i32; + +/// the metadata of a connection +#[derive(Clone, Debug)] +pub struct ConnectionMeta { + /// The group key. All connections under the same key are considered the same for connection reuse. + pub key: GroupKey, + /// The unique ID of a connection. + pub id: ID, +} + +impl ConnectionMeta { + /// Create a new [ConnectionMeta] + pub fn new(key: GroupKey, id: ID) -> Self { + ConnectionMeta { key, id } + } +} + +struct PoolConnection { + pub notify_use: oneshot::Sender, + pub connection: S, +} + +impl PoolConnection { + pub fn new(notify_use: oneshot::Sender, connection: S) -> Self { + PoolConnection { + notify_use, + connection, + } + } + + pub fn release(self) -> S { + // notify the idle watcher to release the connection + let _ = self.notify_use.send(true); + // wait for the watcher to release + self.connection + } +} + +use crossbeam_queue::ArrayQueue; + +/// A pool of exchangeable items +pub struct PoolNode { + connections: Mutex>, + // a small lock free queue to avoid lock contention + hot_queue: ArrayQueue<(ID, T)>, + // to avoid race between 2 evictions on the queue + hot_queue_remove_lock: Mutex<()>, + // TODO: store the GroupKey to avoid hash collision? +} + +// Keep the queue size small because eviction is O(n) in the queue +const HOT_QUEUE_SIZE: usize = 16; + +impl PoolNode { + /// Create a new [PoolNode] + pub fn new() -> Self { + PoolNode { + connections: Mutex::new(HashMap::new()), + hot_queue: ArrayQueue::new(HOT_QUEUE_SIZE), + hot_queue_remove_lock: Mutex::new(()), + } + } + + /// Get any item from the pool + pub fn get_any(&self) -> Option<(ID, T)> { + let hot_conn = self.hot_queue.pop(); + if hot_conn.is_some() { + return hot_conn; + } + let mut connections = self.connections.lock(); + // find one connection, any connection will do + let id = match connections.iter().next() { + Some((k, _)) => *k, // OK to copy i32 + None => return None, + }; + // unwrap is safe since we just found it + let connection = connections.remove(&id).unwrap(); + /* NOTE: we don't resize or drop empty connections hashmap + * We may want to do it if they consume too much memory + * maybe we should use trees to save memory */ + Some((id, connection)) + // connections.lock released here + } + + /// Insert an item with the given unique ID into the pool + pub fn insert(&self, id: ID, conn: T) { + if let Err(node) = self.hot_queue.push((id, conn)) { + // hot queue is full + let mut connections = self.connections.lock(); + connections.insert(node.0, node.1); // TODO: check dup + } + } + + // This function acquires 2 locks and iterates over the entire hot queue + // But it should be fine because remove() rarely happens on a busy PoolNode + /// Remove the item associated with the id from the pool. The item is returned + /// if it is found and removed. + pub fn remove(&self, id: ID) -> Option { + // check the table first as least recent used ones are likely there + let removed = self.connections.lock().remove(&id); + if removed.is_some() { + return removed; + } // lock drops here + + let _queue_lock = self.hot_queue_remove_lock.lock(); + // check the hot queue, note that the queue can be accessed in parallel by insert and get + let max_len = self.hot_queue.len(); + for _ in 0..max_len { + if let Some((conn_id, conn)) = self.hot_queue.pop() { + if conn_id == id { + // this is the item, it is already popped + return Some(conn); + } else { + // not this item, put back to hot queue but it could also be full + self.insert(conn_id, conn); + } + } else { + // other threads grab all the connections + return None; + } + } + None + // _queue_lock drops here + } +} + +/// Connection pool +/// +/// [ConnectionPool] holds reusable connections. A reusable connection is released to this pool to +/// be picked up by another user/request. +pub struct ConnectionPool { + // TODO: n-way pools to reduce lock contention + pool: RwLock>>>>, + lru: Lru, +} + +impl ConnectionPool { + /// Create a new [ConnectionPool] with a size limit. + /// + /// when a connection is released to this pool, the least recently used connection will be dropped. + pub fn new(size: usize) -> Self { + ConnectionPool { + pool: RwLock::new(HashMap::with_capacity(size)), // this is oversized since some connections will have the same key + lru: Lru::new(size), + } + } + + /* get or create and insert a pool node for the hash key */ + fn get_pool_node(&self, key: GroupKey) -> Arc>> { + { + let pool = self.pool.read(); + if let Some(v) = pool.get(&key) { + return (*v).clone(); + } + } // read lock released here + + { + // write lock section + let mut pool = self.pool.write(); + // check again since another task might already added it + if let Some(v) = pool.get(&key) { + return (*v).clone(); + } + let node = Arc::new(PoolNode::new()); + let node_ret = node.clone(); + pool.insert(key, node); // TODO: check dup + node_ret + } + } + + // only remove from pool because lru already removed it + fn pop_evicted(&self, meta: &ConnectionMeta) { + let pool_node = { + let pool = self.pool.read(); + match pool.get(&meta.key) { + Some(v) => (*v).clone(), + None => { + warn!("Fail to get pool node for {:?}", meta); + return; + } // nothing to pop, should return error? + } + }; // read lock released here + + pool_node.remove(meta.id); + debug!("evict fd: {} from key {}", meta.id, meta.key); + } + + fn pop_closed(&self, meta: &ConnectionMeta) { + // NOTE: which of these should be done first? + self.pop_evicted(meta); + self.lru.pop(&meta.id); + } + + /// Get a connection from this pool under the same group key + pub fn get(&self, key: &GroupKey) -> Option { + let pool_node = { + let pool = self.pool.read(); + match pool.get(key) { + Some(v) => (*v).clone(), + None => return None, + } + }; // read lock released here + + if let Some((id, connection)) = pool_node.get_any() { + self.lru.pop(&id); // the notified is not needed + Some(connection.release()) + } else { + None + } + } + + /// Release a connection to this pool for reuse + /// + /// - The returned [`Arc`] will notify any listen when the connection is evicted from the pool. + /// - The returned [`oneshot::Receiver`] will notify when the connection is being picked up by [Self::get()]. + pub fn put( + &self, + meta: &ConnectionMeta, + connection: S, + ) -> (Arc, oneshot::Receiver) { + let (notify_close, replaced) = self.lru.add(meta.id, meta.clone()); + if let Some(meta) = replaced { + self.pop_evicted(&meta); + }; + let pool_node = self.get_pool_node(meta.key); + let (notify_use, watch_use) = oneshot::channel(); + let connection = PoolConnection::new(notify_use, connection); + pool_node.insert(meta.id, connection); + (notify_close, watch_use) + } + + /// Actively monitor the health of a connection that is already released to this pool + /// + /// When the connection breaks, or the optional `timeout` is reached this function will + /// remove it from the pool and drop the connection. + /// + /// If the connection is reused via [Self::get()] or being evicted, this function will just exit. + pub async fn idle_poll( + &self, + connection: OwnedMutexGuard, + meta: &ConnectionMeta, + timeout: Option, + notify_evicted: Arc, + watch_use: oneshot::Receiver, + ) where + Stream: AsyncRead + Unpin + Send, + { + let read_result = tokio::select! { + biased; + _ = watch_use => { + debug!("idle connection is being picked up"); + return + }, + _ = notify_evicted.notified() => { + debug!("idle connection is being evicted"); + // TODO: gracefully close the connection? + return + } + read_result = read_with_timeout(connection , timeout) => read_result + }; + + match read_result { + Ok(n) => { + if n > 0 { + warn!("Data received on idle client connection, close it") + } else { + debug!("Peer closed the idle connection or timeout") + } + } + + Err(e) => { + debug!("error with the idle connection, close it {:?}", e); + } + } + // connection terminated from either peer or timer + self.pop_closed(meta); + } + + /// Passively wait to close the connection after the timeout + /// + /// If this connection is not being picked up or evicted before the timeout is reach, this + /// function will removed it from the pool and close the connection. + pub async fn idle_timeout( + &self, + meta: &ConnectionMeta, + timeout: Duration, + notify_evicted: Arc, + mut notify_closed: watch::Receiver, + watch_use: oneshot::Receiver, + ) { + tokio::select! { + biased; + _ = watch_use => { + debug!("idle connection is being picked up"); + }, + _ = notify_evicted.notified() => { + debug!("idle connection is being evicted"); + // TODO: gracefully close the connection? + } + _ = notify_closed.changed() => { + // assume always changed from false to true + debug!("idle connection is being closed"); + self.pop_closed(meta); + } + _ = sleep(timeout) => { + debug!("idle connection is being evicted"); + self.pop_closed(meta); + } + }; + } +} + +async fn read_with_timeout( + mut connection: OwnedMutexGuard, + timeout_duration: Option, +) -> io::Result +where + S: AsyncRead + Unpin + Send, +{ + let mut buf = [0; 1]; + let read_event = connection.read(&mut buf[..]); + match timeout_duration { + Some(d) => match timeout(d, read_event).await { + Ok(res) => res, + Err(e) => { + debug!("keepalive timeout {:?} reached, {:?}", d, e); + Ok(0) + } + }, + _ => read_event.await, + } +} + +#[cfg(test)] +mod tests { + use super::*; + use log::debug; + use tokio::sync::Mutex as AsyncMutex; + use tokio_test::io::{Builder, Mock}; + + #[tokio::test] + async fn test_lookup() { + let meta1 = ConnectionMeta::new(101, 1); + let value1 = "v1".to_string(); + let meta2 = ConnectionMeta::new(102, 2); + let value2 = "v2".to_string(); + let meta3 = ConnectionMeta::new(101, 3); + let value3 = "v3".to_string(); + let cp: ConnectionPool = ConnectionPool::new(3); //#CP3 + cp.put(&meta1, value1.clone()); + cp.put(&meta2, value2.clone()); + cp.put(&meta3, value3.clone()); + + let found_b = cp.get(&meta2.key).unwrap(); + assert_eq!(found_b, value2); + + let found_a1 = cp.get(&meta1.key).unwrap(); + let found_a2 = cp.get(&meta1.key).unwrap(); + + assert!( + found_a1 == value1 && found_a2 == value3 || found_a2 == value1 && found_a1 == value3 + ); + } + + #[tokio::test] + async fn test_pop() { + let meta1 = ConnectionMeta::new(101, 1); + let value1 = "v1".to_string(); + let meta2 = ConnectionMeta::new(102, 2); + let value2 = "v2".to_string(); + let meta3 = ConnectionMeta::new(101, 3); + let value3 = "v3".to_string(); + let cp: ConnectionPool = ConnectionPool::new(3); //#CP3 + cp.put(&meta1, value1); + cp.put(&meta2, value2); + cp.put(&meta3, value3.clone()); + + cp.pop_closed(&meta1); + + let found_a1 = cp.get(&meta1.key).unwrap(); + assert_eq!(found_a1, value3); + + cp.pop_closed(&meta1); + assert!(cp.get(&meta1.key).is_none()) + } + + #[tokio::test] + async fn test_eviction() { + let meta1 = ConnectionMeta::new(101, 1); + let value1 = "v1".to_string(); + let meta2 = ConnectionMeta::new(102, 2); + let value2 = "v2".to_string(); + let meta3 = ConnectionMeta::new(101, 3); + let value3 = "v3".to_string(); + let cp: ConnectionPool = ConnectionPool::new(2); + let (notify_close1, _) = cp.put(&meta1, value1.clone()); + let (notify_close2, _) = cp.put(&meta2, value2.clone()); + let (notify_close3, _) = cp.put(&meta3, value3.clone()); // meta 1 should be evicted + + let closed_item = tokio::select! { + _ = notify_close1.notified() => {debug!("notifier1"); 1}, + _ = notify_close2.notified() => {debug!("notifier2"); 2}, + _ = notify_close3.notified() => {debug!("notifier3"); 3}, + }; + assert_eq!(closed_item, 1); + + let found_a1 = cp.get(&meta1.key).unwrap(); + assert_eq!(found_a1, value3); + assert_eq!(cp.get(&meta1.key), None) + } + + #[tokio::test] + #[should_panic(expected = "There is still data left to read.")] + async fn test_read_close() { + let meta1 = ConnectionMeta::new(101, 1); + let mock_io1 = Arc::new(AsyncMutex::new(Builder::new().read(b"garbage").build())); + let meta2 = ConnectionMeta::new(102, 2); + let mock_io2 = Arc::new(AsyncMutex::new( + Builder::new().wait(Duration::from_secs(99)).build(), + )); + let meta3 = ConnectionMeta::new(101, 3); + let mock_io3 = Arc::new(AsyncMutex::new( + Builder::new().wait(Duration::from_secs(99)).build(), + )); + let cp: ConnectionPool>> = ConnectionPool::new(3); + let (c1, u1) = cp.put(&meta1, mock_io1.clone()); + let (c2, u2) = cp.put(&meta2, mock_io2.clone()); + let (c3, u3) = cp.put(&meta3, mock_io3.clone()); + + let closed_item = tokio::select! { + _ = cp.idle_poll(mock_io1.try_lock_owned().unwrap(), &meta1, None, c1, u1) => {debug!("notifier1"); 1}, + _ = cp.idle_poll(mock_io2.try_lock_owned().unwrap(), &meta1, None, c2, u2) => {debug!("notifier2"); 2}, + _ = cp.idle_poll(mock_io3.try_lock_owned().unwrap(), &meta1, None, c3, u3) => {debug!("notifier3"); 3}, + }; + assert_eq!(closed_item, 1); + + let _ = cp.get(&meta1.key).unwrap(); // mock_io3 should be selected + assert!(cp.get(&meta1.key).is_none()) // mock_io1 should already be removed by idle_poll + } + + #[tokio::test] + async fn test_read_timeout() { + let meta1 = ConnectionMeta::new(101, 1); + let mock_io1 = Arc::new(AsyncMutex::new( + Builder::new().wait(Duration::from_secs(99)).build(), + )); + let meta2 = ConnectionMeta::new(102, 2); + let mock_io2 = Arc::new(AsyncMutex::new( + Builder::new().wait(Duration::from_secs(99)).build(), + )); + let meta3 = ConnectionMeta::new(101, 3); + let mock_io3 = Arc::new(AsyncMutex::new( + Builder::new().wait(Duration::from_secs(99)).build(), + )); + let cp: ConnectionPool>> = ConnectionPool::new(3); + let (c1, u1) = cp.put(&meta1, mock_io1.clone()); + let (c2, u2) = cp.put(&meta2, mock_io2.clone()); + let (c3, u3) = cp.put(&meta3, mock_io3.clone()); + + let closed_item = tokio::select! { + _ = cp.idle_poll(mock_io1.try_lock_owned().unwrap(), &meta1, Some(Duration::from_secs(1)), c1, u1) => {debug!("notifier1"); 1}, + _ = cp.idle_poll(mock_io2.try_lock_owned().unwrap(), &meta1, Some(Duration::from_secs(2)), c2, u2) => {debug!("notifier2"); 2}, + _ = cp.idle_poll(mock_io3.try_lock_owned().unwrap(), &meta1, Some(Duration::from_secs(3)), c3, u3) => {debug!("notifier3"); 3}, + }; + assert_eq!(closed_item, 1); + + let _ = cp.get(&meta1.key).unwrap(); // mock_io3 should be selected + assert!(cp.get(&meta1.key).is_none()) // mock_io1 should already be removed by idle_poll + } + + #[tokio::test] + async fn test_evict_poll() { + let meta1 = ConnectionMeta::new(101, 1); + let mock_io1 = Arc::new(AsyncMutex::new( + Builder::new().wait(Duration::from_secs(99)).build(), + )); + let meta2 = ConnectionMeta::new(102, 2); + let mock_io2 = Arc::new(AsyncMutex::new( + Builder::new().wait(Duration::from_secs(99)).build(), + )); + let meta3 = ConnectionMeta::new(101, 3); + let mock_io3 = Arc::new(AsyncMutex::new( + Builder::new().wait(Duration::from_secs(99)).build(), + )); + let cp: ConnectionPool>> = ConnectionPool::new(2); + let (c1, u1) = cp.put(&meta1, mock_io1.clone()); + let (c2, u2) = cp.put(&meta2, mock_io2.clone()); + let (c3, u3) = cp.put(&meta3, mock_io3.clone()); // 1 should be evicted at this point + + let closed_item = tokio::select! { + _ = cp.idle_poll(mock_io1.try_lock_owned().unwrap(), &meta1, None, c1, u1) => {debug!("notifier1"); 1}, + _ = cp.idle_poll(mock_io2.try_lock_owned().unwrap(), &meta1, None, c2, u2) => {debug!("notifier2"); 2}, + _ = cp.idle_poll(mock_io3.try_lock_owned().unwrap(), &meta1, None, c3, u3) => {debug!("notifier3"); 3}, + }; + assert_eq!(closed_item, 1); + + let _ = cp.get(&meta1.key).unwrap(); // mock_io3 should be selected + assert!(cp.get(&meta1.key).is_none()) // mock_io1 should already be removed by idle_poll + } +} diff --git a/pingora-pool/src/lib.rs b/pingora-pool/src/lib.rs new file mode 100644 index 0000000..6cbd99e --- /dev/null +++ b/pingora-pool/src/lib.rs @@ -0,0 +1,28 @@ +// 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. + +//! Generic connection pooling +//! +//! The pool is optimized for high concurrency, high RPS use cases. Each connection group has a +//! lock free hot pool to reduce the lock contention when some connections are reused and released +//! very frequently. + +#![warn(clippy::all)] +#![allow(clippy::new_without_default)] +#![allow(clippy::type_complexity)] + +mod connection; +mod lru; + +pub use connection::{ConnectionMeta, ConnectionPool, PoolNode}; diff --git a/pingora-pool/src/lru.rs b/pingora-pool/src/lru.rs new file mode 100644 index 0000000..a370cfb --- /dev/null +++ b/pingora-pool/src/lru.rs @@ -0,0 +1,177 @@ +// 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 core::hash::Hash; +use lru::LruCache; +use parking_lot::RwLock; +use std::cell::RefCell; +use std::sync::atomic::{AtomicBool, Ordering::Relaxed}; +use std::sync::Arc; +use thread_local::ThreadLocal; +use tokio::sync::Notify; + +pub struct Node { + pub close_notifier: Arc, + pub meta: T, +} + +impl Node { + pub fn new(meta: T) -> Self { + Node { + close_notifier: Arc::new(Notify::new()), + meta, + } + } + + pub fn notify_close(&self) { + self.close_notifier.notify_one(); + } +} + +pub struct Lru +where + K: Send, + T: Send, +{ + lru: RwLock>>>>, + size: usize, + drain: AtomicBool, +} + +impl Lru +where + K: Hash + Eq + Send, + T: Send, +{ + pub fn new(size: usize) -> Self { + Lru { + lru: RwLock::new(ThreadLocal::new()), + size, + drain: AtomicBool::new(false), + } + } + + // put a node in and return the meta of the replaced node + pub fn put(&self, key: K, value: Node) -> Option { + if self.drain.load(Relaxed) { + value.notify_close(); // sort of hack to simulate being evicted right away + return None; + } + let lru = self.lru.read(); /* read lock */ + let lru_cache = &mut *(lru + .get_or(|| RefCell::new(LruCache::unbounded())) + .borrow_mut()); + lru_cache.put(key, value); + if lru_cache.len() > self.size { + match lru_cache.pop_lru() { + Some((_, v)) => { + // TODO: drop the lock here? + v.notify_close(); + return Some(v.meta); + } + None => return None, + } + } + None + /* read lock dropped */ + } + + pub fn add(&self, key: K, meta: T) -> (Arc, Option) { + let node = Node::new(meta); + let notifier = node.close_notifier.clone(); + // TODO: check if the key is already in it + (notifier, self.put(key, node)) + } + + pub fn pop(&self, key: &K) -> Option> { + let lru = self.lru.read(); /* read lock */ + let lru_cache = &mut *(lru + .get_or(|| RefCell::new(LruCache::unbounded())) + .borrow_mut()); + lru_cache.pop(key) + /* read lock dropped */ + } + + #[allow(dead_code)] + pub fn drain(&self) { + self.drain.store(true, Relaxed); + + /* drain need to go through all the local lru cache objects + * acquire an exclusive write lock to make it safe */ + let mut lru = self.lru.write(); /* write lock */ + let lru_cache_iter = lru.iter_mut(); + for lru_cache_rc in lru_cache_iter { + let mut lru_cache = lru_cache_rc.borrow_mut(); + for (_, item) in lru_cache.iter() { + item.notify_close(); + } + lru_cache.clear(); + } + /* write lock dropped */ + } +} + +#[cfg(test)] +mod tests { + use super::*; + use log::debug; + + #[tokio::test] + async fn test_evict_close() { + let pool: Lru = Lru::new(2); + let (notifier1, _) = pool.add(1, ()); + let (notifier2, _) = pool.add(2, ()); + let (notifier3, _) = pool.add(3, ()); + let closed_item = tokio::select! { + _ = notifier1.notified() => {debug!("notifier1"); 1}, + _ = notifier2.notified() => {debug!("notifier2"); 2}, + _ = notifier3.notified() => {debug!("notifier3"); 3}, + }; + assert_eq!(closed_item, 1); + } + + #[tokio::test] + async fn test_evict_close_with_pop() { + let pool: Lru = Lru::new(2); + let (notifier1, _) = pool.add(1, ()); + let (notifier2, _) = pool.add(2, ()); + pool.pop(&1); + let (notifier3, _) = pool.add(3, ()); + let (notifier4, _) = pool.add(4, ()); + let closed_item = tokio::select! { + _ = notifier1.notified() => {debug!("notifier1"); 1}, + _ = notifier2.notified() => {debug!("notifier2"); 2}, + _ = notifier3.notified() => {debug!("notifier3"); 3}, + _ = notifier4.notified() => {debug!("notifier4"); 4}, + }; + assert_eq!(closed_item, 2); + } + + #[tokio::test] + async fn test_drain() { + let pool: Lru = Lru::new(4); + let (notifier1, _) = pool.add(1, ()); + let (notifier2, _) = pool.add(2, ()); + let (notifier3, _) = pool.add(3, ()); + pool.drain(); + let (notifier4, _) = pool.add(4, ()); + + tokio::join!( + notifier1.notified(), + notifier2.notified(), + notifier3.notified(), + notifier4.notified() + ); + } +} diff --git a/pingora-proxy/Cargo.toml b/pingora-proxy/Cargo.toml new file mode 100644 index 0000000..d76ab48 --- /dev/null +++ b/pingora-proxy/Cargo.toml @@ -0,0 +1,49 @@ +[package] +name = "pingora-proxy" +version = "0.1.0" +authors = ["Yuchen Wu "] +license = "Apache-2.0" +edition = "2021" +repository = "https://github.com/cloudflare/pingora" +categories = ["asynchronous", "network-programming"] +keywords = ["async", "http", "proxy", "pingora"] +exclude = ["tests/*"] +description = """ +Pingora HTTP proxy APIs and traits. +""" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +name = "pingora_proxy" +path = "src/lib.rs" + +[dependencies] +pingora-error = { version = "0.1.0", path = "../pingora-error" } +pingora-core = { version = "0.1.0", path = "../pingora-core" } +pingora-timeout = { version = "0.1.0", path = "../pingora-timeout" } +pingora-cache = { version = "0.1.0", path = "../pingora-cache" } +tokio = { workspace = true, features = ["macros", "net"] } +pingora-http = { version = "0.1.0", path = "../pingora-http" } +http = { workspace = true } +futures = "0.3" +bytes = { workspace = true } +async-trait = { workspace = true } +log = { workspace = true } +h2 = { workspace = true } +once_cell = { workspace = true } +structopt = "0.3" +regex = "1" + +[dev-dependencies] +reqwest = { version = "0.11", features = [ + "gzip", + "rustls", +], default-features = false } +tokio-test = "0.4" +env_logger = "0.9" +hyperlocal = "0.8" +hyper = "0.14" +tokio-tungstenite = "0.20.1" +pingora-load-balancing = { version = "0.1.0", path = "../pingora-load-balancing" } +prometheus = "0" +futures-util = "0.3" diff --git a/pingora-proxy/LICENSE b/pingora-proxy/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/pingora-proxy/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/pingora-proxy/examples/ctx.rs b/pingora-proxy/examples/ctx.rs new file mode 100644 index 0000000..36169e2 --- /dev/null +++ b/pingora-proxy/examples/ctx.rs @@ -0,0 +1,99 @@ +// 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 async_trait::async_trait; +use log::info; +use std::sync::Mutex; +use structopt::StructOpt; + +use pingora_core::server::configuration::Opt; +use pingora_core::server::Server; +use pingora_core::upstreams::peer::HttpPeer; +use pingora_core::Result; +use pingora_proxy::{ProxyHttp, Session}; + +// global counter +static REQ_COUNTER: Mutex = Mutex::new(0); + +pub struct MyProxy { + // counter for the service + beta_counter: Mutex, // AtomicUsize works too +} + +pub struct MyCtx { + beta_user: bool, +} + +fn check_beta_user(req: &pingora_http::RequestHeader) -> bool { + // some simple logic to check if user is beta + req.headers.get("beta-flag").is_some() +} + +#[async_trait] +impl ProxyHttp for MyProxy { + type CTX = MyCtx; + fn new_ctx(&self) -> Self::CTX { + MyCtx { beta_user: false } + } + + async fn request_filter(&self, session: &mut Session, ctx: &mut Self::CTX) -> Result { + ctx.beta_user = check_beta_user(session.req_header()); + Ok(false) + } + + async fn upstream_peer( + &self, + _session: &mut Session, + ctx: &mut Self::CTX, + ) -> Result> { + let mut req_counter = REQ_COUNTER.lock().unwrap(); + *req_counter += 1; + + let addr = if ctx.beta_user { + let mut beta_count = self.beta_counter.lock().unwrap(); + *beta_count += 1; + info!("I'm a beta user #{beta_count}"); + ("1.0.0.1", 443) + } else { + info!("I'm an user #{req_counter}"); + ("1.1.1.1", 443) + }; + + let peer = Box::new(HttpPeer::new(addr, true, "one.one.one.one".to_string())); + Ok(peer) + } +} + +// RUST_LOG=INFO cargo run --example ctx +// curl 127.0.0.1:6190 -H "Host: one.one.one.one" +// curl 127.0.0.1:6190 -H "Host: one.one.one.one" -H "beta-flag: 1" +fn main() { + env_logger::init(); + + // read command line arguments + let opt = Opt::from_args(); + let mut my_server = Server::new(Some(opt)).unwrap(); + my_server.bootstrap(); + + let mut my_proxy = pingora_proxy::http_proxy_service( + &my_server.configuration, + MyProxy { + beta_counter: Mutex::new(0), + }, + ); + my_proxy.add_tcp("0.0.0.0:6190"); + + my_server.add_service(my_proxy); + my_server.run_forever(); +} diff --git a/pingora-proxy/examples/gateway.rs b/pingora-proxy/examples/gateway.rs new file mode 100644 index 0000000..27c5020 --- /dev/null +++ b/pingora-proxy/examples/gateway.rs @@ -0,0 +1,136 @@ +// 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 async_trait::async_trait; +use log::info; +use prometheus::register_int_counter; +use structopt::StructOpt; + +use pingora_core::server::configuration::Opt; +use pingora_core::server::Server; +use pingora_core::upstreams::peer::HttpPeer; +use pingora_core::Result; +use pingora_http::ResponseHeader; +use pingora_proxy::{ProxyHttp, Session}; + +fn check_login(req: &pingora_http::RequestHeader) -> bool { + // implement you logic check logic here + req.headers.get("Authorization").map(|v| v.as_bytes()) == Some(b"password") +} + +pub struct MyGateway { + req_metric: prometheus::IntCounter, +} + +#[async_trait] +impl ProxyHttp for MyGateway { + type CTX = (); + fn new_ctx(&self) -> Self::CTX {} + + async fn request_filter(&self, session: &mut Session, _ctx: &mut Self::CTX) -> Result { + if session.req_header().uri.path().starts_with("/login") + && !check_login(session.req_header()) + { + let _ = session.respond_error(403).await; + // true: early return as the response is already written + return Ok(true); + } + Ok(false) + } + + async fn upstream_peer( + &self, + session: &mut Session, + _ctx: &mut Self::CTX, + ) -> Result> { + let addr = if session.req_header().uri.path().starts_with("/family") { + ("1.0.0.1", 443) + } else { + ("1.1.1.1", 443) + }; + + info!("connecting to {addr:?}"); + + let peer = Box::new(HttpPeer::new(addr, true, "one.one.one.one".to_string())); + Ok(peer) + } + + async fn response_filter( + &self, + _session: &mut Session, + upstream_response: &mut ResponseHeader, + _ctx: &mut Self::CTX, + ) -> Result<()> + where + Self::CTX: Send + Sync, + { + // replace existing header if any + upstream_response + .insert_header("Server", "MyGateway") + .unwrap(); + // because we don't support h3 + upstream_response.remove_header("alt-svc"); + + Ok(()) + } + + async fn logging( + &self, + session: &mut Session, + _e: Option<&pingora_core::Error>, + ctx: &mut Self::CTX, + ) { + let response_code = session + .response_written() + .map_or(0, |resp| resp.status.as_u16()); + info!( + "{} response code: {response_code}", + self.request_summary(session, ctx) + ); + + self.req_metric.inc(); + } +} + +// RUST_LOG=INFO cargo run --example load_balancer +// curl 127.0.0.1:6191 -H "Host: one.one.one.one" +// curl 127.0.0.1:6190/family/ -H "Host: one.one.one.one" +// curl 127.0.0.1:6191/login/ -H "Host: one.one.one.one" -I -H "Authorization: password" +// curl 127.0.0.1:6191/login/ -H "Host: one.one.one.one" -I -H "Authorization: bad" +// For metrics +// curl 127.0.0.1:6192/ +fn main() { + env_logger::init(); + + // read command line arguments + let opt = Opt::from_args(); + let mut my_server = Server::new(Some(opt)).unwrap(); + my_server.bootstrap(); + + let mut my_proxy = pingora_proxy::http_proxy_service( + &my_server.configuration, + MyGateway { + req_metric: register_int_counter!("reg_counter", "Number of requests").unwrap(), + }, + ); + my_proxy.add_tcp("0.0.0.0:6191"); + my_server.add_service(my_proxy); + + let mut prometheus_service_http = + pingora_core::services::listening::Service::prometheus_http_service(); + prometheus_service_http.add_tcp("127.0.0.1:6192"); + my_server.add_service(prometheus_service_http); + + my_server.run_forever(); +} diff --git a/pingora-proxy/examples/load_balancer.rs b/pingora-proxy/examples/load_balancer.rs new file mode 100644 index 0000000..425b6ec --- /dev/null +++ b/pingora-proxy/examples/load_balancer.rs @@ -0,0 +1,96 @@ +// 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 async_trait::async_trait; +use log::info; +use pingora_core::services::background::background_service; +use std::{sync::Arc, time::Duration}; +use structopt::StructOpt; + +use pingora_core::server::configuration::Opt; +use pingora_core::server::Server; +use pingora_core::upstreams::peer::HttpPeer; +use pingora_core::Result; +use pingora_load_balancing::{health_check, selection::RoundRobin, LoadBalancer}; +use pingora_proxy::{ProxyHttp, Session}; + +pub struct LB(Arc>); + +#[async_trait] +impl ProxyHttp for LB { + type CTX = (); + fn new_ctx(&self) -> Self::CTX {} + + async fn upstream_peer(&self, _session: &mut Session, _ctx: &mut ()) -> Result> { + let upstream = self + .0 + .select(b"", 256) // hash doesn't matter + .unwrap(); + + info!("upstream peer is: {:?}", upstream); + + let peer = Box::new(HttpPeer::new(upstream, true, "one.one.one.one".to_string())); + Ok(peer) + } + + async fn upstream_request_filter( + &self, + _session: &mut Session, + upstream_request: &mut pingora_http::RequestHeader, + _ctx: &mut Self::CTX, + ) -> Result<()> { + upstream_request + .insert_header("Host", "one.one.one.one") + .unwrap(); + Ok(()) + } +} + +// RUST_LOG=INFO cargo run --example load_balancer +fn main() { + env_logger::init(); + + // read command line arguments + let opt = Opt::from_args(); + let mut my_server = Server::new(Some(opt)).unwrap(); + my_server.bootstrap(); + + // 127.0.0.1:343" is just a bad server + let mut upstreams = + LoadBalancer::try_from_iter(["1.1.1.1:443", "1.0.0.1:443", "127.0.0.1:343"]).unwrap(); + + // We add health check in the background so that the bad server is never selected. + let hc = health_check::TcpHealthCheck::new(); + upstreams.set_health_check(hc); + upstreams.health_check_frequency = Some(Duration::from_secs(1)); + + let background = background_service("health check", upstreams); + + let upstreams = background.task(); + + let mut lb = pingora_proxy::http_proxy_service(&my_server.configuration, LB(upstreams)); + lb.add_tcp("0.0.0.0:6188"); + + 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 tls_settings = + pingora_core::listeners::TlsSettings::intermediate(&cert_path, &key_path).unwrap(); + tls_settings.enable_h2(); + lb.add_tls_with_settings("0.0.0.0:6189", None, tls_settings); + + my_server.add_service(lb); + my_server.add_service(background); + my_server.run_forever(); +} diff --git a/pingora-proxy/src/lib.rs b/pingora-proxy/src/lib.rs new file mode 100644 index 0000000..d1aa399 --- /dev/null +++ b/pingora-proxy/src/lib.rs @@ -0,0 +1,628 @@ +// 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. + +//! # pingora-proxy +//! +//! Programmable HTTP proxy built on top of [pingora_core]. +//! +//! # Features +//! - HTTP/1.x and HTTP/2 for both downstream and upstream +//! - Connection pooling +//! - TLSv1.3, mutual TLS, customizable CA +//! - Request/Response scanning, modification or rejection +//! - Dynamic upstream selection +//! - Configurable retry and failover +//! - Fully programmable and customizable at any stage of a HTTP request +//! +//! # How to use +//! +//! Users of this crate defines their proxy by implementing [ProxyHttp] trait, which contains the +//! callbacks to be invoked at each stage of a HTTP request. +//! +//! Then the service can be passed into [`http_proxy_service()`] for a [pingora_core::server::Server] to +//! run it. +//! +//! See `examples/load_balancer.rs` for a detailed example. + +// enable nightly feature async trait so that the docs are cleaner +#![cfg_attr(doc_async_trait, feature(async_fn_in_trait))] + +use async_trait::async_trait; +use bytes::Bytes; +use futures::future::FutureExt; +use http::{header, version::Version}; +use log::{debug, error, trace, warn}; +use once_cell::sync::Lazy; +use pingora_http::{RequestHeader, ResponseHeader}; +use std::fmt::Debug; +use std::str; +use std::sync::Arc; +use tokio::sync::{mpsc, Notify}; +use tokio::time; + +use pingora_cache::NoCacheReason; +use pingora_core::apps::HttpServerApp; +use pingora_core::connectors::{http::Connector, ConnectorOptions}; +use pingora_core::protocols::http::client::HttpSession as ClientSession; +use pingora_core::protocols::http::v1::client::HttpSession as HttpSessionV1; +use pingora_core::protocols::http::HttpTask; +use pingora_core::protocols::http::ServerSession as HttpSession; +use pingora_core::protocols::http::SERVER_NAME; +use pingora_core::protocols::Stream; +use pingora_core::protocols::{Digest, UniqueID}; +use pingora_core::server::configuration::ServerConf; +use pingora_core::server::ShutdownWatch; +use pingora_core::upstreams::peer::{HttpPeer, Peer}; +use pingora_error::{Error, ErrorSource, ErrorType::*, OrErr, Result}; + +const MAX_RETRIES: usize = 16; +const TASK_BUFFER_SIZE: usize = 4; + +mod proxy_cache; +mod proxy_common; +mod proxy_h1; +mod proxy_h2; +mod proxy_purge; +mod proxy_trait; +mod subrequest; + +use subrequest::Ctx as SubReqCtx; + +pub use proxy_trait::ProxyHttp; + +pub mod prelude { + pub use crate::{http_proxy_service, ProxyHttp, Session}; +} + +/// The concrete type that holds the user defined HTTP proxy. +/// +/// Users don't need to interact with this object directly. +pub struct HttpProxy { + inner: SV, // TODO: name it better than inner + client_upstream: Connector, + shutdown: Notify, +} + +impl HttpProxy { + fn new(inner: SV, conf: Arc) -> Arc { + Arc::new(HttpProxy { + inner, + client_upstream: Connector::new(Some(ConnectorOptions::from_server_conf(&conf))), + shutdown: Notify::new(), + }) + } + + async fn handle_new_request( + &self, + mut downstream_session: Box, + ) -> Option> + where + SV: ProxyHttp + Send + Sync, + SV::CTX: Send + Sync, + { + // phase 1 read request header + + let res = tokio::select! { + biased; // biased select is cheaper and we don't want to drop already buffered requests + res = downstream_session.read_request() => { res } + _ = self.shutdown.notified() => { + // service shutting down, dropping the connection to stop more req from coming in + return None; + } + }; + match res { + Ok(true) => { + // TODO: check n==0 + debug!("Successfully get a new request"); + } + Ok(false) => { + return None; // TODO: close connection? + } + Err(mut e) => { + e.as_down(); + error!("Fail to proxy: {}", e); + if matches!(e.etype, InvalidHTTPHeader) { + downstream_session.respond_error(400).await; + } // otherwise the connection must be broken, no need to send anything + downstream_session.shutdown().await; + return None; + } + } + trace!( + "Request header: {:?}", + downstream_session.req_header().as_ref() + ); + Some(downstream_session) + } + + // return bool: server_session can be reused, and error if any + async fn proxy_to_upstream( + &self, + session: &mut Session, + ctx: &mut SV::CTX, + ) -> (bool, Option>) + where + SV: ProxyHttp + Send + Sync, + SV::CTX: Send + Sync, + { + let peer = match self.inner.upstream_peer(session, ctx).await { + Ok(p) => p, + Err(e) => return (false, Some(e)), + }; + + let client_session = self.client_upstream.get_http_session(&*peer).await; + match client_session { + Ok((client_session, client_reused)) => { + let (server_reused, error) = match client_session { + ClientSession::H1(mut h1) => { + let (server_reused, client_reuse, error) = self + .proxy_to_h1_upstream(session, &mut h1, client_reused, &peer, ctx) + .await; + if client_reuse { + let session = ClientSession::H1(h1); + self.client_upstream + .release_http_session(session, &*peer, peer.idle_timeout()) + .await; + } + (server_reused, error) + } + ClientSession::H2(mut h2) => { + let (server_reused, mut error) = self + .proxy_to_h2_upstream(session, &mut h2, client_reused, &peer, ctx) + .await; + let session = ClientSession::H2(h2); + self.client_upstream + .release_http_session(session, &*peer, peer.idle_timeout()) + .await; + + if let Some(e) = error.as_mut() { + // try to downgrade if A. origin says so or B. origin sends an invalid + // response, which usually means origin h2 is not production ready + if matches!(e.etype, H2Downgrade | InvalidH2) { + if peer + .get_alpn() + .map_or(true, |alpn| alpn.get_min_http_version() == 1) + { + // Add the peer to prefer h1 so that all following requests + // will use h1 + self.client_upstream.prefer_h1(&*peer); + } else { + // the peer doesn't allow downgrading to h1 (e.g. gRPC) + e.retry = false.into(); + } + } + } + + (server_reused, error) + } + }; + ( + server_reused, + error.map(|e| { + self.inner + .error_while_proxy(&peer, session, e, ctx, client_reused) + }), + ) + } + Err(e) => { + let new_err = self.inner.fail_to_connect(session, &peer, ctx, e); + (false, Some(new_err.into_up())) + } + } + } + + fn upstream_filter(&self, session: &mut Session, task: &mut HttpTask, ctx: &mut SV::CTX) + where + SV: ProxyHttp, + { + match task { + HttpTask::Header(header, _eos) => { + self.inner.upstream_response_filter(session, header, ctx) + } + HttpTask::Body(data, eos) => self + .inner + .upstream_response_body_filter(session, data, *eos, ctx), + _ => { + // TODO: add other upstream filter traits + } + } + } + + async fn finish( + &self, + mut session: Session, + ctx: &mut SV::CTX, + reuse: bool, + error: Option<&Error>, + ) -> Option + where + SV: ProxyHttp + Send + Sync, + SV::CTX: Send + Sync, + { + self.inner.logging(&mut session, error, ctx).await; + + if reuse { + // TODO: log error + session.downstream_session.finish().await.ok().flatten() + } else { + None + } + } +} + +use pingora_cache::HttpCache; +use pingora_core::protocols::http::compression::ResponseCompressionCtx; + +/// The established HTTP session +/// +/// This object is what users interact with in order to access the request itself or change the proxy +/// behavior. +pub struct Session { + /// the HTTP session to downstream (the client) + pub downstream_session: Box, + /// The interface to control HTTP caching + pub cache: HttpCache, + /// (de)compress responses coming into the proxy (from upstream) + pub upstream_compression: ResponseCompressionCtx, + /// (de)compress responses leaving the proxy (to downstream) + pub downstream_compression: ResponseCompressionCtx, + /// ignore downstream range (skip downstream range filters) + pub ignore_downstream_range: bool, + // the context from parent request + subrequest_ctx: Option>, +} + +impl Session { + fn new(downstream_session: impl Into>) -> Self { + Session { + downstream_session: downstream_session.into(), + cache: HttpCache::new(), + upstream_compression: ResponseCompressionCtx::new(0, false), // disable both + downstream_compression: ResponseCompressionCtx::new(0, false), // disable both + ignore_downstream_range: false, + subrequest_ctx: None, + } + } + + /// Create a new [Session] from the given [Stream] + /// + /// This function is mostly used for testing and mocking. + pub fn new_h1(stream: Stream) -> Self { + Self::new(Box::new(HttpSession::new_http1(stream))) + } + + pub fn as_downstream_mut(&mut self) -> &mut HttpSession { + &mut self.downstream_session + } + + pub fn as_downstream(&self) -> &HttpSession { + &self.downstream_session + } +} + +impl Session { + async fn write_response_tasks(&mut self, mut tasks: Vec) -> Result { + // all built-in downstream response filters goes here + // NOTE: if downstream_session is written directly (error page), the filters will be + // bypassed. + tasks + .iter_mut() + .for_each(|t| self.downstream_compression.response_filter(t)); + self.downstream_session.response_duplex_vec(tasks).await + } +} + +impl AsRef for Session { + fn as_ref(&self) -> &HttpSession { + &self.downstream_session + } +} + +impl AsMut for Session { + fn as_mut(&mut self) -> &mut HttpSession { + &mut self.downstream_session + } +} + +use std::ops::{Deref, DerefMut}; + +impl Deref for Session { + type Target = HttpSession; + + fn deref(&self) -> &Self::Target { + &self.downstream_session + } +} + +impl DerefMut for Session { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.downstream_session + } +} + +// generic HTTP 502 response sent when proxy_upstream_filter refuses to connect to upstream +static BAD_GATEWAY: Lazy = Lazy::new(|| { + let mut resp = ResponseHeader::build(http::StatusCode::BAD_GATEWAY, Some(3)).unwrap(); + resp.insert_header(header::SERVER, &SERVER_NAME[..]) + .unwrap(); + resp.insert_header(header::CONTENT_LENGTH, 0).unwrap(); + resp.insert_header(header::CACHE_CONTROL, "private, no-store") + .unwrap(); + + resp +}); + +impl HttpProxy { + async fn process_request( + self: &Arc, + mut session: Session, + mut ctx: ::CTX, + ) -> Option + where + SV: ProxyHttp + Send + Sync + 'static, + ::CTX: Send + Sync, + { + match self.inner.request_filter(&mut session, &mut ctx).await { + Ok(response_sent) => { + if response_sent { + // TODO: log error + self.inner.logging(&mut session, None, &mut ctx).await; + return session.downstream_session.finish().await.ok().flatten(); + } + /* else continue */ + } + Err(e) => { + if !self.inner.suppress_error_log(&session, &ctx, &e) { + error!( + "Fail to filter request: {}, {}", + e, + self.inner.request_summary(&session, &ctx) + ); + } + self.inner.fail_to_proxy(&mut session, &e, &mut ctx).await; + self.inner.logging(&mut session, Some(&e), &mut ctx).await; + return None; + } + } + + // all built-in downstream request filters go below + + session + .downstream_compression + .request_filter(session.downstream_session.req_header()); + + if let Some((reuse, err)) = self.proxy_cache(&mut session, &mut ctx).await { + // cache hit + return self.finish(session, &mut ctx, reuse, err.as_deref()).await; + } + // either uncacheable, or cache miss + + // decide if the request is allowed to go to upstream + match self + .inner + .proxy_upstream_filter(&mut session, &mut ctx) + .await + { + Ok(proxy_to_upstream) => { + if !proxy_to_upstream { + // The hook can choose to write its own response, but if it doesn't we respond + // with a generic 502 + if session.response_written().is_none() { + match session.write_response_header_ref(&BAD_GATEWAY).await { + Ok(()) => {} + Err(e) => { + if !self.inner.suppress_error_log(&session, &ctx, &e) { + error!( + "Error responding with Bad Gateway: {}, {}", + e, + self.inner.request_summary(&session, &ctx) + ); + } + self.inner.fail_to_proxy(&mut session, &e, &mut ctx).await; + self.inner.logging(&mut session, Some(&e), &mut ctx).await; + return None; + } + } + } + + return self.finish(session, &mut ctx, false, None).await; + } + /* else continue */ + } + Err(e) => { + if !self.inner.suppress_error_log(&session, &ctx, &e) { + error!( + "Error deciding if we should proxy to upstream: {}, {}", + e, + self.inner.request_summary(&session, &ctx) + ); + } + self.inner.fail_to_proxy(&mut session, &e, &mut ctx).await; + self.inner.logging(&mut session, Some(&e), &mut ctx).await; + return None; + } + } + + let mut retries: usize = 0; + + let mut server_reuse = false; + let mut proxy_error: Option> = None; + + while retries < MAX_RETRIES { + retries += 1; + + let (reuse, e) = self.proxy_to_upstream(&mut session, &mut ctx).await; + server_reuse = reuse; + + match e { + Some(error) => { + let retry = error.retry(); + proxy_error = Some(error); + if !retry { + break; + } + // only log error that will be retried here, the final error will be logged below + warn!( + "Fail to proxy: {}, tries: {}, retry: {}, {}", + proxy_error.as_ref().unwrap(), + retries, + retry, + self.inner.request_summary(&session, &ctx) + ); + } + None => { + proxy_error = None; + break; + } + }; + } + + // serve stale if error + // check both error and cache before calling the function because await is not cheap + let serve_stale_result = if proxy_error.is_some() && session.cache.can_serve_stale_error() { + self.handle_stale_if_error(&mut session, &mut ctx, proxy_error.as_ref().unwrap()) + .await + } else { + None + }; + + let final_error = if let Some((reuse, stale_cache_error)) = serve_stale_result { + // don't reuse server conn if serve stale polluted it + server_reuse = server_reuse && reuse; + stale_cache_error + } else { + proxy_error + }; + + if let Some(e) = final_error.as_ref() { + let status = self.inner.fail_to_proxy(&mut session, e, &mut ctx).await; + + // final error will have > 0 status unless downstream connection is dead + if !self.inner.suppress_error_log(&session, &ctx, e) { + error!( + "Fail to proxy: {}, status: {}, tries: {}, retry: {}, {}", + final_error.as_ref().unwrap(), + status, + retries, + false, // we never retry here + self.inner.request_summary(&session, &ctx) + ); + } + } + + // logging() will be called in finish() + self.finish(session, &mut ctx, server_reuse, final_error.as_deref()) + .await + } +} + +/* Make process_subrequest() a trait to workaround https://github.com/rust-lang/rust/issues/78649 + if process_subrequest() is implemented as a member of HttpProxy, rust complains + +error[E0391]: cycle detected when computing type of `proxy_cache::::proxy_cache::{opaque#0}` + --> pingora-proxy/src/proxy_cache.rs:13:10 + | +13 | ) -> Option<(bool, Option>)> + +*/ +#[async_trait] +trait Subrequest { + async fn process_subrequest( + self: &Arc, + session: Box, + sub_req_ctx: Box, + ); +} + +#[async_trait] +impl Subrequest for HttpProxy +where + SV: ProxyHttp + Send + Sync + 'static, + ::CTX: Send + Sync, +{ + async fn process_subrequest( + self: &Arc, + session: Box, + sub_req_ctx: Box, + ) { + debug!("starting subrequest"); + let mut session = match self.handle_new_request(session).await { + Some(downstream_session) => Session::new(downstream_session), + None => return, // bad request + }; + + // no real downstream to keepalive but it doesn't matter what is set here because at the end + // of this fn the dummy connection will be dropped + session.set_keepalive(None); + + session.subrequest_ctx.replace(sub_req_ctx); + trace!("processing subrequest"); + let ctx = self.inner.new_ctx(); + self.process_request(session, ctx).await; + trace!("subrequest done"); + } +} + +#[async_trait] +impl HttpServerApp for HttpProxy +where + SV: ProxyHttp + Send + Sync + 'static, + ::CTX: Send + Sync, +{ + async fn process_new_http( + self: &Arc, + session: HttpSession, + shutdown: &ShutdownWatch, + ) -> Option { + let session = Box::new(session); + + // TODO: keepalive pool, use stack + let mut session = match self.handle_new_request(session).await { + Some(downstream_session) => Session::new(downstream_session), + None => return None, // bad request + }; + + if *shutdown.borrow() { + // stop downstream downstream from reusing if this service is shutting down soon + session.set_keepalive(None); + } else { + // default 60s + session.set_keepalive(Some(60)); + } + + let ctx = self.inner.new_ctx(); + self.process_request(session, ctx).await + } + + fn http_cleanup(&self) { + // Notify all keepalived request blocking on read_request() to abort + self.shutdown.notify_waiters(); + + // TODO: impl shutting down flag so that we don't need to read stack.is_shutting_down() + } + + // TODO implement h2_options +} + +use pingora_core::services::listening::Service; + +/// Create a [Service] from the user implemented [ProxyHttp]. +/// +/// The returned [Service] can be hosted by a [pingora_core::server::Server] directly. +pub fn http_proxy_service(conf: &Arc, inner: SV) -> Service> { + Service::new( + "Pingora HTTP Proxy Service".into(), + HttpProxy::new(inner, conf.clone()), + ) +} diff --git a/pingora-proxy/src/proxy_cache.rs b/pingora-proxy/src/proxy_cache.rs new file mode 100644 index 0000000..02bc378 --- /dev/null +++ b/pingora-proxy/src/proxy_cache.rs @@ -0,0 +1,1203 @@ +// 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 super::*; +use http::StatusCode; +use pingora_cache::key::CacheHashKey; +use pingora_cache::lock::LockStatus; +use pingora_cache::max_file_size::ERR_RESPONSE_TOO_LARGE; +use pingora_cache::{HitStatus, RespCacheable::*}; +use pingora_core::protocols::http::v1::common::header_value_content_length; +use pingora_core::ErrorType; + +impl HttpProxy { + // return bool: server_session can be reused, and error if any + pub(crate) async fn proxy_cache( + self: &Arc, + session: &mut Session, + ctx: &mut SV::CTX, + ) -> Option<(bool, Option>)> + // None: continue to proxy, Some: return + where + SV: ProxyHttp + Send + Sync + 'static, + SV::CTX: Send + Sync, + { + // Cache logic request phase + if let Err(e) = self.inner.request_cache_filter(session, ctx) { + // TODO: handle this error + warn!( + "Fail to request_cache_filter: {e}, {}", + self.inner.request_summary(session, ctx) + ); + } + + // cache key logic, should this be part of request_cache_filter? + if session.cache.enabled() { + match self.inner.cache_key_callback(session, ctx) { + Ok(key) => { + session.cache.set_cache_key(key); + } + Err(e) => { + // TODO: handle this error + session.cache.disable(NoCacheReason::StorageError); + warn!( + "Fail to cache_key_callback: {e}, {}", + self.inner.request_summary(session, ctx) + ); + } + } + } + + // cache purge logic: PURGE short-circuits rest of request + if self.inner.is_purge(session, ctx) { + if session.cache.enabled() { + return self.proxy_purge(session, ctx).await; + } else { + return Some(proxy_purge::write_no_purge_response(session).await); + } + } + + // bypass cache lookup if we predict to be uncacheable + if session.cache.enabled() && !session.cache.cacheable_prediction() { + session.cache.bypass(); + } + + if !session.cache.enabled() { + return None; + } + + // cache lookup logic + loop { + // for cache lock, TODO: cap the max number of loops + match session.cache.cache_lookup().await { + Ok(res) => { + if let Some((mut meta, handler)) = res { + // vary logic + // because this branch can be called multiple times in a loop, and we only + // need to to update the vary once, check if variance is already set to + // prevent unnecessary vary lookups + let cache_key = session.cache.cache_key(); + if let Some(variance) = cache_key.variance_bin() { + // adhoc double check the variance found is the variance we want + if Some(variance) != meta.variance() { + warn!("Cache variance mismatch, {variance:?}, {cache_key:?}"); + session.cache.disable(NoCacheReason::InternalError); + break None; + } + } else { + let req_header = session.req_header(); + let variance = self.inner.cache_vary_filter(&meta, ctx, req_header); + if let Some(variance) = variance { + if !session.cache.cache_vary_lookup(variance, &meta) { + // cache key variance updated, need to lookup again + continue; + } + } //else: vary is not in use + } + + // either no variance or the current handler is the variance + + // hit + // TODO: maybe round and/or cache now() + let hit_status = if meta.is_fresh(std::time::SystemTime::now()) { + // check if we should force expire + // (this is a soft purge which tries to revalidate, + // vs. hard purge which forces miss) + // TODO: allow hard purge + match self + .inner + .cache_hit_filter(&meta, ctx, session.req_header()) + .await + { + Err(e) => { + error!( + "Failed to filter cache hit: {e}, {}", + self.inner.request_summary(session, ctx) + ); + // this return value will cause us to fetch from upstream + HitStatus::FailedHitFilter + } + Ok(expired) => { + // force expired asset should not be serve as stale + // because force expire is usually to remove data + if expired { + meta.disable_serve_stale(); + HitStatus::ForceExpired + } else { + HitStatus::Fresh + } + } + } + } else { + HitStatus::Expired + }; + // init cache for hit / stale + session.cache.cache_found(meta, handler, hit_status); + + if !hit_status.is_fresh() { + // expired or force expired asset + if session.cache.is_cache_locked() { + // first if this is the sub request for the background cache update + if let Some(write_lock) = session + .subrequest_ctx + .as_mut() + .and_then(|ctx| ctx.write_lock.take()) + { + // Put the write lock in the request + session.cache.set_write_lock(write_lock); + // and then let it go to upstream + break None; + } + let will_serve_stale = session.cache.can_serve_stale_updating() + && self.inner.should_serve_stale(session, ctx, None); + if !will_serve_stale { + let lock_status = session.cache.cache_lock_wait().await; + if self.handle_lock_status(session, ctx, lock_status) { + continue; + } else { + break None; + } + } // else continue to serve stale + } else if session.cache.is_cache_lock_writer() { + // stale while revalidate logic for the writer + let will_serve_stale = session.cache.can_serve_stale_updating() + && self.inner.should_serve_stale(session, ctx, None); + if will_serve_stale { + // create a background thread to do the actual update + let subrequest = + Box::new(crate::subrequest::create_dummy_session(session)); + let new_app = self.clone(); // Clone the Arc + let sub_req_ctx = Box::new(SubReqCtx { + write_lock: Some(session.cache.take_write_lock()), + }); + tokio::spawn(async move { + new_app.process_subrequest(subrequest, sub_req_ctx).await; + }); + // continue to serve stale for this request + } else { + // return to fetch from upstream + break None; + } + } else { + // return to fetch from upstream + break None; + } + } + let (reuse, err) = self.proxy_cache_hit(session, ctx).await; + if let Some(e) = err.as_ref() { + error!( + "Fail to serve cache: {e}, {}", + self.inner.request_summary(session, ctx) + ); + } + // responses is served from cache, exit + break Some((reuse, err)); + } else { + // cache miss + if session.cache.is_cache_locked() { + let lock_status = session.cache.cache_lock_wait().await; + if self.handle_lock_status(session, ctx, lock_status) { + continue; + } else { + break None; + } + } else { + self.inner.cache_miss(session, ctx); + break None; + } + } + } + Err(e) => { + // Allow cache miss to fill cache even if cache lookup errors + // this is mostly to suppport backward incompatible metadata update + // TODO: check error types + // session.cache.disable(); + self.inner.cache_miss(session, ctx); + warn!( + "Fail to cache lookup: {e}, {}", + self.inner.request_summary(session, ctx) + ); + break None; + } + } + } + } + + // return bool: server_session can be reused, and error if any + pub(crate) async fn proxy_cache_hit( + &self, + session: &mut Session, + ctx: &mut SV::CTX, + ) -> (bool, Option>) + where + SV: ProxyHttp + Send + Sync, + SV::CTX: Send + Sync, + { + use range_filter::*; + + let seekable = session.cache.hit_handler().can_seek(); + let mut header = cache_hit_header(&session.cache); + + let req = session.req_header(); + + let header_only = conditional_filter::not_modified_filter(req, &mut header) + || req.method == http::method::Method::HEAD; + + // process range header if the cache storage supports seek + let range_type = if seekable && !session.ignore_downstream_range { + range_header_filter(req, &mut header) + } else { + RangeType::None + }; + + // return a 416 with an empty body for simplicity + let header_only = header_only || matches!(range_type, RangeType::Invalid); + + // TODO: use ProxyUseCache to replace the logic below + match self.inner.response_filter(session, &mut header, ctx).await { + Ok(_) => { + if let Err(e) = session + .as_mut() + .write_response_header(header) + .await + .map_err(|e| e.into_down()) + { + // downstream connection is bad already + return (false, Some(e)); + } + } + Err(e) => { + // TODO: more logging and error handling + session.as_mut().respond_error(500).await; + // we have not write anything dirty to downstream, it is still reuseable + return (true, Some(e)); + } + } + debug!("finished sending cached header to downstream"); + + if !header_only { + if let RangeType::Single(r) = range_type { + if let Err(e) = session.cache.hit_handler().seek(r.start, Some(r.end)) { + return (false, Some(e)); + } + } + loop { + match session.cache.hit_handler().read_body().await { + Ok(body) => { + if let Some(b) = body { + // write to downstream + if let Err(e) = session + .as_mut() + .write_response_body(b) + .await + .map_err(|e| e.into_down()) + { + return (false, Some(e)); + } + } else { + break; + } + } + Err(e) => return (false, Some(e)), + } + } + } + + if let Err(e) = session.cache.finish_hit_handler().await { + warn!("Error during finish_hit_handler: {}", e); + } + + match session.as_mut().finish_body().await { + Ok(_) => { + debug!("finished sending cached body to downstream"); + (true, None) + } + Err(e) => (false, Some(e)), + } + } + + // TODO: cache upstream header filter to add/remove headers + + pub(crate) async fn cache_http_task( + &self, + session: &mut Session, + task: &HttpTask, + ctx: &mut SV::CTX, + serve_from_cache: &mut ServeFromCache, + ) -> Result<()> + where + SV: ProxyHttp + Send + Sync, + SV::CTX: Send + Sync, + { + if !session.cache.enabled() && !session.cache.bypassing() { + return Ok(()); + } + + match task { + HttpTask::Header(header, end_stream) => { + // decide if cacheable and create cache meta + // for now, skip 1xxs (should not affect response cache decisions) + // However 101 is an exception because it is the final response header + if header.status.is_informational() + && header.status != StatusCode::SWITCHING_PROTOCOLS + { + return Ok(()); + } + match self.inner.response_cache_filter(session, header, ctx)? { + Cacheable(meta) => { + let mut fill_cache = true; + if session.cache.bypassing() { + // The cache might have been bypassed because the response exceeded the + // maximum cacheable asset size. If that looks like the case (there + // is a maximum file size configured and we don't know the content + // length up front), attempting to re-enable the cache now would cause + // the request to fail when the chunked response exceeds the maximum + // file size again. + if session.cache.max_file_size_bytes().is_some() + && !header.headers.contains_key(header::CONTENT_LENGTH) + { + session.cache.disable(NoCacheReason::ResponseTooLarge); + return Ok(()); + } + + session.cache.response_became_cacheable(); + + if header.status == StatusCode::OK { + self.inner.cache_miss(session, ctx); + } else { + // we've allowed caching on the next request, + // but do not cache _this_ request if bypassed and not 200 + // (We didn't run upstream request cache filters to strip range or condition headers, + // so this could be an uncacheable response e.g. 206 or 304. + // Exclude all non-200 for simplicity, may expand allowable codes in the future.) + fill_cache = false; + session.cache.disable(NoCacheReason::Deferred); + } + } + + // If the Content-Length is known, and a maximum asset size has been configured + // on the cache, validate that the response does not exceed the maximum asset size. + if session.cache.enabled() { + if let Some(max_file_size) = session.cache.max_file_size_bytes() { + let content_length_hdr = header.headers.get(header::CONTENT_LENGTH); + if let Some(content_length) = + header_value_content_length(content_length_hdr) + { + if content_length > max_file_size { + fill_cache = false; + session.cache.response_became_uncacheable( + NoCacheReason::ResponseTooLarge, + ); + session.cache.disable(NoCacheReason::ResponseTooLarge); + } + } + // if the content-length header is not specified, the miss handler + // will count the response size on the fly, aborting the request + // mid-transfer if the max file size is exceeded + } + } + if fill_cache { + let req_header = session.req_header(); + // Update the variance in the meta via the same callback, + // cache_vary_filter(), used in cache lookup for consistency. + // Future cache lookups need a matching variance in the meta + // with the cache key to pick up the correct variance + let variance = self.inner.cache_vary_filter(&meta, ctx, req_header); + session.cache.set_cache_meta(meta); + session.cache.update_variance(variance); + // this sends the meta and header + session.cache.set_miss_handler().await?; + if session.cache.miss_body_reader().is_some() { + serve_from_cache.enable_miss(); + } + if *end_stream { + session + .cache + .miss_handler() + .unwrap() // safe, it is set above + .write_body(Bytes::new(), true) + .await?; + session.cache.finish_miss_handler().await?; + } + } + } + Uncacheable(reason) => { + if !session.cache.bypassing() { + // mark as uncacheable, so we bypass cache next time + session.cache.response_became_uncacheable(reason); + } + session.cache.disable(reason); + } + } + } + HttpTask::Body(data, end_stream) => match data { + Some(d) => { + if session.cache.enabled() { + // this will panic if more data is sent after we see end_stream + // but should be impossible in real world + let miss_handler = session.cache.miss_handler().unwrap(); + // TODO: do this async + let res = miss_handler.write_body(d.clone(), *end_stream).await; + if let Err(err) = res { + if err.etype == ERR_RESPONSE_TOO_LARGE { + debug!("chunked response exceeded max cache size, remembering that it is uncacheable"); + session + .cache + .response_became_uncacheable(NoCacheReason::ResponseTooLarge); + } + + return Err(err); + } + if *end_stream { + session.cache.finish_miss_handler().await?; + } + } + } + None => { + if session.cache.enabled() && *end_stream { + session.cache.finish_miss_handler().await?; + } + } + }, + HttpTask::Trailer(_) => {} // h1 trailer is not supported yet + HttpTask::Done => { + if session.cache.enabled() { + session.cache.finish_miss_handler().await?; + } + } + HttpTask::Failed(_) => { + // TODO: handle this failure: delete the temp files? + } + } + Ok(()) + } + + // Decide if local cache can be used according to upstream http header + // 1. when upstream returns 304, the local cache is refreshed and served fresh + // 2. when upstream returns certain HTTP error status, the local cache is served stale + // Return true if local cache should be used, false otherwise + pub(crate) async fn revalidate_or_stale( + &self, + session: &mut Session, + task: &mut HttpTask, + ctx: &mut SV::CTX, + ) -> bool + where + SV: ProxyHttp + Send + Sync, + SV::CTX: Send + Sync, + { + if !session.cache.enabled() { + return false; + } + + match task { + HttpTask::Header(resp, _eos) => { + if resp.status == StatusCode::NOT_MODIFIED { + if session.cache.maybe_cache_meta().is_some() { + // 304 doesn't contain all the headers, merge 304 into cached 200 header + // in order for response_cache_filter to run correctly + let merged_header = session.cache.revalidate_merge_header(resp); + match self + .inner + .response_cache_filter(session, &merged_header, ctx) + { + Ok(Cacheable(mut meta)) => { + // For simplicity, ignore changes to variance over 304 for now. + // Note this means upstream can only update variance via 2xx + // (expired response). + // + // TODO: if we choose to respect changing Vary / variance over 304, + // then there are a few cases to consider. See `update_variance` in + // the `pingora-cache` module. + let old_meta = session.cache.maybe_cache_meta().unwrap(); // safe, checked above + if let Some(old_variance) = old_meta.variance() { + meta.set_variance(old_variance); + } + if let Err(e) = session.cache.revalidate_cache_meta(meta).await { + warn!("revalidate_cache_meta failed {:?}", e); + } + // We can continue use the revalidated one even the meta was failed + // to write to storage + true + } + Ok(Uncacheable(reason)) => { + // This response was once cacheable, and upstream tells us it has not changed + // but now we decided it is uncacheable! + // RFC 9111: still allowed to reuse stored response this time because + // it was "successfully validated" + // https://www.rfc-editor.org/rfc/rfc9111#constructing.responses.from.caches + // Serve the response, but do not update cache + + // We also want to avoid poisoning downstream's cache with an unsolicited 304 + // if we did not receive a conditional request from downstream + // (downstream may have a different cacheability assessment and could cache the 304) + + //TODO: log more + warn!("Uncacheable {:?} 304 received", reason); + session.cache.response_became_uncacheable(reason); + session.cache.revalidate_uncacheable(merged_header, reason); + true + } + Err(e) => { + warn!("Error {:?} response_cache_filter during revalidation, disable caching", e); + session.cache.disable(NoCacheReason::InternalError); + false + } + } + } else { + //TODO: log more + warn!("304 received without cached asset, disable caching"); + let reason = NoCacheReason::Custom("304 on miss"); + session.cache.response_became_uncacheable(reason); + session.cache.disable(reason); + false + } + } else if resp.status.is_server_error() { + // stale if error logic, 5xx only for now + + // this is response header filter, response_written should always be None? + if !session.cache.can_serve_stale_error() + || session.response_written().is_some() + { + return false; + } + + // create an error to encode the http status code + let http_status_error = Error::create( + ErrorType::HTTPStatus(resp.status.as_u16()), + ErrorSource::Upstream, + None, + None, + ); + self.inner + .should_serve_stale(session, ctx, Some(&http_status_error)) + } else { + false // not 304, not stale if error status code + } + } + _ => false, // not header + } + } + + // None: no staled asset is used, Some(_): staled asset is sent to downstream + // bool: can the downstream connection be reused + pub(crate) async fn handle_stale_if_error( + &self, + session: &mut Session, + ctx: &mut SV::CTX, + error: &Error, + ) -> Option<(bool, Option>)> + where + SV: ProxyHttp + Send + Sync, + SV::CTX: Send + Sync, + { + // the caller might already checked this as an optimization + if !session.cache.can_serve_stale_error() { + return None; + } + + // the error happen halfway through a regular response to downstream + // can't resend the response + if session.response_written().is_some() { + return None; + } + + // check error types + if !self.inner.should_serve_stale(session, ctx, Some(error)) { + return None; + } + + // log the original error + warn!( + "Fail to proxy: {}, serving stale, {}", + error, + self.inner.request_summary(session, ctx) + ); + + Some(self.proxy_cache_hit(session, ctx).await) + } + + // helper function to check when to continue to retry lock (true) or give up (false) + fn handle_lock_status( + &self, + session: &mut Session, + ctx: &SV::CTX, + lock_status: LockStatus, + ) -> bool + where + SV: ProxyHttp, + { + debug!("cache unlocked {lock_status:?}"); + match lock_status { + // should lookup the cached asset again + LockStatus::Done => true, + // should compete to be a new writer + LockStatus::TransientError => true, + // the request is uncacheable, go ahead to fetch from the origin + LockStatus::GiveUp => { + // TODO: It will be nice for the writer to propagate the real reason + session.cache.disable(NoCacheReason::CacheLockGiveUp); + // not cacheable, just go to the origin. + false + } + // treat this the same as TransientError + LockStatus::Dangling => { + // software bug, but request can recover from this + warn!( + "Dangling cache lock, {}", + self.inner.request_summary(session, ctx) + ); + true + } + /* We have 3 options when a lock is held too long + * 1. release the lock and let every request complete for it again + * 2. let every request cache miss + * 3. let every request through while disabling cache + * #1 could repeat the situation but protect the origin from load + * #2 could amplify disk writes and storage for temp file + * #3 is the simplest option for now */ + LockStatus::Timeout => { + warn!( + "Cache lock timeout, {}", + self.inner.request_summary(session, ctx) + ); + session.cache.disable(NoCacheReason::CacheLockTimeout); + // not cacheable, just go to the origin. + false + } + // software bug, this status should be impossible to reach + LockStatus::Waiting => panic!("impossible LockStatus::Waiting"), + } + } +} + +fn cache_hit_header(cache: &HttpCache) -> Box { + let mut header = Box::new(cache.cache_meta().response_header_copy()); + // convert cache response + + // these status codes / method cannot have body, so no need to add chunked encoding + let no_body = matches!(header.status.as_u16(), 204 | 304); + + // https://www.rfc-editor.org/rfc/rfc9111#section-4: + // When a stored response is used to satisfy a request without validation, a cache + // MUST generate an Age header field + if !cache.upstream_used() { + let age = cache.cache_meta().age().as_secs(); + header.insert_header(http::header::AGE, age).unwrap(); + } + + /* Add chunked header to tell downstream to use chunked encoding + * during the absent of content-length in h2 */ + if !no_body + && !header.status.is_informational() + && header.headers.get(http::header::CONTENT_LENGTH).is_none() + { + header + .insert_header(http::header::TRANSFER_ENCODING, "chunked") + .unwrap(); + } + header +} + +// https://datatracker.ietf.org/doc/html/rfc7233#section-3 +pub(crate) mod range_filter { + use super::*; + use http::header::*; + use std::ops::Range; + + // parse bytes into usize, ignores specifc error + fn parse_number(input: &[u8]) -> Option { + str::from_utf8(input).ok()?.parse().ok() + } + + fn parse_range_header(range: &[u8], content_length: usize) -> RangeType { + use regex::Regex; + + // single byte range only for now + // https://datatracker.ietf.org/doc/html/rfc7233#section-2.1 + // https://datatracker.ietf.org/doc/html/rfc7233#appendix-C: case insensitive + static RE_SINGLE_RANGE: Lazy = + Lazy::new(|| Regex::new(r"(?i)bytes=(?P\d*)-(?P\d*)").unwrap()); + + // ignore invalid range header + let Ok(range_str) = str::from_utf8(range) else { + return RangeType::None; + }; + + let Some(captured) = RE_SINGLE_RANGE.captures(range_str) else { + return RangeType::None; + }; + let maybe_start = captured + .name("start") + .and_then(|s| s.as_str().parse::().ok()); + let end = captured + .name("end") + .and_then(|s| s.as_str().parse::().ok()); + + if let Some(start) = maybe_start { + if start >= content_length { + RangeType::Invalid + } else { + // open-ended range should end at the last byte + // over sized end is allow but ignored + // range end is inclusive + let end = std::cmp::min(end.unwrap_or(content_length - 1), content_length - 1) + 1; + if end <= start { + RangeType::Invalid + } else { + RangeType::new_single(start, end) + } + } + } else { + // start is empty, this changes the meaning of the value of `end` + // Now it means to read the last `end` bytes + if let Some(end) = end { + if content_length >= end { + RangeType::new_single(content_length - end, content_length) + } else { + // over sized end is allow but ignored + RangeType::new_single(0, content_length) + } + } else { + // both empty/invalid + RangeType::Invalid + } + } + } + #[test] + fn test_parse_range() { + assert_eq!( + parse_range_header(b"bytes=0-1", 10), + RangeType::new_single(0, 2) + ); + assert_eq!( + parse_range_header(b"bYTes=0-9", 10), + RangeType::new_single(0, 10) + ); + assert_eq!( + parse_range_header(b"bytes=0-12", 10), + RangeType::new_single(0, 10) + ); + assert_eq!( + parse_range_header(b"bytes=0-", 10), + RangeType::new_single(0, 10) + ); + assert_eq!(parse_range_header(b"bytes=2-1", 10), RangeType::Invalid); + assert_eq!(parse_range_header(b"bytes=10-11", 10), RangeType::Invalid); + assert_eq!( + parse_range_header(b"bytes=-2", 10), + RangeType::new_single(8, 10) + ); + assert_eq!( + parse_range_header(b"bytes=-12", 10), + RangeType::new_single(0, 10) + ); + assert_eq!(parse_range_header(b"bytes=-", 10), RangeType::Invalid); + assert_eq!(parse_range_header(b"bytes=", 10), RangeType::None); + } + + #[derive(Debug, Eq, PartialEq, Clone)] + pub enum RangeType { + None, + Single(Range), + // TODO: multi-range + Invalid, + } + + impl RangeType { + fn new_single(start: usize, end: usize) -> Self { + RangeType::Single(Range { start, end }) + } + } + + // TODO: if-range + + // single range for now + pub fn range_header_filter(req: &RequestHeader, resp: &mut ResponseHeader) -> RangeType { + // The Range header field is evaluated after evaluating the precondition + // header fields defined in [RFC7232], and only if the result in absence + // of the Range header field would be a 200 (OK) response + if resp.status != StatusCode::OK { + return RangeType::None; + } + + // "A server MUST ignore a Range header field received with a request method other than GET." + if req.method != http::Method::GET && req.method != http::Method::HEAD { + return RangeType::None; + } + + let Some(range_header) = req.headers.get(RANGE) else { + return RangeType::None; + }; + + // Content-Length is not required by RFC but it is what nginx does and easier to implement + // with this header present. + let Some(content_length_bytes) = resp.headers.get(CONTENT_LENGTH) else { + return RangeType::None; + }; + // bail on invalid content length + let Some(content_length) = parse_number(content_length_bytes.as_bytes()) else { + return RangeType::None; + }; + + // TODO: we can also check Accept-Range header from resp. Nginx gives uses the option + // see proxy_force_ranges + + let range_type = parse_range_header(range_header.as_bytes(), content_length); + + match &range_type { + RangeType::None => { /* nothing to do*/ } + RangeType::Single(r) => { + // 206 response + resp.set_status(StatusCode::PARTIAL_CONTENT).unwrap(); + resp.insert_header(&CONTENT_LENGTH, r.end - r.start) + .unwrap(); + resp.insert_header( + &CONTENT_RANGE, + format!("bytes {}-{}/{content_length}", r.start, r.end - 1), // range end is inclusive + ) + .unwrap() + } + RangeType::Invalid => { + // 416 response + resp.set_status(StatusCode::RANGE_NOT_SATISFIABLE).unwrap(); + // empty body for simplicity + resp.insert_header(&CONTENT_LENGTH, HeaderValue::from_static("0")) + .unwrap(); + // TODO: remove other headers like content-encoding + resp.remove_header(&CONTENT_TYPE); + resp.insert_header(&CONTENT_RANGE, format!("bytes */{content_length}")) + .unwrap() + } + } + + range_type + } + + #[test] + fn test_range_filter() { + fn gen_req() -> RequestHeader { + RequestHeader::build(http::Method::GET, b"/", Some(1)).unwrap() + } + fn gen_resp() -> ResponseHeader { + let mut resp = ResponseHeader::build(200, Some(1)).unwrap(); + resp.append_header("Content-Length", "10").unwrap(); + resp + } + + // no range + let req = gen_req(); + let mut resp = gen_resp(); + assert_eq!(RangeType::None, range_header_filter(&req, &mut resp)); + assert_eq!(resp.status.as_u16(), 200); + + // regular range + let mut req = gen_req(); + req.insert_header("Range", "bytes=0-1").unwrap(); + let mut resp = gen_resp(); + assert_eq!( + RangeType::new_single(0, 2), + range_header_filter(&req, &mut resp) + ); + assert_eq!(resp.status.as_u16(), 206); + assert_eq!(resp.headers.get("content-length").unwrap().as_bytes(), b"2"); + assert_eq!( + resp.headers.get("content-range").unwrap().as_bytes(), + b"bytes 0-1/10" + ); + + // bad range + let mut req = gen_req(); + req.insert_header("Range", "bytes=1-0").unwrap(); + let mut resp = gen_resp(); + assert_eq!(RangeType::Invalid, range_header_filter(&req, &mut resp)); + assert_eq!(resp.status.as_u16(), 416); + assert_eq!(resp.headers.get("content-length").unwrap().as_bytes(), b"0"); + assert_eq!( + resp.headers.get("content-range").unwrap().as_bytes(), + b"bytes */10" + ); + } + + pub struct RangeBodyFilter { + range: RangeType, + current: usize, + } + + impl RangeBodyFilter { + pub fn new() -> Self { + RangeBodyFilter { + range: RangeType::None, + current: 0, + } + } + + pub fn set(&mut self, range: RangeType) { + self.range = range; + } + + pub fn filter_body(&mut self, data: Option) -> Option { + match &self.range { + RangeType::None => data, + RangeType::Invalid => None, + RangeType::Single(r) => { + let current = self.current; + self.current += data.as_ref().map_or(0, |d| d.len()); + data.and_then(|d| Self::filter_range_data(r.start, r.end, current, d)) + } + } + } + + fn filter_range_data( + start: usize, + end: usize, + current: usize, + data: Bytes, + ) -> Option { + if current + data.len() < start || current >= end { + // if the current data is out side the desired range, just drop the data + None + } else if current >= start && current + data.len() <= end { + // all data is within the slice + Some(data) + } else { + // data: current........current+data.len() + // range: start...........end + let slice_start = start.saturating_sub(current); + let slice_end = std::cmp::min(data.len(), end - current); + Some(data.slice(slice_start..slice_end)) + } + } + } + + #[test] + fn test_range_body_filter() { + let mut body_filter = RangeBodyFilter::new(); + assert_eq!(body_filter.filter_body(Some("123".into())).unwrap(), "123"); + + let mut body_filter = RangeBodyFilter::new(); + body_filter.set(RangeType::Invalid); + assert!(body_filter.filter_body(Some("123".into())).is_none()); + + let mut body_filter = RangeBodyFilter::new(); + body_filter.set(RangeType::new_single(0, 1)); + assert_eq!(body_filter.filter_body(Some("012".into())).unwrap(), "0"); + assert!(body_filter.filter_body(Some("345".into())).is_none()); + + let mut body_filter = RangeBodyFilter::new(); + body_filter.set(RangeType::new_single(4, 6)); + assert!(body_filter.filter_body(Some("012".into())).is_none()); + assert_eq!(body_filter.filter_body(Some("345".into())).unwrap(), "45"); + assert!(body_filter.filter_body(Some("678".into())).is_none()); + + let mut body_filter = RangeBodyFilter::new(); + body_filter.set(RangeType::new_single(1, 7)); + assert_eq!(body_filter.filter_body(Some("012".into())).unwrap(), "12"); + assert_eq!(body_filter.filter_body(Some("345".into())).unwrap(), "345"); + assert_eq!(body_filter.filter_body(Some("678".into())).unwrap(), "6"); + } +} + +// https://datatracker.ietf.org/doc/html/rfc7232 +// Strictly speaking this module is also usable for web server, not just proxy +mod conditional_filter { + use super::*; + use http::header::*; + + // return if 304 is applied to the response + pub fn not_modified_filter(req: &RequestHeader, resp: &mut ResponseHeader) -> bool { + // https://datatracker.ietf.org/doc/html/rfc7232#section-4.1 + // 304 can only validate 200 + if resp.status != StatusCode::OK { + return false; + } + + // TODO: If-Match and if If-Unmodified-Since + + // https://datatracker.ietf.org/doc/html/rfc7232#section-6 + + if let Some(inm) = req.headers.get(IF_NONE_MATCH) { + if let Some(etag) = resp.headers.get(ETAG) { + if validate_etag(inm.as_bytes(), etag.as_bytes()) { + to_304(resp); + return true; + } + } + // MUST ignore If-Modified-Since if the request contains an If-None-Match header + return false; + } + + // TODO: GET/HEAD only https://datatracker.ietf.org/doc/html/rfc7232#section-3.3 + if let Some(since) = req.headers.get(IF_MODIFIED_SINCE) { + if let Some(last) = resp.headers.get(LAST_MODIFIED) { + if test_not_modified(since.as_bytes(), last.as_bytes()) { + to_304(resp); + return true; + } + } + } + false + } + + fn validate_etag(input_etag: &[u8], target_etag: &[u8]) -> bool { + // https://datatracker.ietf.org/doc/html/rfc7232#section-3.2 unsafe method only + if input_etag == b"*" { + return true; + } + // TODO: etag validation: https://datatracker.ietf.org/doc/html/rfc7232#section-2.3.2 + input_etag == target_etag + } + + fn test_not_modified(input_time: &[u8], last_modified_time: &[u8]) -> bool { + // TODO: http-date comparison: https://datatracker.ietf.org/doc/html/rfc7232#section-2.2.2 + input_time == last_modified_time + } + + fn to_304(resp: &mut ResponseHeader) { + // https://datatracker.ietf.org/doc/html/rfc7232#section-4.1 + // XXX: https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.2 + // "A server may send content-length in 304", but no common web server does it + // So we drop both content-length and content-type for consistency/less surprise + resp.set_status(StatusCode::NOT_MODIFIED).unwrap(); + resp.remove_header(&CONTENT_LENGTH); + resp.remove_header(&CONTENT_TYPE); + } +} + +// a state machine for proxy logic to tell when to use cache in the case of +// miss/revalidation/error. +#[derive(Debug)] +pub(crate) enum ServeFromCache { + Off, // not using cache + CacheHeader, // should serve cache header + CacheHeaderOnly, // should serve cache header + CacheBody, // should serve cache body + CacheHeaderMiss, // should serve cache header but upstream response should be admitted to cache + CacheBodyMiss, // should serve cache body but upstream response should be admitted to cache + Done, // should serve cache body +} + +impl ServeFromCache { + pub fn new() -> Self { + Self::Off + } + + pub fn is_on(&self) -> bool { + !matches!(self, Self::Off) + } + + pub fn is_miss(&self) -> bool { + matches!(self, Self::CacheHeaderMiss | Self::CacheBodyMiss) + } + + pub fn is_miss_header(&self) -> bool { + matches!(self, Self::CacheHeaderMiss) + } + + pub fn is_miss_body(&self) -> bool { + matches!(self, Self::CacheBodyMiss) + } + + pub fn should_discard_upstream(&self) -> bool { + self.is_on() && !self.is_miss() + } + + pub fn should_send_to_downstream(&self) -> bool { + !self.is_on() + } + + pub fn enable(&mut self) { + *self = Self::CacheHeader; + } + + pub fn enable_miss(&mut self) { + if !self.is_on() { + *self = Self::CacheHeaderMiss; + } + } + + pub fn enable_header_only(&mut self) { + match self { + Self::CacheBody => *self = Self::Done, // TODO: make sure no body is read yet + _ => *self = Self::CacheHeaderOnly, + } + } + + // This function is (best effort) cancel-safe to be used in select + pub async fn next_http_task(&mut self, cache: &mut HttpCache) -> Result { + if !cache.enabled() { + // Cache is disabled due to internal error + // TODO: if nothing is sent to eyeball yet, figure out a way to recovery by + // fetching from upstream + return Error::e_explain(InternalError, "Cache disabled"); + } + match self { + Self::Off => panic!("ProxyUseCache not enabled"), + Self::CacheHeader => { + *self = Self::CacheBody; + Ok(HttpTask::Header(cache_hit_header(cache), false)) // false for now + } + Self::CacheHeaderMiss => { + *self = Self::CacheBodyMiss; + Ok(HttpTask::Header(cache_hit_header(cache), false)) // false for now + } + Self::CacheHeaderOnly => { + *self = Self::Done; + Ok(HttpTask::Header(cache_hit_header(cache), true)) + } + Self::CacheBody => { + if let Some(b) = cache.hit_handler().read_body().await? { + Ok(HttpTask::Body(Some(b), false)) // false for now + } else { + *self = Self::Done; + Ok(HttpTask::Done) + } + } + Self::CacheBodyMiss => { + // safety: called of enable_miss() call it only if the async_body_reader exist + if let Some(b) = cache.miss_body_reader().unwrap().read_body().await? { + Ok(HttpTask::Body(Some(b), false)) // false for now + } else { + *self = Self::Done; + Ok(HttpTask::Done) + } + } + Self::Done => Ok(HttpTask::Done), + } + } +} + +/* Downstream revalidation, only needed when cache is on because otherwise origin + * will handle it */ +pub(crate) fn downstream_response_conditional_filter( + use_cache: &mut ServeFromCache, + req: &RequestHeader, + resp: &mut ResponseHeader, +) { + // TODO: range + let header_only = conditional_filter::not_modified_filter(req, resp) + || req.method == http::method::Method::HEAD; + if header_only { + if use_cache.is_on() { + // tell cache to stop after yielding header + use_cache.enable_header_only(); + } else { + // headers only during cache miss, upstream should continue send + // body to cache, `session` will ignore body automatically because + // of the signature of `header` (304) + // TODO: we should drop body before/within this filter so that body + // filter only runs on data downstream sees + } + } +} diff --git a/pingora-proxy/src/proxy_common.rs b/pingora-proxy/src/proxy_common.rs new file mode 100644 index 0000000..d7d97b3 --- /dev/null +++ b/pingora-proxy/src/proxy_common.rs @@ -0,0 +1,93 @@ +/// Possible downstream states during request multiplexing +#[derive(Debug, Clone, Copy)] +pub(crate) enum DownstreamStateMachine { + /// more request (body) to read + Reading, + /// no more data to read + ReadingFinished, + /// downstream is already errored or closed + Errored, +} + +#[allow(clippy::wrong_self_convention)] +impl DownstreamStateMachine { + pub fn new(finished: bool) -> Self { + if finished { + Self::ReadingFinished + } else { + Self::Reading + } + } + + // Can call read() to read more data or wait on closing + pub fn can_poll(&self) -> bool { + !matches!(self, Self::Errored) + } + + pub fn is_reading(&self) -> bool { + matches!(self, Self::Reading) + } + + pub fn is_done(&self) -> bool { + !matches!(self, Self::Reading) + } + + pub fn is_errored(&self) -> bool { + matches!(self, Self::Errored) + } + + /// Move the state machine to Finished state if `set` is true + pub fn maybe_finished(&mut self, set: bool) { + if set { + *self = Self::ReadingFinished + } + } + + pub fn to_errored(&mut self) { + *self = Self::Errored + } +} + +/// Possible upstream states during request multiplexing +#[derive(Debug, Clone, Copy)] +pub(crate) struct ResponseStateMachine { + upstream_response_done: bool, + cached_response_done: bool, +} + +impl ResponseStateMachine { + pub fn new() -> Self { + ResponseStateMachine { + upstream_response_done: false, + cached_response_done: true, // no cached response by default + } + } + + pub fn is_done(&self) -> bool { + self.upstream_response_done && self.cached_response_done + } + + pub fn upstream_done(&self) -> bool { + self.upstream_response_done + } + + pub fn cached_done(&self) -> bool { + self.cached_response_done + } + + pub fn enable_cached_response(&mut self) { + self.cached_response_done = false; + } + + pub fn maybe_set_upstream_done(&mut self, done: bool) { + if done { + self.upstream_response_done = true; + } + } + + pub fn maybe_set_cache_done(&mut self, done: bool) { + if done { + self.cached_response_done = true; + } + } +} diff --git a/pingora-proxy/src/proxy_h1.rs b/pingora-proxy/src/proxy_h1.rs new file mode 100644 index 0000000..77bc50b --- /dev/null +++ b/pingora-proxy/src/proxy_h1.rs @@ -0,0 +1,596 @@ +// 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 super::*; +use crate::proxy_cache::{range_filter::RangeBodyFilter, ServeFromCache}; +use crate::proxy_common::*; +use http::Version; + +impl HttpProxy { + pub(crate) async fn proxy_1to1( + &self, + session: &mut Session, + client_session: &mut HttpSessionV1, + peer: &HttpPeer, + ctx: &mut SV::CTX, + ) -> (bool, bool, Option>) + where + SV: ProxyHttp + Send + Sync, + SV::CTX: Send + Sync, + { + client_session.read_timeout = peer.options.read_timeout; + client_session.write_timeout = peer.options.write_timeout; + + // phase 2 send to upstream + + let mut req = session.req_header().clone(); + + // Convert HTTP2 headers to H1 + if req.version == Version::HTTP_2 { + req.set_version(Version::HTTP_11); + // if client has body but has no content length, add chunked encoding + // https://datatracker.ietf.org/doc/html/rfc9112#name-message-body + // "The presence of a message body in a request is signaled by a Content-Length or Transfer-Encoding header field." + if !session.is_body_empty() && session.get_header(header::CONTENT_LENGTH).is_none() { + req.insert_header(header::TRANSFER_ENCODING, "chunked") + .unwrap(); + } + if session.get_header(header::HOST).is_none() { + // H2 is required to set :authority, but no necessarily header + // most H1 server expect host header, so convert + let host = req.uri.authority().map_or("", |a| a.as_str()).to_owned(); + req.insert_header(header::HOST, host).unwrap(); + } + // TODO: Add keepalive header for connection reuse, but this is not required per RFC + } + + if session.cache.enabled() { + if let Err(e) = pingora_cache::filters::upstream::request_filter( + &mut req, + session.cache.maybe_cache_meta(), + ) { + session.cache.disable(NoCacheReason::InternalError); + warn!("cache upstream filter error {}, disabling cache", e); + } + } + + match self + .inner + .upstream_request_filter(session, &mut req, ctx) + .await + { + Ok(_) => { /* continue */ } + Err(e) => { + return (false, true, Some(e)); + } + } + + session.upstream_compression.request_filter(&req); + + debug!("Sending header to upstream {:?}", req); + + match client_session.write_request_header(Box::new(req)).await { + Ok(_) => { /* Continue */ } + Err(e) => { + return (false, false, Some(e.into_up())); + } + } + + let (tx_upstream, rx_upstream) = mpsc::channel::(TASK_BUFFER_SIZE); + let (tx_downstream, rx_downstream) = mpsc::channel::(TASK_BUFFER_SIZE); + + session.as_mut().enable_retry_buffering(); + + // start bi-directional streaming + let ret = tokio::try_join!( + self.proxy_handle_downstream(session, tx_downstream, rx_upstream, ctx), + self.proxy_handle_upstream(client_session, tx_upstream, rx_downstream), + ); + + match ret { + Ok((_first, _second)) => { + client_session.respect_keepalive(); + (true, true, None) + } + Err(e) => (false, false, Some(e)), + } + } + + pub(crate) async fn proxy_to_h1_upstream( + &self, + session: &mut Session, + client_session: &mut HttpSessionV1, + reused: bool, + peer: &HttpPeer, + ctx: &mut SV::CTX, + ) -> (bool, bool, Option>) + // (reuse_server, reuse_client, error) + where + SV: ProxyHttp + Send + Sync, + SV::CTX: Send + Sync, + { + if let Err(e) = self + .inner + .connected_to_upstream( + session, + reused, + peer, + client_session.id(), + Some(client_session.digest()), + ctx, + ) + .await + { + return (false, false, Some(e)); + } + + let (server_session_reuse, client_session_reuse, error) = + self.proxy_1to1(session, client_session, peer, ctx).await; + + (server_session_reuse, client_session_reuse, error) + } + + async fn proxy_handle_upstream( + &self, + client_session: &mut HttpSessionV1, + tx: mpsc::Sender, + mut rx: mpsc::Receiver, + ) -> Result<()> + where + SV: ProxyHttp + Send + Sync, + SV::CTX: Send + Sync, + { + let mut request_done = false; + let mut response_done = false; + + /* duplex mode, wait for either to complete */ + while !request_done || !response_done { + tokio::select! { + res = client_session.read_response_task(), if !response_done => { + match res { + Ok(task) => { + response_done = task.is_end(); + let result = tx.send(task) + .await.or_err( + InternalError, + "Failed to send upstream header to pipe"); + // If the request is upgraded, the downstream pipe can early exit + // when the downstream connection is closed. + // In that case, this function should ignore that the pipe is closed. + // So that this function could read the rest events from rx including + // the closure, then exit. + if result.is_err() && !client_session.is_upgrade_req() { + return result; + } + }, + Err(e) => { + // Push the error to downstream and then quit + // Don't care if send fails: downstream already gone + let _ = tx.send(HttpTask::Failed(e.into_up())).await; + // Downstream should consume all remaining data and handle the error + return Ok(()) + } + } + }, + + body = rx.recv(), if !request_done => { + request_done = send_body_to1(client_session, body).await?; + // An upgraded request is terminated when either side is done + if request_done && client_session.is_upgrade_req() { + response_done = true; + } + }, + + else => { + // this shouldn't be reached as the while loop would already exit + break; + } + } + } + + Ok(()) + } + + // todo use this function to replace bidirection_1to2() + async fn proxy_handle_downstream( + &self, + session: &mut Session, + tx: mpsc::Sender, + mut rx: mpsc::Receiver, + ctx: &mut SV::CTX, + ) -> Result<()> + where + SV: ProxyHttp + Send + Sync, + SV::CTX: Send + Sync, + { + let mut downstream_state = DownstreamStateMachine::new(session.as_mut().is_body_done()); + + let buffer = session.as_ref().get_retry_buffer(); + + // retry, send buffer if it exists or body empty + if buffer.is_some() || session.as_mut().is_body_empty() { + let send_permit = tx + .reserve() + .await + .or_err(InternalError, "reserving body pipe")?; + send_body_to_pipe(buffer, downstream_state.is_done(), send_permit).await; + } + + let mut response_state = ResponseStateMachine::new(); + + // these two below can be wrapped into an internal ctx + // use cache when upstream revalidates (or TODO: error) + let mut serve_from_cache = proxy_cache::ServeFromCache::new(); + let mut range_body_filter = proxy_cache::range_filter::RangeBodyFilter::new(); + + /* duplex mode without caching + * Read body from downstream while reading response from upstream + * If response is done, only read body from downstream + * If request is done, read response from upstream while idling downstream (to close quickly) + * If both are done, quit the loop + * + * With caching + but without partial read support + * Similar to above, cache admission write happen when the data is write to downstream + * + * With caching + partial read support + * A. Read upstream response and write to cache + * B. Read data from cache and send to downstream + * If B fails (usually downstream close), continue A. + * If A fails, exit with error. + * If both are done, quit the loop + * Usually there is no request body to read for cacheable request + */ + while !downstream_state.is_done() || !response_state.is_done() { + // reserve tx capacity ahead to avoid deadlock, see below + + let send_permit = tx + .try_reserve() + .or_err(InternalError, "try_reserve() body pipe for upstream"); + + tokio::select! { + // only try to send to pipe if there is capacity to avoid deadlock + // Otherwise deadlock could happen if both upstream and downstream are blocked + // on sending to their corresponding pipes which are both full. + body = session.downstream_session.read_body_or_idle(downstream_state.is_done()), + if downstream_state.can_poll() && send_permit.is_ok() => { + + debug!("downstream event"); + let body = match body { + Ok(b) => b, + Err(e) => { + if serve_from_cache.is_miss() { + // ignore downstream error so that upstream can continue write cache + downstream_state.to_errored(); + warn!( + "Downstream Error ignored during caching: {}, {}", + e, + self.inner.request_summary(session, ctx) + ); + continue; + } else { + return Err(e.into_down()); + } + } + }; + // If the request is websocket, `None` body means the request is closed. + // Set the response to be done as well so that the request completes normally. + if body.is_none() && session.is_upgrade_req() { + response_state.maybe_set_upstream_done(true); + } + // TODO: consider just drain this if serve_from_cache is set + let request_done = send_body_to_pipe( + body, + session.is_body_done(), + send_permit.unwrap(), // safe because we checked is_ok() + ) + .await; + downstream_state.maybe_finished(request_done); + }, + + _ = tx.reserve(), if downstream_state.is_reading() && send_permit.is_err() => { + debug!("waiting for permit {send_permit:?}"); + /* No permit, wait on more capacity to avoid starving. + * Otherwise this select only blocks on rx, which might send no data + * before the entire body is uploaded. + * once more capacity arrives we just loop back + */ + }, + + task = rx.recv(), if !response_state.upstream_done() => { + debug!("upstream event: {:?}", task); + if let Some(t) = task { + if serve_from_cache.should_discard_upstream() { + // just drain, do we need to do anything else? + continue; + } + // pull as many tasks as we can + let mut tasks = Vec::with_capacity(TASK_BUFFER_SIZE); + tasks.push(t); + while let Some(maybe_task) = rx.recv().now_or_never() { + debug!("upstream event now: {:?}", maybe_task); + if let Some(t) = maybe_task { + tasks.push(t); + } else { + break; // upstream closed + } + } + + /* run filters before sending to downstream */ + let mut filtered_tasks = Vec::with_capacity(TASK_BUFFER_SIZE); + for mut t in tasks { + if self.revalidate_or_stale(session, &mut t, ctx).await { + serve_from_cache.enable(); + response_state.enable_cached_response(); + // skip downstream filtering entirely as the 304 will not be sent + break; + } + session.upstream_compression.response_filter(&mut t); + let task = self.h1_response_filter(session, t, ctx, + &mut serve_from_cache, + &mut range_body_filter, false).await?; + if serve_from_cache.is_miss_header() { + response_state.enable_cached_response(); + } + // check error and abort + // otherwise the error is surfaced via write_response_tasks() + if !serve_from_cache.should_send_to_downstream() { + if let HttpTask::Failed(e) = task { + return Err(e); + } + } + filtered_tasks.push(task); + } + + if !serve_from_cache.should_send_to_downstream() { + // TODO: need to derive response_done from filtered_tasks in case downstream failed already + continue; + } + + // set to downstream + let response_done = session.write_response_tasks(filtered_tasks).await?; + response_state.maybe_set_upstream_done(response_done); + // unsuccessful upgrade response may force the request done + downstream_state.maybe_finished(session.is_body_done()); + } else { + debug!("empty upstream event"); + response_state.maybe_set_upstream_done(true); + } + }, + + task = serve_from_cache.next_http_task(&mut session.cache), + if !response_state.cached_done() && !downstream_state.is_errored() && serve_from_cache.is_on() => { + + let task = self.h1_response_filter(session, task?, ctx, + &mut serve_from_cache, + &mut range_body_filter, true).await?; + debug!("serve_from_cache task {task:?}"); + + match session.write_response_tasks(vec![task]).await { + Ok(b) => response_state.maybe_set_cache_done(b), + Err(e) => if serve_from_cache.is_miss() { + // give up writing to downstream but wait for upstream cache write to finish + downstream_state.to_errored(); + response_state.maybe_set_cache_done(true); + warn!( + "Downstream Error ignored during caching: {}, {}", + e, + self.inner.request_summary(session, ctx) + ); + continue; + } else { + return Err(e); + } + } + if response_state.cached_done() { + if let Err(e) = session.cache.finish_hit_handler().await { + warn!("Error during finish_hit_handler: {}", e); + } + } + } + + else => { + break; + } + } + } + + match session.as_mut().finish_body().await { + Ok(_) => { + debug!("finished sending body to downstream"); + } + Err(e) => { + error!("Error finish sending body to downstream: {}", e); + // TODO: don't do downstream keepalive + } + } + Ok(()) + } + + async fn h1_response_filter( + &self, + session: &mut Session, + mut task: HttpTask, + ctx: &mut SV::CTX, + serve_from_cache: &mut ServeFromCache, + range_body_filter: &mut RangeBodyFilter, + from_cache: bool, // are the task from cache already + ) -> Result + where + SV: ProxyHttp + Send + Sync, + SV::CTX: Send + Sync, + { + // skip caching if already served from cache + if !from_cache { + self.upstream_filter(session, &mut task, ctx); + + // cache the original response before any downstream transformation + // requests that bypassed cache still need to run filters to see if the response has become cacheable + if session.cache.enabled() || session.cache.bypassing() { + if let Err(e) = self + .cache_http_task(session, &task, ctx, serve_from_cache) + .await + { + session.cache.disable(NoCacheReason::StorageError); + if serve_from_cache.is_miss_body() { + // if the response stream cache body during miss but write fails, it has to + // give up the entire request + return Err(e); + } else { + // otherwise, continue processing the response + warn!( + "Fail to cache response: {}, {}", + e, + self.inner.request_summary(session, ctx) + ); + } + } + } + + if !serve_from_cache.should_send_to_downstream() { + return Ok(task); + } + } // else: cached/local response, no need to trigger upstream filters and caching + + match task { + HttpTask::Header(mut header, end) => { + let req = session.req_header(); + + /* Downstream revalidation/range, only needed when cache is on because otherwise origin + * will handle it */ + // TODO: if cache is disabled during response phase, we should still do the filter + if session.cache.enabled() { + proxy_cache::downstream_response_conditional_filter( + serve_from_cache, + req, + &mut header, + ); + if !session.ignore_downstream_range { + let range_type = + proxy_cache::range_filter::range_header_filter(req, &mut header); + range_body_filter.set(range_type); + } + } + + /* Convert HTTP 1.0 style response to chunked encoding so that we don't + * have to close the downstream connection */ + // these status codes / method cannot have body, so no need to add chunked encoding + let no_body = req.method == http::method::Method::HEAD + || matches!(header.status.as_u16(), 204 | 304); + if !no_body + && !header.status.is_informational() + && header + .headers + .get(http::header::TRANSFER_ENCODING) + .is_none() + && header.headers.get(http::header::CONTENT_LENGTH).is_none() + && !end + { + header.insert_header(http::header::TRANSFER_ENCODING, "chunked")?; + } + + match self.inner.response_filter(session, &mut header, ctx).await { + Ok(_) => Ok(HttpTask::Header(header, end)), + Err(e) => Err(e), + } + } + HttpTask::Body(data, end) => { + let data = range_body_filter.filter_body(data); + if let Some(duration) = self.inner.response_body_filter(session, &data, ctx)? { + trace!("delaying response for {:?}", duration); + time::sleep(duration).await; + } + Ok(HttpTask::Body(data, end)) + } + HttpTask::Trailer(h) => Ok(HttpTask::Trailer(h)), // no h1 trailer filter yet + HttpTask::Done => Ok(task), + HttpTask::Failed(_) => Ok(task), // Do nothing just pass the error down + } + } +} + +// TODO:: use this function to replace send_body_to2 +pub(crate) async fn send_body_to_pipe( + data: Option, + end_of_body: bool, + tx: mpsc::Permit<'_, HttpTask>, +) -> bool { + match data { + Some(data) => { + debug!("Read {} bytes body from downstream", data.len()); + if data.is_empty() && !end_of_body { + /* it is normal to get 0 bytes because of multi-chunk + * don't write 0 bytes to downstream since it will be + * misread as the terminating chunk */ + return false; + } + tx.send(HttpTask::Body(Some(data), end_of_body)); + end_of_body + } + None => { + tx.send(HttpTask::Body(None, true)); + true + } + } +} + +pub(crate) async fn send_body_to1( + client_session: &mut HttpSessionV1, + recv_task: Option, +) -> Result { + let body_done; + + if let Some(task) = recv_task { + match task { + HttpTask::Body(data, end) => { + body_done = end; + if let Some(d) = data { + let m = client_session.write_body(&d).await; + match m { + Ok(m) => match m { + Some(n) => { + debug!("Write {} bytes body to upstream", n); + } + None => { + warn!("Upstream body is already finished. Nothing to write"); + } + }, + Err(e) => { + return e.into_up().into_err(); + } + } + } + } + _ => { + // should never happen, sender only sends body + warn!("Unexpected task sent to upstream"); + body_done = true; + } + } + } else { + // sender dropped + body_done = true; + } + + if body_done { + match client_session.finish_body().await { + Ok(_) => { + debug!("finish sending body to upstream"); + Ok(true) + } + Err(e) => e.into_up().into_err(), + } + } else { + Ok(false) + } +} diff --git a/pingora-proxy/src/proxy_h2.rs b/pingora-proxy/src/proxy_h2.rs new file mode 100644 index 0000000..87bb895 --- /dev/null +++ b/pingora-proxy/src/proxy_h2.rs @@ -0,0 +1,616 @@ +// 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 super::*; +use crate::proxy_cache::{range_filter::RangeBodyFilter, ServeFromCache}; +use crate::proxy_common::*; +use pingora_core::protocols::http::v2::client::{write_body, Http2Session}; + +// add scheme and authority as required by h2 lib +fn update_h2_scheme_authority(header: &mut http::request::Parts, raw_host: &[u8]) -> Result<()> { + let authority = if let Ok(s) = std::str::from_utf8(raw_host) { + if s.starts_with('[') { + // don't mess with ipv6 host + s + } else if let Some(colon) = s.find(':') { + if s.len() == colon + 1 { + // colon is the last char, ignore + s + } else if let Some(another_colon) = s[colon + 1..].find(':') { + // try to get rid of extra port numbers + &s[..colon + 1 + another_colon] + } else { + s + } + } else { + s + } + } else { + return Error::e_explain( + InvalidHTTPHeader, + format!("invalid authority from host {:?}", raw_host), + ); + }; + + let uri = http::uri::Builder::new() + .scheme("https") + .authority(authority) + .path_and_query(header.uri.path_and_query().as_ref().unwrap().as_str()) + .build(); + match uri { + Ok(uri) => { + header.uri = uri; + Ok(()) + } + Err(_) => Error::e_explain( + InvalidHTTPHeader, + format!("invalid authority from host {}", authority), + ), + } +} + +impl HttpProxy { + pub(crate) async fn proxy_1to2( + &self, + session: &mut Session, + client_session: &mut Http2Session, + peer: &HttpPeer, + ctx: &mut SV::CTX, + ) -> (bool, Option>) + // (reuse_server, error) + where + SV: ProxyHttp + Send + Sync, + SV::CTX: Send + Sync, + { + let mut req = session.req_header().clone(); + + if req.version != Version::HTTP_2 { + /* remove H1 specific headers */ + // https://github.com/hyperium/h2/blob/d3b9f1e36aadc1a7a6804e2f8e86d3fe4a244b4f/src/proto/streams/send.rs#L72 + req.remove_header(&http::header::TRANSFER_ENCODING); + req.remove_header(&http::header::CONNECTION); + req.remove_header(&http::header::UPGRADE); + req.remove_header("keep-alive"); + req.remove_header("proxy-connection"); + } + + /* turn it into h2 */ + req.set_version(Version::HTTP_2); + + if session.cache.enabled() { + if let Err(e) = pingora_cache::filters::upstream::request_filter( + &mut req, + session.cache.maybe_cache_meta(), + ) { + session.cache.disable(NoCacheReason::InternalError); + warn!("cache upstream filter error {}, disabling cache", e); + } + } + + match self + .inner + .upstream_request_filter(session, &mut req, ctx) + .await + { + Ok(_) => { /* continue */ } + Err(e) => { + return (false, Some(e)); + } + } + + // Remove H1 `Host` header, save it in order to add to :authority + // We do this because certain H2 servers expect request not to have a host header. + // The `Host` is removed after the upstream filters above for 2 reasons + // 1. there is no API to change the :authority header + // 2. the filter code needs to be aware of the host vs :authority across http versions otherwise + let host = req.remove_header(&http::header::HOST); + + session.upstream_compression.request_filter(&req); + let body_empty = session.as_mut().is_body_empty(); + + let mut req: http::request::Parts = req.into(); + + // H2 requires authority to be set, so copy that from H1 host if that is set + if let Some(host) = host { + if let Err(e) = update_h2_scheme_authority(&mut req, host.as_bytes()) { + return (false, Some(e)); + } + } + + debug!("Request to h2: {:?}", req); + + // don't send END_STREAM on HEADERS for no_header_eos + let send_header_eos = !peer.options.no_header_eos && body_empty; + + let req = Box::new(RequestHeader::from(req)); + match client_session.write_request_header(req, send_header_eos) { + Ok(v) => v, + Err(e) => { + return (false, Some(e.into_up())); + } + }; + + // send END_STREAM on empty DATA frame for no_headers_eos + if peer.options.no_header_eos && body_empty { + match client_session.write_request_body(Bytes::new(), true) { + Ok(()) => debug!("sent empty DATA frame to h2"), + Err(e) => { + return (false, Some(e.into_up())); + } + }; + } + + client_session.read_timeout = peer.options.read_timeout; + + // take the body writer out of the client for easy duplex + let mut client_body = client_session + .take_request_body_writer() + .expect("already send request header"); + + let (tx, rx) = mpsc::channel::(TASK_BUFFER_SIZE); + + session.as_mut().enable_retry_buffering(); + + /* read downstream body and upstream response at the same time */ + + let ret = tokio::try_join!( + self.bidirection_1to2(session, &mut client_body, rx, ctx), + pipe_2to1_response(client_session, tx) + ); + + match ret { + Ok((_first, _second)) => (true, None), + Err(e) => (false, Some(e)), + } + } + + pub(crate) async fn proxy_to_h2_upstream( + &self, + session: &mut Session, + client_session: &mut Http2Session, + reused: bool, + peer: &HttpPeer, + ctx: &mut SV::CTX, + ) -> (bool, Option>) + where + SV: ProxyHttp + Send + Sync, + SV::CTX: Send + Sync, + { + if let Err(e) = self + .inner + .connected_to_upstream( + session, + reused, + peer, + client_session.fd(), + client_session.digest(), + ctx, + ) + .await + { + return (false, Some(e)); + } + + let (server_session_reuse, error) = + self.proxy_1to2(session, client_session, peer, ctx).await; + + (server_session_reuse, error) + } + + async fn bidirection_1to2( + &self, + session: &mut Session, + client_body: &mut h2::SendStream, + mut rx: mpsc::Receiver, + ctx: &mut SV::CTX, + ) -> Result<()> + where + SV: ProxyHttp + Send + Sync, + SV::CTX: Send + Sync, + { + let mut downstream_state = DownstreamStateMachine::new(session.as_mut().is_body_done()); + + // retry, send buffer if it exists + if let Some(buffer) = session.as_mut().get_retry_buffer() { + send_body_to2(Ok(Some(buffer)), downstream_state.is_done(), client_body)?; + } + + let mut response_state = ResponseStateMachine::new(); + + // these two below can be wrapped into an internal ctx + // use cache when upstream revalidates (or TODO: error) + let mut serve_from_cache = ServeFromCache::new(); + let mut range_body_filter = proxy_cache::range_filter::RangeBodyFilter::new(); + + /* duplex mode + * see the Same function for h1 for more comments + */ + while !downstream_state.is_done() || !response_state.is_done() { + // Similar logic in h1 need to reserve capacity first to avoid deadlock + // But we don't need to do the same because the h2 client_body pipe is unbounded (never block) + tokio::select! { + // NOTE: cannot avoid this copy since h2 owns the buf + body = session.downstream_session.read_body_or_idle(downstream_state.is_done()), if downstream_state.can_poll() => { + debug!("downstream event"); + let body = match body { + Ok(b) => b, + Err(e) => { + if serve_from_cache.is_miss() { + // ignore downstream error so that upstream can continue write cache + downstream_state.to_errored(); + warn!( + "Downstream Error ignored during caching: {}, {}", + e, + self.inner.request_summary(session, ctx) + ); + continue; + } else { + return Err(e.into_down()); + } + } + }; + let request_done = send_body_to2(Ok(body), session.is_body_done(), client_body)?; + downstream_state.maybe_finished(request_done); + }, + + task = rx.recv(), if !response_state.upstream_done() => { + if let Some(t) = task { + debug!("upstream event: {:?}", t); + if serve_from_cache.should_discard_upstream() { + // just drain, do we need to do anything else? + continue; + } + // pull as many tasks as we can + let mut tasks = Vec::with_capacity(TASK_BUFFER_SIZE); + tasks.push(t); + while let Some(maybe_task) = rx.recv().now_or_never() { + if let Some(t) = maybe_task { + tasks.push(t); + } else { + break + } + } + + /* run filters before sending to downstream */ + let mut filtered_tasks = Vec::with_capacity(TASK_BUFFER_SIZE); + for mut t in tasks { + if self.revalidate_or_stale(session, &mut t, ctx).await { + serve_from_cache.enable(); + response_state.enable_cached_response(); + // skip downstream filtering entirely as the 304 will not be sent + break; + } + session.upstream_compression.response_filter(&mut t); + // check error and abort + // otherwise the error is surfaced via write_response_tasks() + if !serve_from_cache.should_send_to_downstream() { + if let HttpTask::Failed(e) = t { + return Err(e); + } + } + filtered_tasks.push( + self.h2_response_filter(session, t, ctx, + &mut serve_from_cache, + &mut range_body_filter, false).await?); + if serve_from_cache.is_miss_header() { + response_state.enable_cached_response(); + } + } + + if !serve_from_cache.should_send_to_downstream() { + // TODO: need to derive response_done from filtered_tasks in case downstream failed already + continue; + } + + let response_done = session.write_response_tasks(filtered_tasks).await?; + response_state.maybe_set_upstream_done(response_done); + } else { + debug!("empty upstream event"); + response_state.maybe_set_upstream_done(true); + } + } + + task = serve_from_cache.next_http_task(&mut session.cache), + if !response_state.cached_done() && !downstream_state.is_errored() && serve_from_cache.is_on() => { + let task = self.h2_response_filter(session, task?, ctx, + &mut serve_from_cache, + &mut range_body_filter, true).await?; + match session.write_response_tasks(vec![task]).await { + Ok(b) => response_state.maybe_set_cache_done(b), + Err(e) => if serve_from_cache.is_miss() { + // give up writing to downstream but wait for upstream cache write to finish + downstream_state.to_errored(); + response_state.maybe_set_cache_done(true); + warn!( + "Downstream Error ignored during caching: {}, {}", + e, + self.inner.request_summary(session, ctx) + ); + continue; + } else { + return Err(e); + } + } + if response_state.cached_done() { + if let Err(e) = session.cache.finish_hit_handler().await { + warn!("Error during finish_hit_handler: {}", e); + } + } + } + + else => { + break; + } + } + } + + match session.as_mut().finish_body().await { + Ok(_) => { + debug!("finished sending body to downstream"); + } + Err(e) => { + error!("Error finish sending body to downstream: {}", e); + // TODO: don't do downstream keepalive + } + } + Ok(()) + } + + async fn h2_response_filter( + &self, + session: &mut Session, + mut task: HttpTask, + ctx: &mut SV::CTX, + serve_from_cache: &mut ServeFromCache, + range_body_filter: &mut RangeBodyFilter, + from_cache: bool, // are the task from cache already + ) -> Result + where + SV: ProxyHttp + Send + Sync, + SV::CTX: Send + Sync, + { + if !from_cache { + self.upstream_filter(session, &mut task, ctx); + + // cache the original response before any downstream transformation + // requests that bypassed cache still need to run filters to see if the response has become cacheable + if session.cache.enabled() || session.cache.bypassing() { + if let Err(e) = self + .cache_http_task(session, &task, ctx, serve_from_cache) + .await + { + if serve_from_cache.is_miss_body() { + // if the response stream cache body during miss but write fails, it has to + // give up the entire request + return Err(e); + } else { + // otherwise, continue processing the response + warn!( + "Fail to cache response: {}, {}", + e, + self.inner.request_summary(session, ctx) + ); + } + } + } + // skip the downstream filtering if these tasks are just for cache admission + if !serve_from_cache.should_send_to_downstream() { + return Ok(task); + } + } // else: cached/local response, no need to trigger upstream filters and caching + + match task { + HttpTask::Header(mut header, eos) => { + let req = session.req_header(); + + /* Downstream revalidation, only needed when cache is on because otherwise origin + * will handle it */ + // TODO: if cache is disabled during response phase, we should still do the filter + if session.cache.enabled() { + proxy_cache::downstream_response_conditional_filter( + serve_from_cache, + req, + &mut header, + ); + if !session.ignore_downstream_range { + let range_type = + proxy_cache::range_filter::range_header_filter(req, &mut header); + range_body_filter.set(range_type); + } + } + + self.inner + .response_filter(session, &mut header, ctx) + .await?; + /* Downgrade the version so that write_response_header won't panic */ + header.set_version(Version::HTTP_11); + + // these status codes / method cannot have body, so no need to add chunked encoding + let no_body = session.req_header().method == "HEAD" + || matches!(header.status.as_u16(), 204 | 304); + + /* Add chunked header to tell downstream to use chunked encoding + * during the absent of content-length in h2 */ + if !no_body + && !header.status.is_informational() + && header.headers.get(http::header::CONTENT_LENGTH).is_none() + { + header.insert_header(http::header::TRANSFER_ENCODING, "chunked")?; + } + Ok(HttpTask::Header(header, eos)) + } + HttpTask::Body(data, eos) => { + let data = range_body_filter.filter_body(data); + if let Some(duration) = self.inner.response_body_filter(session, &data, ctx)? { + trace!("delaying response for {:?}", duration); + time::sleep(duration).await; + } + Ok(HttpTask::Body(data, eos)) + } + HttpTask::Trailer(header_map) => { + let trailer_buffer = match header_map { + Some(mut trailer_map) => { + debug!("Parsing response trailers.."); + match self + .inner + .response_trailer_filter(session, &mut trailer_map, ctx) + .await + { + Ok(buf) => buf, + Err(e) => { + error!( + "Encountered error while filtering upstream trailers {:?}", + e + ); + None + } + } + } + _ => None, + }; + // if we have a trailer buffer write it to the downstream response body + if let Some(buffer) = trailer_buffer { + // write_body will not write additional bytes after reaching the content-length + // for gRPC H2 -> H1 this is not a problem but may be a problem for non gRPC code + // https://http2.github.io/http2-spec/#malformed + Ok(HttpTask::Body(Some(buffer), true)) + } else { + Ok(HttpTask::Done) + } + } + HttpTask::Done => Ok(task), + HttpTask::Failed(_) => Ok(task), // Do nothing just pass the error down + } + } +} + +pub(crate) fn send_body_to2( + data: Result>, + end_of_body: bool, + client_body: &mut h2::SendStream, +) -> Result { + match data { + Ok(res) => match res { + Some(data) => { + let data_len = data.len(); + debug!( + "Read {} bytes body from downstream, body end: {}", + data_len, end_of_body + ); + if data_len == 0 && !end_of_body { + /* it is normal to get 0 bytes because of multi-chunk parsing */ + return Ok(false); + } + write_body(client_body, data, end_of_body).map_err(|e| e.into_up())?; + debug!("Write {} bytes body to h2 upstream", data_len); + Ok(end_of_body) + } + None => { + debug!("Read downstream body done"); + /* send a standalone END_STREAM flag */ + write_body(client_body, Bytes::new(), true).map_err(|e| e.into_up())?; + debug!("Write END_STREAM to h2 upstream"); + Ok(true) + } + }, + Err(e) => e.into_down().into_err(), + } +} + +/* Read response header, body and trailer from h2 upstream and send them to tx */ +pub(crate) async fn pipe_2to1_response( + client: &mut Http2Session, + tx: mpsc::Sender, +) -> Result<()> { + client + .read_response_header() + .await + .map_err(|e| e.into_up())?; // should we send the error as an HttpTask? + + let resp_header = Box::new(client.response_header().expect("just read").clone()); + + tx.send(HttpTask::Header(resp_header, client.response_finished())) + .await + .or_err(InternalError, "sending h2 headers to pipe")?; + + while let Some(chunk) = client + .read_response_body() + .await + .map_err(|e| e.into_up()) + .transpose() + { + let data = match chunk { + Ok(d) => d, + Err(e) => { + // Push the error to downstream and then quit + // Don't care if send fails: downstream already gone + let _ = tx.send(HttpTask::Failed(e.into_up())).await; + // Downstream should consume all remaining data and handle the error + return Ok(()); + } + }; + if data.is_empty() && !client.response_finished() { + /* it is normal to get 0 bytes because of multi-chunk + * don't write 0 bytes to downstream since it will be + * misread as the terminating chunk */ + continue; + } + tx.send(HttpTask::Body(Some(data), client.response_finished())) + .await + .or_err(InternalError, "sending h2 body to pipe")?; + } + + // attempt to get trailers + let trailers = match client.read_trailers().await { + Ok(t) => t, + Err(e) => { + // Similar to above, push the error to downstream and then quit + let _ = tx.send(HttpTask::Failed(e.into_up())).await; + return Ok(()); + } + }; + + let trailers = trailers.map(Box::new); + + if trailers.is_some() { + tx.send(HttpTask::Trailer(trailers)) + .await + .or_err(InternalError, "sending h2 trailer to pipe")?; + } + + tx.send(HttpTask::Done) + .await + .unwrap_or_else(|_| debug!("h2 to h1 channel closed!")); + + Ok(()) +} + +#[test] +fn test_update_authority() { + let mut parts = http::request::Builder::new() + .body(()) + .unwrap() + .into_parts() + .0; + update_h2_scheme_authority(&mut parts, b"example.com").unwrap(); + assert_eq!("example.com", parts.uri.authority().unwrap()); + update_h2_scheme_authority(&mut parts, b"example.com:456").unwrap(); + assert_eq!("example.com:456", parts.uri.authority().unwrap()); + update_h2_scheme_authority(&mut parts, b"example.com:").unwrap(); + assert_eq!("example.com:", parts.uri.authority().unwrap()); + update_h2_scheme_authority(&mut parts, b"example.com:123:345").unwrap(); + assert_eq!("example.com:123", parts.uri.authority().unwrap()); + update_h2_scheme_authority(&mut parts, b"[::1]").unwrap(); + assert_eq!("[::1]", parts.uri.authority().unwrap()); +} diff --git a/pingora-proxy/src/proxy_purge.rs b/pingora-proxy/src/proxy_purge.rs new file mode 100644 index 0000000..16796ba --- /dev/null +++ b/pingora-proxy/src/proxy_purge.rs @@ -0,0 +1,90 @@ +// 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 super::*; + +use once_cell::sync::Lazy; +use pingora_core::protocols::http::SERVER_NAME; + +fn gen_purge_response(code: u16) -> ResponseHeader { + let mut resp = ResponseHeader::build(code, Some(3)).unwrap(); + resp.insert_header(header::SERVER, &SERVER_NAME[..]) + .unwrap(); + resp.insert_header(header::CONTENT_LENGTH, 0).unwrap(); + resp.insert_header(header::CACHE_CONTROL, "private, no-store") + .unwrap(); + // TODO more headers? + resp +} + +async fn write_purge_response( + session: &mut Session, + resp: &ResponseHeader, +) -> (bool, Option>) { + match session.as_mut().write_response_header_ref(resp).await { + Ok(_) => (true, None), + // dirty, not reusable + Err(e) => (false, Some(e.into_down())), + } +} + +/// Write a response for a rejected cache purge requests +pub async fn write_no_purge_response(session: &mut Session) -> (bool, Option>) { + // TODO: log send error + write_purge_response(session, &NOT_PURGEABLE).await +} + +static OK: Lazy = Lazy::new(|| gen_purge_response(200)); +static NOT_FOUND: Lazy = Lazy::new(|| gen_purge_response(404)); +// for when purge is sent to uncacheable assets +static NOT_PURGEABLE: Lazy = Lazy::new(|| gen_purge_response(405)); + +impl HttpProxy { + pub(crate) async fn proxy_purge( + &self, + session: &mut Session, + ctx: &mut SV::CTX, + ) -> Option<(bool, Option>)> + where + SV: ProxyHttp + Send + Sync, + SV::CTX: Send + Sync, + { + match session.cache.purge().await { + Ok(found) => { + // canned PURGE response based on whether we found the asset or not + let resp = if found { &*OK } else { &*NOT_FOUND }; + let (reuse, err) = write_purge_response(session, resp).await; + if let Some(e) = err.as_ref() { + error!( + "Failed to send purge response: {}, {}", + e, + self.inner.request_summary(session, ctx) + ) + } + Some((reuse, err)) + } + Err(e) => { + session.cache.disable(NoCacheReason::StorageError); + warn!( + "Fail to purge cache: {}, {}", + e, + self.inner.request_summary(session, ctx) + ); + session.downstream_session.respond_error(500).await; + // still reusable + Some((true, Some(e))) + } + } + } +} diff --git a/pingora-proxy/src/proxy_trait.rs b/pingora-proxy/src/proxy_trait.rs new file mode 100644 index 0000000..c4fa2ef --- /dev/null +++ b/pingora-proxy/src/proxy_trait.rs @@ -0,0 +1,365 @@ +// 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 super::*; +use pingora_cache::{ + key::HashBinary, CacheKey, CacheMeta, NoCacheReason, RespCacheable, RespCacheable::*, +}; + +/// The interface to control the HTTP proxy +/// +/// The methods in [ProxyHttp] are filters/callbacks which will be performed on all requests at their +/// paticular stage (if applicable). +/// +/// If any of the filters returns [Result::Err], the request will fail and the error will be logged. +#[cfg_attr(not(doc_async_trait), async_trait)] +pub trait ProxyHttp { + /// The per request object to share state across the different filters + type CTX; + + /// Define how the `ctx` should be created. + fn new_ctx(&self) -> Self::CTX; + + /// Define where the proxy should sent the request to. + /// + /// The returned [HttpPeer] contains the information regarding where and how this request should + /// be forwarded to. + async fn upstream_peer( + &self, + session: &mut Session, + ctx: &mut Self::CTX, + ) -> Result>; + + /// Handle the incoming request. + /// + /// In this phase, users can parse, validate, rate limit, perform access control and/or + /// return a response for this request. + /// + /// If the user already sent a response to this request, a `Ok(true)` should be returned so that + /// the proxy would exit. The proxy continues to the next phases when `Ok(false)` is returned. + /// + /// By default this filter does nothing and returns `Ok(false)`. + async fn request_filter(&self, _session: &mut Session, _ctx: &mut Self::CTX) -> Result + where + Self::CTX: Send + Sync, + { + Ok(false) + } + + /// This filter decides if the request is cacheable and what cache backend to use + /// + /// The caller can interact with `Session.cache` to enabled caching. + /// + /// By default this filter does nothing which effectively disables caching. + // Ideally only session.cache should be modified, TODO: reflect that in this interface + fn request_cache_filter(&self, _session: &mut Session, _ctx: &mut Self::CTX) -> Result<()> { + Ok(()) + } + + /// This callback generates the cache key + /// + /// This callback is called only when cache is enabled for this request + /// + /// By default this callback returns a default cache key generated from the request. + fn cache_key_callback(&self, session: &Session, _ctx: &mut Self::CTX) -> Result { + let req_header = session.req_header(); + Ok(CacheKey::default(req_header)) + } + + /// This callback is invoked when a cacheable response is ready to be admitted to cache + fn cache_miss(&self, session: &mut Session, _ctx: &mut Self::CTX) { + session.cache.cache_miss(); + } + + /// This filter is called after a successful cache lookup and before the cache asset is ready to + /// be used. + /// + /// This filter allow the user to log or force expire the asset. + // flex purge, other filtering, returns whether asset is should be force expired or not + async fn cache_hit_filter( + &self, + _meta: &CacheMeta, + _ctx: &mut Self::CTX, + _req: &RequestHeader, + ) -> Result + where + Self::CTX: Send + Sync, + { + Ok(false) + } + + /// Decide if a request should continue to upstream after not being served from cache. + /// + /// returns: Ok(true) if the request should continue, Ok(false) if a response was written by the + /// callback and the session should be finished, or an error + /// + /// This filter can be used for deferring checks like rate limiting or access control to when they + /// actually needed after cache miss. + async fn proxy_upstream_filter( + &self, + _session: &mut Session, + _ctx: &mut Self::CTX, + ) -> Result + where + Self::CTX: Send + Sync, + { + Ok(true) + } + + /// Decide if the response is cacheable + fn response_cache_filter( + &self, + _session: &Session, + _resp: &ResponseHeader, + _ctx: &mut Self::CTX, + ) -> Result { + Ok(Uncacheable(NoCacheReason::Custom("default"))) + } + + /// Decide how to generate cache vary key from both request and response + /// + /// None means no variance is need. + fn cache_vary_filter( + &self, + _meta: &CacheMeta, + _ctx: &mut Self::CTX, + _req: &RequestHeader, + ) -> Option { + // default to None for now to disable vary feature + None + } + + /// Modify the request before it is sent to the upstream + /// + /// Unlike [Self::request_filter()], this filter allows to change the request headers to send + /// to the upstream. + async fn upstream_request_filter( + &self, + _session: &mut Session, + _upstream_request: &mut RequestHeader, + _ctx: &mut Self::CTX, + ) -> Result<()> + where + Self::CTX: Send + Sync, + { + Ok(()) + } + + /// Modify the response header from the upstream + /// + /// The modification is before caching so any change here will be stored in cache if enabled. + /// + /// Responses served from cache won't trigger this filter. + fn upstream_response_filter( + &self, + _session: &mut Session, + _upstream_response: &mut ResponseHeader, + _ctx: &mut Self::CTX, + ) { + } + + /// Modify the response header before it is send to the downstream + /// + /// The modification is after caching. This filter is called for all responses including + /// responses served from cache.. + async fn response_filter( + &self, + _session: &mut Session, + _upstream_response: &mut ResponseHeader, + _ctx: &mut Self::CTX, + ) -> Result<()> + where + Self::CTX: Send + Sync, + { + Ok(()) + } + + /// Similar to [Self::upstream_response_filter()] but for response body + /// + /// This function will be called every time a piece of response body is received. The `body` is + /// **not the entire response body**. + fn upstream_response_body_filter( + &self, + _session: &mut Session, + _body: &Option, + _end_of_stream: bool, + _ctx: &mut Self::CTX, + ) { + } + + /// Similar to [Self::response_filter()] but for response body chunks + fn response_body_filter( + &self, + _session: &mut Session, + _body: &Option, + _ctx: &mut Self::CTX, + ) -> Result> + where + Self::CTX: Send + Sync, + { + Ok(None) + } + + /// When a trailer is received. + async fn response_trailer_filter( + &self, + _session: &mut Session, + _upstream_trailers: &mut header::HeaderMap, + _ctx: &mut Self::CTX, + ) -> Result> + where + Self::CTX: Send + Sync, + { + Ok(None) + } + + /// This filter is called when the entire response is sent to the downstream successfully or + /// there is a fatal error that terminate the request. + /// + /// An error log is already emitted if there is any error. This phase is used for collecting + /// metrics and sending access logs. + async fn logging(&self, _session: &mut Session, _e: Option<&Error>, _ctx: &mut Self::CTX) + where + Self::CTX: Send + Sync, + { + } + + /// A value of true means that the log message will be suppressed. The default value is false. + fn suppress_error_log(&self, _session: &Session, _ctx: &Self::CTX, _error: &Error) -> bool { + false + } + + /// This filter is called when there is an error **after** a connection is established (or reused) + /// to the upstream. + fn error_while_proxy( + &self, + peer: &HttpPeer, + session: &mut Session, + e: Box, + _ctx: &mut Self::CTX, + client_reused: bool, + ) -> Box { + let mut e = e.more_context(format!("Peer: {}", peer)); + // only reused client connections where retry buffer is not truncated + e.retry + .decide_reuse(client_reused && !session.as_ref().retry_buffer_truncated()); + e + } + + /// This filter is called when there is an error in the process of establishing a connection + /// to the upstream. + /// + /// In this filter the user can decide whether the error is retry-able by marking the error `e`. + /// + /// If the error can be retried, [Self::upstream_peer()] will be called again so that the user + /// can decide whether to send the request to the same upstream or another upstream that is possibly + /// avaliable. + fn fail_to_connect( + &self, + _session: &mut Session, + _peer: &HttpPeer, + _ctx: &mut Self::CTX, + e: Box, + ) -> Box { + e + } + + /// This filter is called when the request encounters a fatal error. + /// + /// Users may write an error response to the downstream if the downstream is still writable. + /// + /// The response status code of the error response maybe returned for logging purpose. + async fn fail_to_proxy(&self, session: &mut Session, e: &Error, _ctx: &mut Self::CTX) -> u16 + where + Self::CTX: Send + Sync, + { + let server_session = session.as_mut(); + let code = match e.etype() { + HTTPStatus(code) => *code, + _ => { + match e.esource() { + ErrorSource::Upstream => 502, + ErrorSource::Downstream => { + match e.etype() { + WriteError | ReadError | ConnectionClosed => { + /* conn already dead */ + 0 + } + _ => 400, + } + } + ErrorSource::Internal | ErrorSource::Unset => 500, + } + } + }; + if code > 0 { + server_session.respond_error(code).await + } + code + } + + /// Decide whether should serve stale when encountering an error or during revalidation + /// + /// An implementation should follow + /// + /// + /// + /// This filter is only called if cache is enabled. + // 5xx HTTP status will be encoded as ErrorType::HTTPStatus(code) + fn should_serve_stale( + &self, + _session: &mut Session, + _ctx: &mut Self::CTX, + error: Option<&Error>, // None when it is called during stale while revalidate + ) -> bool { + // A cache MUST NOT generate a stale response unless + // it is disconnected + // or doing so is explicitly permitted by the client or origin server + // (e.g. headers or an out-of-band contract) + error.map_or(false, |e| e.esource() == &ErrorSource::Upstream) + } + + /// This filter is called when the request just established or reused a connection to the upstream + /// + /// This filter allows user to log timing and connection related info. + async fn connected_to_upstream( + &self, + _session: &mut Session, + _reused: bool, + _peer: &HttpPeer, + _fd: std::os::unix::io::RawFd, + _digest: Option<&Digest>, + _ctx: &mut Self::CTX, + ) -> Result<()> + where + Self::CTX: Send + Sync, + { + Ok(()) + } + + /// This callback is invoked every time request related error log needs to be generated + /// + /// Users can define what is the important to be written about this request via the returned string. + fn request_summary(&self, session: &Session, _ctx: &Self::CTX) -> String { + session.as_ref().request_summary() + } + + /// Whether the request should be used to invalidate(delete) the HTTP cache + /// + /// - `true`: this request will be used to invalidate the cache. + /// - `false`: this request is a treated as an normal request + fn is_purge(&self, _session: &Session, _ctx: &Self::CTX) -> bool { + false + } +} diff --git a/pingora-proxy/src/subrequest.rs b/pingora-proxy/src/subrequest.rs new file mode 100644 index 0000000..9490a40 --- /dev/null +++ b/pingora-proxy/src/subrequest.rs @@ -0,0 +1,134 @@ +// 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 async_trait::async_trait; +use core::pin::Pin; +use core::task::{Context, Poll}; +use pingora_cache::lock::WritePermit; +use pingora_core::protocols::raw_connect::ProxyDigest; +use pingora_core::protocols::{GetProxyDigest, GetTimingDigest, Ssl, TimingDigest, UniqueID}; +use std::io::Cursor; +use std::sync::Arc; +use tokio::io::{AsyncRead, AsyncWrite, Error, ReadBuf}; + +// An async IO stream that returns the request when being read from and dumps the data to the void +// when being write to +#[derive(Debug)] +pub(crate) struct DummyIO(Cursor>); + +impl DummyIO { + pub fn new(read_bytes: &[u8]) -> Self { + DummyIO(Cursor::new(Vec::from(read_bytes))) + } +} + +impl AsyncRead for DummyIO { + fn poll_read( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut ReadBuf<'_>, + ) -> Poll> { + if self.0.position() < self.0.get_ref().len() as u64 { + Pin::new(&mut self.0).poll_read(cx, buf) + } else { + // all data is read, pending forever otherwise the stream is considered closed + Poll::Pending + } + } +} + +impl AsyncWrite for DummyIO { + fn poll_write( + self: Pin<&mut Self>, + _cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + Poll::Ready(Ok(buf.len())) + } + + fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + fn poll_shutdown(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } +} + +impl UniqueID for DummyIO { + fn id(&self) -> i32 { + 0 // placeholder + } +} + +impl Ssl for DummyIO {} + +impl GetTimingDigest for DummyIO { + fn get_timing_digest(&self) -> Vec> { + vec![] + } +} + +impl GetProxyDigest for DummyIO { + fn get_proxy_digest(&self) -> Option> { + None + } +} + +#[async_trait] +impl pingora_core::protocols::Shutdown for DummyIO { + async fn shutdown(&mut self) -> () {} +} + +#[tokio::test] +async fn test_dummy_io() { + use futures::FutureExt; + use tokio::io::{AsyncReadExt, AsyncWriteExt}; + + let mut dummy = DummyIO::new(&[1, 2]); + let res = dummy.read_u8().await; + assert_eq!(res.unwrap(), 1); + let res = dummy.read_u8().await; + assert_eq!(res.unwrap(), 2); + let res = dummy.read_u8().now_or_never(); + assert!(res.is_none()); // pending forever + let res = dummy.write_u8(0).await; + assert!(res.is_ok()); +} + +// To share state across the parent req and the sub req +pub(crate) struct Ctx { + pub(crate) write_lock: Option, +} + +use crate::HttpSession; + +pub(crate) fn create_dummy_session(parsed_session: &HttpSession) -> HttpSession { + // TODO: check if there is req body, we don't capture the body for now + HttpSession::new_http1(Box::new(DummyIO::new(&parsed_session.to_h1_raw()))) +} + +#[tokio::test] +async fn test_dummy_request() { + use tokio_test::io::Builder; + + let input = b"GET / HTTP/1.1\r\n\r\n"; + let mock_io = Builder::new().read(&input[..]).build(); + let mut req = HttpSession::new_http1(Box::new(mock_io)); + req.read_request().await.unwrap(); + assert_eq!(input.as_slice(), req.to_h1_raw()); + + let mut dummy_req = create_dummy_session(&req); + dummy_req.read_request().await.unwrap(); + assert_eq!(input.as_slice(), req.to_h1_raw()); +} diff --git a/pingora-proxy/tests/headers.dict b/pingora-proxy/tests/headers.dict new file mode 100644 index 0000000000000000000000000000000000000000..a88fa0379b4bdffd2a0e67c955c7ed1d4ff88c40 GIT binary patch literal 6202645 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�@_fex8=B%4 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

qFpOuV`bsk(8GHbr6WKh`){@?#0 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
  • `8_>29$;QtI#HxXXfI}5CzML^nZGThT= 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

    @$z*Z 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 M36Tq{{0t#@DBzF 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 z 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

    u{bFRg`e?>`o!=Nv!kcR`f5oB0u+?@5=7q?4 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 z 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

    Q8`60FTU8FUY^4}&~eM4)h4_0(#VT-{e* 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%0A<~Y{~#@-xJ4tk48y7Zdq7u9*a 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 z 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 z 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%0Du1SzH4q?$U3#G2C7tYt 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

    D{JI%q;O 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

    okY|A>R>Ui@dfUqSEcA7=pJtOMaUEz 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

    1rN8iiASY{Z055Ct+v!RmCx+W>%vtqNXq%?IF zZIx5Gkqx&jyPZv{!)$J|O|{&GmTp&!r?*vk--z_vPfr!y3YNhYn5KFUL9g;OvAaSo9fH%QsNPLJJH zB8Js886BV|eq7UWIgi#I|EZm?zGvK_k5-((Tv%GtPtaV@4B(3isc1RK8i$HmE2@(({&wzFerE~$G-#G0aovzEY_}(93|A9?Wk3h)zKn$Bes4t>g zX{9L=Ndo0n5bQnNHK;h-nOzX zAOgQ*xqRO5W>NF>n4&W&7aLFd!c!aR!LS{C>O{u-SEsm>)?>LPjTUvSs!g?`o7txF z?qIPVwBxrRr41fNKkSHjW?KYQcx)78MJPm=;w{C~aczAgWE#il3clo3DaF9eze=me zx(pyF6;c4p!AC*yl~5ArVOJB@_jFGOJEjA%r}rsVwG;rIMCBBau~im{kE#*S@eXN*{6p-v%Sm%JjY`YzOZmn`-uN#Gm?eB`NfX{(X&d|PyQRDDZLN@b>q#a zbvG-;g0reKbT(m^A-*?@rtQO}uazu)Y(*we;AF-+RidoYAayPZ~R0! zBN&~#6p?s3nzA)~G#HE}P=uF1I%O75w~xD-&w}hsd{YK4JOSMY_ALq$J`U+b;!pnm;MOlp49PU0di(cML_|g#O*+PKl1CU^DvbXS z6EbFvn!+TCE<(3GtiWKBLjn$pi1V9$f@fAgjBlapAl63hLlVok-%Kc~g3tV^s)A~I zZpKb8@}=Hbm>r5{4EyCk_bt^A*R${W?Y?RZdv?bdlxDAyy*(F@FlCOghWmg2_iEai zQ{~bk62!rNcETy?v<`zG?l_Vl{ntB6KHKT1&RSL1oqWP}`^{#5QQmHw`qs>4;~I^n zp!jC86+11xEnmCK5h&>CM2AP#eljlm;N&%AiQboTGgTQyOQC`FE-%JXljN1RR=K(G z24;2CelzgV1;KH4Z=2H?|u7Su|O`mA~;gxmocLz(1_yB zQQto<_n49x0Q`#uNKD6}BFiE-{W4I67KltZglBYFRI^A7S^nsSPzMn~8WOY2!?;bm z9k)?6Nl1I}bV1oc5}geUKx&*zX7h-UwG%Vv+r%2W9O?NAyz^dC>*2d+$P;^H?LxE0 zygNrES6+5 zY@KT+3ojxA^PINH79-oNIe2R;)ZTm({5k!3@m+{agfE+z&;}2V*Wa%kE zWGTS_gcQ;sFy#q^42oaeT^zjTC0a)o7?|FVZ-qXcJ81m8@gKf>dWGRe5OG&f_z|Ui z(N8%US#*}^kXLo|NS}tKqi+{a`Pt4=v*WrnuI9IPE;n6o>fqpyF%{46LK}Q_C%S*V zgbAU$y^RcdokAhkD75OX^4_1>`|yhkXPj?-Br&hH@5^~cs-?WxdTcn^X&n`PsF%vM zx{_TOXF}29QhwEw`QGg1)@oivi7RO4u=hoZs<>@LDWr&^lQBH%p5U*Oc21~PDCivP zp{XE4V}aUJEK{yOhT$9!F+*TDerbBzP40IP(3vTYR7Rm#T^NCz=ZgR<)+_O^Bo>MI zCz$18y+qWCjf~%sKcZ%$=OXdpMQ}Yp057q&f0|>!(SjYuebdeKk|Th9o!wKz?-AQeLVG0rvXh-*T5Hgzs7E@VoTFFY==l~!r`Ss6yja5JmU>fMM3|DwZ2VdGS3 zwA-rXnmp)mU`@oXA+L>{nCOsb&je~k_vy=#-eSLha%F}8xj~#nYSRzBkfewZ?ncjl53MwS|(3CljNhy4&_k>9IG-Poh-6>W2Y4 zus>$B_YK(5Yl*IZd_WSf$ohgUh)x`jpxd*BHX`^eTu`7ZBbmk5N0hd=lfNS`@bEi` zYM%WQc2`k+WT3LAsG@@-9g8kb6hbZr3yfMxa^>+>#T}tCr3KR$TDFf2d6^7(%3k&# z?6OQUVH}i6`ZLNYIBtMlhi7%U;)tX#&G@Ze8zXAC0@}LA&WLvzZ7fwDIb}fb2sJ+14PFVF zKD^scr}!w~6z(7V+i^n6`u8sdCu{2A<@m;ac`FcAW{I)Bsc`N(>URi`y!rX=G%pQ;Xq zfz?i{cviBWi6t-)jXI4|#i%-x+EP=amYRHxFQf`)8gAhGJC*8Vk78po6E_vH4~tG*W8Tx&Y5 z<|;k+tuT5b7gm_4s6G>wTaR<+-;_Q90ZuME;p*~9WCkR*>C@JBxj(|4g{BSHMlvtA zgj#A7j?a^J*BYg)s#`0hf`#QG5sbGhA-kj&{qnaUU@5#&MF!fD_V-Z>fv!75n*$L9 z+k$J?hAC`Ysm|r+x?!kXaT$D&l(p|s8ihetA^{Q<^y2j2Qws|eixuyA_cm3xoxVAr zSCdL~9CKRrq%rKjr!?;=F_ohG*J$FYGSdpXWIZg|@T~u^LJ4Kaot2ayU2($L=uO(9 zpPZMEm{UO-{vEu_nebm(T(8GALlTe3C!t4YGkk zt#+ovQeTT0;iol$AsuP(HW*5y#4hNh>Ih|P^=xKE`*?poA><$A&fv6u@{<>-CA8*e z5bA#00GthN98V_HBDNC%&K4bv!d2aVlvh92H0ZOLB5j+l) zt7`<9i$GjlP5=?$um>(H`>~kFMxhuU3POCog>@d)<5z0|HIQHbocF_jJcUdnk1r?q zs}$S}m`G^`HDj`jjd+M?W$f;~Kt;@)3ju{n5wr#`WM7+jQ7JN@!p=*@s8UplKZMGW zVZ$LM_55&Ry@5s?jz1WXY>`L{f8Fz3M~pK*mOF)PCFWc>?|$(WecJWO)_^tWU%Tk( z#l$&TJ#^=uj?e_Y^58a#Iham9Ahx^zedr!J{k}>2KY47*cszt6h%4nTYe^~CStr6t zDVr;%`_Li_3Q9S%j#37&URdVVK{w*P?h6 zqWJMcryux02)Y3OIsIxJ7oWU0dGZR8e9CruUfc=+WjAZ1$sf@u2pXcS04`sHa};Jc zA44}afckX8f^3qoE$o1G>lO&XokL=pP79088veL&hHw+cOGx;P0OS!|`Tky%%7wBj zH+XnIw=uDGw~>`sUbZ>Q#w%TEH(PFN^;B#-u!>KExw6 zI|;uUd9|3`n-1T^UyI1QReWRWuht@nsgy;~>hNZMw4py86MSq)gHwrk51%yOrO-c% z2o5xREW_{8?1iX^dwKk@z~J~k!YM173oh5K<)|OoF2?WmkTlCj2If2U+00n2<&i5D zU%T2c+T0Cym2{_d)4m)_Ac{FL8+oWEWw{Xr6;_)p3J-e$Ve%!QeEnX6DRghiBO`>l z1h*sXI}a$B$TJ9Nh@7M^O55|YOG`>^#wJNb)WoORJ#=^X=~MLA-^wjO__28dg2{m5@g+ z)F$Xq^kDlC!S(%wh!qAyG2smMSQZN0j?)3{A*bs@-T7tZ%u01UMt^3E_iwaRhn$ZB zR5C&>|b);-Q4*Yy}hCR03)&jOM^j@g))YM|B za(jyb0LCw3v}h_Qw;y6AqH7o6l33=WO>edJD$`Pah+0@`MC;S79A0SoRs6lSmfD+5 zJ{-x`H)G989M=6yh$uEqhu?;8GdaKNw%*4LyJ*8%GHRn)#m;K`<7+>-UXuL){|_>c z@t_X=d;pq(+_)2-Y*&?0<$ave(i^?hO6P{AIoJ+#sTtLY_~ zXO|4GUqoUUWL~4Gkb$pdwl3!WpcLRfA%*|^`mugu@>^G|#-bE|3OCKCu)h)BS~a9A ziFDYgh15#pR64>_f)-0s>Q|*BW9b9bf4&XBDXz}17{Pt$GI#N+BEjGg~MNd#i$qN5E4p?IizJ0BphsKb5rE&1Vi43PXY41LD%YirnZ zDZJSG4+>1mVRABE3(3E&S*8xvlt4o?=8O!#f6l>gA*!^4xQh{y7J=w@%R`k_+_hm} z*_U5kInd7(Q}2gWwr3>Zf z+8yk+V=KEcXHKLLEe57WZ@&4%(?;KR2`VbsS=u@fqJ^4?VFamCVEU}93JNyn`7d;& z@qKL4h=$)PA#?x(Z(E72jaqH51vjmIv}LZsvv@?^w!?$iKGd_lr|3$E&9S;XBoPn* zgVIJg5c?8CP6`+51A1XxqsX`poxkkAT0WI7g)WVv{2@`4Xc3v^u$>E0ls^yE?N%e1 zo~1f73;~qaSRs}irOJz}I&EyUZm6lYVztTp>wd7^{Cf5TLU|iJVmpJsbSc6=m+x}e zgpcyBk&O_K=i>KIYfblMVHY5Z?$IJ(4<~j&9QFHWWH@mK{9$u35`n@QUlvzJAki3R z{r)-cwX$!TD@{_p*U%*9Sc5^V=^GzqEO|c)HuAk?KM(WK-J3xVy2qrSsxGsy@6DXt z+mArEB+#6aQ}&4+Wsg)qzYO^ z%HbU+Tj&?Um;edN=XLZm4F!h-+J7zx<&sYmc$BN{9|%>?n+yK&73{AFQor=;(w7Hl zm=ZwvPJhvc>l%XzF5g3U-TBoNpq;ZL49R+E$l9O`DDO}R0?*4@+p*#Ege1yoPGgO% z27hvNmAcg-IWC5cR_P)Cv3}~n!IvDqvu$+&^S`fi84!Yl1 zA85*V0ah`kIJ}|$QB?k0WOzEnlrK)WQYKwMjp=jsX_D_-v6>f*Z>l5ZsbPdBMGQ~s zUB{907hCPW5_7l^SO>h|De(OHR=QKU^{zgL`M zJe|zn#?c9SxgkUbtimNJm@2XpLG#v!Pny*8+SknoU`ophfxh z{1I$!FuX<-h=Fv6MKZFt82Pgj%ed)6XgmD7Tw#uCPu-Y_Vv#IuQI2tbov2Jx( zkYHJ+Hg8#P%D`nmP$$;bTeM2A8Q}th3D>1u(f4_~x7r60Mur~jE&vlW1bR%Cxn}=v z^$4&dzYYzGs@sz8Biy&_Gq`HFWP|c5)GAoCka>nfEi^Rf6C}fcb)DDpn^yPUqp8uh z%c{TM9zchG1?xkid1`OPS)nh#s@sM+ zjh0^BuobFgDG)yHS4P^n6GNN$;&#RT)qJpBzj&z!$x5dqRM=s9BI%S%Tc?_DZJ(<1 z^iC-@)kdpP-`8SMtSU=-N*SxAN^LOTW+&nNFmpb;|EkX*v@*|oF@2UzXtf`&%GtQ2 zt(Qi7!FclsKptPg_hXTXPieLqQ6*OpF`Ktm3YOf4!cM)<(?D};Yc_@@qDrOT5DUp; zoiU_CP4GbI*dIa?Prolxq`H%A3+hR^?5yolGhf}hUErLQ{4}@1UOn}+o~@J`du*AH+Y>M=Z>vl>$Oid|6HnB0A&C{mvv8>^#t)fr4NV1EAf7?t95gh2u9 z1swPg$ZXKmja_Swo6J?snQtwkiK;$*>J498Y>Sb~&!Y(M*t8<*iLk_LYMi{+Fx>xy zu0>-i7dU7{qHxS%LLMhQ$N*Tbji7k+sd7ujf!Ep-L=I&i60^&%`#l-qcrvt$y!(@pPfetTpy4^2l#O5kp2{#IHwf;AiaT=y< z_iKE{^6SUWbo!xCGlHSb|6bZe!yW`KHbTCiG^cm+cWN!W zzKJyN#ZN!1Ee-&rCoH*;1QE*$BZYgOKs^{IOk6OxqGSJMO$ik}s(qo-aJ`@%^N|nr zXh%WTew1W$Jce8CS#^)yG68+zi zuS)UWHdsxqRB2k$YWi}vYAth(>^P||mTE(a6lQ)Y&M3)GoV`A0=%{(B$n2EC>)~LL z07u%PiXzUk=!487{y`}YwVYF;`AN9q#=gWqaG8)pzO@^6#)46FX#8IXp{^aHv z#fk_#y_n&ku_IF6YJEw*jw=}b+>wYYM4>_RR8-$0!W4-(#{TB-1$cNAOrb6 z@aN1ZjF05d!8Yxo+lm+<@DK$R7`p+3qbr-{>eftH{b}jSrr8}Xx>}~NdtQ2@=`a>a zxX!c^$+*2%P|e9r%#wz+RMu-1<7$4~QV{nv^HwPXd|a&x=CjG&q6LK@905%L-eE96 zLIfoW1)dJ`nf9N88}#H)-d)IsyBwjzV?f67#dvtn5gy+T4UWfz$UPTGgxC>8QFVGe zNX!k|AzU;CE7f$+Re6|_;|suDLH$70C=jn}?he-VBCc75<*lAr-V_lUwLLY~!Rb`^ zbh#`x9(aV?#$O4kvShHK2{Rc?81dbN`0A)XfGyxRYqo{s0lo)*U>LPJVPYfNNhIEX zQJF}8*Ze^tqx@Zdnn{QqvyCMx6I=Msw5A3=ik72eax5kk+*yyT=-@Cs+n56w6{yx(dfRMM%!uW9Gt;gO)#1DLKAqJItz=~z2`zV#guR_q@~O>S2}L^n`7|k%<3{QoT4CV4h^1T)-SI2 z@|zj0qC_j*j8JdM=h0aFA>=HPoSPuRZ=Pl-&>P-{49JYC;k{y?ni9E@6 zLygz=q&v#yhP&6vaxr|WZ2$}VV>4VgLxZkT>{s%$aYb7AY)EP{KdTKc6fHg}hklI_ zJq|-oPNS?=LTE>QN2_>SUIcL`hCw6rlqQS>3*MjbjlzaEM9Av&yTKqZI<$U#yI6H; z{f_SpFSsM>CE$JW&f7p|GU)_xWaMYZG>V;7%f!Qf{$yKuuhE()>2P$F8HD%4Sg9V% zDDjOn9(M=T_@KC)HZ*mv<@Hvj--oHIS4yJdwwFlI?N}N_^~_Wud~jy+krL&rGU!K8$eDM3fS0hAwXwZ5@h3O1iqU% zBfh2jklP#pOF<^A`Ng=sr)1UkbYZ&H=1<-iULQgVHlGkuEr?%_QLJ&!qOb~*>}!w# zEA(D!M9q|plsTP6n$1$a(J95JxrO!=*{sKQ_I+qCVs2ikL~4E25iD^w&Jz)J8}P>K z$u4kuGy`I_>JjuID*xXFl%S4i_u_Vzs+aEW@S+mU*S>Cu>Y_{9~$V>37I0| z6?*#PjpOkcki95E#ah2I-?g(_A!|v$wx!l!HnnVTKkim~R&gG$7n+T*n|ZTzT_$hn>gQ;V%F0qeE#h8#X2u z4>p?db6~Hutd$eRu=^#U`icUSzy}B~1~**Wx4jN3_4y4~T z^BE9Bf{4M+mx5`M_#y587ncIRJ^}GN51rY|S8Kl&+^5`oJ1?guYEe_Bgmv1Trn|Jm zKx~pGMSG>~KA&$+SKe!CTWZ=nun_;&|7Xatbe?D}R0G=_ze?jO#@p3f969Lr6iqCf+`+b;s{FI1n zXLxM9`v0K-3_Gb)9Qzq)f+yrR`nTnVe}rhjZh;UchSXEo^>ahstlxfm`*c3a=jmRp(YCJXJ_jmw zh+#x)mRu>L_e6WKnD^an|Gid|2_vq=7Yn0UwL9HbtlAHicD%sFsMnfeFhry-VdSs< z#YEW2-EgSivL1aFZcXf zl-Jc<=(S%=G}bG5Iv=dU+2$fnx%1X|%680UdYYZARku2~)Tm|UtJfaBHX&f-dWiZ` zS8d#_Nop4fP~7#jXaw5{_tXma$NgqpEXY3F>D-JH=P(h(#31y)AbLf@>CYoYOxzX7 z?-;+KHgm;i`8I$DwJEu<$(QICwUOvpwY$$PvG@{6;#Gw%_!LC#8~Z26sOgF z4n@?b@#Jl|E*1v+O6_&;WrovwEF~$K{QFyZs3*f$xvmtMPny zFUFcrgX$v6Qpd9$+(Bie2ojkVKxL0t@&W`CkJd+N1k@lwBO_+!bct`EdaPgt!TYrQ ze_NrRUXbC$2kA_Z73nyx&_$Mk=Dn} z?DTD+_wwnri2W{mQ!)JW9rpmJ4qN{1CIH!2(5oI)?qcQum_ZjIN|nbj`r{$EsDPzj z4f-Z-XEz;7#ym9tD;2A?&X`>#99yMp&AO-Lae_-##QpkVHhSSKiW1pRM1+2DIQu}t ze)4>f^#p=3*wI5`q0_G$e7x?|7x4QV(+O;1uq-^_zN1SaPZEQ5%M;5Of?(f-^m3_a za{?^vJ~0TThG7^ZNj$vpDe#n~a+iNSYzqW`j)4{T(SuzSHa;SJPcW`8>(}#-x%zkO zS3=7a{Xl>|VSdEb{dlOZ!-*URI(i<8|4VY<;m2R*-GaLN^x4lH<;Q{71qt7RTal1G zVK+#nh-A2pKc^!Egf8<2OB3Ed%sOE$sd^hJ1ldm_?}Vw;zX@=(J9f}&t8FBoZCT8* zK#pK(S|Cs~1&-J^P4u7w#l1ptc*y;NfM@D6RUI_*udmhki-Y1}Opb0)Nd8402uu5% zf54dIWaP|0(mg^?`_xL4cEY|qorAY20RRu&_!!@i-(`6$zU(MLl->YJR7`&?5(WaW!oxiAUCYxoXr z;1N)B$R}iAamopTf%ruQBfiF=Wb)N6@kA^X(o8x8Kxwkb6inU}{BESEp@b7^SdKAt zC zh_d5y=^;)>acvJCJoZwug|majl#Iz3%8ekNxWArX?@K$`*@6O9o_tXk-Wk%64dF-8 zf>Ocm^V1wJKMLMY;sG=;jI<$^vJ|#mv`OH%ZLVl`@o^K-<^-8O8mI>Y*#3K1N-20z zVa-K`6Y^Nr&mPxnxjXL(+?8Ta;1)mK-B}mihOC!cp|sK+wPO3y$>>WoQ7)%}F(Dc+ z$G~cxP&fuvFofEKTLcaN7AvjBy{pVwnVAw&I^b%b7KD{6BRo-)A&PWmA7G>!ygC1l z>OtD!w+s_e84kC2M+hQ1`9OpuNWt^xJv@yEKGgj@1Fju?Q1t5ZLfa;z#tlJP;)6RT ziYF{sE!S3L2jlYKFHaEAmO@eaEA=L-{KFMF=4cLjOUAn6mxZ+x3bNe`9#YaXgD~1< zh12;Asan4wn&4f{N#c6&kU7F)Gk!YdmtWzFn@WROzyiz`{c?Mz@Q!6B%$!;RW}+#R z_^S=UL`QuqyAKxAIFd0w!WGwikQL2ZiAf`|C2Urg%)m-U8z)x99N9YZWYVj8%2=BA zR->j_Now&Nxh3h4{4?k3)P|Z z3d82<#I zkM9!FKL&S52{n}kDL?~g1z4b@fCWth^*`?5OzCm*WT9zbi1~j$-sH0#5fvi$1{^Z+ zr>gq~)JN3?SBDQM`t&>WR~CLC1E%xB9pKTsKYG8O=Di zx>wpYEbCa=ehIRz(6ERvK%8Hj#qw1Vf-2rLWfrzPfD1 z0RvSUrn|aNrtXqRxAgnEN5;X&H{p3>MlC&`EP20~iefYI<3CinM>hxsCWydQzPMBH zXIAjYP}G~5!=YvQOkt*9gKUA|=a+L6WM$9EHt=vhWC@)IdW(P+SPWN7DhNvP`2hm^ zs2wghvio~6R2h7*58!*l9G2($Q!Q1iz4rG~Jnbg(@9l=+C6oEFp+#HP_GuB?r)EQE z>@d3?@#coWq)CYfI?GE_9A+g;D*8L|?Dpb)`&(KLwwk)sIb zG>8Kj1l$bR_$bk%2+eNU6Qzx)_{HAN4fz$B{P;Vf!-N;{@Z^NLoe|D)$%gAE^psdk z3Cba+s{nG~*q}As-1I|8w)ojgx)4uZ;Hb2V*qj|~DerA-O=0S5npgHCrtXL{G4U9NN{#P3)!y*(|zV!woI?8XPo+&dRuZb>T z{0s{OO0Yjc8~?aLFn7UVH&I?ldPR>7no=mMR{pNdd8D1{S<`%#DlNqe-ZJD63re`8 zwoRFCf*clNxI+>_e9T;-&Po65yjcUz;z)8yurfeZ`&i9IFV4{MMGFGO-kvF1;$V=* zv`qqnF6i@EAUiyzCeAY8;M|M{VKVXpu=;;(T5$QOvxVyJFgW=~1IGRK!k)AmJ3Z23 zd&^&+&6b|-U!RMd!|;q4O%bT$JcNy&Uk!+` zJ6X9$|Jw`0Z2IU(tz@P{t=^kkSQ}>7PEA<@I(^d@GX=g|_xYFupT4KZ=T!~ZSJO(2Gb zpE4SJ`N`ome3IMhG4|{6Z86)xQRcNj3AqL5ttMs4n?LvV=u|3MsDy~&REu&dn!FyV zi^(z&T@V!;dnrCFL=RX{b5JCSRC%$m#cwHYZLnQ{OA*K+e3_t%I;fqnYymrl!hi(p zA=QMi-dD@r_rR{-zNO^*0P5l677BWSX4Wqn` zvI~J7DZB(6P@^#N@NjIR!xg>H;ej}0IYZ|#p3e`>r?v8Snhv}mY}fw2wukFGj}|ZX z?<3PuLUd{(|ul>gc$o=^1|6UAMf86E1D|S?TTF>>N)26uP zf$|jegCqzdwh;;fkN6R8H&av?Z24c+W4^Lp(N0|&(#nJ1fAHtSUjv*M2#J#Hp{nHc z+rmkxOJhJ9u+M`2yc`{H9SF&cjmU9;g(5cG6aIZrqd9oFqJ9j~>M>PC&yKX#CdJ&M z-o?04JWLPWRi}?31X*)$ER3dp5lz3su<9Ux|CG^sIzkv>MWuQzx2Vh)TDe*^JT4SER?Zg+Ck`@`ZcATD0&gQo@k=ymx@Gr^ksirLJ0>~}O=z`l}OFGwj#Q|$|) zX>t4?`F?lPzstEbUWn!R`T(DXHvNmC-uhi2HMfrP=isAa8E%hqlp4_umnO%G2&bQ!vDbADNIP)W+{uW5)CHo(%FO-9DutX>>-M9lmO-!jwix{UMF(aU! z=W#8{UWP6Q0VHpGwO`VZBKUj|Jkf;N*bDyjJm(*u^XL9Ix-Kg;(|ffT>^!m^+Cmgry-@oS5S!mJA(9~J$J{? zq8(z22VddEolLR!dl^pDm*wTp9d`kl!T-6_ZEmIRG?Lr(`nf_iJKVbCl^&hv6>E~q z+l6(pn4BB#t6I~?Pfn^yZ{%luUQfdbgb&{60ToYB5OvRl3x7UWw@Zt^pNO)3C48%J zYVp?tkFBYmne?aa)iBwf`2`|S zt2x!M9dTRw~YPbcK6C05C*I>OHXp z9@w;S)Q6{ylzZ-9vpiZsDTu=x>IRpU`BR&K5) zt!%Aq$g8e43J=(EV&QZ(>87pr`dpb1RVxrWknOpEmwc`o`bcse0c zHqnDZoI)2WiP&J&#zA3N@QL#*Hqpdr`3Ikn3(_-FYBqI>ELJ`q2_Z$iWj_EXfu^=Y zw9_P;fgixQ=6gH@tP#LYh8>_IwS||Hnhh-CcBa&-#HCz4J<9FmL91TXGL_;!Tdywj z_2MpHmNvOcSZ?+mbsm%V&G&q5k469^wL5S5)|!QjV;Spo4DYY5&K z7Y5<57}@i#d!jZp2d4gl506=j{QK0hQn8>;B@Fi~${3sm!R?xRH=l}WF`7GIN_76z zFeocP`oR`uNEj^XLYOV?@sC~l>*!ZVSPCTq&0I=emU63_+M2yu(eR*D&<8Vp+Sisj zcdqXSlX0T*G|K5#TB$8(L`47jaT?1VFz9;00nDf4+c0;qcC0rhSpFB_I&Y9upslUH;_wUOR+`*y<@oCoJ7&dMsAJy)_e#qb*Bz zE$O?NqewloxB26^t86^6o;7Eo#<0@u^e3J5w6Rkf`E;{197^3ma9^#JyT&-6=WDgd zunHQ^;589=!^gGcEl^5`Qpw$%qKlaaE(kORql~ZYUSl+v8uK25XhWs~OLiQ?pjA*p4R} zZ^fxoD(4d=JX_0Jt5J07USb@>P)W{jhuyDB1Q8ks3UlZ_WL+S8R0+}t==86R6*4Tl z4&4X9+v=fh;B$u`dyD11BS$&X--{6R-62PwZ^hj9L+TDE5?#F&(7=b3Pd5mu?|&z*yD^^TF)J zMJvS=;tbz2z{1e~MdZL;p!bj%9AUHrjDj;lp!}A5_@+L*9*k*U-maKFvB{4)yUU_IKi+L?KqsWtDVfGY!v%(~0w%9+lq))o5nb=?152saMLsm-EhW zT+2#MxKkND|CG!N5rFW1Jth%yPOds0lsp(NaF={|(b4gd+bi%!_U4N&>>r)Y@em67;5+->`( zFyK>sC*|o|IueOXsdcj*ST$GD`(dJm-M+6|{>Lh(BGVL=&+0MYo5vl|E<-fniQm8f zzlYFSL7agxq^SSrFd<~@gFxyZBSJ7MCOtmu`}@8B^vforRG_#Mi#3MD0G!V@(TZyA2y_ltkx#eFaiyVDVl}+j<&FpFpYFeQ7X0YBT$9KcxLP!g2?44_eO zK`N8pNkcK#yIM!C$(2~ojORTq*>XqIbg)a>g=3YfW2vQV-PmSV4+YQ)U+9=;%zVxw zX3^XW#`r~d&*)sp4?ZptcQ_9ZmUEx6{=+50-a-(Mr>l9#bD?aCRsZXB2sns6Z?RU! zQ-yo+WGzA1M=EmSMuVv;T>@5d!&49$}_a@zh1!`o2~Gw$Tg1?VPA!i9tc zC+?fo%~L|piM~{o@hAnF1G;1pAh89>J(j$OaCy_+z4!WCL@e1vGgfK1!`Z%)4%OdA z;l+Ex8@kE#Hd@&AY8hv(EF>?qJHgyvv@X0=Tl07fV1XRWQ~%?0)0A6ftAWWX;}HB) zFatm>3?JC`uykT&RwG-r(}{WcoVU2gv%fgHwB(-ME`Sg&nP4-KygDQt3t2$TGD|bV{{(qqqy~ z|Mr!+xz6s)Rw+1a3`LAbVn=^>*6e}!FeNxzG5-GP-@G3{T@Z1kfceF47x+ZBq4*H& zCqhAiEDj0?hEtGc(b<~Oc<{ZYp9!0n1Lzv?K{lz|lfllMfIBFEtrw#&QVl;g3n9Y% zBJwUMfmsVCCI$+><;RK+jQJ=!G;6qE%5>P_4jUV_H^m4j+D)B@YcYG_gIZ6q9zuqO zb;nKpllDe415l$>05u4CFjSCEqBbC8gPlcon1h(E1-Q%oC3+tUzvqRHh%PEaI z8CCB!htYB~xEYn={c&uX96zOtDRWaUC!d1rP!6Q`Sg!IHK@?@6beE_svr+rs<2b+g z2B2V?hd&krbXJDPctFP^@DQddVE@Jdq#d*=_8k;~d}+ar&-->2)-WL47r485q_*OZ zAOG=dmG{~%(V9Okiq_^eCdITtE%F}CwbHMx^m0{-JhisLY%>)@d0ne*snajl8VkID zykUklJb13_;miv3s#|23IL!HltGCGWff{?fwV=krx1_-LH^1Af4&4pbEYzb&8lro=mJ2n5n84^O!cFNS|*ecoQ}V)a?piH3B8dOOmx8{=i-H56Sn z+q2r!pfp+!TD5GdV#tHwECy)!72JpE>|s3-rgn$*1cOiji%)!DR!13}9R~q8FX+F0d$2R^vOPQ(?!h_2n-zpLInwC+{%^}nT7 zYZK^g)A@3LE@wNHayQ%z4u`8$dQ}~kTPru6vEY!h-kwJupE8zCvuY7OrSo_pIy~b) z|3a7qEmIYkrFgg>>+g<-knHf^jZrqXm3(zk=+ztVO5)u}L}PNcKb%dYPPad9CK}1g zNUvJPQjc09ERZmr%SROiux+8PRB#Q0xf&!qlYlEaNQ~-im^3`9*OyJ0u+xtI!vIN< zPZOeVD}KPf!>c`fiysa^-}>OGg7#uE_!WBdFGQf{C-1E2pe>w$W&MJCA{L$Rr^|;o zVGQ(q6!jkNSP1~*_KpP;#VV0TTOpKB+_67@z0DX=X&?!a-a7U+4z1>~*xFsR+JB?@ zMRnWn*{M|RtwreLrnHt4vu=4}R=xfNH^_83goVjkON`(2nbU>eS}(qb_hr5Dlw8)N zXr`21J7&Mf2f3^dX%C5Z@$17+Yc1MFcGw5uQHALY-$qE-S;YJyxImFVhTyoSigw}S zN$`i@s+bvM8tZVnzRkN&iC$_Qv}!RNU{c|<+S*N@qS@7ZxS*=B)O$73H?(o87N7kO zR8zRLQ9wL^gmE=kpqSiYwHE@?qxQb=M==SLC4(462Nq)3>QmR!)tC$q8P3CC=DQxa zir3UQRvf(akaFK*lkjQ5GLPLDI_a+(`wMEA&nmbY{mTqpXxaUV$?fIS3G?tPi;Gk4 zeG_xVvn)RDhmW=rqBhdi01jOm%6#1k;3h?|E*{sW4YQn4s=tU*pfNTPGZ(>wxIAwm zj|mifJ_=?a6Lx>x*L064qX)B4xv$t_eUAvJVYKR0ZKl#DK7i{$To1!^33D%1B=x}K zAQqIVoZ&|bY;R%AyFyaxKeUu+Yz+|J8@Yjktk6Y*&twxKrciL>@W}TeC5Y|Xfw%de zGaKiNHU(2627?weLdGn9_Rwv(1zkP1GAR4_tp{lrEqJQ&Ye#Nx>1)CTU8HD6b$>NZisheKlL!g^|@Ev*`@{ds<{ALmGKvy2tL;b;| zG|rDJld-eV?1-{Y_4mbfD3TdllVmy?@wVfvo0?2}+kVPis}~7=r$m!jGFu zVwUWKCIqxmtbu=p0^=mL9JEr@_6)HfoT84Q@lLp+GVUX}G*NLHC>p{7-@% zMiq+S$%rAuMa_8p@s~R=(tOb+U44(Q-5oDp?F?6yTEkH5shWSU=BA@oIqMV~PvwqV zXv*pLtl59+#gjX8rFB}@02ohT8=gOwxsdSaKCu`uU91Vnr1f)`xk=)u(%_ag;=R0SbS(v41d62NDG%Tl>1)3KcJr?D=y&kkX!Ga$jb4b2v^#r&8 z1d4Wo%lF{-I32?-d`*o&R|MJnn3s2Y&QEnJ2!;U593I$lM^q_i(eFt?1}6@ngY$_} zCrF3FmH-$eog;S+&(JpwyGVa{jQ$hkmVx=?r>z7EL<3RsQ}Fxmau}g3=FQQzX%ET+ zZ)pzFfwZRf(wi4QdFN&wyU66Z{o>FD{kZoN*aDWXUxF<@HB?egSC^>Lpva&HG(Q8a zG#kuUlrJ;aSSiIc%CSy&`!`n|t(E_Rbh!^+^Wzb?u08wVl$Sux#@IVMXiRFMJTGTV z%Pb5GJRSQrXO(@awo5;Tn`UO4jym;9Dw^8_&4%U0XT@x_s;uU#)gYTpH%QeURie$Q zy(%wLl5>a8bl1a?gbhv5Tfg?5@y{-($Ol;I3u+0nxzpd@qhIjNkuAf9el)M_cmPbo z|Nb~F{D+&?C!2~$*PH4^BiR6wP7q&$EN*d0%`eJj6&=-7)94%^0yB)KhM1zZ1Nz3uFP+i1q4$I*Jtne?f?~ zhA7pdh4S89mloc8FDBdJ^rrY$kmEApqIUf~o2ZVfR;CsXbtle#yXnx1ZZD;@0E+-X z+V%9q7gtJn!{E_QTpPIEbu$W|mkpAWf4Z<|iNz64hg$#O6+FHa8|O+DX=MMjjbKry zzknqnx(vhoKNoKylBK<9LV=4c@XvPA@0MUpH(K-!Wo3-xuR= zk?}keGy22at~{b6@7T*e*K(Ozw1W9eVHI1%W214q5lvV*^psc8Ouq~$kCebSk-i$gfshvOMoKXz?SZzqHwk0Pc>uf?;%mU&>n7!$?~ ze4?)|CdLM$4)V9rhwe%Q#fKyKN@7y=0Xh7G@$qrc)qoLR0?R?0p)1Y5*2X0Zw^9r4 zr%u3wC4BYUKmL=fCtCMb?3Fy-zs)=ANqr_|*1c6r8|PY!#LM3X+K=nyO+}`H-yOUH z6&*Ri8=iccgAc#nM!`*%@oisCv)J~Scw+}hSw=V_@t18oL>3ViWPX$P;2i@Y1KF7= zgd7j{na3jxW;~BwkK+NtgL(DX#ke@4En?`tRgmESCcW|pWg>eC_lw|93(m?V76Ix` z+NTN6!=)wBRQxM#8WPN|AH7M~Urdya04tA96hKaBf=D4!jwn95e6i}^7BgDcUk*FKjkPeh3T5IX?kzu84ip?oApY#2h9AFz(pC6=AagkAW^)%o-1skKnZf z5}`fRZsUTmc@s$$XvK+O0WS%%$QP@dR_`^^thU@)C9<66l8JaPGu_uCm8Yd#Z_hSQ z6@BZ~(+!c!x{BArnYUON3!3vqKf1!Xr0Uoc5@}!N-e`ijjE(BWnT#G<;owgTua2N8 z^j)GB8rke9llI?pO(!Jjr|WsfjTH!uVi5h%^Kp6)u_diI`OZ>Ynwm8qWAaF>3mP6= z0>!kV<9R#G1i=olv}2IVxrX3{P~_?WEI_EeC4N}zS-;Px;~)}*cHjzAcv}Z43$lnX z>x2Rbkr&DZ2l4B_fBxS~2iIe)>fsCDO8+o;#PjoKyis^73HP6i(gbcsX7G2C+%3)C z)Kq${wOlASbV$kILxD@Z+reG$00n(=qvW<@#6%t!t~uw;Ojz^FN2)lVm@>uJX4A<1 zLP`}BGqi`>Y+O4;X389h?xd?UT-AHM;r~+8#IVN56dV$sO zQp5$@c0E#)f&l4+uZhAGK?01~>3-5KE??J4LTSDBzGn9#9a(GYjmUOZRiDbG`nFjx z2jlAQDV&?G7sVa0&%qM>2sGMoyht7Oh+QM*#6{hpcqSHa7U9oGc|d)KkNTpLl&(L6 zDDi;o7tt>FalVtx6iE_y;=zr#Gb2yC$|}7o>TaW+nPGuZiw&~=rTdqS+Q@Tz){BiC z(j}GB+p*BRtOgH_2-O*S57y`1=Ode<&32eCT$`q9{_KHmdO|2U|G{ z=Y>I$RL)s$tpDEEASGFn<+9E>Yp>w4A}8k@;~saQi8`CSv4@^^mvcws_N=bT0Yh2H z$#NZz-OaZ%DjmGrN1Pn0{S$%M+$~&_r=!u`x-is}bm6kL1{~%FOIO;s_FUU4KKYL~t|j+k;*oeWWupalo6S z=>TWK|NB2b-9IKPTK@che(nYqJGvpG0kb<&f}2jhm`~;R6G|i9Ob;Svk)ik?Lq?!q%t!1nIadTM-mbSh4!tTYY{q}gYn@yxaJ+*Z( zbZOIJy9QlY2fxv`^L06Pnv9zHaCbnATav={lPxdzg|EIfa$Yaqfy+cfjK?|P$RVlZ zRtNPYhjf3A9Fhjp`T433Ezt}(ltgE1_@IM2`>u=zovnc_K)gKZ7bsgk?kV4M0D}Uy zJ*ffC86I*nIJq4xD_X7}&LBvU>EGpA;jV@95mszQK*;Z)vEY?v!Kd_fwf!IHCZBSH zD@V!CnRMjnWF_gCdp14M?7^%a$+om@rDm#~9%i?tYSvs&wT(K;v`6EoUB5J(lz1Qg zb$6Tg_r__XoHVgQJ$Mi8&P!ie?&kHZoz7Ka-qd{C-uLE>Z6H0ehq=O17(3`Nu14f= z+#tNea|`G+XUu494dQ$tXcHeLwN3E0u)$x%;1&sWO^{O)YI>KDVfJYzSb{k}R30FG z071v1g^ghI=uLin5VXS|{B_*d1Hu-AIq#khd@on$CS`>}!#v$w98X^_L*{wM_k}^t z_b>@nuQYvtA=3H;@!dD>3PU+?#OA#iOYJ|j$qhnYy8Q*6~?R?y*rjI_5E6k+tQ!j2AgOeUvv zA_j4skU5~Zi8G<%bbK6wj-|3dSyU!RF~5VWxYSRoUld|^?NU~K%k~Wfx~ACwVarVp zG80dH18%nhi25Ci%gk(-8kCez#x+8^W9WuyD|EZ70`#wwF**1zt{|>%*ti@4nd8C0 zppEEUsuB+&y&e8$2Rq^apr%71&G$^L=1vymZotj-_gTEbnE}OGU~IGN8QiB>x(0K~ zFA4}2wU|s(n+M%^rf#&VZdb`o{oQE38QaRdqs&XC9=nQ;3ebi{fQ=xd$&NxF>c`g3 zM|9AKcI4zQ!_LU-FAWMzEPaHB-Z5Z>qB;$EUdu5pr!`99RzCcaZQes6ItRrceywj_ zEBZEPJ?H+;tA!Y7&=|mKfM4G6yr#<_JI5A)uZ%;OsXG&SpCDLn7kh%xIeeV%4yeKn zv|w$zUkRDTu*4ig^V7(fV+gIZ&!a*Pm$viM{Mnt`+&A844i)-mk}sICcmH^vF3zLD zRL-=YojI2G&?`kMq}z@g>&|k#SVp4DcxvIDJRM#_YSm~r2HT|7=V4D<;wFn;6`)K% z)!mHn976_7`0fB@*r^GLW%|J3&Y+B;FV=YujeAM8^B|||^stkuEP2vl`LfxI?}D8e zsfQrmK%f;N0}*5x)`xE^bL1dIlEZx#X9>2~E~-y}#?J%)Tv5Ha6sHlP?0!KR=giKN z;aIAlDwKTL?zRw~&w{IL+@}^_SKdWokR8>>$;61zmq~9Cdr$^8vNygzZEndNhiw?r}_>mlWINg07qBo(wn)qW< zvj{(e=G$4y@)exC4!$J*kv8IF4bW53YZ+qx!0AFWBk9$5*Offtqh0v0ia z{dMCdeD|a~{<aSappwQZ7dYgX_=~myTWAVOEYSOdbB|Ev3F28;iaH@x&f{MRe<5?AUg8k&mxV6%BkXryFBA#k0b+W`q8_H+DQqH zu@tw^m#sI}Mlvryx891M8tJ!R|M3t4r}MFKssu&_f@`;`4e$CeO#AwS2yS8ZMSK~a zSBzdFFi>XI;9%d$w?pY#;XqQ7-Y)kpD44WiQBA7cmKNV%EA3$SWyw*rhRL^ZBt=@&s-LcAAM< zKPI^>GgdoPV^WF`8R~F#yFsR6KdGotD2E);3Z+`YZT1lsiR3e+8@R8Ke(CqywvQp3 zuWRAR#dduR)o~~b?T=AkL|}<8iDT`5d2s&ilAIr-3BFjoBYATecps`E zIvp$(sK|7NTRJPoFq|9WLX3;IvJG`hp;DlQMf-|RFO{0*^Eo%k?;pnq_r&yrHgra; z5pOc_l%mgpprtB)=-gy#CrNfO`nFGYrxM+K7mjou^tk;Y=nW+jkjYVx8OV$q@9H{x zI3!}t!n)nwC-C)l@Z@dNIe@Mtqt|B-3YkB~dg?NMZHTW!@Y+$4wU(5&5%Y zxBl&U{_%v57Kx`vuruO?C4JP=$sGOtLv}Od7Q{C~on_D?xMLH;j*=SHOR`x}dg~Mg z4^=@}W{A7RMPxiRka%p~rN=qX{Of1MnczIO7m2YsloMa2-k#an={nsp3WsXZ!P#B8 zZL#NzB|?R*&$rVe`b$AshNeSrE~%HF=Kf{G^u{CkczB#{jH5nx(dB1bsn-;6lMhFC z>2)seX`pWj4ST3O5VIio7FZZj9z0a8K@z2shs;O4mi}Vq#FpYNz4Oco{FX^N&DTTk z3J~9U5lKLJ*zN87i0;FwC3HYQKFl1CJ*4}l-P8RmZ6A<{)H9Fne^|$YC;@0=3}tE_ z%~E_E_Fd71hheSj7*FGgiwsTok`Dk^FBE3v3lYTsJiLPUFyrpR(|~t~@R%3_g`M33 z3HNowU_`(e96$TZ>Pzwo{P@nmY`nh_;4~HtRK(*29pG_gp|oeL0lIp(6JU4p{rW7z zKE9CbD%Yqv;0af7zV=jXb0Z;Q7w`p~KmmDJL=U!}Qas?CN0t5W*>ix=JFd)|F3;_WKPkp3De9rLmYjfMyaY<}7Ll%~T%bN-=q5#j#fTo*YjiY3RSq<5>Z= zFhrUg#6b$@OWIYjb_(apY+h<0k#7cydZ=*^@fjO-t6dClhl}95m7WLk?V(;@SdnB0 zhp}97q>i$MQmEG~78_4-&0Ej{t)X|H-O>cfY|!af!9ln_SgJWZmD~Lf*{VYg{OIie za>X%?r$N*p=dn_wja-s1I-P$Br{b8sqHc9bT>=?`AhpP#+Z5G zYqo=jbxE0}-})hQThM#kdfd}r7PG1Lrd}S8meWAQ^TH2g>yg_G&t!QN9G0X{w* zQ!sI=0RsATO1ixOfv;rBF}J2&y-mbDK2|1K*QdHe36cRMgILI~Oza)#&Qp%GWC(!8 z2DcMqMS@a=D<*C#;ai3vR^ViSs+vVtjSn!?#Sj5y)E8Y|%-+9UIg8we`9fXBks0xc zy!O@l`^!d8rRzQfJkG!0#j?RjH)_|0jZ$e`sn3VARcgGCsJ@;(DIBuBwqoXM&H17w zV&py1WhcZtG{dm!s|Cf5L|Ymr>HTZtUFV))?s<$2cQAbbJ)iOb!RO=oov-}C$_W5Y zJck*K{QI#sPCxuoW+tZh91V{Sb&t;n6&i{+YBDGm;ZBILGSw`L@?z}ADp!Rkz^3kD z1%y4C@TR%^bcJ7ivCJt*5(9joca$rBIlLGD9>oTbv2l!~9ER2$Vv0?~5JpGXt@G>V z)c)@eNf8tqnLj_*eTk(TOg(Flu{GAl(zD<1J!}+;6Hix|CJF^Jn{%$b!BFA2tehLv zAK`0BReaTu5^m&_taA%7u8aAR(;WmA40Q~eGDP^EesFa z1bycg7`yJtLjV2bp3GVen$jwOWXTMisWU_r>-SH)&|WRf*I~L|-DSG{eC~DpvZ&XS z>);}=ANU)iX1^Eh)x2wS$Hm*so%rEgrcyay$|KWM;;;BtE$XPn-E=fypl}PmBOSaqx@2AtXNgk@*RbX-+sAh#jw2~9tkenN4MnI zBf9P7nZ^K{3lh6Udu)UZA^#@!8me<~qlBIS@8b*m^^f1-fV;AK?An`du@K3`+bag# zwNxTK-5Jf-&}cJEHbZ$j6VOQY@RFO)TE$mQD-{yk_ffdFDvq{BMITR6-kmQOE)?2N zzHH1p?+jy`USPl%__2ec^x*$N+P*kkSzCyjg`jld_jrDg`dBv8>GypiuWg4@@ofIR zU+^dM5pOFy^`+kIw&tP|p`t^@;s9&VxIjQoYSbekfcXbeiQErZ z{B(ROH@AFOG2_a*i~$*f=0L!Mm6w504WWC^L`*pANBFa1T+cV3xAS1Jmz=3~Uwdvw zb}zM*)>adf{dO>IRMd#9(qjzL`CcJ9MR==z!l!YR#9)t2U**uV@eJdP0S7wui?_wN zGjn0+`vLXHEJi46@wDvxclwl1*gX5IMk}d3I50p+L#V8eJ7fvc<9?fbPaRoqc;0JW zEb6=DKXv%#_*k$`2e_GhH_q{CUQXFDqcSbTXVs_F zK-;YX^H^eTHOF6?194g0X%yA|(QFLEBESE)ljQ+p(jh0@668$N4pE+Vv4kMDCS;=y z4?FhT-?o2TeZV*7y5O+=hlq5?M{p8xAs%W0FCQ_BPNGKexl?{gbf%d+hJ({w9V@L_ zKZsk~{H@%G`_e|t4iy_4WufEJ^3RV$KRpZ^-B!soUgOz#I5*YW&r!oaingp)Y?0sO zU$e{D)N19Yo>9CNYMn}81a5)96lyqELjHNi@%@+MN^_rK>)0Z>zu6hAx9iyig82UM z&d{Bcioc_SfvluryUGa-T?OY{AKs=!hWUfl!q$wMp_m%jz9t6#gWb+|`p{jB*(J)!ItRI7+T-j*o>)IAo!Y9>B(eGtMxja|w0n60n4XQVcFEfkw~a z+f`v}9TA`U!Sf8E-O12G@IC*Jrkwbtk`~HGqOo>5=ahz&kC#H(_%0U@rU!4sWU9k? zlN@V?HVTKMR>fAyC72uKayj1Jq*|kFv+mFO@=w}RrV^M9Cv!8gu?4DiMK4G10VYp( z2Nra&P7226u{)LIB5|mai}v$@K7?T3;{$Y&)FM8|d<%BskvDk+I)49f4h@X)k2)Pv z-q=6jcw)Yqi(BeA8r^hu{c8HjwlZ z6kJAy7r^9SY-OCc#hLGj;Sn^u>*Gs=e9#$SD7X}G{2sU>R)?}jO5n*gxPob#UL1|8 z&1Jye4B?Q+%f;I3rX91|K5x~#S(U7BWwBY{joq`@43G^Z7MqNd z9Nimi1<}{ZPWVyAN)^jiCr8!Yc`+PgzqmvYll5U+etZz!mQ-htEo=8NM-v@g zmEMVU6%ZHubhYy(5vspo25_lCk~$4z>xcM`pa=3Q;!(Xs66Kss-xyAv9wIl#?=NT^jdgi* zeZI|S@3r+dvUy*mE5Z4=qI8!D|3Tf?8;y7imtwiZF6B_7!I-#T)zClLR&}gv*~iiP za4L5o+=q1kL!TT$r$l);-T{xU$pDlg*yCcnciGyVe*9&IFBX=Rs~`8n~YK2g6d#HXOKH}KwK@=YHfboSnctX@dXw7d&JV$~wxza8_93x!@*m$sqLR9&l z^h@fp?fC1e=6J_DKo6hhSfBb+*O@7FDmCa9#p+0SIpIkD)mEAduT~l^CSf)4WNs_t zq5eK?Kh3fo^(nFp7j{ad+v;1LRO7wgyj_({ijW{9dj@U`5(G=Y60n$Lb|JbCh7etx zJ$DG2<>rUD^u^7OGR*JH0WbQkzkcwKC;ZOM&4;rF@pE|C;ppb6BwX`&fIUVieyM0K zyJ1UUTKZr>Chi-ZJWA+enn#Xw2%HD4wCW^ugkS_QME6T z$ULCH5~tt9N_+|j{99o#7DTo>^9_=XdbqgBChC)Q?`4*)C35et#cs45AJ-O*_tYji z&gM62RggKf$Z4(DtYikgZLO-c8{wC2ub5qA!_2o{3fraj)U)D^*Yp%;@2NLaOol5R zG<#RLf(nNebqYp;SY!~6VE8HfAh`y})M6S>Yfm(%a*66^8a ztc=Q+$vO>@|F*IY*htPomS4JgK{25@sGux(I19oe;jSNM{--C=AK_=>7ebIgm`p_= zB+o596J1`{3|icS0l<(>*Kada;#RxVhwnbUnagHNzt;9- zKK9J3E6;M@niTw=NX!`ZdyUQBT2$<5tR7e!m2ACIm_$77(HrK+y_ZUDz?t~1*$JZ9}58~v>1iZ1JIX2)`Y=p zQDrKppox8Qu8n7}t>jC>R9d!?ed#y!);y$lBBjhGn0(2X+V$pmS_xhD&iZ84m?s;( zeDS?p$R0-B)FIW@SAm5(EzT$Dw7V6JqWy7ilT-Q)JGaX1L*B`HUD_bqUX@mUuf4Zp zw%s0Rd)-`H#eQPF@}9pdur#b~U~^NJ-~Fy&iO6|vp6d}>m%n9Tou4rHV99xW10pv5 z`4@dLwhKpnaUZoY|Mjm3U%xovgE_VEzVICguh?%rm69iBCp{%O;k#G$gLs*E95a*8 ziye^EwW9+OA&U3*Fd%_ch-)c$uy`Y*Z7ktFTK@xJUFbz6K{GJT-3b9rZvzPf!fTm zQCW)zheR?ko&yU-NywD~pFT~?5#Qqbf@Li232Tq-^5)A`I@tRHDU%3lq4CsAk}PaX zv*8dhB)JFg-21|gFHZ}9f``95R6gGEonz}0U+MJQ%=qZAP#^U-(~(Us(#NXe>qgQr z+pPZt6p=Ch@h_W+_iVWZmN(wLmg|esDz&VT_BgG~xBZF7_qJ={X*^Q8rAl%ck&|5< z47_*&>V2>_FDiQITI@LlvS=M#-f%o(7R>NhLTGgJ&PdY;W0C6*;72B8Ylk<)^IdbcXj)y&$MYcH%q4s-4Q z`R|XVJ+6v;1^)%^KgTxSnI9%SqNu^ZHv}vCSJ4C45m8&X{e6bPx#h3C zHGKN8SM_OyMVIYsn@(wX(54HKMB?2a^u%AyBzZ3<{SkMGQ*K^)0k|FPF|Zwd9yj#I zN%_r|20NY44z#U)i-BPE^Gx`*IqJ@q2q4V|628PG&;Ltoczj}RcOqR#W%4EIf_n=( zxo`vI?4#gk8ZThv85ec#Lnt<9OHl58I$Mz(Qko#N)sffiucrJ6LYS@NQb$HB2b#jY zX&A6|`DrJ77i&4inUHCA*1Is*3_EBG(@h+4xUu`cKGt z%!kl9lB)&dndn&Pbf8djt!67Ks3UPeXj1`SG89Wj6QPLePm-StN*SYIr$dhPvn3Sf zo%m?jtkx2n;ieO>v6HxM^5t_x^O0<>l6)zJr@@qew`^}#85D1wTHjl5MH}t?ZX4M7 zwbV9Pnk2fh-i!Ja+P{qZ@71)^349pW5aLKo=3NRkeJmT~W6?0e&I;qt1)rZi^`Q#l z{17Q&K0qAbyjkdP1HIX%+EX{Zy|wM9iz#KZ9!+<#N_HM;z1sbZ^177lcjvIe97p`H zI9|`9dj}7?{8J&j`ZtkuL(9LE)=#;X`jn6$D&nY8(blx#pS4Qa_Ne`?n~lsizsj}z z8(;3L01xU0K`VW~*a5KSQpKiAg+LG%$DfNiHf_D6dfaQX;MH);@%7$274IEcVcbxj zos#Y`2r~%Q%p-guu*#v?6UiT~rpBZMiR`)gX(m8C~+e%`c`LhFk z^(=RuEoUT$J#0e}5PU&taDRv1OltD(WTUc5EdIZX`I!}GfeA{o?RS$rvD@RN%py^X{=@n-(Q zTHnlNF!DS%IE}`Ad-*7}?f4dS@q~AAGslw%8Wh1n^ep0ZD4rE40u>c82BJS(oHXTp z|Gw4x|>!+0KVoy7A3$L>^3pmJ*b&?Hlf1FgbY(0?dZ8zC$G1VR#GiT&VCY!?}xdT!1 zqpMb09K1P#e_Xy*frlMN^c^_GeQE(zZb++;1PLs8*23IiH**zd>CTs@jsLQ*EGf;% zv)O#HLdig8J*vmwr&d1U^{e|RCYrm~{@&MJEnlhxM&_9sM6V5_4g|+BJiB|XX_FYwKE#8*dbS4+{^Rfa!H?wR4`&*oRKL0HPUFo{ zpf|{>bJb|~y}NC%qb|BH;qXc=uWCju-Uq9JaQvSW1afI|@l_OpI4l0v&!3!%fS?ry z$?BKmB$SuXN-s8$n{My(Htjy;B?%hF8hU9;BlOew&{FYtJDm8Wyr`1zC(#!i?=HW+ zQa#jtxmUYX9VYy{#*cHDSE*&2hHeFigN0)RehJFTohN)6*dMrI);vOf%X#hS1 z*MH-))7}s(4!kFup{~N#bdt(-qB${X>Hwg_TXmqZt5Ou24uAc6+}lQw9im45RXeGK zujx-NOAX(aiM?KFBn#zXZ)Z;1rP?G}si(_jOZCn3iTuH+wKt95KT^efJDQ5+YYhO_ zgTHeqHe%0}mS-3<@}vA~tPxeS{rt4jh^J?>g6dzcpsqUP+xg3Eoos|->b$1L0@1P# z|FJvkSyrweALWM_-7@I9f^l(@6cC~V0S(qTxeri+F`nX}gMegFPzq*%1deF9500WD zISDSA;kIU1HN>lDR`j=P7oj}Ed@xh(;W6pyA-=Sd2(??@dUCaX$%=cO9aDx+ucK)_ zJP7Oxb}138K+=ht%fRwgF}ZU;aeLPed_Lzx-fp>}fP@^!Tr&E}Sq)*S5NL_CaM%`~ zK0A4R!H3vPFhAjDK4YB4jV>7TW98N9VKLn+cW##ohnfpX9 zMZCg%P>wD0kw7yxZFlO+@N_cYuGfd~)Es0(G`@cs7(wsrQO&Uj{yZdvbEharpZ!#x4(gpeOJ?5oY;=G9Jl$EYw(Tzz5;-&+ z6({2&$3c~Q?UrcD@X&^63J)CS48XY|MAO6`B>|s?54}IUxddBwUqL8rnMh&6(uHoQ z3&@U(B;!fmI}7mhXD6cg{5(fqIIYsyw5IFrB@yPF4*7ZGfDHoK${9VAnv4V~1Ow^Z zzY_)IA!n&r97oD(*4*jMSl(KC8!sh0HOH{XdA=iJ{`<$}sdu6jO@VUvViQ4QM)!Vk zXQ~h~#69Y(_Jlu|2%F>D{dQ}{lJ@+37w7iZbj8yHXi=PTDBc0bBZH({&I_()5dB_E z?%of3-Ksm4m|Wu(%)l+xHZXi+RO7*m4EGU^Ww^s)oh;f4C++=<WT_>*$gU3rd zynsSHoFGY7&pxIbIzX%3YcKS%G@A4wtdg2Drf9%L+s1Z~^ki+N`9-=LuAHZwOuE9Ut41oU3E@C8z zf+AXDP_2ZyQIHDyLtVDQx-+c){bM$_0eM#I!`CToFhw}!v>zuZ9Qm8b+i$)j7YaXH zIgz^d^Ou@DQj*E(x}+rIPKl`$`)_K7RW^AK(rk#Gy`nJQksS4 z6E|6On^srB6Z+PH)E&ksGaLom5%3Pgj{5x&0|)m`*V>X;sPCaGc=?FgZ_E=hf=Dab&6yKeqTV>!X) zMf>Nv+M-WJAxfEeb6s2tD|a>dagXiJWOyE*syjX%CZCqcCqV<#K#CH-@*xgfdB#41 z+u!uJH{Fo~-l?7$sXy*phSLmX8NkmC*3C2_j8|RIkFWsgh7W0sjsK@2p>(LR1VO?S z=VnI~W&^z=zaL9V@4O&{9cWx2Ku}*$ zVp&L)eOlKO#6t=c9&o7ZcSFp`Q;;g|`Yb16as_C0dmM<(3CIroQ!E>Ns@pw$JG!8- zVsm7}4g5MSEVYzxya>54HxK6pNhDDeO5yJd&X>mpUtz$oWE$v467c^Lj9t~<17yqjx6jaB(Sy33A&AR8~R2Pu8L^RqIbL+d?KA%+8X%r$KR6+O~a>VA38`iiC;>6UI2T z>etqlp_2pq&^SfNd>B^2refGxQ}fk~`r1ei^OKU6tCsXaJU?hp%ENY}r03Mcp*`&R z^6%qG{ynGU2_wuGOy8C6Pf>&$Yw-%|Q>AlM^%7DYoXDm_HRM3^Ok; z3#S%+IYh^q*fy>nY8b2p>%D|O)lMH)ai71aq_=jk5_yRhOGUga7Ye8XlhKQMgTtBP z6NKrjJsZa(_O6S=>caNo=w+Ean_9Eth<}t7_gJrees!vc8)Z#6J5cqUlCEm+5!Ed8 zCpFyTI_rtgm)I8bksY6X)iI2xS*`NE!BsWWUhR^v)zv7FNrKo<68&|on^%XvwEfgv zj3=u>HhuBAiDP6Y&m7`>``tKu!`u)l=wqX&k7s*q9Ugz*p`wdo&p|^);CEra^7(87 z?UxMgAICnxvvwrbe^r#IVQ@`*FN0ioqx$V)#B)zI5YX6)fh?FEL9y`;^P!7-koAm3 zF^&}63BP{Ez20_q^qOne(^~h{*BW-}$#Q3~RTBGla2e0+Y;9GnRlFH*vD4l~Sc!s_ zaH}MfRkfAIedGlI@g7$45?UToliE8@V7h~3ojTN?a08)q$`TIw;VkM(nBtNHx{JLF zBt~>Ye>2RK;U{gjiUAHTIE-o@s+UfWkQ~m(v{lEKaFV4@JbZs6{1nmJ<5hVTsVehi zZm87i_B8pvXisyCo~dk$&3<%lzV{vk+X&VHF~BTS|JQA2{U>%WTvpwgV4oQjm#hVh zeM85|#W$tp@fFzm*bN@NznwSbJmgfweHC8afmMTf3-K8p+mntUGP*-Q=n|d-RVQGh za=}XyceM}>Dxf4vkjQkjsbQ|lLyfRpbYjsTD@MZ-qwGF;_r$N|mYPY~|3yO=%ylfxYkxewnbKxDxn=)Jxtt;&{3DTN6QfA{l`wX$}sP=ypfU(b3#Y zLNUY)$~6?>TR86CE@vo=k2Qti#qs*rUXUveKN(WNV{QY;kDcFFRA2_FZ*TX1TgB5Q zteRv^bcwz&@r0lYk@G;@N4`K~QRNf8?p{u7uo}IINd-C0kUcMVg>NQigqVbhs{p2y z81+B1k$3rH@rQJ%KhzKAA96#se+2D$=BoV|{}G)hc+l2ZUh7?=!DOph%qP^szG777 z1D{e}RLJ4!27nywfMN#?{4j5+<^c*crAy(d(!JZ3NWpD*nJC1?)>lyjg;P_E{6S`e2^@*~3t@9{4tdxM9#u00buh0H#LLZZMula7bv zApQq$fxkmu@bCHGn`_}COXNs_w?a<{H2~#>?_4X=is8tqU*Fg zB`{?R$C1zA1fKTLF>|FcdEKnfTB!D9Xf{7|}LkwbI~ z;~zRK%$qU!z$phD6~BH{|0$E);vKu_&y;RrgK&&ietdyA19acC%W7!Gf@DK_sC*+P zM|?-|AK*}a5WhG+Mq-h=6f{WQh%3?FmjMokYoaNx12U}BHD=_N&*-At`pmodT-gIz z0jC6Ev9RaD*qRA$`DJARvI{8yotON|LzTku5yGSS6x<$Bqk5qH+TTF5DeqnqZv+1z zHmJi0uDlO|t;RoBH#Dv(WNWD)pDbnq7{a(J5u}7!9S|YL>fGLmJ@a?{MDcT!dyK{~ zIJigs0ZbEM128~=#Ne7y2?yZE9>P{F(JJmbI`@5-dkC>Jm?FFH z>YK9o_!_{poZ_E+_b&hRmck_M-yBDP-WvlT1c;7%4LdVN79nI=;M?re?1&_)Wdp$= z@RX1`IAc#hG5MXg=(vvnj{7?pmpUVQa5HBbU7pR>e|#R`C}eLw)-B{+)~Mx!48=ks z4JinFPy_74&-aeidJ^NVt5XE|IWA6+`T{@%i`|44}3 z9Hc1jw;Kv4>Z7*Z%UZK{e<`u-9vZK^>TtY{zlXBfaU+o#TdPfUw$?`ZkMXMb(+1h* zf}hVy_sbGyDu4E1<#~EKMwE{YlEn2Ifj;`$fB$)$V0wDc`Lri+MJ#mwa;MVii%QNl zzCJ5j9ph`+Q}4Ru(klCv$5sgyk_6%jJT`ljMuB2L9)$IS^Xli56!w=7eJ(UiiVHE8 zBY=)u0M{A?fLV8{sjHK^P)fusWeT>t%9ir;Mm7|w_mz5}m_+XS-rG3%U$i&bch^`) z`3r^pQ+K{BM`qr|JgzI*OlY

    `mR28_}a-e15gT4A`3%vnh-H3VxRYoJp#%mI!0V&HlGXwtof1 zA^XtVCl9Ns$U7|_6648W^1htB=X-<6a`IqLdkeZ{@1cjjE~-!e@BiGK);Kc8;8g4%0j$bipp<5+E;>|j1@9Ww;9VobA5nJGwEx*5aku=KR`UtZA#wavQu}jz zl6;(|OS61=otk!^I(0*xMXJqeD!qITKE0G)j6&tLJ=x|Lxx_`-(1^saL{%HN(KxOb zO!qI1OSduXR@=GBIQKwVIa^atr7W7icS7Aj#IY#=FoF)*rqmm4v!eWPPMo4ab znCQOrQ}qZWVcm?Pkx* zc&==;*VfCx7ij78PwekUS!FekF&z268@r1E01w`@bhs=XPRtExLj|-3ko&huaN`h64FS8bMbV z1NK+LtzNNg73OnnqFlqR^X@~$vCxwsLm>Bdbee=QNndFh8Zh}ammrw=bn4(7SH5;> zKEX@W0RWGbu-k;AQQ>v`Jz#VMc*gbC1w%RLx6DSZqhCo@_imdxUM5#wyd>JG%F|QYc+uaYn_a6u(w8sYTq-ee9y6nAHPlP)8bGGjnJZd< zv~jU4#Y-iQ9AyZLC4^Fh@)->?y$U(U5OY;{iwL&o3rqV}?1xl!d3^W`u8>U@Nvcoq zz)!|)-b>I@Liqjih=ccU(^)~EH-EKV@&$oI1CqYu=xT z?>{(vQIV&-uq8l3tgIDL^o@Xn<1INn68j4K=gbAqjDh0& zJ}grWFZK4czhMFxwYYl@Cx>7X{8bE45vR6|hhF2I2X_f2olrTFm0%C^wa2c{<5h=rj_^hy6?n#4|mxNRo%-t`W!Mty<~Zv(VkQ1 zT|VI*ieo@90k|NwiQNP)B@<7U77%#^`;Pzh1S|UDo!ekzw7{e+G8MsDJc=Y8dneXP z*upiLR_tg|AVCul035Uf`F%ePsXpvR#b*cobmLC`O;2 zM?oZXyx**QfN`W*-`sAj5O$r==ehQ`+jo39mJdb-2T+c>9S#Qe7-k4YH?kvUctDB_ zCV(_u^hZG?G5@Ri@=-{(R)yqCs5ML}twxK4vRbg%sD+EkL9Y<34+@RfVG%x4Ynzfp ztHFVG!d?tX0r1c>;`y{cwwQ?M%*$MGO5LMoq6xpa->S=Fq2kb_IMg+;GeOtF45T?q z!A$*z&&eC0ZxFbA=JB&BR~Xh%m2fH zcDN|2{WOJSsv(49HVV~IyfAv+rEw|Df`d$YG%2K*`0}8rifb{01bt*r4F~^^-x{9+ z1vrG}=CHH+*>c6BU_8RD8n=H2B^29`XHC*j#pmJ+Ne_xG9AOz{?JF#wtOhtU+Sy_A zH)H1AAK`r+pC~c*CX^Z!>zhXkDUPULZC}s%;njGt@re+jle@@ zuWehlZDrDcBJU4xZbs+0rI_= zM1rwiwgb3BV6G6r+Y3)T`O89?PIwK-jy+27Vy?n~Pk2!#l1qdS$X*c|p?4Lh=s?C} zi85Tk)m=boHlC}l?iy4)9t#mg?w^XEHe0zuyO+`YQZOKS;co@{U2#}t1mv* z?tBf`3&W^4V(E1D;iYEPUY^oqMCeS@Xl*`a<-)0ew~nC}1BSFx{D zBEN2Z^L*iFa@sIpGmqvHRCu!J&(XGH!$-MIv4782cqu@Zv^_lgDK;-rTnJZuDU+G! zEpgrwX+e|YU6M|j7BH`4oW-|}43UIRzT}FPuwJsA#j^icO|3Rr?WL5$J)@Yqn-uR> z&ODztrWqnFw8nGuX;IGo`R4!+@j6kCOYO?ezC#W}QIrPqIenh{hZh8p{?RFlfs35s z;oyIyi?0fODvFy4pUDig8OsF36qXnkLk|!^uTwuW9gQ+bgyB+IgNe!HH>zgu~pr^=nYk{i73Zr0(5MO+cYwug}^NP;}GyMzIF z`LqpqF$CLRM7+!xY^{wd#$ceWA#Jxf>?ua6yBVf30Q7b2?f)>9JWuN44K|&}*rfd2 zZDQJIV3v3<9F&jG^m8tvDh6?F2! zc_lt`9`4dk@8hNNvFzX7o&hj2$Ifi~_Jv$F=P$ zVjU$R*`Lukg$mqq>R`^(9hwhvrZpkWZE9+3ga91DC*?srD!SQ+1!!Vj$s>ME6ytx3i`Sk~Ejjr``*AZ_|&;>*x#}_5oYbW z>h4(lBq?whEZg^XcMNBW0rYH4ZqD$CPyCFI1QB8LU7ZMLqvX=>SLI2+M(3>Hb!i8f z7F*JtVW*)~>*Hv68C`9b(T=@wW6go0)|-R&wD{1erH9(f`t`L`w`;RRqMjR}(B%o< zL*SmM0V{0nYC;QcenKzzSH$qBgmvW1avtnU`yZO1{S}(n>-Ye=7kYD1+V-72(4Err zsd9FabV8vwJ->D4jc&d_9EG~-ayzI!4;$rVpwb8=W*@bBy#KnvPW?yb6^#{+b5yO` z&Ll{9Eqjm~t{(Jdn5N(HO{CsCHZ_0$0+?+FzvZ!EMbhF zdQPpNXuZK}?s3?tJB2~!^)=Ph%|qD(eG85>t_)sjL-p}?G527FdxD%(?~K2{Gvuk> zYs$p#+zN+E5gsR&)X=#|+qMA~Ssf_l;CVs)4dKjvM0lY|(=K49d*1hRqhT&#Os+$X zu>%Fkx;i{aeRsoiBcTLPyq%`rhogMzVeDty8;f7BfT%aWa z4PBiS5FagDpucA2@JBpVt{=7k;Q}u^_){JO1_L5%;DCqCGF*R4T+^Z^?%$BB@Rh{; zMes25dn%0B4SGC(to%H3{V(7V&NK>hpQR8}J;_v84{jJ^jJ>%r-!yjn-v&tgQyuSutS{+#USP*5ubVndkZ-n? z8+Ft(I9_4#L*b0i(6{dGz0LDeG!`T`lt?_Q+2|~vUVD{UzwlIFl|t3kc9dR+^yR!7 z&ljH3?apg#Gf*e7m^z%;PeyCnw{uP_8Jr)RM;5tMZA3(V>AZH`iokHvmHBp-qQDNq zJ&xWS>Wy#3A|6@e@b~G{+IwaNlbye~7SIPGz~LRUDwbb{Zx{{B{O#KC4byc#q_3xz zGMN3u^B;x6J!1WL+`6E;So^drg6GlIbqc|A9(RLwF^nS;Xvf(O2j-yJp z1uz1M0}u_D0o_5kw*@O)RGy#T%ehc#nCK(^%9_n}j2e2%@D;UviDeovWJ;|7Gdj?+s9pY?^l)JlWLs;&25E161s+BaUUe94;4y6afC z5$#llYBELiPhnikJ}$b;M+5!!thWGf(!Ss6bPgqNr(^Gtk7P(}0i-y88B3Hh-tV(* zwFka26M0JM?io-VFcb7CKRhd>FTnxv*+v_*NlZ1pd{BSuD|B*+m!$IhW;}7RF`X|q z2bs*5SZ2O4#v({*E>2vJ!V4Ko#xNFktOBvy0QM2k0M$#+_4oL4Y6EoMV_M55?;CDD zUNsx9H*dQdAdG_tGYOSeTY_&HJc4Li*blT_wsx;%5Xsxuvu*dVqtw6sy(cOHu2NJ` zBi%lv+M(yrLVwx5*Za+nStGN}Tj8M*o(58*{KD?99~ZNyQFyWmgdf_y#e-VUMjuAw z`8*eWc+D)JP8egX$k*XibJd(@AJt4Ffu+gj?lE7fyr)wP-lNF-qBs8~N=!BMzYoLu z9WFVa=O3)6a%9qLMO)d)I$UdiygUs1W4$yPWi0bCRkX_axz(K{-px^dGkR{$Yul!^ ziP%kNnwc)&SBl8E&M`{?ZFC%|HD-Ek^s_iiLF9%=kGmOXIPTs5E9Kb`0uz6d%-HAP znO!YoMdqpdYrygDAZQF10B$%-IK)^~Ro>j*n<`;P`~ZV0WL8nM&FIOYd%&kbqK!AK zsMZo5;+*X*AW=b$Vq7s&<4EyP5ncWD9${D2M&!Jvp&{FJ{8(uz+)>dN}cw9f4 zZ;NJZn0V>6x|>HeRaT=pLT$3uQAfnp;?}fdDa*La4$NcKr@N=7TWqwSo~AFWdJulq za8pZ6aXpLbh-Z9pAg$co8d~jJDtny%|z)C3qe=>-jc)0_U0x*wMKF&_$zm zAXBa}mG{u|2o6iS{(X&w1dclRo<3gAFkk2A{t^zo@r>D-N-@buia2lt{=&c!KJ_}# z8IL=GjyrN^9upb{n?y`TjUBP%)G#38W=fN8UtdjvTXXtyzjU+qwB22+j*)Ly=SxmZ zsWQ(OB>W<%7}zI5Hx0RT5*9c(PT3aR>V+2!K&eQ1ZSEy}m?Le6)ulc_BfoY4LuU4lT`ArVg~;CpBN9)l zfMN@p=gLUsTexAhTHRYtU?MjWmpH*1ZhdgfVT_{>F%4)vVLi~goFN*Z!k7&+bmi%@ zMMNd=jPBr@OGPRJ`BRku^auANZgsc0V9=c9#_wXFGj!`7sea)(ml1gWw>VLBWdzZ5 z&Au!A`D^$WN-LXf3 z#ebpyKBR*3CGv8g1>*vo$m^L1K=oDKA}eJU3r7yZ+o9v%|BNpEu%s?Jel~D#is{d+ z`1IvwN#6hG+x}oY&e#QxAlcNuZR1Y zVzCv>*CN|>@oDiqezRmmat6bj01wQx+wHK7mq{c*o~xQzO^4eEaHE2UrPf}u&LCdx z4K)MQt zBf(v#j7y57A${K|%dR5+uk2;Q-a&M633wpa(M;X7@e1IXwA&)pbsbb#fF27OCEc1) zFcXu<5<9b?sfKNGm^4fUAZ$UpH#HK=thP9^M%ul3m*vZ3miiNS92p3)SB(e!T&y%i z8RBL25iJEDRw&8W$|!Tz8Se+WJF$q|b9MxX&2%KEi{z5~w<|h>2Za`Xxj-$NuhVP) z`h0rMuZwPD=ZSc=Yr+Fv6hh;q4WhTQ2m zx-Ar)VaiSol-lcNZafy6$;X=Uv3#l48u@A=9m;G%%e%+JbP|J8mCbSI8~ZsYpk_5O zKM4~!9mL2c)hPe-cFJ56Z2s~|fk*+J)}~D+`p9y??tN`mhj$9@ z+Us`uIxyaySuQnvvHP=U1$OV)-WtwOvofiS6`%h(esYF6GHJub^qT_&*E4BF?cFr- z2gb(X)nwwo^mRKATOK%E03kGS=s-5K zbr1ArRMpmLvOJw}**zHbe(|ItkCW#+g5HxJA3GOzcOY;~kC2I?M`Rw@V_zn;%tn8X zXe8Vwt(%P}A`w<%W=8j*q8(v+_;Y{=ybh2GT6e)KRQ*4Kd}{|C{f>tXxBMzh$3{f$ z?2D94m5mHbIy0{DN!AaDUS-}U^P`wk0&py zX>7X~hKhDghB4Vq>W2WXt=W1Vw;0=&Zj~1$;MP-VkCUdpm~Cqe1W7 zBZBNgbpEnEX|CFa4DCi;gQ>j+%Q$HH>kY_%pj5)dl-}UDx9@*Q&-&%V?0|1F$MA;m zxwoIb+R}G#aJ6p3|`)>bQ5^KqrBCY|==e$p6r``d;xSj6I?c2|maa292_jYUXC zZ0mi^_*iKl#dNJdh%A+tO{QnG7vZAijvcLPsO9aHZc~4Ur1ObtVV;7~^f_&ZLJPkR zovs!KU~!*{iE9bBTaq1kCckGsdMql`4p5^Gy%%K?5qV^tfAj6))Fd6BPxr%+Ltc(2osJ~|w)v5O z9<)6BjK4D~s7gXni2Eo}Of3?4%9fGqQ?@ZAg6nZvyurQ`IUtxG{3c}TsCBrqy%+NS zP-TD}QUiPbK?qbYo+gK_&K(2>?#Ct^0I**Bdw_JfrbL4xssHyM|FZyEYhn5s=cdhH zDdC4#htG6U75y-I-(RHTCAV)yq`$(@>0pKEfsmrQ^AI#n5aHE zFFYrs32#F1SXXVu?L6NN^yqW1J3s`o>_4a9i)uc27s}g}S*!HWdwppMKd^kQvF| z2oVtr5y-euGB9%Hlv7-s0*;#=?EplNT{`{60l7Og}2qUL^r2s*2Mm)pf%Qc09E*K4e6XJsR3xz-Sf~v2_ zbN}lhp<{O)E0HU<$E77!Kp%>cV(_yLNE+p+`luDPbf!9OXb+7}y0c71CP{amec70y ze*F2lm96Ji@&0-+dWglvc0k|}Z`R`VGqUT+Y(p#@5oL8wK00>YYC)dQ3(YjG15-9s9;h02F*b{JHD?aI|$`d^OMIM(5%Eu09(+yLYR>YS^D7@=mT*T8{et zL|J=nJ}*YfW30IPb1C1$(+R)ukXSb1bA~FHkYg7yBaSe58VE!Wn-xM3RFJ(C+AC_m z&O~Jl5)$arHh<$s#8WIuGR=T@=sSTpgLv<8->K5yH)GTvNDwtomHwK3U47KrmG?x5 z5s?v#Z0n6ypw?Syl^3&G4^5nD>4}|Z_%d&H*r(H`7wUjRde3pk55rU5KzTXrX9C2k ze)Q7W#jKXun)+OuM^N@JGrhb9PEpqLnE4 zXP^FX3$|<-ob@_AQN!J4moMp##5-4_hgDsk6+ADo%?a85hQKq*Wm&3rscS0JN4Oo%bI0A~qNPN2*3gc+qX z>(Ru8&RA512#u5G!mT{XZ{Dl@n^Ly)z_^BKkUU7G@d|m;?nyfRm&B318Kh#N1og=K zSC3ZQ7(5yniEE#=yO=~Gr@wk0K{3R9RjM3+*y!;cfQ{~v&L7Lj{WTO0`*e?Eq}*=5 z@P-y@$?8;IlQZ`*S+%rhOFUzk!tdvye49U6|8gkPwjks_Stk3)88+&jjYs5wZF$+G z5LVUTO|9zduw}x}(akhNFs$8p13H!T)8SvF^GHU|B{iIkK*l|=BMf4eB@d)Zgc^bTaD!>%(~;r)C0{2vlJNgsvH?w~EUlJ80e4#1L_}PG$@L z2k3zuWNa8d`(x;o-!1UJZ3w4J``M z@cr~79&EISJ*r)C^!*#VYri2y@lf^nYH&Z;j`j=lrwtRmL6j-1p!QcbqiZ*WvwwF< z@Yfj~*Gp(u+sw#tRN~kcCtT2F2ZK>;*MegD`DAuC`Pto|#@gO2vqq_9y;efO*UZ`t z&a&f4%UtH0nL^|x9bUcH>eKDV9gMT{)JfPVc8IJI#_?p-SSB{YSP}3CImhv~L`F;P zczOO~#=suML|$^yG1de6qsF3iXBSfp<;o|&(%is*)Y+(zt?iioKR)yN?g~I$9+zW7 zdpZ3(7;NsftGHQ-7cSNF|L9!_i{2j~vVT{ecQA|nm^MV!d&2mkKC=dH;3F&sjp#Tq zd~n2J;6n=IPbNno(G?&CLPvyAppXnP(S+41yh&zugbS$3CtgU<^cN6lH^17)L#iNv zocz8%d4!Y#ZZ=asKDj^i!n*`(Q4#&63ExTZKcQ$UhKX-TjiEgS+}fXbln?|z$5kc9 ze@G`Jz3ykGNElHjb59e|n}IvDBpaL#CZlG=Cf*slZwqG_N6f+D3=$|s5*#&|Y@Iuv zrpg=LeTNWq@I;}ufGx9sXP9K-L;>Mu5w`Yiq$A3p@mRcw@f zsESX^!L&#ct!eGp6|VyDB6(t?_L&Wjq#Mj@7uM?=y7n#sp8M5lSa#8DJCmTXPNb%0 zMYTKINPh0V45}S#F;%Cl?5r1Uzdqdsw|7P|zCD9Q=!ZCl7zk4?;9eUf#e!adkZ|~R zMmwmp*i-8rd=nmHp3U9)2E9SA1`3Fw`Jem(;PJL2&{$B zn!|x$;D!x(+hlXZcn0fRbi%l*V}tOG$KJjO!DElqIi_k1DrWdS{6XYdc**uwZvn)& zH5`QlHGOTYJpbZmAjXno4-hApRvnh}drBW>qT8YtPEWP+$7AC)`caI}mqj&_%=0?- z!($?q+m=S}cUHDkZ)Gc)k6D{w&G+Qpsy!;Si!G~Bv9~XE?3hXsa|J2r>{e;I>EfA|h~L|*V~j|!s7GQ3_MiU+dq8-<{K_i}vizHZdv0$B|0 zlTr&<4%4)AoE=IIMl2x!MA7MZ3$FQ8e~dM=uH82hiEh{aXfECxrP{PP-%tk-dlReJ z_0ESLc`2l(Gq(f_=D?Ue-36lYN<7<7+sjsy7VRT8nB>AKeKSlvHv1cOsCWBKXEJ@N zn-7VP)Z=3`p$wxXrP1jmGNa5>sj|&PYLUm(>-HsBfu?YRBmlTDRA*8u-{JY_XNPQs z*#q=n2g1LP&T{{H{7%PNt#A$=qa z+P#N!BleP|&5Ne8v1{L&x~VmTF~e$^&$D>wxx30tKKsVfYc&*`sI_7;-Wo=RcUjJk z!BbDIMS|LT7=GO(((k5`t9hH{G5T7(?P)!}86TsWW3&7+cLl6rTMUXz!ui})!*^KD zl-(F(K4$=V>N#KZ8u8yZ|Mz7ll}Rw$IAr4C&p!vmDDQKe`y7Ns%L>m%7w2;V7A>gs_`V5wrHw+Dg^u;x=_-F; zZPn!bO-Y*TmZH2UmbEF=7S)?bt>022joPWyckkI~pJ@zDm zQg`2jCHZPO_P-84jCK6kr6QH&H@Y4FT_ZAPZ_-{k{jh&&8-X>TFl(Wk+P=xSc*w7I4V0I7Ao}}u zc$npvIfwan;D1W1iA{S5Z-24f{!ZGn|CPu>(vE~udR|*{dvvjfmVeo8Rk#Ppss_b8 zFVw)wa38dR88}hH2AYUFX-wdu zKBp_8e%5eM6?i?@bSVh7Ra$!QXu_u7iL;?=>CNOry z+|pWt_(;cp4y1jKBIW^eW_~!!uKU4nQihcy^@?_91|R0#sJ2X2=KW~mA^kG#n|Fgn zsGMn(?<{tOY&4#GazpX$YvpPK#}IxGY)T`&M-mjqSkip}ke_ujE`w+eDcq`{7ouGt zLW$`G`5qQtO+=LN>%MkP@{t~(or|_r2D`Y(imU}jyUw)Cr z{UzvP4$Oluseiy|AC6+>c@aV zDZ)kY5RVXkRO_E!I7XARYgsPH2i`uao{&g5;)%Ue@lgK%Xa|0#Cla^H>H^{XrBJ{~ z4*1)+{k9vqaKK44YaW@CnD4^8~kKzsN* zP+(9K5UzsyYWJ&DcW2FFn^<5%34(3MgfA|*JIoyBTukR362k0&{$;f%yzMoytEGP* zAu-@3!NjUFGQ(K?{QFP%yX1oG&R^j6V!E&}Q}tB6-EA$0vrMvIaMq#jET~TE<>u3K z9F;@V7|rvWn(UWf_!Za6sEACoLiezdsSmzNIls{$c-Mp}rhKe7iY}S!dn81>l>NcT zIzk|tZkaCo^dUOALTqP)Blqqj^vau5~34P_t^D%J6Vro0PA^Ee5{N^36AGJ`y$aO z;T!VXEJQKooubD>JDAMl#}je_1_FwJ1pnYqMo2mX4Q37sYxl4P+XHgIFO7*Xj#VT! zlDroM7pp)e59{j^s;0nXFsnvgrfgcs!TAj=hoC2XMJ+(WPJQuEUE7ghqcwUh##gI9 zher0a&S)ko%}A=!$mG+}&knYlwrj0kA>K|K!C`S?gy)at!gi^e&*hJ&>T@_;ojq(z zt1xT+O9gV$EK&m=DRDR$@c%%c4&5TiB?zFme!kgFF@|L~^$YPHUu<^SU7r4>i|!JS zVy|A=O<2s?ge+hak|^%*ShlsfbC9;!#MA(}^(I-H=mZqDlcva?i6=X3sD~OpC`1<~ zj{L(Zo~zIngcu5h^n2Txa~R&6L+#$SZ~n_1S`RuTO;6429V)+Xus@Pp)m`nyqq_^8 z@r2WXhTX*6l7?OmUI~#iy%4$GHt#j`XtH6lM1Y2w@Y$a0$4Q7N#4nlTUCmX|MZ+=j zXcm5J3I-)Y^OqeFCfJ^Zu+tM==MC{U`1Mxa9?ffmjX8hmMS3sq*-?4<@HoxKlbMg{ zR;k_Pa?!hCmd{*_g}sG)M(D?(77{M`c6>&SE!;+r;Q2MsM&JaxBlMF68h9o^42m%N zQ(#ey*(kSg*rAzbP)@iVx&poFiorHtl)p{y@M@&M z-+IvSx2Bszdwf6KaC}0;G%*4jx7)p&U_2d5Xo*w;k(CjPhSOR)swEQW9pXkj5ss!b zJ;|?x(@Bp=s3?a=jLpx$YTq+mzxpXe9mFl4xlFtcDp-E;v z7{=JE?S0J37Xa(9JfHSODkAv^%kWV`(s5D?&qSN5;6(Uk zIh`R75gK8S{pqW)g(F4?)Q;b2nx_8XF@xjSY^dMR{BE#nS09yMZq9 zpz#0H2i!XllNsE1(X&wx1wqorJ!kF$l<<@v+7{?(K0Zkl`Tg;8T+TAT-gNdQQpY2^ zLiESR3ndcCkszO;Uz_LGWHLR96gt*4T;CM$YUAFxTgg6D>hIXE)wB6fJi&$1@@`-Z?; zJmkruLuIC#77I`YqI%RtW=TjWrEfEkC^&k>DUBj#?qTz|lxa<2+EdEGLb5j`wmIE? zve!?I!NZ+8E;Ag6lsrB0cItjqXW{Bxefw+9~D;M^`?f@g3Y1zT9$YSo|i_ zKu{Hb8QhhmygZ(p*G;ztpFCV3ItMv3e-QC2NVqAQjeuCqt@SJPS*lP{8_(QS!MsQ> z)B+(mj9=Jx%mye#Fg2mSJ&}x}*+YiKm<%V2^YR64A8yw;!{`w#P?%aX->cjk~H-9R{v#!&3 zA60wMc^^G=yPf5{CJv%JRC9H7@vGjpZ_NDxCeUrJy&`;2CA54ju^ zLDU36p7=DBjO<@WsQzYvGG<6Hc7U}Wa0g^Uib}){Ou!ujwmCNg4(oe14me|mF+CeM zA3xc3_-Tp2o;#29YL8Qdjjj(k;p5I>24z;TP`eC!9gBH;%l0TRN0Zh!sf_8=Oh4*5Dc zzQ9JkMX~h0j&Eyf@p4)59lEnoU`9yRY<_Q_?$kf1h9qK?angce&_j1I9Q^kUOr{wn z(Vtp19gwea|1cl724R@-<6{*L6;grmC<@@~RXBB*2PuC05m=F3cQA0VnHXFwSIjJ- zJ8D}T6pGgjT^Fx$!dR&X~|} zw-CTxsu)8S(0C-kFy{zxO8^|b3%&hWNkMo4U3mybxW{sf6+CoA^%zp8@Cg1@g4fD0 zU$fd^EXWv{je*`$EP1bt!xzPpeK4;6u|4>FLp$HC9ie}*MlutjbjA>bY;$s{EXP=Jv1EU%`J;`1sR3VI)jNP_$-lmIwkH_UXP+ATKuVX>D0eT`F z28rbJp>j@)aX^@D66AaSzR8!ofBRZfBH6jn8gXt z!Z+JkqCF`N6ll@@PH5T*o&jRh^zT;kR{}Zg7T`bS#@7jQ_yaN=8-G5Ke_Q>hmmD8S zj9{@lzW+8vM6e*9)|o45X4D)E+oA#+pDs@J24df%WMU~{;?o%8k`)xDCq6ucGmMna zvKJ43mHobZPDBrx2zp7Hheu3U4Ym|oq^%QF&e#CUAUDifs&^7hQFZ0HQc$wxnYPWn zWESmuD}L8Wew3E4QPUG8n_@F)kD$x z!_DAm69Z5|7nTzNB!1il_g63nVVas8=_67KWeTeN-h!L2- zP3m|7TZ4}Y8_k2!On zeFL*mu`yANTFAMmEEzJHbVZhCSTYC+oRiASADRBBGTMA}E49i;dRlAOBB51s9sh_I zjb(8wmE3W^f|BGp`+Z9ogcslu27P^w)qOQkvNOh=KI@_g8SD$a+I45+9Z2xG6)cD^|mJ@!{T^mqYB?5)WOhc%|cJQIzNt(Z{f!c5*Rn;5rH zFd^;cfu#C1;{A-^wtFdmrHY0ETf-Si2!fyEo&8Udi+y>HcF!0@U;#{ht-I3~^EaD6 zy#jds_f4Yw+|UN~ypBF1&xuhYsf6BhZAZV; z^=B)aj^z@$=g7zK(W*bqJHec4n4VG9UTkW3R_p*pSAAhgjF4V*bO17cIFqP#aizw` zA^gj4?YO@psQtURTT<(EHuJg_83(7sMWNhEhqK0Pl-_pi(gg9#q!cXHW^ny6Chd*h zzgYb&4)W8>CLCZ!nwoLXOQ$$aq3I3*$adW?4X**=M!gXYJT1JEZ_*|eqYbtFUAuA&Ib3(rL2aw1XHl#2Jp3X>9d0E zfVFF2v`jiwE50}K!&3SAX=LPMlf)!yZi=SU4R#|hakts76ceJG+}y~x9j2ZayL3dS zNWai=xI}vtu`LEx)J9I2fEVON;p0|wIjq?U&w@95t)p^7N{eXE{0Yx!0m)kBwCBs1 z`9c7XS4cPMB{?1#>2lzFF@Xa;2}YUh(#SHljc8twvuI9Wo5TKr`iYSoDRIn+0|M-k z^lS+q`@g=BF>`mke~gM*TO^o&}e|W^P2}@G@7J zPU6YO{(^^6TldGcWj={ArScwM&D8hK&~+coF$(ISDElB`d7`vWcvJ}zCK945H>H7A zA_i%FZ5rvr=R7beV2nvOcF8A=Iw(5P>_);TF#0LRA%u2$@OONK112Y9P2->6zkO2a zB$P?0O_T+G0aBQBR7rj(A%sE(nO-WCD(&w~e!rmmpg}x%5RRy4wF5|m_W@B2$at^T zv+QY7&n{hSa^*|mALXZKP@Elp3#QU9q^-=dRjb&me)OxYdRYlJb!*mJ?Vz~5ebSy` z%>fg|RF}|6G7d;_f!hZ29G{&K_Q7GrV_ly{zVqy%qTIPbUj;;w=SKW>oTo4K#g*{% zAJ2DT^d_`KliA?F2Y{r=SFtCxBXtqh3`S6&4GuyEaQ@)UADf-{L;a1&EP@jYf-FX* z=q)e{X9tP|Z0Oo9VfMCWvOvZ8?@Lv~SMC)%RdF94nd6lb9x`Uq)RnmfcyRt%2YMrW zu*4E`G7-dg;Ft@JaM+H6o(v2H!bTJ>KcOfble+b@;FP@)2O3O_EhNyvKnl^2ayjO6 z#9H1aQ<05PaTpQM7&tHjEJh)UIUh$hR=)K*7`3vILZ(NHUF`L=TDhZ@ruj{F^U}%X zlB>;gxG~;!YV6+Mu*1CRKMVQuT#m}p#>nTZcdi#>dM~4$%cGPD(XY|`zYk{{wJw(P zVK)TXN+>~i;8N&v0*HDO1t1&^_VENU+DfrnP@ft(M$)NGYnThaHtN0COlyN;tN)tp zc3+dZU@`d;DpXV3A`T-$?mW3^%)EvHkK{DRB7W>F?FIMa4&@2ufUdpC6X}hF*oJ;0 zf>Ni*u)tTP$+(^KZRhU+rg-}sEaxhb)B8ni79_W4sYad)%iLWy^z>9qkDuO+*UhRx zBeQZ}%}{AEDbF5qc-?L5{q?$1e5^2tLWy>Y|KE}_;6z>6h%Wz$@Dj%VQ7c6L05ya- zG*M)UYubq10nAvqp6G__k(ERPKvTZOi}vlJf4Ej;!5n7P%p{3Rc9YnjL67}4U>`r> zNwgk#oZ|@*a?q{D3YCBGy5~n&Dj~{N9r}|H#^0i|xvUjY@Orr%Bi}(RX#XI|azC2I zKKbn7n!DAcx>Gb8)$LOOthw_>!wj1CGFQqs_rCTFVdw^@c?Z}$`1eQsCcW8 z5-b))SoIStBD5X~UR)`58<)g~;tzn{{%ZCna}V)T^aXW5or6mJKhn@2FX2NA%c@Ik zSNu^=TX&rvOKzMk=icAzB~2~mXS3z9^0X>9okhQ{&O+P7{P!(B)GQ~ydCKIyT{;ij zNfU?S9gh(##bo;V_VL9NkuL<}?+890_|F8{&}iP#YZG}Bg`G=P=Wh{0F!cToU)A`~ z7F|}zJ92R3lU@RsNqPGpv3RR?lZQx}$+>!|Wl<+*Ja^d3tnL?!ae`5SE6}Yb;_cRML2< znmN}^tg@U4OEm27lOO)PB-8o>HIMHXP}BW$%^fHFRLWWr>#^LPhKJ2cbCJp=l-2(m zTqAb`W;l+m*ou$?)4fJnq9;rkE7Zog$l+_Tm=1ZNY^R@_S_hl?C`vA@{9OF!aSSo= z83-GOSjwpWo+$5+YcS!NZ1GinJ^19!?f?C}dO>rq|2kB-o;~T_o%Dv?l}CoC-vG4_ z$TIBM2a;9@!-KDLdE9dz!dFyGk^X~`8~BYX8X*WaoO2v5c=CMSK?UYHo3yx2ox)Y$ zGoYBK?XKXX=bNQ|Xc-SrtM8-PxZ2OxM$vG>Lh|s6C4&~PsKc<+pLIvuVKyr*(mC5g z3E3g1&4k^C1I$hs#-#zuJ?7*p;Fc*2{wEI#J-vb0x`AZsWS+1AatW0d5s{|o(W5G9 z5BsdtGdA-#eFdMxtD!wE_NO4^xGE3k3oa*RG!zL$+L~uVu%4VxnUMII3==IY7-Y;z z_YZr5p@jqtF~e$`Y=cWbNd)X}5VDb4(NI}C0@Tkt2_~(FYmCdx8qP->wyXjRhWu~> zhpFXaG4iB7jjCg7lX|tS(W~AqMc1S4dvZH_ zmm>0Xh#Ox6d);Zh;P}OfZ%dnUeLc-u?Nn}{e%vu(ufDI_+ikksYt>qV^k5bWq>X0f z_5B&eb1~_Zw~4{5&>Hs>1+BN3PP(D^aAwB-{5h1>p8WDDx5+kNU$)ul=%w6xn`Lt) z0`=aMSWdrpNAGQ~vOV2Nu+YGn22ks4BQe=@nG_@YbS;+@hD+C8lgb*35gQ52EO8nl zbOMF0r$6E$>s#k$d#yfUwE?c%Ck$i2L8 z28GA1^Z5EYI`#%C#!ghE7mQB=E<$ajJv=mYERLZ&!CyDHfgCS`;3+9=-*9?45~)Ic zeR90(6eLR!OxdV?qMZ9{cv}9wm_CtfhK=^c5Q~_Spb0|{un#wxgDoOwlZ?r*e?41O zAx9)?EDtz4MmSI`C;t&IN8whmOPua=4sAJMSBi=D0op^DK{KKxHHsYC-`2i=2fV9a zx93l7D^{|zFXP3ioXV#kRj0ami;VJW^Ci?v7C(AZc|c;Z(9^h>jTp6RKQSu3ypHUu zv8~15?QNsr90>bmxFvWZm_ej1N0Hm&pU_?K$^moHyBNyga1Wu6QV0Azy^y@jtZ?H&{XlEQOo+-4KSds<2 zGtHd$qyfB5bmq}zS{psQHrvf*t-shj4b;~dG~wLqWV78oh95Syp{Z2no!fgFkX<$X zEzwN4a`t#R8IP>q%$fUY(tslA0q-^8Gmo+37owdx_%rT53~#1?l$+5XijN!nkD=du z{GmLN>?Gx8@CUK1un^nhMJbMy^kC#YJ<6+w$2K1(XdA2EOM zCRiwYu)%Q$l^Fm9TVs=`+edmTsY53D-_xD#;~pw#Pave z=4Via+uk-J9MYVG{_yLY8O1;pc~-FHXe-7s!Dux;JJ z!VD=-9;;D^B-)u`;Nh((G;iH-8>F?*UqU^%6FKU-V)opb})bP;*+80 zX@`gVOMkWmE(0_@I=jn>;&I!6P>yqtpSJ{b1<}tck3w7wNRtpc&1ULrmmSd8)V~8AZ4>kSB7X~ztj`{QuXPbp*cyWk}h#+d)0i367*>qxw=5z`t z@2OpRb~cHM+gw)%sZ;@X^p{p?_}=O}(O51$T_xt#rdBReRB-^xM3IfxTk)5ase|{f z_d67!9vTiPib?QVY%SpTK;Q7(hrZ_RsvPbDR2?|tp)k?_X>z{73-AYJP_%OzIl1M3 zX;Tgt1b>}Kd)e@@?FfbfI9ZqhM#xS8GM5u*)BZUcx*5$9lDP0TF3UY8dAMQN=s$xP z!(&WFydo+l&S;%@J;?s#33)f-ShUC)a&92w1@3a8gqsT7hTqEWn)90nI-m#e+`viI zq)WwEl^d8auY~GcW$9A38H~oD=^mHW@0%;;DjNQ3lKCl=cy!JDjg;?v2vzLTQ0@Nv z&y1%7Xl9IL_50hWYu*LG1k4P4a~ls=Dc?<5z6#NZ)I%7=)A0>U_v#grgLm__iRaH_ zNJI(eNnRv0{>{q~fwUi%#viL)Pgbsf`oEDSAY7`DKc*!3DD49_AiUUk-R)GTm8{iL zd%5<5KEbv;WoIMSB%H`TjNZG2iu+>Ey49y)WwBG$o}s*M7{E-zH=wI)_!?plZbV!x zJ;8K{X7xma>s#;RUnr@hL_Zp$pU%|D{W%x|{9L1vqUX7KM!e$G$7a0yeZerjU~XT+ zXld73K;46}6Ty7m9QDe*^-%+vp$Ku<4oXbb3I=lbxN%)#2r`XPi0pR5Z5uL@0_T-U zeZ;cb(5jVBPa80MoR10GVllh6v3eMFyLSgJ%xTGI1XHP00*QNEOJI>e5xowq%=zIw zK9m`^*mw{@3`MYQ3L8`)6}+H1ITa?>h`VnOT$n?ty^xt)M5k(Wg*qTPxHPaTvS&GM zP0S^K`!Qn?w+Zc6ScGf8!k<-42*YEc-+H_H)hb4Eu%den?B5p}t}5_PgzU@mU7i&& z-=1iv*X)OgUIm?h@3!*Y}CFYE!R}y-iI42FF>Si+IFO?64LXvm~MNzdjMr=`+#23?H;?O1=gy)Wr?!~G$FD(j0iUDZL z=D}10rwKYlpiPGO3dn9)EDFdgs?~D5x)R01oIzDUD0G3ai9dp{$pdK287aCheLwaO z0B6VB26-4J&b{vCrk&h2c{B~N7Y1vL%5D2%iXE{H7`2#@MSv0%htkC+CBq~v$i*rN zy!0!0z582KA(vkk)_l^0%Y6MvC?Y!%ROBEvp#)&*pYXD{G4!opB#rxzBPZYa{gC)K zxgWmi9yAxy{CKLZYmU{@DTre=tf9T%83Umpfj`Q_k;^Kj95P^e?k^wk-SUB=q{+kY z4|zF#Ir=I_z4wL;hopk|wtHXp?;()dtKOP;MqzbghGe=?a$(T^V{^oRg8CGN;Y83W z8ZoimgsOpQ41RL!fE5bN$uJy9lraPE-47%vvK zFeYhyl-|r^&&%Mr8nj=^%Vb{(3OJm%jFy{S}fib4#3F zW&iD7HSgj1ko-}LTvQIakOaEyP^!zO)Fb!+Z|w%>Vncu?9cG>QWlO0jJhnr}bfg!u zgw9tx4sd*o$!te>Ixt$;>Uq$-yVx0zJDy1vTha{Ht^KFc9_iNVkJ#>Wdb>Q!I3?Ra zQZkxYgCTH1$Hi^dQ$n+AGEqXGVkl=A`8v}Ir;GCz!=v}tS|M!@%1=SN8~xaZ`lI+X z?VTE_a(S~|^=s2s+R>5^Zl}Gp8m;KYt|l7Q;o@PMNL63zkuDp`IQ(M2S3<`pN|L%s zr1b(fE{@Fo6NN_$d&xl*_R~$@znpA8ez^pPw-8nTddIQU1{oyo35!RH1?-v#V_=ZO zFbx_p0JYdMF*pfX#MP1_;Kc%+ZgC+^+yi*vh@Kg>$AS6Gemh$&Z^PaIQ#mmN0&&1W zP`vzzpHoAC@~aMAQ_VlR{U> zvW-Z4W?*gpeRHsYu@FaCa7Rr?uttdwK{zC|IoSKDnym zi162su3>40{{!%6VKAI-d((1o`M4-|K9q@7cT4?5WxS}n)_U?fY8Bzp&7ay?GyT|k z4Te__p+syntu8`lBM@vk&FHig?iSM1XFK(bXS7`pJ5xRK_#E#nQxEOl;=%BM5l*X{ z|EjUkE|xe)?JT#xA|$9>&>jVeT=)#d-4PS6t6yNsd*p9#PrT^Yu1%fLb^~(YK^r+V zM?c=e{Us=FuS{2WpW{n^O@;soajNoCN`&WD=1FO&3EgxW^{4E!mT9I7E$!6}hdQs$ z`#2VSN+l|zY*Qg=N)yDw93ZK{+4mf}= zkI#_*D+fp}kr~pAz4}4{NL+|#Ifqf=UpEdkZIG$(Epfb5YB?(Y`Cs5(UmQ5vWNe#6 zl0m;}gW@X$lrfMC0X@5_(thY>9tb6$XVr(y%b=$8pKJMTs+KG-vV-Ebk!-!|;SQv@ zS|q)mj-~V8XK_$i?U`zODkrrd8bQ2Sp?1URfZ^?!kZqaQ`{lthvl^qlVyhUveVxPL zW-S3aUb>u5%L(riT5t(6$GB|YsmbnmlHBR785Z@PgNA1&5DG+pm5CBRH9ck;P#I+= zpZF?O7A2t+5M(zW=5G<8n{WuBcgW{Zb@%&WFZ4+Ij`R%su|RPm>_Bl4j1^MFaxRm5 z21^y!w%<3&)KjXO`gM~@osZXojuCrZ>rQnN8pbP`mqzpc&8;;6i3jnH6>7-Yil*(< z^F=|XOcwxM5?V1LNn3RsXly3t1JofQiDda|ZUj^jq@oxd@zAqVhkf6Zq@R6-%tbR&W&a9gy&qxd}w^yl3oW z1)Ru-v68jGpz#Y`oDU!5X6v{O_flPcS9-QnYE6OT-dq*i?SXs?GK{qk!)9}leowQyGJwJfFY z7Q(A&VVy7@`boSf%tU8ZCn!rNXe8O0%+df3gG%o)H|xs$TO@9$poAuQ;#8S9Xu1(P zcFl}3Qemj+K!OtS$1i{A3KV6)H`IaD% z#3j6n2Z`x3#XhXhpu8);73wN9ZdwRRmk?m|hvJD$d zY=b&X9Hw#Qcxz-8O0!ix_8T+<3)6@Iel!ja^PLF(qquD`_XgABxWMe&210fq3~7q) zw&69Y4vt(Nm-DQ%H*jOnf2EYimDP=}wRrbFD~q{W53bYoX0i8T%o?GR-N+T5r=z7^ z94|gLPcPe-QQ`f`DfdUw+IIY|jm&oJCRb116sx71Vy(>oU%tsb%YRR>>6Kz{ z|Ms4#cOT#K+14bsec!qRrbef>tV}zYq8$fLr(FrCw-6@wYUrQZD`*mYLdIWw2w#T- z1ZwXJ?{KKbo&ve&N;USJNU=X&W+M)LQFbgOaCi*i(0|#}R2i)FD zVPq>IiID?hCfjf?~4JCrmh_#urCh>uwkhMc74eYpBxWa-1^xe zxnj>p`LPW4t_cA-MSro4d2b&10*QxCDA3)!_LAWzJ5gGuko=Fr)9HL0elM*@DVB3( zF++7G2@i~x@RpKi4B!>{F{<~=k6~Z~%l+7eY<;()z90(H_5Sxw8*mbuzWe8Pfgag< zgG2mgY(`MKl+C-b)VjluH&|^@G(aXXDfO*bI8*X@rbp)o~P3*mV{$mkm_p$z)=caVnAKhow%F#c6xoHV9(1 zrj6cU8@F$NVd^`7U?H|?Ylhx`dClo+F&rqli{+?iK4@=4*Xb>XfW#SZC)+bc4h=HP zizgx+$W}`DD8@(6!AT@JS(S&QMg8@K4-&J*!|D8J)FTd0p+Ue2PSbP&=u+W$GxO$& zgn(uEV5DMQ?&V_PRxOOw|8q(gZJUGnx2eDotk6t^|Lr^_vxW6ru0KydCt}P-CA|rJ zTYM;a$T@t_XYddJyGcYIpQNW(#%U!zqcXY*X2D$L%$FEzBu>og*MV0jS+~l?+{e^4 zBdtz0o^HIBAIs17(sZ9E$o?5vT#;;v1tYAP})=h8kXBAZyXgbM%DH0(h`DBB`8&bQi8?@jE#IW#GWEvHSjf} zf|99;XUlTj3cmV!Nr0AYMPh!!5prN1sVFDDe&f3%{V*Knu7nhS$2N37lvDSL*o7oI zljb%)iN6N*SzW8gW4T6qRSEZ>v`BUw>8{cfwI2=LB?`v6n+|no*$IO?B zgh>d)BWxOQ6WazHcp<;@UH{|xs?OTBUTDu2jcz7WF1K^J!nW5eM7wT2SBNb`AE7~{ z@=)Ktwi6$%Iduz^kJ7B?!E2w9o%)_7hg%1Z_af{i?jmeC}`Aw@SEY+|t z#^&(?9*SRQsPjmF4|Ni8W$?I3DY^UiRVt$t?`t!4QON7F72014NX?6!JdS~(=GZRt zizsR!7}gM0&>pw>vJh#Cp*zo-$IdLDOz$F=K=>517-6HeLIa6L-qanNOifB#<)4MU z7%gk*V)Ajwp!zvJU%!7;S{bF0(5A_)qScGDSmxtpFgLAopZm8C93N*6Y`owY=&%s3 zKF)#_3zGVh^xvQ=QV)?{?nhU5d;|QEUjm{w0~E#5Vpcp316xoOfi4>?1MGT5`BhH^ zRnSuTY8jsnC*fanM38SxhH7ggZN5*+g2?W&-T7guxOT$HN&6Q<$;peoEH+Z(nm*`E zO5=8;SxTq-jaW96c%4@2xkfI!o;1?yRX$iMSe@b1c%P55KX3svAd_?7@L@#j2BJ=o zC8tjq2?uUJUi#+on~g9skmz0G>tnkg;))GF-|UxZ;^9Iz#q;?JLv~&aHXlpmhrQ1L znRa+zOm_{Y0Q-GUyF67bP5XEH zoZZ{s3t}4CxDVg$0yHr(05P*ekQ9`Sd6KfOin?CAoGo$pPz5a)&KI^cX*|=zDDFG{J(Fe{{>im6TVUY z_s#6Tv>V?Zj9!d|DycTd&2RrBFU8~Hao-P2qs%q<8hxD+$5#{V_Hw&C{m1j|60ISR zAmoc1T}>O|R9sJzm<=Zdei(iN08z(d*@#oQ#A()|>0l@s*;lgIn0^N??rSc-IUYQg zxuV}x+{s>a4%$y3&vhU}LL#M~U-|@Cu!`ZV0bmLLS_BTO6GuQ^#ap$PqJA%Og|H1_ zkPHs91|AN)cF$*?@K7>`kzf~>$VT720RkIM zVnO{fD}iJqFia2wBP2T^$HPquQT1LO8Zj*M#wXueC4RB=J-nJvj_dACd6TK1$`5vR zHhBKm3gej@XtiE1`R5_Na$MH{V0hnDvb347KLKVbjKk=eZh!f2&!HBG!1&)Wg&^ZC zL6K#HJ;jYwV>1g_14bEv$#Op5Fx41!T<782E<;Gv(5w(2??dguam3oj*GfbvL!ytY zUGDkk`LX{oCJ$eplKrMgwZh)utI9aO7#GYS|I9f=yk{SH@~`GGoCcbDv%}L0kB>_5 zC2N%5$Y7O`JFZjEINk`>!8yi-OOK}pzA{!MVEpz)Hx*-QDVAt`|KqVW*uTbJf-RWe zHR}XAQA$KwUHML~5z?+r`}Y@df}Nk6Hi?fGb3{@%p!LFQ=cYN>EJ)Qybdc9wi2sAz zj8s09yNs^IGn0C~w=NDo!cVSkG)r~bf#Z*T%s;f>5{bVOU3{TS8?Q9ud=vp}(t<@W?*W$-$LhKMj z`^@0(qXhl(@nP_u57&&XTa3Hi+B!3AWw+Hv)#oCCtid9|rRqPoJMrMU@T6)br4VTj z%OCp28V?%a1IvE4h>cI_xjxGpi(pPmrusIn{O+vHK=}XsdjxU1V^7y4n!!1>(9pCc z`0;+Y<~JBG{uorY|K9M--o+=bS#=&Cx&Bg4g3Kjj+2_P#>zPA!2e+M02VdIVZn(0| zjt28aXONnO`u%R+N=(a}YOS#j>9bx~tELNsP>dkOdaRwzXDn^jDc_*%_;g3%jP`7u zuFQw=43>e6Z;2_8lVp`(Jo`)a``8jrDLoD!|M;c$-3{Ne%+0Ab%qXFA3Q9&r-28RY zgDFXDcl|b5&e%!$MY#~efVU55E)MOZjiib^id_!9y!b5_UkDc={*WHtmpDowEHhB!Juu zUpneQpmRg`mz``pA^hv1^+G}XuK9qBXDB{5o|9L*ET@luhp+y;oQ9j^mD7+Xb{3Gi zNnsq!PPO-BQ!5)CYZB~f&BAOR54FmTL~!)z6jNDSDK8I$E?6&k(Le<|H*GU1$=jA` zFfP*_gW;_bJz{y6BoNQdof}oO7rSDcA_fwOwiD|7wBbqwb5sXT61O{FNBRB&z<>7I z(_6=yh)Od{<^_;#2qr!FxdRaDMwl|=m?{0{)A`+I3DLu$wu=DVQK7f7W+U{Ev?|j^ z6v73mHJv=r<~N56lXuaY0~zfIfsA*@EFB)aZ%@}C{4ZYd8h_Wr*Kl@`U!ctPbp*kw z@-EmJO}ij=>WN+qjt2y}bI^<_oh92wfH9#V$kjS9CNuIfDi;TC!Vi&IhY9v!utPWL z{pt};Vp4(;BQqbl6HLcrEt!sk3c?dpqL|%bV()?cGToM(>N9+wsYO^MKNuC*I*=;_ za&8}?i>A@mE|$&JibMW9Gi7-M*yOaUzPQ<{U=?F+7p%Ob^4Ix8~+cE2XvAV z(wt<32K)7{~Px!nV-sJ5eincUA%9!73Cp zvk0!Vikuf9KA-A}Fcq7GppJaglt?YQXRb^*)5StWLCm*x)vf{cHg(6ZZ`-7=hKsuw zi~1$GNEV{JF#=#nXPGRC;0CY(b02+-H-W>>7LZYG&xS<++6|dnK?P*mq76TF4xuE_ z*x;@j_VXn2U40jO@uk~?Hb#cGMj#i^>d&kIRR;FE{Dv;6z#>~ZL#e=;LaW95$mN7x zr*L?P%?6>j`G;2^*=NlcvDO%$A<=;`1m{26R+*UwLmZ@<6c!FvSe;vsqH=iHG3Vj5 z1N1m|!(!@=2QH=~*sKWR$#Hm34(Y|CF1BiI9lt!v)Q}y<7El9?L}p_6sy+69o0c80 zX)25KaLZ8pdn=t<$NP50$={>*iCP+%4H`)B=H%DEV>!sad-y9*wf$CT*g;UC(cS!K zcl;I{yHcGMLW8GSed5MyGi8H;377I zZH`4IOiU{<#KqB^!6!lNe!&fPZG?#eZd`;-a1;Q8UE1+L<;5*f2X`WS$D>^kh%J#+ zmvtwpXCSa_y6DizFHs9)7oT-=}g@HQ@X5-yqW^2~<;R_zxdb;xb zxLUqHj6%!o&W~mfwI_}cITD&(*Uyj6pljUUG(N_eWc+VS5m-A6Cl83~ocJ4hetz2~ z!?E(%HQ1-K!OqK5cV16T`=#MizK8ZGTRl9mFc<)GSezHGQ(g)!;C@?2A&Bc#`JcArLk-jg#B+?lmPhjNFedKR< z16z~hB@kr;tDdvKq=zx6x3f}w@2~dS)07^I77RUJiG~t|5JAl4LREPhSW~O&w#F4> zwAIQld8gl6mD+dRmsPZ`1Q+F=@m{TOYsqY|>P9b-Ih@rnL{Y_ilyru+uoyt-!qh9! zDUe>>7NNU-FOOgf6E=R|%m#~ox|7*xTBiR#8^u2=E5-xm*HtbZ>1E$P>e*gCHEXN~ zGkw&xQ!m#!{l{MC$ZKMRI0m6Q-IXs}gx%hJqB9YklkUzRPaK?=Rg9vTI(zJ^MPLIY zOzl4GSvT(L@*vA1C?zQO>Kf>^zeGI#?SoIuMG^W1EQ0Ig{T)qe`GDwd4U07o^%eJc zobj0LX>CzsXyl=W!}wpyc}?6&I{%Vd{kgV!jOS3M`5HHZ@l>kOj8whfInHp@> zxyIL_F3xaI^oFe%1owiu*^lBFH(~aF6{MzBlAw#@iTbxE;rREt6EFb%$i?W^Xi(q= zQ8yev$Ki+CaWx(F?t9oZ!q+HW)z^LF>s>f~wb?ClYpQrn<*d@=9E>t=1veE=7f`C_ zbaM3B66qr3C4}FQvn2!dj7JK-EJ4@Ij_L7sS{TIcKDK))nkk6BR`SO$c|IS!wR_;* zvk3>H`2Vy*?>weR zlmvmNa_OarAMi)#w~REn*WynuPHv9eX;iC*DKi^gk&XyP`{7VNC3au;?c{@n!0Z#p z^(qm-_!L3GV@-Nx@x^*2lF&O)d^aS=SG@MFt|u`9a?6{dQ{NjS8Df3Llf@T!^-Zz# zcPS9xMhda`Y`5E+FE9_gZ?Em~jK>cd$-S?JggfZH0U5q`kAqMu7cb)QSQ{LxqT0ku z{KV^-#_GwW3WiiTdY+$W;=P11 zafsR_hzBnnI6Ir_k{XFlgPNLUP)8=)lL6{d*O#eS+Z{C}@y6u1df292$ zqLNxI-4tQ40aHiyYcWH@JcDj4vcYB^!VInR-uts`AV5f!&)N6xU6n9;c%HSs>pOfl z*D$mdn|(t?3_bV7KJAVYC(wgL3k4KsRkjif01KZ+z8-18h|Nv?pXFgw4K_zs&T55< z)A@Xp-Dd-pMQOTMW7Sq-5J(pqAA_R)`ccee?VaW#jyo}@uq#naU$D!%$7h8_qLI;{ z;=t17XE5V`{G;91|5k`hlTcUkZ4eq-$eDZM0A#?e!B?F+xvLx@oAMHfQ1f ztFudTZe|;Pe%a*yR7pT20HVb<6)fc`S*xN~9lRDQyLc%$j=k=Kbt`3(ypwO0*3Erl zKgo5b$L#26S?#R%Ord~WgiqfMh2jSnBnl6p`kti=GSLf?LSWZ@*PIb8d(h9PbP zJ1Iq1X$tFK}JYhwpCZ4+SV5`Q2r^`(m&tt?=b#ICZY>kMk46Hr*;JZ=v)a zr1m*t?Tl2m*=zLuk@+xENKU4+z zExP*W$NI}xq1uy|RDJF)+VjJuTBQ?%Q26I;65NCtGlm60X6L=4`i0KFu|MvOA=_!p zk4D1x)7{d0^;$S`GC%H{x3xr%IY!X%!>$ebEDPyp00Jv-pF9X7AtT`?+4RTU_jp;oxigbyY2_=k4yc zR9;2La#KDYr?2Ll^{pKox60Zu63@98M(3EL#pJPoE0AZz(e>eewM6Pnq?Th5DkA74VTt0&G+>RN; zVe#2Ww%fyEOTnVBRS5Z(v$x`GJId!<&EC=XJnWAFEvMl*waxSD)#{I8QEiZ0tPO8^ zm`t|&+5V~;SZ5H`9}DApKT@ms&8F`)x1W#0;nS=R^A09wrxlP=Z@GSFwY$3cvDl*B zMlbU7zSnhbCVfFL=c!}i65=HLDI4*J;58pD&yU*;Y;I{hlo!MlOVfRV#vbh)9~%qvVEQ ztmy_(-YBl9ecjwp_GiGeg3KcpYAew{?tXJgo|I)WQN<9r7yO;`H4rEu%-@ta?{V1wXz< z9AXM5rm+zcrui7;=h2MPnlb8vrGoiPozUcRB@>CReF>E*aW%FmCv*qv02B&|KV-U8{>L>_UQS`*1`A<+6?Y`oN=e-xmy{& zVmp_o@E+_{Ah(1$%N}~RzB;?BNc94Tg2w=yvsQC9^x=6J z>=F6M#NH<9-3-s6|1(4)yy}W&07+Mlx42S!dTg8j+=+>p+NjX~8FryUrmDmsrmLcI zz)!6!Edv|H)d~})1;lmFM&KUr&tfa+)?(oFYBWm!#RN-OUjSx5iQk2zrvotvdVBAl za!q-~Cj}4Opl|Id&846A*hm z?h!wC)XPjaL=)2MLRw`+ZQx=H?8C8>KIWcBK*$R;Ni)KxOI`+~X@ibg!=0L(I+j+c zVO0tl?tyRLYdR_$jh706W;C;X07HCyI3% zV_QH4+r8wPvotOrHDAU!jQGCC(8p%5Y+I3WFw#Ey7llsP_~*5$9Yfa8>-T;PS^om9 zXM8fv=`uV|j1u$XE|B%6*RP9oOMS})Le09OUtMaL05ebG%YC=W<35V`=_}y+aJxRg z7`LS>tmypil1)C~rlyqQPPVJzM|ZNc==NjagUg*<1vzgFxyWoB1}_O@Ly;b-Qus<^ z?MFA~2X4pF8jG6%W5)T$?t(5%{A+XS^TvGcjxe_4)#LLUS~s;Fu2L6Kr88x=qaT;6 zo_?S)=31UFVcFT(;zPHLbHIV-$1Nk`mwbcvAQ>;KwLoVbZj)lr1==D!0_h-M1^#se zb0v$F#Ue>B3?d_IlI^di;(jgn)i+xy(ZqDpFnnbnJk=x4a^mcRfMrY*vG?Zp*9a8B zmI7CN*8YDe9kDsPyoq&_tB70$b&Nvd1=tWuaBg38O^O6y`kC5A_!e>f!a;#?W^+*P z$Tz^Wa3n>kgxvR5wuhG_ZTXA#K>6WR{#YuCfJ1<(^JCc~=3lFN)LEf`Sf_N6ZNfkn zAu>{L+szlfwc60tkJ2*#Jm~aQZ7~S#D^*Rz4bZE@pfgMjFGz!Xj8ci2mKrc5GJ#mfi+PrWNuQdbua_AUJeM^B z(dvMYFVr(E+U`b7=cfcD3Fnr5jv)aCxRUZI7BjvG6neZ(DHsj#A+Q}D4>x&+F8FI% zg=Z-GY0Qk^nQ~r(0p#Pr(D0X^t#-J6d%A2eOBlMd zKF(0R?tH#@Svz~C2(SJihn381!8UGIMn<)Hd85=*r!JLDJC8p@py`Ra`SnU`J)dGH;J`L++xDObEv(Mb!uLfR5w&Qmf zpKugMoH`v#s0hvm3h-gz8({8n=ZDq_VhW>qQz_1B<7#48nQ4YKtfU6z`0*{?w6Z(Z z8jmMNEtRp_sX%Mpd@b5ouY=anvLl#!fo&-({{v7>d1jzY~goaZ}{%Lc69edz4o2 z`Chj)WcYj3+xIQ<)tXFp#5A6}#?YW^L*_MgT|iw!3cm;Qh_5XMa(hnm3*TUA zenKcKQjY!*c5{AGNG9!P%|HOLrU-Be_mr05ei@|G6+PI0^`ZQNp}0fZ&L2tUft&ff z@!U>!$D`QsHCV_B>uxX|cUI4VkJO+IvXYuF4#`7qotvb}(y$66LlVTVdz~L9K60cz zf_h;=;uGx{n>5mGrN^Sh`mcSGzJ&^_ee=Zy%#>xp<*J~uRKtDZo6p^C03mE>WD+V& zCwh)=kZq=h2%B+Y`l8DA`w5TI*&^r~kSTFr2jM=!ykl*K!EgMaw{eS5IPdZwoBnlU zCCa_7_^Ihg3&faafP{v&VqhJjCBKwcRS7@(;(8-o$Q%>YJcC%e)?rg;@R2TQ>D^bsXv~8}GQIGr=UKs(Qccn{vVUbdOC+rbe}w{c z&!VA@e0Wgd>m%cM(axB*{dd*&PlXEh36JxDZpT$I21Gp&h*6svb}8;@11wo=Gx<2 z1=4Zfl4NnnwD~Q!{SmKB1#du~vvA*}ujCG7vSQLRLpygA3lz)WkTky3HyFNBaFP15 zSbMHh^6qPTR%QSe=_cVGvTEYu_bI9oTMz)zTY@UwRUV9F7cMFQsQ*!<_>cLk?Wx`Ep=^9E>_Arip3 z%dy1yJ?L0(yEbOUL3lsp*;7}mU3O*-J0`L8!Q}^9xNJtNv%=P6npyiQ+u>Ok0G@y+u45b?UDB*~~b^7F~AyDoh<9~RRW zM^|$hLIy!%FbqN`ZtBpUswKUwM?7-<+68VmCr;nx?cPs>i z>xb6EFnlyoynl}2XtCL~zeBg6X~Mn}Quuv0hQ(!1sv)Fi1eIVS*|i`|0j5R77StZ% z^i6-<=%(Mog~<3gTl$AeZ8Ocp+pX&6_*}`Rnx%5?u&bn$R;4&mE1Toz{Ex{$UxzQu z!h88_PUCg`t1eUGyDrhsCQHsJ4WtBpfSgHEX*Yo6C5&;U&-lbm>W?cV$zMhjN&^xAOah&m3TckD800EZwakf3rw5a7RtKqVx5^?|#AbK9OQ zQ}_>qq8~pc%FIUZm-GGM-O(C@yHf>-=M9O|Dn}aB0#+<2rAcyyyAj#xV@PRZx$9*v zpIqQ#(tw!3d|vU;S&^68tM7fO2S~#+Tyd{eNK%pe{05)*YPzP3*}a7N(e(^m!N9G?+^-!mPf@zxA!I&peBP zximfI+DC67wrmtjb}vgz!E8R`hbImx>y!er9VW@$F(u967bBn=wcTa*@{J~nO37!> zUF->mKRBn+`2Myaqnxhh#b=Y9T}_-$&j7~eZaoJDQ_TvGre1=U~68pMh|+)F#MEuh$KE6!hvI75u>?w#FV4H-7;lDSt!%I5IYi_%@^Tec{!<9DviE zhtgLnRC_V}>tO!+<8 zhyGVE_?yCpl`0mF1^6efCR6cxN=qeW(BwMp7qKrl<&zSwmEWq>u=WOlEf6Q|;H$CCELL9yw`{xZbgnFr1S%ie zh+C6IqWlO|#qbxBJCh|SnDBKe-TanK?74tu@?<{j!^?oFk{Hm=Tz8msHVo|q!@P%V zSaBcrnCEBsN8@0AR6gcvsX=F2-sNj;f2WyL3bhz6=lNqX5gWIgbr8%hxm(d-KApr% z_OsPvN87y2%$+fx6LHAwA58w-1_D1gzZ4?M6U`E#Cv^bz&^wVnO0t6r ztRN-(cOB+ei>K1bP{8G&mWV`HYcdhtIDZlX)!=FsBv{FZs#5Ww#0}DS@-GznL5~*E zH3+B>TY8X6S{|SpfZQ-lX`(hfV9SOF!C}M$WwonP=OCgv<#-Td2i*Ax{Vh#qSAz}*7{em;!0?&jnRK)MpNQ%h8_16T6YqYGtW4Bi z*rt(-!F#<0a>B&z;zNzWe~&R7g7dI^6%+l4t8$%|l7C)!LrUkrn%zl4Z_vQS4jV;V zWv`jvjUwUcYBuX6Ie6Tc z(Z!Nw3j+<|k%0r82y`b-9!)K|u$tvzcy8JRnEm3$y25XfnP5Y~l*3a%ZlTS59gO6!-Iw|eVUb%7fH~V?9pnDrEis5!MdT2xop_El$ zE)8vbEbQZpjXGIRdrGUnZwD8{@^BZedL6@w8=fR4qm0lVI)gCskIZKewE+N)Om%2P z*%#)n`ku=(1RuZH8QUu#SL2fU{EB@-tglS52tSboZn4~-d#%aVuF-Ey3ZPxU1GInc zwEirI@E%OdfHh;$_~T02#VcKUe*g!2X!L%=fL`|J@0*o4kFmC0*Uf-NJ{-;ISbRtT z&XmmyaRy|KUL4?C`{}@V|NLufGv>~J<6S(f%|h-3vv)3wXh!Ih|KT>mYsy*CPuCD$ z1sL`KKmp8PjmGta^EY#gF8)F+J~u9uXla2sXgWO_W|vU0Aco*-WH2Wq>Wq;wA+~pG!t5_=s+6~QD7>#%BQ5&a+yBY$2U|bssV1{GNp)@QO zzMg>Dh{a)npckNusJ3cYxK3L6Rn7j+|>Q1+3YwwOgP&I^An&qFi~ zVKno;$YNFMRxsCpUoM)MW~r;HHX>NBI`+NMWq@lq;eaZyBrsO;)QId z5^}`nxA4XSOA^I|(IGm7D3oxj8;0t1XD2I z57)EbgTzGTUj$!T4AFZbyIQHZk^cmkPYFrY4wsb>!-UyA?G{K6!KNM-tDH>0aUmYb zF6q1m1-eUa>gfr1+HmMX?P{l)4@4?{U+`fCo{pF5>DOuSqk1?F%zPzxKL|o=OeiRl z8B$pSgiYbKgxm=CaQNUF324$W*vJ}l1G-im{<*g(Ii;D!P8>oIG2CIDp&N4}xOZT9 zag2}&mwyS~TeX1xa_thUMI;@|oMke?BkC8HTkW+PO^0%|)qIp_Kiv0~eAwT}ck->6 zKay;>8nOk>vk7m`m+a(|)xcC$bJgcjTZuK_c8P7S`Py7;dWCdhP+h3U?O5%e5KT2O z_y0lXL7)bl3-Thki`lFluv9CL!QC$Ci zZliNa6=Kzwj73|X_o$>2dkCt@uKs@ZDy3vz$^Q@F%pH+Ln&9A<$mA?BT|xJfyRCKSfwCJN#`-L<0DhGP5*^e0UZ@&-5>D4>h3YS zVctY0yG2++7jiyz4*Wpr^X0Ld_v}%P9s2sQ^fu^t7KLV@+l}hE&?5G>J!HzA%%(UR z4yPaOaNDT4o-tvN#&Uq}{S$!&9r%;W4{Qd~X4%>W5)oC-`3JTGRXhc2SovGR4wOj{ z0SJ`#1D`*#S^sSQtn4cF+%i(>CuwRriM%qJsLu^nM(-{knQvFkQNo)|guBoETfjP^ zksOEb3jRmj6VX79SsstrU=r%WCjy2^R1gar&w#)H{OA7*Ug===Ud62d)-tzl<`t>v3qhO71pVQL%olOWvde}X2+t9Rx*}#>zsLLxI{&2! zIX?$+_>E2m6%AW2XM{o$xlEVcOBC7EsDvrNqqUIT|D$41AVMsgpK{$#+2}cy_bJIW z3`xVuDf|uEYZtH=@cEC#e{QBT6tEVe3|3MGYX-^_2*M;i&?Li=!4m;rP^bXxVl;Ll zRxT^$LPn{D!{u10P%Skcl?mFh*h_E8~Jv%yDni(E{SH!!`W z5VgPUnTAMfxqhFXk|aPUtFp0U?BgIf{DGMPo1zlrhP7eazuc>IN@1V}VT-!tR-d0C z4*qdjL_N;d1+e6&0QC6qi3fQISsrq0h?FwBOj)S0@$vlUU*p^Uf?b_M_>E5$b0?t? zes;t%W>ms2+z{uB_D*>%o2pwn<>kd#ahEq;^y9=8xwEgHv-$*YIr|C|5etW04^(y2 zgJh`Z!Q0$|*cU_-oB#Xg=`C6+1Pa=;6RFY2u)#1vNq;uplPCPwY=v*!@3TPvOM=CnB7bo zUAC<=mXpm=ej!m^$LHir*DUn2%!!Ku8~lHQEU#hcQy!9gsXnjIsSQ(oI^5a=V!-8y zkH_L)#zSR2x>5$(7Xc*Tn;IQi0@Hht;FJFQr2TdFFesaPW~{o2@`2-VJBb&)V>WBc3IEH)PrK#eDqF(-GlY$IQ3nMweY9s>uLqm;Vof0=>=wL3x?$4*Q`vc5g5o5?ml6PJ@ zLC@&f0(uxaWX~k)ktptMd*596w}<$o+}LT+Up?7`XmQaYlD7!7gAyK+Y%oai2X4DmPvis{h&Be=B9PnM~B|cS46a;YO+1K9L$&IsLd>$6~ott8;E@3|5ec zB?Nb*;tC~ESmMPfP(c0_`>srWn*;cTX28S;nBJ$ksutJ-kw%;Z*Y3{w^;3px8l-`Q zx^R|4XE!<+t|vD-9R7Z}?n^NA!@Ynq=iVG2kuReM6x4!+-b~eSpx|eVrAuhz{6cKJ z-@sXyLge#~iD(Ej>3!+WDeJ&*&*&G$+NodUhPpskPBG8yhfDz>ztM0nO!Ajk>%+M) z`ocy8CFejvfO=wNfa8Xv!@o4Wl5eIlA5sDyajGGZoRC4b61lTs9DcWmogzCqsCfU& z00*uk6_{Hpq6B<$o3cP&zT17RYF~Sls3$*W;C>801s*?@s(*(tnKOyIg93!D5zV&}Ls!)BFQ&y6RhgwdjLguNu4+>d3irYAb<{64Bw z)5}J-KOU^34T4vS%}n7Ki@lD9{p>QS)Q2)bSxrIsKfVuKF}HJv;sd_e+jPYy?8SK6 z%U-vM_A+pHmLTAAs3e^OMP$EkL|Ngh_0cuEX z0tza+IJ|wC^RVuPUtV1?IwTdvPnNI^9bRZuU_9S3eopL1&?$*Q`%)P{(!HPGLlQ*i z%vo;PE6{?`lty$9@@={zA8KZZDv(~-da%jT8AkRtX0o4cjt{E$@KGHcKZcUx9m#YH z$@MC~uC2;3J&M=O+X=IKoSn4`g?#Ub*4WSk??b(ZvEu4u!*#*%>&~toIS5n_$4psj z#%uYvcz5tcT;a=%qnX~og{5~KJRvZ-fXhN7Wb$>(h7S^`0dfs>I$#$W6t=cN`0im* zH5yS8iAYL|GLwecABqBFCVa8~rjG}~wheT$N+qlp8sW}jRu2c4(b&8&*tI(Fn~~T@ z4$&nkM6t%Q+34o%K}XBuBpLsD`h$(CCM&Kmx1HFrN92af68P2CbvA?*yVz|{mZW+o{=_p0Wqr@K^?lF1VP);KhJz&*ZDqc=M35){{}k?3u@{UTVJ?NPu(Of}syyCBEpoykft%H}n|-13Z51 z3l<->lkczK213m^3po(l*k-l2n7D%`e6k=T^k|Q$fRC0%N-bF&n3-OtLKquaz(63_ z@ZUXBNqTfFM?F56s5rbx)F2%e>!+Iy6Z8QoI?NJ#ZMPw?%ksks9K!)VDxC3Ey3^v$BC6}NJxQ~Yd{3R1ArHsG) zk^#{8MCua1p7fCPVN5HDC^19$w`wLl05mFH(fM1J&2YN5Hi94~sbjbE1okqxtp<3X z3CPKtxa0oIlkkg(NMec;P2l@8$61~rTdYloa}Nb0UdCzO_Cqf?%$xjU>D6x5IPkMd&Prz_@9^XJuZpsCyqV9k%XaR zd4r`0ggAUp!XNNPPJ~b7I>~~$9XL^t`(o*K-CKMQ9BbQ`sAbk5SR+t3qPIQnUy#D>5t$HC*~mD z86Ja7CB>&<^T67H&Gh{1+a_9pXZ`bslj|k?8H@N0;tc`;PcsTTLb)e0;CaoxNPZf_ z3|Q+bs~!_h*1Q0tH}Swe2?%ZrXS@aA=;#5fNAR!0o{!lzzDSJyEF7mlOHFBi=~C@M z-Dd}kM}b%~d#D4$cCq*avI&U@&wFVXIAY)S3t?b+Zck`6Ts5v1 zZ{od$&cGR=D7ch~f4r=(o?(HRoTg@X!0S2d=o0WCxDJgxz~F^Z$Wjssi@&;Dy|-Ka znH$bZ{>UQZ(GGupH8>Ue`ZWwzm2%sydBCHL3tE$BX6>_(5v zh0PY1BKX-%V!8NCCS5&W;+S3dmM?+8{Tf7QoGIc?A`XE}hTUL;0$%;4!pj zGN6(>Y5_Uzf>C_GK72ldn+&K-g8RhlNR*9_%l6A-q-v+`|J-VSJzbABFXYJx`IU_2 z)QE&0nApzBBny#)_B88P}cA;j?E>KCTlf+s5^RLri zJtVJ9VV`$@J)P(%*Fy6Au-BWIYwGyKaJ85Sj=Z9Y8?n;2JSV}csO9aI^P7za%YWf( zgCzfSD>sv;sFG(+R@M)6njlsLETD)923UfLLa}6?rooaG{QjRa+V}+^W}r+`40EXK zNtV3cWrc*;^nj#%(WS`>$-WH1*S;^#z}@#Z1@|{{9^3GXk4~v8l8Q@Qwlk9oU(Ffq z4@iYpuf-Xf{&m<0$x?P6#tu|}3>#50LJjB0h)|XrgHjN-8u;B;4;1F~b_k6?Xz#a` zEnS72yVLD>x{uJ%BJ(Fs;k&8O*P|VQJSN!gBS?%1C@p&sWB?r$cO-;p=%RGmVNB*; zXN6V19a|^6#%rLK8^ydFk3_p~HqBMams`$L{&jP;+w|($Wogz}$20vupd1mWef0fA z6mY_WVcUn!YuY`uYfrb}Ie!XCz;*G)Aj8~MOM`G80i24l>5rwmTAJ@}KSiMdJhQbH z=2~z;`sVd!C3LN?bq%y%FhR)2ywh!6!>h4yKLT1D&he+ZgovIO=Pe|@`Wl^p6pemC zh2uhnY%-l;PHhrqD{-?J7znqAZQ<$;{$sWc{=Jx8iuDIGj+s9BJs*1qPanU1PqW|L zkKNyxIE#fOL*f^hK2MY17)k^H;h{?3o8eEkwbz2N4;`!3R-iKW4=1bfcw60v5(y(# zU9)nhvd5aYx3-eg&T^M*&$Lc>kjkmrYrI?wzwSq)S@St&rMgch5>sA&+)%w!Tow&u=B#rMokZ@wuQ&a*6((P3wGONL!$t%5=8b zrRsWW*qjcM>3O}i$p^=oa-nrB1q!MB^XeEIwi3^)q_@2o)>h9I#)y6)8$;-c;B=~e z7d$8st}{0HtlJ1U!cGDm)wc(WQkm=7b@l4|_y`OkL`iszd zwO_3B)4)vM*Wca}oz8rFgezWllwp@*j95Tye;9F+HjetAWgce$B?27Bk`(UQQn;ZF z&J^ZbhqTM8po){~BXo^bUrgoi&md0oK*40UaY5XkK}HH}?c9MNWq-{Pfb)mCpRp`A zR0iF^4@~Vq7QS47&c<~f1t9f??8UK_s_FC+VOLko>Ct%Ta>aaE&RHY47%(R+I_RULEV*HX5gWuV-0k@Gomy!Z%_SDm zV__=F6QG+z%d zYk(n$b@r|Id3Rw222%6~6|@8y$yMoQBfEaFK2CEVv*>@UZK1w)FN@TNQFv#9(i8GwCu9`QH+IlO~3kE=61GoE?6h1^>uZo zlb#*w!tTOigp=5%9b%G#IkK)?hZzvK!&(HjN%p-*{UAvf;gGw|=jx?4?q+kRXV|=c zXoA0<*2$jLe|}vS^I5%8ADPj@C^YULyMvWkHk0YDx0?z!_qj<=+fSxuYP<<=n;OZi z&CzZ=&X(A}qFwK^U+WZ(RSJQ~Rx7mvbz?Skj#Zv!$$?>MID!*#`C zcR`_Zw<1KFSU{=ixS28V5ac5y>R*zDZ^tgk7DOBgfnH~^QM>S4P=6_M*2i3 zSpyApk2IN@f+!V$9cCpUikK!7!^W7As1cuGL-*IqAh#vsNR$$i_=k#{KmbA-dX}%t z?cBx3mrYaea=H?IGq$Z8^>MbJIW9`i-e_-8YVMH3RWqUIQ903>Rs5SnvV3SBSE~|9 znAK7E`0=_Qzwc+Ek9yf^sEuLhBYzyfw}Qh%w;kD*v=6^OJx%UZ1Di`3Dxyj}r%jy3 zK}h(*Al@X&MJ$DuJR)2-35T$BH+wnKpg%MrN1L7lSvglO1eB<5=M%yQm(^rEzwBB%0AoWHZBCc*Q_;pkjZ|*oA2b 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 D5d*6 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

    xertO8-S*sGh;nHkd0RpnPjK2XioaY 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

    s^AYG6 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

    M$cH6Vw^^Sp`BV3a}La;~J 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 z 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⪼x4%ir{!jxF(B^ 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

    @Nc(Vk}mHnG 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

    $ks^dy!DS`NWP-^!^=R1ghb+7` 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 z%0D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

    EIWJ05_`sCXiD*bu2# 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

    V{@uX=1`B`30tSU8zc;H=M=239CL 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 z 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 kI7TSfDN)KIwE@>S=U< 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


    qK~Z)ce(~L!5CH!CJ3Y<6Y-l3 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.unwrap(); + assert_eq!(headers["x-cache-status"], "miss"); + assert_eq!(res.text().await.unwrap(), "hello world"); + + let res = reqwest::get(url).await.unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + let cache_hit_epoch = headers["x-epoch"].to_str().unwrap().parse::().unwrap(); + assert_eq!(headers["x-cache-status"], "hit"); + assert_eq!(res.text().await.unwrap(), "hello world"); + + assert_eq!(cache_miss_epoch, cache_hit_epoch); + + sleep(Duration::from_millis(1100)).await; // ttl is 1 + + let res = reqwest::get(url).await.unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + let cache_expired_epoch = headers["x-epoch"].to_str().unwrap().parse::().unwrap(); + assert_eq!(headers["x-cache-status"], "expired"); + assert_eq!(res.text().await.unwrap(), "hello world"); + + assert!(cache_expired_epoch > cache_hit_epoch); + } + + #[tokio::test] + async fn test_purge() { + init(); + let res = reqwest::get("http://127.0.0.1:6148/unique/test_purge/test2") + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "miss"); + assert_eq!(res.text().await.unwrap(), "hello world"); + + let res = reqwest::get("http://127.0.0.1:6148/unique/test_purge/test2") + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "hit"); + assert_eq!(res.text().await.unwrap(), "hello world"); + + let res = reqwest::Client::builder() + .build() + .unwrap() + .request( + reqwest::Method::from_bytes(b"PURGE").unwrap(), + "http://127.0.0.1:6148/unique/test_purge/test2", + ) + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + assert_eq!(res.text().await.unwrap(), ""); + + let res = reqwest::Client::builder() + .build() + .unwrap() + .request( + reqwest::Method::from_bytes(b"PURGE").unwrap(), + "http://127.0.0.1:6148/unique/test_purge/test2", + ) + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::NOT_FOUND); + assert_eq!(res.text().await.unwrap(), ""); + + let res = reqwest::get("http://127.0.0.1:6148/unique/test_purge/test2") + .await + .unwrap(); + let headers = res.headers(); + assert_eq!(res.status(), StatusCode::OK); + assert_eq!(headers["x-cache-status"], "miss"); + assert_eq!(res.text().await.unwrap(), "hello world"); + } + + #[tokio::test] + async fn test_cache_miss_convert() { + init(); + + // test if-* header is stripped + let client = reqwest::Client::new(); + let res = client + .get("http://127.0.0.1:6148/unique/test_cache_miss_convert/no_if_headers") + .header("if-modified-since", "Wed, 19 Jan 2022 18:39:12 GMT") + .send() + .await + .unwrap(); + // 200 because last-modified not returned from upstream + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "miss"); + assert_eq!(res.text().await.unwrap(), "no if headers detected\n"); + + // test range header is stripped + let client = reqwest::Client::new(); + let res = client + .get("http://127.0.0.1:6148/unique/test_cache_miss_convert2/no_if_headers") + .header("Range", "bytes=0-1") + .send() + .await + .unwrap(); + // we have not implemented downstream range yet, it should be 206 once we have it + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "miss"); + assert_eq!(res.text().await.unwrap(), "no if headers detected\n"); + } + + #[tokio::test] + async fn test_network_error_mid_response() { + init(); + let url = "http://127.0.0.1:6148/sleep/test_network_error_mid_response.txt"; + + let res = reqwest::Client::new() + .get(url) + .header("x-set-sleep", "0") // no need to sleep + .header("x-set-body-sleep", "0.1") // pause the body a bit before abort + .header("x-abort-body", "true") // this will tell origin to kill the conn right away + .send() + .await + .unwrap(); + assert_eq!(res.status(), 200); + // sleep just a little to make sure the req above gets the cache lock + sleep(Duration::from_millis(50)).await; + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "miss"); + // the connection dies + assert!(res.text().await.is_err()); + + let res = reqwest::Client::new() + .get(url) + .header("x-set-sleep", "0") // no need to sleep + .header("x-set-body-sleep", "0.1") // pause the body a bit before abort + .header("x-abort-body", "true") // this will tell origin to kill the conn right away + .send() + .await + .unwrap(); + assert_eq!(res.status(), 200); + // sleep just a little to make sure the req above gets the cache lock + sleep(Duration::from_millis(50)).await; + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "miss"); + // the connection dies + assert!(res.text().await.is_err()); + } + + #[tokio::test] + async fn test_cache_upstream_revalidation() { + init(); + let url = "http://127.0.0.1:6148/unique/test_upstream_revalidation/revalidate_now"; + + let res = reqwest::get(url).await.unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + let cache_miss_epoch = headers["x-epoch"].to_str().unwrap().parse::().unwrap(); + assert_eq!(headers["x-cache-status"], "miss"); + assert_eq!(res.text().await.unwrap(), "hello world"); + + let res = reqwest::get(url).await.unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + let cache_hit_epoch = headers["x-epoch"].to_str().unwrap().parse::().unwrap(); + assert_eq!(headers["x-cache-status"], "hit"); + assert_eq!(res.text().await.unwrap(), "hello world"); + + assert_eq!(cache_miss_epoch, cache_hit_epoch); + + sleep(Duration::from_millis(1100)).await; // ttl is 1 + + let res = reqwest::get(url).await.unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + let cache_expired_epoch = headers["x-epoch"].to_str().unwrap().parse::().unwrap(); + assert_eq!(headers["x-cache-status"], "revalidated"); + assert_eq!(res.text().await.unwrap(), "hello world"); + + // still the old object + assert_eq!(cache_expired_epoch, cache_hit_epoch); + } + + #[tokio::test] + async fn test_cache_downstream_revalidation() { + init(); + let url = "http://127.0.0.1:6148/unique/test_downstream_revalidation/revalidate_now"; + let client = reqwest::Client::new(); + + // MISS + 304 + let res = client + .get(url) + .header("If-None-Match", "\"abcd\"") // the fixed etag of this endpoint + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::NOT_MODIFIED); + let headers = res.headers(); + let cache_miss_epoch = headers["x-epoch"].to_str().unwrap().parse::().unwrap(); + assert_eq!(headers["x-cache-status"], "miss"); + assert_eq!(res.text().await.unwrap(), ""); // 304 no body + + // HIT + 304 + let res = client + .get(url) + .header("If-None-Match", "\"abcd\"") // the fixed etag of this endpoint + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::NOT_MODIFIED); + let headers = res.headers(); + let cache_hit_epoch = headers["x-epoch"].to_str().unwrap().parse::().unwrap(); + assert_eq!(headers["x-cache-status"], "hit"); + assert_eq!(res.text().await.unwrap(), ""); // 304 no body + + assert_eq!(cache_miss_epoch, cache_hit_epoch); + + sleep(Duration::from_millis(1100)).await; // ttl is 1 + + // revalidated + 304 + let res = client + .get(url) + .header("If-None-Match", "\"abcd\"") // the fixed etag of this endpoint + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::NOT_MODIFIED); + let headers = res.headers(); + let cache_expired_epoch = headers["x-epoch"].to_str().unwrap().parse::().unwrap(); + assert_eq!(headers["x-cache-status"], "revalidated"); + assert_eq!(res.text().await.unwrap(), ""); // 304 no body + + // still the old object + assert_eq!(cache_expired_epoch, cache_hit_epoch); + } + + #[tokio::test] + async fn test_cache_downstream_head() { + init(); + let url = "http://127.0.0.1:6148/unique/test_downstream_head/revalidate_now"; + let client = reqwest::Client::new(); + + // MISS + HEAD + let res = client.head(url).send().await.unwrap(); + + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + let cache_miss_epoch = headers["x-epoch"].to_str().unwrap().parse::().unwrap(); + assert_eq!(headers["x-cache-status"], "miss"); + assert_eq!(res.text().await.unwrap(), ""); // HEAD no body + + // HIT + HEAD + let res = client.head(url).send().await.unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + let cache_hit_epoch = headers["x-epoch"].to_str().unwrap().parse::().unwrap(); + assert_eq!(headers["x-cache-status"], "hit"); + assert_eq!(res.text().await.unwrap(), ""); // HEAD no body + + assert_eq!(cache_miss_epoch, cache_hit_epoch); + + sleep(Duration::from_millis(1100)).await; // ttl is 1 + + // revalidated + HEAD + let res = client.head(url).send().await.unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + let cache_expired_epoch = headers["x-epoch"].to_str().unwrap().parse::().unwrap(); + assert_eq!(headers["x-cache-status"], "revalidated"); + assert_eq!(res.text().await.unwrap(), ""); // HEAD no body + + // still the old object + assert_eq!(cache_expired_epoch, cache_hit_epoch); + } + + #[tokio::test] + async fn test_purge_reject() { + init(); + + let res = reqwest::Client::builder() + .build() + .unwrap() + .request( + reqwest::Method::from_bytes(b"PURGE").unwrap(), + "http://127.0.0.1:6148/", + ) + .header("x-bypass-cache", "1") // not to cache this one + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::METHOD_NOT_ALLOWED); + assert_eq!(res.text().await.unwrap(), ""); + } + + #[tokio::test] + async fn test_1xx_caching() { + // 1xx shouldn't interfere with HTTP caching + + // set up a one-off mock server + // (warp / hyper don't have custom 1xx sending capabilities yet) + async fn mock_1xx_server(port: u16, cc_header: &str) { + use tokio::io::AsyncWriteExt; + + let listener = tokio::net::TcpListener::bind(format!("127.0.0.1:{}", port)) + .await + .unwrap(); + if let Ok((mut stream, _addr)) = listener.accept().await { + stream.write_all(b"HTTP/1.1 103 Early Hints\r\nLink: ; rel=preconnect\r\n\r\n").await.unwrap(); + // wait a bit so that the client can read + sleep(Duration::from_millis(100)).await; + stream.write_all(format!("HTTP/1.1 200 OK\r\nContent-Length: 5\r\nCache-Control: {}\r\n\r\nhello", cc_header).as_bytes()).await.unwrap(); + sleep(Duration::from_millis(100)).await; + } + } + + init(); + + let url = "http://127.0.0.1:6148/unique/test_1xx_caching"; + + tokio::spawn(async { + mock_1xx_server(6151, "max-age=5").await; + }); + // wait for server to start + sleep(Duration::from_millis(100)).await; + + let client = reqwest::Client::new(); + let res = client + .get(url) + .header("x-port", "6151") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "miss"); + assert_eq!(res.text().await.unwrap(), "hello"); + + let res = client + .get(url) + .header("x-port", "6151") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "hit"); + assert_eq!(res.text().await.unwrap(), "hello"); + + // 1xx shouldn't interfere with bypass + let url = "http://127.0.0.1:6148/unique/test_1xx_bypass"; + + tokio::spawn(async { + mock_1xx_server(6152, "private, no-store").await; + }); + // wait for server to start + sleep(Duration::from_millis(100)).await; + + let res = client + .get(url) + .header("x-port", "6152") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "no-cache"); + assert_eq!(res.text().await.unwrap(), "hello"); + + // restart the one-off server - still uncacheable + sleep(Duration::from_millis(100)).await; + tokio::spawn(async { + mock_1xx_server(6152, "private, no-store").await; + }); + // wait for server to start + sleep(Duration::from_millis(100)).await; + + let res = client + .get(url) + .header("x-port", "6152") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "no-cache"); + assert_eq!(res.text().await.unwrap(), "hello"); + } + + #[tokio::test] + async fn test_bypassed_became_cacheable() { + init(); + + let url = "http://127.0.0.1:6148/unique/test_bypassed/cache_control"; + + let res = reqwest::Client::new() + .get(url) + .header("set-cache-control", "private, max-age=0") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + let cc = headers.get("Cache-Control").unwrap(); + assert_eq!(cc, "private, max-age=0"); + assert_eq!(headers["x-cache-status"], "no-cache"); + assert_eq!(res.text().await.unwrap(), "hello world"); + + // request should bypass cache, but became cacheable (cache fill) + let res = reqwest::Client::new() + .get(url) + .header("set-cache-control", "public, max-age=10") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "miss"); + assert_eq!(res.text().await.unwrap(), "hello world"); + + // HIT + let res = reqwest::Client::new() + .get(url) + .header("set-cache-control", "public, max-age=10") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "hit"); + assert_eq!(res.text().await.unwrap(), "hello world"); + } + + #[tokio::test] + async fn test_bypassed_304() { + init(); + + let url = "http://127.0.0.1:6148/unique/test_bypassed_304/cache_control"; + + let res = reqwest::Client::new() + .get(url) + .header("set-cache-control", "private, max-age=0") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + let cc = headers.get("Cache-Control").unwrap(); + assert_eq!(cc, "private, max-age=0"); + assert_eq!(headers["x-cache-status"], "no-cache"); + assert_eq!(res.text().await.unwrap(), "hello world"); + + // cacheable without private cache-control + // note this will be a 304 and not a 200, we will cache on _next_ request + let res = reqwest::Client::new() + .get(url) + .header("set-cache-control", "public, max-age=10") + .header("set-revalidated", "1") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::NOT_MODIFIED); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "deferred"); + + // should be cache fill + let res = reqwest::Client::new() + .get(url) + .header("set-cache-control", "public, max-age=10") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "miss"); + assert_eq!(res.text().await.unwrap(), "hello world"); + + // HIT + let res = reqwest::Client::new() + .get(url) + .header("set-cache-control", "public, max-age=10") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "hit"); + assert_eq!(res.text().await.unwrap(), "hello world"); + } + + #[tokio::test] + async fn test_bypassed_uncacheable_304() { + init(); + + let url = "http://127.0.0.1:6148/unique/test_bypassed_private_304/cache_control"; + + // cache fill + let res = reqwest::Client::new() + .get(url) + .header("set-cache-control", "public, max-age=0") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + let cc = headers.get("Cache-Control").unwrap(); + assert_eq!(cc, "public, max-age=0"); + assert_eq!(headers["x-cache-status"], "miss"); + assert_eq!(res.text().await.unwrap(), "hello world"); + + // cache stale + // upstream returns 304, but response became uncacheable + let res = reqwest::Client::new() + .get(url) + .header("set-cache-control", "private") + .header("set-revalidated", "1") + .send() + .await + .unwrap(); + // should see the response body because we didn't send conditional headers + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "revalidated"); + assert_eq!(res.text().await.unwrap(), "hello world"); + + // we bypass cache for this next request + let res = reqwest::Client::new() + .get(url) + .header("set-cache-control", "public, max-age=10") + .header("set-revalidated", "1") // non-200 status to get bypass phase + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::NOT_MODIFIED); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "deferred"); + } + + #[tokio::test] + async fn test_eviction() { + init(); + let url = "http://127.0.0.1:6148/file_maker/test_eviction".to_owned(); + + // admit asset 1 + let res = reqwest::Client::new() + .get(url.clone() + "1") + .header("x-set-size", "3000") + .header("x-eviction", "1") // tell test proxy to use eviction manager + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "miss"); + assert_eq!(res.text().await.unwrap().len(), 3000); + + // admit asset 2 + let res = reqwest::Client::new() + .get(url.clone() + "2") + .header("x-set-size", "3000") + .header("x-eviction", "1") // tell test proxy to use eviction manager + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "miss"); + assert_eq!(res.text().await.unwrap().len(), 3000); + + // touch asset 2 + let res = reqwest::Client::new() + .get(url.clone() + "2") + .header("x-set-size", "3000") + .header("x-eviction", "1") // tell test proxy to use eviction manager + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "hit"); + assert_eq!(res.text().await.unwrap().len(), 3000); + + // touch asset 1 + let res = reqwest::Client::new() + .get(url.clone() + "1") + .header("x-set-size", "3000") + .header("x-eviction", "1") // tell test proxy to use eviction manager + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "hit"); + assert_eq!(res.text().await.unwrap().len(), 3000); + + // admit asset 3 + let res = reqwest::Client::new() + .get(url.clone() + "3") + .header("x-set-size", "6000") + .header("x-eviction", "1") // tell test proxy to use eviction manager + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "miss"); + assert_eq!(res.text().await.unwrap().len(), 6000); + + // check asset 2, it should be evicted already because admitting asset 3 made it full + let res = reqwest::Client::new() + .get(url.clone() + "2") + .header("x-set-size", "3000") + .header("x-eviction", "1") // tell test proxy to use eviction manager + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "miss"); // evicted + assert_eq!(res.text().await.unwrap().len(), 3000); + } + + #[tokio::test] + async fn test_cache_lock_miss_hit() { + init(); + let url = "http://127.0.0.1:6148/sleep/test_cache_lock_miss_hit.txt"; + + // no lock, parallel fetches to a slow origin are all misses + tokio::spawn(async move { + let res = reqwest::Client::new().get(url).send().await.unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "miss"); + assert_eq!(res.text().await.unwrap(), "hello world"); + }); + + tokio::spawn(async move { + let res = reqwest::Client::new().get(url).send().await.unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "miss"); + assert_eq!(res.text().await.unwrap(), "hello world"); + }); + + tokio::spawn(async move { + let res = reqwest::Client::new().get(url).send().await.unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "miss"); + assert_eq!(res.text().await.unwrap(), "hello world"); + }) + .await + .unwrap(); // wait for at least one of them to finish + + let res = reqwest::Client::new().get(url).send().await.unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "hit"); + assert_eq!(res.text().await.unwrap(), "hello world"); + + // try with lock + let url = "http://127.0.0.1:6148/sleep/test_cache_lock_miss_hit2.txt"; + let task1 = tokio::spawn(async move { + let res = reqwest::Client::new() + .get(url) + .header("x-lock", "true") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "miss"); + assert_eq!(res.text().await.unwrap(), "hello world"); + }); + // sleep just a little to make sure the req above gets the cache lock + sleep(Duration::from_millis(50)).await; + let task2 = tokio::spawn(async move { + let res = reqwest::Client::new() + .get(url) + .header("x-lock", "true") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "hit"); + let lock_time_ms: u32 = headers["x-cache-lock-time-ms"] + .to_str() + .unwrap() + .parse() + .unwrap(); + assert!(lock_time_ms > 900 && lock_time_ms < 1000); + assert_eq!(res.text().await.unwrap(), "hello world"); + }); + let task3 = tokio::spawn(async move { + let res = reqwest::Client::new() + .get(url) + .header("x-lock", "true") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "hit"); + let lock_time_ms: u32 = headers["x-cache-lock-time-ms"] + .to_str() + .unwrap() + .parse() + .unwrap(); + assert!(lock_time_ms > 900 && lock_time_ms < 1000); + assert_eq!(res.text().await.unwrap(), "hello world"); + }); + + task1.await.unwrap(); + task2.await.unwrap(); + task3.await.unwrap(); + } + + #[tokio::test] + async fn test_cache_lock_expired() { + init(); + let url = "http://127.0.0.1:6148/sleep/test_cache_lock_expired.txt"; + + // cache one + let res = reqwest::Client::new() + .get(url) + .header("x-no-stale-revalidate", "true") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "miss"); + assert_eq!(res.text().await.unwrap(), "hello world"); + // let it stale + sleep(Duration::from_secs(1)).await; + + let task1 = tokio::spawn(async move { + let res = reqwest::Client::new() + .get(url) + .header("x-lock", "true") + .header("x-no-stale-revalidate", "true") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "expired"); + assert_eq!(res.text().await.unwrap(), "hello world"); + }); + // sleep just a little to make sure the req above gets the cache lock + sleep(Duration::from_millis(50)).await; + let task2 = tokio::spawn(async move { + let res = reqwest::Client::new() + .get(url) + .header("x-lock", "true") + .header("x-no-stale-revalidate", "true") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "hit"); + assert_eq!(res.text().await.unwrap(), "hello world"); + }); + let task3 = tokio::spawn(async move { + let res = reqwest::Client::new() + .get(url) + .header("x-lock", "true") + .header("x-no-stale-revalidate", "true") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "hit"); + assert_eq!(res.text().await.unwrap(), "hello world"); + }); + + task1.await.unwrap(); + task2.await.unwrap(); + task3.await.unwrap(); + } + + #[tokio::test] + async fn test_cache_lock_network_error() { + init(); + let url = "http://127.0.0.1:6148/sleep/test_cache_lock_network_error.txt"; + + // FIXME: Dangling lock happens in this test because the first request aborted without + // properly release the lock. This is a bug + + let task1 = tokio::spawn(async move { + let res = reqwest::Client::new() + .get(url) + .header("x-lock", "true") + .header("x-set-sleep", "0.3") // sometimes we hit the retry logic which is x3 slow + .header("x-abort", "true") // this will tell origin to kill the conn right away + .send() + .await + .unwrap(); + assert_eq!(res.status(), 502); // error happened + }); + // sleep just a little to make sure the req above gets the cache lock + sleep(Duration::from_millis(50)).await; + + let task2 = tokio::spawn(async move { + let res = reqwest::Client::new() + .get(url) + .header("x-lock", "true") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + let status = headers["x-cache-status"].to_owned(); + assert_eq!(res.text().await.unwrap(), "hello world"); + status + }); + let task3 = tokio::spawn(async move { + let res = reqwest::Client::new() + .get(url) + .header("x-lock", "true") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + let status = headers["x-cache-status"].to_owned(); + assert_eq!(res.text().await.unwrap(), "hello world"); + status + }); + + task1.await.unwrap(); + let status2 = task2.await.unwrap(); + let status3 = task3.await.unwrap(); + + let mut count_miss = 0; + if status2 == "miss" { + count_miss += 1; + } + if status3 == "miss" { + count_miss += 1; + } + assert_eq!(count_miss, 1); + } + + #[tokio::test] + async fn test_cache_lock_uncacheable() { + init(); + let url = "http://127.0.0.1:6148/sleep/test_cache_lock_uncacheable.txt"; + + let task1 = tokio::spawn(async move { + let res = reqwest::Client::new() + .get(url) + .header("x-lock", "true") + .header("x-no-store", "true") // tell origin to return CC: no-store + .send() + .await + .unwrap(); + assert_eq!(res.status(), 200); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "no-cache"); + assert_eq!(res.text().await.unwrap(), "hello world"); + }); + // sleep just a little to make sure the req above gets the cache lock + sleep(Duration::from_millis(50)).await; + + let task2 = tokio::spawn(async move { + let res = reqwest::Client::new() + .get(url) + .header("x-lock", "true") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "no-cache"); + assert_eq!(res.text().await.unwrap(), "hello world"); + }); + let task3 = tokio::spawn(async move { + let res = reqwest::Client::new() + .get(url) + .header("x-lock", "true") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "no-cache"); + assert_eq!(res.text().await.unwrap(), "hello world"); + }); + + task1.await.unwrap(); + task2.await.unwrap(); + task3.await.unwrap(); + } + + #[tokio::test] + async fn test_cache_lock_timeout() { + init(); + let url = "http://127.0.0.1:6148/sleep/test_cache_lock_timeout.txt"; + + let task1 = tokio::spawn(async move { + let res = reqwest::Client::new() + .get(url) + .header("x-lock", "true") + .header("x-set-sleep", "3") // we have a 2 second cache lock timeout + .send() + .await + .unwrap(); + assert_eq!(res.status(), 200); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "miss"); + assert_eq!(res.text().await.unwrap(), "hello world"); + }); + // sleep just a little to make sure the req above gets the cache lock + sleep(Duration::from_millis(50)).await; + + let task2 = tokio::spawn(async move { + let res = reqwest::Client::new() + .get(url) + .header("x-lock", "true") + .header("x-set-sleep", "0.1") // tell origin to return faster + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "no-cache"); + assert_eq!(res.text().await.unwrap(), "hello world"); + }); + + // send the 3rd request after the 2 second cache lock timeout where the + // first request still holds the lock (3s delay in origin) + sleep(Duration::from_millis(2000)).await; + let task3 = tokio::spawn(async move { + let res = reqwest::Client::new() + .get(url) + .header("x-lock", "true") + .header("x-set-sleep", "0.1") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "no-cache"); + assert_eq!(res.text().await.unwrap(), "hello world"); + }); + + task1.await.unwrap(); + task2.await.unwrap(); + task3.await.unwrap(); + + let res = reqwest::Client::new() + .get(url) + .header("x-lock", "true") + .send() + .await + .unwrap(); + assert_eq!(res.status(), 200); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "hit"); // the first request cached it + assert_eq!(res.text().await.unwrap(), "hello world"); + } + + #[tokio::test] + async fn test_cache_serve_stale_network_error() { + init(); + let url = "http://127.0.0.1:6148/sleep/test_cache_serve_stale_network_error.txt"; + + let res = reqwest::Client::new() + .get(url) + .header("x-set-sleep", "0") // no need to sleep we just reuse this endpoint + .send() + .await + .unwrap(); + assert_eq!(res.status(), 200); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "miss"); + assert_eq!(res.text().await.unwrap(), "hello world"); + + sleep(Duration::from_millis(1100)).await; // ttl is 1 + + let res = reqwest::Client::new() + .get(url) + .header("x-set-sleep", "0") // no need to sleep we just reuse this endpoint + .header("x-abort", "true") // this will tell origin to kill the conn right away + .send() + .await + .unwrap(); + assert_eq!(res.status(), 200); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "stale"); + assert_eq!(res.text().await.unwrap(), "hello world"); + } + + #[tokio::test] + async fn test_cache_serve_stale_network_error_mid_response() { + init(); + let url = + "http://127.0.0.1:6148/sleep/test_cache_serve_stale_network_error_mid_response.txt"; + + let res = reqwest::Client::new() + .get(url) + .header("x-set-sleep", "0") // no need to sleep we just reuse this endpoint + .send() + .await + .unwrap(); + assert_eq!(res.status(), 200); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "miss"); + assert_eq!(res.text().await.unwrap(), "hello world"); + + sleep(Duration::from_millis(1100)).await; // ttl is 1 + + let res = reqwest::Client::new() + .get(url) + .header("x-set-sleep", "0") // no need to sleep we just reuse this endpoint + .header("x-set-body-sleep", "0.1") // pause the body a bit before abort + .header("x-abort-body", "true") // this will tell origin to kill the conn right away + .send() + .await + .unwrap(); + assert_eq!(res.status(), 200); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "expired"); + // the connection dies + assert!(res.text().await.is_err()); + } + + #[tokio::test] + async fn test_cache_serve_stale_on_500() { + init(); + let url = "http://127.0.0.1:6148/sleep/test_cache_serve_stale_on_500.txt"; + + let res = reqwest::Client::new() + .get(url) + .header("x-set-sleep", "0") // no need to sleep we just reuse this endpoint + .send() + .await + .unwrap(); + assert_eq!(res.status(), 200); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "miss"); + assert_eq!(res.text().await.unwrap(), "hello world"); + + sleep(Duration::from_millis(1100)).await; // ttl is 1 + + let res = reqwest::Client::new() + .get(url) + .header("x-set-sleep", "0") // no need to sleep we just reuse this endpoint + .header("x-error-header", "true") // this will tell origin to return 500 + .send() + .await + .unwrap(); + assert_eq!(res.status(), 200); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "stale"); + assert_eq!(res.text().await.unwrap(), "hello world"); + } + + #[tokio::test] + async fn test_stale_while_revalidate_many_readers() { + init(); + let url = "http://127.0.0.1:6148/sleep/test_stale_while_revalidate_many_readers.txt"; + + // cache one + let res = reqwest::Client::new().get(url).send().await.unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "miss"); + assert_eq!(res.text().await.unwrap(), "hello world"); + // let it stale + sleep(Duration::from_secs(1)).await; + + let task1 = tokio::spawn(async move { + let res = reqwest::Client::new() + .get(url) + .header("x-lock", "true") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "stale"); + assert_eq!(res.text().await.unwrap(), "hello world"); + }); + // sleep just a little to make sure the req above gets the cache lock + sleep(Duration::from_millis(50)).await; + let task2 = tokio::spawn(async move { + let res = reqwest::Client::new() + .get(url) + .header("x-lock", "true") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "stale"); + assert_eq!(res.text().await.unwrap(), "hello world"); + }); + let task3 = tokio::spawn(async move { + let res = reqwest::Client::new() + .get(url) + .header("x-lock", "true") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "stale"); + assert_eq!(res.text().await.unwrap(), "hello world"); + }); + + task1.await.unwrap(); + task2.await.unwrap(); + task3.await.unwrap(); + } + + #[tokio::test] + async fn test_stale_while_revalidate_single_request() { + init(); + let url = "http://127.0.0.1:6148/sleep/test_stale_while_revalidate_single_request.txt"; + + // cache one + let res = reqwest::Client::new() + .get(url) + .header("x-set-sleep", "0") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "miss"); + assert_eq!(res.text().await.unwrap(), "hello world"); + // let it stale + sleep(Duration::from_secs(1)).await; + + let res = reqwest::Client::new() + .get(url) + .header("x-lock", "true") + .header("x-set-sleep", "0") // by default /sleep endpoint will sleep 1s + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "stale"); + assert_eq!(res.text().await.unwrap(), "hello world"); + + // wait for the background request to finish + sleep(Duration::from_millis(100)).await; + + let res = reqwest::Client::new() + .get(url) + .header("x-lock", "true") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "hit"); // fresh + assert_eq!(res.text().await.unwrap(), "hello world"); + } + + #[tokio::test] + async fn test_cache_streaming_partial_body() { + init(); + let url = "http://127.0.0.1:6148/slow_body/test_cache_streaming_partial_body.txt"; + let task1 = tokio::spawn(async move { + let res = reqwest::Client::new() + .get(url) + .header("x-lock", "true") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "miss"); + assert_eq!(res.text().await.unwrap(), "hello world!"); + }); + // sleep just a little to make sure the req above gets the cache lock + sleep(Duration::from_millis(50)).await; + + let task2 = tokio::spawn(async move { + let res = reqwest::Client::new() + .get(url) + .header("x-lock", "true") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "hit"); + let lock_time_ms: u32 = headers["x-cache-lock-time-ms"] + .to_str() + .unwrap() + .parse() + .unwrap(); + // the entire body should need 2 extra seconds, here the test shows that + // only the header is under cache lock and the body should be streamed + assert!(lock_time_ms > 900 && lock_time_ms < 1000); + assert_eq!(res.text().await.unwrap(), "hello world!"); + }); + let task3 = tokio::spawn(async move { + let res = reqwest::Client::new() + .get(url) + .header("x-lock", "true") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "hit"); + let lock_time_ms: u32 = headers["x-cache-lock-time-ms"] + .to_str() + .unwrap() + .parse() + .unwrap(); + // the entire body should need 2 extra seconds, here the test shows that + // only the header is under cache lock and the body should be streamed + assert!(lock_time_ms > 900 && lock_time_ms < 1000); + assert_eq!(res.text().await.unwrap(), "hello world!"); + }); + + task1.await.unwrap(); + task2.await.unwrap(); + task3.await.unwrap(); + } + + #[tokio::test] + async fn test_range_request() { + init(); + let url = "http://127.0.0.1:6148/unique/test_range_request/now"; + + let res = reqwest::Client::new() + .get(url) + .header("Range", "bytes=0-1") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::PARTIAL_CONTENT); + let headers = res.headers(); + let cache_miss_epoch = headers["x-epoch"].to_str().unwrap().parse::().unwrap(); + assert_eq!(headers["x-cache-status"], "miss"); + assert_eq!(res.text().await.unwrap(), "he"); + + // full body is cached + let res = reqwest::get(url).await.unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + let cache_hit_epoch = headers["x-epoch"].to_str().unwrap().parse::().unwrap(); + assert_eq!(headers["x-cache-status"], "hit"); + assert_eq!(res.text().await.unwrap(), "hello world"); + + assert_eq!(cache_miss_epoch, cache_hit_epoch); + + let res = reqwest::Client::new() + .get(url) + .header("Range", "bytes=0-1") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::PARTIAL_CONTENT); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "hit"); + assert_eq!(res.text().await.unwrap(), "he"); + + let res = reqwest::Client::new() + .get(url) + .header("Range", "bytes=1-0") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::RANGE_NOT_SATISFIABLE); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "hit"); + assert_eq!(res.text().await.unwrap(), ""); + + let res = reqwest::Client::new() + .head(url) + .header("Range", "bytes=0-1") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::PARTIAL_CONTENT); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "hit"); + assert_eq!(res.text().await.unwrap(), ""); + + sleep(Duration::from_millis(1100)).await; // ttl is 1 + + let res = reqwest::Client::new() + .get(url) + .header("Range", "bytes=0-1") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::PARTIAL_CONTENT); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "expired"); + assert_eq!(res.text().await.unwrap(), "he"); + } + + #[tokio::test] + async fn test_caching_when_downstream_bails() { + init(); + let url = "http://127.0.0.1:6148/slow_body/test_caching_when_downstream_bails/"; + + tokio::spawn(async move { + let res = reqwest::Client::new() + .get(url) + .header("x-lock", "true") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "miss"); + // exit without res.text().await so that we bail early + }); + // sleep just a little to make sure the req above gets the cache lock + sleep(Duration::from_millis(50)).await; + + let res = reqwest::Client::new() + .get(url) + .header("x-lock", "true") + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "hit"); + let lock_time_ms: u32 = headers["x-cache-lock-time-ms"] + .to_str() + .unwrap() + .parse() + .unwrap(); + // the entire body should need 2 extra seconds, here the test shows that + // only the header is under cache lock and the body should be streamed + assert!(lock_time_ms > 900 && lock_time_ms < 1000); + assert_eq!(res.text().await.unwrap(), "hello world!"); + } + + async fn send_vary_req(url: &str, vary: &str) -> reqwest::Response { + reqwest::Client::new() + .get(url) + .header("x-vary-me", vary) + .send() + .await + .unwrap() + } + + #[tokio::test] + async fn test_vary_caching() { + init(); + let url = "http://127.0.0.1:6148/unique/test_vary_caching/now"; + + let res = send_vary_req(url, "a").await; + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + let cache_a_miss_epoch = headers["x-epoch"].to_str().unwrap().parse::().unwrap(); + assert_eq!(headers["x-cache-status"], "miss"); + assert_eq!(res.text().await.unwrap(), "hello world"); + + let res = send_vary_req(url, "a").await; + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + let cache_hit_epoch = headers["x-epoch"].to_str().unwrap().parse::().unwrap(); + assert_eq!(headers["x-cache-status"], "hit"); + assert_eq!(res.text().await.unwrap(), "hello world"); + + assert_eq!(cache_a_miss_epoch, cache_hit_epoch); + + let res = send_vary_req(url, "b").await; + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + let cache_b_miss_epoch = headers["x-epoch"].to_str().unwrap().parse::().unwrap(); + assert_eq!(headers["x-cache-status"], "miss"); + assert_eq!(res.text().await.unwrap(), "hello world"); + + let res = send_vary_req(url, "b").await; + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + let cache_hit_epoch = headers["x-epoch"].to_str().unwrap().parse::().unwrap(); + assert_eq!(headers["x-cache-status"], "hit"); + assert_eq!(res.text().await.unwrap(), "hello world"); + + assert_eq!(cache_b_miss_epoch, cache_hit_epoch); + assert!(cache_a_miss_epoch != cache_b_miss_epoch); + } + + #[tokio::test] + async fn test_vary_purge() { + init(); + let url = "http://127.0.0.1:6148/unique/test_vary_purge/now"; + + send_vary_req(url, "a").await; + let res = send_vary_req(url, "a").await; + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "hit"); + + send_vary_req(url, "b").await; + let res = send_vary_req(url, "b").await; + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "hit"); + + //both variances are cached + + let res = reqwest::Client::builder() + .build() + .unwrap() + .request(reqwest::Method::from_bytes(b"PURGE").unwrap(), url) + .send() + .await + .unwrap(); + assert_eq!(res.status(), StatusCode::OK); + assert_eq!(res.text().await.unwrap(), ""); + + //both should be miss + + let res = send_vary_req(url, "a").await; + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "miss"); + + let res = send_vary_req(url, "b").await; + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "miss"); + } + + async fn send_max_file_size_req(url: &str, max_file_size_bytes: usize) -> reqwest::Response { + reqwest::Client::new() + .get(url) + .header( + "x-cache-max-file-size-bytes", + max_file_size_bytes.to_string(), + ) + .send() + .await + .unwrap() + } + + #[tokio::test] + async fn test_cache_max_file_size() { + init(); + let url = "http://127.0.0.1:6148/unique/test_cache_max_file_size_100/now"; + + let res = send_max_file_size_req(url, 100).await; + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "miss"); + assert_eq!(res.text().await.unwrap(), "hello world"); + + let res = send_max_file_size_req(url, 100).await; + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "hit"); + assert_eq!(res.text().await.unwrap(), "hello world"); + + let url = "http://127.0.0.1:6148/unique/test_cache_max_file_size_1/now"; + let res = send_max_file_size_req(url, 1).await; + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "no-cache"); + assert_eq!(res.text().await.unwrap(), "hello world"); + + let res = send_max_file_size_req(url, 1).await; + assert_eq!(res.status(), StatusCode::OK); + let headers = res.headers(); + assert_eq!(headers["x-cache-status"], "no-cache"); + assert_eq!(res.text().await.unwrap(), "hello world"); + } +} diff --git a/pingora-proxy/tests/utils/cert.rs b/pingora-proxy/tests/utils/cert.rs new file mode 100644 index 0000000..674a3ac --- /dev/null +++ b/pingora-proxy/tests/utils/cert.rs @@ -0,0 +1,47 @@ +// 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 pingora_core::tls::pkey::{PKey, Private}; +use pingora_core::tls::x509::X509; +use std::fs; + +pub static ROOT_CERT: Lazy = Lazy::new(|| load_cert("keys/root.crt")); +pub static ROOT_KEY: Lazy> = Lazy::new(|| load_key("keys/root.key")); +pub static INTERMEDIATE_CERT: Lazy = Lazy::new(|| load_cert("keys/intermediate.crt")); +pub static INTERMEDIATE_KEY: Lazy> = Lazy::new(|| load_key("keys/intermediate.key")); +pub static LEAF_CERT: Lazy = Lazy::new(|| load_cert("keys/leaf.crt")); +pub static LEAF2_CERT: Lazy = Lazy::new(|| load_cert("keys/leaf2.crt")); +pub static LEAF_KEY: Lazy> = Lazy::new(|| load_key("keys/leaf.key")); +pub static LEAF2_KEY: Lazy> = Lazy::new(|| load_key("keys/leaf2.key")); +pub static SERVER_CERT: Lazy = Lazy::new(|| load_cert("keys/server.crt")); +pub static SERVER_KEY: Lazy> = Lazy::new(|| load_key("keys/key.pem")); +pub static CURVE_521_TEST_KEY: Lazy> = + Lazy::new(|| load_key("keys/curve_test.521.key.pem")); +pub static CURVE_521_TEST_CERT: Lazy = Lazy::new(|| load_cert("keys/curve_test.521.crt")); +pub static CURVE_384_TEST_KEY: Lazy> = + Lazy::new(|| load_key("keys/curve_test.384.key.pem")); +pub static CURVE_384_TEST_CERT: Lazy = Lazy::new(|| load_cert("keys/curve_test.384.crt")); + +fn load_cert(path: &str) -> X509 { + let path = format!("{}/{path}", super::conf_dir()); + let cert_bytes = fs::read(path).unwrap(); + X509::from_pem(&cert_bytes).unwrap() +} + +fn load_key(path: &str) -> PKey { + let path = format!("{}/{path}", super::conf_dir()); + let key_bytes = fs::read(path).unwrap(); + PKey::private_key_from_pem(&key_bytes).unwrap() +} diff --git a/pingora-proxy/tests/utils/conf/keys/README.md b/pingora-proxy/tests/utils/conf/keys/README.md new file mode 100644 index 0000000..13965cd --- /dev/null +++ b/pingora-proxy/tests/utils/conf/keys/README.md @@ -0,0 +1,18 @@ +Some test certificates. The CA is specified in your package directory (grep for ca_file). + +Some handy commands: +``` +# Describe a pkey +openssl [ec|rsa|...] -in key.pem -noout -text +# Describe a cert +openssl x509 -in some_cert.crt -noout -text + +# Generate self-signed cert +openssl ecparam -genkey -name secp256r1 -noout -out test_key.pem +openssl req -new -x509 -key test_key.pem -out test.crt -days 3650 -sha256 -subj '/CN=openrusty.org' + +# Generate a cert signed by another +openssl ecparam -genkey -name secp256r1 -noout -out test_key.pem +openssl req -new -key test_key.pem -out test.csr +openssl x509 -req -in test.csr -CA server.crt -CAkey key.pem -CAcreateserial -CAserial test.srl -out test.crt -days 3650 -sha256 +``` diff --git a/pingora-proxy/tests/utils/conf/keys/ca1.crt b/pingora-proxy/tests/utils/conf/keys/ca1.crt new file mode 100644 index 0000000..021c59d --- /dev/null +++ b/pingora-proxy/tests/utils/conf/keys/ca1.crt @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFbTCCA1UCFDsRVhSk+Asz9Q9BwsvZucCbYA5/MA0GCSqGSIb3DQEBCwUAMHMx +CzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4g +RnJhbmNpc2NvMR4wHAYDVQQKDBVDbG91ZGZsYXJlIFRlc3QgU3VpdGUxFzAVBgNV +BAMMDnNlbGZzaWduZWQuY29tMB4XDTIwMDkxODIwMzk1MloXDTMwMDkxNjIwMzk1 +MlowczELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM +DVNhbiBGcmFuY2lzY28xHjAcBgNVBAoMFUNsb3VkZmxhcmUgVGVzdCBTdWl0ZTEX +MBUGA1UEAwwOc2VsZnNpZ25lZC5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQCuFbjnE8gTFMrcCXmiP4t1wrK0uW5JSvWpxZAfTHroka/o8wBcKa1c +7dXOGSEzKkTdsmrAkvi2KXMEAd08iwnY52xQ3vpaQDCiBhJhLUGaG2nJ5iH6A3CX +VfsoHccFTp3N4/iiCjxyxnUoQZW1fuun5A9cow6F8xNa7EPtPMJsK7nUYDW2PLj4 +881aphUM483gS/Ph5IpaZs6bRP0HyscdSC8hoIZxkOfIgp8a9BvgnaK8cPhoNGFl +HNu4hU+0cxjke/iz9iKRHtdcyuKnRMv8kt+acTpdgWl5E4nmvwXFloPeUuUAEgcc +qcp9Uai2dp9XKfxAGW2wEQPpZseDH7mZ7+NwqxJ2z4R55fdIn8jmALJdz+npvpRr +QHHc6k9jv0iYv9XwZOqT1crlzwcCo3x8A7oD+sJrat5oY1zBXjNzLpb9DKyVQ1em +Ho/7VrLFtK+rJzI/b7D0r6GKk/h3SeqxmgN22fFPcbEM2eUIibUvmCB4OLooWkBs +eSeDr5wMZ7u9ExljGLywKHnOQQ7dlVUWeN5cncv9yU05fWE/whPEOri1ksyNdYr6 +kjIY1NYKmXfRaKaR9/JCVkhZj0H8VI6QpkqVHKgI5UMeE5dHMYbxJv0lmG+w6XN1 +Zew7DZRTidlBa6COxgCeQydxRTORCCPYQVYAGY5XiYtmWLGmsQjC1QIDAQABMA0G +CSqGSIb3DQEBCwUAA4ICAQAgGv+gvw5X9ftkGu/FEFK15dLHlFZ25tKHJw3LhJEf +xlDOCFI/zR+h2PFdVzks14LLrf4sSkRfJVkk2Qe5uRhHLcgnPIkCkJpGlpFMx2+V +O6azhJlnLEYeVXuzNiQHC+9LJH8i3NK37O8Z1z2EGsAz9kR09OBEvgDjSXFxCN0J +KLAMe4wfAhjUUt9/0bm9u7FYWyj0D5dUVeAul9X3Vo1HfffNovq2cuUlL1AG5Ku+ +nPkxGckBo/Lc7jZQRcoZ2+mtvsfyMH5l9OW6JRrnC/Rf5P9bEjUcAskMh5WRdHSL +j98oCkosxg2ndTXke091lToqr7sZ1kiGA+Bj4cPlVXckQn3WU7GiUSSRqotZtn8g +EMT2iqHH3/iJOgtDe8XPWdBYNDeDFRVNpOtgCuYLXdz/Vli0Cecm3escbW/+GZ9P +vgZoNUej8/WTWHNy732N1cHvSbT3kLN6uONP4wNelh+UnfmiG10O54x7iaM3grt9 +YvQ1I1G60NCj1tF9KvrCYCK/wnXnTWhlNZ4y+XbILFqE+k8zqiNzGZV9a8FAzht2 +APsm2JzzZz6Ph6Zw8fVOS/LX7WgF/kNe5nIzVLqyFXtFxgomXaoxbADUTe16TVb3 +6sV8p7nlq2r7Dr0+uROm7ZEg1F23SiieDoRvw5fUbRhZCU93fv7Nt7hWlKP+UqJj +Zg== +-----END CERTIFICATE----- diff --git a/pingora-proxy/tests/utils/conf/keys/ca1.key.pem b/pingora-proxy/tests/utils/conf/keys/ca1.key.pem new file mode 100644 index 0000000..813dbe5 --- /dev/null +++ b/pingora-proxy/tests/utils/conf/keys/ca1.key.pem @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY----- diff --git a/pingora-proxy/tests/utils/conf/keys/ca2.crt b/pingora-proxy/tests/utils/conf/keys/ca2.crt new file mode 100644 index 0000000..021c59d --- /dev/null +++ b/pingora-proxy/tests/utils/conf/keys/ca2.crt @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFbTCCA1UCFDsRVhSk+Asz9Q9BwsvZucCbYA5/MA0GCSqGSIb3DQEBCwUAMHMx +CzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4g +RnJhbmNpc2NvMR4wHAYDVQQKDBVDbG91ZGZsYXJlIFRlc3QgU3VpdGUxFzAVBgNV +BAMMDnNlbGZzaWduZWQuY29tMB4XDTIwMDkxODIwMzk1MloXDTMwMDkxNjIwMzk1 +MlowczELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM +DVNhbiBGcmFuY2lzY28xHjAcBgNVBAoMFUNsb3VkZmxhcmUgVGVzdCBTdWl0ZTEX +MBUGA1UEAwwOc2VsZnNpZ25lZC5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQCuFbjnE8gTFMrcCXmiP4t1wrK0uW5JSvWpxZAfTHroka/o8wBcKa1c +7dXOGSEzKkTdsmrAkvi2KXMEAd08iwnY52xQ3vpaQDCiBhJhLUGaG2nJ5iH6A3CX +VfsoHccFTp3N4/iiCjxyxnUoQZW1fuun5A9cow6F8xNa7EPtPMJsK7nUYDW2PLj4 +881aphUM483gS/Ph5IpaZs6bRP0HyscdSC8hoIZxkOfIgp8a9BvgnaK8cPhoNGFl +HNu4hU+0cxjke/iz9iKRHtdcyuKnRMv8kt+acTpdgWl5E4nmvwXFloPeUuUAEgcc +qcp9Uai2dp9XKfxAGW2wEQPpZseDH7mZ7+NwqxJ2z4R55fdIn8jmALJdz+npvpRr +QHHc6k9jv0iYv9XwZOqT1crlzwcCo3x8A7oD+sJrat5oY1zBXjNzLpb9DKyVQ1em +Ho/7VrLFtK+rJzI/b7D0r6GKk/h3SeqxmgN22fFPcbEM2eUIibUvmCB4OLooWkBs +eSeDr5wMZ7u9ExljGLywKHnOQQ7dlVUWeN5cncv9yU05fWE/whPEOri1ksyNdYr6 +kjIY1NYKmXfRaKaR9/JCVkhZj0H8VI6QpkqVHKgI5UMeE5dHMYbxJv0lmG+w6XN1 +Zew7DZRTidlBa6COxgCeQydxRTORCCPYQVYAGY5XiYtmWLGmsQjC1QIDAQABMA0G +CSqGSIb3DQEBCwUAA4ICAQAgGv+gvw5X9ftkGu/FEFK15dLHlFZ25tKHJw3LhJEf +xlDOCFI/zR+h2PFdVzks14LLrf4sSkRfJVkk2Qe5uRhHLcgnPIkCkJpGlpFMx2+V +O6azhJlnLEYeVXuzNiQHC+9LJH8i3NK37O8Z1z2EGsAz9kR09OBEvgDjSXFxCN0J +KLAMe4wfAhjUUt9/0bm9u7FYWyj0D5dUVeAul9X3Vo1HfffNovq2cuUlL1AG5Ku+ +nPkxGckBo/Lc7jZQRcoZ2+mtvsfyMH5l9OW6JRrnC/Rf5P9bEjUcAskMh5WRdHSL +j98oCkosxg2ndTXke091lToqr7sZ1kiGA+Bj4cPlVXckQn3WU7GiUSSRqotZtn8g +EMT2iqHH3/iJOgtDe8XPWdBYNDeDFRVNpOtgCuYLXdz/Vli0Cecm3escbW/+GZ9P +vgZoNUej8/WTWHNy732N1cHvSbT3kLN6uONP4wNelh+UnfmiG10O54x7iaM3grt9 +YvQ1I1G60NCj1tF9KvrCYCK/wnXnTWhlNZ4y+XbILFqE+k8zqiNzGZV9a8FAzht2 +APsm2JzzZz6Ph6Zw8fVOS/LX7WgF/kNe5nIzVLqyFXtFxgomXaoxbADUTe16TVb3 +6sV8p7nlq2r7Dr0+uROm7ZEg1F23SiieDoRvw5fUbRhZCU93fv7Nt7hWlKP+UqJj +Zg== +-----END CERTIFICATE----- diff --git a/pingora-proxy/tests/utils/conf/keys/ca_chain.cert b/pingora-proxy/tests/utils/conf/keys/ca_chain.cert new file mode 100644 index 0000000..2cb2caf --- /dev/null +++ b/pingora-proxy/tests/utils/conf/keys/ca_chain.cert @@ -0,0 +1,60 @@ +-----BEGIN CERTIFICATE----- +MIIEjjCCAnagAwIBAgIUHIB/tqjZJaKIgeWwvXRt03C0yIMwDQYJKoZIhvcNAQEL +BQAwXzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1TYW4gRnJh +bmNpc2NvMRAwDgYDVQQKDAdSb290IENBMRkwFwYDVQQDDBByb290LnBpbmdvcmEu +b3JnMB4XDTIyMTExMDE5MzI0M1oXDTI1MDgwNjE5MzI0M1owTjELMAkGA1UEBhMC +VVMxCzAJBgNVBAgMAkNBMRgwFgYDVQQKDA9JbnRlcm1lZGlhdGUgQ0ExGDAWBgNV +BAMMD2ludC5waW5nb3JhLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAL4klMT1Bc4vYWN7zF+x7x34s3L51Sve3AVydGGtzej2hC3m4CictVfKfkC6 +jMNRo3mpUsnAJSbyRh91fec8nnOT8MEYnmm05Lbf5DG4RULrKSg52zge4SFTLO2n +2eCa4SYwRpj+MQmFrCQ++s9gJ/5weN95z23XAS1EL2GK50Z/fKQfRCo+aZTRB6dU +KK2cUwuDAHTkVSePVAX8KGcZu2Qm/jTBlcDIfn7OmTu2g/n5YSRJg3MWKeJlAbVo +VNxmaRYQOs2X7y4WwcSAfEncyVXRzqFxEfSDnq2A2+pp/sKoCjTgE6n94SzyqyFm +yJ8FmvV79qCDHSaeIhR5qQEIlO8CAwEAAaNTMFEwHQYDVR0OBBYEFP5ivTJr/S6Z +VpOI4+JykGPID8s3MB8GA1UdIwQYMBaAFJ5hR0odQYOtYsY3P18WIC2byI1oMA8G +A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBAM337XP2Hm7LE3KLW+nn +khyj82ahj2k2+H/OdwGqzfqHCObTP+ydNJhOQVD+r255qQC9eAvd6ivF/h1tJOvv +Ed8vQMfLCO9VDFy6KCmlZQV6djRU1QXJIR/jf7TNqrFOcuKPGv5Vs6JwDdaHc0ae +ug7CGppnu5cxf/04sa7pWOdCFbhDRtfooo9fgGN2jcTFqfGyzocBwx7dgqEmZkae +yJAH0x4ldpKM9aO44h0Uy36c5RaWmdyFIh88QW62NoHamfwZoaVyycn82wcP4fFG +PRHm/AaDkYFGiQy22y7DD+MeZNUgCcAJpDYxfe87Cm4dw9NweMF6Jpo/8Ib1oLPq +E3miiFjWQwpMhxSQxpjqR92FPs9+/ktvYqbbMlyu/tju0rK17DXUi1zSIHoydPt0 +ymwWMxg7Jxpmg0x+eyWr5CP/ULM+F2Tk9W7x0B5DnpDJeCk+1ydUhII9AnTOCUWs +0VRlqTgFKahkHfiLBjPaLCgA0D3dz06EfEq5tmC8t0MDAqw9M4bDdow29K0aN6K8 +Gax7S5EK9aK09+HJ+7T5uxkUC+iIzfk53RhAfQiXdyKPpkbndRP67OiaAwk+hIXm +U1d1GsC854KYQs2GtHHvBcTGEADfU36TF/w2oJYQIrBjd23ZCf9jFK/WQ5GBFitT +ljoURxQQQy3LGjcH8W18JdRE +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFnzCCA4egAwIBAgIUE5kg5Z26V4swShJoSwfNVsJkHbYwDQYJKoZIhvcNAQEL +BQAwXzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1TYW4gRnJh +bmNpc2NvMRAwDgYDVQQKDAdSb290IENBMRkwFwYDVQQDDBByb290LnBpbmdvcmEu +b3JnMB4XDTIyMTExMDE5MjY1MFoXDTQyMTExMDE5MjY1MFowXzELMAkGA1UEBhMC +VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMRAwDgYDVQQK +DAdSb290IENBMRkwFwYDVQQDDBByb290LnBpbmdvcmEub3JnMIICIjANBgkqhkiG +9w0BAQEFAAOCAg8AMIICCgKCAgEA4s1XxwZruaRwuDX1IkM2oxdSdjg7FeUp8lsN +Uix4NdXz8IoQWRzCfFuRBKFHptahutSO6Bbewm9XmU2hHG7aoCqaZqEVQ/3KRLZ4 +mzaNBCzDNgPTmDkz/DZKzOVuyVvbmTOsLn53yxKnFP9MEDIEemqGiM80MmFfCm/o +0vLkjwkRpreMsWPUhrq3igTWRctUYMJAeDsEaaXB1k5ovWICrEylMzslgSNfoBed +NmBpurz+yQddKNMTb/SLYxa7B1uZKDRSIXwwOZPdBDyUdlStUPodNG/OzprN+bRC +oFRB9EFG1m5oPJXQIalePj0dwhXl/bkV4uRxCSZmBZK3fbtLMF+Wkg2voTrn51Yv +lKkzUQoEX6WWtUameZZbUB8TbW2lmANuvGBmvBbj3+4ztmtJPXfJBkckCeUC6bwC +4CKrgB587ElY357Vqv/HmRRC9kxdzpOS9s5CtcqJ3Dg1TmLajyRQkf8wMqk0fhh7 +V+VrPXB030MGABXh5+B2HOsF307vF030v7z+Xp5VRLGBqmDwK0Reo2h8cg9PkMDS +5Qc2zOJVslkJ+QYdkea1ajVpCsFbaC1JPmRWihTllboUqsk9oSS3jcIZ8vW3QKMg +ZbKtVbtVHr3mNGWuVs96iDN5Us3SJ6KGS8sanrAYAAB/NKd1Wl3I0aVtcb6eOONd +edf9+b0CAwEAAaNTMFEwHQYDVR0OBBYEFJ5hR0odQYOtYsY3P18WIC2byI1oMB8G +A1UdIwQYMBaAFJ5hR0odQYOtYsY3P18WIC2byI1oMA8GA1UdEwEB/wQFMAMBAf8w +DQYJKoZIhvcNAQELBQADggIBAIrpAsrPre3R4RY0JmnvomgH+tCSMHb6dW52YrEl +JkEG4cVc5MKs5QfPp8l2d1DngqiOUnOf0MWwWNDidHQZKrWs59j67L8qKN91VQKe +cSNEX3iMFvE59Hr0Ner6Kr09wZLHVVNGcy0FdhWpJdDUGDoQjfL7n7usJyCUqWSq +/pa1I9Is3ZfeQ5f7Ztrdz35vVPj+0BlHXbZM5AZi8Dwf3vXFBlPty3fITpE65cty +cYnbpGto+wDoZj9fkKImjK21QsJdmHwaWRgmXX3WbdFBAbScTjDOc5Mls2VY8rSh ++xLI1KMB0FHSJqrGoFN3uE+G1vJX/hgn98KZKob23yJr2TWr9LHI56sMfN5xdd5A +iOHxYODSrIAi1k+bSlDz6WfEtufoqwBwHiog4nFOXrlHpGO6eUB1QjaQJZwKn2zE +3BjqJOoqbuBMg5XZRjihHcVVuZdU39/zQDwqliNpx3km4FzOiEoBABGzLP+Qt0Ch +cJFS1Yc8ffv616yP4A9qkyogk9YBBvNbDLB7WV8h8p1s4JP3f5aDUlxtAD+E+3aJ +8mrb3P7/0A2QyxlgX4qQOdj++b7GzXDxxLgOimJ4pLo0fdY8KWMeHvZPiMryHkMx +3GSZCHeleSVBCPB2pPCzUqkkKADbjBX3SYJsAMF9uXQAR4U7wojjvAmbt6vJEh6j +TEUG +-----END CERTIFICATE----- diff --git a/pingora-proxy/tests/utils/conf/keys/ca_chain.srl b/pingora-proxy/tests/utils/conf/keys/ca_chain.srl new file mode 100644 index 0000000..5c31864 --- /dev/null +++ b/pingora-proxy/tests/utils/conf/keys/ca_chain.srl @@ -0,0 +1 @@ +764CA822243398735D12CB8F1295AEDF38869BA7 diff --git a/pingora-proxy/tests/utils/conf/keys/cert_chain.crt b/pingora-proxy/tests/utils/conf/keys/cert_chain.crt new file mode 100644 index 0000000..6b19e08 --- /dev/null +++ b/pingora-proxy/tests/utils/conf/keys/cert_chain.crt @@ -0,0 +1,40 @@ +-----BEGIN CERTIFICATE----- +MIICtzCCAl2gAwIBAgIUC8kzFXZNRqjR158InTieHg1VrWowCgYIKoZIzj0EAwIw +gY4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1T +YW4gRnJhbmNpc2NvMRgwFgYDVQQKEw9IYXBweUNlcnQsIEluYy4xHzAdBgNVBAsT +FkhhcHB5Q2VydCBJbnRlcm1lZGlhdGUxFzAVBgNVBAMTDihkZXYgdXNlIG9ubHkp +MCAXDTE5MTIwOTE5NDgwMFoYDzIxMTkxMTE1MTk0ODAwWjCBgTELMAkGA1UEBhMC +VVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28x +GTAXBgNVBAoTEERFUiBpcyBGdW4sIEluYy4xETAPBgNVBAsTCEVuY29kaW5nMRcw +FQYDVQQDEw4oZGV2IHVzZSBvbmx5KTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA +BJSBMLYEVPgjmd2vWgMpN9LupZa56T7Ds1+wAlyMphLDN56PWuphsrNsEwiIIeNv +MtRTPRuoiBkfvMiWON6nkGWjgaEwgZ4wDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQM +MAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFOYNuOCrYKnTFIEV +ck5845y/yZHkMB8GA1UdIwQYMBaAFFZRXwepqUwm9Kh+repV7LkBDnEHMCkGA1Ud +EQQiMCCCCWRlcmlzLmZ1boITd2VsbGtub3duLmRlcmlzLmZ1bjAKBggqhkjOPQQD +AgNIADBFAiEA9XAQ1Xi4Lav8LKzXZMSOHHj21ycqf3grnUfKJ6iwRvkCIDevfipo +qIuR/Dnt1bBoXxFKv0w/LpH/89jIohUQwVSc +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIJAN0mCzwZkgZKMA0GCSqGSIb3DQEBCwUAMHgxCzAJBgNV +BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNp +c2NvMRgwFgYDVQQKDA9DbG91ZEZsYXJlLCBJbmMxDDAKBgNVBAsMA1ImRDEUMBIG +A1UEAwwLZXhhbXBsZS5jb20wHhcNMTYwNjMwMTY1NTM5WhcNMzYwNjI1MTY1NTM5 +WjB4MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwN +U2FuIEZyYW5jaXNjbzEYMBYGA1UECgwPQ2xvdWRGbGFyZSwgSW5jMQwwCgYDVQQL +DANSJkQxFDASBgNVBAMMC2V4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA7y+v+9Eh2LjFoZbUetrJc+IVPb92PBNNY5AM+Nxukzj/9hth +tu7UPFnO+USrh+nFtR/rFfC6UwUqCtPaQ4EkSVJslR8f34GoOlc8zz7+dq9sGGu0 +hUPCLiptfBdIu73l0XqMd+xdGprl8hMdpH0CyKhAqTpv/00cmFobFwm1Fbf146hb +YAhyP6rIzDlrhvYFe3sFwAIjXQ0qyN+ffm/Ot1iFdYER24sl63XfwBPS97DwO70p +4jtbea8zlN58CFmTTK899J1f4MGbzvMyttdHG+WjhLNplB7fhtBdiHes2EdQws2S +TKbK5D/69OYXSVCwimcOnlklcJ1NpQJFFaWeKQIDAQABo1AwTjAdBgNVHQ4EFgQU +cu65A8EdrKWjFy9PZSRvSu8+4G0wHwYDVR0jBBgwFoAUcu65A8EdrKWjFy9PZSRv +Su8+4G0wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAl3lAgKb+3NQ/ ++a+ooaML1Ndmh7h+UWl4bXx1TXwaLAi0iIujrAa3AM86vqKxFeCwZC9bAPEyGQrH +AF8JQbWAa2SckSDPSxM1ETV7EtJS4plaSfWxzX/m8jtd7D5RbzyE/qUH5JsXvCta +rKOMJPNvSfTuxQMX/Qyp0cHZUr/3ylUhdLWYsNwTAlQgx0OK8w+zWx6ESCM52Cz4 +Gqjpgcq6qylE2RoNmY0L+xb1B0YS+fslcjSXJZ/Z1j9mVrUM4wuekgcIxJfUrfhv +/957d4I04iMp6F/XgrrKUewCGiifcDi87nwoqHJwSIWG33LTb4e8mSe4Y83Fh8L2 +KWQDqcnYug== +-----END CERTIFICATE----- \ No newline at end of file diff --git a/pingora-proxy/tests/utils/conf/keys/curve_test.384.crt b/pingora-proxy/tests/utils/conf/keys/curve_test.384.crt new file mode 100644 index 0000000..b44accd --- /dev/null +++ b/pingora-proxy/tests/utils/conf/keys/curve_test.384.crt @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBnDCCASOgAwIBAgIJAJ8dDVMCYWE3MAoGCCqGSM49BAMDMBsxGTAXBgNVBAMM +EG9wZW5ydXN0eTM4NC5vcmcwHhcNMjMwNDA3MTY0NzEyWhcNMzMwNDA0MTY0NzEy +WjAbMRkwFwYDVQQDDBBvcGVucnVzdHkzODQub3JnMHYwEAYHKoZIzj0CAQYFK4EE +ACIDYgAENKtL8ciBDxA9G2auTbtbteNu8DI7gp0039+J6Z29laQpHLMw8MH7Wegx +HTv9RTXcf1sTCBloZh8qTvZTDh1yi7kjhZ2yLdVEVoakC5HBKvWzo1ewjSkOfBX7 +LF4p/8ULozMwMTAvBgNVHREEKDAmghIqLm9wZW5ydXN0eTM4NC5vcmeCEG9wZW5y +dXN0eTM4NC5vcmcwCgYIKoZIzj0EAwMDZwAwZAIwL8ad/dyrC62bFC7gGZkRzaTm +r2XlaMk6LB02IbVJgQytu+p50pnAgELVXISLP8LIAjBAjQ71pDbCjfg8Ts6iOnWH +p4R+Z2BjbTZu+Kmn1x8nyo2OJcchRYTRAKMS7YWstIk= +-----END CERTIFICATE----- diff --git a/pingora-proxy/tests/utils/conf/keys/curve_test.384.key.pem b/pingora-proxy/tests/utils/conf/keys/curve_test.384.key.pem new file mode 100644 index 0000000..391da5b --- /dev/null +++ b/pingora-proxy/tests/utils/conf/keys/curve_test.384.key.pem @@ -0,0 +1,6 @@ +-----BEGIN EC PRIVATE KEY----- +MIGkAgEBBDCWPID9PlALCL+dNPdlEBw2fP4cU56akYDeV08fpY+DkhaJicPxAilY +2T68Epv7nh6gBwYFK4EEACKhZANiAAQ0q0vxyIEPED0bZq5Nu1u1427wMjuCnTTf +34npnb2VpCkcszDwwftZ6DEdO/1FNdx/WxMIGWhmHypO9lMOHXKLuSOFnbIt1URW +hqQLkcEq9bOjV7CNKQ58FfssXin/xQs= +-----END EC PRIVATE KEY----- diff --git a/pingora-proxy/tests/utils/conf/keys/curve_test.521.crt b/pingora-proxy/tests/utils/conf/keys/curve_test.521.crt new file mode 100644 index 0000000..b4a24d4 --- /dev/null +++ b/pingora-proxy/tests/utils/conf/keys/curve_test.521.crt @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB5zCCAUmgAwIBAgIJALxqm9BrQU12MAoGCCqGSM49BAMEMBsxGTAXBgNVBAMM +EG9wZW5ydXN0eTUyMS5vcmcwHhcNMjMwNDA3MTY0NjU4WhcNMzMwNDA0MTY0NjU4 +WjAbMRkwFwYDVQQDDBBvcGVucnVzdHk1MjEub3JnMIGbMBAGByqGSM49AgEGBSuB +BAAjA4GGAAQA9LXDr66Cx/DZYnSacGu0FxlSx/e7xTm49g2QGU7TkO8TEyaOkErl +IaqJE7YxQp+CUMfelVVkUJmVlJ4Fkrl3nR4A3YLDjEYihXnuLZajbwkjC7vzKO8A +O2ln8R5JSzClUoTu7s2nok7tw/6dP4i08YPk4Pkxm5NHIok0uFmoaJpdkq6jMzAx +MC8GA1UdEQQoMCaCEioub3BlbnJ1c3R5NTIxLm9yZ4IQb3BlbnJ1c3R5NTIxLm9y +ZzAKBggqhkjOPQQDBAOBiwAwgYcCQgCdVxTjVAPCIouh1HH4haJDpS1/g30jcTj6 +FGvyxofIX4Q6fO3Ig8DlJa+SrDq2f75/f8RSC71NB6peNjP8IARCOAJBKEMcXjK5 +btvZxg+puzyxuMNRtUUk/Re/pzzLJbi7o6MWVNgLQJ3d9kUVHzbQEXNiUe82vbYK +uairSMDS6Dl1j/A= +-----END CERTIFICATE----- diff --git a/pingora-proxy/tests/utils/conf/keys/curve_test.521.key.pem b/pingora-proxy/tests/utils/conf/keys/curve_test.521.key.pem new file mode 100644 index 0000000..739b862 --- /dev/null +++ b/pingora-proxy/tests/utils/conf/keys/curve_test.521.key.pem @@ -0,0 +1,7 @@ +-----BEGIN EC PRIVATE KEY----- +MIHbAgEBBEFiMUgbEqjcf3K4Ba+CFUv20+ryJq9REjWUkoi9AgkpGuEAqLQza3CM +kSGSiPdm9gWmpeLlCExPVJRbcTmAhoZUcKAHBgUrgQQAI6GBiQOBhgAEAPS1w6+u +gsfw2WJ0mnBrtBcZUsf3u8U5uPYNkBlO05DvExMmjpBK5SGqiRO2MUKfglDH3pVV +ZFCZlZSeBZK5d50eAN2Cw4xGIoV57i2Wo28JIwu78yjvADtpZ/EeSUswpVKE7u7N +p6JO7cP+nT+ItPGD5OD5MZuTRyKJNLhZqGiaXZKu +-----END EC PRIVATE KEY----- diff --git a/pingora-proxy/tests/utils/conf/keys/ex1.crt b/pingora-proxy/tests/utils/conf/keys/ex1.crt new file mode 100644 index 0000000..2846e9f --- /dev/null +++ b/pingora-proxy/tests/utils/conf/keys/ex1.crt @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtzCCAl2gAwIBAgIUC8kzFXZNRqjR158InTieHg1VrWowCgYIKoZIzj0EAwIw +gY4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1T +YW4gRnJhbmNpc2NvMRgwFgYDVQQKEw9IYXBweUNlcnQsIEluYy4xHzAdBgNVBAsT +FkhhcHB5Q2VydCBJbnRlcm1lZGlhdGUxFzAVBgNVBAMTDihkZXYgdXNlIG9ubHkp +MCAXDTE5MTIwOTE5NDgwMFoYDzIxMTkxMTE1MTk0ODAwWjCBgTELMAkGA1UEBhMC +VVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28x +GTAXBgNVBAoTEERFUiBpcyBGdW4sIEluYy4xETAPBgNVBAsTCEVuY29kaW5nMRcw +FQYDVQQDEw4oZGV2IHVzZSBvbmx5KTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA +BJSBMLYEVPgjmd2vWgMpN9LupZa56T7Ds1+wAlyMphLDN56PWuphsrNsEwiIIeNv +MtRTPRuoiBkfvMiWON6nkGWjgaEwgZ4wDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQM +MAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFOYNuOCrYKnTFIEV +ck5845y/yZHkMB8GA1UdIwQYMBaAFFZRXwepqUwm9Kh+repV7LkBDnEHMCkGA1Ud +EQQiMCCCCWRlcmlzLmZ1boITd2VsbGtub3duLmRlcmlzLmZ1bjAKBggqhkjOPQQD +AgNIADBFAiEA9XAQ1Xi4Lav8LKzXZMSOHHj21ycqf3grnUfKJ6iwRvkCIDevfipo +qIuR/Dnt1bBoXxFKv0w/LpH/89jIohUQwVSc +-----END CERTIFICATE----- diff --git a/pingora-proxy/tests/utils/conf/keys/ex1.key.b64 b/pingora-proxy/tests/utils/conf/keys/ex1.key.b64 new file mode 100644 index 0000000..a3d18c5 --- /dev/null +++ b/pingora-proxy/tests/utils/conf/keys/ex1.key.b64 @@ -0,0 +1 @@ +AAEAAJIx7XoAAAABAAAAIAAAAAAAAAACAAH//wAAABAAAAAAW66OYKnvlI3LQETZc85HajCUyhsAAAAAAAAAAAAAAAD+EOoVAAAAAQAAAKAAAAAAAAAAAv////8AAACQAAAAB018vkpfL1Bmrc2c9A5NcT3M3EdG+ZQfTZGN4BHUIpzOXK85cESryj5aFHIOh37fuRZlcCO8i9G44x+xNE45M9nw7tI2D4Sf1zraq9titAqMj3I+I3CZW2LX61CHyMYlfdxG/F7OR7dz1kbUcJeP73l+v65cPIEwek6gzvTZOIz2W8AnFdc0jW3iZFcgAhPmJzkBs4EAAAABAAAAMAAAAAAAAAACAAAAAAAAACAAAAAM0IInmYQDB4EBkHw182qCs6LncTgAAAAAAAAAAAAAAAA= \ No newline at end of file diff --git a/pingora-proxy/tests/utils/conf/keys/intermediate.crt b/pingora-proxy/tests/utils/conf/keys/intermediate.crt new file mode 100644 index 0000000..7d34a41 --- /dev/null +++ b/pingora-proxy/tests/utils/conf/keys/intermediate.crt @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEjjCCAnagAwIBAgIUHIB/tqjZJaKIgeWwvXRt03C0yIMwDQYJKoZIhvcNAQEL +BQAwXzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1TYW4gRnJh +bmNpc2NvMRAwDgYDVQQKDAdSb290IENBMRkwFwYDVQQDDBByb290LnBpbmdvcmEu +b3JnMB4XDTIyMTExMDE5MzI0M1oXDTI1MDgwNjE5MzI0M1owTjELMAkGA1UEBhMC +VVMxCzAJBgNVBAgMAkNBMRgwFgYDVQQKDA9JbnRlcm1lZGlhdGUgQ0ExGDAWBgNV +BAMMD2ludC5waW5nb3JhLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAL4klMT1Bc4vYWN7zF+x7x34s3L51Sve3AVydGGtzej2hC3m4CictVfKfkC6 +jMNRo3mpUsnAJSbyRh91fec8nnOT8MEYnmm05Lbf5DG4RULrKSg52zge4SFTLO2n +2eCa4SYwRpj+MQmFrCQ++s9gJ/5weN95z23XAS1EL2GK50Z/fKQfRCo+aZTRB6dU +KK2cUwuDAHTkVSePVAX8KGcZu2Qm/jTBlcDIfn7OmTu2g/n5YSRJg3MWKeJlAbVo +VNxmaRYQOs2X7y4WwcSAfEncyVXRzqFxEfSDnq2A2+pp/sKoCjTgE6n94SzyqyFm +yJ8FmvV79qCDHSaeIhR5qQEIlO8CAwEAAaNTMFEwHQYDVR0OBBYEFP5ivTJr/S6Z +VpOI4+JykGPID8s3MB8GA1UdIwQYMBaAFJ5hR0odQYOtYsY3P18WIC2byI1oMA8G +A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBAM337XP2Hm7LE3KLW+nn +khyj82ahj2k2+H/OdwGqzfqHCObTP+ydNJhOQVD+r255qQC9eAvd6ivF/h1tJOvv +Ed8vQMfLCO9VDFy6KCmlZQV6djRU1QXJIR/jf7TNqrFOcuKPGv5Vs6JwDdaHc0ae +ug7CGppnu5cxf/04sa7pWOdCFbhDRtfooo9fgGN2jcTFqfGyzocBwx7dgqEmZkae +yJAH0x4ldpKM9aO44h0Uy36c5RaWmdyFIh88QW62NoHamfwZoaVyycn82wcP4fFG +PRHm/AaDkYFGiQy22y7DD+MeZNUgCcAJpDYxfe87Cm4dw9NweMF6Jpo/8Ib1oLPq +E3miiFjWQwpMhxSQxpjqR92FPs9+/ktvYqbbMlyu/tju0rK17DXUi1zSIHoydPt0 +ymwWMxg7Jxpmg0x+eyWr5CP/ULM+F2Tk9W7x0B5DnpDJeCk+1ydUhII9AnTOCUWs +0VRlqTgFKahkHfiLBjPaLCgA0D3dz06EfEq5tmC8t0MDAqw9M4bDdow29K0aN6K8 +Gax7S5EK9aK09+HJ+7T5uxkUC+iIzfk53RhAfQiXdyKPpkbndRP67OiaAwk+hIXm +U1d1GsC854KYQs2GtHHvBcTGEADfU36TF/w2oJYQIrBjd23ZCf9jFK/WQ5GBFitT +ljoURxQQQy3LGjcH8W18JdRE +-----END CERTIFICATE----- diff --git a/pingora-proxy/tests/utils/conf/keys/intermediate.csr b/pingora-proxy/tests/utils/conf/keys/intermediate.csr new file mode 100644 index 0000000..8035e28 --- /dev/null +++ b/pingora-proxy/tests/utils/conf/keys/intermediate.csr @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICkzCCAXsCAQAwTjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRgwFgYDVQQK +DA9JbnRlcm1lZGlhdGUgQ0ExGDAWBgNVBAMMD2ludC5waW5nb3JhLm9yZzCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL4klMT1Bc4vYWN7zF+x7x34s3L5 +1Sve3AVydGGtzej2hC3m4CictVfKfkC6jMNRo3mpUsnAJSbyRh91fec8nnOT8MEY +nmm05Lbf5DG4RULrKSg52zge4SFTLO2n2eCa4SYwRpj+MQmFrCQ++s9gJ/5weN95 +z23XAS1EL2GK50Z/fKQfRCo+aZTRB6dUKK2cUwuDAHTkVSePVAX8KGcZu2Qm/jTB +lcDIfn7OmTu2g/n5YSRJg3MWKeJlAbVoVNxmaRYQOs2X7y4WwcSAfEncyVXRzqFx +EfSDnq2A2+pp/sKoCjTgE6n94SzyqyFmyJ8FmvV79qCDHSaeIhR5qQEIlO8CAwEA +AaAAMA0GCSqGSIb3DQEBCwUAA4IBAQAb7MY4eggHzheSS0wA2CtY1Q1YCU44XIjU +CuR0ht02jEZ5sXAvIvtrBfQdTZ3pWWbUwxfFmGcLUqS2aafQsVR5EHDl1YjAxy0Z +htIecE8Rb89p/O44pVdivLYPj4SvHUk0Hq7hkgyPL55Va0thMLSjjCyRouK4dX2d +gKnGfdFg5vkOjY7HWVJuWHioQTb5gjvF3dOTWbmJl3m5so5QJxjOjfA+iKvH+kOb +4/OnwmDYxJ/d+4sReiFeiOXWlwuubYpzAbi1TxsDcQGlp8PO6JjFA9PJqZuYZqhL +KzBwFqxujS12v6ccyqg2zLLveH9M9HgliAqDlSxsGvhyu19RVwtG +-----END CERTIFICATE REQUEST----- diff --git a/pingora-proxy/tests/utils/conf/keys/intermediate.key b/pingora-proxy/tests/utils/conf/keys/intermediate.key new file mode 100644 index 0000000..31ac627 --- /dev/null +++ b/pingora-proxy/tests/utils/conf/keys/intermediate.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC+JJTE9QXOL2Fj +e8xfse8d+LNy+dUr3twFcnRhrc3o9oQt5uAonLVXyn5AuozDUaN5qVLJwCUm8kYf +dX3nPJ5zk/DBGJ5ptOS23+QxuEVC6ykoOds4HuEhUyztp9ngmuEmMEaY/jEJhawk +PvrPYCf+cHjfec9t1wEtRC9hiudGf3ykH0QqPmmU0QenVCitnFMLgwB05FUnj1QF +/ChnGbtkJv40wZXAyH5+zpk7toP5+WEkSYNzFiniZQG1aFTcZmkWEDrNl+8uFsHE +gHxJ3MlV0c6hcRH0g56tgNvqaf7CqAo04BOp/eEs8qshZsifBZr1e/aggx0mniIU +eakBCJTvAgMBAAECggEAHukXfkVO4kv1ixSvDseAVeD+WyyeKPmbzw7iOJbmqH6a +0lN8EV4YZOM4TxGEnKQC7V5HZSDlaUVtfOO+yf6iy6s7MkjsR8buf4Q6NpL8P3q3 +QCDXsHHkq2Q4I5Jr6wWCoJCsiWaZVjDy4RmT8G5zUfu6yqmkvPh86nzxLuxD2MPM +nu3eR7hbiCisk+Of6oIknRU8vhsnjOOkEZ5PyDAcQbxwbfXuARHayxNOsyM2bMKM +LvS01JRQHbDEm/vpjvMmoAuGk1EKyTnGxMmooEYKDYHTJQYYEZTRwJtD/YZD90aY +D7tg1YMAn80z6l2f1Mg1PN8X9yIhUhHL4uZfhGa1kQKBgQD5A8R3uwlTBCivYYM3 +WdICFJVhsKIS1M8mJgepNmZtggkaeGHrGiOWfXX8kr5Jqkw4QwvJyz1QFMVvathM +WbuY+1TCzvN7820n0luWFe8iGHqyuXBksroeW+d8p+qD6B1Y1YOtdb2/gmeYrWIH +pwTlalTsE0gVfh363/ow5GOHrQKBgQDDegqcPjjOd5EdlN19ga7x4NNWT/aT07UO +FC8Xwml6VvmN8cGn4z9dbzPB8Q6uUlgfwsyzO7DyXDxHQZA8iRb/5HjlEGJ3HYbC +lq5nkvgfM3GGVQ/7EbVt7TtDFE8ZQsObvS6KCIXDT5NL8JfypmajQYVnupgbBTlR +bjVOnrrSiwKBgC9KNd9/F7A6U/eqjx7N4gIfIpdg0ga9f3GBO2c5O46EaXIrdn0N +g8CqpuOGgri+rKbqpKx3+nbg2vXj1pv5VpUg9eHhJ4BcpFgxrM7972IMQBD9Aok9 +H/dwALA9u129kQUz10Pz3ksmWsI1+y303AstfF8w8jmSr+La8kqitPwpAoGBAJxV +uLKo2MnXuomMC3BbDU2JX7xCC5TC1qTB47/+zlj3wnKRjS32gzD4xM4xOmqUlMIi +C5C1Bpluxw6+Ets3UNurID0i030sciCiXi2bzzE09XBYC4Xi7dVSy/ij/3bWfJbL +wLLIiiJgPA+aBgwcpS2gM094XjoN/X9wwtV0ATptAoGBAIZ7jEYoz4G4wkM7qyeW +bA87hAlTcBY4kB9FueUHsPw3VYXQUVu6MB5YzgirRFMLTcGN+ltuZ9bRYxJSFiCi +R6eaBkMIBO6vrp5UDjrIuSAW6IpIFsgaVqFOZxkk4mkISef8d3b4n5JMpKNGrbFk +tlasWnqSVlC53w9u6yL+s07f +-----END PRIVATE KEY----- diff --git a/pingora-proxy/tests/utils/conf/keys/intermediate.srl b/pingora-proxy/tests/utils/conf/keys/intermediate.srl new file mode 100644 index 0000000..8eb8f1d --- /dev/null +++ b/pingora-proxy/tests/utils/conf/keys/intermediate.srl @@ -0,0 +1 @@ +199D7F7B72FA2892E58A80EC205EE63A20543BE0 diff --git a/pingora-proxy/tests/utils/conf/keys/key.pem b/pingora-proxy/tests/utils/conf/keys/key.pem new file mode 100644 index 0000000..0fe68f2 --- /dev/null +++ b/pingora-proxy/tests/utils/conf/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-proxy/tests/utils/conf/keys/leaf.crt b/pingora-proxy/tests/utils/conf/keys/leaf.crt new file mode 100644 index 0000000..8ebd98c --- /dev/null +++ b/pingora-proxy/tests/utils/conf/keys/leaf.crt @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDQDCCAigCFHZMqCIkM5hzXRLLjxKVrt84hpunMA0GCSqGSIb3DQEBCwUAME4x +CzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEYMBYGA1UECgwPSW50ZXJtZWRpYXRl +IENBMRgwFgYDVQQDDA9pbnQucGluZ29yYS5vcmcwHhcNMjIxMTEwMTg1NzE0WhcN +MzIxMTA3MTg1NzE0WjBrMQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExFjAUBgNV +BAcMDVNhbiBGcmFuY2lzY28xITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5 +IEx0ZDEUMBIGA1UEAwwLcGluZ29yYS5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQCTvo3hkSRrrJfrfZ1LiujaffSuErWbkiHkqOqAMofsqmkt+S4K +BAbwcJN8g/HN7Jxr43lFo7kZeFQZ6utg6uywe4yBxppqAt4r/Th1tUBJ982Vcs9K +3sMyjWO9UgSyoQdRjjXKlUYI316SBPYgFiac1M2UocPycEavxIlYrpS7d1i1PCSj +ByMiBbalSxrwEv97FOlSW0f0COiLoV36SXuq8jNyrFzk4zZXCYz5WjgZSkm/iFJL +abbX5nTmrzLnfm7BSbpnRMdQtYUqYubR+rlBuiGZsDM9FRsT+H6uOQwgIKqGz6I+ +diBK3oIHeD4F5Lma6Evt66AGwrwDkNhSyQV1AgMBAAEwDQYJKoZIhvcNAQELBQAD +ggEBADn5HmEwQUn/Tbb+Lqh6Zp2K/RrOH7lEz4IE1N90mRPF2Aa8oOwE7dwWfsUr +dJqzkrARiiYMy1wL6P8xhBsStLJPf0RM9uIpfxIaq7fF5RhJPuc3rVfkDsnZeo+Q +zdXtBal8BlfGjLvZgZzIei6IlGZ/j8yHDcEVP8IpQoSLtrQpSWe4CwGoSXfx/JqA +SD2ZS46mEVQIaQ4QEZecVLEQQTeEYMX50HkD+ea9GsuSQF5cOfY/lrHuFa0tW0SX +zYWtq9XTwEc+nPPLL0UMQWFWlsMb7pS2vtQS93wm00G6rpFHVEyq1ePbmDxRsjV4 +cgEH6QwqLWOmGHx4xpw2ZESwnUY= +-----END CERTIFICATE----- diff --git a/pingora-proxy/tests/utils/conf/keys/leaf.csr b/pingora-proxy/tests/utils/conf/keys/leaf.csr new file mode 100644 index 0000000..7c3a206 --- /dev/null +++ b/pingora-proxy/tests/utils/conf/keys/leaf.csr @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICsDCCAZgCAQAwazELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQH +DA1TYW4gRnJhbmNpc2NvMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBM +dGQxFDASBgNVBAMMC3BpbmdvcmEub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAk76N4ZEka6yX632dS4ro2n30rhK1m5Ih5KjqgDKH7KppLfkuCgQG +8HCTfIPxzeyca+N5RaO5GXhUGerrYOrssHuMgcaaagLeK/04dbVASffNlXLPSt7D +Mo1jvVIEsqEHUY41ypVGCN9ekgT2IBYmnNTNlKHD8nBGr8SJWK6Uu3dYtTwkowcj +IgW2pUsa8BL/exTpUltH9Ajoi6Fd+kl7qvIzcqxc5OM2VwmM+Vo4GUpJv4hSS2m2 +1+Z05q8y535uwUm6Z0THULWFKmLm0fq5QbohmbAzPRUbE/h+rjkMICCqhs+iPnYg +St6CB3g+BeS5muhL7eugBsK8A5DYUskFdQIDAQABoAAwDQYJKoZIhvcNAQELBQAD +ggEBABu/Xes3RKEGof0N6jGbP9UgPeTm5ljIfqY1/xJT1uQTKNti7qn8OCzEBFGf +IvlXnqN3bjSK7wExan9hNZqJO2R2ye+Jliil39LsUellU9BL3TWayKFgu7h4eoCs +J1Yty2qibhxowzld3qhBIxJO1Qf2MAxM/O4KmBmiKLbPLRodRckGH+22JYqM3NNt +WXDyncHOBD1DpoMHfHgvdmdPPXuBoDTNbS9Wtyf/EmXck5Uj1rinBzlIJZJZxtkN +qlOW9HcBDBUeIJq4qt92niSia/9kfndrcnOSonylQHF0ALw6S6MHBVkok3Vro0Gc +CxMlJO8IQSxn11Xeg4WSCtTLipk= +-----END CERTIFICATE REQUEST----- diff --git a/pingora-proxy/tests/utils/conf/keys/leaf.key b/pingora-proxy/tests/utils/conf/keys/leaf.key new file mode 100644 index 0000000..d58e9f3 --- /dev/null +++ b/pingora-proxy/tests/utils/conf/keys/leaf.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEuwIBADANBgkqhkiG9w0BAQEFAASCBKUwggShAgEAAoIBAQCTvo3hkSRrrJfr +fZ1LiujaffSuErWbkiHkqOqAMofsqmkt+S4KBAbwcJN8g/HN7Jxr43lFo7kZeFQZ +6utg6uywe4yBxppqAt4r/Th1tUBJ982Vcs9K3sMyjWO9UgSyoQdRjjXKlUYI316S +BPYgFiac1M2UocPycEavxIlYrpS7d1i1PCSjByMiBbalSxrwEv97FOlSW0f0COiL +oV36SXuq8jNyrFzk4zZXCYz5WjgZSkm/iFJLabbX5nTmrzLnfm7BSbpnRMdQtYUq +YubR+rlBuiGZsDM9FRsT+H6uOQwgIKqGz6I+diBK3oIHeD4F5Lma6Evt66AGwrwD +kNhSyQV1AgMBAAECgf9K7dlcYhVBMRyF0gR0INRMpenxs+C8MDYAQaqsWZ7rPYHE ++cWKTtXgxeIGxDleC8yeQD9rkh0jTbiuwaBJBtwDT/rH1nF5p6Va/zwjIPP55N3e +wttenUYMh/3i24sxDM8pYsuPx8+SWwvGAmjQ3RW4Ht95rJDejmf1vIyWQp7Wc8C/ +i5/8YIznfP8TVBA5aggUKJ+aqsHlpBxuZ2+Lnv+Dn67cAiBR1uB7Pvtu25MhrocW +z8ZCgUhwcimmi0+ZoxJSd8wVA7bPJqg4gBeELCbWiR4Bnn2vLu55/UJ4jtoVRU3l +vzlrRZTBRVElocojX7u+0sdovWtD0SIEzN+7sWcCgYEAxXsy5w+HSefIBrtsIod4 +GtpXfGusgUOqR9c57Tq8boOkT+5vkTAovk+BRXQGWcaU3a2wEqbPQ6UQhWOoBiTu ++eiwhv7dUiczDte1xABkyqHYeaE+VMiGh+8orR/AxQWHtYQW01Fa1CSayGW9GEIY +94BhmmvQuMUklM9gYDDO4RsCgYEAv4ZYsIimjhMO47X3A86GA4hgBoI1IO9WZWjK +SmYNdWPcH7A5iamfdmk4frSjDVZ5oHHKtx9JhgpKucFjRCLzWVJw34JohExICHxu +FKeoVSKiUcmke5kE+wDRpz38vCUzThDAdI4kK5ALt35XCp0GLahhgral7C0bO5L3 +K9NNrK8CgYEAhsvHPQzObdX2JRI9h3wssTekS9s7TqifTJZOhe13vX/B4oWARfw3 +c1/Vf1DpHNJ9vqrV6oVOKIA9PK9/e2IudQsto5fH/lGfelwnR/h01BORLcSwRTLz +EUpf23w3GsThkzbsVaXMd83ckTlQz4QegqJw/PTm7ZgzlhfPUxk9vU0CgYAKn3X9 +3KZ4TOBPiwE3adYPDhpdYg12VTASkdxeggiPEUndTBX0576bf7yNcpF0pO48EvOu +coLOd3Wrlelelx2uP59ZFk+bvutj5Rrp9F6m0jP0m12PKW6YSXRXdV22Rc3xr4Yt +MNEaxXOQ6uYDBbCZCbTW3jCXx+yxwjYJbT/qqwKBgGoGcZtZPVSQebxAWUXXIRT4 +kCen7eaJFgkD8OKILfq02ks2WYs3IK+XIv/+DEuYZJKP1dyTPnKL1Qc9B4kcrgWj +dR0yEiGnjG7ULzJWHhx/lSXot8VcDSOr9oZ+hVIjwKMsO1WwhPD5Hp4r9a0jIquI +A8xdbpCsmC60hkhJk2B1 +-----END PRIVATE KEY----- diff --git a/pingora-proxy/tests/utils/conf/keys/leaf2.crt b/pingora-proxy/tests/utils/conf/keys/leaf2.crt new file mode 100644 index 0000000..0e58371 --- /dev/null +++ b/pingora-proxy/tests/utils/conf/keys/leaf2.crt @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEQDCCAygCFBmdf3ty+iiS5YqA7CBe5jogVDvhMA0GCSqGSIb3DQEBCwUAME4x +CzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEYMBYGA1UECgwPSW50ZXJtZWRpYXRl +IENBMRgwFgYDVQQDDA9pbnQucGluZ29yYS5vcmcwHhcNMjIxMjIyMjIxNzIyWhcN +MzIxMjE5MjIxNzIyWjBrMQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExFjAUBgNV +BAcMDVNhbiBGcmFuY2lzY28xITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5 +IEx0ZDEUMBIGA1UEAwwLcGluZ29yYS5vcmcwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQD1HQzvibMFxG/OdudzEpiFHl5JkHj/ZzhR8a47dmWcIjEaYd1z +/hMZ8Zdpc/Ho3IKzwSQ5+5UyKcFjNmERYIje6pdH6NG8407Syv3Cxr1oR7t8kWoW +lIsbC1A9Ikhh7pHZntoYrUUjGslgHH8KQFtNPYmOJxwx1EYha/7pdr3/mc2MvidW +IRcxokkww39G3YP5UxV1IWM7OJZ8nWASRthwerfhCRrAX+OilVB+Ei8p08+BJnvS +gyROC/vUU9RXggg63qgRKNraamUlW4fhBY9Qxr8vkuFFoXNxZllKxUlZW2YtQKmk +QQCs4u1cF42ugGBeVqGooFvmezYPRwOxwL3R71UDDdEd/PQEg7skvu/Tyn+s6st1 +zcyBO+CT4Ogo2qbT7BaD9K/umElSDEIkW4JED+WtMihAZSeoAO4vsrh3ZGK5i3zv +VLFTbbbgE0vxoqF78ryxrzQuPJEIA5j1TycWjxTNl6IDy3J3QUjNzuVHZB5NK+N2 +Xx/rPhxh96GpY31tOCVC2L/YgkdnQB0e5ICet+LMGDcaNbXTFJoEEvq1patLJ23P +tyXgigl19OgLLFW9U5eExQ99QbdQhMORh4M7IN+UAmIiokHi4ZaH76VKaqKPzZ7r +MEsAeYryTfN5SdF4XFTDojR7rYT3kwPl7au66rDNdS3nNUTSHja6RxWqzwIDAQAB +MA0GCSqGSIb3DQEBCwUAA4IBAQCpyWaCksa8DSofS3ttjh5fRjUkth7O6nEDDZC3 +jOSNmwK0rZIK7pPLl7ogPVGpgu+dyTGQ9Jb3w5Xm3N26u/fLbVk7t7BCYbDMr14o +bJrSswz04GN/+e+JEVVTd6vU7weQGLbXrSMSsovzRJDhJe7qeV+u3RsxOLFyQntr +OqWB1x4bU/OghDOUSlRENwUCFursFHO3QWeD/ECPPSe1Q9J5Tkk/wd3TGTyyRUkW +hIgXrfIrZjEApa+nQma7+gUUQ6gwJxB1wEeQOOkSNizrOj0kdSKBCpSEeJCcbJpl +29FigdShOhBUqIZH0Y487VpaxfqBB4Kq4vlIQhfas/f6h6hS +-----END CERTIFICATE----- diff --git a/pingora-proxy/tests/utils/conf/keys/leaf2.csr b/pingora-proxy/tests/utils/conf/keys/leaf2.csr new file mode 100644 index 0000000..fe84667 --- /dev/null +++ b/pingora-proxy/tests/utils/conf/keys/leaf2.csr @@ -0,0 +1,28 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIEsDCCApgCAQAwazELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQH +DA1TYW4gRnJhbmNpc2NvMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBM +dGQxFDASBgNVBAMMC3BpbmdvcmEub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEA9R0M74mzBcRvznbncxKYhR5eSZB4/2c4UfGuO3ZlnCIxGmHdc/4T +GfGXaXPx6NyCs8EkOfuVMinBYzZhEWCI3uqXR+jRvONO0sr9wsa9aEe7fJFqFpSL +GwtQPSJIYe6R2Z7aGK1FIxrJYBx/CkBbTT2JjiccMdRGIWv+6Xa9/5nNjL4nViEX +MaJJMMN/Rt2D+VMVdSFjOziWfJ1gEkbYcHq34QkawF/jopVQfhIvKdPPgSZ70oMk +Tgv71FPUV4IIOt6oESja2mplJVuH4QWPUMa/L5LhRaFzcWZZSsVJWVtmLUCppEEA +rOLtXBeNroBgXlahqKBb5ns2D0cDscC90e9VAw3RHfz0BIO7JL7v08p/rOrLdc3M +gTvgk+DoKNqm0+wWg/Sv7phJUgxCJFuCRA/lrTIoQGUnqADuL7K4d2RiuYt871Sx +U2224BNL8aKhe/K8sa80LjyRCAOY9U8nFo8UzZeiA8tyd0FIzc7lR2QeTSvjdl8f +6z4cYfehqWN9bTglQti/2IJHZ0AdHuSAnrfizBg3GjW10xSaBBL6taWrSydtz7cl +4IoJdfToCyxVvVOXhMUPfUG3UITDkYeDOyDflAJiIqJB4uGWh++lSmqij82e6zBL +AHmK8k3zeUnReFxUw6I0e62E95MD5e2ruuqwzXUt5zVE0h42ukcVqs8CAwEAAaAA +MA0GCSqGSIb3DQEBCwUAA4ICAQDn0ccCSKBk85dj4EeEzlBhRSlyPh+I6MamrIeM +OnKf0MPnetjAWsbHCqsbXakxC27u5MhiNu9g7zStuisG9oYE3cZVhGPK0QBf0N6C +wlclbFj6tTMhtxpwP2D8vNxEXbBqfCcQHI36qVfFOPm7wUlNGVKeinaW+d3azLtw +oUi683poEBWXdFu/xeE27DPT829/J0OHMm0O++lbKuzJO/9081vIMi95RUiz4uFX ++PyIXXYL+5C+L5PLmCtL/i5pVYo5ldHtqV1Q5XNlklmrF4YTHI6skovp6wkPCgpb +46W1mpHVt3sCpb52HGrcQWvyzBnkgekIdew0ed7DOMYV1dnGA95AzvwYQF2+thHp +yb7PINgrnby1h2y15EY7fczwfw5QffTc1zHaWQSXueBMQz0UkZS6h8bBON3tqoFd +Rhf9tdzIxp7l61Up0LJA2upRLW38Y81eqtpKVZHQY/qk2nLkKZ+Cbt1+TwtpfNll +aFcR+8epD4ojyAxwPJsSBL1VD9BMBX+Yep80qxNvj4O18dkrFSPOcsDW+IigMi26 +AWcOqPzQKUt5dGiGFJbvn5huCyUlX2Al7pXUTGBmXuO+4P0EFWo/oeUCLJ3nkrvQ +2tK39+RHwuZ9MQpZl0FSJFpXEECuRfI5l3Ci1fQD7F9T+T6mIlDGnO0cPVSaQ6dO +OdpRdQ== +-----END CERTIFICATE REQUEST----- diff --git a/pingora-proxy/tests/utils/conf/keys/leaf2.key b/pingora-proxy/tests/utils/conf/keys/leaf2.key new file mode 100644 index 0000000..47e4c40 --- /dev/null +++ b/pingora-proxy/tests/utils/conf/keys/leaf2.key @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIJKAIBAAKCAgEA9R0M74mzBcRvznbncxKYhR5eSZB4/2c4UfGuO3ZlnCIxGmHd +c/4TGfGXaXPx6NyCs8EkOfuVMinBYzZhEWCI3uqXR+jRvONO0sr9wsa9aEe7fJFq +FpSLGwtQPSJIYe6R2Z7aGK1FIxrJYBx/CkBbTT2JjiccMdRGIWv+6Xa9/5nNjL4n +ViEXMaJJMMN/Rt2D+VMVdSFjOziWfJ1gEkbYcHq34QkawF/jopVQfhIvKdPPgSZ7 +0oMkTgv71FPUV4IIOt6oESja2mplJVuH4QWPUMa/L5LhRaFzcWZZSsVJWVtmLUCp +pEEArOLtXBeNroBgXlahqKBb5ns2D0cDscC90e9VAw3RHfz0BIO7JL7v08p/rOrL +dc3MgTvgk+DoKNqm0+wWg/Sv7phJUgxCJFuCRA/lrTIoQGUnqADuL7K4d2RiuYt8 +71SxU2224BNL8aKhe/K8sa80LjyRCAOY9U8nFo8UzZeiA8tyd0FIzc7lR2QeTSvj +dl8f6z4cYfehqWN9bTglQti/2IJHZ0AdHuSAnrfizBg3GjW10xSaBBL6taWrSydt +z7cl4IoJdfToCyxVvVOXhMUPfUG3UITDkYeDOyDflAJiIqJB4uGWh++lSmqij82e +6zBLAHmK8k3zeUnReFxUw6I0e62E95MD5e2ruuqwzXUt5zVE0h42ukcVqs8CAwEA +AQKCAgBI6Lk+TzFHF+VB/rBd1Dw17JCTRTwYjHV+OmtfGJqk1K7ScCXVKNA5uVkW +bvyYDW97VIoYDTOV1kHF5xj8eEB+Pj19kE1C6EI8BVFyLHeOmzezl/V8ffbatoTJ +incJWlNb7hplmLSl+oPH6PII9Jez5AgUlqGWWNP7gQo0G7PsYa14nd9JiVJC20j2 +DlC/nYhyEzqguquvo+dvbchz50reOkKT14dzjZJCfDOTLImG4ZAplG7kcUnNRVdF +EyJoXS9hg3VulT50FY28jPtf/a1hk5yu4/vKIHocUxtgWEq3H67G6yMKzqMKyf1c +lUz5iQohRZeUdw6fAitUZAU/TFupj4cblFish6BsJBZRBdxKAh5hzbDGeVFPtJi0 +k2fgSPBJNzOz8yrowPyaTF0dzoowdFGQ7FNoNM4Xokk7D9s+dZda8D6bW6hMlj7j +yV2MmCHVDq3zuT+HeuygJSzsrF94p9p8xFrKBFl7saltuDv/GQ5yVIAz449nbwh/ +b5C2LQ+ZqG6sHtcR6zDImxDyfV6Rjq2qTqOFWSOpMyj+fiyzw8aOFWw1D26Q9stA +PqP/XjqhjzJcK3emW1Z5bFQ4YJ9JnFlx11MjeCf/XyQc1Bt3SXEh5NtOB9iECpN6 +VfILGDQcUFHEsObrCZI3GLHppOf387qgry0m8B5G/8CbfFqKUQKCAQEA+w0AvX0U +c6W4GoZRyaVTF/NLHgECHHTCP14kliXJchRqpmfHZ2BnUt7YhSX/cLZfROEPzkN0 +dWyZNRMnyTqbNqQ8nec1m9RUfNY9aNRg2dn9eWB032qkyv4hH40tAB+SysNP+Vwk +O3SfFv0+xEWV6Btg3lfaXUxaIdIqpyO31GH5+Q4/+7ykCrKXXRRCGwsF6+nQ2heM +mfjFpBfXvbzCHfVtcofklM/JFZgflmpbBh8UuCoXkiD2s47QHHUVXtrJmlmuj3dX +cOu4n9gCwmDJ7GQHHVrM/UmazOxOA/Jm2hZBO4lsKnWKziYw2pxPtkNNKKlQKEve +HQrA1QlEuHzNrQKCAQEA+fIVViEgCoO/8RfCzZ1KRaaRmbLj+OPaif2tuKTa/5yM +GwsRPlkrIv3aqt0Ut2xUmCS4UA9JHDgEu2cU7MwE4K+/JWcjMmTA+dB0wJBwReXQ +XCrNbzj3si7faHUhngE5V5g2e6LKzG7H+KP5INIusx7MOLXql/arXoekfr3mqYhB +KN2kbDDeco4466e+ADT5WtyTmVeTU0mrCrslOelGfk2z8kZAFAbs3Lx3aUhRiqYg +vkFWOEQLi7RnDTnbq/VlNlLco+M4GDVd7i1oyDKtIX+0cgDlPiJpwdkEB91/CXEJ +oeIZhvwBs5+Wl4IcBfT8KwA1cXi2ojsTwRs93Rnx6wKCAQAYtyr/fLTqvcHmOpsK +sw//J6CZj5fZnVUST/5iGc4/QOtO/qCO+NqzOeUvFpKTUiEG8vFPaSyp8ssSgpRE +J1ToiDq/gOeyM7EtqRnanC38xI1Dyc83v5QBuAsixA9OF82n0Jqq/ftDLzQKW1w2 +jnM3qppayWNiFAY7lilE0yth6VNmxZRfAC9WLkbgjwIDD47Brv80uWTKM8ehZAeF +UnP55xOjVuWWEO7HBXb2o/naHG05xEsVw9EF1GWAp7Y25Gs8mt+omCMvpsVCV03O +PSEj+KUKqsnLldd7nTgBA3hEuDQr3Fedxnyn1vKwUvs2AmIyQpj1nqJ7UXeygXsW +fpLxAoIBAQDgIj8R4liKNUUdHLKakY710H3Gd03JdgIWNf7fki20hBx7b7xBzdJJ +6Zx6FhCqvyFI4bzKRjrIbE+KAdEY24cQOWlOUCOW4BTQsCbSO3QCqifjTpq0P0CX +b0L1t/uyZeSW8S8CRaRYGIuIIvqXfQNVqqt1u2Qoa5GXDknrQb2jj0TnMYJtZpFD +5teSMvTF2Ls2yJAvNQIu8OPJlrK2MML/JgzUmDyD+QXUl8j5B1nf3EOGeK6pfBNi +bx7uFFEx7beaNEoZSPuXcdvOZrgMtqzcWllk1fq8cj2mEEZ2CyENRWle2pMLodag +zd5L9OfOS7cJlIFYROh5qEJ5q0UZjVeLAoIBACjbUlgxojC5e4zVMtSuudnkzNo1 +sMr5sb0UHa9SgVvi8gPaoNnwYorKgjBH6Kuv5reOpc9yuc58zl6kFuBUdZDV70yM +CODpVao3Zr8V4P+aGL8PtW4CEShpx8RhoOquTvnp1/cyMaWG27zc49QMf3bcCqWZ +IxZv1U+6AcohtljRuoI2sIzt3Nr5LWUqQxeaR6gVQNgJHLUNcBc7OEFWJOfQp0iv ++ibpIuGczevkNjQf+h4XpK/BTAQLo0w0u3Q05hPVpIcb44/9Br8wDyIbSz8YnpRe +DAC/IedXRyfpH6ySOI1et+CQ14PPktR44dc/e5RolW/OW24+p9l6D4iNp4g= +-----END RSA PRIVATE KEY----- diff --git a/pingora-proxy/tests/utils/conf/keys/public.pem b/pingora-proxy/tests/utils/conf/keys/public.pem new file mode 100644 index 0000000..0866a04 --- /dev/null +++ b/pingora-proxy/tests/utils/conf/keys/public.pem @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2f/1Fm1HjySdokPq2T0F1xxol9nS +EYQ+foFINeaWYk+FxMGpriJTBb8AGka87cWklw1ZqytfaT6pkureDbTkwg== +-----END PUBLIC KEY----- diff --git a/pingora-proxy/tests/utils/conf/keys/root.crt b/pingora-proxy/tests/utils/conf/keys/root.crt new file mode 100644 index 0000000..5d6507e --- /dev/null +++ b/pingora-proxy/tests/utils/conf/keys/root.crt @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIIFnzCCA4egAwIBAgIUE5kg5Z26V4swShJoSwfNVsJkHbYwDQYJKoZIhvcNAQEL +BQAwXzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1TYW4gRnJh +bmNpc2NvMRAwDgYDVQQKDAdSb290IENBMRkwFwYDVQQDDBByb290LnBpbmdvcmEu +b3JnMB4XDTIyMTExMDE5MjY1MFoXDTQyMTExMDE5MjY1MFowXzELMAkGA1UEBhMC +VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMRAwDgYDVQQK +DAdSb290IENBMRkwFwYDVQQDDBByb290LnBpbmdvcmEub3JnMIICIjANBgkqhkiG +9w0BAQEFAAOCAg8AMIICCgKCAgEA4s1XxwZruaRwuDX1IkM2oxdSdjg7FeUp8lsN +Uix4NdXz8IoQWRzCfFuRBKFHptahutSO6Bbewm9XmU2hHG7aoCqaZqEVQ/3KRLZ4 +mzaNBCzDNgPTmDkz/DZKzOVuyVvbmTOsLn53yxKnFP9MEDIEemqGiM80MmFfCm/o +0vLkjwkRpreMsWPUhrq3igTWRctUYMJAeDsEaaXB1k5ovWICrEylMzslgSNfoBed +NmBpurz+yQddKNMTb/SLYxa7B1uZKDRSIXwwOZPdBDyUdlStUPodNG/OzprN+bRC +oFRB9EFG1m5oPJXQIalePj0dwhXl/bkV4uRxCSZmBZK3fbtLMF+Wkg2voTrn51Yv +lKkzUQoEX6WWtUameZZbUB8TbW2lmANuvGBmvBbj3+4ztmtJPXfJBkckCeUC6bwC +4CKrgB587ElY357Vqv/HmRRC9kxdzpOS9s5CtcqJ3Dg1TmLajyRQkf8wMqk0fhh7 +V+VrPXB030MGABXh5+B2HOsF307vF030v7z+Xp5VRLGBqmDwK0Reo2h8cg9PkMDS +5Qc2zOJVslkJ+QYdkea1ajVpCsFbaC1JPmRWihTllboUqsk9oSS3jcIZ8vW3QKMg +ZbKtVbtVHr3mNGWuVs96iDN5Us3SJ6KGS8sanrAYAAB/NKd1Wl3I0aVtcb6eOONd +edf9+b0CAwEAAaNTMFEwHQYDVR0OBBYEFJ5hR0odQYOtYsY3P18WIC2byI1oMB8G +A1UdIwQYMBaAFJ5hR0odQYOtYsY3P18WIC2byI1oMA8GA1UdEwEB/wQFMAMBAf8w +DQYJKoZIhvcNAQELBQADggIBAIrpAsrPre3R4RY0JmnvomgH+tCSMHb6dW52YrEl +JkEG4cVc5MKs5QfPp8l2d1DngqiOUnOf0MWwWNDidHQZKrWs59j67L8qKN91VQKe +cSNEX3iMFvE59Hr0Ner6Kr09wZLHVVNGcy0FdhWpJdDUGDoQjfL7n7usJyCUqWSq +/pa1I9Is3ZfeQ5f7Ztrdz35vVPj+0BlHXbZM5AZi8Dwf3vXFBlPty3fITpE65cty +cYnbpGto+wDoZj9fkKImjK21QsJdmHwaWRgmXX3WbdFBAbScTjDOc5Mls2VY8rSh ++xLI1KMB0FHSJqrGoFN3uE+G1vJX/hgn98KZKob23yJr2TWr9LHI56sMfN5xdd5A +iOHxYODSrIAi1k+bSlDz6WfEtufoqwBwHiog4nFOXrlHpGO6eUB1QjaQJZwKn2zE +3BjqJOoqbuBMg5XZRjihHcVVuZdU39/zQDwqliNpx3km4FzOiEoBABGzLP+Qt0Ch +cJFS1Yc8ffv616yP4A9qkyogk9YBBvNbDLB7WV8h8p1s4JP3f5aDUlxtAD+E+3aJ +8mrb3P7/0A2QyxlgX4qQOdj++b7GzXDxxLgOimJ4pLo0fdY8KWMeHvZPiMryHkMx +3GSZCHeleSVBCPB2pPCzUqkkKADbjBX3SYJsAMF9uXQAR4U7wojjvAmbt6vJEh6j +TEUG +-----END CERTIFICATE----- diff --git a/pingora-proxy/tests/utils/conf/keys/root.key b/pingora-proxy/tests/utils/conf/keys/root.key new file mode 100644 index 0000000..ce4f21e --- /dev/null +++ b/pingora-proxy/tests/utils/conf/keys/root.key @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +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 +74xuCrejGJzwfA5Uel7mb6rqB/1law== +-----END PRIVATE KEY----- diff --git a/pingora-proxy/tests/utils/conf/keys/root.srl b/pingora-proxy/tests/utils/conf/keys/root.srl new file mode 100644 index 0000000..7c228f6 --- /dev/null +++ b/pingora-proxy/tests/utils/conf/keys/root.srl @@ -0,0 +1 @@ +1C807FB6A8D925A28881E5B0BD746DD370B4C883 diff --git a/pingora-proxy/tests/utils/conf/keys/server.crt b/pingora-proxy/tests/utils/conf/keys/server.crt new file mode 100644 index 0000000..afb2d1e --- /dev/null +++ b/pingora-proxy/tests/utils/conf/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-proxy/tests/utils/conf/keys/server.csr b/pingora-proxy/tests/utils/conf/keys/server.csr new file mode 100644 index 0000000..ca75dce --- /dev/null +++ b/pingora-proxy/tests/utils/conf/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-proxy/tests/utils/conf/origin/.gitignore b/pingora-proxy/tests/utils/conf/origin/.gitignore new file mode 100644 index 0000000..eed5f2a --- /dev/null +++ b/pingora-proxy/tests/utils/conf/origin/.gitignore @@ -0,0 +1,6 @@ +** +!html +!html/** +!conf +!conf/** +!.gitignore diff --git a/pingora-proxy/tests/utils/conf/origin/conf/keys b/pingora-proxy/tests/utils/conf/origin/conf/keys new file mode 120000 index 0000000..f86df4c --- /dev/null +++ b/pingora-proxy/tests/utils/conf/origin/conf/keys @@ -0,0 +1 @@ +../../keys \ No newline at end of file diff --git a/pingora-proxy/tests/utils/conf/origin/conf/nginx.conf b/pingora-proxy/tests/utils/conf/origin/conf/nginx.conf new file mode 100644 index 0000000..b0ab281 --- /dev/null +++ b/pingora-proxy/tests/utils/conf/origin/conf/nginx.conf @@ -0,0 +1,432 @@ + +#user nobody; +worker_processes 1; + +error_log /dev/stdout; +#error_log logs/error.log notice; +#error_log logs/error.log info; + +pid /tmp/mock_origin.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 off; + + sendfile on; + #tcp_nopush on; + + keepalive_timeout 60; + keepalive_requests 99999; + + lua_shared_dict hit_counter 10m; + + #gzip on; + + # mTLS endpoint + server { + listen 8444 ssl http2; + 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; + ssl_client_certificate keys/root.crt; + ssl_verify_client on; + ssl_verify_depth 4; + + location / { + return 200 "hello world"; + } + } + + # secp384r1 endpoint (ECDH and ECDSA) + server { + listen 8445 ssl http2; + ssl_protocols TLSv1.2; + ssl_ciphers TLS-AES-128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA512; + ssl_certificate keys/curve_test.384.crt; + ssl_certificate_key keys/curve_test.384.key.pem; + ssl_ecdh_curve secp384r1; + + location /384 { + return 200 "Happy Friday!"; + } + } + + # secp521r1 endpoint (ECDH and ECDSA) + server { + listen 8446 ssl http2; + ssl_protocols TLSv1.2; + ssl_ciphers TLS-AES-128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA512; + ssl_certificate keys/curve_test.521.crt; + ssl_certificate_key keys/curve_test.521.key.pem; + ssl_ecdh_curve secp521r1; + + location /521 { + return 200 "Happy Monday!"; + } + } + + server { + listen 8000; + # 8001 is used for bad_lb test only to avoid unexpected connection reuse + listen 8001; + listen [::]:8000; + #listen 8443 ssl; + listen unix:/tmp/nginx-test.sock; + 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; + + # for benchmark + http2_max_requests 999999; + + #charset koi8-r; + + #access_log logs/host.access.log main; + + add_header Origin-Http2 $http2; + + location / { + root ./html; + index index.html index.htm; + } + + # this allows an arbitrary prefix to be included in URLs, so + # that tests can control caching. + location ~ ^/unique/[^/]+(/.*)$ { + rewrite ^/unique/[^/]+(/.*)$ $1 last; + } + + # this serves as an origin hit counter for an arbitrary prefix, which + # then redirects to the rest of the URL like our unique/... endpoint. + location ~ ^/hitcounted/[^/]+(/.*)$ { + rewrite_by_lua_block { + -- Extract specified ID + local _, _, id = string.find(ngx.var.request_uri, "[^/]+/([^/]+)") + + -- Incr hit counter + local hits = ngx.shared.hit_counter + if not hits:get(id) then + hits:safe_set(id, 0, nil) + end + local value = hits:incr(id, 1) + + -- Rewrite URI to the requested destination + local destStartIndex = string.find(ngx.var.request_uri, id) + string.len(id) + local dest = string.sub(ngx.var.request_uri, destStartIndex) + ngx.req.set_uri(dest, true) + } + } + + # this serves the hit count from the hitcounted endpoint + location ~ ^/read_hit_count/[^/]+(/.*)$ { + content_by_lua_block { + -- Find the hit count for the given ID and return it. + local _, _, id = string.find(ngx.var.request_uri, "[^/]+/([^/]+)") + local hits = ngx.shared.hit_counter + ngx.print(hits:get(id) or 0) + } + } + + location /test { + return 200; + } + location /test2 { + return 200 "hello world"; + } + location /test3 { + #return 200; + content_by_lua_block { + ngx.print("hello world") + } + } + + location /test4 { + rewrite_by_lua_block { + ngx.exit(200) + } + #return 201; + + } + + location /now { + header_filter_by_lua_block { + ngx.header["x-epoch"] = ngx.now() + } + return 200 "hello world"; + } + + location /brotli { + header_filter_by_lua_block { + local ae = ngx.req.get_headers()["Accept-Encoding"] + if ae and ae:find("br") then + ngx.header["Content-Encoding"] = "br" + else + return ngx.exit(400) + end + } + content_by_lua_block { + -- brotli compressed 'hello'. + ngx.print("\x0f\x02\x80hello\x03") + } + } + + location /cache_control { + header_filter_by_lua_block { + local h = ngx.req.get_headers() + if h["set-cache-control"] then + ngx.header["Cache-Control"] = h["set-cache-control"] + end + if h["set-cache-tag"] then + ngx.header["Cache-Tag"] = h["set-cache-tag"] + end + if h["set-revalidated"] then + return ngx.exit(304) + end + } + return 200 "hello world"; + } + + location /revalidate_now { + header_filter_by_lua_block { + ngx.header["x-epoch"] = ngx.now() + ngx.header["Last-Modified"] = "Tue, 03 May 2022 01:04:39 GMT" + ngx.header["Etag"] = '"abcd"' + local h = ngx.req.get_headers() + if h["if-modified-since"] or h["if-none-match"] then + -- just assume they match + return ngx.exit(304) + end + } + return 200 "hello world"; + } + + location /revalidate_vary { + header_filter_by_lua_block { + ngx.header["Last-Modified"] = "Tue, 03 May 2022 01:04:39 GMT" + ngx.header["Etag"] = '"abcd"' + local h = ngx.req.get_headers() + if h["set-vary"] then + ngx.header["Vary"] = h["set-vary"] + end + if h["set-no-vary"] then + -- expects proxy to force return no variance with this + ngx.header["Vary"] = "x-no-vary" + end + if not h["x-no-revalidate"] and (h["if-modified-since"] or h["if-none-match"]) then + -- just assume they match + return ngx.exit(304) + end + } + return 200 "hello world"; + } + + location /no_if_headers { + content_by_lua_block { + local h = ngx.req.get_headers() + if h["if-modified-since"] or h["if-none-match"] or h["range"] then + return ngx.exit(400) + end + ngx.say("no if headers detected") + } + } + + location /client_ip { + add_header x-client-ip $remote_addr; + return 200; + } + + # 1. A origin load balancer that rejects reused connetions. + # this is to simulate the common problem when customers LB drops + # connection silently after being keepalived for awhile + # 2. A middlebox might drop the connection if the origin takes too long + # to respond. We should not retry in this case. + location /bad_lb { + rewrite_by_lua_block { + ngx.sleep(1) + if tonumber(ngx.var.connection_requests) > 1 then + -- force drop the request and close the connection + ngx.exit(444) + end + ngx.req.read_body() + local data = ngx.req.get_body_data() + if data then + ngx.say(data) + else + ngx.say("dog!") + end + } + } + + location /duplex/ { + client_max_body_size 1G; + content_by_lua_block { + ngx.print(string.rep("A", 64)) + ngx.print(string.rep("A", 64)) + ngx.print(string.rep("A", 64)) + ngx.print(string.rep("A", 64)) + ngx.print(string.rep("A", 64)) + -- without ngx.req.read_body(), the body will return wihtout waiting for req body + } + } + + location /upload/ { + client_max_body_size 1G; + content_by_lua_block { + ngx.req.read_body() + ngx.print(string.rep("A", 64)) + ngx.print(string.rep("A", 64)) + ngx.print(string.rep("A", 64)) + ngx.print(string.rep("A", 64)) + ngx.print(string.rep("A", 64)) + } + } + + location /tls_verify { + keepalive_timeout 0; + return 200; + } + + location /noreuse { + keepalive_timeout 0; + return 200 "hello world"; + } + + location /set_cookie { + add_header Set-Cookie "chocolate chip"; + return 200 "hello world"; + } + + location /chunked { + content_by_lua_block { + ngx.req.read_body() + ngx.print(string.rep("A", 64)) + } + } + + location /echo { + content_by_lua_block { + ngx.req.read_body() + local data = ngx.req.get_body_data() + if data then + ngx.print(data) + end + } + } + + location /low_ttl { + add_header Cache-Control "public, max-age=0"; + return 200 "low ttl"; + } + + location /connection_die { + content_by_lua_block { + ngx.print(string.rep("A", 5)) + ngx.flush() + ngx.exit(444) -- 444 kills the connection right away + } + } + + location /no_compression { + gzip off; # avoid accidental turn it on at server block + content_by_lua_block { + ngx.print(string.rep("B", 32)) + } + } + + location /file_maker { + gzip off; # fixed content size + content_by_lua_block { + local size = tonumber(ngx.var.http_x_set_size) or 1024 + ngx.print(string.rep("A", size)) + } + } + + location /sleep { + rewrite_by_lua_block { + local sleep_sec = tonumber(ngx.var.http_x_set_sleep) or 1 + ngx.sleep(sleep_sec) + if ngx.var.http_x_abort then + -- force drop the request and close the connection + ngx.exit(444) + end + } + content_by_lua_block { + if ngx.var.http_x_error_header then + ngx.status = 500 + ngx.exit(0) + return + end + ngx.print("hello ") + ngx.flush() + local sleep_sec = tonumber(ngx.var.http_x_set_body_sleep) or 0 + ngx.sleep(sleep_sec) + if ngx.var.http_x_abort_body then + ngx.flush() + -- force drop the request and close the connection + ngx.exit(444) + return + end + ngx.print("world") + } + header_filter_by_lua_block { + if ngx.var.http_x_no_store then + ngx.header["Cache-control"] = "no-store" + end + if ngx.var.http_x_no_stale_revalidate then + ngx.header["Cache-control"] = "stale-while-revalidate=0" + end + if ngx.var.http_x_set_content_length then + ngx.header["Content-Length"] = "11" -- based on "hello world" + end + } + } + + location /slow_body { + content_by_lua_block { + local sleep_sec = tonumber(ngx.var.http_x_set_sleep) or 1 + ngx.flush() + ngx.sleep(sleep_sec) + ngx.print("hello ") + ngx.flush() + ngx.sleep(sleep_sec) + ngx.print("world") + ngx.sleep(sleep_sec) + ngx.print("!") + } + } + + location /content_type { + header_filter_by_lua_block { + ngx.header["Content-Type"] = ngx.var.http_set_content_type + } + return 200 "hello world"; + } + + #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-proxy/tests/utils/conf/origin/html/index.html b/pingora-proxy/tests/utils/conf/origin/html/index.html new file mode 100644 index 0000000..980a0d5 --- /dev/null +++ b/pingora-proxy/tests/utils/conf/origin/html/index.html @@ -0,0 +1 @@ +Hello World! diff --git a/pingora-proxy/tests/utils/mock_origin.rs b/pingora-proxy/tests/utils/mock_origin.rs new file mode 100644 index 0000000..db84f8d --- /dev/null +++ b/pingora-proxy/tests/utils/mock_origin.rs @@ -0,0 +1,36 @@ +// 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::process; +use std::{thread, time}; + +pub static MOCK_ORIGIN: Lazy = Lazy::new(init); + +fn init() -> bool { + // TODO: figure out a way to kill openresty when exiting + process::Command::new("pkill") + .args(["-F", "/tmp/mock_origin.pid"]) + .spawn() + .unwrap(); + let _origin = thread::spawn(|| { + process::Command::new("openresty") + .args(["-p", &format!("{}/origin", super::conf_dir())]) + .output() + .unwrap(); + }); + // wait until the server is up + thread::sleep(time::Duration::from_secs(2)); + true +} diff --git a/pingora-proxy/tests/utils/mod.rs b/pingora-proxy/tests/utils/mod.rs new file mode 100644 index 0000000..6a5a1c9 --- /dev/null +++ b/pingora-proxy/tests/utils/mod.rs @@ -0,0 +1,32 @@ +// 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. + +#![allow(unused)] + +pub mod cert; +pub mod mock_origin; +pub mod server_utils; +pub mod websocket; + +use once_cell::sync::Lazy; +use tokio::runtime::{Builder, Runtime}; + +// for tests with a static connection pool, if we use tokio::test the reactor +// will no longer be associated with the backing pool fds since it's dropped per test +pub static GLOBAL_RUNTIME: Lazy = + Lazy::new(|| Builder::new_multi_thread().enable_all().build().unwrap()); + +pub fn conf_dir() -> String { + format!("{}/tests/utils/conf", env!("CARGO_MANIFEST_DIR")) +} diff --git a/pingora-proxy/tests/utils/server_utils.rs b/pingora-proxy/tests/utils/server_utils.rs new file mode 100644 index 0000000..6862912 --- /dev/null +++ b/pingora-proxy/tests/utils/server_utils.rs @@ -0,0 +1,399 @@ +// 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 super::cert; +use async_trait::async_trait; +use once_cell::sync::Lazy; +use pingora_cache::cache_control::CacheControl; +use pingora_cache::key::HashBinary; +use pingora_cache::VarianceBuilder; +use pingora_cache::{ + eviction::simple_lru::Manager, filters::resp_cacheable, lock::CacheLock, predictor::Predictor, + set_compression_dict_path, CacheMeta, CacheMetaDefaults, CachePhase, MemCache, NoCacheReason, + RespCacheable, +}; +use pingora_core::protocols::Digest; +use pingora_core::server::configuration::Opt; +use pingora_core::services::Service; +use pingora_core::upstreams::peer::HttpPeer; +use pingora_core::utils::CertKey; +use pingora_error::{Error, ErrorSource, Result}; +use pingora_http::{RequestHeader, ResponseHeader}; +use pingora_proxy::{ProxyHttp, Session}; +use std::sync::Arc; +use std::thread; +use structopt::StructOpt; + +pub struct ExampleProxyHttps {} + +#[allow(clippy::upper_case_acronyms)] +pub struct CTX { + conn_reused: bool, +} + +#[async_trait] +impl ProxyHttp for ExampleProxyHttps { + type CTX = CTX; + fn new_ctx(&self) -> Self::CTX { + CTX { conn_reused: false } + } + + async fn upstream_peer( + &self, + session: &mut Session, + _ctx: &mut Self::CTX, + ) -> Result> { + let session = session.as_downstream(); + let req = session.req_header(); + + let port = req + .headers + .get("x-port") + .map_or("8443", |v| v.to_str().unwrap()); + let sni = req.headers.get("sni").map_or("", |v| v.to_str().unwrap()); + let alt = req.headers.get("alt").map_or("", |v| v.to_str().unwrap()); + + let client_cert = session.get_header_bytes("client_cert"); + + let mut peer = Box::new(HttpPeer::new( + format!("127.0.0.1:{port}"), + true, + sni.to_string(), + )); + peer.options.alternative_cn = Some(alt.to_string()); + + let verify = session.get_header_bytes("verify") == b"1"; + peer.options.verify_cert = verify; + + let verify_host = session.get_header_bytes("verify_host") == b"1"; + peer.options.verify_hostname = verify_host; + + if matches!(client_cert, b"1" | b"2") { + let (mut certs, key) = if client_cert == b"1" { + (vec![cert::LEAF_CERT.clone()], cert::LEAF_KEY.clone()) + } else { + (vec![cert::LEAF2_CERT.clone()], cert::LEAF2_KEY.clone()) + }; + if session.get_header_bytes("client_intermediate") == b"1" { + certs.push(cert::INTERMEDIATE_CERT.clone()); + } + peer.client_cert_key = Some(Arc::new(CertKey::new(certs, key))); + } + + if session.get_header_bytes("x-h2") == b"true" { + // default is 1, 1 + peer.options.set_http_version(2, 2); + } + + Ok(peer) + } + + async fn response_filter( + &self, + _session: &mut Session, + upstream_response: &mut ResponseHeader, + ctx: &mut Self::CTX, + ) -> Result<()> + where + Self::CTX: Send + Sync, + { + if ctx.conn_reused { + upstream_response.insert_header("x-conn-reuse", "1")?; + } + Ok(()) + } + + async fn upstream_request_filter( + &self, + session: &mut Session, + req: &mut RequestHeader, + _ctx: &mut Self::CTX, + ) -> Result<()> + where + Self::CTX: Send + Sync, + { + let host = session.get_header_bytes("host-override"); + if host != b"" { + req.insert_header("host", host)?; + } + Ok(()) + } + + async fn connected_to_upstream( + &self, + _http_session: &mut Session, + reused: bool, + _peer: &HttpPeer, + _fd: std::os::unix::io::RawFd, + _digest: Option<&Digest>, + ctx: &mut CTX, + ) -> Result<()> { + ctx.conn_reused = reused; + Ok(()) + } +} + +pub struct ExampleProxyHttp {} + +#[async_trait] +impl ProxyHttp for ExampleProxyHttp { + type CTX = (); + fn new_ctx(&self) -> Self::CTX {} + + async fn request_filter(&self, session: &mut Session, _ctx: &mut Self::CTX) -> Result { + let req = session.req_header(); + let downstream_compression = req.headers.get("x-downstream-compression").is_some(); + if downstream_compression { + session.downstream_compression.adjust_level(6); + } else { + // enable upstream compression for all requests by default + session.upstream_compression.adjust_level(6); + } + + Ok(false) + } + + async fn upstream_peer( + &self, + session: &mut Session, + _ctx: &mut Self::CTX, + ) -> Result> { + let req = session.req_header(); + if req.headers.contains_key("x-uds-peer") { + return Ok(Box::new(HttpPeer::new_uds( + "/tmp/nginx-test.sock", + false, + "".to_string(), + ))); + } + let port = req + .headers + .get("x-port") + .map_or("8000", |v| v.to_str().unwrap()); + let peer = Box::new(HttpPeer::new( + format!("127.0.0.1:{}", port), + false, + "".to_string(), + )); + Ok(peer) + } +} + +static CACHE_BACKEND: Lazy = Lazy::new(MemCache::new); +const CACHE_DEFAULT: CacheMetaDefaults = CacheMetaDefaults::new(|_| Some(1), 1, 1); +static CACHE_PREDICTOR: Lazy> = Lazy::new(|| Predictor::new(5, None)); +static EVICTION_MANAGER: Lazy = Lazy::new(|| Manager::new(8192)); // 8192 bytes +static CACHE_LOCK: Lazy = + Lazy::new(|| CacheLock::new(std::time::Duration::from_secs(2))); + +pub struct ExampleProxyCache {} + +#[async_trait] +impl ProxyHttp for ExampleProxyCache { + type CTX = (); + fn new_ctx(&self) -> Self::CTX {} + + async fn upstream_peer( + &self, + session: &mut Session, + _ctx: &mut Self::CTX, + ) -> Result> { + let req = session.req_header(); + let port = req + .headers + .get("x-port") + .map_or("8000", |v| v.to_str().unwrap()); + let peer = Box::new(HttpPeer::new( + format!("127.0.0.1:{}", port), + false, + "".to_string(), + )); + Ok(peer) + } + + fn request_cache_filter(&self, session: &mut Session, _ctx: &mut Self::CTX) -> Result<()> { + // TODO: only allow GET & HEAD + + if session.get_header_bytes("x-bypass-cache") != b"" { + return Ok(()); + } + + // turn on eviction only for some requests to avoid interference across tests + let eviction = session.req_header().headers.get("x-eviction").map(|_| { + &*EVICTION_MANAGER as &'static (dyn pingora_cache::eviction::EvictionManager + Sync) + }); + let lock = session + .req_header() + .headers + .get("x-lock") + .map(|_| &*CACHE_LOCK); + session + .cache + .enable(&*CACHE_BACKEND, eviction, Some(&*CACHE_PREDICTOR), lock); + + if let Some(max_file_size_hdr) = session + .req_header() + .headers + .get("x-cache-max-file-size-bytes") + { + let bytes = max_file_size_hdr + .to_str() + .unwrap() + .parse::() + .unwrap(); + session.cache.set_max_file_size_bytes(bytes); + } + + Ok(()) + } + + fn cache_vary_filter( + &self, + _meta: &CacheMeta, + _ctx: &mut Self::CTX, + req: &RequestHeader, + ) -> Option { + // Here the response is always vary on request header "x-vary-me" if it exists + // in the real world, this callback should check Vary response header to decide + let vary_me = req.headers.get("x-vary-me")?; + let mut key = VarianceBuilder::new(); + key.add_value("headers.x-vary-me", vary_me); + key.finalize() + } + + fn response_cache_filter( + &self, + _session: &Session, + resp: &ResponseHeader, + _ctx: &mut Self::CTX, + ) -> Result { + let cc = CacheControl::from_resp_headers(resp); + Ok(resp_cacheable(cc.as_ref(), resp, false, &CACHE_DEFAULT)) + } + + async fn response_filter( + &self, + session: &mut Session, + upstream_response: &mut ResponseHeader, + _ctx: &mut Self::CTX, + ) -> Result<()> + where + Self::CTX: Send + Sync, + { + if session.cache.enabled() { + match session.cache.phase() { + CachePhase::Hit => upstream_response.insert_header("x-cache-status", "hit")?, + CachePhase::Miss => upstream_response.insert_header("x-cache-status", "miss")?, + CachePhase::Stale => upstream_response.insert_header("x-cache-status", "stale")?, + CachePhase::Expired => { + upstream_response.insert_header("x-cache-status", "expired")? + } + CachePhase::Revalidated | CachePhase::RevalidatedNoCache(_) => { + upstream_response.insert_header("x-cache-status", "revalidated")? + } + _ => upstream_response.insert_header("x-cache-status", "invalid")?, + } + } else { + match session.cache.phase() { + CachePhase::Disabled(NoCacheReason::Deferred) => { + upstream_response.insert_header("x-cache-status", "deferred")?; + } + _ => upstream_response.insert_header("x-cache-status", "no-cache")?, + } + } + if let Some(d) = session.cache.lock_duration() { + upstream_response.insert_header("x-cache-lock-time-ms", format!("{}", d.as_millis()))? + } + Ok(()) + } + + fn should_serve_stale( + &self, + _session: &mut Session, + _ctx: &mut Self::CTX, + error: Option<&Error>, // None when it is called during stale while revalidate + ) -> bool { + // enable serve stale while updating + error.map_or(true, |e| e.esource() == &ErrorSource::Upstream) + } + + fn is_purge(&self, session: &Session, _ctx: &Self::CTX) -> bool { + session.req_header().method == "PURGE" + } +} + +fn test_main() { + env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init(); + + let opts: Vec = vec![ + "pingora-proxy".into(), + "-c".into(), + "tests/pingora_conf.yaml".into(), + ]; + let mut my_server = pingora_core::server::Server::new(Some(Opt::from_iter(opts))).unwrap(); + my_server.bootstrap(); + + let mut proxy_service_http = + pingora_proxy::http_proxy_service(&my_server.configuration, ExampleProxyHttp {}); + proxy_service_http.add_tcp("0.0.0.0:6147"); + proxy_service_http.add_uds("/tmp/pingora_proxy.sock", None); + + let mut proxy_service_https = + pingora_proxy::http_proxy_service(&my_server.configuration, ExampleProxyHttps {}); + proxy_service_https.add_tcp("0.0.0.0:6149"); + 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 tls_settings = + pingora_core::listeners::TlsSettings::intermediate(&cert_path, &key_path).unwrap(); + tls_settings.enable_h2(); + proxy_service_https.add_tls_with_settings("0.0.0.0:6150", None, tls_settings); + + let mut proxy_service_cache = + pingora_proxy::http_proxy_service(&my_server.configuration, ExampleProxyCache {}); + proxy_service_cache.add_tcp("0.0.0.0:6148"); + + let services: Vec> = vec![ + Box::new(proxy_service_http), + Box::new(proxy_service_https), + Box::new(proxy_service_cache), + ]; + + set_compression_dict_path("tests/headers.dict"); + my_server.add_services(services); + my_server.run_forever(); +} + +pub struct Server { + pub handle: thread::JoinHandle<()>, +} + +impl Server { + pub fn start() -> Self { + let server_handle = thread::spawn(|| { + test_main(); + }); + Server { + handle: server_handle, + } + } +} + +// FIXME: this still allows multiple servers to spawn across intergration tests +pub static TEST_SERVER: Lazy = Lazy::new(Server::start); +use super::mock_origin::MOCK_ORIGIN; + +pub fn init() { + let _ = *TEST_SERVER; + let _ = *MOCK_ORIGIN; +} diff --git a/pingora-proxy/tests/utils/websocket.rs b/pingora-proxy/tests/utils/websocket.rs new file mode 100644 index 0000000..92b35e9 --- /dev/null +++ b/pingora-proxy/tests/utils/websocket.rs @@ -0,0 +1,58 @@ +use std::{io::Error, thread, time::Duration}; + +use futures_util::{SinkExt, StreamExt}; +use log::debug; +use once_cell::sync::Lazy; +use tokio::{ + net::{TcpListener, TcpStream}, + runtime::Builder, +}; + +pub static WS_ECHO: Lazy = Lazy::new(init); + +fn init() -> bool { + thread::spawn(move || { + let runtime = Builder::new_current_thread() + .thread_name("websocket echo") + .enable_all() + .build() + .unwrap(); + runtime.block_on(async move { + server("127.0.0.1:9283").await.unwrap(); + }) + }); + thread::sleep(Duration::from_millis(200)); + true +} + +async fn server(addr: &str) -> Result<(), Error> { + let listener = TcpListener::bind(&addr).await.unwrap(); + while let Ok((stream, _)) = listener.accept().await { + tokio::spawn(handle_connection(stream)); + } + Ok(()) +} + +async fn handle_connection(stream: TcpStream) { + let mut ws_stream = tokio_tungstenite::accept_async(stream).await.unwrap(); + + while let Some(msg) = ws_stream.next().await { + let msg = msg.unwrap(); + let echo = msg.clone(); + if msg.is_text() { + let data = msg.into_text().unwrap(); + if data.contains("close") { + // abruptly close the stream without WS close; + debug!("abrupt close"); + return; + } else if data.contains("graceful") { + debug!("graceful close"); + ws_stream.close(None).await.unwrap(); + // close() only sends frame + return; + } else { + ws_stream.send(echo).await.unwrap(); + } + } + } +} diff --git a/pingora-runtime/Cargo.toml b/pingora-runtime/Cargo.toml new file mode 100644 index 0000000..7305129 --- /dev/null +++ b/pingora-runtime/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "pingora-runtime" +version = "0.1.0" +authors = ["Yuchen Wu "] +license = "Apache-2.0" +edition = "2021" +repository = "https://github.com/cloudflare/pingora" +categories = ["asynchronous", "network-programming"] +keywords = ["async", "non-blocking", "pingora"] +description = """ +Multithreaded Tokio runtime with the option of disabling work stealing. +""" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +name = "pingora_runtime" +path = "src/lib.rs" + +[dependencies] +rand = "0.8" +tokio = { workspace = true, features = ["rt-multi-thread", "sync", "time"] } +once_cell = { workspace = true } +thread_local = "1" + +[dev-dependencies] +tokio = { workspace = true, features = ["io-util", "net"] } + +[[bench]] +name = "hello" +harness = false diff --git a/pingora-runtime/LICENSE b/pingora-runtime/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/pingora-runtime/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/pingora-runtime/benches/hello.rs b/pingora-runtime/benches/hello.rs new file mode 100644 index 0000000..ef715b3 --- /dev/null +++ b/pingora-runtime/benches/hello.rs @@ -0,0 +1,106 @@ +// 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. + +//! Pingora tokio runtime. +//! +//! Tokio runtime comes in two flavors: a single-threaded runtime +//! and a multi-threaded one which provides work stealing. +//! Benchmark shows that, compared to the single-threaded runtime, the multi-threaded one +//! has some overhead due to its more sophisticated work steal scheduling. +//! +//! This crate provides a third flavor: a multi-threaded runtime without work stealing. +//! This flavor is as efficient as the single-threaded runtime while allows the async +//! program to use multiple cores. + +use pingora_runtime::{current_handle, Runtime}; +use std::error::Error; +use std::{thread, time}; +use tokio::io::{AsyncReadExt, AsyncWriteExt}; +use tokio::net::TcpListener; + +async fn hello_server(port: usize) -> Result<(), Box> { + let addr = format!("127.0.0.1:{port}"); + let listener = TcpListener::bind(&addr).await.unwrap(); + println!("Listening on: {}", addr); + + loop { + let (mut socket, _) = listener.accept().await.unwrap(); + socket.set_nodelay(true).unwrap(); + let rt = current_handle(); + rt.spawn(async move { + loop { + let mut buf = [0; 1024]; + let res = socket.read(&mut buf).await; + + let n = match res { + Ok(n) => n, + Err(_) => return, + }; + + if n == 0 { + return; + } + + let _ = socket + .write_all( + b"HTTP/1.1 200 OK\r\ncontent-length: 12\r\nconnection: keep-alive\r\n\r\nHello world!", + ) + .await; + } + }); + } +} + +/* On M1 macbook pro +wrk -t40 -c1000 -d10 http://127.0.0.1:3001 --latency +Running 10s test @ http://127.0.0.1:3001 + 40 threads and 1000 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 3.53ms 0.87ms 17.12ms 84.99% + Req/Sec 7.09k 1.29k 33.11k 93.30% + Latency Distribution + 50% 3.56ms + 75% 3.95ms + 90% 4.37ms + 99% 5.38ms + 2844034 requests in 10.10s, 203.42MB read +Requests/sec: 281689.27 +Transfer/sec: 20.15MB + +wrk -t40 -c1000 -d10 http://127.0.0.1:3000 --latency +Running 10s test @ http://127.0.0.1:3000 + 40 threads and 1000 connections + Thread Stats Avg Stdev Max +/- Stdev + Latency 12.16ms 16.29ms 112.29ms 83.40% + Req/Sec 5.47k 2.01k 48.85k 83.67% + Latency Distribution + 50% 2.09ms + 75% 20.23ms + 90% 37.11ms + 99% 65.16ms + 2190869 requests in 10.10s, 156.70MB read +Requests/sec: 216918.71 +Transfer/sec: 15.52MB +*/ + +fn main() -> Result<(), Box> { + let rt = Runtime::new_steal(2, ""); + let handle = rt.get_handle(); + handle.spawn(hello_server(3000)); + let rt2 = Runtime::new_no_steal(2, ""); + let handle = rt2.get_handle(); + handle.spawn(hello_server(3001)); + thread::sleep(time::Duration::from_secs(999999999)); + Ok(()) +} diff --git a/pingora-runtime/src/lib.rs b/pingora-runtime/src/lib.rs new file mode 100644 index 0000000..b07ee72 --- /dev/null +++ b/pingora-runtime/src/lib.rs @@ -0,0 +1,265 @@ +// 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. + +//! Pingora tokio runtime. +//! +//! Tokio runtime comes in two flavors: a single-threaded runtime +//! and a multi-threaded one which provides work stealing. +//! Benchmark shows that, compared to the single-threaded runtime, the multi-threaded one +//! has some overhead due to its more sophisticated work steal scheduling. +//! +//! This crate provides a third flavor: a multi-threaded runtime without work stealing. +//! This flavor is as efficient as the single-threaded runtime while allows the async +//! program to use multiple cores. + +use once_cell::sync::{Lazy, OnceCell}; +use rand::Rng; +use std::sync::Arc; +use std::thread::JoinHandle; +use std::time::Duration; +use thread_local::ThreadLocal; +use tokio::runtime::{Builder, Handle}; +use tokio::sync::oneshot::{channel, Sender}; + +/// Pingora async multi-threaded runtime +/// +/// The `Steal` flavor is effectively tokio multi-threaded runtime. +/// +/// The `NoSteal` flavor is backed by multiple tokio single-threaded runtime. +pub enum Runtime { + Steal(tokio::runtime::Runtime), + NoSteal(NoStealRuntime), +} + +impl Runtime { + /// Create a `Steal` flavor runtime. This just a regular tokio runtime + pub fn new_steal(threads: usize, name: &str) -> Self { + Self::Steal( + Builder::new_multi_thread() + .enable_all() + .worker_threads(threads) + .thread_name(name) + .build() + .unwrap(), + ) + } + + /// Create a `NoSteal` flavor runtime. This is backed by multiple tokio current-thread runtime + pub fn new_no_steal(threads: usize, name: &str) -> Self { + Self::NoSteal(NoStealRuntime::new(threads, name)) + } + + /// Return the &[Handle] of the [Runtime]. + /// For `Steal` flavor, it will just return the &[Handle]. + /// For `NoSteal` flavor, it will return the &[Handle] of a random thread in its pool. + /// So if we want tasks to spawn on all the threads, call this function to get a fresh [Handle] + /// for each async task. + pub fn get_handle(&self) -> &Handle { + match self { + Self::Steal(r) => r.handle(), + Self::NoSteal(r) => r.get_runtime(), + } + } + + /// Call tokio's `shutdown_timeout` of all the runtimes. This function is blocking until + /// all runtimes exit. + pub fn shutdown_timeout(self, timeout: Duration) { + match self { + Self::Steal(r) => r.shutdown_timeout(timeout), + Self::NoSteal(r) => r.shutdown_timeout(timeout), + } + } +} + +// only NoStealRuntime set the pools in thread threads +static CURRENT_HANDLE: Lazy> = Lazy::new(ThreadLocal::new); + +/// Return the [Handle] of current runtime. +/// If the current thread is under a `Steal` runtime, the current [Handle] is returned. +/// If the current thread is under a `NoSteal` runtime, the [Handle] of a random thread +/// under this runtime is returned. This function will panic if called outside any runtime. +pub fn current_handle() -> Handle { + if let Some(pools) = CURRENT_HANDLE.get() { + // safety: the CURRENT_HANDLE is set when the pool is being initialized in init_pools() + let pools = pools.get().unwrap(); + let mut rng = rand::thread_rng(); + let index = rng.gen_range(0..pools.len()); + pools[index].clone() + } else { + // not NoStealRuntime, just check the current tokio runtime + Handle::current() + } +} + +type Control = (Sender, JoinHandle<()>); +type Pools = Arc>>; + +/// Multi-threaded runtime backed by a pool of single threaded tokio runtime +pub struct NoStealRuntime { + threads: usize, + name: String, + // Lazily init the runtimes so that they are created after pingora + // daemonize itself. Otherwise the runtime threads are lost. + pools: Arc>>, + controls: OnceCell>, +} + +impl NoStealRuntime { + /// Create a new [NoStealRuntime]. Panic if `threads` is 0 + pub fn new(threads: usize, name: &str) -> Self { + assert!(threads != 0); + NoStealRuntime { + threads, + name: name.to_string(), + pools: Arc::new(OnceCell::new()), + controls: OnceCell::new(), + } + } + + fn init_pools(&self) -> (Box<[Handle]>, Vec) { + let mut pools = Vec::with_capacity(self.threads); + let mut controls = Vec::with_capacity(self.threads); + for _ in 0..self.threads { + let rt = Builder::new_current_thread().enable_all().build().unwrap(); + let handler = rt.handle().clone(); + let (tx, rx) = channel::(); + let pools_ref = self.pools.clone(); + let join = std::thread::Builder::new() + .name(self.name.clone()) + .spawn(move || { + CURRENT_HANDLE.get_or(|| pools_ref); + if let Ok(timeout) = rt.block_on(rx) { + rt.shutdown_timeout(timeout); + } // else Err(_): tx is dropped, just exit + }) + .unwrap(); + pools.push(handler); + controls.push((tx, join)); + } + + (pools.into_boxed_slice(), controls) + } + + /// Return the &[Handle] of a random thread of this runtime + pub fn get_runtime(&self) -> &Handle { + let mut rng = rand::thread_rng(); + + let index = rng.gen_range(0..self.threads); + self.get_runtime_at(index) + } + + /// Return the number of threads of this runtime + pub fn threads(&self) -> usize { + self.threads + } + + fn get_pools(&self) -> &[Handle] { + if let Some(p) = self.pools.get() { + p + } else { + // TODO: use a mutex to avoid creating a lot threads only to drop them + let (pools, controls) = self.init_pools(); + // there could be another thread racing with this one to init the pools + match self.pools.try_insert(pools) { + Ok(p) => { + // unwrap to make sure that this is the one that init both pools and controls + self.controls.set(controls).unwrap(); + p + } + // another thread already set it, just return it + Err((p, _my_pools)) => p, + } + } + } + + /// Return the &[Handle] of a given thread of this runtime + pub fn get_runtime_at(&self, index: usize) -> &Handle { + let pools = self.get_pools(); + &pools[index] + } + + /// Call tokio's `shutdown_timeout` of all the runtimes. This function is blocking until + /// all runtimes exit. + pub fn shutdown_timeout(mut self, timeout: Duration) { + if let Some(controls) = self.controls.take() { + let (txs, joins): (Vec>, Vec>) = controls.into_iter().unzip(); + for tx in txs { + let _ = tx.send(timeout); // Err() when rx is dropped + } + for join in joins { + let _ = join.join(); // ignore thread error + } + } // else, the controls and the runtimes are not even init yet, just return; + } + + // TODO: runtime metrics +} + +#[test] +fn test_steal_runtime() { + use tokio::time::{sleep, Duration}; + + let rt = Runtime::new_steal(2, "test"); + let handle = rt.get_handle(); + let ret = handle.block_on(async { + sleep(Duration::from_secs(1)).await; + let handle = current_handle(); + let join = handle.spawn(async { + sleep(Duration::from_secs(1)).await; + }); + join.await.unwrap(); + 1 + }); + + assert_eq!(ret, 1); +} + +#[test] +fn test_no_steal_runtime() { + use tokio::time::{sleep, Duration}; + + let rt = Runtime::new_no_steal(2, "test"); + let handle = rt.get_handle(); + let ret = handle.block_on(async { + sleep(Duration::from_secs(1)).await; + let handle = current_handle(); + let join = handle.spawn(async { + sleep(Duration::from_secs(1)).await; + }); + join.await.unwrap(); + 1 + }); + + assert_eq!(ret, 1); +} + +#[test] +fn test_no_steal_shutdown() { + use tokio::time::{sleep, Duration}; + + let rt = Runtime::new_no_steal(2, "test"); + let handle = rt.get_handle(); + let ret = handle.block_on(async { + sleep(Duration::from_secs(1)).await; + let handle = current_handle(); + let join = handle.spawn(async { + sleep(Duration::from_secs(1)).await; + }); + join.await.unwrap(); + 1 + }); + assert_eq!(ret, 1); + + rt.shutdown_timeout(Duration::from_secs(1)); +} diff --git a/pingora-timeout/Cargo.toml b/pingora-timeout/Cargo.toml new file mode 100644 index 0000000..1b271e4 --- /dev/null +++ b/pingora-timeout/Cargo.toml @@ -0,0 +1,37 @@ +[package] +name = "pingora-timeout" +version = "0.1.0" +authors = ["Yuchen Wu "] +license = "Apache-2.0" +edition = "2021" +repository = "https://github.com/cloudflare/pingora" +categories = ["asynchronous"] +keywords = ["async", "non-blocking", "pingora"] +description = """ +Highly efficient async timer and timeout system for Tokio runtimes. +""" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +name = "pingora_timeout" +path = "src/lib.rs" + +[dependencies] +tokio = { workspace = true, features = [ + "time", + "rt-multi-thread", + "macros", + "sync", +] } +pin-project-lite = "0.2" +futures = "0.3" +once_cell = { workspace = true } +parking_lot = "0.12" +thread_local = "1.0" + +[dev-dependencies] +bencher = "0.1.5" + +[[bench]] +name = "benchmark" +harness = false diff --git a/pingora-timeout/LICENSE b/pingora-timeout/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/pingora-timeout/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/pingora-timeout/benches/benchmark.rs b/pingora-timeout/benches/benchmark.rs new file mode 100644 index 0000000..cd6635d --- /dev/null +++ b/pingora-timeout/benches/benchmark.rs @@ -0,0 +1,169 @@ +// 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 pingora_timeout::*; +use std::time::{Duration, Instant}; +use tokio::time::sleep; +use tokio::time::timeout as tokio_timeout; + +const LOOP_SIZE: u32 = 100000; + +async fn bench_timeout() -> u32 { + let mut n = 0; + for _ in 0..LOOP_SIZE { + let fut = async { 1 }; + let to = timeout(Duration::from_secs(1), fut); + n += to.await.unwrap(); + } + n +} + +async fn bench_tokio_timeout() -> u32 { + let mut n = 0; + for _ in 0..LOOP_SIZE { + let fut = async { 1 }; + let to = tokio_timeout(Duration::from_secs(1), fut); + n += to.await.unwrap(); + } + n +} + +async fn bench_fast_timeout() -> u32 { + let mut n = 0; + for _ in 0..LOOP_SIZE { + let fut = async { 1 }; + let to = fast_timeout::fast_timeout(Duration::from_secs(1), fut); + n += to.await.unwrap(); + } + n +} + +fn bench_tokio_timer() { + let mut list = Vec::with_capacity(LOOP_SIZE as usize); + let before = Instant::now(); + for _ in 0..LOOP_SIZE { + list.push(sleep(Duration::from_secs(1))); + } + let elapsed = before.elapsed(); + println!( + "tokio timer create {:?} total, {:?} avg per iteration", + elapsed, + elapsed / LOOP_SIZE + ); + + let before = Instant::now(); + drop(list); + let elapsed = before.elapsed(); + println!( + "tokio timer drop {:?} total, {:?} avg per iteration", + elapsed, + elapsed / LOOP_SIZE + ); +} + +async fn bench_multi_thread_tokio_timer(threads: usize) { + let mut handlers = vec![]; + for _ in 0..threads { + let handler = tokio::spawn(async { + bench_tokio_timer(); + }); + handlers.push(handler); + } + for thread in handlers { + thread.await.unwrap(); + } +} + +use std::sync::Arc; + +async fn bench_multi_thread_timer(threads: usize, tm: Arc) { + let mut handlers = vec![]; + for _ in 0..threads { + let tm_ref = tm.clone(); + let handler = tokio::spawn(async move { + bench_timer(&tm_ref); + }); + handlers.push(handler); + } + for thread in handlers { + thread.await.unwrap(); + } +} + +use pingora_timeout::timer::TimerManager; + +fn bench_timer(tm: &TimerManager) { + let mut list = Vec::with_capacity(LOOP_SIZE as usize); + let before = Instant::now(); + for _ in 0..LOOP_SIZE { + list.push(tm.register_timer(Duration::from_secs(1))); + } + let elapsed = before.elapsed(); + println!( + "pingora timer create {:?} total, {:?} avg per iteration", + elapsed, + elapsed / LOOP_SIZE + ); + + let before = Instant::now(); + drop(list); + let elapsed = before.elapsed(); + println!( + "pingora timer drop {:?} total, {:?} avg per iteration", + elapsed, + elapsed / LOOP_SIZE + ); +} + +#[tokio::main(worker_threads = 4)] +async fn main() { + let before = Instant::now(); + bench_timeout().await; + let elapsed = before.elapsed(); + println!( + "pingora timeout {:?} total, {:?} avg per iteration", + elapsed, + elapsed / LOOP_SIZE + ); + + let before = Instant::now(); + bench_fast_timeout().await; + let elapsed = before.elapsed(); + println!( + "pingora fast timeout {:?} total, {:?} avg per iteration", + elapsed, + elapsed / LOOP_SIZE + ); + + let before = Instant::now(); + bench_tokio_timeout().await; + let elapsed = before.elapsed(); + println!( + "tokio timeout {:?} total, {:?} avg per iteration", + elapsed, + elapsed / LOOP_SIZE + ); + + println!("==========================="); + + let tm = pingora_timeout::timer::TimerManager::new(); + bench_timer(&tm); + bench_tokio_timer(); + + println!("==========================="); + + let tm = Arc::new(tm); + bench_multi_thread_timer(4, tm).await; + bench_multi_thread_tokio_timer(4).await; +} diff --git a/pingora-timeout/src/fast_timeout.rs b/pingora-timeout/src/fast_timeout.rs new file mode 100644 index 0000000..5fa7a3d --- /dev/null +++ b/pingora-timeout/src/fast_timeout.rs @@ -0,0 +1,132 @@ +// 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. + +//! The fast and more complicated version of pingora-timeout +//! +//! The following optimizations are applied +//! - The timeouts lazily initialize their timer when the Future is pending for the first time. +//! - There is no global lock for creating and cancelling timeouts. +//! - Timeout timers are rounded to the next 10ms tick and timers are shared across all timeouts with the same deadline. +//! +//! In order for this to work, a standalone thread is created to arm the timers, which has its +//! overheads. As a general rule, the benefits of this doesn't outweight the overhead unless +//! there are more than about 100/s timeout() calls in the system. Use regular tokio timeout or +//! [super::tokio_timeout] in the low usage case. + +use super::timer::*; +use super::*; +use once_cell::sync::Lazy; +use std::sync::Arc; + +static TIMER_MANAGER: Lazy> = Lazy::new(|| { + let tm = Arc::new(TimerManager::new()); + check_clock_thread(&tm); + tm +}); + +fn check_clock_thread(tm: &Arc) { + if tm.should_i_start_clock() { + std::thread::Builder::new() + .name("Timer thread".into()) + .spawn(|| TIMER_MANAGER.clock_thread()) + .unwrap(); + } +} + +/// The timeout generated by [fast_timeout()]. +/// +/// Users don't need to interact with this object. +pub struct FastTimeout(Duration); + +impl ToTimeout for FastTimeout { + fn timeout(&self) -> BoxFuture<'static, ()> { + Box::pin(TIMER_MANAGER.register_timer(self.0).poll()) + } + + fn create(d: Duration) -> Self { + FastTimeout(d) + } +} + +/// Similar to [tokio::time::timeout] but more efficient. +pub fn fast_timeout(duration: Duration, future: T) -> Timeout +where + T: Future, +{ + check_clock_thread(&TIMER_MANAGER); + Timeout::new_with_delay(future, duration) +} + +/// Similar to [tokio::time::sleep] but more efficient. +pub async fn fast_sleep(duration: Duration) { + check_clock_thread(&TIMER_MANAGER); + TIMER_MANAGER.register_timer(duration).poll().await +} + +/// Pause the timer for fork() +/// +/// Because RwLock across fork() is undefined behavior, this function makes sure that no one +/// holds any locks. +/// +/// This function should be called right before fork(). +pub fn pause_for_fork() { + TIMER_MANAGER.pause_for_fork(); +} + +/// Unpause the timer after fork() +/// +/// This function should be called right after fork(). +pub fn unpause() { + TIMER_MANAGER.unpause(); +} + +#[cfg(test)] +mod tests { + use super::*; + use std::time::Duration; + + #[tokio::test] + async fn test_timeout() { + let fut = tokio_sleep(Duration::from_secs(1000)); + let to = fast_timeout(Duration::from_secs(1), fut); + assert!(to.await.is_err()) + } + + #[tokio::test] + async fn test_instantly_return() { + let fut = async { 1 }; + let to = fast_timeout(Duration::from_secs(1), fut); + assert_eq!(to.await.unwrap(), 1) + } + + #[tokio::test] + async fn test_delayed_return() { + let fut = async { + tokio_sleep(Duration::from_secs(1)).await; + 1 + }; + let to = fast_timeout(Duration::from_secs(1000), fut); + assert_eq!(to.await.unwrap(), 1) + } + + #[tokio::test] + async fn test_sleep() { + let fut = async { + fast_sleep(Duration::from_secs(1)).await; + 1 + }; + let to = fast_timeout(Duration::from_secs(1000), fut); + assert_eq!(to.await.unwrap(), 1) + } +} diff --git a/pingora-timeout/src/lib.rs b/pingora-timeout/src/lib.rs new file mode 100644 index 0000000..f3a33dd --- /dev/null +++ b/pingora-timeout/src/lib.rs @@ -0,0 +1,175 @@ +// 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. + +#![warn(clippy::all)] + +//! A drop-in replacement of [tokio::time::timeout] which is much more efficient. +//! +//! Similar to [tokio::time::timeout] but more efficient on busy concurrent IOs where timeouts are +//! created and canceled very frequently. +//! +//! This crate provides the following optimizations +//! - The timeouts lazily initializes their timer when the Future is pending for the first time. +//! - There is no global lock for creating and cancelling timeouts. +//! - Timeout timers are rounded to the next 10ms tick and timers are shared across all timeouts with the same deadline. +//! +//! Benchmark: +//! +//! 438.302µs total, 4ns avg per iteration +//! +//! v.s. Tokio timeout(): +//! +//! 10.716192ms total, 107ns avg per iteration +//! + +pub mod fast_timeout; +pub mod timer; + +pub use fast_timeout::fast_sleep as sleep; +pub use fast_timeout::fast_timeout as timeout; + +use futures::future::BoxFuture; +use pin_project_lite::pin_project; +use std::future::Future; +use std::pin::Pin; +use std::task::{self, Poll}; +use tokio::time::{sleep as tokio_sleep, Duration}; + +/// The interface to start a timeout +/// +/// Users don't need to interact with this trait +pub trait ToTimeout { + fn timeout(&self) -> BoxFuture<'static, ()>; + fn create(d: Duration) -> Self; +} + +/// The timeout generated by [tokio_timeout()]. +/// +/// Users don't need to interact with this object. +pub struct TokioTimeout(Duration); + +impl ToTimeout for TokioTimeout { + fn timeout(&self) -> BoxFuture<'static, ()> { + Box::pin(tokio_sleep(self.0)) + } + + fn create(d: Duration) -> Self { + TokioTimeout(d) + } +} + +/// The error type returned when the timeout is reached. +#[derive(Debug)] +pub struct Elapsed; + +impl std::fmt::Display for Elapsed { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "Timeout Elapsed") + } +} + +impl std::error::Error for Elapsed {} + +/// The [tokio::time::timeout] with just lazy timer initialization. +/// +/// The timer is created the first time the `future` is pending. This avoids unnecessary timer +/// creation and cancellation on busy IOs with a good chance to be already ready (e.g., reading +/// data from TCP where the recv buffer already has a lot data to read right away). +pub fn tokio_timeout(duration: Duration, future: T) -> Timeout +where + T: Future, +{ + Timeout::::new_with_delay(future, duration) +} + +pin_project! { + /// The timeout future returned by the timeout functions + #[must_use = "futures do nothing unless you `.await` or poll them"] + pub struct Timeout { + #[pin] + value: T, + #[pin] + delay: Option>, + callback: F, // callback to create the timer + } +} + +impl Timeout +where + F: ToTimeout, +{ + pub(crate) fn new_with_delay(value: T, d: Duration) -> Timeout { + Timeout { + value, + delay: None, + callback: F::create(d), + } + } +} + +impl Future for Timeout +where + T: Future, + F: ToTimeout, +{ + type Output = Result; + + fn poll(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll { + let mut me = self.project(); + + // First, try polling the future + if let Poll::Ready(v) = me.value.poll(cx) { + return Poll::Ready(Ok(v)); + } + + let delay = me + .delay + .get_or_insert_with(|| Box::pin(me.callback.timeout())); + + match delay.as_mut().poll(cx) { + Poll::Pending => Poll::Pending, + Poll::Ready(()) => Poll::Ready(Err(Elapsed {})), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::time::Duration; + + #[tokio::test] + async fn test_timeout() { + let fut = tokio_sleep(Duration::from_secs(1000)); + let to = timeout(Duration::from_secs(1), fut); + assert!(to.await.is_err()) + } + + #[tokio::test] + async fn test_instantly_return() { + let fut = async { 1 }; + let to = timeout(Duration::from_secs(1), fut); + assert_eq!(to.await.unwrap(), 1) + } + + #[tokio::test] + async fn test_delayed_return() { + let fut = async { + tokio_sleep(Duration::from_secs(1)).await; + 1 + }; + let to = timeout(Duration::from_secs(1000), fut); + assert_eq!(to.await.unwrap(), 1) + } +} diff --git a/pingora-timeout/src/timer.rs b/pingora-timeout/src/timer.rs new file mode 100644 index 0000000..6e25c24 --- /dev/null +++ b/pingora-timeout/src/timer.rs @@ -0,0 +1,328 @@ +// 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. + +//! Lightweight timer for systems with high rate of operations with timeout +//! associated with them +//! +//! Users don't need to interact with this module. +//! +//! The idea is to bucket timers into finite time slots so that operations that +//! start and end quickly don't have to create their own timers all the time +//! +//! Benchmark: +//! - create 7.809622ms total, 78ns avg per iteration +//! - drop: 1.348552ms total, 13ns avg per iteration +//! +//! tokio timer: +//! - create 34.317439ms total, 343ns avg per iteration +//! - drop: 10.694154ms total, 106ns avg per iteration + +use parking_lot::RwLock; +use std::collections::BTreeMap; +use std::sync::atomic::{AtomicBool, AtomicI64, Ordering}; +use std::sync::Arc; +use std::time::{Duration, Instant}; +use thread_local::ThreadLocal; +use tokio::sync::Notify; + +const RESOLUTION_MS: u64 = 10; +const RESOLUTION_DURATION: Duration = Duration::from_millis(RESOLUTION_MS); + +// round to the NEXT timestamp based on the resolution +#[inline] +fn round_to(raw: u128, resolution: u128) -> u128 { + raw - 1 + resolution - (raw - 1) % resolution +} +// millisecond resolution as most +#[derive(PartialEq, PartialOrd, Eq, Ord, Clone, Copy, Debug)] +struct Time(u128); + +impl From for Time { + fn from(raw_ms: u128) -> Self { + Time(round_to(raw_ms, RESOLUTION_MS as u128)) + } +} + +impl From for Time { + fn from(d: Duration) -> Self { + Time(round_to(d.as_millis(), RESOLUTION_MS as u128)) + } +} + +impl Time { + pub fn not_after(&self, ts: u128) -> bool { + self.0 <= ts + } +} + +/// the stub for waiting for a timer to be expired. +pub struct TimerStub(Arc, Arc); + +impl TimerStub { + /// Wait for the timer to expire. + pub async fn poll(self) { + if self.1.load(Ordering::SeqCst) { + return; + } + self.0.notified().await; + } +} + +struct Timer(Arc, Arc); + +impl Timer { + pub fn new() -> Self { + Timer(Arc::new(Notify::new()), Arc::new(AtomicBool::new(false))) + } + + pub fn fire(&self) { + self.1.store(true, Ordering::SeqCst); + self.0.notify_waiters(); + } + + pub fn subscribe(&self) -> TimerStub { + TimerStub(self.0.clone(), self.1.clone()) + } +} + +/// The object that holds all the timers registered to it. +pub struct TimerManager { + // each thread insert into its local timer tree to avoid lock contention + timers: ThreadLocal>>, + zero: Instant, // the reference zero point of Timestamp + // Start a new clock thread if this is -1 or staled. The clock thread should keep updating this + clock_watchdog: AtomicI64, + paused: AtomicBool, +} + +// Consider the clock thread is dead after it fails to update the thread in DELAYS_SEC +const DELAYS_SEC: i64 = 2; // TODO: make sure this value is larger than RESOLUTION_DURATION + +impl Default for TimerManager { + fn default() -> Self { + TimerManager { + timers: ThreadLocal::new(), + zero: Instant::now(), + clock_watchdog: AtomicI64::new(-DELAYS_SEC), + paused: AtomicBool::new(false), + } + } +} + +impl TimerManager { + /// Create a new [TimerManager] + pub fn new() -> Self { + Self::default() + } + + // this thread sleep a resolution time and fire all Timers that a due to fire + pub(crate) fn clock_thread(&self) { + loop { + std::thread::sleep(RESOLUTION_DURATION); + let now = Instant::now() - self.zero; + self.clock_watchdog + .store(now.as_secs() as i64, Ordering::Relaxed); + if self.is_paused_for_fork() { + // just stop acquiring the locks, waiting for fork to happen + continue; + } + let now = now.as_millis(); + // iterate through the timer tree for all threads + for thread_timer in self.timers.iter() { + let mut timers = thread_timer.write(); + // Fire all timers until now + loop { + let key_to_remove = timers.iter().next().and_then(|(k, _)| { + if k.not_after(now) { + Some(*k) + } else { + None + } + }); + if let Some(k) = key_to_remove { + let timer = timers.remove(&k); + // safe to unwrap, the key is from iter().next() + timer.unwrap().fire(); + } else { + break; + } + } + // write lock drops here + } + } + } + + // False if the clock is already started + // If true, the caller must start the clock thread next + pub(crate) fn should_i_start_clock(&self) -> bool { + let Err(prev) = self.is_clock_running() else { + return false; + }; + let now = Instant::now().duration_since(self.zero).as_secs() as i64; + let res = + self.clock_watchdog + .compare_exchange(prev, now, Ordering::SeqCst, Ordering::SeqCst); + res.is_ok() + } + + // Ok(()) if clock is running (watch dog is within DELAYS_SEC of now) + // Err(time) if watch do stopped at `time` + pub(crate) fn is_clock_running(&self) -> Result<(), i64> { + let now = Instant::now().duration_since(self.zero).as_secs() as i64; + let prev = self.clock_watchdog.load(Ordering::SeqCst); + if now < prev + DELAYS_SEC { + Ok(()) + } else { + Err(prev) + } + } + + /// Register a timer. + /// + /// When the timer expires, the [TimerStub] will be notified. + pub fn register_timer(&self, duration: Duration) -> TimerStub { + if self.is_paused_for_fork() { + // Return a dummy TimerStub that will trigger right away. + // This is fine assuming pause_for_fork() is called right before fork(). + // The only possible register_timer() is from another thread which will + // be entirely lost after fork() + // TODO: buffer these register calls instead (without a lock) + let timer = Timer::new(); + timer.fire(); + return timer.subscribe(); + } + let now: Time = (Instant::now() + duration - self.zero).into(); + { + let timers = self.timers.get_or(|| RwLock::new(BTreeMap::new())).read(); + if let Some(t) = timers.get(&now) { + return t.subscribe(); + } + } // drop read lock + + let timer = Timer::new(); + let mut timers = self.timers.get_or(|| RwLock::new(BTreeMap::new())).write(); + // Usually we check if another thread has insert the same node before we get the write lock, + // but because only this thread will insert anything to its local timers tree, there + // is no possible race that can happen. The only other thread is the clock thread who + // only removes timer from the tree + let stub = timer.subscribe(); + timers.insert(now, timer); + stub + } + + fn is_paused_for_fork(&self) -> bool { + self.paused.load(Ordering::SeqCst) + } + + /// Pause the timer for fork() + /// + /// Because RwLock across fork() is undefined behavior, this function makes sure that no one + /// holds any locks. + /// + /// This function should be called right before fork(). + pub fn pause_for_fork(&self) { + self.paused.store(true, Ordering::SeqCst); + // wait for everything to get out of their locks + std::thread::sleep(RESOLUTION_DURATION * 2); + } + + /// Unpause the timer after fork() + /// + /// This function should be called right after fork(). + pub fn unpause(&self) { + self.paused.store(false, Ordering::SeqCst) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::sync::Arc; + + #[test] + fn test_round() { + assert_eq!(round_to(30, 10), 30); + assert_eq!(round_to(31, 10), 40); + assert_eq!(round_to(29, 10), 30); + } + + #[test] + fn test_time() { + let t: Time = 128.into(); // t will round to 130 + assert_eq!(t, Duration::from_millis(130).into()); + assert!(!t.not_after(128)); + assert!(!t.not_after(129)); + assert!(t.not_after(130)); + assert!(t.not_after(131)); + } + + #[tokio::test] + async fn test_timer_manager() { + let tm_a = Arc::new(TimerManager::new()); + let tm = tm_a.clone(); + std::thread::spawn(move || tm_a.clock_thread()); + + let now = Instant::now(); + let t1 = tm.register_timer(Duration::from_secs(1)); + let t2 = tm.register_timer(Duration::from_secs(1)); + t1.poll().await; + assert_eq!(now.elapsed().as_secs(), 1); + let now = Instant::now(); + t2.poll().await; + // t2 fired along t1 so no extra wait time + assert_eq!(now.elapsed().as_secs(), 0); + } + + #[test] + fn test_timer_manager_start_check() { + let tm = Arc::new(TimerManager::new()); + assert!(tm.should_i_start_clock()); + assert!(!tm.should_i_start_clock()); + assert!(tm.is_clock_running().is_ok()); + } + + #[test] + fn test_timer_manager_watchdog() { + let tm = Arc::new(TimerManager::new()); + assert!(tm.should_i_start_clock()); + assert!(!tm.should_i_start_clock()); + + // we don't actually start the clock thread, sleep for the watchdog to expire + std::thread::sleep(Duration::from_secs(DELAYS_SEC as u64 + 1)); + assert!(tm.is_clock_running().is_err()); + assert!(tm.should_i_start_clock()); + } + + #[tokio::test] + async fn test_timer_manager_pause() { + let tm_a = Arc::new(TimerManager::new()); + let tm = tm_a.clone(); + std::thread::spawn(move || tm_a.clock_thread()); + + let now = Instant::now(); + let t1 = tm.register_timer(Duration::from_secs(2)); + tm.pause_for_fork(); + // no actual fork happen, we just test that pause and unpause work + + // any timer in this critical section is timed out right away + let t2 = tm.register_timer(Duration::from_secs(2)); + t2.poll().await; + assert_eq!(now.elapsed().as_secs(), 0); + + std::thread::sleep(Duration::from_secs(1)); + tm.unpause(); + t1.poll().await; + assert_eq!(now.elapsed().as_secs(), 2); + } +} diff --git a/pingora/Cargo.toml b/pingora/Cargo.toml new file mode 100644 index 0000000..c269199 --- /dev/null +++ b/pingora/Cargo.toml @@ -0,0 +1,50 @@ +[package] +name = "pingora" +version = "0.1.0" +authors = ["Yuchen Wu "] +license = "Apache-2.0" +edition = "2021" +repository = "https://github.com/cloudflare/pingora" +description = """ +A framework to build fast, reliable and programmable networked systems at Internet scale. +""" +categories = ["asynchronous", "network-programming"] +keywords = ["async", "proxy", "http", "pingora"] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +name = "pingora" +path = "src/lib.rs" + +[dependencies] +pingora-core = { version = "0.1.0", path = "../pingora-core" } +pingora-http = { version = "0.1.0", path = "../pingora-http" } +pingora-timeout = { version = "0.1.0", path = "../pingora-timeout" } +pingora-load-balancing = { version = "0.1.0", path = "../pingora-load-balancing", optional = true } +pingora-proxy = { version = "0.1.0", path = "../pingora-proxy", optional = true } +pingora-cache = { version = "0.1.0", path = "../pingora-cache", optional = true } + +[dev-dependencies] +structopt = "0.3" +tokio = { workspace = true, features = ["rt-multi-thread", "signal"] } +matches = "0.1" +env_logger = "0.9" +reqwest = { version = "0.11", features = ["rustls"], default-features = false } +hyperlocal = "0.8" +hyper = "0.14" +jemallocator = "0.5" +async-trait = { workspace = true } +http = { workspace = true } +log = { workspace = true } +prometheus = "0.13" +once_cell = { workspace = true } +bytes = { workspace = true } + +[features] +default = ["openssl"] +openssl = ["pingora-core/openssl"] +boringssl = ["pingora-core/boringssl"] +proxy = ["pingora-proxy"] +lb = ["pingora-load-balancing", "proxy"] +cache = ["pingora-cache"] diff --git a/pingora/LICENSE b/pingora/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/pingora/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/pingora/examples/app/echo.rs b/pingora/examples/app/echo.rs new file mode 100644 index 0000000..61f94e5 --- /dev/null +++ b/pingora/examples/app/echo.rs @@ -0,0 +1,98 @@ +// 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 async_trait::async_trait; +use bytes::Bytes; +use http::{Response, StatusCode}; +use log::debug; +use once_cell::sync::Lazy; +use pingora_timeout::timeout; +use prometheus::{register_int_counter, IntCounter}; +use std::sync::Arc; +use std::time::Duration; +use tokio::io::{AsyncReadExt, AsyncWriteExt}; + +use pingora::apps::http_app::ServeHttp; +use pingora::apps::ServerApp; +use pingora::protocols::http::ServerSession; +use pingora::protocols::Stream; +use pingora::server::ShutdownWatch; + +static REQ_COUNTER: Lazy = + Lazy::new(|| register_int_counter!("reg_counter", "Number of requests").unwrap()); + +#[derive(Clone)] +pub struct EchoApp; + +#[async_trait] +impl ServerApp for EchoApp { + async fn process_new( + self: &Arc, + mut io: Stream, + _shutdown: &ShutdownWatch, + ) -> Option { + let mut buf = [0; 1024]; + loop { + let n = io.read(&mut buf).await.unwrap(); + if n == 0 { + debug!("session closing"); + return None; + } + io.write_all(&buf[0..n]).await.unwrap(); + io.flush().await.unwrap(); + } + } +} + +pub struct HttpEchoApp; + +#[async_trait] +impl ServeHttp for HttpEchoApp { + async fn response(&self, http_stream: &mut ServerSession) -> Response> { + REQ_COUNTER.inc(); + // 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() + } +} + +impl EchoApp { + pub fn new() -> Arc { + Arc::new(EchoApp {}) + } +} + +pub fn new_http_echo_app() -> Arc { + Arc::new(HttpEchoApp {}) +} diff --git a/pingora/examples/app/mod.rs b/pingora/examples/app/mod.rs new file mode 100644 index 0000000..7395897 --- /dev/null +++ b/pingora/examples/app/mod.rs @@ -0,0 +1,16 @@ +// 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. + +pub mod echo; +pub mod proxy; diff --git a/pingora/examples/app/proxy.rs b/pingora/examples/app/proxy.rs new file mode 100644 index 0000000..4ac0aae --- /dev/null +++ b/pingora/examples/app/proxy.rs @@ -0,0 +1,104 @@ +// 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 async_trait::async_trait; +use log::debug; + +use std::sync::Arc; +use tokio::io::{AsyncReadExt, AsyncWriteExt}; +use tokio::select; + +use pingora::apps::ServerApp; +use pingora::connectors::TransportConnector; +use pingora::protocols::Stream; +use pingora::server::ShutdownWatch; +use pingora::upstreams::peer::BasicPeer; + +pub struct ProxyApp { + client_connector: TransportConnector, + proxy_to: BasicPeer, +} + +enum DuplexEvent { + DownstreamRead(usize), + UpstreamRead(usize), +} + +impl ProxyApp { + pub fn new(proxy_to: BasicPeer) -> Self { + ProxyApp { + client_connector: TransportConnector::new(None), + proxy_to, + } + } + + async fn duplex(&self, mut server_session: Stream, mut client_session: Stream) { + let mut upstream_buf = [0; 1024]; + let mut downstream_buf = [0; 1024]; + loop { + let downstream_read = server_session.read(&mut upstream_buf); + let upstream_read = client_session.read(&mut downstream_buf); + let event: DuplexEvent; + select! { + n = downstream_read => event + = DuplexEvent::DownstreamRead(n.unwrap()), + n = upstream_read => event + = DuplexEvent::UpstreamRead(n.unwrap()), + } + match event { + DuplexEvent::DownstreamRead(0) => { + debug!("downstream session closing"); + return; + } + DuplexEvent::UpstreamRead(0) => { + debug!("upstream session closing"); + return; + } + DuplexEvent::DownstreamRead(n) => { + client_session.write_all(&upstream_buf[0..n]).await.unwrap(); + client_session.flush().await.unwrap(); + } + DuplexEvent::UpstreamRead(n) => { + server_session + .write_all(&downstream_buf[0..n]) + .await + .unwrap(); + server_session.flush().await.unwrap(); + } + } + } + } +} + +#[async_trait] +impl ServerApp for ProxyApp { + async fn process_new( + self: &Arc, + io: Stream, + _shutdown: &ShutdownWatch, + ) -> Option { + let client_session = self.client_connector.new_stream(&self.proxy_to).await; + + match client_session { + Ok(client_session) => { + self.duplex(io, client_session).await; + None + } + Err(e) => { + debug!("Failed to create client session: {}", e); + None + } + } + } +} diff --git a/pingora/examples/client.rs b/pingora/examples/client.rs new file mode 100644 index 0000000..c235dd1 --- /dev/null +++ b/pingora/examples/client.rs @@ -0,0 +1,40 @@ +// 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 pingora::connectors::http::Connector; +use pingora::upstreams::peer::HttpPeer; +use pingora_http::RequestHeader; + +#[tokio::main] +async fn main() { + let connector = Connector::new(None); + + let mut peer = HttpPeer::new("1.1.1.1:443", true, "one.one.one.one".into()); + peer.options.set_http_version(2, 1); + let (mut http, _reused) = connector.get_http_session(&peer).await.unwrap(); + + let mut new_request = RequestHeader::build("GET", b"/", None).unwrap(); + new_request + .insert_header("Host", "one.one.one.one") + .unwrap(); + http.write_request_header(Box::new(new_request)) + .await + .unwrap(); + // Servers usually don't respond until the full request body is read. + http.finish_request_body().await.unwrap(); + http.read_response_header().await.unwrap(); + println!("{:#?}", http.response_header().unwrap()); + // TODO: continue reading the body + // TODO: return the connection back to the `connector` (or discard it) +} diff --git a/pingora/examples/server.rs b/pingora/examples/server.rs new file mode 100644 index 0000000..be60b3a --- /dev/null +++ b/pingora/examples/server.rs @@ -0,0 +1,163 @@ +// 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. + +#[global_allocator] +static GLOBAL: jemallocator::Jemalloc = jemallocator::Jemalloc; + +use pingora::server::configuration::Opt; +use pingora::server::{Server, ShutdownWatch}; +use pingora::services::background::{background_service, BackgroundService}; +use pingora::services::{listening::Service as ListeningService, Service}; + +use async_trait::async_trait; +use structopt::StructOpt; +use tokio::time::interval; + +use std::time::Duration; +use std::vec::Vec; + +mod app; +mod service; + +pub struct ExampleBackgroundService; +#[async_trait] +impl BackgroundService for ExampleBackgroundService { + async fn start(&self, mut shutdown: ShutdownWatch) { + let mut period = interval(Duration::from_secs(1)); + loop { + tokio::select! { + _ = shutdown.changed() => { + // shutdown + break; + } + _ = period.tick() => { + // do some work + // ... + } + } + } + } +} + +use pingora::tls::pkey::{PKey, Private}; +use pingora::tls::x509::X509; +struct DynamicCert { + cert: X509, + key: PKey, +} + +impl DynamicCert { + fn new(cert: &str, key: &str) -> Box { + let cert_bytes = std::fs::read(cert).unwrap(); + let cert = X509::from_pem(&cert_bytes).unwrap(); + + let key_bytes = std::fs::read(key).unwrap(); + let key = PKey::private_key_from_pem(&key_bytes).unwrap(); + Box::new(DynamicCert { cert, key }) + } +} + +#[async_trait] +impl pingora::listeners::TlsAccept for DynamicCert { + async fn certificate_callback(&self, ssl: &mut pingora::tls::ssl::SslRef) { + use pingora::tls::ext; + ext::ssl_use_certificate(ssl, &self.cert).unwrap(); + ext::ssl_use_private_key(ssl, &self.key).unwrap(); + } +} + +const USAGE: &str = r#" +Usage +port 6142: TCP echo server +nc 127.0.0.1 6142 + +port 6143: TLS echo server +openssl s_client -connect 127.0.0.1:6143 + +port 6145: Http echo server +curl http://127.0.0.1:6145 -v -d 'hello' + +port 6148: Https echo server +curl https://127.0.0.1:6148 -vk -d 'hello' + +port 6141: TCP proxy +curl http://127.0.0.1:6141 -v -H 'host: 1.1.1.1' + +port 6144: TLS proxy +curl https://127.0.0.1:6144 -vk -H 'host: one.one.one.one' -o /dev/null + +port 6150: metrics endpoint +curl http://127.0.0.1:6150 +"#; + +pub fn main() { + env_logger::init(); + + print!("{USAGE}"); + + let opt = Some(Opt::from_args()); + let mut my_server = Server::new(opt).unwrap(); + my_server.bootstrap(); + + 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 echo_service = service::echo::echo_service(); + echo_service.add_tcp("127.0.0.1:6142"); + echo_service + .add_tls("0.0.0.0:6143", &cert_path, &key_path) + .unwrap(); + + let mut echo_service_http = service::echo::echo_service_http(); + echo_service_http.add_tcp("0.0.0.0:6145"); + echo_service_http.add_uds("/tmp/echo.sock", None); + + let dynamic_cert = DynamicCert::new(&cert_path, &key_path); + let mut tls_settings = pingora::listeners::TlsSettings::with_callbacks(dynamic_cert).unwrap(); + // by default intermediate supports both TLS 1.2 and 1.3. We force to tls 1.2 just for the demo + tls_settings + .set_max_proto_version(Some(pingora::tls::ssl::SslVersion::TLS1_2)) + .unwrap(); + tls_settings.enable_h2(); + echo_service_http.add_tls_with_settings("0.0.0.0:6148", None, tls_settings); + + let proxy_service = service::proxy::proxy_service( + "0.0.0.0:6141", // listen + "1.1.1.1:80", // proxy to + ); + + let proxy_service_ssl = service::proxy::proxy_service_tls( + "0.0.0.0:6144", // listen + "1.1.1.1:443", // proxy to + "one.one.one.one", // SNI + &cert_path, + &key_path, + ); + + let mut prometheus_service_http = ListeningService::prometheus_http_service(); + prometheus_service_http.add_tcp("127.0.0.1:6150"); + + let background_service = background_service("example", ExampleBackgroundService {}); + + let services: Vec> = vec![ + Box::new(echo_service), + Box::new(echo_service_http), + Box::new(proxy_service), + Box::new(proxy_service_ssl), + Box::new(prometheus_service_http), + Box::new(background_service), + ]; + my_server.add_services(services); + my_server.run_forever(); +} diff --git a/pingora/examples/service/echo.rs b/pingora/examples/service/echo.rs new file mode 100644 index 0000000..8126088 --- /dev/null +++ b/pingora/examples/service/echo.rs @@ -0,0 +1,24 @@ +// 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 crate::app::echo::{new_http_echo_app, EchoApp, HttpEchoApp}; +use pingora::services::listening::Service; + +pub fn echo_service() -> Service { + Service::new("Echo Service".to_string(), EchoApp::new()) +} + +pub fn echo_service_http() -> Service { + Service::new("Echo Service HTTP".to_string(), new_http_echo_app()) +} diff --git a/pingora/examples/service/mod.rs b/pingora/examples/service/mod.rs new file mode 100644 index 0000000..7395897 --- /dev/null +++ b/pingora/examples/service/mod.rs @@ -0,0 +1,16 @@ +// 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. + +pub mod echo; +pub mod proxy; diff --git a/pingora/examples/service/proxy.rs b/pingora/examples/service/proxy.rs new file mode 100644 index 0000000..a103b47 --- /dev/null +++ b/pingora/examples/service/proxy.rs @@ -0,0 +1,46 @@ +// 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 crate::app::proxy::ProxyApp; +use pingora_core::listeners::Listeners; +use pingora_core::services::listening::Service; +use pingora_core::upstreams::peer::BasicPeer; +use std::sync::Arc; + +pub fn proxy_service(addr: &str, proxy_addr: &str) -> Service { + let proxy_to = BasicPeer::new(proxy_addr); + + Service::with_listeners( + "Proxy Service".to_string(), + Listeners::tcp(addr), + Arc::new(ProxyApp::new(proxy_to)), + ) +} + +pub fn proxy_service_tls( + addr: &str, + proxy_addr: &str, + proxy_sni: &str, + cert_path: &str, + key_path: &str, +) -> Service { + let mut proxy_to = BasicPeer::new(proxy_addr); + // set SNI to enable TLS + proxy_to.sni = proxy_sni.into(); + Service::with_listeners( + "Proxy Service TLS".to_string(), + Listeners::tls(addr, cert_path, key_path).unwrap(), + Arc::new(ProxyApp::new(proxy_to)), + ) +} diff --git a/pingora/src/lib.rs b/pingora/src/lib.rs new file mode 100644 index 0000000..c714ca6 --- /dev/null +++ b/pingora/src/lib.rs @@ -0,0 +1,102 @@ +// 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. + +#![warn(clippy::all)] +#![allow(clippy::new_without_default)] +#![allow(clippy::type_complexity)] +#![allow(clippy::match_wild_err_arm)] +#![allow(clippy::missing_safety_doc)] +#![allow(clippy::upper_case_acronyms)] +// This enables the feature that labels modules that are only available with +// certain pingora features +#![cfg_attr(docsrs, feature(doc_cfg))] + +//! # Pingora +//! +//! Pingora is a framework to build fast, reliable and programmable networked systems at Internet scale. +//! +//! # Features +//! - Http 1.x and Http 2 +//! - Modern TLS with OpenSSL or BoringSSL (FIPS compatible) +//! - Zero downtime upgrade +//! +//! # Usage +//! This crate provides low level service and protocol implementation and abstraction. +//! +//! If looking to build a (reverse) proxy, see [`pingora-proxy`](https://docs.rs/pingora-proxy) crate. +//! +//! # features +//! * `openssl`: Using OpenSSL as the internal TLS backend. This feature is default on. +//! * `boringssl`: Switch the internal TLS library from OpenSSL to BoringSSL. This feature will disable `openssl`. +//! * `proxy`: This feature will include and export `pingora_proxy::prelude::*`. +//! * `lb`: This feature will include and export `pingora_load_balancing::prelude::*`. +//! * `cache`: This feature will include and export `pingora_cache::prelude::*`. + +pub use pingora_core::*; + +/// HTTP header objects that preserve http header cases +pub mod http { + pub use pingora_http::*; +} + +#[cfg(feature = "cache")] +#[cfg_attr(docsrs, doc(cfg(feature = "cache")))] +/// Caching services and tooling +pub mod cache { + pub use pingora_cache::*; +} + +#[cfg(feature = "lb")] +#[cfg_attr(docsrs, doc(cfg(feature = "lb")))] +/// Load balancing recipes +pub mod lb { + pub use pingora_load_balancing::*; +} + +#[cfg(feature = "proxy")] +#[cfg_attr(docsrs, doc(cfg(feature = "proxy")))] +/// Load balancing recipes +pub mod proxy { + pub use pingora_proxy::*; +} + +#[cfg(feature = "time")] +#[cfg_attr(docsrs, doc(cfg(feature = "time")))] +/// Timeouts and other useful time utilities +pub mod time { + pub use pingora_timeout::*; +} + +/// A useful set of types for getting started +pub mod prelude { + pub use pingora_core::prelude::*; + pub use pingora_http::prelude::*; + pub use pingora_timeout::*; + + #[cfg(feature = "cache")] + #[cfg_attr(docsrs, doc(cfg(feature = "cache")))] + pub use pingora_cache::prelude::*; + + #[cfg(feature = "lb")] + #[cfg_attr(docsrs, doc(cfg(feature = "lb")))] + pub use pingora_load_balancing::prelude::*; + + #[cfg(feature = "proxy")] + #[cfg_attr(docsrs, doc(cfg(feature = "proxy")))] + pub use pingora_proxy::prelude::*; + + #[cfg(feature = "time")] + #[cfg_attr(docsrs, doc(cfg(feature = "time")))] + pub use pingora_timeout::*; +} diff --git a/pingora/tests/pingora_conf.yaml b/pingora/tests/pingora_conf.yaml new file mode 100644 index 0000000..c21ae15 --- /dev/null +++ b/pingora/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/tinyufo/Cargo.toml b/tinyufo/Cargo.toml new file mode 100644 index 0000000..a726715 --- /dev/null +++ b/tinyufo/Cargo.toml @@ -0,0 +1,41 @@ +[package] +name = "TinyUFO" +version = "0.1.0" +authors = ["Yuchen Wu "] +edition = "2021" +license = "Apache-2.0" +description = "In-memory cache implementation with TinyLFU as the admission policy and S3-FIFO as the eviction policy" +repository = "https://github.com/cloudflare/pingora" +categories = ["algorithms", "caching"] +keywords = ["cache", "pingora"] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +name = "tinyufo" +path = "src/lib.rs" + +[dependencies] +ahash = { workspace = true } +flurry = "<0.5.0" # Try not to require Rust 1.71 +parking_lot = "0" +crossbeam-queue = "0" + +[dev-dependencies] +rand = "0" +lru = "0" +zipf = "7" +moka = { version = "0", features = ["sync"] } +dhat = "0" + +[[bench]] +name = "bench_perf" +harness = false + +[[bench]] +name = "bench_hit_ratio" +harness = false + +[[bench]] +name = "bench_memory" +harness = false diff --git a/tinyufo/LICENSE b/tinyufo/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/tinyufo/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/tinyufo/README.md b/tinyufo/README.md new file mode 100644 index 0000000..50e2dd3 --- /dev/null +++ b/tinyufo/README.md @@ -0,0 +1,49 @@ +# TinyUFO + +TinyUFO is a fast and efficient in-memory cache. It adopts the state-of-the-art [S3-FIFO](https://s3fifo.com/) as well as [TinyLFU](https://arxiv.org/abs/1512.00727) algorithms to achieve high throughput and high hit ratio as the same time. + +## Usage + +See docs + +## Performance Comparison +We compare TinyUFO with [lru](https://crates.io/crates/lru), the most commonly used cache algorithm and [moka](https://crates.io/crates/moka), another [great](https://github.com/rust-lang/crates.io/pull/3999) cache library that implements TinyLFU. + +### Hit Ratio + +The table below show the cache hit ratio of the compared algorithm under different size of cache, zipf=1. + +|cache size / total assets | TinyUFO | TinyUFO - LRU | TinyUFO - moka (TinyLFU) | +| -------- | ------- | ------- | ------ | +| 0.5% | 45.26% | +14.21pp | -0.33pp +| 1% | 52.35% | +13.19pp | +1.69pp +| 5% | 68.89% | +10.14pp | +1.91pp +| 10% | 75.98% | +8.39pp | +1.59pp +| 25% | 85.34% | +5.39pp | +0.95pp + +Both TinyUFO and moka greatly improves hit ratio from lru. TinyUFO is the one better in this workload. +[This paper](https://dl.acm.org/doi/pdf/10.1145/3600006.3613147) contains more thorough cache performance +evaluations S3-FIFO, which TinyUFO varies from, against many caching algorithms under a variety of workloads. + +### Speed + +The table below shows the number of operations performed per second for each cache library. The tests are performed using 8 threads on a x64 Linux desktop. + +| Setup | TinyUFO | LRU | moka | +| -------- | ------- | ------- | ------ | +| Pure read | 148.7 million ops | 7.0 million ops | 14.1 million ops +| Mixed read/write | 80.9 million ops | 6.8 million ops | 16.6 million ops + +Because of TinyUFO's lock-free design, it greatly outperforms the others. + +### Memory overhead + +The table below show the memory allocation (in bytes) of the compared cache library under certain workloads to store zero-sized assets. + +| cache size | TinyUFO | LRU | moka | +| -------- | ------- | ------- | ------ | +| 100 | 39,409 | 9,408 | 354,376 +| 1000 | 236,053 | 128,512 | 535,888 +| 10000 | 2,290,635 | 1,075,648 | 2,489,088 + +Whether these overheads matter depends on the actual sizes and volume of the assets. The more advanced algorithms are likely to be less memory efficient than the simple LRU. \ No newline at end of file diff --git a/tinyufo/benches/bench_hit_ratio.rs b/tinyufo/benches/bench_hit_ratio.rs new file mode 100644 index 0000000..72dacd5 --- /dev/null +++ b/tinyufo/benches/bench_hit_ratio.rs @@ -0,0 +1,100 @@ +// 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 rand::prelude::*; +use std::num::NonZeroUsize; + +const ITEMS: usize = 10_000; +const ITERATIONS: usize = 5_000_000; + +fn bench_one(zip_exp: f64, cache_size_percent: f32) { + print!("{zip_exp:.2}, {cache_size_percent:4}\t\t\t"); + let cache_size = (cache_size_percent * ITEMS as f32).round() as usize; + let mut lru = lru::LruCache::::new(NonZeroUsize::new(cache_size).unwrap()); + let moka = moka::sync::Cache::new(cache_size as u64); + let tinyufo = tinyufo::TinyUfo::new(cache_size, cache_size); + + let mut rng = thread_rng(); + let zipf = zipf::ZipfDistribution::new(ITEMS, zip_exp).unwrap(); + + let mut lru_hit = 0; + let mut moka_hit = 0; + let mut tinyufo_hit = 0; + + for _ in 0..ITERATIONS { + let key = zipf.sample(&mut rng) as u64; + + if lru.get(&key).is_some() { + lru_hit += 1; + } else { + lru.push(key, ()); + } + + if moka.get(&key).is_some() { + moka_hit += 1; + } else { + moka.insert(key, ()); + } + + if tinyufo.get(&key).is_some() { + tinyufo_hit += 1; + } else { + tinyufo.put(key, (), 1); + } + } + + print!("{:.2}%\t\t", lru_hit as f32 / ITERATIONS as f32 * 100.0); + print!("{:.2}%\t\t", moka_hit as f32 / ITERATIONS as f32 * 100.0); + println!("{:.2}%", tinyufo_hit as f32 / ITERATIONS as f32 * 100.0); +} + +/* +cargo bench --bench bench_hit_ratio + +zipf & cache size lru moka TinyUFO +0.90, 0.005 19.23% 33.46% 33.35% +0.90, 0.01 26.21% 37.88% 40.10% +0.90, 0.05 45.59% 55.34% 57.81% +0.90, 0.1 55.73% 64.22% 66.34% +0.90, 0.25 71.18% 77.15% 78.53% +1.00, 0.005 31.09% 45.65% 45.13% +1.00, 0.01 39.17% 50.69% 52.23% +1.00, 0.05 58.73% 66.95% 68.81% +1.00, 0.1 67.57% 74.35% 75.93% +1.00, 0.25 79.91% 84.34% 85.27% +1.05, 0.005 37.68% 51.77% 51.26% +1.05, 0.01 46.11% 57.07% 58.41% +1.05, 0.05 65.04% 72.33% 73.91% +1.05, 0.1 73.11% 78.96% 80.22% +1.05, 0.25 83.77% 87.45% 88.16% +1.10, 0.005 44.48% 57.86% 57.25% +1.10, 0.01 52.97% 63.18% 64.23% +1.10, 0.05 70.94% 77.27% 78.57% +1.10, 0.1 78.11% 83.05% 84.06% +1.10, 0.25 87.08% 90.06% 90.62% +1.50, 0.005 85.25% 89.89% 89.68% +1.50, 0.01 89.88% 92.79% 92.94% +1.50, 0.05 96.04% 97.09% 97.25% +1.50, 0.1 97.52% 98.17% 98.26% +1.50, 0.25 98.81% 99.09% 99.10% + */ + +fn main() { + println!("zipf & cache size\t\tlru\t\tmoka\t\tTinyUFO",); + for zif_exp in [0.9, 1.0, 1.05, 1.1, 1.5] { + for cache_capacity in [0.005, 0.01, 0.05, 0.1, 0.25] { + bench_one(zif_exp, cache_capacity); + } + } +} diff --git a/tinyufo/benches/bench_memory.rs b/tinyufo/benches/bench_memory.rs new file mode 100644 index 0000000..e55a561 --- /dev/null +++ b/tinyufo/benches/bench_memory.rs @@ -0,0 +1,120 @@ +// 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. + +#[global_allocator] +static ALLOC: dhat::Alloc = dhat::Alloc; + +use rand::prelude::*; +use std::num::NonZeroUsize; + +const ITERATIONS: usize = 5_000_000; + +fn bench_lru(zip_exp: f64, items: usize, cache_size_percent: f32) { + let cache_size = (cache_size_percent * items as f32).round() as usize; + let mut lru = lru::LruCache::::new(NonZeroUsize::new(cache_size).unwrap()); + + let mut rng = thread_rng(); + let zipf = zipf::ZipfDistribution::new(items, zip_exp).unwrap(); + + for _ in 0..ITERATIONS { + let key = zipf.sample(&mut rng) as u64; + + if lru.get(&key).is_none() { + lru.push(key, ()); + } + } +} + +fn bench_moka(zip_exp: f64, items: usize, cache_size_percent: f32) { + let cache_size = (cache_size_percent * items as f32).round() as usize; + let moka = moka::sync::Cache::new(cache_size as u64); + + let mut rng = thread_rng(); + let zipf = zipf::ZipfDistribution::new(items, zip_exp).unwrap(); + + for _ in 0..ITERATIONS { + let key = zipf.sample(&mut rng) as u64; + + if moka.get(&key).is_none() { + moka.insert(key, ()); + } + } +} + +fn bench_tinyufo(zip_exp: f64, items: usize, cache_size_percent: f32) { + let cache_size = (cache_size_percent * items as f32).round() as usize; + let tinyufo = tinyufo::TinyUfo::new(cache_size, (cache_size as f32 * 1.0) as usize); + + let mut rng = thread_rng(); + let zipf = zipf::ZipfDistribution::new(items, zip_exp).unwrap(); + + for _ in 0..ITERATIONS { + let key = zipf.sample(&mut rng) as u64; + + if tinyufo.get(&key).is_none() { + tinyufo.put(key, (), 1); + } + } +} + +/* +cargo bench --bench bench_memory + +total items 1000, cache size 10% +lru +dhat: At t-gmax: 9,408 bytes in 106 blocks +moka +dhat: At t-gmax: 354,232 bytes in 1,581 blocks +TinyUFO +dhat: At t-gmax: 37,337 bytes in 351 blocks + +total items 10000, cache size 10% +lru +dhat: At t-gmax: 128,512 bytes in 1,004 blocks +moka +dhat: At t-gmax: 535,320 bytes in 7,278 blocks +TinyUFO +dhat: At t-gmax: 236,053 bytes in 2,182 blocks + +total items 100000, cache size 10% +lru +dhat: At t-gmax: 1,075,648 bytes in 10,004 blocks +moka +dhat: At t-gmax: 2,489,088 bytes in 62,374 blocks +TinyUFO +dhat: At t-gmax: 2,290,635 bytes in 20,467 blocks +*/ + +fn main() { + for items in [1000, 10_000, 100_000] { + println!("\ntotal items {items}, cache size 10%"); + { + let _profiler = dhat::Profiler::new_heap(); + bench_lru(1.05, items, 0.1); + println!("lru"); + } + + { + let _profiler = dhat::Profiler::new_heap(); + bench_moka(1.05, items, 0.1); + println!("\nmoka"); + } + + { + let _profiler = dhat::Profiler::new_heap(); + bench_tinyufo(1.05, items, 0.1); + println!("\nTinyUFO"); + } + } +} diff --git a/tinyufo/benches/bench_perf.rs b/tinyufo/benches/bench_perf.rs new file mode 100644 index 0000000..1295fb2 --- /dev/null +++ b/tinyufo/benches/bench_perf.rs @@ -0,0 +1,290 @@ +// 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 rand::prelude::*; +use std::num::NonZeroUsize; +use std::sync::Mutex; +use std::thread; +use std::time::Instant; + +const ITEMS: usize = 100; + +const ITERATIONS: usize = 5_000_000; +const THREADS: usize = 8; + +/* +cargo bench --bench bench_perf + +Note: the performance number vary a lot on different planform, CPU and CPU arch +Below is from Linux + Ryzen 5 7600 CPU + +lru read total 150.423567ms, 30ns avg per operation, 33239472 ops per second +moka read total 462.133322ms, 92ns avg per operation, 10819389 ops per second +tinyufo read total 199.007359ms, 39ns avg per operation, 25124698 ops per second + +lru read total 5.402631847s, 1.08µs avg per operation, 925474 ops per second +... +total 6960329 ops per second + +moka read total 2.742258211s, 548ns avg per operation, 1823314 ops per second +... +total 14072430 ops per second + +tinyufo read total 208.346855ms, 41ns avg per operation, 23998444 ops per second +... +total 148691408 ops per second + +lru mixed read/write 5.500309876s, 1.1µs avg per operation, 909039 ops per second, 407431 misses +... +total 6846743 ops per second + +moka mixed read/write 2.368500882s, 473ns avg per operation, 2111040 ops per second 279324 misses +... +total 16557962 ops per second + +tinyufo mixed read/write 456.134531ms, 91ns avg per operation, 10961678 ops per second, 294977 misses +... +total 80865792 ops per second +*/ + +fn main() { + // we don't bench eviction here so make the caches large enough to hold all + let lru = Mutex::new(lru::LruCache::::unbounded()); + let moka = moka::sync::Cache::new(ITEMS as u64 + 10); + let tinyufo = tinyufo::TinyUfo::new(ITEMS + 10, 10); + + // populate first, then we bench access/promotion + for i in 0..ITEMS { + lru.lock().unwrap().put(i as u64, ()); + moka.insert(i as u64, ()); + tinyufo.put(i as u64, (), 1); + } + + // single thread + let mut rng = thread_rng(); + let zipf = zipf::ZipfDistribution::new(ITEMS, 1.03).unwrap(); + + let before = Instant::now(); + for _ in 0..ITERATIONS { + lru.lock().unwrap().get(&(zipf.sample(&mut rng) as u64)); + } + let elapsed = before.elapsed(); + println!( + "lru read total {elapsed:?}, {:?} avg per operation, {} ops per second", + elapsed / ITERATIONS as u32, + (ITERATIONS as f32 / elapsed.as_secs_f32()) as u32 + ); + + let before = Instant::now(); + for _ in 0..ITERATIONS { + moka.get(&(zipf.sample(&mut rng) as u64)); + } + let elapsed = before.elapsed(); + println!( + "moka read total {elapsed:?}, {:?} avg per operation, {} ops per second", + elapsed / ITERATIONS as u32, + (ITERATIONS as f32 / elapsed.as_secs_f32()) as u32 + ); + + let before = Instant::now(); + for _ in 0..ITERATIONS { + tinyufo.get(&(zipf.sample(&mut rng) as u64)); + } + let elapsed = before.elapsed(); + println!( + "tinyufo read total {elapsed:?}, {:?} avg per operation, {} ops per second", + elapsed / ITERATIONS as u32, + (ITERATIONS as f32 / elapsed.as_secs_f32()) as u32 + ); + + // concurrent + + let before = Instant::now(); + thread::scope(|s| { + for _ in 0..THREADS { + s.spawn(|| { + let mut rng = thread_rng(); + let zipf = zipf::ZipfDistribution::new(ITEMS, 1.03).unwrap(); + let before = Instant::now(); + for _ in 0..ITERATIONS { + lru.lock().unwrap().get(&(zipf.sample(&mut rng) as u64)); + } + let elapsed = before.elapsed(); + println!( + "lru read total {elapsed:?}, {:?} avg per operation, {} ops per second", + elapsed / ITERATIONS as u32, + (ITERATIONS as f32 / elapsed.as_secs_f32()) as u32 + ); + }); + } + }); + let elapsed = before.elapsed(); + println!( + "total {} ops per second", + (ITERATIONS as f32 * THREADS as f32 / elapsed.as_secs_f32()) as u32 + ); + + let before = Instant::now(); + thread::scope(|s| { + for _ in 0..THREADS { + s.spawn(|| { + let mut rng = thread_rng(); + let zipf = zipf::ZipfDistribution::new(ITEMS, 1.03).unwrap(); + let before = Instant::now(); + for _ in 0..ITERATIONS { + moka.get(&(zipf.sample(&mut rng) as u64)); + } + let elapsed = before.elapsed(); + println!( + "moka read total {elapsed:?}, {:?} avg per operation, {} ops per second", + elapsed / ITERATIONS as u32, + (ITERATIONS as f32 / elapsed.as_secs_f32()) as u32 + ); + }); + } + }); + let elapsed = before.elapsed(); + println!( + "total {} ops per second", + (ITERATIONS as f32 * THREADS as f32 / elapsed.as_secs_f32()) as u32 + ); + + let before = Instant::now(); + thread::scope(|s| { + for _ in 0..THREADS { + s.spawn(|| { + let mut rng = thread_rng(); + let zipf = zipf::ZipfDistribution::new(ITEMS, 1.03).unwrap(); + let before = Instant::now(); + for _ in 0..ITERATIONS { + tinyufo.get(&(zipf.sample(&mut rng) as u64)); + } + let elapsed = before.elapsed(); + println!( + "tinyufo read total {elapsed:?}, {:?} avg per operation, {} ops per second", + elapsed / ITERATIONS as u32, + (ITERATIONS as f32 / elapsed.as_secs_f32()) as u32 + ); + }); + } + }); + let elapsed = before.elapsed(); + println!( + "total {} ops per second", + (ITERATIONS as f32 * THREADS as f32 / elapsed.as_secs_f32()) as u32 + ); + + ///// bench mixed read and write ///// + const CACHE_SIZE: usize = 1000; + let items: usize = 10000; + const ZIPF_EXP: f64 = 1.3; + + let lru = Mutex::new(lru::LruCache::::new( + NonZeroUsize::new(CACHE_SIZE).unwrap(), + )); + let before = Instant::now(); + thread::scope(|s| { + for _ in 0..THREADS { + s.spawn(|| { + let mut miss_count = 0; + let mut rng = thread_rng(); + let zipf = zipf::ZipfDistribution::new(items, ZIPF_EXP).unwrap(); + let before = Instant::now(); + for _ in 0..ITERATIONS { + let key = zipf.sample(&mut rng) as u64; + let mut lru = lru.lock().unwrap(); + if lru.get(&key).is_none() { + lru.put(key, ()); + miss_count += 1; + } + } + let elapsed = before.elapsed(); + println!( + "lru mixed read/write {elapsed:?}, {:?} avg per operation, {} ops per second, {miss_count} misses", + elapsed / ITERATIONS as u32, + (ITERATIONS as f32 / elapsed.as_secs_f32()) as u32 + ); + }); + } + }); + let elapsed = before.elapsed(); + println!( + "total {} ops per second", + (ITERATIONS as f32 * THREADS as f32 / elapsed.as_secs_f32()) as u32 + ); + + let moka = moka::sync::Cache::new(CACHE_SIZE as u64); + + let before = Instant::now(); + thread::scope(|s| { + for _ in 0..THREADS { + s.spawn(|| { + let mut miss_count = 0; + let mut rng = thread_rng(); + let zipf = zipf::ZipfDistribution::new(items, ZIPF_EXP).unwrap(); + let before = Instant::now(); + for _ in 0..ITERATIONS { + let key = zipf.sample(&mut rng) as u64; + if moka.get(&key).is_none() { + moka.insert(key, ()); + miss_count += 1; + } + } + let elapsed = before.elapsed(); + println!( + "moka mixed read/write {elapsed:?}, {:?} avg per operation, {} ops per second {miss_count} misses", + elapsed / ITERATIONS as u32, + (ITERATIONS as f32 / elapsed.as_secs_f32()) as u32 + ); + }); + } + }); + let elapsed = before.elapsed(); + println!( + "total {} ops per second", + (ITERATIONS as f32 * THREADS as f32 / elapsed.as_secs_f32()) as u32 + ); + + let tinyufo = tinyufo::TinyUfo::new(CACHE_SIZE, CACHE_SIZE); + let before = Instant::now(); + thread::scope(|s| { + for _ in 0..THREADS { + s.spawn(|| { + let mut miss_count = 0; + let mut rng = thread_rng(); + let zipf = zipf::ZipfDistribution::new(items, ZIPF_EXP).unwrap(); + let before = Instant::now(); + for _ in 0..ITERATIONS { + let key = zipf.sample(&mut rng) as u64; + if tinyufo.get(&key).is_none() { + tinyufo.put(key, (), 1); + miss_count +=1; + } + } + let elapsed = before.elapsed(); + println!( + "tinyufo mixed read/write {elapsed:?}, {:?} avg per operation, {} ops per second, {miss_count} misses", + elapsed / ITERATIONS as u32, + (ITERATIONS as f32 / elapsed.as_secs_f32()) as u32, + ); + }); + } + }); + + let elapsed = before.elapsed(); + println!( + "total {} ops per second", + (ITERATIONS as f32 * THREADS as f32 / elapsed.as_secs_f32()) as u32 + ); +} diff --git a/tinyufo/src/estimation.rs b/tinyufo/src/estimation.rs new file mode 100644 index 0000000..19d84d4 --- /dev/null +++ b/tinyufo/src/estimation.rs @@ -0,0 +1,188 @@ +// 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 ahash::RandomState; +use std::hash::Hash; +use std::sync::atomic::{AtomicU8, AtomicUsize, Ordering}; + +struct Estimator { + estimator: Box<[(Box<[AtomicU8]>, RandomState)]>, +} + +impl Estimator { + fn optimal_paras(items: usize) -> (usize, usize) { + use std::cmp::max; + // derived from https://en.wikipedia.org/wiki/Count%E2%80%93min_sketch + // width = ceil(e / ε) + // depth = ceil(ln(1 − δ) / ln(1 / 2)) + let error_range = 1.0 / (items as f64); + let failure_probability = 1.0 / (items as f64); + ( + max((std::f64::consts::E / error_range).ceil() as usize, 16), + max((failure_probability.ln() / 0.5f64.ln()).ceil() as usize, 2), + ) + } + + fn optimal(items: usize) -> Self { + let (slots, hashes) = Self::optimal_paras(items); + Self::new(hashes, slots) + } + + /// Create a new `Estimator` with the given amount of hashes and columns (slots). + pub fn new(hashes: usize, slots: usize) -> Self { + let mut estimator = Vec::with_capacity(hashes); + for _ in 0..hashes { + let mut slot = Vec::with_capacity(slots); + for _ in 0..slots { + slot.push(AtomicU8::new(0)); + } + estimator.push((slot.into_boxed_slice(), RandomState::new())); + } + + Estimator { + estimator: estimator.into_boxed_slice(), + } + } + + pub fn incr(&self, key: T) -> u8 { + let mut min = u8::MAX; + for (slot, hasher) in self.estimator.iter() { + let hash = hasher.hash_one(&key) as usize; + let counter = &slot[hash % slot.len()]; + let (_current, new) = incr_no_overflow(counter); + min = std::cmp::min(min, new); + } + min + } + + /// Get the estimated frequency of `key`. + pub fn get(&self, key: T) -> u8 { + let mut min = u8::MAX; + for (slot, hasher) in self.estimator.iter() { + let hash = hasher.hash_one(&key) as usize; + let counter = &slot[hash % slot.len()]; + let current = counter.load(Ordering::Relaxed); + min = std::cmp::min(min, current); + } + min + } + + /// right shift all values inside this `Estimator`. + pub fn age(&self, shift: u8) { + for (slot, _) in self.estimator.iter() { + for counter in slot.iter() { + // we don't CAS because the only update between the load and store + // is fetch_add(1), which should be fine to miss/ignore + let c = counter.load(Ordering::Relaxed); + counter.store(c >> shift, Ordering::Relaxed); + } + } + } +} + +fn incr_no_overflow(var: &AtomicU8) -> (u8, u8) { + loop { + let current = var.load(Ordering::Relaxed); + if current == u8::MAX { + return (current, current); + } + let new = if current == u8::MAX - 1 { + u8::MAX + } else { + current + 1 + }; + if let Err(new) = var.compare_exchange(current, new, Ordering::Acquire, Ordering::Relaxed) { + // someone else beat us to it + if new == u8::MAX { + // already max + return (current, new); + } // else, try again + } else { + return (current, new); + } + } +} + +// bare-minimum TinyLfu with CM-Sketch, no doorkeeper for now +pub(crate) struct TinyLfu { + estimator: Estimator, + window_counter: AtomicUsize, + window_limit: usize, +} + +impl TinyLfu { + pub fn get(&self, key: T) -> u8 { + self.estimator.get(key) + } + + pub fn incr(&self, key: T) -> u8 { + let window_size = self.window_counter.fetch_add(1, Ordering::Relaxed); + // When window_size concurrently increases, only one resets the window and age the estimator. + // > self.window_limit * 2 is a safety net in case for whatever reason window_size grows + // out of control + if window_size == self.window_limit || window_size > self.window_limit * 2 { + self.window_counter.store(0, Ordering::Relaxed); + self.estimator.age(1); // right shift 1 bit + } + self.estimator.incr(key) + } + + // because we use 8-bits counters, window size can be 256 * the cache size + pub fn new(cache_size: usize) -> Self { + Self { + estimator: Estimator::optimal(cache_size), + window_counter: Default::default(), + // 8x: just a heuristic to balance the memory usage and accuracy + window_limit: cache_size * 8, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_cmk_paras() { + let (slots, hashes) = Estimator::optimal_paras(1_000_000); + // just smoke check some standard input + assert_eq!(slots, 2718282); + assert_eq!(hashes, 20); + } + + #[test] + fn test_tiny_lfu() { + let tiny = TinyLfu::new(1); + assert_eq!(tiny.get(1), 0); + assert_eq!(tiny.incr(1), 1); + assert_eq!(tiny.incr(1), 2); + assert_eq!(tiny.get(1), 2); + + assert_eq!(tiny.get(2), 0); + assert_eq!(tiny.incr(2), 1); + assert_eq!(tiny.incr(2), 2); + assert_eq!(tiny.get(2), 2); + + assert_eq!(tiny.incr(3), 1); + assert_eq!(tiny.incr(3), 2); + assert_eq!(tiny.incr(3), 3); + assert_eq!(tiny.incr(3), 4); + + // 8 incr(), now reset + + assert_eq!(tiny.incr(3), 3); + assert_eq!(tiny.incr(1), 2); + assert_eq!(tiny.incr(2), 2); + } +} diff --git a/tinyufo/src/lib.rs b/tinyufo/src/lib.rs new file mode 100644 index 0000000..879e373 --- /dev/null +++ b/tinyufo/src/lib.rs @@ -0,0 +1,632 @@ +// 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. + +//! A In-memory cache implementation with TinyLFU as the admission policy and [S3-FIFO](https://s3fifo.com/) as the eviction policy. +//! +//! TinyUFO improves cache hit ratio noticeably compared to LRU. +//! +//! TinyUFO is lock-free. It is very fast in the systems with a lot concurrent reads and/or writes + +use ahash::RandomState; +use crossbeam_queue::SegQueue; +use flurry::HashMap; +use std::marker::PhantomData; +use std::sync::atomic::AtomicUsize; +use std::sync::atomic::{ + AtomicBool, AtomicU8, + Ordering::{Acquire, Relaxed, SeqCst}, +}; +mod estimation; +use estimation::TinyLfu; +use std::hash::Hash; + +const SMALL: bool = false; +const MAIN: bool = true; + +// Indicate which queue an item is located +#[derive(Debug, Default)] +struct Location(AtomicBool); + +impl Location { + fn new_small() -> Self { + Self(AtomicBool::new(SMALL)) + } + + fn value(&self) -> bool { + self.0.load(Relaxed) + } + + fn is_main(&self) -> bool { + self.value() + } + + fn move_to_main(&self) { + self.0.store(true, Relaxed); + } +} + +// We have 8 bits to spare but we still cap at 3. This is to make sure that the main queue +// in the worst case can find something to evict quickly +const USES_CAP: u8 = 3; + +#[derive(Debug, Default)] +struct Uses(AtomicU8); + +impl Uses { + pub fn inc_uses(&self) { + loop { + let uses = self.uses(); + if uses >= USES_CAP { + return; + } + if let Err(new) = self.0.compare_exchange(uses, uses + 1, Acquire, Relaxed) { + // someone else beat us to it + if new >= USES_CAP { + // already above cap + return; + } // else, try again + } else { + return; + } + } + } + + // decrease uses, return the previous value + pub fn decr_uses(&self) -> u8 { + loop { + let uses = self.uses(); + if uses == 0 { + return 0; + } + if let Err(new) = self.0.compare_exchange(uses, uses - 1, Acquire, Relaxed) { + // someone else beat us to it + if new == 0 { + return 0; + } // else, try again + } else { + return uses; + } + } + } + + pub fn uses(&self) -> u8 { + self.0.load(Relaxed) + } +} + +type Key = u64; +type Weight = u16; + +/// The key-value pair returned from cache eviction +#[derive(Clone)] +pub struct KV { + /// NOTE: that we currently don't store the Actual key in the cache. This returned value + /// is just the hash of it. + pub key: Key, + pub data: T, + pub weight: Weight, +} + +// the data and its metadata +struct Bucket { + uses: Uses, + queue: Location, + weight: Weight, + data: T, +} + +impl Bucket { + fn update_bucket(&self, main_queue: bool, data: T, weight: Weight) -> Self { + Self { + uses: Uses(self.uses.uses().into()), + queue: Location(main_queue.into()), + weight, + data, + } + } +} + +const SMALL_QUEUE_PERCENTAGE: f32 = 0.1; + +struct FiFoQueues { + total_weight_limit: usize, + + small: SegQueue, + small_weight: AtomicUsize, + + main: SegQueue, + main_weight: AtomicUsize, + + // this replaces the ghost queue of S3-FIFO with similar goal: track the evicted assets + estimator: TinyLfu, + + _t: PhantomData, +} + +type Buckets = HashMap, RandomState>; + +impl FiFoQueues { + fn admit( + &self, + key: Key, + data: T, + weight: u16, + ignore_lfu: bool, + buckets: &Buckets, + ) -> Vec> { + // Note that we only use TinyLFU during cache admission but not cache read. + // So effectively we mostly sketch the popularity of less popular assets. + // In this way the sketch is a bit more accurate on these assets. + // Also we don't need another separated window cache to address the sparse burst issue as + // this sketch doesn't favor very popular assets much. + let new_freq = self.estimator.incr(key); + + assert!(weight > 0); + let new_bucket = { + let pinned_buckets = buckets.pin(); + let bucket = pinned_buckets.get(&key); + let Some(bucket) = bucket else { + let mut evicted = self.evict_to_limit(weight, buckets); + // TODO: figure out the right way to compare frequencies of different weights across + // many evicted assets. For now TinyLFU is only used when only evicting 1 item. + let (key, data, weight) = if !ignore_lfu && evicted.len() == 1 { + // Apply the admission algorithm of TinyLFU: compare the incoming new item + // and the evicted one. The more popular one is admitted to cache + let evicted_first = &evicted[0]; + let evicted_freq = self.estimator.get(evicted_first.key); + if evicted_freq > new_freq { + // put it back + let first = evicted.pop().expect("just check non-empty"); + // return the put value + evicted.push(KV { key, data, weight }); + (first.key, first.data, first.weight) + } else { + (key, data, weight) + } + } else { + (key, data, weight) + }; + + let bucket = Bucket { + queue: Location::new_small(), + weight, + uses: Default::default(), // 0 + data, + }; + let old = pinned_buckets.insert(key, bucket); + if old.is_none() { + // Always push key first before updating weight + // If doing the other order, another concurrent thread might not + // find things to evict + self.small.push(key); + self.small_weight.fetch_add(weight as usize, SeqCst); + } // else: two threads are racing adding the item + // TODO: compare old.weight and update accordingly + return evicted; + }; + + // the item exists, in case weight changes + let old_weight = bucket.weight; + bucket.uses.inc_uses(); + + fn update_atomic(weight: &AtomicUsize, old: u16, new: u16) { + if old == new { + return; + } + if old > new { + weight.fetch_sub((old - new) as usize, SeqCst); + } else { + weight.fetch_add((new - old) as usize, SeqCst); + } + } + if bucket.queue.is_main() { + update_atomic(&self.main_weight, old_weight, weight); + bucket.update_bucket(MAIN, data, weight) + } else { + update_atomic(&self.small_weight, old_weight, weight); + bucket.update_bucket(SMALL, data, weight) + } + }; + + // replace the existing one + buckets.pin().insert(key, new_bucket); + + // NOTE: there is a chance that the item itself is evicted if it happens to be the one selected + // by the algorithm. We could avoid this by checking if the item is in the returned evicted items, + // and then add it back. But to keep the code simple we just allow it to happen. + self.evict_to_limit(0, buckets) + } + + // the `extra_weight` is to essentially tell the cache to reserve that amount of weight for + // admission. It is used when calling `evict_to_limit` before admitting the asset itself. + fn evict_to_limit(&self, extra_weight: Weight, buckets: &Buckets) -> Vec> { + let mut evicted = if self.total_weight_limit + < self.small_weight.load(SeqCst) + self.main_weight.load(SeqCst) + extra_weight as usize + { + Vec::with_capacity(1) + } else { + vec![] + }; + while self.total_weight_limit + < self.small_weight.load(SeqCst) + self.main_weight.load(SeqCst) + extra_weight as usize + { + if let Some(evicted_item) = self.evict_one(buckets) { + evicted.push(evicted_item); + } else { + break; + } + } + + evicted + } + + fn evict_one(&self, buckets: &Buckets) -> Option> { + let evict_small = self.small_weight_limit() <= self.small_weight.load(SeqCst); + + if evict_small { + let evicted = self.evict_one_from_small(buckets); + // evict_one_from_small could just promote everything to main without evicting any + // so need to evict_one_from_main if nothing evicted + if evicted.is_some() { + return evicted; + } + } + self.evict_one_from_main(buckets) + } + + fn small_weight_limit(&self) -> usize { + (self.total_weight_limit as f32 * SMALL_QUEUE_PERCENTAGE).floor() as usize + 1 + } + + fn evict_one_from_small(&self, buckets: &Buckets) -> Option> { + loop { + let Some(to_evict) = self.small.pop() else { + // empty queue, this is caught between another pop() and fetch_sub() + return None; + }; + let pinned_buckets = buckets.pin(); + let maybe_bucket = pinned_buckets.get(&to_evict); + + let Some(bucket) = maybe_bucket.as_ref() else { + //key in queue but not bucket, shouldn't happen, but ignore + continue; + }; + + let weight = bucket.weight; + self.small_weight.fetch_sub(weight as usize, SeqCst); + + if bucket.uses.uses() > 1 { + // move to main + bucket.queue.move_to_main(); + self.main.push(to_evict); + self.main_weight.fetch_add(weight as usize, SeqCst); + // continue until find one to evict + continue; + } + // move to ghost + + let data = bucket.data.clone(); + let weight = bucket.weight; + pinned_buckets.remove(&to_evict); + return Some(KV { + key: to_evict, + data, + weight, + }); + } + } + + fn evict_one_from_main(&self, buckets: &Buckets) -> Option> { + loop { + let Some(to_evict) = self.main.pop() else { + return None; + }; + let buckets = buckets.pin(); + let maybe_bucket = buckets.get(&to_evict); + if let Some(bucket) = maybe_bucket.as_ref() { + if bucket.uses.decr_uses() > 0 { + // put it back + self.main.push(to_evict); + // continue the loop + } else { + // evict + let weight = bucket.weight; + self.main_weight.fetch_sub(weight as usize, SeqCst); + let data = bucket.data.clone(); + buckets.remove(&to_evict); + return Some(KV { + key: to_evict, + data, + weight, + }); + } + } // else: key in queue but not bucket, shouldn't happen + } + } +} + +/// [TinyUfo] cache +pub struct TinyUfo { + queues: FiFoQueues, + buckets: HashMap, RandomState>, + random_status: RandomState, + _k: PhantomData, +} + +impl TinyUfo { + /// Create a new TinyUfo cache with the given weight limit and the given + /// size limit of the ghost queue. + pub fn new(total_weight_limit: usize, estimated_size: usize) -> Self { + let queues = FiFoQueues { + small: SegQueue::new(), + small_weight: 0.into(), + main: SegQueue::new(), + main_weight: 0.into(), + total_weight_limit, + estimator: TinyLfu::new(estimated_size), + _t: PhantomData, + }; + TinyUfo { + queues, + buckets: HashMap::with_capacity_and_hasher(estimated_size, RandomState::new()), + random_status: RandomState::new(), + _k: PhantomData, + } + } + + // TODO: with_capacity() + + /// Read the given key + /// + /// Return Some(T) if the key exists + pub fn get(&self, key: &K) -> Option { + let key = self.random_status.hash_one(key); + let buckets = self.buckets.pin(); + buckets.get(&key).map(|p| { + p.uses.inc_uses(); + p.data.clone() + }) + } + + /// Put the key value to the [TinyUfo] + /// + /// Return a list of [KV] of key and `T` that are evicted + pub fn put(&self, key: K, data: T, weight: Weight) -> Vec> { + let key = self.random_status.hash_one(key); + self.queues.admit(key, data, weight, false, &self.buckets) + } + + /// Always put the key value to the [TinyUfo] + /// + /// Return a list of [KV] of key and `T` that are evicted + /// + /// Similar to [Self::put] but guarantee the assertion of the asset. + /// In [Self::put], the TinyLFU check may reject putting the current asset if it is less + /// popular than the once being evicted. + /// + /// In some real world use cases, a few reads to the same asset may be pending for the put action + /// to be finished so that they can read the asset from cache. Neither the above behaviors are ideal + /// for this use case. + /// + /// Compared to [Self::put], the hit ratio when using this function is reduced by about 0.5pp or less in + /// under zipf workloads. + pub fn force_put(&self, key: K, data: T, weight: Weight) -> Vec> { + let key = self.random_status.hash_one(key); + self.queues.admit(key, data, weight, true, &self.buckets) + } + + #[cfg(test)] + fn peek_queue(&self, key: K) -> Option { + let key = self.random_status.hash_one(key); + self.buckets.pin().get(&key).map(|p| p.queue.value()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_uses() { + let uses: Uses = Default::default(); + assert_eq!(uses.uses(), 0); + uses.inc_uses(); + assert_eq!(uses.uses(), 1); + for _ in 0..USES_CAP { + uses.inc_uses(); + } + assert_eq!(uses.uses(), USES_CAP); + + for _ in 0..USES_CAP + 2 { + uses.decr_uses(); + } + assert_eq!(uses.uses(), 0); + } + + #[test] + fn test_evict_from_small() { + let cache = TinyUfo::new(5, 5); + + cache.put(1, 1, 1); + cache.put(2, 2, 2); + cache.put(3, 3, 2); + // cache full now + + assert_eq!(cache.peek_queue(1), Some(SMALL)); + assert_eq!(cache.peek_queue(2), Some(SMALL)); + assert_eq!(cache.peek_queue(3), Some(SMALL)); + + let evicted = cache.put(4, 4, 3); + assert_eq!(evicted.len(), 2); + assert_eq!(evicted[0].data, 1); + assert_eq!(evicted[1].data, 2); + + assert_eq!(cache.peek_queue(1), None); + assert_eq!(cache.peek_queue(2), None); + assert_eq!(cache.peek_queue(3), Some(SMALL)); + } + + #[test] + fn test_evict_from_small_to_main() { + let cache = TinyUfo::new(5, 5); + + cache.put(1, 1, 1); + cache.put(2, 2, 2); + cache.put(3, 3, 2); + // cache full now + + cache.get(&1); + cache.get(&1); // 1 will be moved to main during next eviction + + assert_eq!(cache.peek_queue(1), Some(SMALL)); + assert_eq!(cache.peek_queue(2), Some(SMALL)); + assert_eq!(cache.peek_queue(3), Some(SMALL)); + + let evicted = cache.put(4, 4, 1); + assert_eq!(evicted.len(), 1); + assert_eq!(evicted[0].data, 2); + + assert_eq!(cache.peek_queue(1), Some(MAIN)); + // 2 is evicted because 1 is in main + assert_eq!(cache.peek_queue(2), None); + assert_eq!(cache.peek_queue(3), Some(SMALL)); + assert_eq!(cache.peek_queue(4), Some(SMALL)); + } + + #[test] + fn test_evict_reentry() { + let cache = TinyUfo::new(5, 5); + + cache.put(1, 1, 1); + cache.put(2, 2, 2); + cache.put(3, 3, 2); + // cache full now + + assert_eq!(cache.peek_queue(1), Some(SMALL)); + assert_eq!(cache.peek_queue(2), Some(SMALL)); + assert_eq!(cache.peek_queue(3), Some(SMALL)); + + let evicted = cache.put(4, 4, 1); + assert_eq!(evicted.len(), 1); + assert_eq!(evicted[0].data, 1); + + assert_eq!(cache.peek_queue(1), None); + assert_eq!(cache.peek_queue(2), Some(SMALL)); + assert_eq!(cache.peek_queue(3), Some(SMALL)); + assert_eq!(cache.peek_queue(4), Some(SMALL)); + + let evicted = cache.put(1, 1, 1); + assert_eq!(evicted.len(), 1); + assert_eq!(evicted[0].data, 2); + + assert_eq!(cache.peek_queue(1), Some(SMALL)); + assert_eq!(cache.peek_queue(2), None); + assert_eq!(cache.peek_queue(3), Some(SMALL)); + assert_eq!(cache.peek_queue(4), Some(SMALL)); + } + + #[test] + fn test_evict_entry_denied() { + let cache = TinyUfo::new(5, 5); + + cache.put(1, 1, 1); + cache.put(2, 2, 2); + cache.put(3, 3, 2); + // cache full now + + assert_eq!(cache.peek_queue(1), Some(SMALL)); + assert_eq!(cache.peek_queue(2), Some(SMALL)); + assert_eq!(cache.peek_queue(3), Some(SMALL)); + + // trick: put a few times to bump their frequencies + cache.put(1, 1, 1); + cache.put(2, 2, 2); + cache.put(3, 3, 2); + + let evicted = cache.put(4, 4, 1); + assert_eq!(evicted.len(), 1); + assert_eq!(evicted[0].data, 4); // 4 is returned + + assert_eq!(cache.peek_queue(1), Some(SMALL)); + assert_eq!(cache.peek_queue(2), Some(SMALL)); + assert_eq!(cache.peek_queue(3), Some(SMALL)); + assert_eq!(cache.peek_queue(4), None); + } + + #[test] + fn test_force_put() { + let cache = TinyUfo::new(5, 5); + + cache.put(1, 1, 1); + cache.put(2, 2, 2); + cache.put(3, 3, 2); + // cache full now + + assert_eq!(cache.peek_queue(1), Some(SMALL)); + assert_eq!(cache.peek_queue(2), Some(SMALL)); + assert_eq!(cache.peek_queue(3), Some(SMALL)); + + // trick: put a few times to bump their frequencies + cache.put(1, 1, 1); + cache.put(2, 2, 2); + cache.put(3, 3, 2); + + // force put will replace 1 with 4 even through 1 is more popular + let evicted = cache.force_put(4, 4, 1); + assert_eq!(evicted.len(), 1); + assert_eq!(evicted[0].data, 1); // 1 is returned + + assert_eq!(cache.peek_queue(1), None); + assert_eq!(cache.peek_queue(2), Some(SMALL)); + assert_eq!(cache.peek_queue(3), Some(SMALL)); + assert_eq!(cache.peek_queue(4), Some(SMALL)); + } + + #[test] + fn test_evict_from_main() { + let cache = TinyUfo::new(5, 5); + + cache.put(1, 1, 1); + cache.put(2, 2, 2); + cache.put(3, 3, 2); + // cache full now + + // all 3 will qualify to main + cache.get(&1); + cache.get(&1); + cache.get(&2); + cache.get(&2); + cache.get(&3); + cache.get(&3); + + let evicted = cache.put(4, 4, 1); + assert_eq!(evicted.len(), 1); + assert_eq!(evicted[0].data, 1); + + // 1 kicked from main + assert_eq!(cache.peek_queue(1), None); + assert_eq!(cache.peek_queue(2), Some(MAIN)); + assert_eq!(cache.peek_queue(3), Some(MAIN)); + assert_eq!(cache.peek_queue(4), Some(SMALL)); + + let evicted = cache.put(1, 1, 1); + assert_eq!(evicted.len(), 1); + assert_eq!(evicted[0].data, 4); + + assert_eq!(cache.peek_queue(1), Some(SMALL)); + assert_eq!(cache.peek_queue(2), Some(MAIN)); + assert_eq!(cache.peek_queue(3), Some(MAIN)); + assert_eq!(cache.peek_queue(4), None); + } +}

    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

    7S*7+#IJB7Kh#hzlCw%n|KU#4MK|xO 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

    ANx5WI5pvj|THz&&u1*cSV)$M)gs;;r#`&q}`n} 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

  • tKsm!8#m!7x0jJn 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 c+M1@~ literal 0 HcmV?d00001 diff --git a/docs/quick_start.md b/docs/quick_start.md new file mode 100644 index 0000000..c59add2 --- /dev/null +++ b/docs/quick_start.md @@ -0,0 +1,324 @@ +# Quick Start: load balancer + +## Introduction + +This quick start shows how to build a bare-bones load balancer using pingora and pingora-proxy. + +The goal of the load balancer is for every incoming HTTP request, select one of the two backends: https://1.1.1.1 and https://1.0.0.1 in a round-robin fashion. + +## Build a basic load balancer + +Create a new cargo project for our load balancer. Let's call it `load_balancer` + +``` +cargo new load_balancer +``` + +### Include the Pingora Crate and Basic Dependencies + +In your project's `cargo.toml` file add the following to your dependencies +``` +async-trait="0.1" +pingora = { version = "0.1", features = [ "lb" ] } +``` + +### Create a pingora server +First, let's create a pingora server. A pingora `Server` is a process which can host one or many +services. The pingora `Server` takes care of configuration and CLI argument parsing, daemonization, +signal handling, and graceful restart or shutdown. + +The preferred usage is to initialize the `Server` in the `main()` function and +use `run_forever()` to spawn all the runtime threads and block the main thread until the server is +ready to exit. + + +```rust +use async_trait::async_trait; +use pingora::prelude::*; +use std::sync::Arc; + +fn main() { + let mut my_server = Server::new(None).unwrap(); + my_server.bootstrap(); + my_server.run_forever(); +} +``` + +This will compile and run, but it doesn't do anything interesting. + +### Create a load balancer proxy +Next let's create a load balancer. Our load balancer holds a static list of upstream IPs. The `pingora-load-balancing` crate already provides the `LoadBalancer` struct with common selection algorithms such as round robin and hashing. So let’s just use it. If the use case requires more sophisticated or customized server selection logic, users can simply implement it themselves in this function. + + +```rust +pub struct LB(Arc>); +``` + +In order to make the server a proxy, we need to implement the `ProxyHttp` trait for it. + +Any object that implements the `ProxyHttp` trait essentially defines how a request is handled in +the proxy. The only required method in the `ProxyHttp` trait is `upstream_peer()` which returns +the address where the request should be proxied to. + +In the body of the `upstream_peer()`, let's use the `select()` method for the `LoadBalancer` to round-robin across the upstream IPs. In this example we use HTTPS to connect to the backends, so we also need to specify to `use_tls` and set the SNI when constructing our [`Peer`](peer.md) object. + +```rust +#[async_trait] +impl ProxyHttp for LB { + + /// For this small example, we don't need context storage + type CTX = (); + fn new_ctx(&self) -> () { + () + } + + async fn upstream_peer(&self, _session: &mut Session, _ctx: &mut ()) -> Result> { + let upstream = self.0 + .select(b"", 256) // hash doesn't matter for round robin + .unwrap(); + + println!("upstream peer is: {:upstream?}"); + + // Set SNI to one.one.one.one + let peer = Box::new(HttpPeer::new(upstream, true, "one.one.one.one".to_string())); + Ok(peer) + } +} +``` + +In order for the 1.1.1.1 backends to accept our requests, a host header must be present. Adding this header +can be done by the `upstream_request_filter()` callback which modifies the request header after +the connection to the backends are established and before the request header is sent. + +```rust +impl ProxyHttp for LB { + // ... + async fn upstream_request_filter( + &self, + _session: &mut Session, + upstream_request: &mut RequestHeader, + _ctx: &mut Self::CTX, + ) -> Result<()> { + upstream_request.insert_header("Host", "one.one.one.one").unwrap(); + Ok(()) + } +} +``` + + +### Create a pingora-proxy service +Next, let's create a proxy service that follows the instructions of the load balancer above. + +A pingora `Service` listens to one or multiple (TCP or Unix domain socket) endpoints. When a new connection is established +the `Service` hands the connection over to its "application." `pingora-proxy` is such an application +which proxies the HTTP request to the given backend as configured above. + +In the example below, we create a `LB` instance with two backends `1.1.1.1:443` and `1.0.0.1:443`. +We put that `LB` instance to a proxy `Service` via the `http_proxy_service()` call and then tell our +`Server` to host that proxy `Service`. + +```rust +fn main() { + let mut my_server = Server::new(None).unwrap(); + my_server.bootstrap(); + + let upstreams = + LoadBalancer::try_from_iter(["1.1.1.1:443", "1.0.0.1:443"]).unwrap(); + + let mut lb = http_proxy_service(&my_server.configuration, LB(Arc::new(upstreams))); + lb.add_tcp("0.0.0.0:6188"); + + my_server.add_service(lb); + + my_server.run_forever(); +} +``` + +### Run it + +Now that we have added the load balancer to the service, we can run our new +project with + +```cargo run``` + +To test it, simply send the server a few requests with the command: +``` +curl 127.0.0.1:6188 -svo /dev/null +``` + +You can also navigate your browser to [http://localhost:6188](http://localhost:6188) + +The following output shows that the load balancer is doing its job to balance across the two backends: +``` +upstream peer is: Backend { addr: Inet(1.0.0.1:443), weight: 1 } +upstream peer is: Backend { addr: Inet(1.1.1.1:443), weight: 1 } +upstream peer is: Backend { addr: Inet(1.0.0.1:443), weight: 1 } +upstream peer is: Backend { addr: Inet(1.1.1.1:443), weight: 1 } +upstream peer is: Backend { addr: Inet(1.0.0.1:443), weight: 1 } +... +``` + +Well done! At this point you have a functional load balancer. It is a _very_ +basic load balancer though, so the next section will walk you through how to +make it more robust with some built-in pingora tooling. + +## Add functionality + +Pingora provides several helpful features that can be enabled and configured +with just a few lines of code. These range from simple peer health checks to +the ability to seamlessly update running binary with zero service interruptions. + +### Peer health checks + +To make our load balancer more reliable, we would like to add some health checks +to our upstream peers. That way if there is a peer that has gone down, we can +quickly stop routing our traffic to that peer. + +First let's see how our simple load balancer behaves when one of the peers is +down. To do this, we'll update the list of peers to include a peer that is +guaranteed to be broken. + +```rust +fn main() { + // ... + let upstreams = + LoadBalancer::try_from_iter(["1.1.1.1:443", "1.0.0.1:443", "127.0.0.1:343"]).unwrap(); + // ... +} +``` + +Now if we run our loud balancer again with `cargo run`, and test it with + +``` +curl 127.0.0.1:6188 -svo /dev/null +``` + +We can see that one in every 3 request fails with `502: Bad Gateway`. This is +because our peer selection is strictly following the `RoundRobin` selection +pattern we gave it with no consideration to whether that peer is healthy. We can +fix this by adding a basic health check service. + +```rust +fn main() { + let mut my_server = Server::new(None).unwrap(); + my_server.bootstrap(); + + // Note that upstreams needs to be declared as `mut` now + let mut upstreams = + LoadBalancer::try_from_iter(["1.1.1.1:443", "1.0.0.1:443", "127.0.0.1:343"]).unwrap(); + + let hc = TcpHealthCheck::new(); + upstreams.set_health_check(hc); + upstreams.health_check_frequency = Some(std::time::Duration::from_secs(1)); + + let background = background_service("health check", upstreams); + let upstreams = background.task(); + + // `upstreams` no longer need to be wrapped in an arc + let mut lb = http_proxy_service(&my_server.configuration, LB(upstreams)); + lb.add_tcp("0.0.0.0:6188"); + + my_server.add_service(background); + + my_server.add_service(lb); + my_server.run_forever(); +} +``` + +Now if we again run and test our load balancer, we see that all requests +succeed and the broken peer is never used. Based on the configuration we used, +if that peer were to become healthy again, it would be re-included in the round +robin again in within 1 second. + +### Command line options + +The pingora `Server` type provides a lot of built-in functionality that we can +take advantage of with single-line change. + +```rust +fn main() { + let mut my_server = Server::new(Some(Opt::default())).unwrap(); + ... +} +``` + +With this change, the command-line arguments passed to our load balancer will be +consumed by Pingora. We can test this by running: + +``` +cargo run -- -h +``` + +We should see a help menu with the list of arguments now available to us. We +will take advantage of those in the next sections to do more with our load +balancer for free + +### Running in the background + +Passing the parameter `-d` or `--daemon` will tell the program to run in the background. + +``` +cargo run -- -d +``` + +To stop this service, you can send `SIGTERM` signal to it for a graceful shutdown, in which the service will stop accepting new request but try to finish all ongoing requests before exiting. +``` +pkill -SIGTERM load_balancer +``` + (`SIGTERM` is the default signal for `pkill`.) + +### Configurations +Pingora configuration files help define how to run the service. Here is an +example config file that defines how many threads the service can have, the +location of the pid file, the error log file, and the upgrade coordination +socket (which we will explain later). Copy the contents below and put them into +a file called `conf.yaml` in your `load_balancer` project directory. + +```yaml +--- +version: 1 +threads: 2 +pid_file: /tmp/load_balancer.pid +error_log: /tmp/load_balancer_err.log +upgrade_sock: /tmp/load_balancer.sock +``` + +To use this conf file: +``` +RUST_LOG=INFO cargo run -- -c conf.yaml -d +``` +`RUST_LOG=INFO` is here so that the service actually populate the error log. + +Now you can find the pid of the service. +``` + cat /tmp/load_balancer.pid +``` + +### Gracefully upgrade the service +(Linux only) + +Let's say we changed the code of the load balancer, recompiled the binary. Now we want to upgrade the service running in the background to this newer version. + +If we simply stop the old service, then start the new one, some request arriving in between could be lost. Fortunately, Pingora provides a graceful way to upgrade the service. + +This is done by, first, send `SIGQUIT` signal to the running server, and then start the new server with the parameter `-u` \ `--upgrade`. + +``` +pkill -SIGQUIT load_balancer &&\ +RUST_LOG=INFO cargo run -- -c conf.yaml -d -u +``` + +In this process, The old running server will wait and hand over its listening sockets to the new server. Then the old server runs until all its ongoing requests finish. + +From a client's perspective, the service is always running because the listening socket is never closed. + +## Full examples + +The full code for this example is available in this repository under + +[pingora-proxy/examples/load_balancer.rs](../pingora-proxy/examples/load_balancer.rs) + +Other examples that you may find helpful are also available here + +[pingora-proxy/examples/](../pingora-proxy/examples/) +[pingora/examples](../pingora/examples/) \ No newline at end of file diff --git a/docs/user_guide/conf.md b/docs/user_guide/conf.md new file mode 100644 index 0000000..6e13609 --- /dev/null +++ b/docs/user_guide/conf.md @@ -0,0 +1,33 @@ +# Configuration + +A Pingora configuration file is a list of Pingora settings in yaml format. + +Example +```yaml +--- +version: 1 +threads: 2 +pid_file: /run/pingora.pid +upgrade_sock: /tmp/pingora_upgrade.sock +user: nobody +group: webusers +``` +## Settings +| Key | meaning | value type | +| ------------- |-------------| ----| +| version | the version of the conf, currently it is a constant `1` | number | +| pid_file | The path to the pid file | string | +| daemon | whether to run the server in the background | bool | +| error_log | the path to error log output file. STDERR is used if not set | string | +| upgrade_sock | the path to the upgrade socket. | string | +| threads | number of threads per service | number | +| user | the user the pingora server should be run under after daemonization | string | +| group | the group the pingora server should be run under after daemonization | string | +| client_bind_to_ipv4 | source IPv4 addresses to bind to when connecting to server | list of string | +| client_bind_to_ipv6 | source IPv6 addresses to bind to when connecting to server| list of string | +| ca_file | The path to the root CA file | string | +| work_stealing | Enable work stealing runtime (default true). See Pingora runtime (WIP) section for more info | bool | +| upstream_keepalive_pool_size | The number of total connections to keep in the connetion pool | number | + +## Extension +Any unknown settings will be ignored. This allows extending the conf file to add and pass user defined settings. See User defined configuration section. diff --git a/docs/user_guide/ctx.md b/docs/user_guide/ctx.md new file mode 100644 index 0000000..2d585e6 --- /dev/null +++ b/docs/user_guide/ctx.md @@ -0,0 +1,116 @@ +# Sharing state across phases with `CTX` + +## Using `CTX` +The custom filters users implement in different phases of the request don't interact with each other directly. In order to share information and state across the filters, users can define a `CTX` struct. Each request owns a single `CTX` object. All the filters are able to read and update members of the `CTX` object. The CTX object will be dropped at the end of the request. + +### Example + +In the following example, the proxy parses the request header in the `request_filter` phase, it stores the boolean flag so that later in the `upstream_peer` phase the flag is used to decide which server to route traffic to. (Technically, the header can be parsed in `upstream_peer` phase, but we just do it in an earlier phase just for the demonstration.) + +```Rust +pub struct MyProxy(); + +pub struct MyCtx { + beta_user: bool, +} + +fn check_beta_user(req: &pingora_http::RequestHeader) -> bool { + // some simple logic to check if user is beta + req.headers.get("beta-flag").is_some() +} + +#[async_trait] +impl ProxyHttp for MyProxy { + type CTX = MyCtx; + fn new_ctx(&self) -> Self::CTX { + MyCtx { beta_user: false } + } + + async fn request_filter(&self, session: &mut Session, ctx: &mut Self::CTX) -> Result { + ctx.beta_user = check_beta_user(session.req_header()); + Ok(false) + } + + async fn upstream_peer( + &self, + _session: &mut Session, + ctx: &mut Self::CTX, + ) -> Result> { + let addr = if ctx.beta_user { + info!("I'm a beta user"); + ("1.0.0.1", 443) + } else { + ("1.1.1.1", 443) + }; + + let peer = Box::new(HttpPeer::new(addr, true, "one.one.one.one".to_string())); + Ok(peer) + } +} +``` + +## Sharing state across requests +Sharing state such as a counter, cache and other info across requests is common. There is nothing special needed for sharing resources and data across requests in Pingora. `Arc`, `static` or any other mechanism can be used. + + +### Example +Let's modify the example above to track the number of beta visitors as well as the number of total visitors. The counters can either be defined in the `MyProxy` struct itself or defined as a global variable. Because the counters can be concurrently accessed, Mutex is used here. + +```Rust +// global counter +static REQ_COUNTER: Mutex = Mutex::new(0); + +pub struct MyProxy { + // counter for the service + beta_counter: Mutex, // AtomicUsize works too +} + +pub struct MyCtx { + beta_user: bool, +} + +fn check_beta_user(req: &pingora_http::RequestHeader) -> bool { + // some simple logic to check if user is beta + req.headers.get("beta-flag").is_some() +} + +#[async_trait] +impl ProxyHttp for MyProxy { + type CTX = MyCtx; + fn new_ctx(&self) -> Self::CTX { + MyCtx { beta_user: false } + } + + async fn request_filter(&self, session: &mut Session, ctx: &mut Self::CTX) -> Result { + ctx.beta_user = check_beta_user(session.req_header()); + Ok(false) + } + + async fn upstream_peer( + &self, + _session: &mut Session, + ctx: &mut Self::CTX, + ) -> Result> { + let mut req_counter = REQ_COUNTER.lock().unwrap(); + *req_counter += 1; + + let addr = if ctx.beta_user { + let mut beta_count = self.beta_counter.lock().unwrap(); + *beta_count += 1; + info!("I'm a beta user #{beta_count}"); + ("1.0.0.1", 443) + } else { + info!("I'm an user #{req_counter}"); + ("1.1.1.1", 443) + }; + + let peer = Box::new(HttpPeer::new(addr, true, "one.one.one.one".to_string())); + Ok(peer) + } +} +``` + +The complete example can be found under [`pingora-proxy/examples/ctx.rs`](../../pingora-proxy/examples/ctx.rs). You can run it using `cargo`: +``` +RUST_LOG=INFO cargo run --example ctx +``` \ No newline at end of file diff --git a/docs/user_guide/daemon.md b/docs/user_guide/daemon.md new file mode 100644 index 0000000..f5f8d4a --- /dev/null +++ b/docs/user_guide/daemon.md @@ -0,0 +1,7 @@ +# Daemonization + +When a Pingora server is configured to run as a daemon, after its bootstrapping, it will move itself to the background and optionally change to run under the configured user and group. The `pid_file` option comes handy in this case for the user to track the PID of the daemon in the background. + +Daemonization also allows the server to perform privileged actions like loading secrets and then switch to an unprivileged user before accepting any requests from the network. + +This process happens in the `run_forever()` call. Because daemonization involves `fork()`, certain things like threads created before this call are likely lost. diff --git a/docs/user_guide/error_log.md b/docs/user_guide/error_log.md new file mode 100644 index 0000000..6dd0830 --- /dev/null +++ b/docs/user_guide/error_log.md @@ -0,0 +1,13 @@ +# Error logging + +Pingora libraries are built to expect issues like disconnects, timeouts and invalid inputs from the network. A common way to record these issues are to output them in error log (STDERR or log files). + +## Log level guidelines +Pingora adopts the idea behind [log](https://docs.rs/log/latest/log/). There are five log levels: +* `error`: This level should be used when the error stops the request from being handled correctly. For example when the server we try to connect to is offline. +* `warning`: This level should be used when an error occurs but the system recovers from it. For example when the primary DNS timed out but the system is able to query the secondary DNS. +* `info`: Pingora logs when the server is starting up or shuting down. +* `debug`: Internal details. This log level is not compiled in `release` builds. +* `trace`: Fine-grained internal details. This log level is not compiled in `release` builds. + +The pingora-proxy crate has a well-defined interface to log errors, so that users don't have to manually log common proxy errors. See its guide for more details. diff --git a/docs/user_guide/errors.md b/docs/user_guide/errors.md new file mode 100644 index 0000000..b0a9b82 --- /dev/null +++ b/docs/user_guide/errors.md @@ -0,0 +1,53 @@ +# How to return errors + +For easy error handling, the `pingora-error` crate exports a custom `Result` type used throughout other Pingora crates. + +The `Error` struct used in this `Result`'s error variant is a wrapper around arbitrary error types. It allows the user to tag the source of the underlying error and attach other custom context info. + +Users will often need to return errors by propagating an existing error or creating a wholly new one. `pingora-error` makes this easy with its error building functions. + +## Examples + +For example, one could return an error when an expected header is not present: + +```rust +fn validate_req_header(req: &RequestHeader) -> Result<()> { + // validate that the `host` header exists + req.headers() + .get(http::header::HOST) + .ok_or_else(|| Error::explain(InvalidHTTPHeader, "No host header detected")) +} + +impl MyServer { + pub async fn handle_request_filter( + &self, + http_session: &mut Session, + ctx: &mut CTX, + ) -> Result { + validate_req_header(session.req_header()?).or_err(HTTPStatus(400), "Missing required headers")?; + Ok(true) + } +} +``` + +`validate_req_header` returns an `Error` if the `host` header is not found, using `Error::explain` to create a new `Error` along with an associated type (`InvalidHTTPHeader`) and helpful context that may be logged in an error log. + +This error will eventually propagate to the request filter, where it is returned as a new `HTTPStatus` error using `or_err`. (As part of the default pingora-proxy `fail_to_proxy()` phase, not only will this error be logged, but it will result in sending a `400 Bad Request` response downstream.) + +Note that the original causing error will be visible in the error logs as well. `or_err` wraps the original causing error in a new one with additional context, but `Error`'s `Display` implementation also prints the chain of causing errors. + +## Guidelines + +An error has a _type_ (e.g. `ConnectionClosed`), a _source_ (e.g. `Upstream`, `Downstream`, `Internal`), and optionally, a _cause_ (another wrapped error) and a _context_ (arbitrary user-provided string details). + +A minimal error can be created using functions like `new_in` / `new_up` / `new_down`, each of which specifies a source and asks the user to provide a type. + +Generally speaking: +* To create a new error, without a direct cause but with more context, use `Error::explain`. You can also use `explain_err` on a `Result` to replace the potential error inside it with a new one. +* To wrap a causing error in a new one with more context, use `Error::because`. You can also use `or_err` on a `Result` to replace the potential error inside it by wrapping the original one. + +## Retry + +Errors can be "retry-able." If the error is retry-able, pingora-proxy will be allowed to retry the upstream request. Some errors are only retry-able on [reused connections](pooling.md), e.g. to handle situations where the remote end has dropped a connection we attempted to reuse. + +By default a newly created `Error` either takes on its direct causing error's retry status, or, if left unspecified, is considered not retry-able. diff --git a/docs/user_guide/failover.md b/docs/user_guide/failover.md new file mode 100644 index 0000000..5783256 --- /dev/null +++ b/docs/user_guide/failover.md @@ -0,0 +1,67 @@ +# Handling failures and failover + +Pingora-proxy allows users to define how to handle failures throughout the life of a proxied request. + +When a failure happens before the response header is sent downstream, users have a few options: +1. Send an error page downstream and then give up. +2. Retry the same upstream again. +3. Try another upstream if applicable. + +Otherwise, once the response header is already sent downstream, there is nothing the proxy can do other than logging an error and then giving up on the request. + + +## Retry / Failover +In order to implement retry or failover, `fail_to_connect()` / `error_while_proxy()` needs to mark the error as "retry-able." For failover, `fail_to_connect() / error_while_proxy()` also needs to update the `CTX` to tell `upstream_peer()` not to use the same `Peer` again. + +### Safety +In general, idempotent HTTP requests, e.g., `GET`, are safe to retry. Other requests, e.g., `POST`, are not safe to retry if the requests have already been sent. When `fail_to_connect()` is called, pingora-proxy guarantees that nothing was sent upstream. Users are not recommended to retry an non-idempotent request after `error_while_proxy()` unless they know the upstream server enough to know whether it is safe. + +### Example +In the following example we set a `tries` variable on the `CTX` to track how many connection attempts we've made. When setting our peer in `upstream_peer` we check if `tries` is less than one and connect to 192.0.2.1. On connect failure we increment `tries` in `fail_to_connect` and set `e.set_retry(true)` which tells Pingora this a retryable error. On retry we enter `upstream_peer` again and this time connect to 1.1.1.1. If we're unable to connect to 1.1.1.1 we return a 502 since we only set `e.set_retry(true)` in `fail_to_connect` when `tries` is zero. + +```Rust +pub struct MyProxy(); + +pub struct MyCtx { + tries: usize, +} + +#[async_trait] +impl ProxyHttp for MyProxy { + type CTX = MyCtx; + fn new_ctx(&self) -> Self::CTX { + MyCtx { tries: 0 } + } + + fn fail_to_connect( + &self, + _session: &mut Session, + _peer: &HttpPeer, + ctx: &mut Self::CTX, + mut e: Box, + ) -> Box { + if ctx.tries > 0 { + return e; + } + ctx.tries += 1; + e.set_retry(true); + e + } + + async fn upstream_peer( + &self, + _session: &mut Session, + ctx: &mut Self::CTX, + ) -> Result> { + let addr = if ctx.tries < 1 { + ("192.0.2.1", 443) + } else { + ("1.1.1.1", 443) + }; + + let mut peer = Box::new(HttpPeer::new(addr, true, "one.one.one.one".to_string())); + peer.options.connection_timeout = Some(Duration::from_millis(100)); + Ok(peer) + } +} +``` diff --git a/docs/user_guide/graceful.md b/docs/user_guide/graceful.md new file mode 100644 index 0000000..1f67aa3 --- /dev/null +++ b/docs/user_guide/graceful.md @@ -0,0 +1,19 @@ +# Graceful restart and shutdown + +Graceful restart, upgrade, and shutdown mechanisms are very commonly used to avoid errors or downtime when releasing new versions of pingora servers. + +Pingora graceful upgrade mechanism guarantees the following: +* A request is guaranteed to be handled either by the old server instance or the new one. No request will see connection refused when trying to connect to the server endpoints. +* A request that can finish within the grace period is guaranteed not to be terminated. + +## How to graceful upgrade +### Step 0 +Configure the upgrade socket. The old and new server need to agree on the same path to this socket. See configuration manual for details. + +### Step 1 +Start the new instance with the `--upgrade` cli option. The new instance will not try to listen to the service endpoint right away. It will try to acquire the listening socket from the old instance instead. + +### Step 2 +Send SIGQUIT signal to the old instance. The old instance will start to transfer the listening socket to the new instance. + +Once step 2 is successful, the new instance will start to handle new incoming connections right away. Meanwhile, the old instance will enter its graceful shutdown mode. It waits a short period of time (to give the new instance time to initialize and prepare to handle traffic), after which it will not accept any new connections. diff --git a/docs/user_guide/index.md b/docs/user_guide/index.md new file mode 100644 index 0000000..a8abcb1 --- /dev/null +++ b/docs/user_guide/index.md @@ -0,0 +1,31 @@ +# User Guide + +In this guide, we will cover the most used features, operations and settings of Pingora. + +## Running Pingora servers +* [Start and stop](start_stop.md) +* [Graceful restart and graceful shutdown](graceful.md) +* [Configuration](conf.md) +* [Daemonization](daemon.md) +* [Systemd integration](systemd.md) +* [Handling panics](panic.md) +* [Error logging](error_log.md) +* [Prometheus](prom.md) + +## Building HTTP proxies +* [Life of a request: `pingora-proxy` phases and filters](phase.md) +* [`Peer`: how to connect to upstream](peer.md) +* [Sharing state across phases with `CTX`](ctx.md) +* [How to return errors](errors.md) +* [Examples: take control of the request](modify_filter.md) +* [Connection pooling and reuse](pooling.md) +* [Handling failures and failover](failover.md) + +## Advanced topics (WIP) +* [Pingora internals](internals.md) +* Using BoringSSL +* User defined configuration +* Pingora async runtime and threading model +* Background Service +* Blocking code in async context +* Tracing diff --git a/docs/user_guide/internals.md b/docs/user_guide/internals.md new file mode 100644 index 0000000..0655379 --- /dev/null +++ b/docs/user_guide/internals.md @@ -0,0 +1,256 @@ +# Pingora Internals + +(Special thanks to [James Munns](https://github.com/jamesmunns) for writing this section) + + +## Starting the `Server` + +The pingora system starts by spawning a *server*. The server is responsible for starting *services*, and listening for termination events. + +``` + ┌───────────┐ + ┌─────────>│ Service │ + │ └───────────┘ +┌────────┐ │ ┌───────────┐ +│ Server │──Spawns──┼─────────>│ Service │ +└────────┘ │ └───────────┘ + │ ┌───────────┐ + └─────────>│ Service │ + └───────────┘ +``` + +After spawning the *services*, the server continues to listen to a termination event, which it will propagate to the created services. + +## Services + +*Services* are entities that handle listening to given sockets, and perform the core functionality. A *service* is tied to a particular protocol and set of options. + +> NOTE: there are also "background" services, which just do *stuff*, and aren't necessarily listening to a socket. For now we're just talking about listener services. + +Each service has its own threadpool/tokio runtime, with a number of threads based on the configured value. Worker threads are not shared cross-service. Service runtime threadpools may be work-stealing (tokio-default), or non-work-stealing (N isolated single threaded runtimes). + +``` +┌─────────────────────────┐ +│ ┌─────────────────────┐ │ +│ │┌─────────┬─────────┐│ │ +│ ││ Conn │ Conn ││ │ +│ │├─────────┼─────────┤│ │ +│ ││Endpoint │Endpoint ││ │ +│ │├─────────┴─────────┤│ │ +│ ││ Listeners ││ │ +│ │├─────────┬─────────┤│ │ +│ ││ Worker │ Worker ││ │ +│ ││ Thread │ Thread ││ │ +│ │├─────────┴─────────┤│ │ +│ ││ Tokio Executor ││ │ +│ │└───────────────────┘│ │ +│ └─────────────────────┘ │ +│ ┌───────┐ │ +└─┤Service├───────────────┘ + └───────┘ +``` + +## Service Listeners + +At startup, each Service is assigned a set of downstream endpoints that they listen to. A single service may listen to more than one endpoint. The Server also passes along any relevant configuration, including TLS settings if relevant. + +These endpoints are converted into listening sockets, called `TransportStack`s. Each `TransportStack` is assigned to an async task within that service's executor. + +``` + ┌───────────────────┐ + │┌─────────────────┐│ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ + ┌─────────┐ ││ TransportStack ││ ┌────────────────────┐│ +┌┤Listeners├────────┐ ││ ││ │ │ ││ │ +│└─────────┘ │ ││ (Listener, TLS │├──────spawn(run_endpoint())────>│ Service ││ +│┌─────────────────┐│ ││ Acceptor, ││ │ │ ││ │ +││ Endpoint ││ ││ UpgradeFDs) ││ └────────────────────┘│ +││ addr/ports ││ │├─────────────────┤│ │ │ │ +││ + TLS Settings ││ ││ TransportStack ││ ┌────────────────────┐│ +│├─────────────────┤│ ││ ││ │ │ ││ │ +││ Endpoint ││──build()─> ││ (Listener, TLS │├──────spawn(run_endpoint())────>│ Service ││ +││ addr/ports ││ ││ Acceptor, ││ │ │ ││ │ +││ + TLS Settings ││ ││ UpgradeFDs) ││ └────────────────────┘│ +│├─────────────────┤│ │├─────────────────┤│ │ │ │ +││ Endpoint ││ ││ TransportStack ││ ┌────────────────────┐│ +││ addr/ports ││ ││ ││ │ │ ││ │ +││ + TLS Settings ││ ││ (Listener, TLS │├──────spawn(run_endpoint())────>│ Service ││ +│└─────────────────┘│ ││ Acceptor, ││ │ │ ││ │ +└───────────────────┘ ││ UpgradeFDs) ││ └────────────────────┘│ + │└─────────────────┘│ │ ┌───────────────┐ │ │ ┌──────────────┐ + └───────────────────┘ ─│start_service()│─ ─ ─ ─│ Worker Tasks ├ ─ ─ ┘ + └───────────────┘ └──────────────┘ +``` + +## Downstream connection lifecycle + +Each service processes incoming connections by spawning a task-per-connection. These connections are held open +as long as there are new events to be handled. + +``` + ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ + + │ ┌───────────────┐ ┌────────────────┐ ┌─────────────────┐ ┌─────────────┐ │ +┌────────────────────┐ │ UninitStream │ │ Service │ │ App │ │ Task Ends │ +│ │ │ │ ::handshake() │──>│::handle_event()│──>│ ::process_new() │──┬>│ │ │ +│ Service │──spawn()──> └───────────────┘ └────────────────┘ └─────────────────┘ │ └─────────────┘ +│ │ │ ▲ │ │ +└────────────────────┘ │ while + │ └─────────reuse │ + ┌───────────────────────────┐ + └ ─│ Task on Service Runtime │─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ + └───────────────────────────┘ +``` + +## What is a proxy then? + +Interestingly, the `pingora` `Server` itself has no particular notion of a Proxy. + +Instead, it only thinks in terms of `Service`s, which are expected to contain a particular implementor of the `ServiceApp` trait. + +For example, this is how an `HttpProxy` struct, from the `pingora-proxy` crate, "becomes" a `Service` spawned by the `Server`: + +``` +┌─────────────┐ +│ HttpProxy │ +│ (struct) │ +└─────────────┘ + │ + implements ┌─────────────┐ + │ │HttpServerApp│ + └───────>│ (trait) │ + └─────────────┘ + │ + implements ┌─────────────┐ + │ │ ServerApp │ + └───────>│ (trait) │ + └─────────────┘ + │ + contained ┌─────────────────────┐ + within │ │ + └───────>│ Service │ + │ │ + └─────────────────────┘ +``` + +Different functionality and helpers are provided at different layers in this representation. + +``` +┌─────────────┐ ┌──────────────────────────────────────┐ +│ HttpProxy │ │Handles high level Proxying workflow, │ +│ (struct) │─ ─ ─ ─ │ customizable via ProxyHttp trait │ +└──────┬──────┘ └──────────────────────────────────────┘ + │ +┌──────▼──────┐ ┌──────────────────────────────────────┐ +│HttpServerApp│ │ Handles selection of H1 vs H2 stream │ +│ (trait) │─ ─ ─ ─ │ handling, incl H2 handshake │ +└──────┬──────┘ └──────────────────────────────────────┘ + │ +┌──────▼──────┐ ┌──────────────────────────────────────┐ +│ ServerApp │ │ Handles dispatching of App instances │ +│ (trait) │─ ─ ─ ─ │ as individual tasks, per Session │ +└──────┬──────┘ └──────────────────────────────────────┘ + │ +┌──────▼──────┐ ┌──────────────────────────────────────┐ +│ Service │ │ Handles dispatching of App instances │ +│ (struct) │─ ─ ─ ─ │ as individual tasks, per Listener │ +└─────────────┘ └──────────────────────────────────────┘ +``` + +The `HttpProxy` struct handles the high level workflow of proxying an HTTP connection + +It uses the `ProxyHttp` (note the flipped wording order!) **trait** to allow customization +at each of the following steps (note: taken from [the phase chart](./phase_chart.md) doc): + +```mermaid + graph TD; + start("new request")-->request_filter; + request_filter-->upstream_peer; + + upstream_peer-->Connect{{IO: connect to upstream}}; + + Connect--connection success-->connected_to_upstream; + Connect--connection failure-->fail_to_connect; + + connected_to_upstream-->upstream_request_filter; + upstream_request_filter --> SendReq{{IO: send request to upstream}}; + SendReq-->RecvResp{{IO: read response from upstream}}; + RecvResp-->upstream_response_filter-->response_filter-->upstream_response_body_filter-->response_body_filter-->logging-->endreq("request done"); + + fail_to_connect --can retry-->upstream_peer; + fail_to_connect --can't retry-->fail_to_proxy--send error response-->logging; + + RecvResp--failure-->IOFailure; + SendReq--failure-->IOFailure; + error_while_proxy--can retry-->upstream_peer; + error_while_proxy--can't retry-->fail_to_proxy; + + request_filter --send response-->logging + + + Error>any response filter error]-->error_while_proxy + IOFailure>IO error]-->error_while_proxy + +``` + +## Zooming out + +Before we zoom in, it's probably good to zoom out and remind ourselves how +a proxy generally works: + +``` +┌────────────┐ ┌─────────────┐ ┌────────────┐ +│ Downstream │ │ Proxy │ │ Upstream │ +│ Client │─────────>│ │────────>│ Server │ +└────────────┘ └─────────────┘ └────────────┘ +``` + +The proxy will be taking connections from the **Downstream** client, and (if +everything goes right), establishing a connection with the appropriate +**Upstream** server. This selected upstream server is referred to as +the **Peer**. + +Once the connection is established, the Downstream and Upstream can communicate +bidirectionally. + +So far, the discussion of Server, Services, and Listeners have focused on the LEFT +half of this diagram, handling incoming Downstream connections, and getting it TO +the proxy component. + +Next, we'll look at the RIGHT half of this diagram, connecting to Upstreams. + +## Managing the Upstream + +Connections to Upstream Peers are made through `Connector`s. This is not a specific type or trait, but more +of a "style". + +Connectors are responsible for a few things: + +* Establishing a connection with a Peer +* Maintaining a connection pool with the Peer, allowing for connection reuse across: + * Multiple requests from a single downstream client + * Multiple requests from different downstream clients +* Measuring health of connections, for connections like H2, which perform regular pings +* Handling protocols with multiple poolable layers, like H2 +* Caching, if relevant to the protocol and enabled +* Compression, if relevant to the protocol and enabled + +Now in context, we can see how each end of the Proxy is handled: + +``` +┌────────────┐ ┌─────────────┐ ┌────────────┐ +│ Downstream │ ┌ ─│─ Proxy ┌ ┼ ─ │ Upstream │ +│ Client │─────────>│ │ │──┼─────>│ Server │ +└────────────┘ │ └───────────┼─┘ └────────────┘ + ─ ─ ┘ ─ ─ ┘ + ▲ ▲ + ┌──┘ └──┐ + │ │ + ┌ ─ ─ ─ ─ ┐ ┌ ─ ─ ─ ─ ─ + Listeners Connectors│ + └ ─ ─ ─ ─ ┘ └ ─ ─ ─ ─ ─ +``` + +## What about multiple peers? + +`Connectors` only handle the connection to a single peer, so selecting one of potentially multiple Peers +is actually handled one level up, in the `upstream_peer()` method of the `ProxyHttp` trait. diff --git a/docs/user_guide/modify_filter.md b/docs/user_guide/modify_filter.md new file mode 100644 index 0000000..3e5378f --- /dev/null +++ b/docs/user_guide/modify_filter.md @@ -0,0 +1,133 @@ +# Examples: taking control of the request + +In this section we will go through how to route, modify or reject requests. + +## Routing +Any information from the request can be used to make routing decision. Pingora doesn't impose any constraints on how users could implement their own routing logic. + +In the following example, the proxy sends traffic to 1.0.0.1 only when the request path start with `/family/`. All the other requests are routed to 1.1.1.1. + +```Rust +pub struct MyGateway; + +#[async_trait] +impl ProxyHttp for MyGateway { + type CTX = (); + fn new_ctx(&self) -> Self::CTX {} + + async fn upstream_peer( + &self, + session: &mut Session, + _ctx: &mut Self::CTX, + ) -> Result> { + let addr = if session.req_header().uri.path().starts_with("/family/") { + ("1.0.0.1", 443) + } else { + ("1.1.1.1", 443) + }; + + info!("connecting to {addr:?}"); + + let peer = Box::new(HttpPeer::new(addr, true, "one.one.one.one".to_string())); + Ok(peer) + } +} +``` + + +## Modifying headers + +Both request and response headers can be added, removed or modified in their corresponding phases. In the following example, we add logic to the `response_filter` phase to update the `Server` header and remove the `alt-svc` header. + +```Rust +#[async_trait] +impl ProxyHttp for MyGateway { + ... + async fn response_filter( + &self, + _session: &mut Session, + upstream_response: &mut ResponseHeader, + _ctx: &mut Self::CTX, + ) -> Result<()> + where + Self::CTX: Send + Sync, + { + // replace existing header if any + upstream_response + .insert_header("Server", "MyGateway") + .unwrap(); + // because we don't support h3 + upstream_response.remove_header("alt-svc"); + + Ok(()) + } +} +``` + +## Return Error pages + +Sometimes instead of proxying the traffic, under certain conditions, such as authentication failures, you might want the proxy to just return an error page. + +```Rust +fn check_login(req: &pingora_http::RequestHeader) -> bool { + // implement you logic check logic here + req.headers.get("Authorization").map(|v| v.as_bytes()) == Some(b"password") +} + +#[async_trait] +impl ProxyHttp for MyGateway { + ... + async fn request_filter(&self, session: &mut Session, _ctx: &mut Self::CTX) -> Result { + if session.req_header().uri.path().starts_with("/login") + && !check_login(session.req_header()) + { + let _ = session.respond_error(403).await; + // true: tell the proxy that the response is already written + return Ok(true); + } + Ok(false) + } +``` +## Logging + +Logging logic can be added to the `logging` phase of Pingora. The logging phase runs on every request right before Pingora proxy finish processing it. This phase runs for both successful and failed requests. + +In the example below, we add Prometheus metric and access logging to the proxy. In order for the metrics to be scraped, we also start a Prometheus metric server on a different port. + + +``` Rust +pub struct MyGateway { + req_metric: prometheus::IntCounter, +} + +#[async_trait] +impl ProxyHttp for MyGateway { + ... + async fn logging( + &self, + session: &mut Session, + _e: Option<&pingora::Error>, + ctx: &mut Self::CTX, + ) { + let response_code = session + .response_written() + .map_or(0, |resp| resp.status.as_u16()); + // access log + info!( + "{} response code: {response_code}", + self.request_summary(session, ctx) + ); + + self.req_metric.inc(); + } + +fn main() { + ... + let mut prometheus_service_http = + pingora::services::listening::Service::prometheus_http_service(); + prometheus_service_http.add_tcp("127.0.0.1:6192"); + my_server.add_service(prometheus_service_http); + + my_server.run_forever(); +} +``` \ No newline at end of file diff --git a/docs/user_guide/panic.md b/docs/user_guide/panic.md new file mode 100644 index 0000000..58bf19d --- /dev/null +++ b/docs/user_guide/panic.md @@ -0,0 +1,10 @@ +# Handling panics + +Any panic that happens to particular requests does not affect other ongoing requests or the server's ability to handle other requests. Sockets acquired by the panicking requests are dropped (closed). The panics will be captured by the tokio runtime and then ignored. + +In order to monitor the panics, Pingora server has built-in Sentry integration. +```rust +my_server.sentry = Some("SENTRY_DSN"); +``` + +Even though a panic is not fatal in Pingora, it is still not the preferred way to handle failures like network timeouts. Panics should be reserved for unexpected logic errors. diff --git a/docs/user_guide/peer.md b/docs/user_guide/peer.md new file mode 100644 index 0000000..1176d14 --- /dev/null +++ b/docs/user_guide/peer.md @@ -0,0 +1,35 @@ +# `Peer`: how to connect to upstream + +In the `upstream_peer()` phase the user should return a `Peer` object which defines how to connect to a certain upstream. + +## `Peer` +A `HttpPeer` defines which upstream to connect to. +| attribute | meaning | +| ------------- |-------------| +|address: `SocketAddr`| The IP:Port to connect to | +|scheme: `Scheme`| Http or Https | +|sni: `String`| The SNI to use, Https only | +|proxy: `Option`| The setting to proxy the request through a [CONNECT proxy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/CONNECT) | +|client_cert_key: `Option>`| The client certificate to use in mTLS connections to upstream | +|options: `PeerOptions`| See below | + + +## `PeerOptions` +A `PeerOptions` defines how to connect to the upstream. +| attribute | meaning | +| ------------- |-------------| +|bind_to: `Option`| Which local address to bind to as the client IP | +|connection_timeout: `Option`| How long to wait before giving up *establishing* a TCP connection | +|total_connection_timeout: `Option`| How long to wait before giving up *establishing* a connection including TLS handshake time | +|read_timeout: `Option`| How long to wait before each individual `read()` from upstream. The timer is reset after each `read()` | +|idle_timeout: `Option`| How long to wait before closing a idle connection waiting for connetion reuse | +|write_timeout: `Option`| How long to wait before a `write()` to upstream finishes | +|verify_cert: `bool`| Whether to check if upstream' server cert is valid and validated | +|verify_hostname: `bool`| Whether to check if upstream server cert's CN matches the SNI | +|alternative_cn: `Option`| Accept the cert if the CN matches this name | +|alpn: `ALPN`| Which HTTP protocol to advertise during ALPN, http1.1 and/or http2 | +|ca: `Option>>`| Which Root CA to use to validate the server's cert | +|tcp_keepalive: `Option`| TCP keepalive settings to upstream | + +## Examples +TBD diff --git a/docs/user_guide/phase.md b/docs/user_guide/phase.md new file mode 100644 index 0000000..aa30f3a --- /dev/null +++ b/docs/user_guide/phase.md @@ -0,0 +1,126 @@ +# Life of a request: pingora-proxy phases and filters + +## Intro +The pingora-proxy HTTP proxy framework supports highly programmable proxy behaviors. This is done by allowing users to inject custom logic into different phases (stages) in the life of a request. + +## Life of a proxied HTTP request +1. The life of a proxied HTTP request starts when the proxy reads the request header from the **downstream** (i.e., the client). +2. Then, the proxy connects to the **upstream** (i.e., the remote server). This step is skipped if there is a previously established [connection to reuse](pooling.md). +3. The proxy then sends the request header to the upstream. +4. Once the request header is sent, the proxy enters a duplex mode, which simultaneously proxies: + a. upstream response (both header and body) to the downstream, and + b. downstream request body to upstream (if any). +5. Once the entire request/response finishes, the life of the request is ended. All resources are released. The downstream connections and the upstream connections are recycled to be reused if applicable. + +## Pingora-proxy phases and filters +Pingora-proxy allows users to insert arbitrary logic into the life of a request. +```mermaid + graph TD; + start("new request")-->request_filter; + request_filter-->upstream_peer; + + upstream_peer-->Connect{{IO: connect to upstream}}; + + Connect--connection success-->connected_to_upstream; + Connect--connection failure-->fail_to_connect; + + connected_to_upstream-->upstream_request_filter; + upstream_request_filter --> SendReq{{IO: send request to upstream}}; + SendReq-->RecvResp{{IO: read response from upstream}}; + RecvResp-->upstream_response_filter-->response_filter-->upstream_response_body_filter-->response_body_filter-->logging-->endreq("request done"); + + fail_to_connect --can retry-->upstream_peer; + fail_to_connect --can't retry-->fail_to_proxy--send error response-->logging; + + RecvResp--failure-->IOFailure; + SendReq--failure-->IOFailure; + error_while_proxy--can retry-->upstream_peer; + error_while_proxy--can't retry-->fail_to_proxy; + + request_filter --send response-->logging + + + Error>any response filter error]-->error_while_proxy + IOFailure>IO error]-->error_while_proxy +``` + +### General filter usage guidelines +* Most filters return a [`pingora_error::Result<_>`](errors.md). When the returned value is `Result::Err`, `fail_to_proxy()` will be called and the request will be terminated. +* Most filters are async functions, which allows other async operations such as IO to be performed within the filters. +* A per-request `CTX` object can be defined to share states across the filters of the same request. All filters have mutable access to this object. +* Most filters are optional. +* The reason both `upstream_response_*_filter()` and `response_*_filter()` exist is for HTTP caching integration reasons (still WIP). + + +### `request_filter()` +This is the first phase of every request. + +This phase is usually for validating request inputs, rate limiting, and initializing context. + +### `proxy_upstream_filter()` +This phase determines if we should continue to the upstream to serve a response. If we short-circuit, a 502 is returned by default, but a different response can be implemented. + +This phase returns a boolean determining if we should continue to the upstream or error. + +### `upstream_peer()` +This phase decides which upstream to connect to (e.g. with DNS lookup and hashing/round-robin), and how to connect to it. + +This phase returns a `Peer` that defines the upstream to connect to. Implementing this phase is **required**. + +### `connected_to_upstream()` +This phase is executed when upstream is successfully connected. + +Usually this phase is for logging purposes. Connection info such as RTT and upstream TLS ciphers are reported in this phase. + +### `fail_to_connect()` +The counterpart of `connected_to_upstream()`. This phase is called if an error is encountered when connecting to upstream. + +In this phase users can report the error in Sentry/Prometheus/error log. Users can also decide if the error is retry-able. + +If the error is retry-able, `upstream_peer()` will be called again, in which case the user can decide whether to retry the same upstream or failover to a secondary one. + +If the error is not retry-able, the request will end. + +### `upstream_request_filter()` +This phase is to modify requests before sending to upstream. + +### `upstream_response_filter()/upstream_response_body_filter()` +This phase is triggered after an upstream response header/body is received. + +This phase is to modify response headers (or body) before sending to downstream. Note that this phase is called _prior_ to HTTP caching and therefore any changes made here will affect the response stored in the HTTP cache. + +### `response_filter()/response_body_filter()/response_trailer_filter()` +This phase is triggered after a response header/body/trailer is ready to send to downstream. + +This phase is to modify them before sending to downstream. + +### `error_while_proxy()` +This phase is triggered during proxy errors to upstream, this is after the connection is established. + +This phase may decide to retry a request if the connection was re-used and the HTTP method is idempotent. + +### `fail_to_proxy()` +This phase is called whenever an error is encounter during any of the phases above. + +This phase is usually for error logging and error reporting to downstream. + +### `logging()` +This is the last phase that runs after the request is finished (or errors) and before any of its resources are released. Every request will end up in this final phase. + +This phase is usually for logging and post request cleanup. + +### `request_summary()` +This is not a phase, but a commonly used callback. + +Every error that reaches `fail_to_proxy()` will be automatically logged in the error log. `request_summary()` will be called to dump the info regarding the request when logging the error. + +This callback returns a string which allows users to customize what info to dump in the error log to help track and debug the failures. + +### `suppress_error_log()` +This is also not a phase, but another callback. + +`fail_to_proxy()` errors are automatically logged in the error log, but users may not be interested in every error. For example, downstream errors are logged if the client disconnects early, but these errors can become noisy if users are mainly interested in observing upstream issues. This callback can inspect the error and returns true or false. If true, the error will not be written to the log. + +### Cache filters + +To be documented diff --git a/docs/user_guide/phase_chart.md b/docs/user_guide/phase_chart.md new file mode 100644 index 0000000..a7d01d4 --- /dev/null +++ b/docs/user_guide/phase_chart.md @@ -0,0 +1,30 @@ +Pingora proxy phases without caching +```mermaid + graph TD; + start("new request")-->request_filter; + request_filter-->upstream_peer; + + upstream_peer-->Connect{{IO: connect to upstream}}; + + Connect--connection success-->connected_to_upstream; + Connect--connection failure-->fail_to_connect; + + connected_to_upstream-->upstream_request_filter; + upstream_request_filter --> SendReq{{IO: send request to upstream}}; + SendReq-->RecvResp{{IO: read response from upstream}}; + RecvResp-->upstream_response_filter-->response_filter-->upstream_response_body_filter-->response_body_filter-->logging-->endreq("request done"); + + fail_to_connect --can retry-->upstream_peer; + fail_to_connect --can't retry-->fail_to_proxy--send error response-->logging; + + RecvResp--failure-->IOFailure; + SendReq--failure-->IOFailure; + error_while_proxy--can retry-->upstream_peer; + error_while_proxy--can't retry-->fail_to_proxy; + + request_filter --send response-->logging + + + Error>any response filter error]-->error_while_proxy + IOFailure>IO error]-->error_while_proxy +``` \ No newline at end of file diff --git a/docs/user_guide/pooling.md b/docs/user_guide/pooling.md new file mode 100644 index 0000000..0a108b3 --- /dev/null +++ b/docs/user_guide/pooling.md @@ -0,0 +1,22 @@ +# Connection pooling and reuse + +When the request to a `Peer` (upstream server) is finished, the connection to that peer is kept alive and added to a connection pool to be _reused_ by subsequent requests. This happens automatically without any special configuration. + +Requests that reuse previously established connections avoid the latency and compute cost of setting up a new connection, improving the Pingora server's overall performance and scalability. + +## Same `Peer` +Only the connections to the exact same `Peer` can be reused by a request. For correctness and security reasons, two `Peer`s are the same if and only if all the following attributes are the same +* IP:port +* scheme +* SNI +* client cert +* verify cert +* verify hostname +* alternative_cn +* proxy settings + +## Disable pooling +To disable connection pooling and reuse to a certain `Peer`, just set the `idle_timeout` to 0 seconds to all requests using that `Peer`. + +## Failure +A connection is considered not reusable if errors happen during the request. diff --git a/docs/user_guide/prom.md b/docs/user_guide/prom.md new file mode 100644 index 0000000..f248b0e --- /dev/null +++ b/docs/user_guide/prom.md @@ -0,0 +1,22 @@ +# Prometheus + +Pingora has a built-in prometheus HTTP metric server for scraping. + +```rust + ... + let mut prometheus_service_http = Service::prometheus_http_service(); + prometheus_service_http.add_tcp("0.0.0.0:1234"); + my_server.add_service(prometheus_service_http); + my_server.run_forever(); +``` + +The simplest way to use it is to have [static metrics](https://docs.rs/prometheus/latest/prometheus/#static-metrics). + +```rust +static MY_COUNTER: Lazy = Lazy::new(|| { + register_int_gauge!("my_counter", "my counter").unwrap() +}); + +``` + +This static metric will automatically appear in the Prometheus metric endpoint. diff --git a/docs/user_guide/start_stop.md b/docs/user_guide/start_stop.md new file mode 100644 index 0000000..2c2a585 --- /dev/null +++ b/docs/user_guide/start_stop.md @@ -0,0 +1,27 @@ +# Starting and stoping Pingora server + +A pingora server is a regular unprivileged multithreaded process. + +## Start +By default, the server will run in the foreground. + +A Pingora server by default takes the following command-line arguments: + +| Argument | Effect | default| +| ------------- |-------------| ----| +| -d, --daemon | Daemonize the server | false | +| -t, --test | Test the server conf and then exit (WIP) | false | +| -c, --conf | The path to the configuarion file | empty string | +| -u, --upgrade | This server should gracefully upgrade a running server | false | + +## Stop +A Pingora server will listen to the following signals. + +### SIGINT: fast shutdown +Upon receiving SIGINT (ctrl + c), the server will exit immediately with no delay. All unfinished requests will be interrupted. This behavior is usually less preferred because it could break requests. + +### SIGTERM: graceful shutdown +Upon receiving SIGTERM, the server will notify all its services to shutdown, wait for some preconfigured time and then exit. This behavior gives requests a grace period to finish. + +### SIGQUIT: graceful upgrade +Similar to SIGQUIT, but the server will also transfer all its listening sockets to a new Pingora server so that there is no downtime during the upgrade. See the [graceful upgrade](graceful.md) section for more details. diff --git a/docs/user_guide/systemd.md b/docs/user_guide/systemd.md new file mode 100644 index 0000000..d5474d0 --- /dev/null +++ b/docs/user_guide/systemd.md @@ -0,0 +1,14 @@ +# Systemd integration + +A Pingora server doesn't depend on systemd but it can easily be made into a systemd service. + +```ini +[Service] +Type=forking +PIDFile=/run/pingora.pid +ExecStart=/bin/pingora -d -c /etc/pingora.conf +ExecReload=kill -QUIT $MAINPID +ExecReload=/bin/pingora -u -d -c /etc/pingora.conf +``` + +The example systemd setup integrates Pingora's graceful upgrade into systemd. To upgrade the pingora service, simply install a version of the binary and then call `systemctl reload pingora.service`. diff --git a/pingora-boringssl/Cargo.toml b/pingora-boringssl/Cargo.toml new file mode 100644 index 0000000..d84ed81 --- /dev/null +++ b/pingora-boringssl/Cargo.toml @@ -0,0 +1,36 @@ +[package] +name = "pingora-boringssl" +version = "0.1.0" +authors = ["Yuchen Wu "] +license = "Apache-2.0" +edition = "2021" +repository = "https://github.com/cloudflare/pingora" +categories = ["asynchronous", "network-programming"] +keywords = ["async", "tls", "ssl", "pingora"] +description = """ +BoringSSL async APIs for Pingora. +""" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +name = "pingora_boringssl" +path = "src/lib.rs" + +[dependencies] +boring = { version = "4.5", features = ["pq-experimental"] } +boring-sys = "4.5" +futures-util = { version = "0.3", default-features = false } +tokio = { workspace = true, features = ["io-util", "net", "macros", "rt-multi-thread"] } +libc = "0.2.70" +foreign-types-shared = { version = "0.3" } + + +[dev-dependencies] +tokio-test = "0.4" +tokio = { workspace = true, features = ["full"] } + +[features] +default = [] +pq_use_second_keyshare = [] +# waiting for boring-rs release +read_uninit = [] diff --git a/pingora-boringssl/LICENSE b/pingora-boringssl/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/pingora-boringssl/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/pingora-boringssl/src/boring_tokio.rs b/pingora-boringssl/src/boring_tokio.rs new file mode 100644 index 0000000..dd99533 --- /dev/null +++ b/pingora-boringssl/src/boring_tokio.rs @@ -0,0 +1,305 @@ +// 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. + +//! This file reimplements tokio-boring with the [overhauled](https://github.com/sfackler/tokio-openssl/commit/56f6618ab619f3e431fa8feec2d20913bf1473aa) +//! tokio-openssl interface while the tokio APIs from official [boring] crate is not yet caught up to it. + +use boring::error::ErrorStack; +use boring::ssl::{self, ErrorCode, ShutdownResult, Ssl, SslRef, SslStream as SslStreamCore}; +use futures_util::future; +use std::fmt; +use std::io::{self, Read, Write}; +use std::pin::Pin; +use std::task::{Context, Poll}; +use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; + +struct StreamWrapper { + stream: S, + context: usize, +} + +impl fmt::Debug for StreamWrapper +where + S: fmt::Debug, +{ + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&self.stream, fmt) + } +} + +impl StreamWrapper { + /// # Safety + /// + /// Must be called with `context` set to a valid pointer to a live `Context` object, and the + /// wrapper must be pinned in memory. + unsafe fn parts(&mut self) -> (Pin<&mut S>, &mut Context<'_>) { + debug_assert_ne!(self.context, 0); + let stream = Pin::new_unchecked(&mut self.stream); + let context = &mut *(self.context as *mut _); + (stream, context) + } +} + +impl Read for StreamWrapper +where + S: AsyncRead, +{ + fn read(&mut self, buf: &mut [u8]) -> io::Result { + let (stream, cx) = unsafe { self.parts() }; + let mut buf = ReadBuf::new(buf); + match stream.poll_read(cx, &mut buf)? { + Poll::Ready(()) => Ok(buf.filled().len()), + Poll::Pending => Err(io::Error::from(io::ErrorKind::WouldBlock)), + } + } +} + +impl Write for StreamWrapper +where + S: AsyncWrite, +{ + fn write(&mut self, buf: &[u8]) -> io::Result { + let (stream, cx) = unsafe { self.parts() }; + match stream.poll_write(cx, buf) { + Poll::Ready(r) => r, + Poll::Pending => Err(io::Error::from(io::ErrorKind::WouldBlock)), + } + } + + fn flush(&mut self) -> io::Result<()> { + let (stream, cx) = unsafe { self.parts() }; + match stream.poll_flush(cx) { + Poll::Ready(r) => r, + Poll::Pending => Err(io::Error::from(io::ErrorKind::WouldBlock)), + } + } +} + +fn cvt(r: io::Result) -> Poll> { + match r { + Ok(v) => Poll::Ready(Ok(v)), + Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => Poll::Pending, + Err(e) => Poll::Ready(Err(e)), + } +} + +fn cvt_ossl(r: Result) -> Poll> { + match r { + Ok(v) => Poll::Ready(Ok(v)), + Err(e) => match e.code() { + ErrorCode::WANT_READ | ErrorCode::WANT_WRITE => Poll::Pending, + _ => Poll::Ready(Err(e)), + }, + } +} + +/// An asynchronous version of [`boring::ssl::SslStream`]. +#[derive(Debug)] +pub struct SslStream(SslStreamCore>); + +impl SslStream { + /// Like [`SslStream::new`](ssl::SslStream::new). + pub fn new(ssl: Ssl, stream: S) -> Result { + SslStreamCore::new(ssl, StreamWrapper { stream, context: 0 }).map(SslStream) + } + + /// Like [`SslStream::connect`](ssl::SslStream::connect). + pub fn poll_connect( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + self.with_context(cx, |s| cvt_ossl(s.connect())) + } + + /// A convenience method wrapping [`poll_connect`](Self::poll_connect). + pub async fn connect(mut self: Pin<&mut Self>) -> Result<(), ssl::Error> { + future::poll_fn(|cx| self.as_mut().poll_connect(cx)).await + } + + /// Like [`SslStream::accept`](ssl::SslStream::accept). + pub fn poll_accept(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.with_context(cx, |s| cvt_ossl(s.accept())) + } + + /// A convenience method wrapping [`poll_accept`](Self::poll_accept). + pub async fn accept(mut self: Pin<&mut Self>) -> Result<(), ssl::Error> { + future::poll_fn(|cx| self.as_mut().poll_accept(cx)).await + } + + /// Like [`SslStream::do_handshake`](ssl::SslStream::do_handshake). + pub fn poll_do_handshake( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + self.with_context(cx, |s| cvt_ossl(s.do_handshake())) + } + + /// A convenience method wrapping [`poll_do_handshake`](Self::poll_do_handshake). + pub async fn do_handshake(mut self: Pin<&mut Self>) -> Result<(), ssl::Error> { + future::poll_fn(|cx| self.as_mut().poll_do_handshake(cx)).await + } + + // TODO: early data +} + +impl SslStream { + /// Returns a shared reference to the `Ssl` object associated with this stream. + pub fn ssl(&self) -> &SslRef { + self.0.ssl() + } + + /// Returns a shared reference to the underlying stream. + pub fn get_ref(&self) -> &S { + &self.0.get_ref().stream + } + + /// Returns a mutable reference to the underlying stream. + pub fn get_mut(&mut self) -> &mut S { + &mut self.0.get_mut().stream + } + + /// Returns a pinned mutable reference to the underlying stream. + pub fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut S> { + unsafe { Pin::new_unchecked(&mut self.get_unchecked_mut().0.get_mut().stream) } + } + + fn with_context(self: Pin<&mut Self>, ctx: &mut Context<'_>, f: F) -> R + where + F: FnOnce(&mut SslStreamCore>) -> R, + { + let this = unsafe { self.get_unchecked_mut() }; + this.0.get_mut().context = ctx as *mut _ as usize; + let r = f(&mut this.0); + this.0.get_mut().context = 0; + r + } +} + +#[cfg(feature = "read_uninit")] +impl AsyncRead for SslStream +where + S: AsyncRead + AsyncWrite, +{ + fn poll_read( + self: Pin<&mut Self>, + ctx: &mut Context<'_>, + buf: &mut ReadBuf<'_>, + ) -> Poll> { + self.with_context(ctx, |s| { + // SAFETY: read_uninit does not de-initialize the buffer. + match cvt(s.read_uninit(unsafe { buf.unfilled_mut() }))? { + Poll::Ready(nread) => { + unsafe { + buf.assume_init(nread); + } + buf.advance(nread); + Poll::Ready(Ok(())) + } + Poll::Pending => Poll::Pending, + } + }) + } +} + +#[cfg(not(feature = "read_uninit"))] +impl AsyncRead for SslStream +where + S: AsyncRead + AsyncWrite, +{ + fn poll_read( + self: Pin<&mut Self>, + ctx: &mut Context<'_>, + buf: &mut ReadBuf<'_>, + ) -> Poll> { + self.with_context(ctx, |s| { + // This isn't really "proper", but rust-openssl doesn't currently expose a suitable interface even though + // OpenSSL itself doesn't require the buffer to be initialized. So this is good enough for now. + let slice = unsafe { + let buf = buf.unfilled_mut(); + std::slice::from_raw_parts_mut(buf.as_mut_ptr().cast::(), buf.len()) + }; + match cvt(s.read(slice))? { + Poll::Ready(nread) => { + unsafe { + buf.assume_init(nread); + } + buf.advance(nread); + Poll::Ready(Ok(())) + } + Poll::Pending => Poll::Pending, + } + }) + } +} + +impl AsyncWrite for SslStream +where + S: AsyncRead + AsyncWrite, +{ + fn poll_write(self: Pin<&mut Self>, ctx: &mut Context, buf: &[u8]) -> Poll> { + self.with_context(ctx, |s| cvt(s.write(buf))) + } + + fn poll_flush(self: Pin<&mut Self>, ctx: &mut Context) -> Poll> { + self.with_context(ctx, |s| cvt(s.flush())) + } + + fn poll_shutdown(mut self: Pin<&mut Self>, ctx: &mut Context) -> Poll> { + match self.as_mut().with_context(ctx, |s| s.shutdown()) { + Ok(ShutdownResult::Sent) | Ok(ShutdownResult::Received) => {} + Err(ref e) if e.code() == ErrorCode::ZERO_RETURN => {} + Err(ref e) if e.code() == ErrorCode::WANT_READ || e.code() == ErrorCode::WANT_WRITE => { + return Poll::Pending; + } + Err(e) => { + return Poll::Ready(Err(e + .into_io_error() + .unwrap_or_else(|e| io::Error::new(io::ErrorKind::Other, e)))); + } + } + + self.get_pin_mut().poll_shutdown(ctx) + } +} + +#[tokio::test] +async fn test_google() { + use boring::ssl; + use std::net::ToSocketAddrs; + use std::pin::Pin; + use tokio::io::{AsyncReadExt, AsyncWriteExt}; + use tokio::net::TcpStream; + + let addr = "8.8.8.8:443".to_socket_addrs().unwrap().next().unwrap(); + let stream = TcpStream::connect(&addr).await.unwrap(); + + let ssl_context = ssl::SslContext::builder(ssl::SslMethod::tls()) + .unwrap() + .build(); + let ssl = ssl::Ssl::new(&ssl_context).unwrap(); + let mut stream = crate::tokio_ssl::SslStream::new(ssl, stream).unwrap(); + + Pin::new(&mut stream).connect().await.unwrap(); + + stream.write_all(b"GET / HTTP/1.0\r\n\r\n").await.unwrap(); + + let mut buf = vec![]; + stream.read_to_end(&mut buf).await.unwrap(); + let response = String::from_utf8_lossy(&buf); + let response = response.trim_end(); + + // any response code is fine + assert!(response.starts_with("HTTP/1.0 ")); + assert!(response.ends_with("") || response.ends_with("")); +} diff --git a/pingora-boringssl/src/ext.rs b/pingora-boringssl/src/ext.rs new file mode 100644 index 0000000..bdc0d56 --- /dev/null +++ b/pingora-boringssl/src/ext.rs @@ -0,0 +1,192 @@ +// 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. + +//! the extended functionalities that are yet exposed via the [`boring`] APIs + +use boring::error::ErrorStack; +use boring::pkey::{HasPrivate, PKeyRef}; +use boring::ssl::{Ssl, SslAcceptor, SslRef}; +use boring::x509::store::X509StoreRef; +use boring::x509::verify::X509VerifyParamRef; +use boring::x509::X509Ref; +use foreign_types_shared::ForeignTypeRef; +use libc::*; +use std::ffi::CString; + +fn cvt(r: c_int) -> Result { + if r != 1 { + Err(ErrorStack::get()) + } else { + Ok(r) + } +} + +/// Add name as an additional reference identifier that can match the peer's certificate +/// +/// See [X509_VERIFY_PARAM_set1_host](https://www.openssl.org/docs/man3.1/man3/X509_VERIFY_PARAM_set1_host.html). +pub fn add_host(verify_param: &mut X509VerifyParamRef, host: &str) -> Result<(), ErrorStack> { + if host.is_empty() { + return Ok(()); + } + unsafe { + cvt(boring_sys::X509_VERIFY_PARAM_add1_host( + verify_param.as_ptr(), + host.as_ptr() as *const _, + host.len(), + )) + .map(|_| ()) + } +} + +/// Set the verify cert store of `ssl` +/// +/// See [SSL_set1_verify_cert_store](https://www.openssl.org/docs/man1.1.1/man3/SSL_set1_verify_cert_store.html). +pub fn ssl_set_verify_cert_store( + ssl: &mut SslRef, + cert_store: &X509StoreRef, +) -> Result<(), ErrorStack> { + unsafe { + cvt(boring_sys::SSL_set1_verify_cert_store( + ssl.as_ptr(), + cert_store.as_ptr(), + ))?; + } + Ok(()) +} + +/// Load the certificate into `ssl` +/// +/// See [SSL_use_certificate](https://www.openssl.org/docs/man1.1.1/man3/SSL_use_certificate.html). +pub fn ssl_use_certificate(ssl: &mut SslRef, cert: &X509Ref) -> Result<(), ErrorStack> { + unsafe { + cvt(boring_sys::SSL_use_certificate(ssl.as_ptr(), cert.as_ptr()))?; + } + Ok(()) +} + +/// Load the private key into `ssl` +/// +/// See [SSL_use_certificate](https://www.openssl.org/docs/man1.1.1/man3/SSL_use_PrivateKey.html). +pub fn ssl_use_private_key(ssl: &mut SslRef, key: &PKeyRef) -> Result<(), ErrorStack> +where + T: HasPrivate, +{ + unsafe { + cvt(boring_sys::SSL_use_PrivateKey(ssl.as_ptr(), key.as_ptr()))?; + } + Ok(()) +} + +/// Add the certificate into the cert chain of `ssl` +/// +/// See [SSL_add1_chain_cert](https://www.openssl.org/docs/man1.1.1/man3/SSL_add1_chain_cert.html) +pub fn ssl_add_chain_cert(ssl: &mut SslRef, cert: &X509Ref) -> Result<(), ErrorStack> { + unsafe { + cvt(boring_sys::SSL_add1_chain_cert(ssl.as_ptr(), cert.as_ptr()))?; + } + Ok(()) +} + +/// Set renegotiation +/// +/// This function is specific to BoringSSL +/// See +pub fn ssl_set_renegotiate_mode_freely(ssl: &mut SslRef) { + unsafe { + boring_sys::SSL_set_renegotiate_mode( + ssl.as_ptr(), + boring_sys::ssl_renegotiate_mode_t::ssl_renegotiate_freely, + ); + } +} + +/// Set the curves/groups of `ssl` +/// +/// See [set_groups_list](https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set1_curves.html). +pub fn ssl_set_groups_list(ssl: &mut SslRef, groups: &str) -> Result<(), ErrorStack> { + let groups = CString::new(groups).unwrap(); + unsafe { + // somehow SSL_set1_groups_list doesn't exist but SSL_set1_curves_list means the same anyways + cvt(boring_sys::SSL_set1_curves_list( + ssl.as_ptr(), + groups.as_ptr(), + ))?; + } + Ok(()) +} + +/// Set's whether a second keyshare to be sent in client hello when PQ is used. +/// +/// Default is true. When `true`, the first PQ (if any) and none-PQ keyshares are sent. +/// When `false`, only the first configured keyshares are sent. +#[cfg(feature = "pq_use_second_keyshare")] +pub fn ssl_use_second_key_share(ssl: &mut SslRef, enabled: bool) { + unsafe { boring_sys::SSL_use_second_keyshare(ssl.as_ptr(), enabled as _) } +} +#[cfg(not(feature = "pq_use_second_keyshare"))] +pub fn ssl_use_second_key_share(_ssl: &mut SslRef, _enabled: bool) {} + +/// Clear the error stack +/// +/// SSL calls should check and clear the BoringSSL error stack. But some calls fail to do so. +/// This causes the next unrelated SSL call to fail due to the leftover errors. This function allow +/// the caller to clear the error stack before performing SSL calls to avoid this issue. +pub fn clear_error_stack() { + let _ = ErrorStack::get(); +} + +/// Create a new [Ssl] from &[SslAcceptor] +/// +/// This function is needed because [Ssl::new()] doesn't take `&SslContextRef` like openssl-rs +pub fn ssl_from_acceptor(acceptor: &SslAcceptor) -> Result { + Ssl::new_from_ref(acceptor.context()) +} + +/// Suspend the TLS handshake when a certificate is needed. +/// +/// This function will cause tls handshake to pause and return the error: SSL_ERROR_WANT_X509_LOOKUP. +/// The caller should set the certificate and then call [unblock_ssl_cert()] before continue the +/// handshake on the tls connection. +pub fn suspend_when_need_ssl_cert(ssl: &mut SslRef) { + unsafe { + boring_sys::SSL_set_cert_cb(ssl.as_ptr(), Some(raw_cert_block), std::ptr::null_mut()); + } +} + +/// Unblock a TLS handshake after the certificate is set. +/// +/// The user should continue to call tls handshake after this function is called. +pub fn unblock_ssl_cert(ssl: &mut SslRef) { + unsafe { + boring_sys::SSL_set_cert_cb(ssl.as_ptr(), None, std::ptr::null_mut()); + } +} + +// Just block the handshake +extern "C" fn raw_cert_block(_ssl: *mut boring_sys::SSL, _arg: *mut c_void) -> c_int { + -1 +} + +/// Whether the TLS error is SSL_ERROR_WANT_X509_LOOKUP +pub fn is_suspended_for_cert(error: &boring::ssl::Error) -> bool { + error.code().as_raw() == boring_sys::SSL_ERROR_WANT_X509_LOOKUP +} + +#[allow(clippy::mut_from_ref)] +/// Get a mutable SslRef ouf of SslRef. which is a missing functionality for certain SslStream +/// # Safety +/// the caller need to make sure that they hold a &mut SslRef +pub unsafe fn ssl_mut(ssl: &SslRef) -> &mut SslRef { + unsafe { SslRef::from_ptr_mut(ssl.as_ptr()) } +} diff --git a/pingora-boringssl/src/lib.rs b/pingora-boringssl/src/lib.rs new file mode 100644 index 0000000..26dfaab --- /dev/null +++ b/pingora-boringssl/src/lib.rs @@ -0,0 +1,34 @@ +// 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. + +//! The BoringSSL API compatibility layer. +//! +//! This crate aims at making [boring] APIs exchangeable with [openssl-rs](https://docs.rs/openssl/latest/openssl/). +//! In other words, this crate and `pingora-openssl` expose identical rust APIs. + +#![warn(clippy::all)] + +use boring as ssl_lib; +pub use boring_sys as ssl_sys; +pub mod boring_tokio; +pub use boring_tokio as tokio_ssl; +pub mod ext; + +// export commonly used libs +pub use ssl_lib::error; +pub use ssl_lib::hash; +pub use ssl_lib::nid; +pub use ssl_lib::pkey; +pub use ssl_lib::ssl; +pub use ssl_lib::x509; diff --git a/pingora-cache/Cargo.toml b/pingora-cache/Cargo.toml new file mode 100644 index 0000000..3add293 --- /dev/null +++ b/pingora-cache/Cargo.toml @@ -0,0 +1,64 @@ +[package] +name = "pingora-cache" +version = "0.1.0" +authors = ["Yuchen Wu "] +license = "Apache-2.0" +edition = "2021" +repository = "https://github.com/cloudflare/pingora" +categories = ["asynchronous", "network-programming"] +keywords = ["async", "http", "cache"] +description = """ +HTTP caching APIs for Pingora proxy. +""" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +name = "pingora_cache" +path = "src/lib.rs" + +[dependencies] +pingora-core = { version = "0.1.0", path = "../pingora-core" } +pingora-error = { version = "0.1.0", path = "../pingora-error" } +pingora-header-serde = { version = "0.1.0", path = "../pingora-header-serde" } +pingora-http = { version = "0.1.0", path = "../pingora-http" } +pingora-lru = { version = "0.1.0", path = "../pingora-lru" } +pingora-timeout = { version = "0.1.0", path = "../pingora-timeout" } +http = { workspace = true } +indexmap = "1" +once_cell = { workspace = true } +regex = "1" +blake2 = "0.10" +serde = { version = "1.0", features = ["derive"] } +rmp-serde = "1" +bytes = { workspace = true } +httpdate = "1.0.2" +log = { workspace = true } +async-trait = { workspace = true } +parking_lot = "0.12" +rustracing = "0.5.1" +rustracing_jaeger = "0.7" +rmp = "0.8" +tokio = { workspace = true } +lru = { workspace = true } +ahash = { workspace = true } +hex = "0.4" +httparse = { workspace = true } + +[dev-dependencies] +tokio-test = "0.4" +tokio = { workspace = true, features = ["fs"] } +env_logger = "0.9" +dhat = "0" +futures = "0.3" + +[[bench]] +name = "simple_lru_memory" +harness = false + +[[bench]] +name = "lru_memory" +harness = false + +[[bench]] +name = "lru_serde" +harness = false diff --git a/pingora-cache/LICENSE b/pingora-cache/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/pingora-cache/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/pingora-cache/benches/lru_memory.rs b/pingora-cache/benches/lru_memory.rs new file mode 100644 index 0000000..d2d022f --- /dev/null +++ b/pingora-cache/benches/lru_memory.rs @@ -0,0 +1,96 @@ +// 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. + +#[global_allocator] +static ALLOC: dhat::Alloc = dhat::Alloc; + +use pingora_cache::{ + eviction::{lru::Manager, EvictionManager}, + CacheKey, +}; + +const ITEMS: usize = 5 * usize::pow(2, 20); + +/* + Total: 681,836,456 bytes (100%, 28,192,797.16/s) in 10,485,845 blocks (100%, 433,572.15/s), avg size 65.02 bytes, avg lifetime 5,935,075.17 µs (24.54% of program duration) + At t-gmax: 569,114,536 bytes (100%) in 5,242,947 blocks (100%), avg size 108.55 bytes + At t-end: 88 bytes (100%) in 3 blocks (100%), avg size 29.33 bytes + Allocated at { + #0: [root] + } + ├── PP 1.1/5 { + │ Total: 293,601,280 bytes (43.06%, 12,139,921.91/s) in 5,242,880 blocks (50%, 216,784.32/s), avg size 56 bytes, avg lifetime 11,870,032.65 µs (49.08% of program duration) + │ Max: 293,601,280 bytes in 5,242,880 blocks, avg size 56 bytes + │ At t-gmax: 293,601,280 bytes (51.59%) in 5,242,880 blocks (100%), avg size 56 bytes + │ At t-end: 0 bytes (0%) in 0 blocks (0%), avg size 0 bytes + │ Allocated at { + │ #1: 0x5555703cf69c: alloc::alloc::exchange_malloc (alloc/src/alloc.rs:326:11) + │ #2: 0x5555703cf69c: alloc::boxed::Box::new (alloc/src/boxed.rs:215:9) + │ #3: 0x5555703cf69c: pingora_lru::LruUnit::admit (pingora-lru/src/lib.rs:201:20) + │ #4: 0x5555703cf69c: pingora_lru::Lru::admit (pingora-lru/src/lib.rs:48:26) + │ #5: 0x5555703cf69c: as pingora_cache::eviction::EvictionManager>::admit (src/eviction/lru.rs:114:9) + │ #6: 0x5555703cf69c: lru_memory::main (pingora-cache/benches/lru_memory.rs:78:9) + │ } + │ } + ├── PP 1.2/5 { + │ Total: 203,685,456 bytes (29.87%, 8,422,052.97/s) in 50 blocks (0%, 2.07/s), avg size 4,073,709.12 bytes, avg lifetime 6,842,528.74 µs (28.29% of program duration) + │ Max: 132,906,576 bytes in 32 blocks, avg size 4,153,330.5 bytes + │ At t-gmax: 132,906,576 bytes (23.35%) in 32 blocks (0%), avg size 4,153,330.5 bytes + │ At t-end: 0 bytes (0%) in 0 blocks (0%), avg size 0 bytes + │ Allocated at { + │ #1: 0x5555703cec54: ::allocate (alloc/src/alloc.rs:237:9) + │ #2: 0x5555703cec54: alloc::raw_vec::RawVec::allocate_in (alloc/src/raw_vec.rs:185:45) + │ #3: 0x5555703cec54: alloc::raw_vec::RawVec::with_capacity_in (alloc/src/raw_vec.rs:131:9) + │ #4: 0x5555703cec54: alloc::vec::Vec::with_capacity_in (src/vec/mod.rs:641:20) + │ #5: 0x5555703cec54: alloc::vec::Vec::with_capacity (src/vec/mod.rs:483:9) + │ #6: 0x5555703cec54: pingora_lru::linked_list::Nodes::with_capacity (pingora-lru/src/linked_list.rs:50:25) + │ #7: 0x5555703cec54: pingora_lru::linked_list::LinkedList::with_capacity (pingora-lru/src/linked_list.rs:121:20) + │ #8: 0x5555703cec54: pingora_lru::LruUnit::with_capacity (pingora-lru/src/lib.rs:176:20) + │ #9: 0x5555703cec54: pingora_lru::Lru::with_capacity (pingora-lru/src/lib.rs:28:36) + │ #10: 0x5555703cec54: pingora_cache::eviction::lru::Manager<_>::with_capacity (src/eviction/lru.rs:22:17) + │ #11: 0x5555703cec54: lru_memory::main (pingora-cache/benches/lru_memory.rs:74:19) + │ } + │ } + ├── PP 1.3/5 { + │ Total: 142,606,592 bytes (20.92%, 5,896,544.09/s) in 32 blocks (0%, 1.32/s), avg size 4,456,456 bytes, avg lifetime 22,056,252.88 µs (91.2% of program duration) + │ Max: 142,606,592 bytes in 32 blocks, avg size 4,456,456 bytes + │ At t-gmax: 142,606,592 bytes (25.06%) in 32 blocks (0%), avg size 4,456,456 bytes + │ At t-end: 0 bytes (0%) in 0 blocks (0%), avg size 0 bytes + │ Allocated at { + │ #1: 0x5555703ceb64: alloc::alloc::alloc (alloc/src/alloc.rs:95:14) + │ #2: 0x5555703ceb64: ::allocate (src/raw/alloc.rs:47:35) + │ #3: 0x5555703ceb64: hashbrown::raw::alloc::inner::do_alloc (src/raw/alloc.rs:62:9) + │ #4: 0x5555703ceb64: hashbrown::raw::RawTableInner::new_uninitialized (src/raw/mod.rs:1080:38) + │ #5: 0x5555703ceb64: hashbrown::raw::RawTableInner::fallible_with_capacity (src/raw/mod.rs:1109:30) + │ #6: 0x5555703ceb64: hashbrown::raw::RawTable::fallible_with_capacity (src/raw/mod.rs:460:20) + │ #7: 0x5555703ceb64: hashbrown::raw::RawTable::with_capacity_in (src/raw/mod.rs:481:15) + │ #8: 0x5555703ceb64: hashbrown::raw::RawTable::with_capacity (src/raw/mod.rs:411:9) + │ #9: 0x5555703ceb64: hashbrown::map::HashMap::with_capacity_and_hasher (hashbrown-0.12.3/src/map.rs:422:20) + │ #10: 0x5555703ceb64: hashbrown::map::HashMap::with_capacity (hashbrown-0.12.3/src/map.rs:326:9) + │ #11: 0x5555703ceb64: pingora_lru::LruUnit::with_capacity (pingora-lru/src/lib.rs:175:27) + │ #12: 0x5555703ceb64: pingora_lru::Lru::with_capacity (pingora-lru/src/lib.rs:28:36) + │ #13: 0x5555703ceb64: pingora_cache::eviction::lru::Manager<_>::with_capacity (src/eviction/lru.rs:22:17) + │ #14: 0x5555703ceb64: lru_memory::main (pingora-cache/benches/lru_memory.rs:74:19) + │ } + │ } +*/ +fn main() { + let _profiler = dhat::Profiler::new_heap(); + let manager = Manager::<32>::with_capacity(ITEMS, ITEMS / 32); + let unused_ttl = std::time::SystemTime::now(); + for i in 0..ITEMS { + let item = CacheKey::new("", i.to_string(), "").to_compact(); + manager.admit(item, 1, unused_ttl); + } +} diff --git a/pingora-cache/benches/lru_serde.rs b/pingora-cache/benches/lru_serde.rs new file mode 100644 index 0000000..7ad4234 --- /dev/null +++ b/pingora-cache/benches/lru_serde.rs @@ -0,0 +1,46 @@ +// 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 std::time::Instant; + +use pingora_cache::{ + eviction::{lru::Manager, EvictionManager}, + CacheKey, +}; + +const ITEMS: usize = 5 * usize::pow(2, 20); + +fn main() { + let manager = Manager::<32>::with_capacity(ITEMS, ITEMS / 32); + let manager2 = Manager::<32>::with_capacity(ITEMS, ITEMS / 32); + let unused_ttl = std::time::SystemTime::now(); + for i in 0..ITEMS { + let item = CacheKey::new("", i.to_string(), "").to_compact(); + manager.admit(item, 1, unused_ttl); + } + + /* lru serialize shard 19 22.573338ms, 5241623 bytes + * lru deserialize shard 19 39.260669ms, 5241623 bytes */ + for i in 0..32 { + let before = Instant::now(); + let ser = manager.serialize_shard(i).unwrap(); + let elapsed = before.elapsed(); + println!("lru serialize shard {i} {elapsed:?}, {} bytes", ser.len()); + + let before = Instant::now(); + manager2.deserialize_shard(&ser).unwrap(); + let elapsed = before.elapsed(); + println!("lru deserialize shard {i} {elapsed:?}, {} bytes", ser.len()); + } +} diff --git a/pingora-cache/benches/simple_lru_memory.rs b/pingora-cache/benches/simple_lru_memory.rs new file mode 100644 index 0000000..b12a5c8 --- /dev/null +++ b/pingora-cache/benches/simple_lru_memory.rs @@ -0,0 +1,78 @@ +// 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. + +#[global_allocator] +static ALLOC: dhat::Alloc = dhat::Alloc; + +use pingora_cache::{ + eviction::{simple_lru::Manager, EvictionManager}, + CacheKey, +}; + +const ITEMS: usize = 5 * usize::pow(2, 20); + +/* + Total: 704,643,412 bytes (100%, 29,014,058.85/s) in 10,485,787 blocks (100%, 431,757.73/s), avg size 67.2 bytes, avg lifetime 6,163,799.09 µs (25.38% of program duration) + At t-gmax: 520,093,936 bytes (100%) in 5,242,886 blocks (100%), avg size 99.2 bytes + ├── PP 1.1/4 { + │ Total: 377,487,360 bytes (53.57%, 15,543,238.31/s) in 5,242,880 blocks (50%, 215,878.31/s), avg size 72 bytes, avg lifetime 12,327,602.83 µs (50.76% of program duration) + │ Max: 377,487,360 bytes in 5,242,880 blocks, avg size 72 bytes + │ At t-gmax: 377,487,360 bytes (72.58%) in 5,242,880 blocks (100%), avg size 72 bytes + │ At t-end: 0 bytes (0%) in 0 blocks (0%), avg size 0 bytes + │ Allocated at { + │ #1: 0x5555791dd7e0: alloc::alloc::exchange_malloc (alloc/src/alloc.rs:326:11) + │ #2: 0x5555791dd7e0: alloc::boxed::Box::new (alloc/src/boxed.rs:215:9) + │ #3: 0x5555791dd7e0: lru::LruCache::replace_or_create_node (lru-0.8.1/src/lib.rs:391:20) + │ #4: 0x5555791dd7e0: lru::LruCache::capturing_put (lru-0.8.1/src/lib.rs:355:44) + │ #5: 0x5555791dd7e0: lru::LruCache::push (lru-0.8.1/src/lib.rs:334:9) + │ #6: 0x5555791dd7e0: pingora_cache::eviction::simple_lru::Manager::insert (src/eviction/simple_lru.rs:49:23) + │ #7: 0x5555791dd7e0: ::admit (src/eviction/simple_lru.rs:166:9) + │ #8: 0x5555791dd7e0: simple_lru_memory::main (pingora-cache/benches/simple_lru_memory.rs:21:9) + │ } + │ } + ├── PP 1.2/4 { + │ Total: 285,212,780 bytes (40.48%, 11,743,784.5/s) in 22 blocks (0%, 0.91/s), avg size 12,964,217.27 bytes, avg lifetime 1,116,774.23 µs (4.6% of program duration) + │ Max: 213,909,520 bytes in 2 blocks, avg size 106,954,760 bytes + │ At t-gmax: 142,606,344 bytes (27.42%) in 1 blocks (0%), avg size 142,606,344 bytes + │ At t-end: 0 bytes (0%) in 0 blocks (0%), avg size 0 bytes + │ Allocated at { + │ #1: 0x5555791dae20: alloc::alloc::alloc (alloc/src/alloc.rs:95:14) + │ #2: 0x5555791dae20: ::allocate (src/raw/alloc.rs:47:35) + │ #3: 0x5555791dae20: hashbrown::raw::alloc::inner::do_alloc (src/raw/alloc.rs:62:9) + │ #4: 0x5555791dae20: hashbrown::raw::RawTableInner::new_uninitialized (src/raw/mod.rs:1080:38) + │ #5: 0x5555791dae20: hashbrown::raw::RawTableInner::fallible_with_capacity (src/raw/mod.rs:1109:30) + │ #6: 0x5555791dae20: hashbrown::raw::RawTableInner::prepare_resize (src/raw/mod.rs:1353:29) + │ #7: 0x5555791dae20: hashbrown::raw::RawTableInner::resize_inner (src/raw/mod.rs:1426:29) + │ #8: 0x5555791dae20: hashbrown::raw::RawTableInner::reserve_rehash_inner (src/raw/mod.rs:1403:13) + │ #9: 0x5555791dae20: hashbrown::raw::RawTable::reserve_rehash (src/raw/mod.rs:680:13) + │ #10: 0x5555791dde50: hashbrown::raw::RawTable::reserve (src/raw/mod.rs:646:16) + │ #11: 0x5555791dde50: hashbrown::raw::RawTable::insert (src/raw/mod.rs:725:17) + │ #12: 0x5555791dde50: hashbrown::map::HashMap::insert (hashbrown-0.12.3/src/map.rs:1679:13) + │ #13: 0x5555791dde50: lru::LruCache::capturing_put (lru-0.8.1/src/lib.rs:361:17) + │ #14: 0x5555791dde50: lru::LruCache::push (lru-0.8.1/src/lib.rs:334:9) + │ #15: 0x5555791dde50: pingora_cache::eviction::simple_lru::Manager::insert (src/eviction/simple_lru.rs:49:23) + │ #16: 0x5555791dde50: ::admit (src/eviction/simple_lru.rs:166:9) + │ #17: 0x5555791dde50: simple_lru_memory::main (pingora-cache/benches/simple_lru_memory.rs:21:9) + │ } + │ } +*/ +fn main() { + let _profiler = dhat::Profiler::new_heap(); + let manager = Manager::new(ITEMS); + let unused_ttl = std::time::SystemTime::now(); + for i in 0..ITEMS { + let item = CacheKey::new("", i.to_string(), "").to_compact(); + manager.admit(item, 1, unused_ttl); + } +} diff --git a/pingora-cache/src/cache_control.rs b/pingora-cache/src/cache_control.rs new file mode 100644 index 0000000..6686c3e --- /dev/null +++ b/pingora-cache/src/cache_control.rs @@ -0,0 +1,839 @@ +// 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. + +//! Functions and utilities to help parse Cache-Control headers + +use super::*; + +use http::header::HeaderName; +use http::HeaderValue; +use indexmap::IndexMap; +use once_cell::sync::Lazy; +use pingora_error::{Error, ErrorType, Result}; +use pingora_http::ResponseHeader; +use regex::bytes::Regex; +use std::num::IntErrorKind; +use std::slice; +use std::str; + +/// The max delta-second per [RFC 7234](https://datatracker.ietf.org/doc/html/rfc7234#section-1.2.1) +// "If a cache receives a delta-seconds +// value greater than the greatest integer it can represent, or if any +// of its subsequent calculations overflows, the cache MUST consider the +// value to be either 2147483648 (2^31) or the greatest positive integer +// it can conveniently represent." +pub const DELTA_SECONDS_OVERFLOW_VALUE: u32 = 2147483648; + +/// Cache control directive key type +pub type DirectiveKey = String; + +/// Cache control directive value type +#[derive(Debug)] +pub struct DirectiveValue(pub Vec); + +impl AsRef<[u8]> for DirectiveValue { + fn as_ref(&self) -> &[u8] { + &self.0 + } +} + +impl DirectiveValue { + /// A [DirectiveValue] without quotes (`"`). + pub fn parse_as_bytes(&self) -> &[u8] { + self.0 + .strip_prefix(&[b'"']) + .and_then(|bytes| bytes.strip_suffix(&[b'"'])) + .unwrap_or(&self.0[..]) + } + + /// A [DirectiveValue] without quotes (`"`) as `str`. + pub fn parse_as_str(&self) -> Result<&str> { + str::from_utf8(self.parse_as_bytes()).or_else(|e| { + Error::e_because(ErrorType::InternalError, "could not parse value as utf8", e) + }) + } + + /// Parse the [DirectiveValue] as delta seconds + /// + /// `"`s are ignored. The value is capped to [DELTA_SECONDS_OVERFLOW_VALUE]. + pub fn parse_as_delta_seconds(&self) -> Result { + match self.parse_as_str()?.parse::() { + Ok(value) => Ok(value), + Err(e) => { + // delta-seconds expect to handle positive overflow gracefully + if e.kind() == &IntErrorKind::PosOverflow { + Ok(DELTA_SECONDS_OVERFLOW_VALUE) + } else { + Error::e_because(ErrorType::InternalError, "could not parse value as u32", e) + } + } + } + } +} + +/// An ordered map to store cache control key value pairs. +pub type DirectiveMap = IndexMap>; + +/// Parsed Cache-Control directives +#[derive(Debug)] +pub struct CacheControl { + /// The parsed directives + pub directives: DirectiveMap, +} + +/// Cacheability calculated from cache control. +#[derive(Debug, PartialEq, Eq)] +pub enum Cacheable { + /// Cacheable + Yes, + /// Not cacheable + No, + /// No directive found for explicit cacheability + Default, +} + +/// An iter over all the cache control directives +pub struct ListValueIter<'a>(slice::Split<'a, u8, fn(&u8) -> bool>); + +impl<'a> ListValueIter<'a> { + pub fn from(value: &'a DirectiveValue) -> Self { + ListValueIter(value.parse_as_bytes().split(|byte| byte == &b',')) + } +} + +// https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.3 +// optional whitespace OWS = *(SP / HTAB); SP = 0x20, HTAB = 0x09 +fn trim_ows(bytes: &[u8]) -> &[u8] { + fn not_ows(b: &u8) -> bool { + b != &b'\x20' && b != &b'\x09' + } + // find first non-OWS char from front (head) and from end (tail) + let head = bytes.iter().position(not_ows).unwrap_or(0); + let tail = bytes + .iter() + .rposition(not_ows) + .map(|rpos| rpos + 1) + .unwrap_or(head); + &bytes[head..tail] +} + +impl<'a> Iterator for ListValueIter<'a> { + type Item = &'a [u8]; + + fn next(&mut self) -> Option { + Some(trim_ows(self.0.next()?)) + } +} + +/* + Originally from https://github.com/hapijs/wreck: + Cache-Control = 1#cache-directive + cache-directive = token [ "=" ( token / quoted-string ) ] + token = [^\x00-\x20\(\)<>@\,;\:\\"\/\[\]\?\=\{\}\x7F]+ + quoted-string = "(?:[^"\\]|\\.)*" +*/ +static RE_CACHE_DIRECTIVE: Lazy = + // unicode support disabled, allow ; or , delimiter | capture groups: 1: directive = 2: token OR quoted-string + Lazy::new(|| { + Regex::new(r#"(?-u)(?:^|(?:\s*[,;]\s*))([^\x00-\x20\(\)<>@,;:\\"/\[\]\?=\{\}\x7F]+)(?:=((?:[^\x00-\x20\(\)<>@,;:\\"/\[\]\?=\{\}\x7F]+|(?:"(?:[^"\\]|\\.)*"))))?"#).unwrap() + }); + +impl CacheControl { + // Our parsing strategy is more permissive than the RFC in a few ways: + // - Allows semicolons as delimiters (in addition to commas). + // - Allows octets outside of visible ASCII in tokens. + // - Doesn't require no-value for "boolean directives," such as must-revalidate + // - Allows quoted-string format for numeric values. + fn from_headers(headers: http::header::GetAll) -> Option { + let mut directives = IndexMap::new(); + // should iterate in header line insertion order + for line in headers { + for captures in RE_CACHE_DIRECTIVE.captures_iter(line.as_bytes()) { + // directive key + // header values don't have to be utf-8, but we store keys as strings for case-insensitive hashing + let key = captures.get(1).and_then(|cap| { + str::from_utf8(cap.as_bytes()) + .ok() + .map(|token| token.to_lowercase()) + }); + if key.is_none() { + continue; + } + // directive value + // match token or quoted-string + let value = captures + .get(2) + .map(|cap| DirectiveValue(cap.as_bytes().to_vec())); + directives.insert(key.unwrap(), value); + } + } + Some(CacheControl { directives }) + } + + /// Parse from the given header name in `headers` + pub fn from_headers_named(header_name: &str, headers: &http::HeaderMap) -> Option { + if !headers.contains_key(header_name) { + return None; + } + + Self::from_headers(headers.get_all(header_name)) + } + + /// Parse from the given header name in the [ReqHeader] + pub fn from_req_headers_named(header_name: &str, req_header: &ReqHeader) -> Option { + Self::from_headers_named(header_name, &req_header.headers) + } + + /// Parse `Cache-Control` header name from the [ReqHeader] + pub fn from_req_headers(req_header: &ReqHeader) -> Option { + Self::from_req_headers_named("cache-control", req_header) + } + + /// Parse from the given header name in the [RespHeader] + pub fn from_resp_headers_named(header_name: &str, resp_header: &RespHeader) -> Option { + Self::from_headers_named(header_name, &resp_header.headers) + } + + /// Parse `Cache-Control` header name from the [RespHeader] + pub fn from_resp_headers(resp_header: &RespHeader) -> Option { + Self::from_resp_headers_named("cache-control", resp_header) + } + + /// Whether the given directive is in the cache control. + pub fn has_key(&self, key: &str) -> bool { + self.directives.contains_key(key) + } + + /// Whether the `public` directive is in the cache control. + pub fn public(&self) -> bool { + self.has_key("public") + } + + /// Whether the given directive exists and it has no value. + fn has_key_without_value(&self, key: &str) -> bool { + matches!(self.directives.get(key), Some(None)) + } + + /// Whether the standalone `private` exists in the cache control + // RFC 7234: using the #field-name versions of `private` + // means a shared cache "MUST NOT store the specified field-name(s), + // whereas it MAY store the remainder of the response." + // It must be a boolean form (no value) to apply to the whole response. + // https://datatracker.ietf.org/doc/html/rfc7234#section-5.2.2.6 + pub fn private(&self) -> bool { + self.has_key_without_value("private") + } + + fn get_field_names(&self, key: &str) -> Option { + if let Some(Some(value)) = self.directives.get(key) { + Some(ListValueIter::from(value)) + } else { + None + } + } + + /// Get the values of `private=` + pub fn private_field_names(&self) -> Option { + self.get_field_names("private") + } + + /// Whether the standalone `no-cache` exists in the cache control + pub fn no_cache(&self) -> bool { + self.has_key_without_value("no-cache") + } + + /// Get the values of `no-cache=` + pub fn no_cache_field_names(&self) -> Option { + self.get_field_names("no-cache") + } + + /// Whether `no-store` exists. + pub fn no_store(&self) -> bool { + self.has_key("no-store") + } + + fn parse_delta_seconds(&self, key: &str) -> Result> { + if let Some(Some(dir_value)) = self.directives.get(key) { + Ok(Some(dir_value.parse_as_delta_seconds()?)) + } else { + Ok(None) + } + } + + /// Return the `max-age` seconds + pub fn max_age(&self) -> Result> { + self.parse_delta_seconds("max-age") + } + + /// Return the `s-maxage` seconds + pub fn s_maxage(&self) -> Result> { + self.parse_delta_seconds("s-maxage") + } + + /// Return the `stale-while-revalidate` seconds + pub fn stale_while_revalidate(&self) -> Result> { + self.parse_delta_seconds("stale-while-revalidate") + } + + /// Return the `stale-if-error` seconds + pub fn stale_if_error(&self) -> Result> { + self.parse_delta_seconds("stale-if-error") + } + + /// Whether `must-revalidate` exists. + pub fn must_revalidate(&self) -> bool { + self.has_key("must-revalidate") + } + + /// Whether `proxy-revalidate` exists. + pub fn proxy_revalidate(&self) -> bool { + self.has_key("proxy-revalidate") + } + + /// Whether `only-if-cached` exists. + pub fn only_if_cached(&self) -> bool { + self.has_key("only-if-cached") + } +} + +impl InterpretCacheControl for CacheControl { + fn is_cacheable(&self) -> Cacheable { + if self.no_store() || self.private() { + return Cacheable::No; + } + if self.has_key("s-maxage") || self.has_key("max-age") || self.public() { + return Cacheable::Yes; + } + Cacheable::Default + } + + fn allow_caching_authorized_req(&self) -> bool { + // RFC 7234 https://datatracker.ietf.org/doc/html/rfc7234#section-3 + // "MUST NOT" store requests with Authorization header + // unless response contains one of these directives + self.must_revalidate() || self.public() || self.has_key("s-maxage") + } + + fn fresh_sec(&self) -> Option { + if self.no_cache() { + // always treated as stale + return Some(0); + } + match self.s_maxage() { + Ok(Some(seconds)) => Some(seconds), + // s-maxage not present + Ok(None) => match self.max_age() { + Ok(Some(seconds)) => Some(seconds), + _ => None, + }, + _ => None, + } + } + + fn serve_stale_while_revalidate_sec(&self) -> Option { + // RFC 7234: these directives forbid serving stale. + // https://datatracker.ietf.org/doc/html/rfc7234#section-4.2.4 + if self.must_revalidate() || self.proxy_revalidate() || self.has_key("s-maxage") { + return Some(0); + } + self.stale_while_revalidate().unwrap_or(None) + } + + fn serve_stale_if_error_sec(&self) -> Option { + if self.must_revalidate() || self.proxy_revalidate() || self.has_key("s-maxage") { + return Some(0); + } + self.stale_if_error().unwrap_or(None) + } + + // Strip header names listed in `private` or `no-cache` directives from a response. + fn strip_private_headers(&self, resp_header: &mut ResponseHeader) { + fn strip_listed_headers(resp: &mut ResponseHeader, field_names: ListValueIter) { + for name in field_names { + if let Ok(header) = HeaderName::from_bytes(name) { + resp.remove_header(&header); + } + } + } + + if let Some(headers) = self.private_field_names() { + strip_listed_headers(resp_header, headers); + } + // We interpret `no-cache` the same way as `private`, + // though technically it has a less restrictive requirement + // ("MUST NOT be sent in the response to a subsequent request + // without successful revalidation with the origin server"). + // https://datatracker.ietf.org/doc/html/rfc7234#section-5.2.2.2 + if let Some(headers) = self.no_cache_field_names() { + strip_listed_headers(resp_header, headers); + } + } +} + +/// `InterpretCacheControl` provides a meaningful interface to the parsed `CacheControl`. +/// These functions actually interpret the parsed cache-control directives to return +/// the freshness or other cache meta values that cache-control is signaling. +/// +/// By default `CacheControl` implements an RFC-7234 compliant reading that assumes it is being +/// used with a shared (proxy) cache. +pub trait InterpretCacheControl { + /// Does cache-control specify this response is cacheable? + /// + /// Note that an RFC-7234 compliant cacheability check must also + /// check if the request contained the Authorization header and + /// `allow_caching_authorized_req`. + fn is_cacheable(&self) -> Cacheable; + + /// Does this cache-control allow caching a response to + /// a request with the Authorization header? + fn allow_caching_authorized_req(&self) -> bool; + + /// Returns freshness ttl specified in cache-control + /// + /// - `Some(_)` indicates cache-control specifies a valid ttl. Some(0) = always stale. + /// - `None` means cache-control did not specify a valid ttl. + fn fresh_sec(&self) -> Option; + + /// Returns stale-while-revalidate ttl, + /// + /// The result should consider all the relevant cache directives, not just SWR header itself. + /// + /// Some(0) means serving such stale is disallowed by directive like `must-revalidate` + /// or `stale-while-revalidater=0`. + /// + /// `None` indicates no SWR ttl was specified. + fn serve_stale_while_revalidate_sec(&self) -> Option; + + /// Returns stale-if-error ttl, + /// + /// The result should consider all the relevant cache directives, not just SIE header itself. + /// + /// Some(0) means serving such stale is disallowed by directive like `must-revalidate` + /// or `stale-if-error=0`. + /// + /// `None` indicates no SIE ttl was specified. + fn serve_stale_if_error_sec(&self) -> Option; + + /// Strip header names listed in `private` or `no-cache` directives from a response, + /// usually prior to storing that response in cache. + fn strip_private_headers(&self, resp_header: &mut ResponseHeader); +} + +#[cfg(test)] +mod tests { + use super::*; + use http::header::CACHE_CONTROL; + use http::HeaderValue; + use http::{request, response}; + + fn build_response(cc_key: HeaderName, cc_value: &str) -> response::Parts { + let (parts, _) = response::Builder::new() + .header(cc_key, cc_value) + .body(()) + .unwrap() + .into_parts(); + parts + } + + #[test] + fn test_simple_cache_control() { + let resp = build_response(CACHE_CONTROL, "public, max-age=10000"); + let cc = CacheControl::from_resp_headers(&resp).unwrap(); + assert!(cc.public()); + assert_eq!(cc.max_age().unwrap().unwrap(), 10000); + } + + #[test] + fn test_private_cache_control() { + let resp = build_response(CACHE_CONTROL, "private"); + let cc = CacheControl::from_resp_headers(&resp).unwrap(); + + assert!(cc.private()); + assert!(cc.max_age().unwrap().is_none()); + } + + #[test] + fn test_directives_across_header_lines() { + let (parts, _) = response::Builder::new() + .header(CACHE_CONTROL, "public,") + .header("cache-Control", "max-age=10000") + .body(()) + .unwrap() + .into_parts(); + let cc = CacheControl::from_resp_headers(&parts).unwrap(); + + assert!(cc.public()); + assert_eq!(cc.max_age().unwrap().unwrap(), 10000); + } + + #[test] + fn test_recognizes_semicolons_as_delimiters() { + let resp = build_response(CACHE_CONTROL, "public; max-age=0"); + let cc = CacheControl::from_resp_headers(&resp).unwrap(); + + assert!(cc.public()); + assert_eq!(cc.max_age().unwrap().unwrap(), 0); + } + + #[test] + fn test_unknown_directives() { + let resp = build_response(CACHE_CONTROL, "public,random1=random2, rand3=\"\""); + let cc = CacheControl::from_resp_headers(&resp).unwrap(); + let mut directive_iter = cc.directives.iter(); + + let first = directive_iter.next().unwrap(); + assert_eq!(first.0, &"public"); + assert!(first.1.is_none()); + + let second = directive_iter.next().unwrap(); + assert_eq!(second.0, &"random1"); + assert_eq!(second.1.as_ref().unwrap().0, "random2".as_bytes()); + + let third = directive_iter.next().unwrap(); + assert_eq!(third.0, &"rand3"); + assert_eq!(third.1.as_ref().unwrap().0, "\"\"".as_bytes()); + + assert!(directive_iter.next().is_none()); + } + + #[test] + fn test_case_insensitive_directive_keys() { + let resp = build_response( + CACHE_CONTROL, + "Public=\"something\", mAx-AGe=\"10000\", foo=cRaZyCaSe, bAr=\"inQuotes\"", + ); + let cc = CacheControl::from_resp_headers(&resp).unwrap(); + + assert!(cc.public()); + assert_eq!(cc.max_age().unwrap().unwrap(), 10000); + + let mut directive_iter = cc.directives.iter(); + let first = directive_iter.next().unwrap(); + assert_eq!(first.0, &"public"); + assert_eq!(first.1.as_ref().unwrap().0, "\"something\"".as_bytes()); + + let second = directive_iter.next().unwrap(); + assert_eq!(second.0, &"max-age"); + assert_eq!(second.1.as_ref().unwrap().0, "\"10000\"".as_bytes()); + + // values are still stored with casing + let third = directive_iter.next().unwrap(); + assert_eq!(third.0, &"foo"); + assert_eq!(third.1.as_ref().unwrap().0, "cRaZyCaSe".as_bytes()); + + let fourth = directive_iter.next().unwrap(); + assert_eq!(fourth.0, &"bar"); + assert_eq!(fourth.1.as_ref().unwrap().0, "\"inQuotes\"".as_bytes()); + + assert!(directive_iter.next().is_none()); + } + + #[test] + fn test_non_ascii() { + let resp = build_response(CACHE_CONTROL, "püblic=💖, max-age=\"💯\""); + let cc = CacheControl::from_resp_headers(&resp).unwrap(); + + // Not considered valid registered directive keys / values + assert!(!cc.public()); + assert_eq!( + cc.max_age().unwrap_err().context.unwrap().to_string(), + "could not parse value as u32" + ); + + let mut directive_iter = cc.directives.iter(); + let first = directive_iter.next().unwrap(); + assert_eq!(first.0, &"püblic"); + assert_eq!(first.1.as_ref().unwrap().0, "💖".as_bytes()); + + let second = directive_iter.next().unwrap(); + assert_eq!(second.0, &"max-age"); + assert_eq!(second.1.as_ref().unwrap().0, "\"💯\"".as_bytes()); + + assert!(directive_iter.next().is_none()); + } + + #[test] + fn test_non_utf8_key() { + let mut resp = response::Builder::new().body(()).unwrap(); + resp.headers_mut().insert( + CACHE_CONTROL, + HeaderValue::from_bytes(b"bar\xFF=\"baz\", a=b").unwrap(), + ); + let (parts, _) = resp.into_parts(); + let cc = CacheControl::from_resp_headers(&parts).unwrap(); + + // invalid bytes for key + let mut directive_iter = cc.directives.iter(); + let first = directive_iter.next().unwrap(); + assert_eq!(first.0, &"a"); + assert_eq!(first.1.as_ref().unwrap().0, "b".as_bytes()); + + assert!(directive_iter.next().is_none()); + } + + #[test] + fn test_non_utf8_value() { + // RFC 7230: 0xFF is part of obs-text and is officially considered a valid octet in quoted-strings + let mut resp = response::Builder::new().body(()).unwrap(); + resp.headers_mut().insert( + CACHE_CONTROL, + HeaderValue::from_bytes(b"max-age=ba\xFFr, bar=\"baz\xFF\", a=b").unwrap(), + ); + let (parts, _) = resp.into_parts(); + let cc = CacheControl::from_resp_headers(&parts).unwrap(); + + assert_eq!( + cc.max_age().unwrap_err().context.unwrap().to_string(), + "could not parse value as utf8" + ); + + let mut directive_iter = cc.directives.iter(); + + let first = directive_iter.next().unwrap(); + assert_eq!(first.0, &"max-age"); + assert_eq!(first.1.as_ref().unwrap().0, b"ba\xFFr"); + + let second = directive_iter.next().unwrap(); + assert_eq!(second.0, &"bar"); + assert_eq!(second.1.as_ref().unwrap().0, b"\"baz\xFF\""); + + let third = directive_iter.next().unwrap(); + assert_eq!(third.0, &"a"); + assert_eq!(third.1.as_ref().unwrap().0, "b".as_bytes()); + + assert!(directive_iter.next().is_none()); + } + + #[test] + fn test_age_overflow() { + let resp = build_response( + CACHE_CONTROL, + "max-age=-99999999999999999999999999, s-maxage=99999999999999999999999999", + ); + let cc = CacheControl::from_resp_headers(&resp).unwrap(); + + assert_eq!( + cc.s_maxage().unwrap().unwrap(), + DELTA_SECONDS_OVERFLOW_VALUE + ); + // negative ages still result in errors even with overflow handling + assert_eq!( + cc.max_age().unwrap_err().context.unwrap().to_string(), + "could not parse value as u32" + ); + } + + #[test] + fn test_fresh_sec() { + let resp = build_response(CACHE_CONTROL, ""); + let cc = CacheControl::from_resp_headers(&resp).unwrap(); + assert!(cc.fresh_sec().is_none()); + + let resp = build_response(CACHE_CONTROL, "max-age=12345"); + let cc = CacheControl::from_resp_headers(&resp).unwrap(); + assert_eq!(cc.fresh_sec().unwrap(), 12345); + + let resp = build_response(CACHE_CONTROL, "max-age=99999,s-maxage=123"); + let cc = CacheControl::from_resp_headers(&resp).unwrap(); + // prefer s-maxage over max-age + assert_eq!(cc.fresh_sec().unwrap(), 123); + } + + #[test] + fn test_cacheability() { + let resp = build_response(CACHE_CONTROL, ""); + let cc = CacheControl::from_resp_headers(&resp).unwrap(); + assert_eq!(cc.is_cacheable(), Cacheable::Default); + + // uncacheable + let resp = build_response(CACHE_CONTROL, "private, max-age=12345"); + let cc = CacheControl::from_resp_headers(&resp).unwrap(); + assert_eq!(cc.is_cacheable(), Cacheable::No); + + let resp = build_response(CACHE_CONTROL, "no-store, max-age=12345"); + let cc = CacheControl::from_resp_headers(&resp).unwrap(); + assert_eq!(cc.is_cacheable(), Cacheable::No); + + // cacheable + let resp = build_response(CACHE_CONTROL, "public"); + let cc = CacheControl::from_resp_headers(&resp).unwrap(); + assert_eq!(cc.is_cacheable(), Cacheable::Yes); + + let resp = build_response(CACHE_CONTROL, "max-age=0"); + let cc = CacheControl::from_resp_headers(&resp).unwrap(); + assert_eq!(cc.is_cacheable(), Cacheable::Yes); + } + + #[test] + fn test_no_cache() { + let resp = build_response(CACHE_CONTROL, "no-cache, max-age=12345"); + let cc = CacheControl::from_resp_headers(&resp).unwrap(); + assert_eq!(cc.is_cacheable(), Cacheable::Yes); + assert_eq!(cc.fresh_sec().unwrap(), 0); + } + + #[test] + fn test_no_cache_field_names() { + let resp = build_response(CACHE_CONTROL, "no-cache=\"set-cookie\", max-age=12345"); + let cc = CacheControl::from_resp_headers(&resp).unwrap(); + assert!(!cc.private()); + assert_eq!(cc.is_cacheable(), Cacheable::Yes); + assert_eq!(cc.fresh_sec().unwrap(), 12345); + let mut field_names = cc.no_cache_field_names().unwrap(); + assert_eq!( + str::from_utf8(field_names.next().unwrap()).unwrap(), + "set-cookie" + ); + assert!(field_names.next().is_none()); + + let mut resp = response::Builder::new().body(()).unwrap(); + resp.headers_mut().insert( + CACHE_CONTROL, + HeaderValue::from_bytes( + b"private=\"\", no-cache=\"a\xFF, set-cookie, Baz\x09 , c,d ,, \"", + ) + .unwrap(), + ); + let (parts, _) = resp.into_parts(); + let cc = CacheControl::from_resp_headers(&parts).unwrap(); + let mut field_names = cc.private_field_names().unwrap(); + assert_eq!(str::from_utf8(field_names.next().unwrap()).unwrap(), ""); + assert!(field_names.next().is_none()); + let mut field_names = cc.no_cache_field_names().unwrap(); + assert!(str::from_utf8(field_names.next().unwrap()).is_err()); + assert_eq!( + str::from_utf8(field_names.next().unwrap()).unwrap(), + "set-cookie" + ); + assert_eq!(str::from_utf8(field_names.next().unwrap()).unwrap(), "Baz"); + assert_eq!(str::from_utf8(field_names.next().unwrap()).unwrap(), "c"); + assert_eq!(str::from_utf8(field_names.next().unwrap()).unwrap(), "d"); + assert_eq!(str::from_utf8(field_names.next().unwrap()).unwrap(), ""); + assert_eq!(str::from_utf8(field_names.next().unwrap()).unwrap(), ""); + assert!(field_names.next().is_none()); + } + + #[test] + fn test_strip_private_headers() { + let mut resp = ResponseHeader::build(200, None).unwrap(); + resp.append_header( + CACHE_CONTROL, + "no-cache=\"x-private-header\", max-age=12345", + ) + .unwrap(); + resp.append_header("X-Private-Header", "dropped").unwrap(); + + let cc = CacheControl::from_resp_headers(&resp).unwrap(); + cc.strip_private_headers(&mut resp); + assert!(!resp.headers.contains_key("X-Private-Header")); + } + + #[test] + fn test_stale_while_revalidate() { + let resp = build_response(CACHE_CONTROL, "max-age=12345, stale-while-revalidate=5"); + let cc = CacheControl::from_resp_headers(&resp).unwrap(); + assert_eq!(cc.stale_while_revalidate().unwrap().unwrap(), 5); + assert_eq!(cc.serve_stale_while_revalidate_sec().unwrap(), 5); + assert!(cc.serve_stale_if_error_sec().is_none()); + } + + #[test] + fn test_stale_if_error() { + let resp = build_response(CACHE_CONTROL, "max-age=12345, stale-if-error=3600"); + let cc = CacheControl::from_resp_headers(&resp).unwrap(); + assert_eq!(cc.stale_if_error().unwrap().unwrap(), 3600); + assert_eq!(cc.serve_stale_if_error_sec().unwrap(), 3600); + assert!(cc.serve_stale_while_revalidate_sec().is_none()); + } + + #[test] + fn test_must_revalidate() { + let resp = build_response( + CACHE_CONTROL, + "max-age=12345, stale-while-revalidate=60, stale-if-error=30, must-revalidate", + ); + let cc = CacheControl::from_resp_headers(&resp).unwrap(); + assert!(cc.must_revalidate()); + assert_eq!(cc.stale_while_revalidate().unwrap().unwrap(), 60); + assert_eq!(cc.stale_if_error().unwrap().unwrap(), 30); + assert_eq!(cc.serve_stale_while_revalidate_sec().unwrap(), 0); + assert_eq!(cc.serve_stale_if_error_sec().unwrap(), 0); + } + + #[test] + fn test_proxy_revalidate() { + let resp = build_response( + CACHE_CONTROL, + "max-age=12345, stale-while-revalidate=60, stale-if-error=30, proxy-revalidate", + ); + let cc = CacheControl::from_resp_headers(&resp).unwrap(); + assert!(cc.proxy_revalidate()); + assert_eq!(cc.stale_while_revalidate().unwrap().unwrap(), 60); + assert_eq!(cc.stale_if_error().unwrap().unwrap(), 30); + assert_eq!(cc.serve_stale_while_revalidate_sec().unwrap(), 0); + assert_eq!(cc.serve_stale_if_error_sec().unwrap(), 0); + } + + #[test] + fn test_s_maxage_stale() { + let resp = build_response( + CACHE_CONTROL, + "s-maxage=0, stale-while-revalidate=60, stale-if-error=30", + ); + let cc = CacheControl::from_resp_headers(&resp).unwrap(); + assert_eq!(cc.stale_while_revalidate().unwrap().unwrap(), 60); + assert_eq!(cc.stale_if_error().unwrap().unwrap(), 30); + assert_eq!(cc.serve_stale_while_revalidate_sec().unwrap(), 0); + assert_eq!(cc.serve_stale_if_error_sec().unwrap(), 0); + } + + #[test] + fn test_authorized_request() { + let resp = build_response(CACHE_CONTROL, "max-age=10"); + let cc = CacheControl::from_resp_headers(&resp).unwrap(); + assert!(!cc.allow_caching_authorized_req()); + + let resp = build_response(CACHE_CONTROL, "s-maxage=10"); + let cc = CacheControl::from_resp_headers(&resp).unwrap(); + assert!(cc.allow_caching_authorized_req()); + + let resp = build_response(CACHE_CONTROL, "public"); + let cc = CacheControl::from_resp_headers(&resp).unwrap(); + assert!(cc.allow_caching_authorized_req()); + + let resp = build_response(CACHE_CONTROL, "must-revalidate, max-age=0"); + let cc = CacheControl::from_resp_headers(&resp).unwrap(); + assert!(cc.allow_caching_authorized_req()); + + let resp = build_response(CACHE_CONTROL, ""); + let cc = CacheControl::from_resp_headers(&resp).unwrap(); + assert!(!cc.allow_caching_authorized_req()); + } + + fn build_request(cc_key: HeaderName, cc_value: &str) -> request::Parts { + let (parts, _) = request::Builder::new() + .header(cc_key, cc_value) + .body(()) + .unwrap() + .into_parts(); + parts + } + + #[test] + fn test_request_only_if_cached() { + let req = build_request(CACHE_CONTROL, "only-if-cached=1"); + let cc = CacheControl::from_req_headers(&req).unwrap(); + assert!(cc.only_if_cached()) + } +} diff --git a/pingora-cache/src/eviction/lru.rs b/pingora-cache/src/eviction/lru.rs new file mode 100644 index 0000000..47c88a6 --- /dev/null +++ b/pingora-cache/src/eviction/lru.rs @@ -0,0 +1,431 @@ +// 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. + +//! A shared LRU cache manager + +use super::EvictionManager; +use crate::key::CompactCacheKey; + +use async_trait::async_trait; +use pingora_error::{BError, ErrorType::*, OrErr, Result}; +use pingora_lru::Lru; +use serde::de::SeqAccess; +use serde::{Deserialize, Serialize}; +use std::fs::File; +use std::hash::{Hash, Hasher}; +use std::io::prelude::*; +use std::path::Path; +use std::time::SystemTime; + +/// A shared LRU cache manager designed to manage a large volume of assets. +/// +/// - Space optimized in-memory LRU (see [pingora_lru]). +/// - Instead of a single giant LRU, this struct shards the assets into `N` independent LRUs. +/// This allows [EvictionManager::save()] not to lock the entire cache mananger while performing +/// serialization. +pub struct Manager(Lru); + +#[derive(Debug, Serialize, Deserialize)] +struct SerdeHelperNode(CompactCacheKey, usize); + +impl Manager { + /// Create a [Manager] with the given size limit and estimated per shard capacity. + /// + /// The `capacity` is for preallocating to avoid reallocation cost when the LRU grows. + pub fn with_capacity(limit: usize, capacity: usize) -> Self { + Manager(Lru::with_capacity(limit, capacity)) + } + + /// Serialize the given shard + pub fn serialize_shard(&self, shard: usize) -> Result> { + use rmp_serde::encode::Serializer; + use serde::ser::SerializeSeq; + use serde::ser::Serializer as _; + + assert!(shard < N); + + // NOTE: This could use a lot memory to buffer the serialized data in memory + // NOTE: This for loop could lock the LRU for too long + let mut nodes = Vec::with_capacity(self.0.shard_len(shard)); + self.0.iter_for_each(shard, |(node, size)| { + nodes.push(SerdeHelperNode(node.clone(), size)); + }); + let mut ser = Serializer::new(vec![]); + let mut seq = ser + .serialize_seq(Some(self.0.shard_len(shard))) + .or_err(InternalError, "fail to serialize node")?; + for node in nodes { + seq.serialize_element(&node).unwrap(); // write to vec, safe + } + + seq.end().or_err(InternalError, "when serializing LRU")?; + Ok(ser.into_inner()) + } + + /// Deserialize a shard + /// + /// Shard number is not needed because the key itself will hash to the correct shard. + pub fn deserialize_shard(&self, buf: &[u8]) -> Result<()> { + use rmp_serde::decode::Deserializer; + use serde::de::Deserializer as _; + + let mut de = Deserializer::new(buf); + let visitor = InsertToManager { lru: self }; + de.deserialize_seq(visitor) + .or_err(InternalError, "when deserializing LRU")?; + Ok(()) + } +} + +struct InsertToManager<'a, const N: usize> { + lru: &'a Manager, +} + +impl<'de, 'a, const N: usize> serde::de::Visitor<'de> for InsertToManager<'a, N> { + type Value = (); + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("array of lru nodes") + } + + fn visit_seq(self, mut seq: A) -> Result + where + A: SeqAccess<'de>, + { + while let Some(node) = seq.next_element::()? { + let key = u64key(&node.0); + self.lru.0.insert_tail(key, node.0, node.1); // insert in the back + } + Ok(()) + } +} + +#[inline] +fn u64key(key: &CompactCacheKey) -> u64 { + // note that std hash is not uniform, I'm not sure if ahash is also the case + let mut hasher = ahash::AHasher::default(); + key.hash(&mut hasher); + hasher.finish() +} + +const FILE_NAME: &str = "lru.data"; + +#[inline] +fn err_str_path(s: &str, path: &Path) -> String { + format!("{s} {}", path.display()) +} + +#[async_trait] +impl EvictionManager for Manager { + fn total_size(&self) -> usize { + self.0.weight() + } + fn total_items(&self) -> usize { + self.0.len() + } + fn evicted_size(&self) -> usize { + self.0.evicted_weight() + } + fn evicted_items(&self) -> usize { + self.0.evicted_len() + } + + fn admit( + &self, + item: CompactCacheKey, + size: usize, + _fresh_until: SystemTime, + ) -> Vec { + let key = u64key(&item); + self.0.admit(key, item, size); + self.0 + .evict_to_limit() + .into_iter() + .map(|(key, _weight)| key) + .collect() + } + + fn remove(&self, item: &CompactCacheKey) { + let key = u64key(item); + self.0.remove(key); + } + + fn access(&self, item: &CompactCacheKey, size: usize, _fresh_until: SystemTime) -> bool { + let key = u64key(item); + if !self.0.promote(key) { + self.0.admit(key, item.clone(), size); + false + } else { + true + } + } + + fn peek(&self, item: &CompactCacheKey) -> bool { + let key = u64key(item); + self.0.peek(key) + } + + async fn save(&self, dir_path: &str) -> Result<()> { + let dir_path_str = dir_path.to_owned(); + + tokio::task::spawn_blocking(move || { + let dir_path = Path::new(&dir_path_str); + std::fs::create_dir_all(dir_path) + .or_err_with(InternalError, || err_str_path("fail to create", dir_path)) + }) + .await + .or_err(InternalError, "async blocking IO failure")??; + + for i in 0..N { + let data = self.serialize_shard(i)?; + let dir_path = dir_path.to_owned(); + tokio::task::spawn_blocking(move || { + let file_path = Path::new(&dir_path).join(format!("{}.{i}", FILE_NAME)); + let mut file = File::create(&file_path) + .or_err_with(InternalError, || err_str_path("fail to create", &file_path))?; + file.write_all(&data).or_err_with(InternalError, || { + err_str_path("fail to write to", &file_path) + }) + }) + .await + .or_err(InternalError, "async blocking IO failure")??; + } + Ok(()) + } + + async fn load(&self, dir_path: &str) -> Result<()> { + // TODO: check the saved shards so that we load all the save files + for i in 0..N { + let dir_path = dir_path.to_owned(); + + let data = tokio::task::spawn_blocking(move || { + let file_path = Path::new(&dir_path).join(format!("{}.{i}", FILE_NAME)); + let mut file = File::open(&file_path) + .or_err_with(InternalError, || err_str_path("fail to open", &file_path))?; + let mut buffer = Vec::with_capacity(8192); + file.read_to_end(&mut buffer) + .or_err_with(InternalError, || { + err_str_path("fail to write to", &file_path) + })?; + Ok::, BError>(buffer) + }) + .await + .or_err(InternalError, "async blocking IO failure")??; + self.deserialize_shard(&data)?; + } + + Ok(()) + } +} + +#[cfg(test)] +mod test { + use super::*; + use crate::CacheKey; + use EvictionManager; + + // we use shard (N) = 1 for eviction consistency in all tests + + #[test] + fn test_admission() { + let lru = Manager::<1>::with_capacity(4, 10); + let key1 = CacheKey::new("", "a", "1").to_compact(); + let until = SystemTime::now(); // unused value as a placeholder + let v = lru.admit(key1.clone(), 1, until); + assert_eq!(v.len(), 0); + let key2 = CacheKey::new("", "b", "1").to_compact(); + let v = lru.admit(key2.clone(), 2, until); + assert_eq!(v.len(), 0); + let key3 = CacheKey::new("", "c", "1").to_compact(); + let v = lru.admit(key3, 1, until); + assert_eq!(v.len(), 0); + + // lru si full (4) now + + let key4 = CacheKey::new("", "d", "1").to_compact(); + let v = lru.admit(key4, 2, until); + // need to reduce used by at least 2, both key1 and key2 are evicted to make room for 3 + assert_eq!(v.len(), 2); + assert_eq!(v[0], key1); + assert_eq!(v[1], key2); + } + + #[test] + fn test_access() { + let lru = Manager::<1>::with_capacity(4, 10); + let key1 = CacheKey::new("", "a", "1").to_compact(); + let until = SystemTime::now(); // unused value as a placeholder + let v = lru.admit(key1.clone(), 1, until); + assert_eq!(v.len(), 0); + let key2 = CacheKey::new("", "b", "1").to_compact(); + let v = lru.admit(key2.clone(), 2, until); + assert_eq!(v.len(), 0); + let key3 = CacheKey::new("", "c", "1").to_compact(); + let v = lru.admit(key3, 1, until); + assert_eq!(v.len(), 0); + + // lru is full (4) now + // make key1 most recently used + lru.access(&key1, 1, until); + assert_eq!(v.len(), 0); + + let key4 = CacheKey::new("", "d", "1").to_compact(); + let v = lru.admit(key4, 2, until); + assert_eq!(v.len(), 1); + assert_eq!(v[0], key2); + } + + #[test] + fn test_remove() { + let lru = Manager::<1>::with_capacity(4, 10); + let key1 = CacheKey::new("", "a", "1").to_compact(); + let until = SystemTime::now(); // unused value as a placeholder + let v = lru.admit(key1.clone(), 1, until); + assert_eq!(v.len(), 0); + let key2 = CacheKey::new("", "b", "1").to_compact(); + let v = lru.admit(key2.clone(), 2, until); + assert_eq!(v.len(), 0); + let key3 = CacheKey::new("", "c", "1").to_compact(); + let v = lru.admit(key3, 1, until); + assert_eq!(v.len(), 0); + + // lru is full (4) now + // remove key1 + lru.remove(&key1); + + // key2 is the least recently used one now + let key4 = CacheKey::new("", "d", "1").to_compact(); + let v = lru.admit(key4, 2, until); + assert_eq!(v.len(), 1); + assert_eq!(v[0], key2); + } + + #[test] + fn test_access_add() { + let lru = Manager::<1>::with_capacity(4, 10); + let until = SystemTime::now(); // unused value as a placeholder + + let key1 = CacheKey::new("", "a", "1").to_compact(); + lru.access(&key1, 1, until); + let key2 = CacheKey::new("", "b", "1").to_compact(); + lru.access(&key2, 2, until); + let key3 = CacheKey::new("", "c", "1").to_compact(); + lru.access(&key3, 2, until); + + let key4 = CacheKey::new("", "d", "1").to_compact(); + let v = lru.admit(key4, 2, until); + // need to reduce used by at least 2, both key1 and key2 are evicted to make room for 3 + assert_eq!(v.len(), 2); + assert_eq!(v[0], key1); + assert_eq!(v[1], key2); + } + + #[test] + fn test_admit_update() { + let lru = Manager::<1>::with_capacity(4, 10); + let key1 = CacheKey::new("", "a", "1").to_compact(); + let until = SystemTime::now(); // unused value as a placeholder + let v = lru.admit(key1.clone(), 1, until); + assert_eq!(v.len(), 0); + let key2 = CacheKey::new("", "b", "1").to_compact(); + let v = lru.admit(key2.clone(), 2, until); + assert_eq!(v.len(), 0); + let key3 = CacheKey::new("", "c", "1").to_compact(); + let v = lru.admit(key3, 1, until); + assert_eq!(v.len(), 0); + + // lru is full (4) now + // update key2 to reduce its size by 1 + let v = lru.admit(key2, 1, until); + assert_eq!(v.len(), 0); + + // lru is not full anymore + let key4 = CacheKey::new("", "d", "1").to_compact(); + let v = lru.admit(key4.clone(), 1, until); + assert_eq!(v.len(), 0); + + // make key4 larger + let v = lru.admit(key4, 2, until); + // need to evict now + assert_eq!(v.len(), 1); + assert_eq!(v[0], key1); + } + + #[test] + fn test_peek() { + let lru = Manager::<1>::with_capacity(4, 10); + let until = SystemTime::now(); // unused value as a placeholder + + let key1 = CacheKey::new("", "a", "1").to_compact(); + lru.access(&key1, 1, until); + let key2 = CacheKey::new("", "b", "1").to_compact(); + lru.access(&key2, 2, until); + assert!(lru.peek(&key1)); + assert!(lru.peek(&key2)); + } + + #[test] + fn test_serde() { + let lru = Manager::<1>::with_capacity(4, 10); + let key1 = CacheKey::new("", "a", "1").to_compact(); + let until = SystemTime::now(); // unused value as a placeholder + let v = lru.admit(key1.clone(), 1, until); + assert_eq!(v.len(), 0); + let key2 = CacheKey::new("", "b", "1").to_compact(); + let v = lru.admit(key2.clone(), 2, until); + assert_eq!(v.len(), 0); + let key3 = CacheKey::new("", "c", "1").to_compact(); + let v = lru.admit(key3, 1, until); + assert_eq!(v.len(), 0); + + // lru is full (4) now + // make key1 most recently used + lru.access(&key1, 1, until); + assert_eq!(v.len(), 0); + + // load lru2 with lru's data + let ser = lru.serialize_shard(0).unwrap(); + let lru2 = Manager::<1>::with_capacity(4, 10); + lru2.deserialize_shard(&ser).unwrap(); + + let key4 = CacheKey::new("", "d", "1").to_compact(); + let v = lru2.admit(key4, 2, until); + assert_eq!(v.len(), 1); + assert_eq!(v[0], key2); + } + + #[tokio::test] + async fn test_save_to_disk() { + let until = SystemTime::now(); // unused value as a placeholder + let lru = Manager::<2>::with_capacity(10, 10); + + lru.admit(CacheKey::new("", "a", "1").to_compact(), 1, until); + lru.admit(CacheKey::new("", "b", "1").to_compact(), 2, until); + lru.admit(CacheKey::new("", "c", "1").to_compact(), 1, until); + lru.admit(CacheKey::new("", "d", "1").to_compact(), 1, until); + lru.admit(CacheKey::new("", "e", "1").to_compact(), 2, until); + lru.admit(CacheKey::new("", "f", "1").to_compact(), 1, until); + + // load lru2 with lru's data + lru.save("/tmp/test_lru_save").await.unwrap(); + let lru2 = Manager::<2>::with_capacity(4, 10); + lru2.load("/tmp/test_lru_save").await.unwrap(); + + let ser0 = lru.serialize_shard(0).unwrap(); + let ser1 = lru.serialize_shard(1).unwrap(); + + assert_eq!(ser0, lru2.serialize_shard(0).unwrap()); + assert_eq!(ser1, lru2.serialize_shard(1).unwrap()); + } +} diff --git a/pingora-cache/src/eviction/mod.rs b/pingora-cache/src/eviction/mod.rs new file mode 100644 index 0000000..7c9d60b --- /dev/null +++ b/pingora-cache/src/eviction/mod.rs @@ -0,0 +1,89 @@ +// 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. + +//! Cache eviction module + +use crate::key::CompactCacheKey; + +use async_trait::async_trait; +use pingora_error::Result; +use std::time::SystemTime; + +pub mod lru; +pub mod simple_lru; + +/// The trait that a cache eviction algorithm needs to implement +/// +/// NOTE: these trait methods require &self not &mut self, which means concurrency should +/// be handled the implementations internally. +#[async_trait] +pub trait EvictionManager { + /// Total size of the cache in bytes tracked by this eviction mananger + fn total_size(&self) -> usize; + /// Number of assets tracked by this eviction mananger + fn total_items(&self) -> usize; + /// Number of bytes that are already evicted + /// + /// The accumulated number is returned to play well with Prometheus counter metric type. + fn evicted_size(&self) -> usize; + /// Number of assets that are already evicted + /// + /// The accumulated number is returned to play well with Prometheus counter metric type. + fn evicted_items(&self) -> usize; + + /// Admit an item + /// + /// Return one or more items to evict. The sizes of these items are deducted + /// from the total size already. The caller needs to make sure that these assets are actually + /// removed from the storage. + /// + /// If the item is already admitted, A. update its freshness; B. if the new size is larger than the + /// existing one, Some(_) might be returned for the caller to evict. + fn admit( + &self, + item: CompactCacheKey, + size: usize, + fresh_until: SystemTime, + ) -> Vec; + + /// Remove an item from the eviction manager. + /// + /// The size of the item will be deducted. + fn remove(&self, item: &CompactCacheKey); + + /// Access an item that should already be in cache. + /// + /// If the item is not tracked by this [EvictionManager], track it but no eviction will happen. + /// + /// The call used for asking the eviction manager to track the assets that are already admitted + /// in the cache storage system. + fn access(&self, item: &CompactCacheKey, size: usize, fresh_until: SystemTime) -> bool; + + /// Peek into the manager to see if the item is already tracked by the system + /// + /// This function should have no side-effect on the asset itself. For example, for LRU, this + /// method shouldn't change the popularity of the asset being peeked. + fn peek(&self, item: &CompactCacheKey) -> bool; + + /// Serialize to save the state of this eviction mananger to disk + /// + /// This function is for preserving the eviction manager's state across server restarts. + /// + /// `dir_path` define the directory on disk that the data should use. + // dir_path is &str no AsRef so that trait objects can be used + async fn save(&self, dir_path: &str) -> Result<()>; + + /// The counterpart of [Self::save()]. + async fn load(&self, dir_path: &str) -> Result<()>; +} diff --git a/pingora-cache/src/eviction/simple_lru.rs b/pingora-cache/src/eviction/simple_lru.rs new file mode 100644 index 0000000..73efb85 --- /dev/null +++ b/pingora-cache/src/eviction/simple_lru.rs @@ -0,0 +1,445 @@ +// 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. + +//! A simple LRU cache manager built on top of the `lru` crate + +use super::EvictionManager; +use crate::key::CompactCacheKey; + +use async_trait::async_trait; +use lru::LruCache; +use parking_lot::RwLock; +use pingora_error::{BError, ErrorType::*, OrErr, Result}; +use serde::de::SeqAccess; +use serde::{Deserialize, Serialize}; +use std::collections::hash_map::DefaultHasher; +use std::fs::File; +use std::hash::{Hash, Hasher}; +use std::io::prelude::*; +use std::path::Path; +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::time::SystemTime; + +#[derive(Debug, Deserialize, Serialize)] +struct Node { + key: CompactCacheKey, + size: usize, +} + +/// A simple LRU eviction manager +/// +/// The implementation is not optimized. All operation require global locks. +pub struct Manager { + lru: RwLock>, + limit: usize, + used: AtomicUsize, + items: AtomicUsize, + evicted_size: AtomicUsize, + evicted_items: AtomicUsize, +} + +impl Manager { + /// Create a new [Manager] with the given total size limit `limit`. + pub fn new(limit: usize) -> Self { + Manager { + lru: RwLock::new(LruCache::unbounded()), + limit, + used: AtomicUsize::new(0), + items: AtomicUsize::new(0), + evicted_size: AtomicUsize::new(0), + evicted_items: AtomicUsize::new(0), + } + } + + fn insert(&self, hash_key: u64, node: CompactCacheKey, size: usize, reverse: bool) { + use std::cmp::Ordering::*; + let node = Node { key: node, size }; + let old = { + let mut lru = self.lru.write(); + let old = lru.push(hash_key, node); + if reverse && old.is_none() { + lru.demote(&hash_key); + } + old + }; + if let Some(old) = old { + // replacing a node, just need to update used size + match size.cmp(&old.1.size) { + Greater => self.used.fetch_add(size - old.1.size, Ordering::Relaxed), + Less => self.used.fetch_sub(old.1.size - size, Ordering::Relaxed), + Equal => 0, // same size, update nothing, use 0 to match other arms' type + }; + } else { + self.used.fetch_add(size, Ordering::Relaxed); + self.items.fetch_add(1, Ordering::Relaxed); + } + } + + // evict items until the used capacity is below limit + fn evict(&self) -> Vec { + if self.used.load(Ordering::Relaxed) <= self.limit { + return vec![]; + } + let mut to_evict = Vec::with_capacity(1); // we will at least pop 1 item + while self.used.load(Ordering::Relaxed) > self.limit { + if let Some((_, node)) = self.lru.write().pop_lru() { + self.used.fetch_sub(node.size, Ordering::Relaxed); + self.items.fetch_sub(1, Ordering::Relaxed); + self.evicted_size.fetch_add(node.size, Ordering::Relaxed); + self.evicted_items.fetch_add(1, Ordering::Relaxed); + to_evict.push(node.key); + } else { + // lru empty + return to_evict; + } + } + to_evict + } + + // This could use a lot memory to buffer the serialized data in memory and could lock the LRU + // for too long + fn serialize(&self) -> Result> { + use rmp_serde::encode::Serializer; + use serde::ser::SerializeSeq; + use serde::ser::Serializer as _; + // NOTE: This could use a lot memory to buffer the serialized data in memory + let mut ser = Serializer::new(vec![]); + // NOTE: This long for loop could lock the LRU for too long + let lru = self.lru.read(); + let mut seq = ser + .serialize_seq(Some(lru.len())) + .or_err(InternalError, "fail to serialize node")?; + for item in lru.iter() { + seq.serialize_element(item.1).unwrap(); // write to vec, safe + } + seq.end().or_err(InternalError, "when serializing LRU")?; + Ok(ser.into_inner()) + } + + fn deserialize(&self, buf: &[u8]) -> Result<()> { + use rmp_serde::decode::Deserializer; + use serde::de::Deserializer as _; + let mut de = Deserializer::new(buf); + let visitor = InsertToManager { lru: self }; + de.deserialize_seq(visitor) + .or_err(InternalError, "when deserializing LRU")?; + Ok(()) + } +} + +struct InsertToManager<'a> { + lru: &'a Manager, +} + +impl<'de, 'a> serde::de::Visitor<'de> for InsertToManager<'a> { + type Value = (); + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("array of lru nodes") + } + + fn visit_seq(self, mut seq: A) -> Result + where + A: SeqAccess<'de>, + { + while let Some(node) = seq.next_element::()? { + let key = u64key(&node.key); + self.lru.insert(key, node.key, node.size, true); // insert in the back + } + Ok(()) + } +} + +#[inline] +fn u64key(key: &CompactCacheKey) -> u64 { + let mut hasher = DefaultHasher::new(); + key.hash(&mut hasher); + hasher.finish() +} + +const FILE_NAME: &str = "simple_lru.data"; + +#[async_trait] +impl EvictionManager for Manager { + fn total_size(&self) -> usize { + self.used.load(Ordering::Relaxed) + } + fn total_items(&self) -> usize { + self.items.load(Ordering::Relaxed) + } + fn evicted_size(&self) -> usize { + self.evicted_size.load(Ordering::Relaxed) + } + fn evicted_items(&self) -> usize { + self.evicted_items.load(Ordering::Relaxed) + } + + fn admit( + &self, + item: CompactCacheKey, + size: usize, + _fresh_until: SystemTime, + ) -> Vec { + let key = u64key(&item); + self.insert(key, item, size, false); + self.evict() + } + + fn remove(&self, item: &CompactCacheKey) { + let key = u64key(item); + let node = self.lru.write().pop(&key); + if let Some(n) = node { + self.used.fetch_sub(n.size, Ordering::Relaxed); + self.items.fetch_sub(1, Ordering::Relaxed); + } + } + + fn access(&self, item: &CompactCacheKey, size: usize, _fresh_until: SystemTime) -> bool { + let key = u64key(item); + if self.lru.write().get(&key).is_none() { + self.insert(key, item.clone(), size, false); + false + } else { + true + } + } + + fn peek(&self, item: &CompactCacheKey) -> bool { + let key = u64key(item); + self.lru.read().peek(&key).is_some() + } + + async fn save(&self, dir_path: &str) -> Result<()> { + let data = self.serialize()?; + let dir_path = dir_path.to_owned(); + tokio::task::spawn_blocking(move || { + let dir_path = Path::new(&dir_path); + std::fs::create_dir_all(dir_path).or_err(InternalError, "fail to create {dir_path}")?; + let file_path = dir_path.join(FILE_NAME); + let mut file = + File::create(file_path).or_err(InternalError, "fail to create {file_path}")?; + file.write_all(&data) + .or_err(InternalError, "fail to write to {file_path}") + }) + .await + .or_err(InternalError, "async blocking IO failure")? + } + + async fn load(&self, dir_path: &str) -> Result<()> { + let dir_path = dir_path.to_owned(); + let data = tokio::task::spawn_blocking(move || { + let file_path = Path::new(&dir_path).join(FILE_NAME); + let mut file = + File::open(file_path).or_err(InternalError, "fail to open {file_path}")?; + let mut buffer = Vec::with_capacity(8192); + file.read_to_end(&mut buffer) + .or_err(InternalError, "fail to write to {file_path}")?; + Ok::, BError>(buffer) + }) + .await + .or_err(InternalError, "async blocking IO failure")??; + self.deserialize(&data) + } +} + +#[cfg(test)] +mod test { + use super::*; + use crate::CacheKey; + + #[test] + fn test_admission() { + let lru = Manager::new(4); + let key1 = CacheKey::new("", "a", "1").to_compact(); + let until = SystemTime::now(); // unused value as a placeholder + let v = lru.admit(key1.clone(), 1, until); + assert_eq!(v.len(), 0); + let key2 = CacheKey::new("", "b", "1").to_compact(); + let v = lru.admit(key2.clone(), 2, until); + assert_eq!(v.len(), 0); + let key3 = CacheKey::new("", "c", "1").to_compact(); + let v = lru.admit(key3, 1, until); + assert_eq!(v.len(), 0); + + // lru si full (4) now + + let key4 = CacheKey::new("", "d", "1").to_compact(); + let v = lru.admit(key4, 2, until); + // need to reduce used by at least 2, both key1 and key2 are evicted to make room for 3 + assert_eq!(v.len(), 2); + assert_eq!(v[0], key1); + assert_eq!(v[1], key2); + } + + #[test] + fn test_access() { + let lru = Manager::new(4); + let key1 = CacheKey::new("", "a", "1").to_compact(); + let until = SystemTime::now(); // unused value as a placeholder + let v = lru.admit(key1.clone(), 1, until); + assert_eq!(v.len(), 0); + let key2 = CacheKey::new("", "b", "1").to_compact(); + let v = lru.admit(key2.clone(), 2, until); + assert_eq!(v.len(), 0); + let key3 = CacheKey::new("", "c", "1").to_compact(); + let v = lru.admit(key3, 1, until); + assert_eq!(v.len(), 0); + + // lru is full (4) now + // make key1 most recently used + lru.access(&key1, 1, until); + assert_eq!(v.len(), 0); + + let key4 = CacheKey::new("", "d", "1").to_compact(); + let v = lru.admit(key4, 2, until); + assert_eq!(v.len(), 1); + assert_eq!(v[0], key2); + } + + #[test] + fn test_remove() { + let lru = Manager::new(4); + let key1 = CacheKey::new("", "a", "1").to_compact(); + let until = SystemTime::now(); // unused value as a placeholder + let v = lru.admit(key1.clone(), 1, until); + assert_eq!(v.len(), 0); + let key2 = CacheKey::new("", "b", "1").to_compact(); + let v = lru.admit(key2.clone(), 2, until); + assert_eq!(v.len(), 0); + let key3 = CacheKey::new("", "c", "1").to_compact(); + let v = lru.admit(key3, 1, until); + assert_eq!(v.len(), 0); + + // lru is full (4) now + // remove key1 + lru.remove(&key1); + + // key2 is the least recently used one now + let key4 = CacheKey::new("", "d", "1").to_compact(); + let v = lru.admit(key4, 2, until); + assert_eq!(v.len(), 1); + assert_eq!(v[0], key2); + } + + #[test] + fn test_access_add() { + let lru = Manager::new(4); + let until = SystemTime::now(); // unused value as a placeholder + + let key1 = CacheKey::new("", "a", "1").to_compact(); + lru.access(&key1, 1, until); + let key2 = CacheKey::new("", "b", "1").to_compact(); + lru.access(&key2, 2, until); + let key3 = CacheKey::new("", "c", "1").to_compact(); + lru.access(&key3, 2, until); + + let key4 = CacheKey::new("", "d", "1").to_compact(); + let v = lru.admit(key4, 2, until); + // need to reduce used by at least 2, both key1 and key2 are evicted to make room for 3 + assert_eq!(v.len(), 2); + assert_eq!(v[0], key1); + assert_eq!(v[1], key2); + } + + #[test] + fn test_admit_update() { + let lru = Manager::new(4); + let key1 = CacheKey::new("", "a", "1").to_compact(); + let until = SystemTime::now(); // unused value as a placeholder + let v = lru.admit(key1.clone(), 1, until); + assert_eq!(v.len(), 0); + let key2 = CacheKey::new("", "b", "1").to_compact(); + let v = lru.admit(key2.clone(), 2, until); + assert_eq!(v.len(), 0); + let key3 = CacheKey::new("", "c", "1").to_compact(); + let v = lru.admit(key3, 1, until); + assert_eq!(v.len(), 0); + + // lru is full (4) now + // update key2 to reduce its size by 1 + let v = lru.admit(key2, 1, until); + assert_eq!(v.len(), 0); + + // lru is not full anymore + let key4 = CacheKey::new("", "d", "1").to_compact(); + let v = lru.admit(key4.clone(), 1, until); + assert_eq!(v.len(), 0); + + // make key4 larger + let v = lru.admit(key4, 2, until); + // need to evict now + assert_eq!(v.len(), 1); + assert_eq!(v[0], key1); + } + + #[test] + fn test_serde() { + let lru = Manager::new(4); + let key1 = CacheKey::new("", "a", "1").to_compact(); + let until = SystemTime::now(); // unused value as a placeholder + let v = lru.admit(key1.clone(), 1, until); + assert_eq!(v.len(), 0); + let key2 = CacheKey::new("", "b", "1").to_compact(); + let v = lru.admit(key2.clone(), 2, until); + assert_eq!(v.len(), 0); + let key3 = CacheKey::new("", "c", "1").to_compact(); + let v = lru.admit(key3, 1, until); + assert_eq!(v.len(), 0); + + // lru is full (4) now + // make key1 most recently used + lru.access(&key1, 1, until); + assert_eq!(v.len(), 0); + + // load lru2 with lru's data + let ser = lru.serialize().unwrap(); + let lru2 = Manager::new(4); + lru2.deserialize(&ser).unwrap(); + + let key4 = CacheKey::new("", "d", "1").to_compact(); + let v = lru2.admit(key4, 2, until); + assert_eq!(v.len(), 1); + assert_eq!(v[0], key2); + } + + #[tokio::test] + async fn test_save_to_disk() { + let lru = Manager::new(4); + let key1 = CacheKey::new("", "a", "1").to_compact(); + let until = SystemTime::now(); // unused value as a placeholder + let v = lru.admit(key1.clone(), 1, until); + assert_eq!(v.len(), 0); + let key2 = CacheKey::new("", "b", "1").to_compact(); + let v = lru.admit(key2.clone(), 2, until); + assert_eq!(v.len(), 0); + let key3 = CacheKey::new("", "c", "1").to_compact(); + let v = lru.admit(key3, 1, until); + assert_eq!(v.len(), 0); + + // lru is full (4) now + // make key1 most recently used + lru.access(&key1, 1, until); + assert_eq!(v.len(), 0); + + // load lru2 with lru's data + lru.save("/tmp/test_simple_lru_save").await.unwrap(); + let lru2 = Manager::new(4); + lru2.load("/tmp/test_simple_lru_save").await.unwrap(); + + let key4 = CacheKey::new("", "d", "1").to_compact(); + let v = lru2.admit(key4, 2, until); + assert_eq!(v.len(), 1); + assert_eq!(v[0], key2); + } +} diff --git a/pingora-cache/src/filters.rs b/pingora-cache/src/filters.rs new file mode 100644 index 0000000..8293cb5 --- /dev/null +++ b/pingora-cache/src/filters.rs @@ -0,0 +1,673 @@ +// 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. + +//! Utility functions to help process HTTP headers for caching + +use super::*; +use crate::cache_control::{CacheControl, Cacheable, InterpretCacheControl}; +use crate::{RespCacheable, RespCacheable::*}; + +use http::{header, HeaderValue}; +use httpdate::HttpDate; +use log::warn; +use pingora_http::{RequestHeader, ResponseHeader}; + +/// Decide if the request can be cacheable +pub fn request_cacheable(req_header: &ReqHeader) -> bool { + // TODO: the check is incomplete + matches!(req_header.method, Method::GET | Method::HEAD) +} + +/// Decide if the response is cacheable. +/// +/// `cache_control` is the parsed [CacheControl] from the response header. It is an standalone +/// argument so that caller has the flexibility to choose to use, change or ignore it. +// TODO: vary processing +pub fn resp_cacheable( + cache_control: Option<&CacheControl>, + resp_header: &ResponseHeader, + authorization_present: bool, + defaults: &CacheMetaDefaults, +) -> RespCacheable { + let now = SystemTime::now(); + let expire_time = calculate_fresh_until( + now, + cache_control, + resp_header, + authorization_present, + defaults, + ); + if let Some(fresh_until) = expire_time { + let (stale_while_revalidate_sec, stale_if_error_sec) = + calculate_serve_stale_sec(cache_control, defaults); + + let mut cloned_header = resp_header.clone(); + if let Some(cc) = cache_control { + cc.strip_private_headers(&mut cloned_header); + } + return Cacheable(CacheMeta::new( + fresh_until, + now, + stale_while_revalidate_sec, + stale_if_error_sec, + cloned_header, + )); + } + Uncacheable(NoCacheReason::OriginNotCache) +} + +/// Calculate the [SystemTime] at which the asset expires +/// +/// Return None when not cacheable. +pub fn calculate_fresh_until( + now: SystemTime, + cache_control: Option<&CacheControl>, + resp_header: &RespHeader, + authorization_present: bool, + defaults: &CacheMetaDefaults, +) -> Option { + fn freshness_ttl_to_time(now: SystemTime, fresh_sec: u32) -> Option { + if fresh_sec == 0 { + // ensure that the response is treated as stale + now.checked_sub(Duration::from_secs(1)) + } else { + now.checked_add(Duration::from_secs(fresh_sec.into())) + } + } + + // A request with Authorization is normally not cacheable, unless Cache-Control allows it + if authorization_present { + let uncacheable = cache_control + .as_ref() + .map_or(true, |cc| !cc.allow_caching_authorized_req()); + if uncacheable { + return None; + } + } + + let uncacheable = cache_control + .as_ref() + .map_or(false, |cc| cc.is_cacheable() == Cacheable::No); + if uncacheable { + return None; + } + + // For TTL check cache-control first, then expires header, then defaults + cache_control + .and_then(|cc| { + cc.fresh_sec() + .and_then(|ttl| freshness_ttl_to_time(now, ttl)) + }) + .or_else(|| calculate_expires_header_time(resp_header)) + .or_else(|| { + defaults + .fresh_sec(resp_header.status) + .and_then(|ttl| freshness_ttl_to_time(now, ttl)) + }) +} + +/// Calculate the expire time from the `Expires` header only +pub fn calculate_expires_header_time(resp_header: &RespHeader) -> Option { + // according to RFC 7234: + // https://datatracker.ietf.org/doc/html/rfc7234#section-4.2.1 + // - treat multiple expires headers as invalid + // https://datatracker.ietf.org/doc/html/rfc7234#section-5.3 + // - "MUST interpret invalid date formats... as representing a time in the past" + fn parse_expires_value(expires_value: &HeaderValue) -> Option { + let expires = expires_value.to_str().ok()?; + Some(SystemTime::from( + expires + .parse::() + .map_err(|e| warn!("Invalid HttpDate in Expires: {}, error: {}", expires, e)) + .ok()?, + )) + } + + let mut expires_iter = resp_header.headers.get_all("expires").iter(); + let expires_header = expires_iter.next(); + if expires_header.is_none() || expires_iter.next().is_some() { + return None; + } + parse_expires_value(expires_header.unwrap()).or(Some(SystemTime::UNIX_EPOCH)) +} + +/// Calculates stale-while-revalidate and stale-if-error seconds from Cache-Control or the [CacheMetaDefaults]. +pub fn calculate_serve_stale_sec( + cache_control: Option<&impl InterpretCacheControl>, + defaults: &CacheMetaDefaults, +) -> (u32, u32) { + let serve_stale_while_revalidate_sec = cache_control + .and_then(|cc| cc.serve_stale_while_revalidate_sec()) + .unwrap_or_else(|| defaults.serve_stale_while_revalidate_sec()); + let serve_stale_if_error_sec = cache_control + .and_then(|cc| cc.serve_stale_if_error_sec()) + .unwrap_or_else(|| defaults.serve_stale_if_error_sec()); + (serve_stale_while_revalidate_sec, serve_stale_if_error_sec) +} + +/// Filters to run when sending requests to upstream +pub mod upstream { + use super::*; + + /// Adjust the request header for cacheable requests + /// + /// This filter does the following in order to fetch the entire response to cache + /// - Convert HEAD to GET + /// - `If-*` headers are removed + /// - `Range` header is removed + /// + /// When `meta` is set, this function will inject `If-modified-since` according to the `Last-Modified` header + /// and inject `If-none-match` according to `Etag` header + pub fn request_filter(req: &mut RequestHeader, meta: Option<&CacheMeta>) -> Result<()> { + // change HEAD to GET, HEAD itself is not semantically cacheable + if req.method == Method::HEAD { + req.set_method(Method::GET); + } + + // remove downstream precondition headers https://datatracker.ietf.org/doc/html/rfc7232#section-3 + // we'd like to cache the 200 not the 304 + req.remove_header(&header::IF_MATCH); + req.remove_header(&header::IF_NONE_MATCH); + req.remove_header(&header::IF_MODIFIED_SINCE); + req.remove_header(&header::IF_UNMODIFIED_SINCE); + // see below range header + req.remove_header(&header::IF_RANGE); + + // remove downstream range header as we'd like to cache the entire response (this might change in the future) + req.remove_header(&header::RANGE); + + // we have a persumably staled response already, add precondition headers for revalidation + if let Some(m) = meta { + // rfc7232: "SHOULD send both validators in cache validation" but + // there have been weird cases that an origin has matching etag but not Last-Modified + if let Some(since) = m.headers().get(&header::LAST_MODIFIED) { + req.insert_header(header::IF_MODIFIED_SINCE, since).unwrap(); + } + if let Some(etag) = m.headers().get(&header::ETAG) { + req.insert_header(header::IF_NONE_MATCH, etag).unwrap(); + } + } + + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use http::header::{HeaderName, CACHE_CONTROL, EXPIRES, SET_COOKIE}; + use http::StatusCode; + use httpdate::fmt_http_date; + + fn init_log() { + let _ = env_logger::builder().is_test(true).try_init(); + } + + const DEFAULTS: CacheMetaDefaults = CacheMetaDefaults::new( + |status| match status { + StatusCode::OK => Some(10), + StatusCode::NOT_FOUND => Some(5), + StatusCode::PARTIAL_CONTENT => None, + _ => Some(1), + }, + 0, + u32::MAX, /* "infinite" stale-if-error */ + ); + + // Cache nothing, by default + const BYPASS_CACHE_DEFAULTS: CacheMetaDefaults = CacheMetaDefaults::new(|_| None, 0, 0); + + fn build_response(status: u16, headers: &[(HeaderName, &str)]) -> ResponseHeader { + let mut header = ResponseHeader::build(status, Some(headers.len())).unwrap(); + for (k, v) in headers { + header.append_header(k.to_string(), *v).unwrap(); + } + header + } + + fn resp_cacheable_wrapper( + resp: &ResponseHeader, + defaults: &CacheMetaDefaults, + authorization_present: bool, + ) -> Option { + if let Cacheable(meta) = resp_cacheable( + CacheControl::from_resp_headers(resp).as_ref(), + resp, + authorization_present, + defaults, + ) { + Some(meta) + } else { + None + } + } + + #[test] + fn test_resp_cacheable() { + let meta = resp_cacheable_wrapper( + &build_response(200, &[(CACHE_CONTROL, "max-age=12345")]), + &DEFAULTS, + false, + ); + + let meta = meta.unwrap(); + assert!(meta.is_fresh(SystemTime::now())); + assert!(meta.is_fresh( + SystemTime::now() + .checked_add(Duration::from_secs(12)) + .unwrap() + ),); + assert!(!meta.is_fresh( + SystemTime::now() + .checked_add(Duration::from_secs(12346)) + .unwrap() + )); + } + + #[test] + fn test_resp_uncacheable_directives() { + let meta = resp_cacheable_wrapper( + &build_response(200, &[(CACHE_CONTROL, "private, max-age=12345")]), + &DEFAULTS, + false, + ); + assert!(meta.is_none()); + + let meta = resp_cacheable_wrapper( + &build_response(200, &[(CACHE_CONTROL, "no-store, max-age=12345")]), + &DEFAULTS, + false, + ); + assert!(meta.is_none()); + } + + #[test] + fn test_resp_cache_authorization() { + let meta = resp_cacheable_wrapper(&build_response(200, &[]), &DEFAULTS, true); + assert!(meta.is_none()); + + let meta = resp_cacheable_wrapper( + &build_response(200, &[(CACHE_CONTROL, "max-age=10")]), + &DEFAULTS, + true, + ); + assert!(meta.is_none()); + + let meta = resp_cacheable_wrapper( + &build_response(200, &[(CACHE_CONTROL, "s-maxage=10")]), + &DEFAULTS, + true, + ); + assert!(meta.unwrap().is_fresh(SystemTime::now())); + + let meta = resp_cacheable_wrapper( + &build_response(200, &[(CACHE_CONTROL, "public, max-age=10")]), + &DEFAULTS, + true, + ); + assert!(meta.unwrap().is_fresh(SystemTime::now())); + + let meta = resp_cacheable_wrapper( + &build_response(200, &[(CACHE_CONTROL, "must-revalidate")]), + &DEFAULTS, + true, + ); + assert!(meta.unwrap().is_fresh(SystemTime::now())); + } + + #[test] + fn test_resp_zero_max_age() { + let meta = resp_cacheable_wrapper( + &build_response(200, &[(CACHE_CONTROL, "max-age=0, public")]), + &DEFAULTS, + false, + ); + + // cacheable, but needs revalidation + assert!(!meta.unwrap().is_fresh(SystemTime::now())); + } + + #[test] + fn test_resp_expires() { + let five_sec_time = SystemTime::now() + .checked_add(Duration::from_secs(5)) + .unwrap(); + + // future expires is cacheable + let meta = resp_cacheable_wrapper( + &build_response(200, &[(EXPIRES, &fmt_http_date(five_sec_time))]), + &DEFAULTS, + false, + ); + + let meta = meta.unwrap(); + assert!(meta.is_fresh(SystemTime::now())); + assert!(!meta.is_fresh( + SystemTime::now() + .checked_add(Duration::from_secs(6)) + .unwrap() + )); + + // even on default uncacheable statuses + let meta = resp_cacheable_wrapper( + &build_response(206, &[(EXPIRES, &fmt_http_date(five_sec_time))]), + &DEFAULTS, + false, + ); + assert!(meta.is_some()); + } + + #[test] + fn test_resp_past_expires() { + // cacheable, but expired + let meta = resp_cacheable_wrapper( + &build_response(200, &[(EXPIRES, "Fri, 15 May 2015 15:34:21 GMT")]), + &BYPASS_CACHE_DEFAULTS, + false, + ); + assert!(!meta.unwrap().is_fresh(SystemTime::now())); + } + + #[test] + fn test_resp_nonstandard_expires() { + // init log to allow inspecting warnings + init_log(); + + // invalid cases, according to parser + // (but should be stale according to RFC) + let meta = resp_cacheable_wrapper( + &build_response(200, &[(EXPIRES, "Mon, 13 Feb 0002 12:00:00 GMT")]), + &BYPASS_CACHE_DEFAULTS, + false, + ); + assert!(!meta.unwrap().is_fresh(SystemTime::now())); + + let meta = resp_cacheable_wrapper( + &build_response(200, &[(EXPIRES, "Fri, 01 Dec 99999 16:00:00 GMT")]), + &BYPASS_CACHE_DEFAULTS, + false, + ); + assert!(!meta.unwrap().is_fresh(SystemTime::now())); + + let meta = resp_cacheable_wrapper( + &build_response(200, &[(EXPIRES, "0")]), + &BYPASS_CACHE_DEFAULTS, + false, + ); + assert!(!meta.unwrap().is_fresh(SystemTime::now())); + } + + #[test] + fn test_resp_multiple_expires() { + let five_sec_time = SystemTime::now() + .checked_add(Duration::from_secs(5)) + .unwrap(); + let ten_sec_time = SystemTime::now() + .checked_add(Duration::from_secs(10)) + .unwrap(); + + // multiple expires = uncacheable + let meta = resp_cacheable_wrapper( + &build_response( + 200, + &[ + (EXPIRES, &fmt_http_date(five_sec_time)), + (EXPIRES, &fmt_http_date(ten_sec_time)), + ], + ), + &BYPASS_CACHE_DEFAULTS, + false, + ); + assert!(meta.is_none()); + + // unless the default is cacheable + let meta = resp_cacheable_wrapper( + &build_response( + 200, + &[ + (EXPIRES, &fmt_http_date(five_sec_time)), + (EXPIRES, &fmt_http_date(ten_sec_time)), + ], + ), + &DEFAULTS, + false, + ); + assert!(meta.is_some()); + } + + #[test] + fn test_resp_cache_control_with_expires() { + let five_sec_time = SystemTime::now() + .checked_add(Duration::from_secs(5)) + .unwrap(); + // cache-control takes precedence over expires + let meta = resp_cacheable_wrapper( + &build_response( + 200, + &[ + (EXPIRES, &fmt_http_date(five_sec_time)), + (CACHE_CONTROL, "max-age=0"), + ], + ), + &DEFAULTS, + false, + ); + assert!(!meta.unwrap().is_fresh(SystemTime::now())); + } + + #[test] + fn test_resp_stale_while_revalidate() { + // respect defaults + let meta = resp_cacheable_wrapper( + &build_response(200, &[(CACHE_CONTROL, "max-age=10")]), + &DEFAULTS, + false, + ); + + let meta = meta.unwrap(); + let eleven_sec_time = SystemTime::now() + .checked_add(Duration::from_secs(11)) + .unwrap(); + assert!(!meta.is_fresh(eleven_sec_time)); + assert!(!meta.serve_stale_while_revalidate(SystemTime::now())); + assert!(!meta.serve_stale_while_revalidate(eleven_sec_time)); + + // override with stale-while-revalidate + let meta = resp_cacheable_wrapper( + &build_response( + 200, + &[(CACHE_CONTROL, "max-age=10, stale-while-revalidate=5")], + ), + &DEFAULTS, + false, + ); + + let meta = meta.unwrap(); + let eleven_sec_time = SystemTime::now() + .checked_add(Duration::from_secs(11)) + .unwrap(); + let sixteen_sec_time = SystemTime::now() + .checked_add(Duration::from_secs(16)) + .unwrap(); + assert!(!meta.is_fresh(eleven_sec_time)); + assert!(meta.serve_stale_while_revalidate(eleven_sec_time)); + assert!(!meta.serve_stale_while_revalidate(sixteen_sec_time)); + } + + #[test] + fn test_resp_stale_if_error() { + // respect defaults + let meta = resp_cacheable_wrapper( + &build_response(200, &[(CACHE_CONTROL, "max-age=10")]), + &DEFAULTS, + false, + ); + + let meta = meta.unwrap(); + let hundred_years_time = SystemTime::now() + .checked_add(Duration::from_secs(86400 * 365 * 100)) + .unwrap(); + assert!(!meta.is_fresh(hundred_years_time)); + assert!(meta.serve_stale_if_error(hundred_years_time)); + + // override with stale-if-error + let meta = resp_cacheable_wrapper( + &build_response( + 200, + &[( + CACHE_CONTROL, + "max-age=10, stale-while-revalidate=5, stale-if-error=60", + )], + ), + &DEFAULTS, + false, + ); + + let meta = meta.unwrap(); + let eleven_sec_time = SystemTime::now() + .checked_add(Duration::from_secs(11)) + .unwrap(); + let seventy_sec_time = SystemTime::now() + .checked_add(Duration::from_secs(70)) + .unwrap(); + assert!(!meta.is_fresh(eleven_sec_time)); + assert!(meta.serve_stale_if_error(SystemTime::now())); + assert!(meta.serve_stale_if_error(eleven_sec_time)); + assert!(!meta.serve_stale_if_error(seventy_sec_time)); + + // never serve stale + let meta = resp_cacheable_wrapper( + &build_response(200, &[(CACHE_CONTROL, "max-age=10, stale-if-error=0")]), + &DEFAULTS, + false, + ); + + let meta = meta.unwrap(); + let eleven_sec_time = SystemTime::now() + .checked_add(Duration::from_secs(11)) + .unwrap(); + assert!(!meta.is_fresh(eleven_sec_time)); + assert!(!meta.serve_stale_if_error(eleven_sec_time)); + } + + #[test] + fn test_resp_status_cache_defaults() { + // 200 response + let meta = resp_cacheable_wrapper(&build_response(200, &[]), &DEFAULTS, false); + assert!(meta.is_some()); + + let meta = meta.unwrap(); + assert!(meta.is_fresh( + SystemTime::now() + .checked_add(Duration::from_secs(9)) + .unwrap() + )); + assert!(!meta.is_fresh( + SystemTime::now() + .checked_add(Duration::from_secs(11)) + .unwrap() + )); + + // 404 response, different ttl + let meta = resp_cacheable_wrapper(&build_response(404, &[]), &DEFAULTS, false); + assert!(meta.is_some()); + + let meta = meta.unwrap(); + assert!(meta.is_fresh( + SystemTime::now() + .checked_add(Duration::from_secs(4)) + .unwrap() + )); + assert!(!meta.is_fresh( + SystemTime::now() + .checked_add(Duration::from_secs(6)) + .unwrap() + )); + + // 206 marked uncacheable (no cache TTL) + let meta = resp_cacheable_wrapper(&build_response(206, &[]), &DEFAULTS, false); + assert!(meta.is_none()); + + // default uncacheable status with explicit Cache-Control is cacheable + let meta = resp_cacheable_wrapper( + &build_response(206, &[(CACHE_CONTROL, "public, max-age=10")]), + &DEFAULTS, + false, + ); + assert!(meta.is_some()); + + let meta = meta.unwrap(); + assert!(meta.is_fresh( + SystemTime::now() + .checked_add(Duration::from_secs(9)) + .unwrap() + )); + assert!(!meta.is_fresh( + SystemTime::now() + .checked_add(Duration::from_secs(11)) + .unwrap() + )); + + // 416 matches any status + let meta = resp_cacheable_wrapper(&build_response(416, &[]), &DEFAULTS, false); + assert!(meta.is_some()); + + let meta = meta.unwrap(); + assert!(meta.is_fresh(SystemTime::now())); + assert!(!meta.is_fresh( + SystemTime::now() + .checked_add(Duration::from_secs(2)) + .unwrap() + )); + } + + #[test] + fn test_resp_cache_no_cache_fields() { + // check #field-names are stripped from the cache header + let meta = resp_cacheable_wrapper( + &build_response( + 200, + &[ + (SET_COOKIE, "my-cookie"), + (CACHE_CONTROL, "private=\"something\", max-age=10"), + (HeaderName::from_bytes(b"Something").unwrap(), "foo"), + ], + ), + &DEFAULTS, + false, + ); + let meta = meta.unwrap(); + assert!(meta.headers().contains_key(SET_COOKIE)); + assert!(!meta.headers().contains_key("Something")); + + let meta = resp_cacheable_wrapper( + &build_response( + 200, + &[ + (SET_COOKIE, "my-cookie"), + ( + CACHE_CONTROL, + "max-age=0, no-cache=\"meta1, SeT-Cookie ,meta2\"", + ), + (HeaderName::from_bytes(b"meta1").unwrap(), "foo"), + ], + ), + &DEFAULTS, + false, + ); + let meta = meta.unwrap(); + assert!(!meta.headers().contains_key(SET_COOKIE)); + assert!(!meta.headers().contains_key("meta1")); + } +} diff --git a/pingora-cache/src/hashtable.rs b/pingora-cache/src/hashtable.rs new file mode 100644 index 0000000..a89f9ad --- /dev/null +++ b/pingora-cache/src/hashtable.rs @@ -0,0 +1,112 @@ +// 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. + +//! Concurrent hash tables and LRUs + +use lru::LruCache; +use parking_lot::{RwLock, RwLockReadGuard, RwLockWriteGuard}; +use std::collections::HashMap; + +// There are probably off-the-shelf crates of this, DashMap? +/// A hash table that shards to a constant number of tables to reduce lock contention +pub struct ConcurrentHashTable { + tables: [RwLock>; N], +} + +#[inline] +fn get_shard(key: u128, n_shards: usize) -> usize { + (key % n_shards as u128) as usize +} + +impl ConcurrentHashTable +where + [RwLock>; N]: Default, +{ + pub fn new() -> Self { + ConcurrentHashTable { + tables: Default::default(), + } + } + pub fn get(&self, key: u128) -> &RwLock> { + &self.tables[get_shard(key, N)] + } + + #[allow(dead_code)] + pub fn read(&self, key: u128) -> RwLockReadGuard> { + self.get(key).read() + } + + pub fn write(&self, key: u128) -> RwLockWriteGuard> { + self.get(key).write() + } + + // TODO: work out the lifetimes to provide get/set directly +} + +impl Default for ConcurrentHashTable +where + [RwLock>; N]: Default, +{ + fn default() -> Self { + Self::new() + } +} + +#[doc(hidden)] // not need in public API +pub struct LruShard(RwLock>); +impl Default for LruShard { + fn default() -> Self { + // help satisfy default construction of array + LruShard(RwLock::new(LruCache::unbounded())) + } +} + +/// Sharded concurrent data structure for LruCache +pub struct ConcurrentLruCache { + lrus: [LruShard; N], +} + +impl ConcurrentLruCache +where + [LruShard; N]: Default, +{ + pub fn new(shard_capacity: usize) -> Self { + use std::num::NonZeroUsize; + // safe, 1 != 0 + const ONE: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(1) }; + let mut cache = ConcurrentLruCache { + lrus: Default::default(), + }; + for lru in &mut cache.lrus { + lru.0 + .write() + .resize(shard_capacity.try_into().unwrap_or(ONE)); + } + cache + } + pub fn get(&self, key: u128) -> &RwLock> { + &self.lrus[get_shard(key, N)].0 + } + + #[allow(dead_code)] + pub fn read(&self, key: u128) -> RwLockReadGuard> { + self.get(key).read() + } + + pub fn write(&self, key: u128) -> RwLockWriteGuard> { + self.get(key).write() + } + + // TODO: work out the lifetimes to provide get/set directly +} diff --git a/pingora-cache/src/key.rs b/pingora-cache/src/key.rs new file mode 100644 index 0000000..26e9362 --- /dev/null +++ b/pingora-cache/src/key.rs @@ -0,0 +1,302 @@ +// 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. + +//! Cache key + +use super::*; + +use blake2::{Blake2b, Digest}; +use serde::{Deserialize, Serialize}; + +// 16-byte / 128-bit key: large enough to avoid collision +const KEY_SIZE: usize = 16; + +/// An 128 bit hash binary +pub type HashBinary = [u8; KEY_SIZE]; + +fn hex2str(hex: &[u8]) -> String { + use std::fmt::Write; + let mut s = String::with_capacity(KEY_SIZE * 2); + for c in hex { + write!(s, "{:02x}", c).unwrap(); // safe, just dump hex to string + } + s +} + +/// Decode the hex str into [HashBinary]. +/// +/// Return `None` when the decode fails or the input is not exact 32 (to decode to 16 bytes). +pub fn str2hex(s: &str) -> Option { + if s.len() != KEY_SIZE * 2 { + return None; + } + let mut output = [0; KEY_SIZE]; + // no need to bubble the error, it should be obvious why the decode fails + hex::decode_to_slice(s.as_bytes(), &mut output).ok()?; + Some(output) +} + +/// The trait for cache key +pub trait CacheHashKey { + /// Return the hash of the cache key + fn primary_bin(&self) -> HashBinary; + + /// Return the variance hash of the cache key. + /// + /// `None` if no variance. + fn variance_bin(&self) -> Option; + + /// Return the hash including both primary and variance keys + fn combined_bin(&self) -> HashBinary { + let key = self.primary_bin(); + if let Some(v) = self.variance_bin() { + let mut hasher = Blake2b128::new(); + hasher.update(key); + hasher.update(v); + hasher.finalize().into() + } else { + // if there is no variance, combined_bin should return the same as primary_bin + key + } + } + + /// An extra tag for identifying users + /// + /// For example if the storage backend implements per user quota, this tag can be used. + fn user_tag(&self) -> &str; + + /// The hex string of [Self::primary_bin()] + fn primary(&self) -> String { + hex2str(&self.primary_bin()) + } + + /// The hex string of [Self::variance_bin()] + fn variance(&self) -> Option { + self.variance_bin().as_ref().map(|b| hex2str(&b[..])) + } + + /// The hex string of [Self::combined_bin()] + fn combined(&self) -> String { + hex2str(&self.combined_bin()) + } +} + +/// General purpose cache key +#[derive(Debug, Clone)] +pub struct CacheKey { + // All strings for now, can be more structural as long as it can hash + namespace: String, + primary: String, + variance: Option, + /// An extra tag for identifying users + /// + /// For example if the storage backend implements per user quota, this tag can be used. + pub user_tag: String, +} + +impl CacheKey { + /// Set the value of the variance hash + pub fn set_variance_key(&mut self, key: HashBinary) { + self.variance = Some(key) + } + + /// Get the value of the variance hash + pub fn get_variance_key(&self) -> Option<&HashBinary> { + self.variance.as_ref() + } + + /// Removes the variance from this cache key + pub fn remove_variance_key(&mut self) { + self.variance = None + } +} + +/// Storage optimized cache key to keep in memory or in storage +// 16 bytes + 8 bytes (+16 * u8) + user_tag.len() + 16 Bytes (Box) +#[derive(Debug, Deserialize, Serialize, Clone, Hash, PartialEq, Eq)] +pub struct CompactCacheKey { + pub primary: HashBinary, + // save 8 bytes for non-variance but waste 8 bytes for variance vs, store flat 16 bytes + pub variance: Option>, + pub user_tag: Box, // the len should be small to keep memory usage bounded +} + +impl CacheHashKey for CompactCacheKey { + fn primary_bin(&self) -> HashBinary { + self.primary + } + + fn variance_bin(&self) -> Option { + self.variance.as_ref().map(|s| *s.as_ref()) + } + + fn user_tag(&self) -> &str { + &self.user_tag + } +} + +/* + * We use blake2 hashing, which is faster and more secure, to replace md5. + * We have not given too much thought on whether non-crypto hash can be safely + * use because hashing performance is not critical. + * Note: we should avoid hashes like ahash which does not have consistent output + * across machines because it is designed purely for in memory hashtable +*/ + +// hash output: we use 128 bits (16 bytes) hash which will map to 32 bytes hex string +pub(crate) type Blake2b128 = Blake2b; + +/// helper function: hash str to u8 +pub fn hash_u8(key: &str) -> u8 { + let mut hasher = Blake2b128::new(); + hasher.update(key); + let raw = hasher.finalize(); + raw[0] +} + +/// helper function: hash str to [HashBinary] +pub fn hash_key(key: &str) -> HashBinary { + let mut hasher = Blake2b128::new(); + hasher.update(key); + let raw = hasher.finalize(); + raw.into() +} + +impl CacheKey { + fn primary_hasher(&self) -> Blake2b128 { + let mut hasher = Blake2b128::new(); + hasher.update(&self.namespace); + hasher.update(&self.primary); + hasher + } + + /// Create a default [CacheKey] from a request, which just takes it URI as the primary key. + pub fn default(req_header: &ReqHeader) -> Self { + CacheKey { + namespace: "".into(), + primary: format!("{}", req_header.uri), + variance: None, + user_tag: "".into(), + } + } + + /// Create a new [CacheKey] from the given namespace, primary, and user_tag string. + /// + /// Both `namespace` and `primary` will be used for the primary hash + pub fn new(namespace: S1, primary: S2, user_tag: S3) -> Self + where + S1: Into, + S2: Into, + S3: Into, + { + CacheKey { + namespace: namespace.into(), + primary: primary.into(), + variance: None, + user_tag: user_tag.into(), + } + } + + /// Return the namespace of this key + pub fn namespace(&self) -> &str { + &self.namespace + } + + /// Return the primary key of this key + pub fn primary_key(&self) -> &str { + &self.primary + } + + /// Convert this key to [CompactCacheKey]. + pub fn to_compact(&self) -> CompactCacheKey { + let primary = self.primary_bin(); + CompactCacheKey { + primary, + variance: self.variance_bin().map(Box::new), + user_tag: self.user_tag.clone().into_boxed_str(), + } + } +} + +impl CacheHashKey for CacheKey { + fn primary_bin(&self) -> HashBinary { + self.primary_hasher().finalize().into() + } + + fn variance_bin(&self) -> Option { + self.variance + } + + fn user_tag(&self) -> &str { + &self.user_tag + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_cache_key_hash() { + let key = CacheKey { + namespace: "".into(), + primary: "aa".into(), + variance: None, + user_tag: "1".into(), + }; + let hash = key.primary(); + assert_eq!(hash, "ac10f2aef117729f8dad056b3059eb7e"); + assert!(key.variance().is_none()); + assert_eq!(key.combined(), hash); + let compact = key.to_compact(); + assert_eq!(compact.primary(), hash); + assert!(compact.variance().is_none()); + assert_eq!(compact.combined(), hash); + } + + #[test] + fn test_cache_key_vary_hash() { + let key = CacheKey { + namespace: "".into(), + primary: "aa".into(), + variance: Some([0u8; 16]), + user_tag: "1".into(), + }; + let hash = key.primary(); + assert_eq!(hash, "ac10f2aef117729f8dad056b3059eb7e"); + assert_eq!(key.variance().unwrap(), "00000000000000000000000000000000"); + assert_eq!(key.combined(), "004174d3e75a811a5b44c46b3856f3ee"); + let compact = key.to_compact(); + assert_eq!(compact.primary(), "ac10f2aef117729f8dad056b3059eb7e"); + assert_eq!( + compact.variance().unwrap(), + "00000000000000000000000000000000" + ); + assert_eq!(compact.combined(), "004174d3e75a811a5b44c46b3856f3ee"); + } + + #[test] + fn test_hex_str() { + let mut key = [0; KEY_SIZE]; + for (i, v) in key.iter_mut().enumerate() { + // key: [0, 1, 2, .., 15] + *v = i as u8; + } + let hex_str = hex2str(&key); + let key2 = str2hex(&hex_str).unwrap(); + for i in 0..KEY_SIZE { + assert_eq!(key[i], key2[i]); + } + } +} diff --git a/pingora-cache/src/lib.rs b/pingora-cache/src/lib.rs new file mode 100644 index 0000000..be352dc --- /dev/null +++ b/pingora-cache/src/lib.rs @@ -0,0 +1,1093 @@ +// 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. + +//! The HTTP caching layer for proxies. + +#![allow(clippy::new_without_default)] + +use http::{method::Method, request::Parts as ReqHeader, response::Parts as RespHeader}; +use key::{CacheHashKey, HashBinary}; +use lock::WritePermit; +use pingora_error::Result; +use pingora_http::ResponseHeader; +use std::time::{Duration, SystemTime}; +use trace::CacheTraceCTX; + +pub mod cache_control; +pub mod eviction; +pub mod filters; +pub mod hashtable; +pub mod key; +pub mod lock; +pub mod max_file_size; +mod memory; +pub mod meta; +pub mod predictor; +pub mod put; +pub mod storage; +pub mod trace; +mod variance; + +use crate::max_file_size::MaxFileSizeMissHandler; +pub use key::CacheKey; +use lock::{CacheLock, LockStatus, Locked}; +pub use memory::MemCache; +pub use meta::{CacheMeta, CacheMetaDefaults}; +pub use storage::{HitHandler, MissHandler, Storage}; +pub use variance::VarianceBuilder; + +pub mod prelude {} + +/// The state machine for http caching +/// +/// This object is used to handle the state and transitions for HTTP caching through the life of a +/// request. +pub struct HttpCache { + phase: CachePhase, + // Box the rest so that a disabled HttpCache struct is small + inner: Option>, +} + +/// This reflects the phase of HttpCache during the lifetime of a request +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum CachePhase { + /// Cache disabled, with reason (NeverEnabled if never explicitly used) + Disabled(NoCacheReason), + /// Cache enabled but nothing is set yet + Uninit, + /// Cache was enabled, the request decided not to use it + // HttpCache.inner is kept + Bypass, + /// Awaiting cache key to be generated + CacheKey, + /// Cache hit + Hit, + /// No cached asset is found + Miss, + /// A staled (expired) asset is found + Stale, + /// A staled (expired) asset was found, so a fresh one was fetched + Expired, + /// A staled (expired) asset was found, and it was revalidated to be fresh + Revalidated, + /// Revalidated, but deemed uncacheable so we do not freshen it + RevalidatedNoCache(NoCacheReason), +} + +impl CachePhase { + /// Convert [CachePhase] as `str`, for logging and debugging. + pub fn as_str(&self) -> &'static str { + match self { + CachePhase::Disabled(_) => "disabled", + CachePhase::Uninit => "uninitialized", + CachePhase::Bypass => "bypass", + CachePhase::CacheKey => "key", + CachePhase::Hit => "hit", + CachePhase::Miss => "miss", + CachePhase::Stale => "stale", + CachePhase::Expired => "expired", + CachePhase::Revalidated => "revalidated", + CachePhase::RevalidatedNoCache(_) => "revalidated-nocache", + } + } +} + +/// The possible reasons for not caching +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub enum NoCacheReason { + /// Caching is not enabled to begin with + NeverEnabled, + /// Origin directives indicated this was not cacheable + OriginNotCache, + /// Response size was larger than the cache's configured maximum asset size + ResponseTooLarge, + /// Due to internal caching storage error + StorageError, + /// Due to other type of internal issues + InternalError, + /// will be cacheable but skip cache admission now + /// + /// This happens when the cache predictor predicted that this request is not cacheable but + /// the response turns out to be OK to cache. However it might be too large to re-enable caching + /// for this request. + Deferred, + /// The writer of the cache lock sees that the request is not cacheable (Could be OriginNotCache) + CacheLockGiveUp, + /// This request waited too long for the writer of the cache lock to finish, so this request will + /// fetch from the origin without caching + CacheLockTimeout, + /// Other custom defined reasons + Custom(&'static str), +} + +impl NoCacheReason { + /// Convert [NoCacheReason] as `str`, for logging and debugging. + pub fn as_str(&self) -> &'static str { + use NoCacheReason::*; + match self { + NeverEnabled => "NeverEnabled", + OriginNotCache => "OriginNotCache", + ResponseTooLarge => "ResponseTooLarge", + StorageError => "StorageError", + InternalError => "InternalError", + Deferred => "Deferred", + CacheLockGiveUp => "CacheLockGiveUp", + CacheLockTimeout => "CacheLockTimeout", + Custom(s) => s, + } + } +} + +/// Response cacheable decision +/// +/// +#[derive(Debug)] +pub enum RespCacheable { + Cacheable(CacheMeta), + Uncacheable(NoCacheReason), +} + +impl RespCacheable { + /// Whether it is cacheable + #[inline] + pub fn is_cacheable(&self) -> bool { + matches!(*self, Self::Cacheable(_)) + } + + /// Unwrap [RespCacheable] to get the [CacheMeta] stored + /// # Panic + /// Panic when this object is not cacheable. Check [Self::is_cacheable()] first. + pub fn unwrap_meta(self) -> CacheMeta { + match self { + Self::Cacheable(meta) => meta, + Self::Uncacheable(_) => panic!("expected Cacheable value"), + } + } +} + +/// Freshness state of cache hit asset +/// +/// +#[derive(Debug, Copy, Clone)] +pub enum HitStatus { + Expired, + ForceExpired, + FailedHitFilter, + Fresh, +} + +impl HitStatus { + /// For displaying cache hit status + pub fn as_str(&self) -> &'static str { + match self { + Self::Expired => "expired", + Self::ForceExpired => "force_expired", + Self::FailedHitFilter => "failed_hit_filter", + Self::Fresh => "fresh", + } + } + + /// Whether cached asset can be served as fresh + pub fn is_fresh(&self) -> bool { + match self { + Self::Expired | Self::ForceExpired | Self::FailedHitFilter => false, + Self::Fresh => true, + } + } +} + +struct HttpCacheInner { + pub key: Option, + pub meta: Option, + // when set, even if an asset exists, it would only be considered valid after this timestamp + pub valid_after: Option, + // when set, an asset will be rejected from the cache if it exceeds this size in bytes + pub max_file_size_bytes: Option, + pub miss_handler: Option, + pub body_reader: Option, + pub storage: &'static (dyn storage::Storage + Sync), // static for now + pub eviction: Option<&'static (dyn eviction::EvictionManager + Sync)>, + pub predictor: Option<&'static (dyn predictor::CacheablePredictor + Sync)>, + pub lock: Option, // TODO: these 3 fields should come in 1 sub struct + pub cache_lock: Option<&'static CacheLock>, + pub lock_duration: Option, + pub traces: trace::CacheTraceCTX, +} + +impl HttpCache { + /// Create a new [HttpCache]. + /// + /// Caching is not enabled by default. + pub fn new() -> Self { + HttpCache { + phase: CachePhase::Disabled(NoCacheReason::NeverEnabled), + inner: None, + } + } + + /// Whether the cache is enabled + pub fn enabled(&self) -> bool { + !matches!(self.phase, CachePhase::Disabled(_) | CachePhase::Bypass) + } + + /// Whether the cache is being bypassed + pub fn bypassing(&self) -> bool { + matches!(self.phase, CachePhase::Bypass) + } + + /// Return the [CachePhase] + pub fn phase(&self) -> CachePhase { + self.phase + } + + /// Whether anything was fetched from the upstream + /// + /// This essentially checks all possible [CachePhase] who need to contact the upstream server + pub fn upstream_used(&self) -> bool { + use CachePhase::*; + match self.phase { + Disabled(_) | Bypass | Miss | Expired | Revalidated | RevalidatedNoCache(_) => true, + Hit | Stale => false, + Uninit | CacheKey => false, // invalid states for this call, treat them as false to keep it simple + } + } + + /// Check whether the backend storage is the type `T`. + pub fn storage_type_is(&self) -> bool { + self.inner + .as_ref() + .and_then(|inner| inner.storage.as_any().downcast_ref::()) + .is_some() + } + + /// Disable caching + pub fn disable(&mut self, reason: NoCacheReason) { + use NoCacheReason::*; + match self.phase { + CachePhase::Disabled(_) => { + // replace reason + self.phase = CachePhase::Disabled(reason); + } + _ => { + self.phase = CachePhase::Disabled(reason); + if let Some(inner) = self.inner.as_mut() { + let lock = inner.lock.take(); + if let Some(Locked::Write(_r)) = lock { + let lock_status = match reason { + // let next request try to fetch it + InternalError | StorageError | Deferred => LockStatus::TransientError, + // no need for the lock anymore + OriginNotCache | ResponseTooLarge => LockStatus::GiveUp, + // not sure which LockStatus make sense, we treat it as GiveUp for now + Custom(_) => LockStatus::GiveUp, + // should never happen, NeverEnabled shouldn't hold a lock + NeverEnabled => panic!("NeverEnabled holds a write lock"), + CacheLockGiveUp | CacheLockTimeout => { + panic!("CacheLock* are for cache lock readers only") + } + }; + inner + .cache_lock + .unwrap() + .release(inner.key.as_ref().unwrap(), lock_status); + } + } + // log initial disable reason + self.inner_mut() + .traces + .cache_span + .set_tag(|| trace::Tag::new("disable_reason", reason.as_str())); + self.inner = None; + } + } + } + + /* The following methods panic when they are used in the wrong phase. + * This is better than returning errors as such panics are only caused by coding error, which + * should be fixed right away. Tokio runtime only crashes the current task instead of the whole + * program when these panics happen. */ + + /// Set the cache to bypass + /// + /// # Panic + /// This call is only allowed in [CachePhase::CacheKey] phase (before any cache lookup is performed). + /// Use it in any other phase will lead to panic. + pub fn bypass(&mut self) { + match self.phase { + CachePhase::CacheKey => { + // before cache lookup / found / miss + self.phase = CachePhase::Bypass; + self.inner_mut() + .traces + .cache_span + .set_tag(|| trace::Tag::new("bypassed", true)); + } + _ => panic!("wrong phase to bypass HttpCache {:?}", self.phase), + } + } + + /// Enable the cache + /// + /// - `storage`: the cache storage backend that implements [storage::Storage] + /// - `eviction`: optionally the eviction mananger, without it, nothing will be evicted from the storage + /// - `predictor`: optionally a cache predictor. The cache predictor predicts whether something is likely + /// to be cacheable or not. This is useful because the proxy can apply different types of optimization to + /// cacheable and uncacheable requests. + /// - `cache_lock`: optionally a cache lock which handles concurrent lookups to the same asset. Without it + /// such lookups will all be allowed to fetch the asset independently. + pub fn enable( + &mut self, + storage: &'static (dyn storage::Storage + Sync), + eviction: Option<&'static (dyn eviction::EvictionManager + Sync)>, + predictor: Option<&'static (dyn predictor::CacheablePredictor + Sync)>, + cache_lock: Option<&'static CacheLock>, + ) { + match self.phase { + CachePhase::Disabled(_) => { + self.phase = CachePhase::Uninit; + self.inner = Some(Box::new(HttpCacheInner { + key: None, + meta: None, + valid_after: None, + max_file_size_bytes: None, + miss_handler: None, + body_reader: None, + storage, + eviction, + predictor, + lock: None, + cache_lock, + lock_duration: None, + traces: CacheTraceCTX::new(), + })); + } + _ => panic!("Cannot enable already enabled HttpCache {:?}", self.phase), + } + } + + // Enable distributed tracing + pub fn enable_tracing(&mut self, parent_span: trace::Span) { + if let Some(inner) = self.inner.as_mut() { + inner.traces.enable(parent_span); + } + } + + // Get the cache `miss` tracing span + pub fn get_miss_span(&mut self) -> Option { + self.inner.as_mut().map(|i| i.traces.get_miss_span()) + } + + // shortcut to access inner, panic if phase is disabled + #[inline] + fn inner_mut(&mut self) -> &mut HttpCacheInner { + self.inner.as_mut().unwrap() + } + + #[inline] + fn inner(&self) -> &HttpCacheInner { + self.inner.as_ref().unwrap() + } + + /// Set the cache key + /// # Panic + /// Cache key is only allowed to be set in its own phase. Set it in other phases will cause panic. + pub fn set_cache_key(&mut self, key: CacheKey) { + match self.phase { + CachePhase::Uninit | CachePhase::CacheKey => { + self.phase = CachePhase::CacheKey; + self.inner_mut().key = Some(key); + } + _ => panic!("wrong phase {:?}", self.phase), + } + } + + /// Return the cache key used for asset lookup + /// # Panic + /// Can only be called after cache key is set and cache is not disabled. Panic otherwise. + pub fn cache_key(&self) -> &CacheKey { + match self.phase { + CachePhase::Disabled(_) | CachePhase::Uninit => panic!("wrong phase {:?}", self.phase), + _ => self.inner().key.as_ref().unwrap(), + } + } + + /// Return the max size allowed to be cached. + pub fn max_file_size_bytes(&self) -> Option { + match self.phase { + CachePhase::Disabled(_) | CachePhase::Uninit => panic!("wrong phase {:?}", self.phase), + _ => self.inner().max_file_size_bytes, + } + } + + /// Set the maximum response _body_ size in bytes that will be admitted to the cache. + /// + /// Response header size does not contribute to the max file size. + pub fn set_max_file_size_bytes(&mut self, max_file_size_bytes: usize) { + match self.phase { + CachePhase::Disabled(_) => panic!("wrong phase {:?}", self.phase), + _ => { + self.inner_mut().max_file_size_bytes = Some(max_file_size_bytes); + } + } + } + + /// Set that cache is found in cache storage. + /// + /// This function is called after [Self::cache_lookup()] which returns the [CacheMeta] and + /// [HitHandler]. + /// + /// The `hit_status` enum allows the caller to force expire assets. + pub fn cache_found(&mut self, meta: CacheMeta, hit_handler: HitHandler, hit_status: HitStatus) { + match self.phase { + // Stale allowed because of cache lock and then retry + CachePhase::CacheKey | CachePhase::Stale => { + self.phase = if hit_status.is_fresh() { + CachePhase::Hit + } else { + CachePhase::Stale + }; + let phase = self.phase; + let inner = self.inner_mut(); + let key = inner.key.as_ref().unwrap(); + if phase == CachePhase::Stale { + if let Some(lock) = inner.cache_lock.as_ref() { + inner.lock = Some(lock.lock(key)); + } + } + inner.traces.log_meta(&meta); + if let Some(eviction) = inner.eviction { + // TODO: make access() accept CacheKey + let cache_key = key.to_compact(); + // FIXME: get size + eviction.access(&cache_key, 0, meta.0.internal.fresh_until); + } + inner.traces.start_hit_span(phase, hit_status); + inner.meta = Some(meta); + inner.body_reader = Some(hit_handler); + } + _ => panic!("wrong phase {:?}", self.phase), + } + } + + /// Mark `self` to be cache miss. + /// + /// This function is called after [Self::cache_lookup()] finds nothing or the caller decides + /// not to use the assets found. + /// # Panic + /// Panic in other phases. + pub fn cache_miss(&mut self) { + match self.phase { + // from CacheKey: set state to miss during cache lookup + // from Bypass: response became cacheable, set state to miss to cache + CachePhase::CacheKey | CachePhase::Bypass => { + self.phase = CachePhase::Miss; + self.inner_mut().traces.start_miss_span(); + } + _ => panic!("wrong phase {:?}", self.phase), + } + } + + /// Return the [HitHandler] + /// # Panic + /// Call this after [Self::cache_found()], panic in other phases. + pub fn hit_handler(&mut self) -> &mut HitHandler { + match self.phase { + CachePhase::Hit + | CachePhase::Stale + | CachePhase::Revalidated + | CachePhase::RevalidatedNoCache(_) => self.inner_mut().body_reader.as_mut().unwrap(), + _ => panic!("wrong phase {:?}", self.phase), + } + } + + /// Return the body reader during a cache admission(miss/expired) which decouples the downstream + /// read and upstream cache write + pub fn miss_body_reader(&mut self) -> Option<&mut HitHandler> { + match self.phase { + CachePhase::Miss | CachePhase::Expired => { + let inner = self.inner_mut(); + if inner.storage.support_streaming_partial_write() { + inner.body_reader.as_mut() + } else { + // body_reader could be set even when the storage doesn't support streaming + // Expired cache would have the reader set. + None + } + } + _ => None, + } + } + + /// Call this when cache hit is fully read. + /// + /// This call will release resource if any and log the timing in tracing if set. + /// # Panic + /// Panic in phases where there is no cache hit. + pub async fn finish_hit_handler(&mut self) -> Result<()> { + match self.phase { + CachePhase::Hit + | CachePhase::Miss + | CachePhase::Expired + | CachePhase::Stale + | CachePhase::Revalidated + | CachePhase::RevalidatedNoCache(_) => { + let inner = self.inner_mut(); + if inner.body_reader.is_none() { + // already finished, we allow calling this function more than once + return Ok(()); + } + let body_reader = inner.body_reader.take().unwrap(); + let key = inner.key.as_ref().unwrap(); + let result = body_reader + .finish(inner.storage, key, &inner.traces.hit_span.handle()) + .await; + inner.traces.finish_hit_span(); + result + } + _ => panic!("wrong phase {:?}", self.phase), + } + } + + /// Set the [MissHandler] according to cache_key and meta, can only call once + pub async fn set_miss_handler(&mut self) -> Result<()> { + match self.phase { + // set_miss_handler() needs to be called after set_cache_meta() (which change Stale to Expire). + // This is an artificial rule to enforce the state transitions + CachePhase::Miss | CachePhase::Expired => { + let max_file_size_bytes = self.max_file_size_bytes(); + + let inner = self.inner_mut(); + if inner.miss_handler.is_some() { + panic!("write handler is already set") + } + let meta = inner.meta.as_ref().unwrap(); + let key = inner.key.as_ref().unwrap(); + let miss_handler = inner + .storage + .get_miss_handler(key, meta, &inner.traces.get_miss_span()) + .await?; + + inner.miss_handler = if let Some(max_size) = max_file_size_bytes { + Some(Box::new(MaxFileSizeMissHandler::new( + miss_handler, + max_size, + ))) + } else { + Some(miss_handler) + }; + + if inner.storage.support_streaming_partial_write() { + // If reader can access partial write, the cache lock can be released here + // to let readers start reading the body. + let lock = inner.lock.take(); + if let Some(Locked::Write(_r)) = lock { + inner.cache_lock.unwrap().release(key, LockStatus::Done); + } + // Downstream read and upstream write can be decoupled + let body_reader = inner + .storage + .lookup(key, &inner.traces.get_miss_span()) + .await?; + + if let Some((_meta, body_reader)) = body_reader { + inner.body_reader = Some(body_reader); + } else { + // body_reader should exist now because streaming_partial_write is to support it + panic!("unable to get body_reader for {:?}", meta); + } + } + Ok(()) + } + _ => panic!("wrong phase {:?}", self.phase), + } + } + + /// Return the [MissHandler] to write the response body to cache. + /// + /// `None`: the handler has not been set or already finished + pub fn miss_handler(&mut self) -> Option<&mut MissHandler> { + match self.phase { + CachePhase::Miss | CachePhase::Expired => self.inner_mut().miss_handler.as_mut(), + _ => panic!("wrong phase {:?}", self.phase), + } + } + + /// Finish cache admission + /// + /// If [self] is dropped without calling this, the cache admission is considered incomplete and + /// should be cleaned up. + /// + /// This call will also trigger eviction if set. + pub async fn finish_miss_handler(&mut self) -> Result<()> { + match self.phase { + CachePhase::Miss | CachePhase::Expired => { + let inner = self.inner_mut(); + if inner.miss_handler.is_none() { + // already finished, we allow calling this function more than once + return Ok(()); + } + let miss_handler = inner.miss_handler.take().unwrap(); + let size = miss_handler.finish().await?; + let lock = inner.lock.take(); + let key = inner.key.as_ref().unwrap(); + if let Some(Locked::Write(_r)) = lock { + // no need to call r.unlock() because release() will call it + // r is a guard to make sure the lock is unlocked when this request is dropped + inner.cache_lock.unwrap().release(key, LockStatus::Done); + } + if let Some(eviction) = inner.eviction { + let cache_key = key.to_compact(); + let meta = inner.meta.as_ref().unwrap(); + let evicted = eviction.admit(cache_key, size, meta.0.internal.fresh_until); + // TODO: make this async + let span = inner.traces.child("eviction"); + let handle = span.handle(); + for item in evicted { + // TODO: warn/log the error + let _ = inner.storage.purge(&item, &handle).await; + } + } + inner.traces.finish_miss_span(); + Ok(()) + } + _ => panic!("wrong phase {:?}", self.phase), + } + } + + /// Set the [CacheMeta] of the cache + pub fn set_cache_meta(&mut self, meta: CacheMeta) { + match self.phase { + // TODO: store the staled meta somewhere else for future use? + CachePhase::Stale | CachePhase::Miss => { + let inner = self.inner_mut(); + inner.traces.log_meta(&meta); + inner.meta = Some(meta); + } + _ => panic!("wrong phase {:?}", self.phase), + } + if self.phase == CachePhase::Stale { + self.phase = CachePhase::Expired; + } + } + + /// Set the [CacheMeta] of the cache after revalidation. + /// + /// Certain info such as the original cache admission time will be preserved. Others will + /// be replaced by the input `meta`. + pub async fn revalidate_cache_meta(&mut self, mut meta: CacheMeta) -> Result { + let result = match self.phase { + CachePhase::Stale => { + let inner = self.inner_mut(); + // TODO: we should keep old meta in place, just use new one to update it + // that requires cacheable_filter to take a mut header and just return InternalMeta + + // update new meta with old meta's created time + let created = inner.meta.as_ref().unwrap().0.internal.created; + meta.0.internal.created = created; + // meta.internal.updated was already set to new meta's `created`, + // no need to set `updated` here + + inner.meta.replace(meta); + + let lock = inner.lock.take(); + if let Some(Locked::Write(_r)) = lock { + inner + .cache_lock + .unwrap() + .release(inner.key.as_ref().unwrap(), LockStatus::Done); + } + + let mut span = inner.traces.child("update_meta"); + // TODO: this call can be async + let result = inner + .storage + .update_meta( + inner.key.as_ref().unwrap(), + inner.meta.as_ref().unwrap(), + &span.handle(), + ) + .await; + span.set_tag(|| trace::Tag::new("updated", result.is_ok())); + result + } + _ => panic!("wrong phase {:?}", self.phase), + }; + self.phase = CachePhase::Revalidated; + result + } + + /// After a successful revalidation, update certain headers for the cached asset + /// such as `Etag` with the fresh response header `resp`. + pub fn revalidate_merge_header(&mut self, resp: &RespHeader) -> ResponseHeader { + match self.phase { + CachePhase::Stale => { + /* + * https://datatracker.ietf.org/doc/html/rfc9110#section-15.4.5 + * 304 response MUST generate ... would have been sent in a 200 ... + * - Content-Location, Date, ETag, and Vary + * - Cache-Control and Expires... + */ + let mut old_header = self.inner().meta.as_ref().unwrap().0.header.clone(); + let mut clone_header = |header_name: &'static str| { + // TODO: multiple headers + if let Some(value) = resp.headers.get(header_name) { + old_header.insert_header(header_name, value).unwrap(); + } + }; + clone_header("cache-control"); + clone_header("expires"); + clone_header("cache-tag"); + clone_header("cdn-cache-control"); + clone_header("etag"); + // https://datatracker.ietf.org/doc/html/rfc9111#section-4.3.4 + // "...cache MUST update its header fields with the header fields provided in the 304..." + // But if the Vary header changes, the cached response may no longer match the + // incoming request. + // + // For simplicity, ignore changing Vary in revalidation for now. + // TODO: if we support vary during revalidation, there are a few edge cases to + // consider (what if Vary header appears/disappears/changes)? + // + // clone_header("vary"); + old_header + } + _ => panic!("wrong phase {:?}", self.phase), + } + } + + /// Mark this asset uncacheable after revalidation + pub fn revalidate_uncacheable(&mut self, header: ResponseHeader, reason: NoCacheReason) { + match self.phase { + CachePhase::Stale => { + // replace cache meta header + self.inner_mut().meta.as_mut().unwrap().0.header = header; + } + _ => panic!("wrong phase {:?}", self.phase), + } + self.phase = CachePhase::RevalidatedNoCache(reason); + // TODO: remove this asset from cache once finished? + } + + /// Update the variance of the [CacheMeta]. + /// + /// Note that this process may change the lookup `key`, and eventually (when the asset is + /// written to storage) invalidate other cached variants under the same primary key as the + /// current asset. + pub fn update_variance(&mut self, variance: Option) { + // If this is a cache miss, we will simply update the variance in the meta. + // + // If this is an expired response, we will have to consider a few cases: + // + // **Case 1**: Variance was absent, but caller sets it now. + // We will just insert it into the meta. The current asset becomes the primary variant. + // Because the current location of the asset is already the primary variant, nothing else + // needs to be done. + // + // **Case 2**: Variance was present, but it changed or was removed. + // We want the current asset to take over the primary slot, in order to invalidate all + // other variants derived under the old Vary. + // + // **Case 3**: Variance did not change. + // Nothing needs to happen. + let inner = match self.phase { + CachePhase::Miss | CachePhase::Expired => self.inner_mut(), + _ => panic!("wrong phase {:?}", self.phase), + }; + + // Update the variance in the meta + if let Some(variance_hash) = variance.as_ref() { + inner + .meta + .as_mut() + .unwrap() + .set_variance_key(*variance_hash); + } else { + inner.meta.as_mut().unwrap().remove_variance(); + } + + // Change the lookup `key` if necessary, in order to admit asset into the primary slot + // instead of the secondary slot. + let key = inner.key.as_ref().unwrap(); + if let Some(old_variance) = key.get_variance_key().as_ref() { + // This is a secondary variant slot. + if Some(*old_variance) != variance.as_ref() { + // This new variance does not match the variance in the cache key we used to look + // up this asset. + // Drop the cache lock to avoid leaving a dangling lock + // (because we locked with the old cache key for the secondary slot) + // TODO: maybe we should try to signal waiting readers to compete for the primary key + // lock instead? we will not be modifying this secondary slot so it's not actually + // ready for readers + if let Some(lock) = inner.cache_lock.as_ref() { + lock.release(key, LockStatus::Done); + } + // Remove the `variance` from the `key`, so that we admit this asset into the + // primary slot. (`key` is used to tell storage where to write the data.) + inner.key.as_mut().unwrap().remove_variance_key(); + } + } + } + + /// Return the [CacheMeta] of this asset + /// + /// # Panic + /// Panic in phases which has no cache meta. + pub fn cache_meta(&self) -> &CacheMeta { + match self.phase { + // TODO: allow in Bypass phase? + CachePhase::Stale + | CachePhase::Expired + | CachePhase::Hit + | CachePhase::Revalidated + | CachePhase::RevalidatedNoCache(_) => self.inner().meta.as_ref().unwrap(), + CachePhase::Miss => { + // this is the async body read case, safe because body_reader is only set + // after meta is retrieved + if self.inner().body_reader.is_some() { + self.inner().meta.as_ref().unwrap() + } else { + panic!("wrong phase {:?}", self.phase); + } + } + + _ => panic!("wrong phase {:?}", self.phase), + } + } + + /// Return the [CacheMeta] of this asset if any + /// + /// Different from [Self::cache_meta()], this function is allowed to be called in + /// [CachePhase::Miss] phase where the cache meta maybe set. + /// # Panic + /// Panic in phases that shouldn't have cache meta. + pub fn maybe_cache_meta(&self) -> Option<&CacheMeta> { + match self.phase { + CachePhase::Miss + | CachePhase::Stale + | CachePhase::Expired + | CachePhase::Hit + | CachePhase::Revalidated + | CachePhase::RevalidatedNoCache(_) => self.inner().meta.as_ref(), + _ => panic!("wrong phase {:?}", self.phase), + } + } + + /// Perform the cache lookup from the given cache storage with the given cache key + /// + /// A cache hit will return [CacheMeta] which contains the header and meta info about + /// the cache as well as a [HitHandler] to read the cache hit body. + /// # Panic + /// Panic in other phases. + pub async fn cache_lookup(&mut self) -> Result> { + match self.phase { + // Stale is allowed here because stale-> cache_lock -> lookup again + CachePhase::CacheKey | CachePhase::Stale => { + let inner = self.inner_mut(); + let mut span = inner.traces.child("lookup"); + let key = inner.key.as_ref().unwrap(); // safe, this phase should have cache key + let result = inner.storage.lookup(key, &span.handle()).await?; + let result = result.and_then(|(meta, header)| { + if let Some(ts) = inner.valid_after { + if meta.created() < ts { + span.set_tag(|| trace::Tag::new("not valid", true)); + return None; + } + } + Some((meta, header)) + }); + if result.is_none() { + if let Some(lock) = inner.cache_lock.as_ref() { + inner.lock = Some(lock.lock(key)); + } + } + span.set_tag(|| trace::Tag::new("found", result.is_some())); + Ok(result) + } + _ => panic!("wrong phase {:?}", self.phase), + } + } + + /// Update variance and see if the meta matches the current variance + /// + /// `cache_lookup() -> compute vary hash -> cache_vary_lookup()` + /// This function allows callers to compute vary based on the initial cache hit. + /// `meta` should be the ones returned from the initial cache_lookup() + /// - return true if the meta is the variance. + /// - return false if the current meta doesn't match the variance, need to cache_lookup() again + pub fn cache_vary_lookup(&mut self, variance: HashBinary, meta: &CacheMeta) -> bool { + match self.phase { + CachePhase::CacheKey => { + let inner = self.inner_mut(); + // make sure that all variance found are fresher than this asset + // this is because when purging all the variance, only the primary slot is deleted + // the created TS of the primary is the tombstone of all the variances + inner.valid_after = Some(meta.created()); + + // update vary + let key = inner.key.as_mut().unwrap(); + // if no variance was previously set, then this is the first cache hit + let is_initial_cache_hit = key.get_variance_key().is_none(); + key.set_variance_key(variance); + let variance_binary = key.variance_bin(); + let matches_variance = meta.variance() == variance_binary; + + // We should remove the variance in the lookup `key` if this is the primary variant + // slot. We know this is the primary variant slot if this is the initial cache hit + // AND the variance in the `key` already matches the `meta`'s.) + // + // For the primary variant slot, the storage backend needs to use the primary key + // for both cache lookup and updating the meta. Otherwise it will look for the + // asset in the wrong location during revalidation. + // + // We can recreate the "full" cache key by using the meta's variance, if needed. + if matches_variance && is_initial_cache_hit { + inner.key.as_mut().unwrap().remove_variance_key(); + } + + matches_variance + } + _ => panic!("wrong phase {:?}", self.phase), + } + } + + /// Whether this request is behind a cache lock in order to wait for another request to read the + /// asset. + pub fn is_cache_locked(&self) -> bool { + matches!(self.inner().lock, Some(Locked::Read(_))) + } + + /// Whether this request is the leader request to fetch the assets for itself and other requests + /// behind the cache lock. + pub fn is_cache_lock_writer(&self) -> bool { + matches!(self.inner().lock, Some(Locked::Write(_))) + } + + /// Take the write lock from this request to transfer it to another one. + /// # Panic + /// Call is_cache_lock_writer() to check first, will panic otherwise. + pub fn take_write_lock(&mut self) -> WritePermit { + let lock = self.inner_mut().lock.take().unwrap(); + match lock { + Locked::Write(w) => w, + Locked::Read(_) => panic!("take_write_lock() called on read lock"), + } + } + + /// Set the write lock, which is usually transferred from [Self::take_write_lock()] + pub fn set_write_lock(&mut self, write_lock: WritePermit) { + self.inner_mut().lock.replace(Locked::Write(write_lock)); + } + + /// Whether this request's cache hit is staled + fn has_staled_asset(&self) -> bool { + self.phase == CachePhase::Stale + } + + /// Whether this asset is staled and stale if error is allowed + pub fn can_serve_stale_error(&self) -> bool { + self.has_staled_asset() && self.cache_meta().serve_stale_if_error(SystemTime::now()) + } + + /// Whether this asset is staled and stale while revalidate is allowed. + pub fn can_serve_stale_updating(&self) -> bool { + self.has_staled_asset() + && self + .cache_meta() + .serve_stale_while_revalidate(SystemTime::now()) + } + + /// Wait for the cache read lock to be unlocked + /// # Panic + /// Check [Self::is_cache_locked()], panic if this request doesn't have a read lock. + pub async fn cache_lock_wait(&mut self) -> LockStatus { + let inner = self.inner_mut(); + let _span = inner.traces.child("cache_lock"); + let lock = inner.lock.take(); // remove the lock from self + if let Some(Locked::Read(r)) = lock { + let now = std::time::Instant::now(); + r.wait().await; + let lock_duration = now.elapsed(); + // it's possible for a request to be locked more than once + inner.lock_duration = Some( + inner + .lock_duration + .map_or(lock_duration, |d| d + lock_duration), + ); + r.lock_status() // TODO: tag the span with lock status + } else { + // should always call is_cache_locked() before this function + panic!("cache_lock_wait on wrong type of lock") + } + } + + /// How long did this request wait behind the read lock + pub fn lock_duration(&self) -> Option { + // FIXME: this duration is lost when cache is disabled + self.inner.as_ref().and_then(|i| i.lock_duration) + } + + /// Delete the asset from the cache storage + /// # Panic + /// Need to be called after cache key is set. Panic otherwise. + pub async fn purge(&mut self) -> Result { + match self.phase { + CachePhase::CacheKey => { + let inner = self.inner_mut(); + let mut span = inner.traces.child("purge"); + let key = inner.key.as_ref().unwrap().to_compact(); + let result = inner.storage.purge(&key, &span.handle()).await; + // FIXME: also need to remove from eviction manager + span.set_tag(|| trace::Tag::new("purged", matches!(result, Ok(true)))); + result + } + _ => panic!("wrong phase {:?}", self.phase), + } + } + + /// Check the cacheable prediction + /// + /// Return true if the predictor is not set + pub fn cacheable_prediction(&self) -> bool { + if let Some(predictor) = self.inner().predictor { + predictor.cacheable_prediction(self.cache_key()) + } else { + true + } + } + + /// Tell the predictor that this response which is previously predicted to be uncacheable + /// is cacheable now. + pub fn response_became_cacheable(&self) { + if let Some(predictor) = self.inner().predictor { + predictor.mark_cacheable(self.cache_key()); + } + } + + /// Tell the predictor that this response is uncacheable so that it will know next time + /// this request arrives. + pub fn response_became_uncacheable(&self, reason: NoCacheReason) { + if let Some(predictor) = self.inner().predictor { + predictor.mark_uncacheable(self.cache_key(), reason); + } + } +} + +/// Set the header compression dictionary that help serialize http header. +/// +/// Return false if it is already set. +pub fn set_compression_dict_path(path: &str) -> bool { + crate::meta::COMPRESSION_DICT_PATH + .set(path.to_string()) + .is_ok() +} diff --git a/pingora-cache/src/lock.rs b/pingora-cache/src/lock.rs new file mode 100644 index 0000000..c5e3c31 --- /dev/null +++ b/pingora-cache/src/lock.rs @@ -0,0 +1,336 @@ +// 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. + +//! Cache lock + +use crate::key::CacheHashKey; + +use crate::hashtable::ConcurrentHashTable; +use pingora_timeout::timeout; +use std::sync::Arc; + +const N_SHARDS: usize = 16; + +/// The global cache locking manager +pub struct CacheLock { + lock_table: ConcurrentHashTable, + timeout: Duration, // fixed timeout value for now +} + +/// A struct prepresenting a locked cache access +#[derive(Debug)] +pub enum Locked { + /// The writer is allowed to fetch the asset + Write(WritePermit), + /// The reader waits for the writer to fetch the asset + Read(ReadLock), +} + +impl Locked { + /// Is this a write lock + pub fn is_write(&self) -> bool { + matches!(self, Self::Write(_)) + } +} + +impl CacheLock { + /// Create a new [CacheLock] with the given lock timeout + /// + /// When the timeout is reached, the read locks are automatically unlocked + pub fn new(timeout: Duration) -> Self { + CacheLock { + lock_table: ConcurrentHashTable::new(), + timeout, + } + } + + /// Try to lock a cache fetch + /// + /// Users should call after a cache miss before fetching the asset. + /// The returned [Locked] will tell the caller either to fetch or wait. + pub fn lock(&self, key: &K) -> Locked { + let hash = key.combined_bin(); + let key = u128::from_be_bytes(hash); // endianness doesn't matter + let table = self.lock_table.get(key); + if let Some(lock) = table.read().get(&key) { + // already has an ongoing request + if lock.0.lock_status() != LockStatus::Dangling { + return Locked::Read(lock.read_lock()); + } + // Dangling: the previous writer quit without unlocking the lock. Requests should + // compete for the write lock again. + } + + let (permit, stub) = WritePermit::new(self.timeout); + let mut table = table.write(); + // check again in case another request already added it + if let Some(lock) = table.get(&key) { + if lock.0.lock_status() != LockStatus::Dangling { + return Locked::Read(lock.read_lock()); + } + } + table.insert(key, stub); + Locked::Write(permit) + } + + /// Release a lock for the given key + /// + /// When the write lock is dropped without being released, the read lock holders will consider + /// it to be failed so that they will compete for the write lock again. + pub fn release(&self, key: &K, reason: LockStatus) { + let hash = key.combined_bin(); + let key = u128::from_be_bytes(hash); // endianness doesn't matter + if let Some(lock) = self.lock_table.write(key).remove(&key) { + // make sure that the caller didn't forget to unlock it + if lock.0.locked() { + lock.0.unlock(reason); + } + } + } +} + +use std::sync::atomic::{AtomicU8, Ordering}; +use std::time::{Duration, Instant}; +use tokio::sync::Semaphore; + +/// Status which the read locks could possibly see. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum LockStatus { + /// Waiting for the writer to populate the asset + Waiting, + /// The writer finishes, readers can start + Done, + /// The writer encountered error, such as network issue. A new writer will be elected. + TransientError, + /// The writer observed that no cache lock is needed (e.g., uncacheable), readers should start + /// to fetch independently without a new writer + GiveUp, + /// The write lock is dropped without being unlocked + Dangling, + /// The lock is held for too long + Timeout, +} + +impl From for u8 { + fn from(l: LockStatus) -> u8 { + match l { + LockStatus::Waiting => 0, + LockStatus::Done => 1, + LockStatus::TransientError => 2, + LockStatus::GiveUp => 3, + LockStatus::Dangling => 4, + LockStatus::Timeout => 5, + } + } +} + +impl From for LockStatus { + fn from(v: u8) -> Self { + match v { + 0 => Self::Waiting, + 1 => Self::Done, + 2 => Self::TransientError, + 3 => Self::GiveUp, + 4 => Self::Dangling, + 5 => Self::Timeout, + _ => Self::GiveUp, // placeholder + } + } +} + +#[derive(Debug)] +struct LockCore { + pub lock_start: Instant, + pub timeout: Duration, + pub(super) lock: Semaphore, + // use u8 for Atomic enum + lock_status: AtomicU8, +} + +impl LockCore { + pub fn new_arc(timeout: Duration) -> Arc { + Arc::new(LockCore { + lock: Semaphore::new(0), + timeout, + lock_start: Instant::now(), + lock_status: AtomicU8::new(LockStatus::Waiting.into()), + }) + } + + fn locked(&self) -> bool { + self.lock.available_permits() == 0 + } + + fn unlock(&self, reason: LockStatus) { + self.lock_status.store(reason.into(), Ordering::SeqCst); + // any small positive number will do, 10 is used for RwLock too + // no need to wake up all at once + self.lock.add_permits(10); + } + + fn lock_status(&self) -> LockStatus { + self.lock_status.load(Ordering::Relaxed).into() + } +} + +// all 3 structs below are just Arc with different interfaces + +/// ReadLock: requests who get it need to wait until it is released +#[derive(Debug)] +pub struct ReadLock(Arc); + +impl ReadLock { + /// Wait for the writer to release the lock + pub async fn wait(&self) { + if !self.locked() || self.expired() { + return; + } + + // TODO: should subtract now - start so that the lock don't wait beyond start + timeout + // Also need to be careful not to wake everyone up at the same time + // (maybe not an issue because regular cache lock release behaves that way) + let _ = timeout(self.0.timeout, self.0.lock.acquire()).await; + // permit is returned to Semaphore right away + } + + /// Test if it is still locked + pub fn locked(&self) -> bool { + self.0.locked() + } + + /// Whether the lock is expired, e.g., the writer has been holding the lock for too long + pub fn expired(&self) -> bool { + // NOTE: this whether the lock is currently expired + // not whether it was timed out during wait() + self.0.lock_start.elapsed() >= self.0.timeout + } + + /// The current status of the lock + pub fn lock_status(&self) -> LockStatus { + let status = self.0.lock_status(); + if matches!(status, LockStatus::Waiting) && self.expired() { + LockStatus::Timeout + } else { + status + } + } +} + +/// WritePermit: requires who get it need to populate the cache and then release it +#[derive(Debug)] +pub struct WritePermit(Arc); + +impl WritePermit { + fn new(timeout: Duration) -> (WritePermit, LockStub) { + let lock = LockCore::new_arc(timeout); + let stub = LockStub(lock.clone()); + (WritePermit(lock), stub) + } + + fn unlock(&self, reason: LockStatus) { + self.0.unlock(reason) + } +} + +impl Drop for WritePermit { + fn drop(&mut self) { + // writer exit without properly unlock, let others to compete for the write lock again + if self.0.locked() { + self.unlock(LockStatus::Dangling); + } + } +} + +struct LockStub(Arc); +impl LockStub { + pub fn read_lock(&self) -> ReadLock { + ReadLock(self.0.clone()) + } +} + +#[cfg(test)] +mod test { + use super::*; + use crate::CacheKey; + + #[test] + fn test_get_release() { + let cache_lock = CacheLock::new(Duration::from_secs(1000)); + let key1 = CacheKey::new("", "a", "1"); + let locked1 = cache_lock.lock(&key1); + assert!(locked1.is_write()); // write permit + let locked2 = cache_lock.lock(&key1); + assert!(!locked2.is_write()); // read lock + cache_lock.release(&key1, LockStatus::Done); + let locked3 = cache_lock.lock(&key1); + assert!(locked3.is_write()); // write permit again + } + + #[tokio::test] + async fn test_lock() { + let cache_lock = CacheLock::new(Duration::from_secs(1000)); + let key1 = CacheKey::new("", "a", "1"); + let permit = match cache_lock.lock(&key1) { + Locked::Write(w) => w, + _ => panic!(), + }; + let lock = match cache_lock.lock(&key1) { + Locked::Read(r) => r, + _ => panic!(), + }; + assert!(lock.locked()); + let handle = tokio::spawn(async move { + lock.wait().await; + assert_eq!(lock.lock_status(), LockStatus::Done); + }); + permit.unlock(LockStatus::Done); + handle.await.unwrap(); // check lock is unlocked and the task is returned + } + + #[tokio::test] + async fn test_lock_timeout() { + let cache_lock = CacheLock::new(Duration::from_secs(1)); + let key1 = CacheKey::new("", "a", "1"); + let permit = match cache_lock.lock(&key1) { + Locked::Write(w) => w, + _ => panic!(), + }; + let lock = match cache_lock.lock(&key1) { + Locked::Read(r) => r, + _ => panic!(), + }; + assert!(lock.locked()); + + let handle = tokio::spawn(async move { + // timed out + lock.wait().await; + assert_eq!(lock.lock_status(), LockStatus::Timeout); + }); + + tokio::time::sleep(Duration::from_secs(2)).await; + + // expired lock + let lock2 = match cache_lock.lock(&key1) { + Locked::Read(r) => r, + _ => panic!(), + }; + assert!(lock2.locked()); + assert_eq!(lock2.lock_status(), LockStatus::Timeout); + lock2.wait().await; + assert_eq!(lock2.lock_status(), LockStatus::Timeout); + + permit.unlock(LockStatus::Done); + handle.await.unwrap(); + } +} diff --git a/pingora-cache/src/max_file_size.rs b/pingora-cache/src/max_file_size.rs new file mode 100644 index 0000000..7d812f2 --- /dev/null +++ b/pingora-cache/src/max_file_size.rs @@ -0,0 +1,75 @@ +// 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. + +//! Set limit on the largest size to cache + +use crate::storage::HandleMiss; +use crate::MissHandler; +use async_trait::async_trait; +use bytes::Bytes; +use pingora_error::{Error, ErrorType}; + +/// [MaxFileSizeMissHandler] wraps a MissHandler to enforce a maximum asset size that should be +/// written to the MissHandler. +/// +/// This is used to enforce a maximum cache size for a request when the +/// response size is not known ahead of time (no Content-Length header). When the response size _is_ +/// known ahead of time, it should be checked up front (when calculating cacheability) for efficiency. +/// Note: for requests with partial read support (where downstream reads the response from cache as +/// it is filled), this will cause the request as a whole to fail. The response will be remembered +/// as uncacheable, though, so downstream will be able to retry the request, since the cache will be +/// disabled for the retried request. +pub struct MaxFileSizeMissHandler { + inner: MissHandler, + max_file_size_bytes: usize, + bytes_written: usize, +} + +impl MaxFileSizeMissHandler { + /// Create a new [MaxFileSizeMissHandler] wrapping the given [MissHandler] + pub fn new(inner: MissHandler, max_file_size_bytes: usize) -> MaxFileSizeMissHandler { + MaxFileSizeMissHandler { + inner, + max_file_size_bytes, + bytes_written: 0, + } + } +} + +/// Error type returned when the limit is reached. +pub const ERR_RESPONSE_TOO_LARGE: ErrorType = ErrorType::Custom("response too large"); + +#[async_trait] +impl HandleMiss for MaxFileSizeMissHandler { + async fn write_body(&mut self, data: Bytes, eof: bool) -> pingora_error::Result<()> { + // fail if writing the body would exceed the max_file_size_bytes + if self.bytes_written + data.len() > self.max_file_size_bytes { + return Error::e_explain( + ERR_RESPONSE_TOO_LARGE, + format!( + "writing data of size {} bytes would exceed max file size of {} bytes", + data.len(), + self.max_file_size_bytes + ), + ); + } + + self.bytes_written += data.len(); + self.inner.write_body(data, eof).await + } + + async fn finish(self: Box) -> pingora_error::Result { + self.inner.finish().await + } +} diff --git a/pingora-cache/src/memory.rs b/pingora-cache/src/memory.rs new file mode 100644 index 0000000..679517d --- /dev/null +++ b/pingora-cache/src/memory.rs @@ -0,0 +1,510 @@ +// 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. + +//! Hash map based in memory cache +//! +//! For testing only, not for production use + +//TODO: Mark this module #[test] only + +use super::*; +use crate::key::{CacheHashKey, CompactCacheKey}; +use crate::storage::{HandleHit, HandleMiss, Storage}; +use crate::trace::SpanHandle; + +use async_trait::async_trait; +use bytes::Bytes; +use parking_lot::RwLock; +use pingora_error::*; +use std::any::Any; +use std::collections::HashMap; +use std::sync::Arc; +use tokio::sync::watch; + +type BinaryMeta = (Vec, Vec); + +pub(crate) struct CacheObject { + pub meta: BinaryMeta, + pub body: Arc>, +} + +pub(crate) struct TempObject { + pub meta: BinaryMeta, + // these are Arc because they need to continue exist after this TempObject is removed + pub body: Arc>>, + bytes_written: Arc>, // this should match body.len() +} + +impl TempObject { + fn new(meta: BinaryMeta) -> Self { + let (tx, _rx) = watch::channel(PartialState::Partial(0)); + TempObject { + meta, + body: Arc::new(RwLock::new(Vec::new())), + bytes_written: Arc::new(tx), + } + } + // this is not at all optimized + fn make_cache_object(&self) -> CacheObject { + let meta = self.meta.clone(); + let body = Arc::new(self.body.read().clone()); + CacheObject { meta, body } + } +} + +/// Hash map based in memory cache +/// +/// For testing only, not for production use. +pub struct MemCache { + pub(crate) cached: Arc>>, + pub(crate) temp: Arc>>, +} + +impl MemCache { + /// Create a new [MemCache] + pub fn new() -> Self { + MemCache { + cached: Arc::new(RwLock::new(HashMap::new())), + temp: Arc::new(RwLock::new(HashMap::new())), + } + } +} + +pub enum MemHitHandler { + Complete(CompleteHit), + Partial(PartialHit), +} + +#[derive(Copy, Clone)] +enum PartialState { + Partial(usize), + Complete(usize), +} + +pub struct CompleteHit { + body: Arc>, + done: bool, + range_start: usize, + range_end: usize, +} + +impl CompleteHit { + fn get(&mut self) -> Option { + if self.done { + None + } else { + self.done = true; + Some(Bytes::copy_from_slice( + &self.body.as_slice()[self.range_start..self.range_end], + )) + } + } + + fn seek(&mut self, start: usize, end: Option) -> Result<()> { + if start >= self.body.len() { + return Error::e_explain( + ErrorType::InternalError, + format!("seek start out of range {start} >= {}", self.body.len()), + ); + } + self.range_start = start; + if let Some(end) = end { + // end over the actual last byte is allowed, we just need to return the actual bytes + self.range_end = std::cmp::min(self.body.len(), end); + } + // seek resets read so that one handler can be used for multiple ranges + self.done = false; + Ok(()) + } +} + +pub struct PartialHit { + body: Arc>>, + bytes_written: watch::Receiver, + bytes_read: usize, +} + +impl PartialHit { + async fn read(&mut self) -> Option { + loop { + let bytes_written = *self.bytes_written.borrow_and_update(); + let bytes_end = match bytes_written { + PartialState::Partial(s) => s, + PartialState::Complete(c) => { + // no more data will arrive + if c == self.bytes_read { + return None; + } + c + } + }; + assert!(bytes_end >= self.bytes_read); + + // more data avaliable to read + if bytes_end > self.bytes_read { + let new_bytes = + Bytes::copy_from_slice(&self.body.read()[self.bytes_read..bytes_end]); + self.bytes_read = bytes_end; + return Some(new_bytes); + } + + // wait for more data + if self.bytes_written.changed().await.is_err() { + // err: sender dropped, body is finished + // FIXME: sender could drop because of an error + return None; + } + } + } +} + +#[async_trait] +impl HandleHit for MemHitHandler { + async fn read_body(&mut self) -> Result> { + match self { + Self::Complete(c) => Ok(c.get()), + Self::Partial(p) => Ok(p.read().await), + } + } + async fn finish( + self: Box, // because self is always used as a trait object + _storage: &'static (dyn storage::Storage + Sync), + _key: &CacheKey, + _trace: &SpanHandle, + ) -> Result<()> { + Ok(()) + } + + fn can_seek(&self) -> bool { + match self { + Self::Complete(_) => true, + Self::Partial(_) => false, // TODO: support seeking in partial reads + } + } + + fn seek(&mut self, start: usize, end: Option) -> Result<()> { + match self { + Self::Complete(c) => c.seek(start, end), + Self::Partial(_) => Error::e_explain( + ErrorType::InternalError, + "seek not supported for partial cache", + ), + } + } + + fn as_any(&self) -> &(dyn Any + Send + Sync) { + self + } +} + +pub struct MemMissHandler { + body: Arc>>, + bytes_written: Arc>, + // these are used only in finish() to to data from temp to cache + key: String, + cache: Arc>>, + temp: Arc>>, +} + +#[async_trait] +impl HandleMiss for MemMissHandler { + async fn write_body(&mut self, data: bytes::Bytes, eof: bool) -> Result<()> { + let current_bytes = match *self.bytes_written.borrow() { + PartialState::Partial(p) => p, + PartialState::Complete(_) => panic!("already EOF"), + }; + self.body.write().extend_from_slice(&data); + let written = current_bytes + data.len(); + let new_state = if eof { + PartialState::Complete(written) + } else { + PartialState::Partial(written) + }; + self.bytes_written.send_replace(new_state); + Ok(()) + } + + async fn finish(self: Box) -> Result { + // safe, the temp object is inserted when the miss handler is created + let cache_object = self.temp.read().get(&self.key).unwrap().make_cache_object(); + let size = cache_object.body.len(); // FIXME: this just body size, also track meta size + self.cache.write().insert(self.key.clone(), cache_object); + self.temp.write().remove(&self.key); + Ok(size) + } +} + +impl Drop for MemMissHandler { + fn drop(&mut self) { + self.temp.write().remove(&self.key); + } +} + +#[async_trait] +impl Storage for MemCache { + async fn lookup( + &'static self, + key: &CacheKey, + _trace: &SpanHandle, + ) -> Result> { + let hash = key.combined(); + // always prefer partial read otherwise fresh asset will not be visible on expired asset + // until it is fully updated + if let Some(temp_obj) = self.temp.read().get(&hash) { + let meta = CacheMeta::deserialize(&temp_obj.meta.0, &temp_obj.meta.1)?; + let partial = PartialHit { + body: temp_obj.body.clone(), + bytes_written: temp_obj.bytes_written.subscribe(), + bytes_read: 0, + }; + let hit_handler = MemHitHandler::Partial(partial); + Ok(Some((meta, Box::new(hit_handler)))) + } else if let Some(obj) = self.cached.read().get(&hash) { + let meta = CacheMeta::deserialize(&obj.meta.0, &obj.meta.1)?; + let hit_handler = CompleteHit { + body: obj.body.clone(), + done: false, + range_start: 0, + range_end: obj.body.len(), + }; + let hit_handler = MemHitHandler::Complete(hit_handler); + Ok(Some((meta, Box::new(hit_handler)))) + } else { + Ok(None) + } + } + + async fn get_miss_handler( + &'static self, + key: &CacheKey, + meta: &CacheMeta, + _trace: &SpanHandle, + ) -> Result { + // TODO: support multiple concurrent writes or panic if the is already a writer + let hash = key.combined(); + let meta = meta.serialize()?; + let temp_obj = TempObject::new(meta); + let miss_handler = MemMissHandler { + body: temp_obj.body.clone(), + bytes_written: temp_obj.bytes_written.clone(), + key: hash.clone(), + cache: self.cached.clone(), + temp: self.temp.clone(), + }; + self.temp.write().insert(hash, temp_obj); + Ok(Box::new(miss_handler)) + } + + async fn purge(&'static self, key: &CompactCacheKey, _trace: &SpanHandle) -> Result { + // TODO: purge partial + + // This usually purges the primary key because, without a lookup, variance key is usually + // empty + let hash = key.combined(); + Ok(self.cached.write().remove(&hash).is_some()) + } + + async fn update_meta( + &'static self, + key: &CacheKey, + meta: &CacheMeta, + _trace: &SpanHandle, + ) -> Result { + let hash = key.combined(); + if let Some(obj) = self.cached.write().get_mut(&hash) { + obj.meta = meta.serialize()?; + Ok(true) + } else { + panic!("no meta found") + } + } + + fn support_streaming_partial_write(&self) -> bool { + true + } + + fn as_any(&self) -> &(dyn Any + Send + Sync) { + self + } +} + +#[cfg(test)] +mod test { + use super::*; + use once_cell::sync::Lazy; + use rustracing::span::Span; + + fn gen_meta() -> CacheMeta { + let mut header = ResponseHeader::build(200, None).unwrap(); + header.append_header("foo1", "bar1").unwrap(); + header.append_header("foo2", "bar2").unwrap(); + header.append_header("foo3", "bar3").unwrap(); + header.append_header("Server", "Pingora").unwrap(); + let internal = crate::meta::InternalMeta::default(); + CacheMeta(Box::new(crate::meta::CacheMetaInner { + internal, + header, + extensions: http::Extensions::new(), + })) + } + + #[tokio::test] + async fn test_write_then_read() { + static MEM_CACHE: Lazy = Lazy::new(MemCache::new); + let span = &Span::inactive().handle(); + + let key1 = CacheKey::new("", "a", "1"); + let res = MEM_CACHE.lookup(&key1, span).await.unwrap(); + assert!(res.is_none()); + + let cache_meta = gen_meta(); + + let mut miss_handler = MEM_CACHE + .get_miss_handler(&key1, &cache_meta, span) + .await + .unwrap(); + miss_handler + .write_body(b"test1"[..].into(), false) + .await + .unwrap(); + miss_handler + .write_body(b"test2"[..].into(), false) + .await + .unwrap(); + miss_handler.finish().await.unwrap(); + + let (cache_meta2, mut hit_handler) = MEM_CACHE.lookup(&key1, span).await.unwrap().unwrap(); + assert_eq!( + cache_meta.0.internal.fresh_until, + cache_meta2.0.internal.fresh_until + ); + + let data = hit_handler.read_body().await.unwrap().unwrap(); + assert_eq!("test1test2", data); + let data = hit_handler.read_body().await.unwrap(); + assert!(data.is_none()); + } + + #[tokio::test] + async fn test_read_range() { + static MEM_CACHE: Lazy = Lazy::new(MemCache::new); + let span = &Span::inactive().handle(); + + let key1 = CacheKey::new("", "a", "1"); + let res = MEM_CACHE.lookup(&key1, span).await.unwrap(); + assert!(res.is_none()); + + let cache_meta = gen_meta(); + + let mut miss_handler = MEM_CACHE + .get_miss_handler(&key1, &cache_meta, span) + .await + .unwrap(); + miss_handler + .write_body(b"test1test2"[..].into(), false) + .await + .unwrap(); + miss_handler.finish().await.unwrap(); + + let (cache_meta2, mut hit_handler) = MEM_CACHE.lookup(&key1, span).await.unwrap().unwrap(); + assert_eq!( + cache_meta.0.internal.fresh_until, + cache_meta2.0.internal.fresh_until + ); + + // out of range + assert!(hit_handler.seek(10000, None).is_err()); + + assert!(hit_handler.seek(5, None).is_ok()); + let data = hit_handler.read_body().await.unwrap().unwrap(); + assert_eq!("test2", data); + let data = hit_handler.read_body().await.unwrap(); + assert!(data.is_none()); + + assert!(hit_handler.seek(4, Some(5)).is_ok()); + let data = hit_handler.read_body().await.unwrap().unwrap(); + assert_eq!("1", data); + let data = hit_handler.read_body().await.unwrap(); + assert!(data.is_none()); + } + + #[tokio::test] + async fn test_write_while_read() { + use futures::FutureExt; + + static MEM_CACHE: Lazy = Lazy::new(MemCache::new); + let span = &Span::inactive().handle(); + + let key1 = CacheKey::new("", "a", "1"); + let res = MEM_CACHE.lookup(&key1, span).await.unwrap(); + assert!(res.is_none()); + + let cache_meta = gen_meta(); + + let mut miss_handler = MEM_CACHE + .get_miss_handler(&key1, &cache_meta, span) + .await + .unwrap(); + + // first reader + let (cache_meta1, mut hit_handler1) = MEM_CACHE.lookup(&key1, span).await.unwrap().unwrap(); + assert_eq!( + cache_meta.0.internal.fresh_until, + cache_meta1.0.internal.fresh_until + ); + + // No body to read + let res = hit_handler1.read_body().now_or_never(); + assert!(res.is_none()); + + miss_handler + .write_body(b"test1"[..].into(), false) + .await + .unwrap(); + + let data = hit_handler1.read_body().await.unwrap().unwrap(); + assert_eq!("test1", data); + let res = hit_handler1.read_body().now_or_never(); + assert!(res.is_none()); + + miss_handler + .write_body(b"test2"[..].into(), false) + .await + .unwrap(); + let data = hit_handler1.read_body().await.unwrap().unwrap(); + assert_eq!("test2", data); + + // second reader + let (cache_meta2, mut hit_handler2) = MEM_CACHE.lookup(&key1, span).await.unwrap().unwrap(); + assert_eq!( + cache_meta.0.internal.fresh_until, + cache_meta2.0.internal.fresh_until + ); + + let data = hit_handler2.read_body().await.unwrap().unwrap(); + assert_eq!("test1test2", data); + let res = hit_handler2.read_body().now_or_never(); + assert!(res.is_none()); + + let res = hit_handler1.read_body().now_or_never(); + assert!(res.is_none()); + + miss_handler.finish().await.unwrap(); + + let data = hit_handler1.read_body().await.unwrap(); + assert!(data.is_none()); + let data = hit_handler2.read_body().await.unwrap(); + assert!(data.is_none()); + } +} diff --git a/pingora-cache/src/meta.rs b/pingora-cache/src/meta.rs new file mode 100644 index 0000000..a534dc0 --- /dev/null +++ b/pingora-cache/src/meta.rs @@ -0,0 +1,608 @@ +// 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. + +//! Metadata for caching + +use http::Extensions; +use pingora_error::{Error, ErrorType::*, OrErr, Result}; +use pingora_http::{HMap, ResponseHeader}; +use serde::{Deserialize, Serialize}; +use std::time::{Duration, SystemTime}; + +use crate::key::HashBinary; + +pub(crate) type InternalMeta = internal_meta::InternalMetaLatest; +mod internal_meta { + use super::*; + + pub(crate) type InternalMetaLatest = InternalMetaV2; + + #[derive(Debug, Deserialize, Serialize, Clone)] + pub(crate) struct InternalMetaV0 { + pub(crate) fresh_until: SystemTime, + pub(crate) created: SystemTime, + pub(crate) stale_while_revalidate_sec: u32, + pub(crate) stale_if_error_sec: u32, + // Do not add more field + } + + impl InternalMetaV0 { + #[allow(dead_code)] + fn serialize(&self) -> Result> { + rmp_serde::encode::to_vec(self).or_err(InternalError, "failed to encode cache meta") + } + + fn deserialize(buf: &[u8]) -> Result { + rmp_serde::decode::from_slice(buf) + .or_err(InternalError, "failed to decode cache meta v0") + } + } + + #[derive(Debug, Deserialize, Serialize, Clone)] + pub(crate) struct InternalMetaV1 { + pub(crate) version: u8, + pub(crate) fresh_until: SystemTime, + pub(crate) created: SystemTime, + pub(crate) stale_while_revalidate_sec: u32, + pub(crate) stale_if_error_sec: u32, + // Do not add more field + } + + impl InternalMetaV1 { + #[allow(dead_code)] + pub const VERSION: u8 = 1; + + #[allow(dead_code)] + pub fn serialize(&self) -> Result> { + assert_eq!(self.version, 1); + rmp_serde::encode::to_vec(self).or_err(InternalError, "failed to encode cache meta") + } + + fn deserialize(buf: &[u8]) -> Result { + rmp_serde::decode::from_slice(buf) + .or_err(InternalError, "failed to decode cache meta v1") + } + } + + #[derive(Debug, Deserialize, Serialize, Clone)] + pub(crate) struct InternalMetaV2 { + pub(crate) version: u8, + pub(crate) fresh_until: SystemTime, + pub(crate) created: SystemTime, + pub(crate) updated: SystemTime, + pub(crate) stale_while_revalidate_sec: u32, + pub(crate) stale_if_error_sec: u32, + // Only the extended field to be added below. One field at a time. + // 1. serde default in order to accept an older version schema without the field existing + // 2. serde skip_serializing_if in order for software with only an older version of this + // schema to decode it + // After full releases, remove `skip_serializing_if` so that we can add the next extended field. + #[serde(default)] + #[serde(skip_serializing_if = "Option::is_none")] + pub(crate) variance: Option, + } + + impl Default for InternalMetaV2 { + fn default() -> Self { + let epoch = SystemTime::UNIX_EPOCH; + InternalMetaV2 { + version: InternalMetaV2::VERSION, + fresh_until: epoch, + created: epoch, + updated: epoch, + stale_while_revalidate_sec: 0, + stale_if_error_sec: 0, + variance: None, + } + } + } + + impl InternalMetaV2 { + pub const VERSION: u8 = 2; + + pub fn serialize(&self) -> Result> { + assert_eq!(self.version, Self::VERSION); + rmp_serde::encode::to_vec(self).or_err(InternalError, "failed to encode cache meta") + } + + fn deserialize(buf: &[u8]) -> Result { + rmp_serde::decode::from_slice(buf) + .or_err(InternalError, "failed to decode cache meta v2") + } + } + + impl From for InternalMetaV2 { + fn from(v0: InternalMetaV0) -> Self { + InternalMetaV2 { + version: InternalMetaV2::VERSION, + fresh_until: v0.fresh_until, + created: v0.created, + updated: v0.created, + stale_while_revalidate_sec: v0.stale_while_revalidate_sec, + stale_if_error_sec: v0.stale_if_error_sec, + ..Default::default() + } + } + } + + impl From for InternalMetaV2 { + fn from(v1: InternalMetaV1) -> Self { + InternalMetaV2 { + version: InternalMetaV2::VERSION, + fresh_until: v1.fresh_until, + created: v1.created, + updated: v1.created, + stale_while_revalidate_sec: v1.stale_while_revalidate_sec, + stale_if_error_sec: v1.stale_if_error_sec, + ..Default::default() + } + } + } + + // cross version decode + pub(crate) fn deserialize(buf: &[u8]) -> Result { + const MIN_SIZE: usize = 10; // a small number to read the first few bytes + if buf.len() < MIN_SIZE { + return Error::e_explain( + InternalError, + format!("Buf too short ({}) to be InternalMeta", buf.len()), + ); + } + let preread_buf = &mut &buf[..MIN_SIZE]; + // the struct is always packed as a fixed size array + match rmp::decode::read_array_len(preread_buf) + .or_err(InternalError, "failed to decode cache meta array size")? + { + // v0 has 4 items and no version number + 4 => Ok(InternalMetaV0::deserialize(buf)?.into()), + // other V should has version number encoded + _ => { + // rmp will encode version < 128 into a fixint (one byte), + // so we use read_pfix + let version = rmp::decode::read_pfix(preread_buf) + .or_err(InternalError, "failed to decode meta version")?; + match version { + 1 => Ok(InternalMetaV1::deserialize(buf)?.into()), + 2 => InternalMetaV2::deserialize(buf), + _ => Error::e_explain( + InternalError, + format!("Unknown InternalMeta version {version}"), + ), + } + } + } + } + + #[cfg(test)] + mod tests { + use super::*; + + #[test] + fn test_internal_meta_serde_v0() { + let meta = InternalMetaV0 { + fresh_until: SystemTime::now(), + created: SystemTime::now(), + stale_while_revalidate_sec: 0, + stale_if_error_sec: 0, + }; + let binary = meta.serialize().unwrap(); + let meta2 = InternalMetaV0::deserialize(&binary).unwrap(); + assert_eq!(meta.fresh_until, meta2.fresh_until); + } + + #[test] + fn test_internal_meta_serde_v1() { + let meta = InternalMetaV1 { + version: InternalMetaV1::VERSION, + fresh_until: SystemTime::now(), + created: SystemTime::now(), + stale_while_revalidate_sec: 0, + stale_if_error_sec: 0, + }; + let binary = meta.serialize().unwrap(); + let meta2 = InternalMetaV1::deserialize(&binary).unwrap(); + assert_eq!(meta.fresh_until, meta2.fresh_until); + } + + #[test] + fn test_internal_meta_serde_v2() { + let meta = InternalMetaV2::default(); + let binary = meta.serialize().unwrap(); + let meta2 = InternalMetaV2::deserialize(&binary).unwrap(); + assert_eq!(meta2.version, 2); + assert_eq!(meta.fresh_until, meta2.fresh_until); + assert_eq!(meta.created, meta2.created); + assert_eq!(meta.updated, meta2.updated); + } + + #[test] + fn test_internal_meta_serde_across_versions() { + let meta = InternalMetaV0 { + fresh_until: SystemTime::now(), + created: SystemTime::now(), + stale_while_revalidate_sec: 0, + stale_if_error_sec: 0, + }; + let binary = meta.serialize().unwrap(); + let meta2 = deserialize(&binary).unwrap(); + assert_eq!(meta2.version, 2); + assert_eq!(meta.fresh_until, meta2.fresh_until); + + let meta = InternalMetaV1 { + version: 1, + fresh_until: SystemTime::now(), + created: SystemTime::now(), + stale_while_revalidate_sec: 0, + stale_if_error_sec: 0, + }; + let binary = meta.serialize().unwrap(); + let meta2 = deserialize(&binary).unwrap(); + assert_eq!(meta2.version, 2); + assert_eq!(meta.fresh_until, meta2.fresh_until); + // `updated` == `created` when upgrading to v2 + assert_eq!(meta2.created, meta2.updated); + } + + #[test] + fn test_internal_meta_serde_v2_extend_fields() { + // make sure that v2 format is backward compatible + // this is the base version of v2 without any extended fields + #[derive(Deserialize, Serialize)] + pub(crate) struct InternalMetaV2Base { + pub(crate) version: u8, + pub(crate) fresh_until: SystemTime, + pub(crate) created: SystemTime, + pub(crate) updated: SystemTime, + pub(crate) stale_while_revalidate_sec: u32, + pub(crate) stale_if_error_sec: u32, + } + + impl InternalMetaV2Base { + pub const VERSION: u8 = 2; + pub fn serialize(&self) -> Result> { + assert!(self.version >= Self::VERSION); + rmp_serde::encode::to_vec(self) + .or_err(InternalError, "failed to encode cache meta") + } + fn deserialize(buf: &[u8]) -> Result { + rmp_serde::decode::from_slice(buf) + .or_err(InternalError, "failed to decode cache meta v2") + } + } + + // ext V2 to base v2 + let meta = InternalMetaV2::default(); + let binary = meta.serialize().unwrap(); + let meta2 = InternalMetaV2Base::deserialize(&binary).unwrap(); + assert_eq!(meta2.version, 2); + assert_eq!(meta.fresh_until, meta2.fresh_until); + assert_eq!(meta.created, meta2.created); + assert_eq!(meta.updated, meta2.updated); + + // base V2 to ext v2 + let now = SystemTime::now(); + let meta = InternalMetaV2Base { + version: InternalMetaV2::VERSION, + fresh_until: now, + created: now, + updated: now, + stale_while_revalidate_sec: 0, + stale_if_error_sec: 0, + }; + let binary = meta.serialize().unwrap(); + let meta2 = InternalMetaV2::deserialize(&binary).unwrap(); + assert_eq!(meta2.version, 2); + assert_eq!(meta.fresh_until, meta2.fresh_until); + assert_eq!(meta.created, meta2.created); + assert_eq!(meta.updated, meta2.updated); + } + } +} + +#[derive(Debug)] +pub(crate) struct CacheMetaInner { + // http header and Internal meta have different ways of serialization, so keep them separated + pub(crate) internal: InternalMeta, + pub(crate) header: ResponseHeader, + /// An opaque type map to hold extra information for communication between cache backends + /// and users. This field is **not** garanteed be persistently stored in the cache backend. + pub extensions: Extensions, +} + +/// The cacheable response header and cache metadata +#[derive(Debug)] +pub struct CacheMeta(pub(crate) Box); + +impl CacheMeta { + /// Create a [CacheMeta] from the given metadata and the response header + pub fn new( + fresh_until: SystemTime, + created: SystemTime, + stale_while_revalidate_sec: u32, + stale_if_error_sec: u32, + header: ResponseHeader, + ) -> CacheMeta { + CacheMeta(Box::new(CacheMetaInner { + internal: InternalMeta { + version: InternalMeta::VERSION, + fresh_until, + created, + updated: created, // created == updated for new meta + stale_while_revalidate_sec, + stale_if_error_sec, + ..Default::default() + }, + header, + extensions: Extensions::new(), + })) + } + + /// When the asset was created/admitted to cache + pub fn created(&self) -> SystemTime { + self.0.internal.created + } + + /// The last time the asset was revalidated + /// + /// This value will be the same as [Self::created()] if no revalidation ever happens + pub fn updated(&self) -> SystemTime { + self.0.internal.updated + } + + /// Is the asset still valid + pub fn is_fresh(&self, time: SystemTime) -> bool { + // NOTE: HTTP cache time resolution is second + self.0.internal.fresh_until >= time + } + + /// How long (in seconds) the asset should be fresh since its admission/revalidation + /// + /// This is essentially the max-age value (or its equivalence) + pub fn fresh_sec(&self) -> u64 { + // swallow `duration_since` error, assets that are always stale have earlier `fresh_until` than `created` + // practically speaking we can always treat these as 0 ttl + // XXX: return Error if `fresh_until` is much earlier than expected? + self.0 + .internal + .fresh_until + .duration_since(self.0.internal.updated) + .map_or(0, |duration| duration.as_secs()) + } + + /// Until when the asset is considered fresh + pub fn fresh_until(&self) -> SystemTime { + self.0.internal.fresh_until + } + + /// How old the asset is since its admission/revalidation + pub fn age(&self) -> Duration { + SystemTime::now() + .duration_since(self.updated()) + .unwrap_or_default() + } + + /// The stale-while-revalidate limit in seconds + pub fn stale_while_revalidate_sec(&self) -> u32 { + self.0.internal.stale_while_revalidate_sec + } + + /// The stale-if-error limit in seconds + pub fn stale_if_error_sec(&self) -> u32 { + self.0.internal.stale_if_error_sec + } + + /// Can the asset be used to serve stale during revalidation at the given time. + /// + /// NOTE: the serve stale functions do not check !is_fresh(time), + /// i.e. the object is already assumed to be stale. + pub fn serve_stale_while_revalidate(&self, time: SystemTime) -> bool { + self.can_serve_stale(self.0.internal.stale_while_revalidate_sec, time) + } + + /// Can the asset be used to serve stale after error at the given time. + /// + /// NOTE: the serve stale functions do not check !is_fresh(time), + /// i.e. the object is already assumed to be stale. + pub fn serve_stale_if_error(&self, time: SystemTime) -> bool { + self.can_serve_stale(self.0.internal.stale_if_error_sec, time) + } + + /// Disable serve stale for this asset + pub fn disable_serve_stale(&mut self) { + self.0.internal.stale_if_error_sec = 0; + self.0.internal.stale_while_revalidate_sec = 0; + } + + /// Get the variance hash of this asset + pub fn variance(&self) -> Option { + self.0.internal.variance + } + + /// Set the variance key of this asset + pub fn set_variance_key(&mut self, variance_key: HashBinary) { + self.0.internal.variance = Some(variance_key); + } + + /// Set the variance (hash) of this asset + pub fn set_variance(&mut self, variance: HashBinary) { + self.0.internal.variance = Some(variance) + } + + /// Removes the variance (hash) of this asset + pub fn remove_variance(&mut self) { + self.0.internal.variance = None + } + + /// Get the response header in this asset + pub fn response_header(&self) -> &ResponseHeader { + &self.0.header + } + + /// Modify the header in this asset + pub fn response_header_mut(&mut self) -> &mut ResponseHeader { + &mut self.0.header + } + + /// Expose the extensions to read + pub fn extensions(&self) -> &Extensions { + &self.0.extensions + } + + /// Expose the extensions to modify + pub fn extensions_mut(&mut self) -> &mut Extensions { + &mut self.0.extensions + } + + /// Get a copy of the response header + pub fn response_header_copy(&self) -> ResponseHeader { + self.0.header.clone() + } + + /// get all the headers of this asset + pub fn headers(&self) -> &HMap { + &self.0.header.headers + } + + fn can_serve_stale(&self, serve_stale_sec: u32, time: SystemTime) -> bool { + if serve_stale_sec == 0 { + return false; + } + if let Some(stale_until) = self + .0 + .internal + .fresh_until + .checked_add(Duration::from_secs(serve_stale_sec.into())) + { + stale_until >= time + } else { + // overflowed: treat as infinite ttl + true + } + } + + /// Serialize this object + pub fn serialize(&self) -> Result<(Vec, Vec)> { + let internal = self.0.internal.serialize()?; + let header = header_serialize(&self.0.header)?; + Ok((internal, header)) + } + + /// Deserialize from the binary format + pub fn deserialize(internal: &[u8], header: &[u8]) -> Result { + let internal = internal_meta::deserialize(internal)?; + let header = header_deserialize(header)?; + Ok(CacheMeta(Box::new(CacheMetaInner { + internal, + header, + extensions: Extensions::new(), + }))) + } +} + +use http::StatusCode; + +/// The function to generate TTL from the given [StatusCode]. +pub type FreshSecByStatusFn = fn(StatusCode) -> Option; + +/// The default settings to generate [CacheMeta] +pub struct CacheMetaDefaults { + // if a status code is not included in fresh_sec, it's not considered cacheable by default. + fresh_sec_fn: FreshSecByStatusFn, + stale_while_revalidate_sec: u32, + // TODO: allow "error" condition to be configurable? + stale_if_error_sec: u32, +} + +impl CacheMetaDefaults { + /// Create a new [CacheMetaDefaults] + pub const fn new( + fresh_sec_fn: FreshSecByStatusFn, + stale_while_revalidate_sec: u32, + stale_if_error_sec: u32, + ) -> Self { + CacheMetaDefaults { + fresh_sec_fn, + stale_while_revalidate_sec, + stale_if_error_sec, + } + } + + /// Return the default TTL for the given [StatusCode] + /// + /// `None`: do no cache this code. + pub fn fresh_sec(&self, resp_status: StatusCode) -> Option { + // safe guard to make sure 304 response to share the same default ttl of 200 + if resp_status == StatusCode::NOT_MODIFIED { + (self.fresh_sec_fn)(StatusCode::OK) + } else { + (self.fresh_sec_fn)(resp_status) + } + } + + /// The default SWR seconds + pub fn serve_stale_while_revalidate_sec(&self) -> u32 { + self.stale_while_revalidate_sec + } + + /// The default SIE seconds + pub fn serve_stale_if_error_sec(&self) -> u32 { + self.stale_if_error_sec + } +} + +use log::warn; +use once_cell::sync::{Lazy, OnceCell}; +use pingora_header_serde::HeaderSerde; +use std::fs::File; +use std::io::Read; + +/* load header compression engine and its' dictionary globally */ +pub(crate) static COMPRESSION_DICT_PATH: OnceCell = OnceCell::new(); + +fn load_file(path: &String) -> Option> { + let mut file = File::open(path) + .map_err(|e| { + warn!( + "failed to open header compress dictionary file at {}, {:?}", + path, e + ); + e + }) + .ok()?; + let mut dict = Vec::new(); + file.read_to_end(&mut dict) + .map_err(|e| { + warn!( + "failed to read header compress dictionary file at {}, {:?}", + path, e + ); + e + }) + .ok()?; + + Some(dict) +} + +static HEADER_SERDE: Lazy = Lazy::new(|| { + let dict = COMPRESSION_DICT_PATH.get().and_then(load_file); + HeaderSerde::new(dict) +}); + +pub(crate) fn header_serialize(header: &ResponseHeader) -> Result> { + HEADER_SERDE.serialize(header) +} + +pub(crate) fn header_deserialize>(buf: T) -> Result { + HEADER_SERDE.deserialize(buf.as_ref()) +} diff --git a/pingora-cache/src/predictor.rs b/pingora-cache/src/predictor.rs new file mode 100644 index 0000000..df8f374 --- /dev/null +++ b/pingora-cache/src/predictor.rs @@ -0,0 +1,228 @@ +// 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. + +//! Cacheability Predictor + +use crate::hashtable::{ConcurrentLruCache, LruShard}; + +pub type CustomReasonPredicate = fn(&'static str) -> bool; + +/// Cacheability Predictor +/// +/// Remembers previously uncacheable assets. +/// Allows bypassing cache / cache lock early based on historical precedent. +/// +/// NOTE: to simply avoid caching requests with certain characteristics, +/// add checks in request_cache_filter to avoid enabling cache in the first place. +/// The predictor's bypass mechanism handles cases where the request _looks_ cacheable +/// but its previous responses suggest otherwise. The request _could_ be cacheable in the future. +pub struct Predictor { + uncacheable_keys: ConcurrentLruCache<(), N_SHARDS>, + skip_custom_reasons_fn: Option, +} + +use crate::{key::CacheHashKey, CacheKey, NoCacheReason}; +use log::debug; + +/// The cache predictor trait. +/// +/// This trait allows user defined predictor to replace [Predictor]. +pub trait CacheablePredictor { + /// Return true if likely cacheable, false if likely not. + fn cacheable_prediction(&self, key: &CacheKey) -> bool; + + /// Mark cacheable to allow next request to cache. + /// Returns false if the key was already marked cacheable. + fn mark_cacheable(&self, key: &CacheKey) -> bool; + + /// Mark uncacheable to actively bypass cache on the next request. + /// May skip marking on certain NoCacheReasons. + /// Returns None if we skipped marking uncacheable. + /// Returns Some(false) if the key was already marked uncacheable. + fn mark_uncacheable(&self, key: &CacheKey, reason: NoCacheReason) -> Option; +} + +// This particular bit of `where [LruShard...; N]: Default` nonsense arises from +// ConcurrentLruCache needing this trait bound, which in turns arises from the Rust +// compiler not being able to guarantee that all array sizes N implement `Default`. +// See https://github.com/rust-lang/rust/issues/61415 +impl Predictor +where + [LruShard<()>; N_SHARDS]: Default, +{ + /// Create a new Predictor with `N_SHARDS * shard_capacity` total capacity for + /// uncacheable cache keys. + /// + /// - `shard_capacity`: defines number of keys remembered as uncacheable per LRU shard. + /// - `skip_custom_reasons_fn`: an optional predicate used in `mark_uncacheable` + /// that can customize which `Custom` `NoCacheReason`s ought to be remembered as uncacheable. + /// If the predicate returns true, then the predictor will skip remembering the current + /// cache key as uncacheable (and avoid bypassing cache on the next request). + pub fn new( + shard_capacity: usize, + skip_custom_reasons_fn: Option, + ) -> Predictor { + Predictor { + uncacheable_keys: ConcurrentLruCache::<(), N_SHARDS>::new(shard_capacity), + skip_custom_reasons_fn, + } + } +} + +impl CacheablePredictor for Predictor +where + [LruShard<()>; N_SHARDS]: Default, +{ + fn cacheable_prediction(&self, key: &CacheKey) -> bool { + // variance key is ignored because this check happens before cache lookup + let hash = key.primary_bin(); + let key = u128::from_be_bytes(hash); // Endianness doesn't matter + + // Note: LRU updated in mark_* functions only, + // as we assume the caller always updates the cacheability of the response later + !self.uncacheable_keys.read(key).contains(&key) + } + + fn mark_cacheable(&self, key: &CacheKey) -> bool { + // variance key is ignored because cacheable_prediction() is called before cache lookup + // where the variance key is unknown + let hash = key.primary_bin(); + let key = u128::from_be_bytes(hash); + + let cache = self.uncacheable_keys.get(key); + if !cache.read().contains(&key) { + // not in uncacheable list, nothing to do + return true; + } + + let mut cache = cache.write(); + cache.pop(&key); + debug!("bypassed request became cacheable"); + false + } + + fn mark_uncacheable(&self, key: &CacheKey, reason: NoCacheReason) -> Option { + // only mark as uncacheable for the future on certain reasons, + // (e.g. InternalErrors) + use NoCacheReason::*; + match reason { + // CacheLockGiveUp: the writer will set OriginNotCache (if applicable) + // readers don't need to do it + NeverEnabled | StorageError | InternalError | Deferred | CacheLockGiveUp + | CacheLockTimeout => { + return None; + } + // Skip certain NoCacheReason::Custom according to user + Custom(reason) if self.skip_custom_reasons_fn.map_or(false, |f| f(reason)) => { + return None; + } + Custom(_) | OriginNotCache | ResponseTooLarge => { /* mark uncacheable for these only */ + } + } + + // variance key is ignored because cacheable_prediction() is called before cache lookup + // where the variance key is unknown + let hash = key.primary_bin(); + let key = u128::from_be_bytes(hash); + + let mut cache = self.uncacheable_keys.get(key).write(); + // put() returns Some(old_value) if the key existed, else None + let new_key = cache.put(key, ()).is_none(); + if new_key { + debug!("request marked uncacheable"); + } + Some(new_key) + } +} + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn test_mark_cacheability() { + let predictor = Predictor::<1>::new(10, None); + let key = CacheKey::new("a", "b", "c"); + // cacheable if no history + assert!(predictor.cacheable_prediction(&key)); + + // don't remember internal / storage errors + predictor.mark_uncacheable(&key, NoCacheReason::InternalError); + assert!(predictor.cacheable_prediction(&key)); + predictor.mark_uncacheable(&key, NoCacheReason::StorageError); + assert!(predictor.cacheable_prediction(&key)); + + // origin explicitly said uncacheable + predictor.mark_uncacheable(&key, NoCacheReason::OriginNotCache); + assert!(!predictor.cacheable_prediction(&key)); + + // mark cacheable again + predictor.mark_cacheable(&key); + assert!(predictor.cacheable_prediction(&key)); + } + + #[test] + fn test_custom_skip_predicate() { + let predictor = Predictor::<1>::new( + 10, + Some(|custom_reason| matches!(custom_reason, "Skipping")), + ); + let key = CacheKey::new("a", "b", "c"); + // cacheable if no history + assert!(predictor.cacheable_prediction(&key)); + + // custom predicate still uses default skip reasons + predictor.mark_uncacheable(&key, NoCacheReason::InternalError); + assert!(predictor.cacheable_prediction(&key)); + + // other custom reasons can still be marked uncacheable + predictor.mark_uncacheable(&key, NoCacheReason::Custom("DontCacheMe")); + assert!(!predictor.cacheable_prediction(&key)); + + let key = CacheKey::new("a", "c", "d"); + assert!(predictor.cacheable_prediction(&key)); + // specific custom reason is skipped + predictor.mark_uncacheable(&key, NoCacheReason::Custom("Skipping")); + assert!(predictor.cacheable_prediction(&key)); + } + + #[test] + fn test_mark_uncacheable_lru() { + let predictor = Predictor::<1>::new(3, None); + let key1 = CacheKey::new("a", "b", "c"); + predictor.mark_uncacheable(&key1, NoCacheReason::OriginNotCache); + assert!(!predictor.cacheable_prediction(&key1)); + + let key2 = CacheKey::new("a", "bc", "c"); + predictor.mark_uncacheable(&key2, NoCacheReason::OriginNotCache); + assert!(!predictor.cacheable_prediction(&key2)); + + let key3 = CacheKey::new("a", "cd", "c"); + predictor.mark_uncacheable(&key3, NoCacheReason::OriginNotCache); + assert!(!predictor.cacheable_prediction(&key3)); + + // promote / reinsert key1 + predictor.mark_uncacheable(&key1, NoCacheReason::OriginNotCache); + + let key4 = CacheKey::new("a", "de", "c"); + predictor.mark_uncacheable(&key4, NoCacheReason::OriginNotCache); + assert!(!predictor.cacheable_prediction(&key4)); + + // key 1 was recently used + assert!(!predictor.cacheable_prediction(&key1)); + // key 2 was evicted + assert!(predictor.cacheable_prediction(&key2)); + assert!(!predictor.cacheable_prediction(&key3)); + assert!(!predictor.cacheable_prediction(&key4)); + } +} diff --git a/pingora-cache/src/put.rs b/pingora-cache/src/put.rs new file mode 100644 index 0000000..c50cc2b --- /dev/null +++ b/pingora-cache/src/put.rs @@ -0,0 +1,754 @@ +// 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. + +//! Cache Put module + +use crate::*; +use bytes::Bytes; +use http::header; +use pingora_core::protocols::http::{ + v1::common::header_value_content_length, HttpTask, ServerSession, +}; + +/// The interface to define cache put behavior +pub trait CachePut { + /// Return whether to cache the asset according to the given response header. + fn cacheable(&self, response: &ResponseHeader) -> RespCacheable { + let cc = cache_control::CacheControl::from_resp_headers(response); + filters::resp_cacheable(cc.as_ref(), response, false, Self::cache_defaults()) + } + + /// Return the [CacheMetaDefaults] + fn cache_defaults() -> &'static CacheMetaDefaults; +} + +use parse_response::ResponseParse; + +/// The cache put context +pub struct CachePutCtx { + cache_put: C, // the user defined cache put behavior + key: CacheKey, + storage: &'static (dyn storage::Storage + Sync), // static for now + eviction: Option<&'static (dyn eviction::EvictionManager + Sync)>, + miss_handler: Option, + max_file_size_bytes: Option, + meta: Option, + parser: ResponseParse, + // FIXME: cache put doesn't have cache lock but some storage cannot handle concurrent put + // to the same asset. + trace: trace::Span, +} + +impl CachePutCtx { + /// Create a new [CachePutCtx] + pub fn new( + cache_put: C, + key: CacheKey, + storage: &'static (dyn storage::Storage + Sync), + eviction: Option<&'static (dyn eviction::EvictionManager + Sync)>, + trace: trace::Span, + ) -> Self { + CachePutCtx { + cache_put, + key, + storage, + eviction, + miss_handler: None, + max_file_size_bytes: None, + meta: None, + parser: ResponseParse::new(), + trace, + } + } + + /// Set the max cacheable size limit + pub fn set_max_file_size_bytes(&mut self, max_file_size_bytes: usize) { + self.max_file_size_bytes = Some(max_file_size_bytes); + } + + async fn put_header(&mut self, meta: CacheMeta) -> Result<()> { + let trace = self.trace.child("cache put header", |o| o.start()).handle(); + let miss_handler = self + .storage + .get_miss_handler(&self.key, &meta, &trace) + .await?; + self.miss_handler = Some( + if let Some(max_file_size_bytes) = self.max_file_size_bytes { + Box::new(MaxFileSizeMissHandler::new( + miss_handler, + max_file_size_bytes, + )) + } else { + miss_handler + }, + ); + self.meta = Some(meta); + Ok(()) + } + + async fn put_body(&mut self, data: Bytes, eof: bool) -> Result<()> { + let miss_handler = self.miss_handler.as_mut().unwrap(); + miss_handler.write_body(data, eof).await + } + + async fn finish(&mut self) -> Result<()> { + let Some(miss_handler) = self.miss_handler.take() else { + // no miss_handler, uncacheable + return Ok(()); + }; + let size = miss_handler.finish().await?; + if let Some(eviction) = self.eviction.as_ref() { + let cache_key = self.key.to_compact(); + let meta = self.meta.as_ref().unwrap(); + let evicted = eviction.admit(cache_key, size, meta.0.internal.fresh_until); + // TODO: make this async + let trace = self + .trace + .child("cache put eviction", |o| o.start()) + .handle(); + for item in evicted { + // TODO: warn/log the error + let _ = self.storage.purge(&item, &trace).await; + } + } + + Ok(()) + } + + async fn do_cache_put(&mut self, data: &[u8]) -> Result> { + let tasks = self.parser.inject_data(data)?; + for task in tasks { + match task { + HttpTask::Header(header, _eos) => match self.cache_put.cacheable(&header) { + RespCacheable::Cacheable(meta) => { + if let Some(max_file_size_bytes) = self.max_file_size_bytes { + let content_length_hdr = header.headers.get(header::CONTENT_LENGTH); + if let Some(content_length) = + header_value_content_length(content_length_hdr) + { + if content_length > max_file_size_bytes { + return Ok(Some(NoCacheReason::ResponseTooLarge)); + } + } + } + + self.put_header(meta).await?; + } + RespCacheable::Uncacheable(reason) => { + return Ok(Some(reason)); + } + }, + HttpTask::Body(data, eos) => { + if let Some(data) = data { + self.put_body(data, eos).await?; + } + } + _ => { + panic!("unexpected HttpTask during cache put {task:?}"); + } + } + } + Ok(None) + } + + /// Start the cache put logic for the given request + /// + /// This function will start to read the request body to put into cache. + /// Return: + /// - `Ok(None)` when the payload will be cache. + /// - `Ok(Some(reason))` when the payload is not cacheable + pub async fn cache_put( + &mut self, + session: &mut ServerSession, + ) -> Result> { + let mut no_cache_reason = None; + while let Some(data) = session.read_request_body().await? { + if no_cache_reason.is_some() { + // even uncacheable, the entire body needs to be drains for 1. downstream + // not throwing errors 2. connection reuse + continue; + } + no_cache_reason = self.do_cache_put(&data).await? + } + self.parser.finish()?; + self.finish().await?; + Ok(no_cache_reason) + } +} + +#[cfg(test)] +mod test { + use super::*; + use once_cell::sync::Lazy; + use rustracing::span::Span; + + struct TestCachePut(); + impl CachePut for TestCachePut { + fn cache_defaults() -> &'static CacheMetaDefaults { + const DEFAULT: CacheMetaDefaults = CacheMetaDefaults::new(|_| Some(1), 1, 1); + &DEFAULT + } + } + + type TestCachePutCtx = CachePutCtx; + static CACHE_BACKEND: Lazy = Lazy::new(MemCache::new); + + #[tokio::test] + async fn test_cache_put() { + let key = CacheKey::new("", "a", "1"); + let span = Span::inactive(); + let put = TestCachePut(); + let mut ctx = TestCachePutCtx::new(put, key.clone(), &*CACHE_BACKEND, None, span); + let payload = b"HTTP/1.1 200 OK\r\n\ + Date: Thu, 26 Apr 2018 05:42:05 GMT\r\n\ + Content-Type: text/html; charset=utf-8\r\n\ + Connection: keep-alive\r\n\ + X-Frame-Options: SAMEORIGIN\r\n\ + Cache-Control: public, max-age=1\r\n\ + Server: origin-server\r\n\ + Content-Length: 4\r\n\r\nrust"; + // here we skip mocking a real http session for simplicity + let res = ctx.do_cache_put(payload).await.unwrap(); + assert!(res.is_none()); // cacheable + ctx.parser.finish().unwrap(); + ctx.finish().await.unwrap(); + + let span = Span::inactive(); + let (meta, mut hit) = CACHE_BACKEND + .lookup(&key, &span.handle()) + .await + .unwrap() + .unwrap(); + assert_eq!( + meta.headers().get("date").unwrap(), + "Thu, 26 Apr 2018 05:42:05 GMT" + ); + let data = hit.read_body().await.unwrap().unwrap(); + assert_eq!(data, "rust"); + } + + #[tokio::test] + async fn test_cache_put_uncacheable() { + let key = CacheKey::new("", "a", "1"); + let span = Span::inactive(); + let put = TestCachePut(); + let mut ctx = TestCachePutCtx::new(put, key.clone(), &*CACHE_BACKEND, None, span); + let payload = b"HTTP/1.1 200 OK\r\n\ + Date: Thu, 26 Apr 2018 05:42:05 GMT\r\n\ + Content-Type: text/html; charset=utf-8\r\n\ + Connection: keep-alive\r\n\ + X-Frame-Options: SAMEORIGIN\r\n\ + Cache-Control: no-store\r\n\ + Server: origin-server\r\n\ + Content-Length: 4\r\n\r\nrust"; + // here we skip mocking a real http session for simplicity + let no_cache = ctx.do_cache_put(payload).await.unwrap().unwrap(); + assert_eq!(no_cache, NoCacheReason::OriginNotCache); + ctx.parser.finish().unwrap(); + ctx.finish().await.unwrap(); + } +} + +// maybe this can simplify some logic in pingora::h1 + +mod parse_response { + use super::*; + use bytes::{Bytes, BytesMut}; + use httparse::Status; + use pingora_error::{ + Error, + ErrorType::{self, *}, + Result, + }; + use pingora_http::ResponseHeader; + + pub const INVALID_CHUNK: ErrorType = ErrorType::new("InvalidChunk"); + pub const INCOMPLETE_BODY: ErrorType = ErrorType::new("IncompleteHttpBody"); + + const MAX_HEADERS: usize = 256; + const INIT_HEADER_BUF_SIZE: usize = 4096; + const CHUNK_DELIMITER_SIZE: usize = 2; // \r\n + + #[derive(Debug, Clone, Copy)] + enum ParseState { + Init, + PartialHeader, + PartialBodyContentLength(usize, usize), + PartialChunkedBody(usize), + PartialHttp10Body(usize), + Done(usize), + Invalid(httparse::Error), + } + + impl ParseState { + fn is_done(&self) -> bool { + matches!(self, Self::Done(_)) + } + fn read_header(&self) -> bool { + matches!(self, Self::Init | Self::PartialHeader) + } + fn read_body(&self) -> bool { + matches!( + self, + Self::PartialBodyContentLength(..) + | Self::PartialChunkedBody(_) + | Self::PartialHttp10Body(_) + ) + } + } + + pub(super) struct ResponseParse { + state: ParseState, + buf: BytesMut, + header_bytes: Bytes, + } + + impl ResponseParse { + pub fn new() -> Self { + ResponseParse { + state: ParseState::Init, + buf: BytesMut::with_capacity(INIT_HEADER_BUF_SIZE), + header_bytes: Bytes::new(), + } + } + + pub fn inject_data(&mut self, data: &[u8]) -> Result> { + self.put_data(data); + + let mut tasks = vec![]; + while !self.state.is_done() { + if self.state.read_header() { + let header = self.parse_header()?; + let Some(header) = header else { + break; + }; + tasks.push(HttpTask::Header(Box::new(header), self.state.is_done())); + } else if self.state.read_body() { + let body = self.parse_body()?; + let Some(body) = body else { + break; + }; + tasks.push(HttpTask::Body(Some(body), self.state.is_done())); + } else { + break; + } + } + Ok(tasks) + } + + fn put_data(&mut self, data: &[u8]) { + use ParseState::*; + if matches!(self.state, Done(_) | Invalid(_)) { + panic!("Wrong phase {:?}", self.state); + } + self.buf.extend_from_slice(data); + } + + fn parse_header(&mut self) -> Result> { + let mut headers = [httparse::EMPTY_HEADER; MAX_HEADERS]; + let mut resp = httparse::Response::new(&mut headers); + let mut parser = httparse::ParserConfig::default(); + parser.allow_spaces_after_header_name_in_responses(true); + parser.allow_obsolete_multiline_headers_in_responses(true); + + let res = parser.parse_response(&mut resp, &self.buf); + let res = match res { + Ok(res) => res, + Err(e) => { + self.state = ParseState::Invalid(e); + return Error::e_because( + InvalidHTTPHeader, + format!("buf: {:?}", String::from_utf8_lossy(&self.buf)), + e, + ); + } + }; + + let split_to = match res { + Status::Complete(s) => s, + Status::Partial => { + self.state = ParseState::PartialHeader; + return Ok(None); + } + }; + // safe to unwrap, valid response always has code set. + let mut response = + ResponseHeader::build(resp.code.unwrap(), Some(resp.headers.len())).unwrap(); + for header in resp.headers { + // TODO: consider hold a Bytes and all header values can be Bytes referencing the + // original buffer without reallocation + response.append_header(header.name.to_owned(), header.value.to_owned())?; + } + // TODO: see above, we can make header value `Bytes` referencing header_bytes + let header_bytes = self.buf.split_to(split_to).freeze(); + self.header_bytes = header_bytes; + self.state = body_type(&response); + + Ok(Some(response)) + } + + fn parse_body(&mut self) -> Result> { + use ParseState::*; + if self.buf.is_empty() { + return Ok(None); + } + match self.state { + Init | PartialHeader | Invalid(_) => { + panic!("Wrong phase {:?}", self.state); + } + Done(_) => Ok(None), + PartialBodyContentLength(total, mut seen) => { + let end = if total < self.buf.len() + seen { + // TODO: warn! more data than expected + total - seen + } else { + self.buf.len() + }; + seen += end; + if seen >= total { + self.state = Done(seen); + } else { + self.state = PartialBodyContentLength(total, seen); + } + Ok(Some(self.buf.split_to(end).freeze())) + } + PartialChunkedBody(seen) => { + let parsed = httparse::parse_chunk_size(&self.buf).map_err(|e| { + self.state = Done(seen); + Error::explain(INVALID_CHUNK, format!("Invalid chucked encoding: {e:?}")) + })?; + match parsed { + httparse::Status::Complete((header_len, body_len)) => { + // 4\r\nRust\r\n: header: "4\r\n", body: "Rust", "\r\n" + let total_chunk_size = + header_len + body_len as usize + CHUNK_DELIMITER_SIZE; + if self.buf.len() < total_chunk_size { + // wait for the full chunk tob read + // Note that we have to buffer the entire chunk in this design + Ok(None) + } else { + if body_len == 0 { + self.state = Done(seen); + } else { + self.state = PartialChunkedBody(seen + body_len as usize); + } + let mut chunk_bytes = self.buf.split_to(total_chunk_size); + let mut chunk_body = chunk_bytes.split_off(header_len); + chunk_body.truncate(body_len as usize); + // Note that the final 0 sized chunk will return an empty Bytes + // instead of not None + Ok(Some(chunk_body.freeze())) + } + } + httparse::Status::Partial => { + // not even a full chunk, continue waiting for more data + Ok(None) + } + } + } + PartialHttp10Body(seen) => { + self.state = PartialHttp10Body(seen + self.buf.len()); + Ok(Some(self.buf.split().freeze())) + } + } + } + + pub fn finish(&mut self) -> Result<()> { + if let ParseState::PartialHttp10Body(seen) = self.state { + self.state = ParseState::Done(seen); + } + if !self.state.is_done() { + Error::e_explain(INCOMPLETE_BODY, format!("{:?}", self.state)) + } else { + Ok(()) + } + } + } + + fn body_type(resp: &ResponseHeader) -> ParseState { + use http::StatusCode; + + if matches!( + resp.status, + StatusCode::NO_CONTENT | StatusCode::NOT_MODIFIED + ) { + // these status code cannot have body by definition + return ParseState::Done(0); + } + if let Some(encoding) = resp.headers.get(http::header::TRANSFER_ENCODING) { + // TODO: case sensitive? + if encoding.as_bytes() == b"chunked" { + return ParseState::PartialChunkedBody(0); + } + } + if let Some(cl) = resp.headers.get(http::header::CONTENT_LENGTH) { + // ignore invalid header value + if let Some(cl) = std::str::from_utf8(cl.as_bytes()) + .ok() + .and_then(|cl| cl.parse::().ok()) + { + return if cl == 0 { + ParseState::Done(0) + } else { + ParseState::PartialBodyContentLength(cl, 0) + }; + } + } + ParseState::PartialHttp10Body(0) + } + + #[cfg(test)] + mod test { + use super::*; + + #[test] + fn test_basic_response() { + let input = b"HTTP/1.1 200 OK\r\n\r\n"; + let mut parser = ResponseParse::new(); + let output = parser.inject_data(input).unwrap(); + assert_eq!(output.len(), 1); + let HttpTask::Header(header, eos) = &output[0] else { + panic!("{:?}", output); + }; + assert_eq!(header.status, 200); + assert!(!eos); + + let body = b"abc"; + let output = parser.inject_data(body).unwrap(); + assert_eq!(output.len(), 1); + let HttpTask::Body(data, _eos) = &output[0] else { + panic!("{:?}", output); + }; + assert_eq!(data.as_ref().unwrap(), &body[..]); + parser.finish().unwrap(); + } + + #[test] + fn test_partial_response_headers() { + let input = b"HTTP/1.1 200 OK\r\n"; + let mut parser = ResponseParse::new(); + let output = parser.inject_data(input).unwrap(); + // header is not complete + assert_eq!(output.len(), 0); + + let output = parser + .inject_data("Server: pingora\r\n\r\n".as_bytes()) + .unwrap(); + assert_eq!(output.len(), 1); + let HttpTask::Header(header, eos) = &output[0] else { + panic!("{:?}", output); + }; + assert_eq!(header.status, 200); + assert_eq!(header.headers.get("Server").unwrap(), "pingora"); + assert!(!eos); + } + + #[test] + fn test_invalid_headers() { + let input = b"HTP/1.1 200 OK\r\nServer: pingora\r\n\r\n"; + let mut parser = ResponseParse::new(); + let output = parser.inject_data(input); + // header is not complete + assert!(output.is_err()); + } + + #[test] + fn test_body_content_length() { + let input = b"HTTP/1.1 200 OK\r\nContent-Length: 6\r\n\r\nabc"; + let mut parser = ResponseParse::new(); + let output = parser.inject_data(input).unwrap(); + + assert_eq!(output.len(), 2); + let HttpTask::Header(header, _eos) = &output[0] else { + panic!("{:?}", output); + }; + assert_eq!(header.status, 200); + + let HttpTask::Body(data, eos) = &output[1] else { + panic!("{:?}", output); + }; + assert_eq!(data.as_ref().unwrap(), "abc"); + assert!(!eos); + + let output = parser.inject_data(b"def").unwrap(); + assert_eq!(output.len(), 1); + let HttpTask::Body(data, eos) = &output[0] else { + panic!("{:?}", output); + }; + assert_eq!(data.as_ref().unwrap(), "def"); + assert!(eos); + + parser.finish().unwrap(); + } + + #[test] + fn test_body_chunked() { + let input = b"HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n4\r\nrust\r\n"; + let mut parser = ResponseParse::new(); + let output = parser.inject_data(input).unwrap(); + + assert_eq!(output.len(), 2); + let HttpTask::Header(header, _eos) = &output[0] else { + panic!("{:?}", output); + }; + assert_eq!(header.status, 200); + + let HttpTask::Body(data, eos) = &output[1] else { + panic!("{:?}", output); + }; + assert_eq!(data.as_ref().unwrap(), "rust"); + assert!(!eos); + + let output = parser.inject_data(b"0\r\n\r\n").unwrap(); + assert_eq!(output.len(), 1); + let HttpTask::Body(data, eos) = &output[0] else { + panic!("{:?}", output); + }; + assert_eq!(data.as_ref().unwrap(), ""); + assert!(eos); + + parser.finish().unwrap(); + } + + #[test] + fn test_body_content_length_early() { + let input = b"HTTP/1.1 200 OK\r\nContent-Length: 6\r\n\r\nabc"; + let mut parser = ResponseParse::new(); + let output = parser.inject_data(input).unwrap(); + + assert_eq!(output.len(), 2); + let HttpTask::Header(header, _eos) = &output[0] else { + panic!("{:?}", output); + }; + assert_eq!(header.status, 200); + + let HttpTask::Body(data, eos) = &output[1] else { + panic!("{:?}", output); + }; + assert_eq!(data.as_ref().unwrap(), "abc"); + assert!(!eos); + + parser.finish().unwrap_err(); + } + + #[test] + fn test_body_content_length_more_data() { + let input = b"HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nabc"; + let mut parser = ResponseParse::new(); + let output = parser.inject_data(input).unwrap(); + + assert_eq!(output.len(), 2); + let HttpTask::Header(header, _eos) = &output[0] else { + panic!("{:?}", output); + }; + assert_eq!(header.status, 200); + + let HttpTask::Body(data, eos) = &output[1] else { + panic!("{:?}", output); + }; + assert_eq!(data.as_ref().unwrap(), "ab"); + assert!(eos); + + // extra data is dropped without error + parser.finish().unwrap(); + } + + #[test] + fn test_body_chunked_early() { + let input = b"HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n4\r\nrust\r\n"; + let mut parser = ResponseParse::new(); + let output = parser.inject_data(input).unwrap(); + + assert_eq!(output.len(), 2); + let HttpTask::Header(header, _eos) = &output[0] else { + panic!("{:?}", output); + }; + assert_eq!(header.status, 200); + + let HttpTask::Body(data, eos) = &output[1] else { + panic!("{:?}", output); + }; + assert_eq!(data.as_ref().unwrap(), "rust"); + assert!(!eos); + + parser.finish().unwrap_err(); + } + + #[test] + fn test_body_chunked_partial_chunk() { + let input = b"HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n4\r\nru"; + let mut parser = ResponseParse::new(); + let output = parser.inject_data(input).unwrap(); + + assert_eq!(output.len(), 1); + let HttpTask::Header(header, _eos) = &output[0] else { + panic!("{:?}", output); + }; + assert_eq!(header.status, 200); + + let output = parser.inject_data(b"st\r\n").unwrap(); + assert_eq!(output.len(), 1); + let HttpTask::Body(data, eos) = &output[0] else { + panic!("{:?}", output); + }; + assert_eq!(data.as_ref().unwrap(), "rust"); + assert!(!eos); + } + + #[test] + fn test_body_chunked_partial_chunk_head() { + let input = b"HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n4\r"; + let mut parser = ResponseParse::new(); + let output = parser.inject_data(input).unwrap(); + + assert_eq!(output.len(), 1); + let HttpTask::Header(header, _eos) = &output[0] else { + panic!("{:?}", output); + }; + assert_eq!(header.status, 200); + + let output = parser.inject_data(b"\nrust\r\n").unwrap(); + assert_eq!(output.len(), 1); + let HttpTask::Body(data, eos) = &output[0] else { + panic!("{:?}", output); + }; + assert_eq!(data.as_ref().unwrap(), "rust"); + assert!(!eos); + } + + #[test] + fn test_body_chunked_many_chunks() { + let input = + b"HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n4\r\nrust\r\n1\r\ny\r\n"; + let mut parser = ResponseParse::new(); + let output = parser.inject_data(input).unwrap(); + + assert_eq!(output.len(), 3); + let HttpTask::Header(header, _eos) = &output[0] else { + panic!("{:?}", output); + }; + assert_eq!(header.status, 200); + let HttpTask::Body(data, eos) = &output[1] else { + panic!("{:?}", output); + }; + assert!(!eos); + assert_eq!(data.as_ref().unwrap(), "rust"); + let HttpTask::Body(data, eos) = &output[2] else { + panic!("{:?}", output); + }; + assert_eq!(data.as_ref().unwrap(), "y"); + assert!(!eos); + } + } +} diff --git a/pingora-cache/src/storage.rs b/pingora-cache/src/storage.rs new file mode 100644 index 0000000..c6365c7 --- /dev/null +++ b/pingora-cache/src/storage.rs @@ -0,0 +1,122 @@ +// 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. + +//! Cache backend storage abstraction + +use super::{CacheKey, CacheMeta}; +use crate::key::CompactCacheKey; +use crate::trace::SpanHandle; + +use async_trait::async_trait; +use pingora_error::Result; +use std::any::Any; + +/// Cache storage interface +#[async_trait] +pub trait Storage { + // TODO: shouldn't have to be static + + /// Lookup the storage for the given [CacheKey] + async fn lookup( + &'static self, + key: &CacheKey, + trace: &SpanHandle, + ) -> Result>; + + /// Write the given [CacheMeta] to the storage. Return [MissHandler] to write the body later. + async fn get_miss_handler( + &'static self, + key: &CacheKey, + meta: &CacheMeta, + trace: &SpanHandle, + ) -> Result; + + /// Delete the cached asset for the given key + /// + /// [CompactCacheKey] is used here because it is how eviction managers store the keys + async fn purge(&'static self, key: &CompactCacheKey, trace: &SpanHandle) -> Result; + + /// Update cache header and metadata for the already stored asset. + async fn update_meta( + &'static self, + key: &CacheKey, + meta: &CacheMeta, + trace: &SpanHandle, + ) -> Result; + + /// Whether this storage backend supports reading partially written data + /// + /// This is to indicate when cache should unlock readers + fn support_streaming_partial_write(&self) -> bool { + false + } + + /// Helper function to cast the trait object to concrete types + fn as_any(&self) -> &(dyn Any + Send + Sync + 'static); +} + +/// Cache hit handling trait +#[async_trait] +pub trait HandleHit { + /// Read cached body + /// + /// Return `None` when no more body to read. + async fn read_body(&mut self) -> Result>; + + /// Finish the current cache hit + async fn finish( + self: Box, // because self is always used as a trait object + storage: &'static (dyn Storage + Sync), + key: &CacheKey, + trace: &SpanHandle, + ) -> Result<()>; + + /// Whether this storage allow seeking to a certain range of body + fn can_seek(&self) -> bool { + false + } + + /// Try to seek to a certain range of the body + /// + /// `end: None` means to read to the end of the body. + fn seek(&mut self, _start: usize, _end: Option) -> Result<()> { + // to prevent impl can_seek() without impl seek + todo!("seek() needs to be implemented") + } + // TODO: fn is_stream_hit() + + /// Helper function to cast the trait object to concrete types + fn as_any(&self) -> &(dyn Any + Send + Sync); +} + +/// Hit Handler +pub type HitHandler = Box<(dyn HandleHit + Sync + Send)>; + +/// Cache miss handling trait +#[async_trait] +pub trait HandleMiss { + /// Write the given body to the storage + async fn write_body(&mut self, data: bytes::Bytes, eof: bool) -> Result<()>; + + /// Finish the cache admission + /// + /// When `self` is dropped without calling this function, the storage should consider this write + /// failed. + async fn finish( + self: Box, // because self is always used as a trait object + ) -> Result; +} + +/// Miss Handler +pub type MissHandler = Box<(dyn HandleMiss + Sync + Send)>; diff --git a/pingora-cache/src/trace.rs b/pingora-cache/src/trace.rs new file mode 100644 index 0000000..c385aea --- /dev/null +++ b/pingora-cache/src/trace.rs @@ -0,0 +1,98 @@ +// 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. + +//! Distributed tracing helpers + +use rustracing_jaeger::span::SpanContextState; +use std::time::SystemTime; + +use crate::{CacheMeta, CachePhase, HitStatus}; + +pub use rustracing::tag::Tag; + +pub type Span = rustracing::span::Span; +pub type SpanHandle = rustracing::span::SpanHandle; + +#[derive(Debug)] +pub(crate) struct CacheTraceCTX { + // parent span + pub cache_span: Span, + // only spans across multiple calls need to store here + pub miss_span: Span, + pub hit_span: Span, +} + +impl CacheTraceCTX { + pub fn new() -> Self { + CacheTraceCTX { + cache_span: Span::inactive(), + miss_span: Span::inactive(), + hit_span: Span::inactive(), + } + } + + pub fn enable(&mut self, cache_span: Span) { + self.cache_span = cache_span; + } + + #[inline] + pub fn child(&self, name: &'static str) -> Span { + self.cache_span.child(name, |o| o.start()) + } + + pub fn start_miss_span(&mut self) { + self.miss_span = self.child("miss"); + } + + pub fn get_miss_span(&self) -> SpanHandle { + self.miss_span.handle() + } + + pub fn finish_miss_span(&mut self) { + self.miss_span.set_finish_time(SystemTime::now); + } + + pub fn start_hit_span(&mut self, phase: CachePhase, hit_status: HitStatus) { + self.hit_span = self.child("hit"); + self.hit_span.set_tag(|| Tag::new("phase", phase.as_str())); + self.hit_span + .set_tag(|| Tag::new("status", hit_status.as_str())); + } + + pub fn finish_hit_span(&mut self) { + self.hit_span.set_finish_time(SystemTime::now); + } + + pub fn log_meta(&mut self, meta: &CacheMeta) { + fn ts2epoch(ts: SystemTime) -> f64 { + ts.duration_since(SystemTime::UNIX_EPOCH) + .unwrap_or_default() // should never overflow but be safe here + .as_secs_f64() + } + let internal = &meta.0.internal; + self.hit_span.set_tags(|| { + [ + Tag::new("created", ts2epoch(internal.created)), + Tag::new("fresh_until", ts2epoch(internal.fresh_until)), + Tag::new("updated", ts2epoch(internal.updated)), + Tag::new("stale_if_error_sec", internal.stale_if_error_sec as i64), + Tag::new( + "stale_while_revalidate_sec", + internal.stale_while_revalidate_sec as i64, + ), + Tag::new("variance", internal.variance.is_some()), + ] + }); + } +} diff --git a/pingora-cache/src/variance.rs b/pingora-cache/src/variance.rs new file mode 100644 index 0000000..cce8160 --- /dev/null +++ b/pingora-cache/src/variance.rs @@ -0,0 +1,120 @@ +use std::{borrow::Cow, collections::BTreeMap}; + +use blake2::Digest; + +use crate::key::{Blake2b128, HashBinary}; + +/// A builder for variance keys, used for distinguishing multiple cached assets +/// at the same URL. This is intended to be easily passed to helper functions, +/// which can each populate a portion of the variance. +pub struct VarianceBuilder<'a> { + values: BTreeMap, Cow<'a, [u8]>>, +} + +impl<'a> VarianceBuilder<'a> { + /// Create an empty variance key. Has no variance by default - add some variance using + /// [`Self::add_value`]. + pub fn new() -> Self { + VarianceBuilder { + values: BTreeMap::new(), + } + } + + /// Add a byte string to the variance key. Not sensitive to insertion order. + /// `value` is intended to take either `&str` or `&[u8]`. + pub fn add_value(&mut self, name: &'a str, value: &'a (impl AsRef<[u8]> + ?Sized)) { + self.values + .insert(name.into(), Cow::Borrowed(value.as_ref())); + } + + /// Move a byte string to the variance key. Not sensitive to insertion order. Useful when + /// writing helper functions which generate a value then add said value to the VarianceBuilder. + /// Without this, the helper function would have to move the value to the calling function + /// to extend its lifetime to at least match the VarianceBuilder. + pub fn add_owned_value(&mut self, name: &'a str, value: Vec) { + self.values.insert(name.into(), Cow::Owned(value)); + } + + /// Check whether this variance key actually has variance, or just refers to the root asset + pub fn has_variance(&self) -> bool { + !self.values.is_empty() + } + + /// Hash this variance key. Returns [`None`] if [`Self::has_variance`] is false. + pub fn finalize(self) -> Option { + const SALT: &[u8; 1] = &[0u8; 1]; + if self.has_variance() { + let mut hash = Blake2b128::new(); + for (name, value) in self.values.iter() { + hash.update(name.as_bytes()); + hash.update(SALT); + hash.update(value); + hash.update(SALT); + } + Some(hash.finalize().into()) + } else { + None + } + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_basic() { + let key_empty = VarianceBuilder::new().finalize(); + assert_eq!(None, key_empty); + + let mut key_value = VarianceBuilder::new(); + key_value.add_value("a", "a"); + let key_value = key_value.finalize(); + + let mut key_owned_value = VarianceBuilder::new(); + key_owned_value.add_owned_value("a", "a".as_bytes().to_vec()); + let key_owned_value = key_owned_value.finalize(); + + assert_ne!(key_empty, key_value); + assert_ne!(key_empty, key_owned_value); + assert_eq!(key_value, key_owned_value); + } + + #[test] + fn test_value_ordering() { + let mut key_abc = VarianceBuilder::new(); + key_abc.add_value("a", "a"); + key_abc.add_value("b", "b"); + key_abc.add_value("c", "c"); + let key_abc = key_abc.finalize().unwrap(); + + let mut key_bac = VarianceBuilder::new(); + key_bac.add_value("b", "b"); + key_bac.add_value("a", "a"); + key_bac.add_value("c", "c"); + let key_bac = key_bac.finalize().unwrap(); + + let mut key_cba = VarianceBuilder::new(); + key_cba.add_value("c", "c"); + key_cba.add_value("b", "b"); + key_cba.add_value("a", "a"); + let key_cba = key_cba.finalize().unwrap(); + + assert_eq!(key_abc, key_bac); + assert_eq!(key_abc, key_cba); + } + + #[test] + fn test_value_overriding() { + let mut key_a = VarianceBuilder::new(); + key_a.add_value("a", "a"); + let key_a = key_a.finalize().unwrap(); + + let mut key_b = VarianceBuilder::new(); + key_b.add_value("a", "b"); + key_b.add_value("a", "a"); + let key_b = key_b.finalize().unwrap(); + + assert_eq!(key_a, key_b); + } +} diff --git a/pingora-core/Cargo.toml b/pingora-core/Cargo.toml new file mode 100644 index 0000000..76d239c --- /dev/null +++ b/pingora-core/Cargo.toml @@ -0,0 +1,81 @@ +[package] +name = "pingora-core" +version = "0.1.0" +authors = ["Yuchen Wu "] +license = "Apache-2.0" +edition = "2021" +repository = "https://github.com/cloudflare/pingora" +categories = ["asynchronous", "network-programming"] +keywords = ["async", "http", "network", "pingora"] +exclude = ["tests/*"] +description = """ +Pingora's APIs and traits for the core network protocols. +""" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +name = "pingora_core" +path = "src/lib.rs" + +[dependencies] +pingora-runtime = { version = "0.1.0", path = "../pingora-runtime" } +pingora-openssl = { version = "0.1.0", path = "../pingora-openssl", optional = true } +pingora-boringssl = { version = "0.1.0", path = "../pingora-boringssl", optional = true } +pingora-pool = { version = "0.1.0", path = "../pingora-pool" } +pingora-error = { version = "0.1.0", path = "../pingora-error" } +pingora-timeout = { version = "0.1.0", path = "../pingora-timeout" } +pingora-http = { version = "0.1.0", path = "../pingora-http" } +tokio = { workspace = true, features = ["rt-multi-thread", "signal"] } +futures = "0.3" +async-trait = { workspace = true } +httparse = { workspace = true } +bytes = { workspace = true } +http = { workspace = true } +log = { workspace = true } +h2 = { workspace = true } +lru = { workspace = true } +nix = "0.24" +structopt = "0.3" +once_cell = { workspace = true } +serde = { version = "1.0", features = ["derive"] } +serde_yaml = "0.8" +libc = "0.2.70" +chrono = { version = "0.4", features = ["alloc"], default-features = false } +thread_local = "1.0" +prometheus = "0.13" +daemonize = "0.5.0" +sentry = { version = "0.26", features = [ + "backtrace", + "contexts", + "panic", + "reqwest", + "rustls", +], default-features = false } +regex = "1" +percent-encoding = "2.1" +parking_lot = "0.12" +socket2 = { version = "0", features = ["all"] } +flate2 = { version = "1", features = ["zlib-ng"], default-features = false } +sfv = "0" +rand = "0.8" +ahash = { workspace = true } +unicase = "2" +brotli = "3" +openssl-probe = "0.1" +tokio-test = "0.4" +zstd = "0" + +[dev-dependencies] +matches = "0.1" +env_logger = "0.9" +reqwest = { version = "0.11", features = ["rustls"], default-features = false } +hyperlocal = "0.8" +hyper = "0.14" +jemallocator = "0.5" + +[features] +default = ["openssl"] +openssl = ["pingora-openssl"] +boringssl = ["pingora-boringssl"] +patched_http1 = [] diff --git a/pingora-core/LICENSE b/pingora-core/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/pingora-core/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/pingora-core/src/apps/http_app.rs b/pingora-core/src/apps/http_app.rs new file mode 100644 index 0000000..4dc9059 --- /dev/null +++ b/pingora-core/src/apps/http_app.rs @@ -0,0 +1,210 @@ +// 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. + +//! A simple HTTP application trait that maps a request to a response + +use async_trait::async_trait; +use http::Response; +use log::{debug, error, trace}; +use pingora_http::ResponseHeader; +use std::sync::Arc; + +use crate::apps::HttpServerApp; +use crate::modules::http::{HttpModules, ModuleBuilder}; +use crate::protocols::http::HttpTask; +use crate::protocols::http::ServerSession; +use crate::protocols::Stream; +use crate::server::ShutdownWatch; + +/// This trait defines how to map a request to a response +#[cfg_attr(not(doc_async_trait), async_trait)] +pub trait ServeHttp { + /// Define the mapping from a request to a response. + /// Note that the request header is already read, but the implementation needs to read the + /// request body if any. + /// + /// # Limitation + /// In this API, the entire response has to be generated before the end of this call. + /// So it is not suitable for streaming response or interactive communications. + /// Users need to implement their own [`super::HttpServerApp`] for those use cases. + async fn response(&self, http_session: &mut ServerSession) -> Response>; +} + +// TODO: remove this in favor of HttpServer? +#[cfg_attr(not(doc_async_trait), async_trait)] +impl HttpServerApp for SV +where + SV: ServeHttp + Send + Sync, +{ + async fn process_new_http( + self: &Arc, + mut http: ServerSession, + shutdown: &ShutdownWatch, + ) -> Option { + match http.read_request().await { + Ok(res) => match res { + false => { + debug!("Failed to read request header"); + return None; + } + true => { + debug!("Successfully get a new request"); + } + }, + Err(e) => { + error!("HTTP server fails to read from downstream: {e}"); + return None; + } + } + trace!("{:?}", http.req_header()); + if *shutdown.borrow() { + http.set_keepalive(None); + } else { + http.set_keepalive(Some(60)); + } + let new_response = self.response(&mut http).await; + let (parts, body) = new_response.into_parts(); + let resp_header: ResponseHeader = parts.into(); + match http.write_response_header(Box::new(resp_header)).await { + Ok(()) => { + debug!("HTTP response header done."); + } + Err(e) => { + error!( + "HTTP server fails to write to downstream: {e}, {}", + http.request_summary() + ); + } + } + if !body.is_empty() { + // TODO: check if chunked encoding is needed + match http.write_response_body(body.into()).await { + Ok(_) => debug!("HTTP response written."), + Err(e) => error!( + "HTTP server fails to write to downstream: {e}, {}", + http.request_summary() + ), + } + } + match http.finish().await { + Ok(c) => c, + Err(e) => { + error!("HTTP server fails to finish the request: {e}"); + None + } + } + } +} + +/// A helper struct for HTTP server with http modules embedded +pub struct HttpServer { + app: SV, + modules: HttpModules, +} + +impl HttpServer { + /// Create a new [HttpServer] with the given app which implements [ServeHttp] + pub fn new_app(app: SV) -> Self { + HttpServer { + app, + modules: HttpModules::new(), + } + } + + /// Add [ModuleBuilder] to this [HttpServer] + pub fn add_module(&mut self, module: ModuleBuilder) { + self.modules.add_module(module) + } +} + +#[cfg_attr(not(doc_async_trait), async_trait)] +impl HttpServerApp for HttpServer +where + SV: ServeHttp + Send + Sync, +{ + async fn process_new_http( + self: &Arc, + mut http: ServerSession, + shutdown: &ShutdownWatch, + ) -> Option { + match http.read_request().await { + Ok(res) => match res { + false => { + debug!("Failed to read request header"); + return None; + } + true => { + debug!("Successfully get a new request"); + } + }, + Err(e) => { + error!("HTTP server fails to read from downstream: {e}"); + return None; + } + } + trace!("{:?}", http.req_header()); + if *shutdown.borrow() { + http.set_keepalive(None); + } else { + http.set_keepalive(Some(60)); + } + let mut module_ctx = self.modules.build_ctx(); + let req = http.req_header_mut(); + module_ctx.request_header_filter(req).ok()?; + let new_response = self.app.response(&mut http).await; + let (parts, body) = new_response.into_parts(); + let resp_header: ResponseHeader = parts.into(); + let mut task = HttpTask::Header(Box::new(resp_header), body.is_empty()); + module_ctx.response_filter(&mut task).ok()?; + + trace!("{task:?}"); + + match http.response_duplex_vec(vec![task]).await { + Ok(_) => { + debug!("HTTP response header done."); + } + Err(e) => { + error!( + "HTTP server fails to write to downstream: {e}, {}", + http.request_summary() + ); + } + } + let mut task = if !body.is_empty() { + HttpTask::Body(Some(body.into()), true) + } else { + HttpTask::Body(None, true) + }; + + trace!("{task:?}"); + + module_ctx.response_filter(&mut task).ok()?; + + // TODO: check if chunked encoding is needed + match http.response_duplex_vec(vec![task]).await { + Ok(_) => debug!("HTTP response written."), + Err(e) => error!( + "HTTP server fails to write to downstream: {e}, {}", + http.request_summary() + ), + } + match http.finish().await { + Ok(c) => c, + Err(e) => { + error!("HTTP server fails to finish the request: {e}"); + None + } + } + } +} diff --git a/pingora-core/src/apps/mod.rs b/pingora-core/src/apps/mod.rs new file mode 100644 index 0000000..db8f11b --- /dev/null +++ b/pingora-core/src/apps/mod.rs @@ -0,0 +1,135 @@ +// 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. + +//! The abstraction and implementation interface for service application logic + +pub mod http_app; +pub mod prometheus_http_app; + +use crate::server::ShutdownWatch; +use async_trait::async_trait; +use log::{debug, error}; +use std::sync::Arc; + +use crate::protocols::http::v2::server; +use crate::protocols::http::ServerSession; +use crate::protocols::Stream; +use crate::protocols::ALPN; + +#[cfg_attr(not(doc_async_trait), async_trait)] +/// This trait defines the interface of a transport layer (TCP or TLS) application. +pub trait ServerApp { + /// Whenever a new connection is established, this function will be called with the established + /// [`Stream`] object provided. + /// + /// The application can do whatever it wants with the `session`. + /// + /// After processing the `session`, if the `session`'s connection is reusable, This function + /// can return it to the service by returning `Some(session)`. The returned `session` will be + /// fed to another [`Self::process_new()`] for another round of processing. + /// If not reusable, `None` should be returned. + /// + /// The `shutdown` argument will change from `false` to `true` when the server receives a + /// signal to shutdown. This argument allows the application to react accordingly. + async fn process_new( + self: &Arc, + mut session: Stream, + // TODO: make this ShutdownWatch so that all task can await on this event + shutdown: &ShutdownWatch, + ) -> Option; + + /// This callback will be called once after the service stops listening to its endpoints. + fn cleanup(&self) {} +} + +/// This trait defines the interface of a HTTP application. +#[cfg_attr(not(doc_async_trait), async_trait)] +pub trait HttpServerApp { + /// Similar to the [`ServerApp`], this function is called whenever a new HTTP session is established. + /// + /// After successful processing, [`ServerSession::finish()`] can be called to return an optionally reusable + /// connection back to the service. The caller needs to make sure that the connection is in a reusable state + /// i.e., no error or incomplete read or write headers or bodies. Otherwise a `None` should be returned. + async fn process_new_http( + self: &Arc, + mut session: ServerSession, + // TODO: make this ShutdownWatch so that all task can await on this event + shutdown: &ShutdownWatch, + ) -> Option; + + /// Provide options on how HTTP/2 connection should be established. This function will be called + /// every time a new HTTP/2 **connection** needs to be established. + /// + /// A `None` means to use the built-in default options. See [`server::H2Options`] for more details. + fn h2_options(&self) -> Option { + None + } + + fn http_cleanup(&self) {} +} + +#[cfg_attr(not(doc_async_trait), async_trait)] +impl ServerApp for T +where + T: HttpServerApp + Send + Sync + 'static, +{ + async fn process_new( + self: &Arc, + stream: Stream, + shutdown: &ShutdownWatch, + ) -> Option { + match stream.selected_alpn_proto() { + Some(ALPN::H2) => { + let h2_options = self.h2_options(); + let h2_conn = server::handshake(stream, h2_options).await; + let mut h2_conn = match h2_conn { + Err(e) => { + error!("H2 handshake error {e}"); + return None; + } + Ok(c) => c, + }; + loop { + // this loop ends when the client decides to close the h2 conn + // TODO: add a timeout? + let h2_stream = server::HttpSession::from_h2_conn(&mut h2_conn).await; + let h2_stream = match h2_stream { + Err(e) => { + // It is common for client to just disconnect TCP without properly + // closing H2. So we don't log the errors here + debug!("H2 error when accepting new stream {e}"); + return None; + } + Ok(s) => s?, // None means the connection is ready to be closed + }; + let app = self.clone(); + let shutdown = shutdown.clone(); + pingora_runtime::current_handle().spawn(async move { + app.process_new_http(ServerSession::new_http2(h2_stream), &shutdown) + .await; + }); + } + } + _ => { + // No ALPN or ALPN::H1 or something else, just try Http1 + self.process_new_http(ServerSession::new_http1(stream), shutdown) + .await + } + } + } + + fn cleanup(&self) { + self.http_cleanup() + } +} diff --git a/pingora-core/src/apps/prometheus_http_app.rs b/pingora-core/src/apps/prometheus_http_app.rs new file mode 100644 index 0000000..146f3da --- /dev/null +++ b/pingora-core/src/apps/prometheus_http_app.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. + +//! A HTTP application that reports Prometheus metrics. + +use async_trait::async_trait; +use http::{self, Response}; +use prometheus::{Encoder, TextEncoder}; + +use super::http_app::HttpServer; +use crate::apps::http_app::ServeHttp; +use crate::modules::http::compression::ResponseCompressionBuilder; +use crate::protocols::http::ServerSession; + +/// A HTTP application that reports Prometheus metrics. +/// +/// This application will report all the [static metrics](https://docs.rs/prometheus/latest/prometheus/index.html#static-metrics) +/// collected via the [Prometheus](https://docs.rs/prometheus/) crate; +pub struct PrometheusHttpApp; + +#[cfg_attr(not(doc_async_trait), async_trait)] +impl ServeHttp for PrometheusHttpApp { + async fn response(&self, _http_session: &mut ServerSession) -> Response> { + let encoder = TextEncoder::new(); + let metric_families = prometheus::gather(); + let mut buffer = vec![]; + encoder.encode(&metric_families, &mut buffer).unwrap(); + Response::builder() + .status(200) + .header(http::header::CONTENT_TYPE, encoder.format_type()) + .header(http::header::CONTENT_LENGTH, buffer.len()) + .body(buffer) + .unwrap() + } +} + +/// The [HttpServer] for [PrometheusHttpApp] +/// +/// This type provides the functionality of [PrometheusHttpApp] with compression enabled +pub type PrometheusServer = HttpServer; + +impl PrometheusServer { + pub fn new() -> Self { + let mut server = Self::new_app(PrometheusHttpApp); + // enable gzip level 7 compression + server.add_module(ResponseCompressionBuilder::enable(7)); + server + } +} diff --git a/pingora-core/src/connectors/http/mod.rs b/pingora-core/src/connectors/http/mod.rs new file mode 100644 index 0000000..c399530 --- /dev/null +++ b/pingora-core/src/connectors/http/mod.rs @@ -0,0 +1,221 @@ +// 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. + +//! Connecting to HTTP servers + +use crate::connectors::ConnectorOptions; +use crate::protocols::http::client::HttpSession; +use crate::upstreams::peer::Peer; +use pingora_error::Result; +use std::time::Duration; + +pub mod v1; +pub mod v2; + +pub struct Connector { + h1: v1::Connector, + h2: v2::Connector, +} + +impl Connector { + pub fn new(options: Option) -> Self { + Connector { + h1: v1::Connector::new(options.clone()), + h2: v2::Connector::new(options), + } + } + + /// Get an [HttpSession] to the given server. + /// + /// The second return value indicates whether the session is connected via a reused stream. + pub async fn get_http_session( + &self, + peer: &P, + ) -> Result<(HttpSession, bool)> { + // NOTE: maybe TODO: we do not yet enforce that only TLS traffic can use h2, which is the + // de facto requirement for h2, because non TLS traffic lack the negotiation mechanism. + + // We assume no peer option == no ALPN == h1 only + let h1_only = peer + .get_peer_options() + .map_or(true, |o| o.alpn.get_max_http_version() == 1); + if h1_only { + let (h1, reused) = self.h1.get_http_session(peer).await?; + Ok((HttpSession::H1(h1), reused)) + } else { + // the peer allows h2, we first check the h2 reuse pool + let reused_h2 = self.h2.reused_http_session(peer).await?; + if let Some(h2) = reused_h2 { + return Ok((HttpSession::H2(h2), true)); + } + let h2_only = peer + .get_peer_options() + .map_or(false, |o| o.alpn.get_min_http_version() == 2) + && !self.h2.h1_is_preferred(peer); + if !h2_only { + // We next check the reuse pool for h1 before creating a new h2 connection. + // This is because the server may not support h2 at all, connections to + // the server could all be h1. + if let Some(h1) = self.h1.reused_http_session(peer).await { + return Ok((HttpSession::H1(h1), true)); + } + } + let session = self.h2.new_http_session(peer).await?; + Ok((session, false)) + } + } + + pub async fn release_http_session( + &self, + session: HttpSession, + peer: &P, + idle_timeout: Option, + ) { + match session { + HttpSession::H1(h1) => self.h1.release_http_session(h1, peer, idle_timeout).await, + HttpSession::H2(h2) => self.h2.release_http_session(h2, peer, idle_timeout), + } + } + + /// Tell the connector to always send h1 for ALPN for the given peer in the future. + pub fn prefer_h1(&self, peer: &impl Peer) { + self.h2.prefer_h1(peer); + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::protocols::http::v1::client::HttpSession as Http1Session; + use crate::upstreams::peer::HttpPeer; + use pingora_http::RequestHeader; + + async fn get_http(http: &mut Http1Session, expected_status: u16) { + let mut req = Box::new(RequestHeader::build("GET", b"/", None).unwrap()); + req.append_header("Host", "one.one.one.one").unwrap(); + http.write_request_header(req).await.unwrap(); + http.read_response().await.unwrap(); + http.respect_keepalive(); + + assert_eq!(http.get_status().unwrap(), expected_status); + while http.read_body_bytes().await.unwrap().is_some() {} + } + + #[tokio::test] + async fn test_connect_h2() { + let connector = Connector::new(None); + let mut peer = HttpPeer::new(("1.1.1.1", 443), true, "one.one.one.one".into()); + peer.options.set_http_version(2, 2); + let (h2, reused) = connector.get_http_session(&peer).await.unwrap(); + assert!(!reused); + match &h2 { + HttpSession::H1(_) => panic!("expect h2"), + HttpSession::H2(h2_stream) => assert!(!h2_stream.ping_timedout()), + } + + connector.release_http_session(h2, &peer, None).await; + + let (h2, reused) = connector.get_http_session(&peer).await.unwrap(); + // reused this time + assert!(reused); + match &h2 { + HttpSession::H1(_) => panic!("expect h2"), + HttpSession::H2(h2_stream) => assert!(!h2_stream.ping_timedout()), + } + } + + #[tokio::test] + async fn test_connect_h1() { + let connector = Connector::new(None); + let mut peer = HttpPeer::new(("1.1.1.1", 443), true, "one.one.one.one".into()); + peer.options.set_http_version(1, 1); + let (mut h1, reused) = connector.get_http_session(&peer).await.unwrap(); + assert!(!reused); + match &mut h1 { + HttpSession::H1(http) => { + get_http(http, 200).await; + } + HttpSession::H2(_) => panic!("expect h1"), + } + connector.release_http_session(h1, &peer, None).await; + + let (mut h1, reused) = connector.get_http_session(&peer).await.unwrap(); + // reused this time + assert!(reused); + match &mut h1 { + HttpSession::H1(_) => {} + HttpSession::H2(_) => panic!("expect h1"), + } + } + + #[tokio::test] + async fn test_connect_h2_fallback_h1_reuse() { + // this test verify that if the server doesn't support h2, the Connector will reuse the + // h1 session instead. + + let connector = Connector::new(None); + let mut peer = HttpPeer::new(("1.1.1.1", 443), true, "one.one.one.one".into()); + // As it is hard to find a server that support only h1, we use the following hack to trick + // the connector to think the server supports only h1. We force ALPN to use h1 and then + // return the connection to the Connector. And then we use a Peer that allows h2 + peer.options.set_http_version(1, 1); + let (mut h1, reused) = connector.get_http_session(&peer).await.unwrap(); + assert!(!reused); + match &mut h1 { + HttpSession::H1(http) => { + get_http(http, 200).await; + } + HttpSession::H2(_) => panic!("expect h1"), + } + connector.release_http_session(h1, &peer, None).await; + + let mut peer = HttpPeer::new(("1.1.1.1", 443), true, "one.one.one.one".into()); + peer.options.set_http_version(2, 1); + + let (mut h1, reused) = connector.get_http_session(&peer).await.unwrap(); + // reused this time + assert!(reused); + match &mut h1 { + HttpSession::H1(_) => {} + HttpSession::H2(_) => panic!("expect h1"), + } + } + + #[tokio::test] + async fn test_connect_prefer_h1() { + let connector = Connector::new(None); + let mut peer = HttpPeer::new(("1.1.1.1", 443), true, "one.one.one.one".into()); + peer.options.set_http_version(2, 1); + connector.prefer_h1(&peer); + + let (mut h1, reused) = connector.get_http_session(&peer).await.unwrap(); + assert!(!reused); + match &mut h1 { + HttpSession::H1(http) => { + get_http(http, 200).await; + } + HttpSession::H2(_) => panic!("expect h1"), + } + connector.release_http_session(h1, &peer, None).await; + + peer.options.set_http_version(2, 2); + let (mut h1, reused) = connector.get_http_session(&peer).await.unwrap(); + // reused this time + assert!(reused); + match &mut h1 { + HttpSession::H1(_) => {} + HttpSession::H2(_) => panic!("expect h1"), + } + } +} diff --git a/pingora-core/src/connectors/http/v1.rs b/pingora-core/src/connectors/http/v1.rs new file mode 100644 index 0000000..513fed1 --- /dev/null +++ b/pingora-core/src/connectors/http/v1.rs @@ -0,0 +1,119 @@ +// 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 crate::connectors::{ConnectorOptions, TransportConnector}; +use crate::protocols::http::v1::client::HttpSession; +use crate::upstreams::peer::Peer; + +use pingora_error::Result; +use std::time::Duration; + +pub struct Connector { + transport: TransportConnector, +} + +impl Connector { + pub fn new(options: Option) -> Self { + Connector { + transport: TransportConnector::new(options), + } + } + + pub async fn get_http_session( + &self, + peer: &P, + ) -> Result<(HttpSession, bool)> { + let (stream, reused) = self.transport.get_stream(peer).await?; + let http = HttpSession::new(stream); + Ok((http, reused)) + } + + pub async fn reused_http_session( + &self, + peer: &P, + ) -> Option { + self.transport + .reused_stream(peer) + .await + .map(HttpSession::new) + } + + pub async fn release_http_session( + &self, + session: HttpSession, + peer: &P, + idle_timeout: Option, + ) { + if let Some(stream) = session.reuse().await { + self.transport + .release_stream(stream, peer.reuse_hash(), idle_timeout); + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::upstreams::peer::HttpPeer; + use pingora_http::RequestHeader; + + async fn get_http(http: &mut HttpSession, expected_status: u16) { + let mut req = Box::new(RequestHeader::build("GET", b"/", None).unwrap()); + req.append_header("Host", "one.one.one.one").unwrap(); + http.write_request_header(req).await.unwrap(); + http.read_response().await.unwrap(); + http.respect_keepalive(); + + assert_eq!(http.get_status().unwrap(), expected_status); + while http.read_body_bytes().await.unwrap().is_some() {} + } + + #[tokio::test] + async fn test_connect() { + let connector = Connector::new(None); + let peer = HttpPeer::new(("1.1.1.1", 80), false, "".into()); + // make a new connection to 1.1.1.1 + let (http, reused) = connector.get_http_session(&peer).await.unwrap(); + assert!(!reused); + + // this http is not even used, so not be able to reuse + connector.release_http_session(http, &peer, None).await; + let (mut http, reused) = connector.get_http_session(&peer).await.unwrap(); + assert!(!reused); + + get_http(&mut http, 301).await; + connector.release_http_session(http, &peer, None).await; + let (_, reused) = connector.get_http_session(&peer).await.unwrap(); + assert!(reused); + } + + #[tokio::test] + async fn test_connect_tls() { + let connector = Connector::new(None); + let peer = HttpPeer::new(("1.1.1.1", 443), true, "one.one.one.one".into()); + // make a new connection to https://1.1.1.1 + let (http, reused) = connector.get_http_session(&peer).await.unwrap(); + assert!(!reused); + + // this http is not even used, so not be able to reuse + connector.release_http_session(http, &peer, None).await; + let (mut http, reused) = connector.get_http_session(&peer).await.unwrap(); + assert!(!reused); + + get_http(&mut http, 200).await; + connector.release_http_session(http, &peer, None).await; + let (_, reused) = connector.get_http_session(&peer).await.unwrap(); + assert!(reused); + } +} diff --git a/pingora-core/src/connectors/http/v2.rs b/pingora-core/src/connectors/http/v2.rs new file mode 100644 index 0000000..389bd4e --- /dev/null +++ b/pingora-core/src/connectors/http/v2.rs @@ -0,0 +1,531 @@ +// 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 super::HttpSession; +use crate::connectors::{ConnectorOptions, TransportConnector}; +use crate::protocols::http::v1::client::HttpSession as Http1Session; +use crate::protocols::http::v2::client::{drive_connection, Http2Session}; +use crate::protocols::{Digest, Stream}; +use crate::upstreams::peer::{Peer, ALPN}; + +use bytes::Bytes; +use h2::client::SendRequest; +use log::debug; +use parking_lot::RwLock; +use pingora_error::{Error, ErrorType::*, OrErr, Result}; +use pingora_pool::{ConnectionMeta, ConnectionPool, PoolNode}; +use std::collections::HashMap; +use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; +use std::sync::Arc; +use std::time::Duration; +use tokio::sync::watch; + +struct Stub(SendRequest); + +impl Stub { + async fn new_stream(&self) -> Result> { + let send_req = self.0.clone(); + send_req + .ready() + .await + .or_err(H2Error, "while creating new stream") + } +} + +pub(crate) struct ConnectionRefInner { + connection_stub: Stub, + closed: watch::Receiver, + ping_timeout_occurred: Arc, + id: i32, + // max concurrent streams this connection is allowed to create + max_streams: usize, + // how many concurrent streams already active + current_streams: AtomicUsize, + // because `SendRequest` doesn't actually have access to the underlying Stream, + // we log info about timing and tcp info here. + pub(crate) digest: Digest, +} + +#[derive(Clone)] +pub(crate) struct ConnectionRef(Arc); + +impl ConnectionRef { + pub fn new( + send_req: SendRequest, + closed: watch::Receiver, + ping_timeout_occurred: Arc, + id: i32, + max_streams: usize, + digest: Digest, + ) -> Self { + ConnectionRef(Arc::new(ConnectionRefInner { + connection_stub: Stub(send_req), + closed, + ping_timeout_occurred, + id, + max_streams, + current_streams: AtomicUsize::new(0), + digest, + })) + } + pub fn more_streams_allowed(&self) -> bool { + self.0.max_streams > self.0.current_streams.load(Ordering::Relaxed) + } + + pub fn is_idle(&self) -> bool { + self.0.current_streams.load(Ordering::Relaxed) == 0 + } + + pub fn release_stream(&self) { + self.0.current_streams.fetch_sub(1, Ordering::SeqCst); + } + + pub fn id(&self) -> i32 { + self.0.id + } + + pub fn digest(&self) -> &Digest { + &self.0.digest + } + + pub fn ping_timedout(&self) -> bool { + self.0.ping_timeout_occurred.load(Ordering::Relaxed) + } + + pub fn is_closed(&self) -> bool { + *self.0.closed.borrow() + } + + // spawn a stream if more stream is allowed, otherwise return Ok(None) + pub async fn spawn_stream(&self) -> Result> { + // Atomically check if the current_stream is over the limit + // load(), compare and then fetch_add() cannot guarantee the same + let current_streams = self.0.current_streams.fetch_add(1, Ordering::SeqCst); + if current_streams >= self.0.max_streams { + // already over the limit, reset the counter to the previous value + self.0.current_streams.fetch_sub(1, Ordering::SeqCst); + return Ok(None); + } + let send_req = self.0.connection_stub.new_stream().await.map_err(|e| { + // fail to create the stream, reset the counter + self.0.current_streams.fetch_sub(1, Ordering::SeqCst); + e + })?; + + Ok(Some(Http2Session::new(send_req, self.clone()))) + } +} + +struct InUsePool { + // TODO: use pingora hashmap to shard the lock contention + pools: RwLock>>, +} + +impl InUsePool { + fn new() -> Self { + InUsePool { + pools: RwLock::new(HashMap::new()), + } + } + + fn insert(&self, reuse_hash: u64, conn: ConnectionRef) { + { + let pools = self.pools.read(); + if let Some(pool) = pools.get(&reuse_hash) { + pool.insert(conn.id(), conn); + return; + } + } // drop read lock + + let pool = PoolNode::new(); + pool.insert(conn.id(), conn); + let mut pools = self.pools.write(); + pools.insert(reuse_hash, pool); + } + + // retrieve a h2 conn ref to create a new stream + // the caller should return the conn ref to this pool if there are still + // capacity left for more streams + fn get(&self, reuse_hash: u64) -> Option { + let pools = self.pools.read(); + pools.get(&reuse_hash)?.get_any().map(|v| v.1) + } + + // release a h2_stream, this functional will cause an ConnectionRef to be returned (if exist) + // the caller should update the ref and then decide where to put it (in use pool or idle) + fn release(&self, reuse_hash: u64, id: i32) -> Option { + let pools = self.pools.read(); + if let Some(pool) = pools.get(&reuse_hash) { + pool.remove(id) + } else { + None + } + } +} + +const DEFAULT_POOL_SIZE: usize = 128; + +/// Http2 connector +pub struct Connector { + // just for creating connections, the Stream of h2 should be reused + transport: TransportConnector, + // the h2 connection idle pool + idle_pool: Arc>, + // the pool of h2 connections that have ongoing streams + in_use_pool: InUsePool, +} + +impl Connector { + /// Create a new [Connector] from the given [ConnectorOptions] + pub fn new(options: Option) -> Self { + let pool_size = options + .as_ref() + .map_or(DEFAULT_POOL_SIZE, |o| o.keepalive_pool_size); + // connection offload is handled by the [TransportConnector] + Connector { + transport: TransportConnector::new(options), + idle_pool: Arc::new(ConnectionPool::new(pool_size)), + in_use_pool: InUsePool::new(), + } + } + + /// Create a new Http2 connection to the given server + /// + /// Either an Http2 or Http1 session can be returned depending on the server's preference. + pub async fn new_http_session( + &self, + peer: &P, + ) -> Result { + let stream = self.transport.new_stream(peer).await?; + + // check alpn + match stream.selected_alpn_proto() { + Some(ALPN::H2) => { /* continue */ } + Some(_) => { + // H2 not supported + return Ok(HttpSession::H1(Http1Session::new(stream))); + } + None => { + // if tls but no ALPN, default to h1 + // else if plaintext and min http version is 1, this is most likely h1 + if peer.tls() + || peer + .get_peer_options() + .map_or(true, |o| o.alpn.get_min_http_version() == 1) + { + return Ok(HttpSession::H1(Http1Session::new(stream))); + } + // else: min http version=H2 over plaintext, there is no ALPN anyways, we trust + // the caller that the server speaks h2c + } + } + let max_h2_stream = peer.get_peer_options().map_or(1, |o| o.max_h2_streams); + let conn = handshake(stream, max_h2_stream, peer.h2_ping_interval()).await?; + let h2_stream = conn + .spawn_stream() + .await? + .expect("newly created connections should have at least one free stream"); + if conn.more_streams_allowed() { + self.in_use_pool.insert(peer.reuse_hash(), conn); + } + Ok(HttpSession::H2(h2_stream)) + } + + /// Try to create a new http2 stream from any existing H2 connection. + /// + /// None means there is no "free" connection left. + pub async fn reused_http_session( + &self, + peer: &P, + ) -> Result> { + // check in use pool first so that we use fewer total connections + // then idle pool + let reuse_hash = peer.reuse_hash(); + + // NOTE: We grab a conn from the pools, create a new stream and put the conn back if the + // conn has more free streams. During this process another caller could arrive but is not + // able to find the conn even the conn has free stream to use. + // We accept this false negative to keep the implementation simple. This false negative + // makes an actual impact when there are only a few connection. + // Alternative design 1. given each free stream a conn object: a lot of Arc<> + // Alternative design 2. mutex the pool, which creates lock contention when concurrency is high + // Alternative design 3. do not pop conn from the pool so that multiple callers can grab it + // which will cause issue where spawn_stream() could return None because others call it + // first. Thus a caller might have to retry or give up. This issue is more likely to happen + // when concurrency is high. + let maybe_conn = self + .in_use_pool + .get(reuse_hash) + .or_else(|| self.idle_pool.get(&reuse_hash)); + if let Some(conn) = maybe_conn { + let h2_stream = conn + .spawn_stream() + .await? + .expect("connection from the pools should have free stream to allocate"); + if conn.more_streams_allowed() { + self.in_use_pool.insert(reuse_hash, conn); + } + Ok(Some(h2_stream)) + } else { + Ok(None) + } + } + + /// Release a finished h2 stream. + /// + /// This function will terminate the [Http2Session]. The corresponding h2 connection will now + /// have one more free stream to use. + /// + /// The h2 connection will be closed after `idle_timeout` if it has no active streams. + pub fn release_http_session( + &self, + session: Http2Session, + peer: &P, + idle_timeout: Option, + ) { + let id = session.conn.id(); + let reuse_hash = peer.reuse_hash(); + // get a ref to the connection, which we might need below, before dropping the h2 + let conn = session.conn(); + // this drop() will both drop the actual stream and call the conn.release_stream() + drop(session); + // find and remove the conn stored in in_use_pool so that it could be put in the idle pool + // if necessary + let conn = self.in_use_pool.release(reuse_hash, id).unwrap_or(conn); + if conn.is_closed() { + // Already dead h2 connection + return; + } + if conn.is_idle() { + let meta = ConnectionMeta { + key: reuse_hash, + id, + }; + let closed = conn.0.closed.clone(); + let (notify_evicted, watch_use) = self.idle_pool.put(&meta, conn); + if let Some(to) = idle_timeout { + let pool = self.idle_pool.clone(); //clone the arc + let rt = pingora_runtime::current_handle(); + rt.spawn(async move { + pool.idle_timeout(&meta, to, notify_evicted, closed, watch_use) + .await; + }); + } + } else { + self.in_use_pool.insert(reuse_hash, conn); + } + } + + /// Tell the connector to always send h1 for ALPN for the given peer in the future. + pub fn prefer_h1(&self, peer: &impl Peer) { + self.transport.prefer_h1(peer); + } + + pub(crate) fn h1_is_preferred(&self, peer: &impl Peer) -> bool { + self.transport + .preferred_http_version + .get(peer) + .map_or(false, |v| matches!(v, ALPN::H1)) + } +} + +// The h2 library we use has unbounded internal buffering, which will cause excessive memory +// consumption when the downstream is slower than upstream. This window size caps the buffering by +// limiting how much data can be inflight. However, setting this value will also cap the max +// download speed by limiting the bandwidth-delay product of a link. +// Long term, we should advertising large window but shrink it when a small buffer is full. +// 8 Mbytes = 80 Mbytes X 100ms, which should be enough for most links. +const H2_WINDOW_SIZE: u32 = 1 << 23; + +async fn handshake( + stream: Stream, + max_streams: usize, + h2_ping_interval: Option, +) -> Result { + use h2::client::Builder; + use pingora_runtime::current_handle; + + // Safe guard: new_http_session() assumes there should be at least one free stream + if max_streams == 0 { + return Error::e_explain(H2Error, "zero max_stream configured"); + } + + let id = stream.id(); + let digest = Digest { + // NOTE: this field is always false because the digest is shared across all streams + // The streams should log their own reuse info + ssl_digest: stream.get_ssl_digest(), + // TODO: log h2 handshake time + timing_digest: stream.get_timing_digest(), + proxy_digest: stream.get_proxy_digest(), + }; + // TODO: make these configurable + let (send_req, connection) = Builder::new() + .enable_push(false) + .initial_max_send_streams(max_streams) + // The limit for the server. Server push is not allowed, so this value doesn't matter + .max_concurrent_streams(1) + .max_frame_size(64 * 1024) // advise server to send larger frames + .initial_window_size(H2_WINDOW_SIZE) + // should this be max_streams * H2_WINDOW_SIZE? + .initial_connection_window_size(H2_WINDOW_SIZE) + .handshake(stream) + .await + .or_err(HandshakeError, "during H2 handshake")?; + debug!("H2 handshake to server done."); + let ping_timeout_occurred = Arc::new(AtomicBool::new(false)); + let ping_timeout_clone = ping_timeout_occurred.clone(); + let max_allowed_streams = std::cmp::min(max_streams, connection.max_concurrent_send_streams()); + + // Safe guard: new_http_session() assumes there should be at least one free stream + // The server won't commonly advertise 0 max stream. + if max_allowed_streams == 0 { + return Error::e_explain(H2Error, "zero max_concurrent_send_streams received"); + } + + let (closed_tx, closed_rx) = watch::channel(false); + + current_handle().spawn(async move { + drive_connection( + connection, + id, + closed_tx, + h2_ping_interval, + ping_timeout_clone, + ) + .await; + }); + Ok(ConnectionRef::new( + send_req, + closed_rx, + ping_timeout_occurred, + id, + max_allowed_streams, + digest, + )) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::upstreams::peer::HttpPeer; + + #[tokio::test] + async fn test_connect_h2() { + let connector = Connector::new(None); + let mut peer = HttpPeer::new(("1.1.1.1", 443), true, "one.one.one.one".into()); + peer.options.set_http_version(2, 2); + let h2 = connector.new_http_session(&peer).await.unwrap(); + match h2 { + HttpSession::H1(_) => panic!("expect h2"), + HttpSession::H2(h2_stream) => assert!(!h2_stream.ping_timedout()), + } + } + + #[tokio::test] + async fn test_connect_h1() { + let connector = Connector::new(None); + let mut peer = HttpPeer::new(("1.1.1.1", 443), true, "one.one.one.one".into()); + // a hack to force h1, new_http_session() in the future might validate this setting + peer.options.set_http_version(1, 1); + let h2 = connector.new_http_session(&peer).await.unwrap(); + match h2 { + HttpSession::H1(_) => {} + HttpSession::H2(_) => panic!("expect h1"), + } + } + + #[tokio::test] + async fn test_connect_h1_plaintext() { + let connector = Connector::new(None); + let mut peer = HttpPeer::new(("1.1.1.1", 80), false, "".into()); + peer.options.set_http_version(2, 1); + let h2 = connector.new_http_session(&peer).await.unwrap(); + match h2 { + HttpSession::H1(_) => {} + HttpSession::H2(_) => panic!("expect h1"), + } + } + + #[tokio::test] + async fn test_h2_single_stream() { + let connector = Connector::new(None); + let mut peer = HttpPeer::new(("1.1.1.1", 443), true, "one.one.one.one".into()); + peer.options.set_http_version(2, 2); + peer.options.max_h2_streams = 1; + let h2 = connector.new_http_session(&peer).await.unwrap(); + let h2_1 = match h2 { + HttpSession::H1(_) => panic!("expect h2"), + HttpSession::H2(h2_stream) => h2_stream, + }; + + let id = h2_1.conn.id(); + + assert!(connector + .reused_http_session(&peer) + .await + .unwrap() + .is_none()); + + connector.release_http_session(h2_1, &peer, None); + + let h2_2 = connector.reused_http_session(&peer).await.unwrap().unwrap(); + assert_eq!(id, h2_2.conn.id()); + + connector.release_http_session(h2_2, &peer, None); + + let h2_3 = connector.reused_http_session(&peer).await.unwrap().unwrap(); + assert_eq!(id, h2_3.conn.id()); + } + + #[tokio::test] + async fn test_h2_multiple_stream() { + let connector = Connector::new(None); + let mut peer = HttpPeer::new(("1.1.1.1", 443), true, "one.one.one.one".into()); + peer.options.set_http_version(2, 2); + peer.options.max_h2_streams = 3; + let h2 = connector.new_http_session(&peer).await.unwrap(); + let h2_1 = match h2 { + HttpSession::H1(_) => panic!("expect h2"), + HttpSession::H2(h2_stream) => h2_stream, + }; + + let id = h2_1.conn.id(); + + let h2_2 = connector.reused_http_session(&peer).await.unwrap().unwrap(); + assert_eq!(id, h2_2.conn.id()); + let h2_3 = connector.reused_http_session(&peer).await.unwrap().unwrap(); + assert_eq!(id, h2_3.conn.id()); + + // max stream is 3 for now + assert!(connector + .reused_http_session(&peer) + .await + .unwrap() + .is_none()); + + connector.release_http_session(h2_1, &peer, None); + + let h2_4 = connector.reused_http_session(&peer).await.unwrap().unwrap(); + assert_eq!(id, h2_4.conn.id()); + + connector.release_http_session(h2_2, &peer, None); + connector.release_http_session(h2_3, &peer, None); + connector.release_http_session(h2_4, &peer, None); + + // all streams are released, now the connection is idle + let h2_5 = connector.reused_http_session(&peer).await.unwrap().unwrap(); + assert_eq!(id, h2_5.conn.id()); + } +} diff --git a/pingora-core/src/connectors/l4.rs b/pingora-core/src/connectors/l4.rs new file mode 100644 index 0000000..6f0f5fd --- /dev/null +++ b/pingora-core/src/connectors/l4.rs @@ -0,0 +1,313 @@ +// 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 log::debug; +use pingora_error::{Context, Error, ErrorType::*, OrErr, Result}; +use rand::seq::SliceRandom; +use std::net::SocketAddr as InetSocketAddr; + +use crate::protocols::l4::ext::{connect as tcp_connect, connect_uds, set_tcp_keepalive}; +use crate::protocols::l4::socket::SocketAddr; +use crate::protocols::l4::stream::Stream; +use crate::upstreams::peer::Peer; + +/// Establish a connection (l4) to the given peer using its settings and an optional bind address. +pub async fn connect