Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
a3b1861
expose content_type on multirangeinfo
gumpt Mar 16, 2026
21fa592
Allow adjusting upstream modules on response header recv
drcaramelsyrup Mar 6, 2026
af7dd46
Don't init body reader on HEAD 1xx
drcaramelsyrup Mar 18, 2026
d0ede94
Make tracing an optional feature in pingora-cache
drcaramelsyrup Mar 5, 2026
b633683
Fix listen fds not inherited during bootstrap_as_a_service graceful u…
johnhurt Mar 20, 2026
c29014f
Retry on new h2 connection if spawn stream broken pipe
mariiacloudflare Mar 17, 2026
63c5f21
Add abort_on_close functionality to HTTP session handling
lxga Mar 9, 2026
22ffdb8
Add comments around pend behavior for abort_on_close
drcaramelsyrup Mar 24, 2026
c4beff8
expose pipe_subrequest outcome
gumpt Mar 25, 2026
542129f
Fix flaky tests: test_tls_psk, test_conn_timeout, test_1xx_caching, l…
johnhurt Mar 23, 2026
1d93711
Replace tokio::sync::Mutex with parking_lot::Mutex for ListenFds
johnhurt Mar 25, 2026
9855feb
ci: use cargo check for MSRV instead of cargo test
zaidoon1 Apr 10, 2026
ee387f4
Add a mechanism for signalling between old and new processes when doi…
johnhurt Mar 29, 2026
d7728ca
Add cancel-safe body and header writer primitives
drcaramelsyrup Feb 28, 2026
5a82204
Add proxy task API for v1 server sessions
drcaramelsyrup Mar 20, 2026
8683056
Use proxy task API for cache-served proxy_h1 downstream writes
drcaramelsyrup Mar 2, 2026
ce16618
Add per-session toggle for the proxy task API
drcaramelsyrup Mar 20, 2026
969eb67
Use proxy task API in proxy_h2 and proxy_custom for cache-served down…
drcaramelsyrup Mar 20, 2026
e7de90a
Fix body bytes count on v1 session
drcaramelsyrup Mar 27, 2026
9267745
add peek_lru to LRU eviction manager
duke8253 Apr 2, 2026
ea9d9ec
Expose Unexpected Data Counter from Connection Pool
daviscloudflare Mar 20, 2026
d41a66b
update bench_lru with production-scale data, warn about promote_top_n
duke8253 Apr 2, 2026
842ddd9
Split out pingora-prometheus into a separate crate
drcaramelsyrup Apr 1, 2026
2114056
Make h2 stream window and conn window size configurable
drcaramelsyrup Apr 4, 2026
c0adfd3
Ignore caching stall tests for CI flakiness
drcaramelsyrup Apr 17, 2026
452813e
ci: add Semgrep OSS scanning workflow
hrushikeshdeshpande Apr 23, 2026
d4e4ae1
vary on available-dictionary
gumpt Apr 9, 2026
6ac51b3
Add upstream module system
drcaramelsyrup Apr 10, 2026
5e0f216
Return error on new conn h2 spawn stream
drcaramelsyrup Apr 11, 2026
8b2fa50
Strip H1-specific headers when downstream is a custom protocol and up…
areyia Apr 14, 2026
927a00c
Avoid hit handler finish on disabled cache
drcaramelsyrup Apr 15, 2026
f6dadf8
Syncing some mismatched internal/external changes
johnhurt Apr 24, 2026
3a95c50
RUSTSEC-2026-0098 and RUSTSEC-2026-0099 fixes
johnhurt Apr 24, 2026
1476e7a
expose pipe receiver in subrequest state
gumpt Apr 14, 2026
1f83d3c
Changing type of PeerOptions curve to Cow to allow for dynamically de…
icrutche Apr 13, 2026
6c523ee
Add support for fractional delta seconds that are floored (optional R…
andrewhavck Apr 21, 2026
a95f8c4
feat: make rustls cert public
shaneutt Apr 12, 2026
bc9870d
Fix flaky test_connector_bind_to on macOS/CI
johnhurt Apr 28, 2026
aece993
let h2 accept loop drain in-flight streams on shutdown
gumpt May 1, 2026
06cbc1c
Derive Clone and Debug on HttpServerOptions
areyia May 1, 2026
043f1f6
Use power-of-two selection to balance eviction
drcaramelsyrup Apr 30, 2026
2536867
Adding curves and second keyshare setting to httppeer hash
icrutche May 1, 2026
ab48509
Add working_directory option for daemon mode
drcaramelsyrup May 6, 2026
7d3677d
Ignore test_upload_connection_die due to timing dependency
johnhurt May 7, 2026
77cce2c
Add cancel-safe proxy task API for Subrequest server sessions
drcaramelsyrup May 4, 2026
c0845a8
Add per-listener L4 buffer configuration
drcaramelsyrup May 5, 2026
5ff6afa
feat(pingora-core): expose PROXY v2 extension-TLV callback
pigri Jun 1, 2026
810a9e3
chore: cargo fmt on the proxy-v2-tlv-callback additions
pigri Jun 1, 2026
8162b85
chore(pingora-core): pin proxy-protocol to v0.5.3 release
pigri Jun 1, 2026
5a6eef3
ci: bump MSRV in the build matrix 1.84.0 → 1.85.0
pigri Jun 1, 2026
a8149cf
fix(pingora-http): parse authority-form URIs for CONNECT request-lines
pigri Jun 1, 2026
abf3db6
fix(pingora-http): tolerate non-URI raw paths; fix doctest + test lint
pigri Jun 1, 2026
115e603
Merge remote-tracking branch 'upstream/main' into feat/proxy-v2-tlv-c…
pigri Jun 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .bleep
Original file line number Diff line number Diff line change
@@ -1 +1 @@
f0b43320bb1a5f7788a7d0e90a804e045f0af2fb
5281b97daa3213287999fb97c2a5de57ae565011
3 changes: 3 additions & 0 deletions .cargo/audit.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[advisories]
# Temp before internal sync applies dependency bumps
ignore = ["RUSTSEC-2026-0097", "RUSTSEC-2026-0098", "RUSTSEC-2026-0099"]
11 changes: 9 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ jobs:
strategy:
fail-fast: false
matrix:
# nightly, msrv, and latest stable
toolchain: [nightly, 1.84.0, 1.91.1]
# nightly, msrv, and latest stable.
# MSRV bumped 1.84.0 → 1.85.0 to pick up `edition = "2024"`
# stabilization, which `proxy-protocol >= 0.5.3` requires.
toolchain: [nightly, 1.85.0, 1.91.1]
runs-on: ubuntu-latest
# Only run on "pull_request" event for external PRs. This is to avoid
# duplicate builds for PRs created from internal branches.
Expand Down Expand Up @@ -38,12 +40,17 @@ jobs:
- name: Run cargo fmt
run: cargo fmt --all -- --check

- name: Run cargo check
run: cargo check --workspace

- name: Run cargo test
if: matrix.toolchain != '1.84.0'
run: cargo test --verbose --lib --bins --tests --no-fail-fast

# Need to run doc tests separately.
# (https://github.com/rust-lang/cargo/issues/6669)
- name: Run cargo doc test
if: matrix.toolchain != '1.84.0'
run: cargo test --verbose --doc

- name: Run cargo clippy
Expand Down
40 changes: 23 additions & 17 deletions .github/workflows/semgrep.yml
Original file line number Diff line number Diff line change
@@ -1,24 +1,30 @@
name: Semgrep OSS scan
on:
pull_request: {}
push:
branches: [main, master]
workflow_dispatch: {}
push:
branches:
- main
- master
schedule:
- cron: '0 0 * * *'
name: Semgrep config
- cron: '0 0 15 * *'
concurrency:
group: semgrep-${{ github.event_name }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
permissions:
contents: read
jobs:
semgrep:
name: semgrep/ci
runs-on: ubuntu-latest
env:
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
SEMGREP_URL: https://cloudflare.semgrep.dev
SEMGREP_APP_URL: https://cloudflare.semgrep.dev
SEMGREP_VERSION_CHECK_URL: https://cloudflare.semgrep.dev/api/check-version
container:
image: returntocorp/semgrep
name: semgrep-oss
runs-on: ubuntu-slim
steps:
- uses: actions/checkout@v4
- run: semgrep ci
- uses: actions/checkout@v5
with:
fetch-depth: 1
- id: cache-semgrep
uses: actions/cache@v5
with:
path: ~/.local
key: semgrep-1.160.0-${{ runner.os }}
- if: steps.cache-semgrep.outputs.cache-hit != 'true'
run: pip install --user semgrep==1.160.0
- run: echo "$HOME/.local/bin" >> "$GITHUB_PATH"
- run: semgrep scan --config=auto
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ dhat-heap.json
.vscode
.idea
.cover
bleeper.user.toml
bleeper.user.toml
.DS_Store
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ members = [
"pingora-ketama",
"pingora-load-balancing",
"pingora-memory-cache",
"pingora-prometheus",
"tinyufo",
]

Expand Down
4 changes: 4 additions & 0 deletions docs/user_guide/conf.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,16 @@ group: webusers
| 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 |
| working_directory | the working directory for the daemonized process | 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 |
| s2n_config_cache_size | The maximum number of unique s2n configs to cache. A value of 0 disables the cache. Default: 10 (s2n-tls only) | number |
| 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 connection pool | number |
| daemon_wait_for_ready | When `true` and `daemon` is `true`, the parent process waits for the daemon to signal readiness (via `SIGUSR1`) before exiting. This causes systemd to delay sending `SIGQUIT` to the old process until the new instance is fully bootstrapped. Default: `false` | bool |
| daemon_ready_timeout_seconds | How long (in seconds) the parent waits for the daemon to signal readiness when `daemon_wait_for_ready` is `true`. If the daemon does not signal in time the parent exits with a non-zero code, causing systemd to abort the reload. Default: `600` | number |
| daemon_notify_timeout_seconds | How long (in seconds) the daemon retries sending `SIGUSR1` to the parent when the attempt fails with a permission error. This covers the brief window after the fork where the parent has not yet dropped its UID to match the daemon. Default: `60` | 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.
3 changes: 1 addition & 2 deletions docs/user_guide/modify_filter.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,7 @@ impl ProxyHttp for MyGateway {

fn main() {
...
let mut prometheus_service_http =
pingora::services::listening::Service::prometheus_http_service();
let mut prometheus_service_http = pingora_prometheus::prometheus_http_service();
prometheus_service_http.add_tcp("127.0.0.1:6192");
my_server.add_service(prometheus_service_http);

Expand Down
8 changes: 7 additions & 1 deletion docs/user_guide/phase.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ Pingora-proxy allows users to insert arbitrary logic into the life of a request.
upstream_request_filter --> request_body_filter;
request_body_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");
RecvResp-.feature: adjust_upstream_modules.->adjust_upstream_modules;
adjust_upstream_modules-->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;
Expand Down Expand Up @@ -92,6 +93,11 @@ If the error is not retry-able, the request will end.
### `upstream_request_filter()`
This phase is to modify requests before sending to upstream.

### `adjust_upstream_modules()` _(feature: `adjust_upstream_modules`)_
This phase is triggered when the upstream response header arrives, before upstream modules (such as `upstream_compression`) process it.

Use this to configure upstream module behavior based on the response header, e.g. setting a dictionary for dictionary-based content encoding. The response header is provided as an immutable reference; to modify the response header itself, use `upstream_response_filter()` instead.

### `upstream_response_filter()/upstream_response_body_filter()/upstream_response_trailer_filter()`
This phase is triggered after an upstream response header/body/trailer is received.

Expand Down
3 changes: 2 additions & 1 deletion docs/user_guide/phase_chart.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ Pingora proxy phases without caching
upstream_request_filter --> request_body_filter;
request_body_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");
RecvResp-.feature: adjust_upstream_modules.->adjust_upstream_modules;
adjust_upstream_modules-->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;
Expand Down
20 changes: 6 additions & 14 deletions docs/user_guide/prom.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,21 @@
# Prometheus

Pingora has a built-in prometheus HTTP metric server for scraping.
The [`pingora-prometheus`](https://docs.rs/pingora-prometheus) crate provides a
Prometheus HTTP metrics server for scraping.

## Enabling Prometheus Support
## Adding the Dependency

Prometheus support is an optional feature in Pingora. To use it, you need to enable the `prometheus` feature in your `Cargo.toml`:
Add `pingora-prometheus` to your `Cargo.toml`:

```toml
# If using the main pingora crate
pingora = { version = "0.8.0", features = ["prometheus"] }

# If using pingora-core directly
pingora-core = { version = "0.8.0", features = ["prometheus"] }

# If using pingora-proxy crate
pingora-proxy = { version = "0.8.0", features = ["prometheus"] }
pingora-prometheus = "0.8.0"
```

## Setting up a Prometheus Metrics Endpoint

Once the feature is enabled, you can set up a Prometheus metrics endpoint like this:

```rust
...
let mut prometheus_service_http = Service::prometheus_http_service();
let mut prometheus_service_http = pingora_prometheus::prometheus_http_service();
prometheus_service_http.add_tcp("0.0.0.0:1234");
my_server.add_service(prometheus_service_http);
my_server.run_forever();
Expand Down
7 changes: 5 additions & 2 deletions pingora-cache/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ httpdate = "1.0.2"
log = { workspace = true }
async-trait = { workspace = true }
parking_lot = "0.12"
cf-rustracing = "1.0"
cf-rustracing-jaeger = "1.0"
cf-rustracing = { version = "1.0", optional = true }
cf-rustracing-jaeger = { version = "1.0", optional = true }
rmp = "0.8.14"
tokio = { workspace = true }
lru = { workspace = true }
Expand All @@ -49,6 +49,8 @@ strum = { version = "0.26", features = ["derive"] }
rand = "0.8"

[dev-dependencies]
cf-rustracing = "1.0"
cf-rustracing-jaeger = "1.0"
tokio-test = "0.4"
tokio = { workspace = true, features = ["fs"] }
env_logger = "0.11"
Expand All @@ -73,3 +75,4 @@ openssl = ["pingora-core/openssl"]
boringssl = ["pingora-core/boringssl"]
rustls = ["pingora-core/rustls"]
s2n = ["pingora-core/s2n"]
trace = ["dep:cf-rustracing", "dep:cf-rustracing-jaeger"]
Loading
Loading