Compare commits

...

132 Commits

Author SHA1 Message Date
Mohammed Al Sahaf df9386fa12 ci: escape backticks in changelogs embedded in JS (#7382)
Tests / test (./cmd/caddy/caddy, ~1.25.0, ubuntu-latest, 0, 1.25, linux) (push) Failing after 18s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.25.0, 1.25, aix) (push) Failing after 17s
Cross-Build / build (~1.25.0, 1.25, darwin) (push) Failing after 16s
Cross-Build / build (~1.25.0, 1.25, dragonfly) (push) Failing after 16s
Cross-Build / build (~1.25.0, 1.25, freebsd) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, illumos) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, linux) (push) Failing after 16s
Cross-Build / build (~1.25.0, 1.25, netbsd) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, openbsd) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, solaris) (push) Failing after 18s
Cross-Build / build (~1.25.0, 1.25, windows) (push) Failing after 15s
Lint / lint (ubuntu-latest, linux) (push) Failing after 14s
Lint / govulncheck (push) Successful in 1m33s
Lint / dependency-review (push) Failing after 15s
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 15s
Tests / test (./cmd/caddy/caddy, ~1.25.0, macos-14, 0, 1.25, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.25.0, windows-latest, True, 1.25, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>
2025-12-03 16:40:31 +00:00
dependabot[bot] 786d537877 build(deps): bump the all-updates group with 3 updates (#7376)
Tests / test (./cmd/caddy/caddy, ~1.25.0, ubuntu-latest, 0, 1.25, linux) (push) Failing after 50s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.25.0, 1.25, aix) (push) Failing after 17s
Cross-Build / build (~1.25.0, 1.25, darwin) (push) Failing after 17s
Cross-Build / build (~1.25.0, 1.25, dragonfly) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, freebsd) (push) Failing after 20s
Cross-Build / build (~1.25.0, 1.25, illumos) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, linux) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, netbsd) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, openbsd) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, solaris) (push) Failing after 28s
Cross-Build / build (~1.25.0, 1.25, windows) (push) Failing after 15s
Lint / lint (ubuntu-latest, linux) (push) Failing after 14s
Lint / govulncheck (push) Successful in 1m25s
Lint / dependency-review (push) Failing after 15s
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 14s
Tests / test (./cmd/caddy/caddy, ~1.25.0, macos-14, 0, 1.25, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.25.0, windows-latest, True, 1.25, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
Bumps the all-updates group with 3 updates: [github.com/klauspost/compress](https://github.com/klauspost/compress), [github.com/quic-go/quic-go](https://github.com/quic-go/quic-go) and [go.uber.org/zap](https://github.com/uber-go/zap).


Updates `github.com/klauspost/compress` from 1.18.1 to 1.18.2
- [Release notes](https://github.com/klauspost/compress/releases)
- [Commits](https://github.com/klauspost/compress/compare/v1.18.1...v1.18.2)

Updates `github.com/quic-go/quic-go` from 0.57.0 to 0.57.1
- [Release notes](https://github.com/quic-go/quic-go/releases)
- [Commits](https://github.com/quic-go/quic-go/compare/v0.57.0...v0.57.1)

Updates `go.uber.org/zap` from 1.27.0 to 1.27.1
- [Release notes](https://github.com/uber-go/zap/releases)
- [Changelog](https://github.com/uber-go/zap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/uber-go/zap/compare/v1.27.0...v1.27.1)

---
updated-dependencies:
- dependency-name: github.com/klauspost/compress
  dependency-version: 1.18.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
- dependency-name: github.com/quic-go/quic-go
  dependency-version: 0.57.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
- dependency-name: go.uber.org/zap
  dependency-version: 1.27.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-02 10:32:58 +03:00
Petr 67a9e0657e reverseproxy: Fix retries for requests with bodies (#7360)
Tests / test (./cmd/caddy/caddy, ~1.25.0, ubuntu-latest, 0, 1.25, linux) (push) Failing after 47s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.25.0, 1.25, aix) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, darwin) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, dragonfly) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, freebsd) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, illumos) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, linux) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, netbsd) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, openbsd) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, solaris) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, windows) (push) Failing after 15s
Lint / lint (ubuntu-latest, linux) (push) Failing after 15s
Lint / govulncheck (push) Successful in 1m49s
Lint / dependency-review (push) Failing after 15s
Tests / test (./cmd/caddy/caddy, ~1.25.0, macos-14, 0, 1.25, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.25.0, windows-latest, True, 1.25, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 17s
* capture the buffered body once, then reset clonedReq.Body before each retry

* no copy

* keep receiver name

* set the buf to nil after extraction and only return it to pool if not nil

---------

Co-authored-by: WeidiDeng <weidi_deng@icloud.com>
2025-11-24 12:03:18 -07:00
ledigang 2cb426776c encode: modernize, replace HasSuffix+TrimSuffix with CutSuffix (#7357)
Tests / test (./cmd/caddy/caddy, ~1.25.0, ubuntu-latest, 0, 1.25, linux) (push) Failing after 16s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.25.0, 1.25, aix) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, darwin) (push) Failing after 16s
Cross-Build / build (~1.25.0, 1.25, dragonfly) (push) Failing after 17s
Cross-Build / build (~1.25.0, 1.25, freebsd) (push) Failing after 16s
Cross-Build / build (~1.25.0, 1.25, illumos) (push) Failing after 17s
Cross-Build / build (~1.25.0, 1.25, linux) (push) Failing after 16s
Cross-Build / build (~1.25.0, 1.25, netbsd) (push) Failing after 16s
Cross-Build / build (~1.25.0, 1.25, openbsd) (push) Failing after 17s
Cross-Build / build (~1.25.0, 1.25, solaris) (push) Failing after 17s
Cross-Build / build (~1.25.0, 1.25, windows) (push) Failing after 17s
Lint / lint (ubuntu-latest, linux) (push) Failing after 17s
Lint / govulncheck (push) Successful in 1m39s
Lint / dependency-review (push) Failing after 15s
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 29s
Tests / test (./cmd/caddy/caddy, ~1.25.0, macos-14, 0, 1.25, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.25.0, windows-latest, True, 1.25, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
Signed-off-by: ledigang <shuangcui@msn.com>
2025-11-21 15:30:26 -07:00
Marten Seemann b9e6f3b227 update quic-go to v0.57.0 (#7359)
Tests / test (./cmd/caddy/caddy, ~1.25.0, ubuntu-latest, 0, 1.25, linux) (push) Failing after 20s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.25.0, 1.25, aix) (push) Failing after 18s
Cross-Build / build (~1.25.0, 1.25, darwin) (push) Failing after 17s
Cross-Build / build (~1.25.0, 1.25, dragonfly) (push) Failing after 16s
Cross-Build / build (~1.25.0, 1.25, freebsd) (push) Failing after 16s
Cross-Build / build (~1.25.0, 1.25, illumos) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, linux) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, netbsd) (push) Failing after 16s
Cross-Build / build (~1.25.0, 1.25, openbsd) (push) Failing after 16s
Cross-Build / build (~1.25.0, 1.25, solaris) (push) Failing after 16s
Cross-Build / build (~1.25.0, 1.25, windows) (push) Failing after 15s
Lint / lint (ubuntu-latest, linux) (push) Failing after 15s
Lint / govulncheck (push) Successful in 1m29s
Lint / dependency-review (push) Failing after 15s
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 15s
Tests / test (./cmd/caddy/caddy, ~1.25.0, macos-14, 0, 1.25, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.25.0, windows-latest, True, 1.25, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
2025-11-21 14:46:47 +03:00
dependabot[bot] eead249382 build(deps): bump golang.org/x/crypto from 0.43.0 to 0.45.0 (#7355)
Tests / test (./cmd/caddy/caddy, ~1.25.0, ubuntu-latest, 0, 1.25, linux) (push) Failing after 18s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.25.0, 1.25, aix) (push) Failing after 17s
Cross-Build / build (~1.25.0, 1.25, darwin) (push) Failing after 16s
Cross-Build / build (~1.25.0, 1.25, dragonfly) (push) Failing after 27s
Cross-Build / build (~1.25.0, 1.25, freebsd) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, illumos) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, linux) (push) Failing after 16s
Cross-Build / build (~1.25.0, 1.25, netbsd) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, openbsd) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, solaris) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, windows) (push) Failing after 15s
Lint / lint (ubuntu-latest, linux) (push) Failing after 15s
Lint / govulncheck (push) Successful in 1m41s
Lint / dependency-review (push) Failing after 16s
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 17s
Tests / test (./cmd/caddy/caddy, ~1.25.0, macos-14, 0, 1.25, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.25.0, windows-latest, True, 1.25, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.43.0 to 0.45.0.
- [Commits](https://github.com/golang/crypto/compare/v0.43.0...v0.45.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-version: 0.45.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-19 20:55:13 -07:00
WeidiDeng a6da1acdc8 reverse_proxy: use interfaces to modify the behaviors of the transports (#7353)
Tests / test (./cmd/caddy/caddy, ~1.25.0, ubuntu-latest, 0, 1.25, linux) (push) Failing after 17s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.25.0, 1.25, aix) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, darwin) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, dragonfly) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, freebsd) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, illumos) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, linux) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, netbsd) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, openbsd) (push) Failing after 17s
Cross-Build / build (~1.25.0, 1.25, solaris) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, windows) (push) Failing after 16s
Lint / lint (ubuntu-latest, linux) (push) Failing after 15s
Lint / govulncheck (push) Successful in 1m23s
Lint / dependency-review (push) Failing after 15s
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 16s
Tests / test (./cmd/caddy/caddy, ~1.25.0, macos-14, 0, 1.25, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.25.0, windows-latest, True, 1.25, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
2025-11-17 09:51:37 -07:00
Mohammed Al Sahaf 56282c5737 ci: implement new release flow (#7341)
Tests / test (./cmd/caddy/caddy, ~1.25.0, ubuntu-latest, 0, 1.25, linux) (push) Failing after 53s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.25.0, 1.25, aix) (push) Failing after 16s
Cross-Build / build (~1.25.0, 1.25, darwin) (push) Failing after 16s
Cross-Build / build (~1.25.0, 1.25, dragonfly) (push) Failing after 17s
Cross-Build / build (~1.25.0, 1.25, freebsd) (push) Failing after 16s
Cross-Build / build (~1.25.0, 1.25, illumos) (push) Failing after 17s
Cross-Build / build (~1.25.0, 1.25, linux) (push) Failing after 16s
Cross-Build / build (~1.25.0, 1.25, netbsd) (push) Failing after 16s
Cross-Build / build (~1.25.0, 1.25, openbsd) (push) Failing after 17s
Cross-Build / build (~1.25.0, 1.25, solaris) (push) Failing after 16s
Cross-Build / build (~1.25.0, 1.25, windows) (push) Failing after 16s
Lint / lint (ubuntu-latest, linux) (push) Failing after 16s
Lint / govulncheck (push) Successful in 1m54s
Lint / dependency-review (push) Failing after 16s
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 16s
Tests / test (./cmd/caddy/caddy, ~1.25.0, macos-14, 0, 1.25, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.25.0, windows-latest, True, 1.25, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
* ci: implement new release flow

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* remove redundant validation

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* extract key sha

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* pin github-scripts

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* switch to PR-based flow

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* don't use top-level permissions

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* restricted global perms + specific local perms

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* make PR draft

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

---------

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>
2025-11-14 14:55:30 -07:00
Kévin Dunglas b3f2db233b core: custom slog handlers for modules (log contextual data) (#7346)
Tests / test (./cmd/caddy/caddy, ~1.25.0, ubuntu-latest, 0, 1.25, linux) (push) Failing after 50s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.25.0, 1.25, aix) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, darwin) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, dragonfly) (push) Failing after 16s
Cross-Build / build (~1.25.0, 1.25, freebsd) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, illumos) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, linux) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, netbsd) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, openbsd) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, solaris) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, windows) (push) Failing after 15s
Lint / lint (ubuntu-latest, linux) (push) Failing after 15s
Lint / govulncheck (push) Successful in 1m47s
Lint / dependency-review (push) Failing after 16s
Tests / test (./cmd/caddy/caddy, ~1.25.0, macos-14, 0, 1.25, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.25.0, windows-latest, True, 1.25, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 18s
2025-11-12 13:29:47 -07:00
dependabot[bot] 07d2aaf22e build(deps): bump the all-updates group with 4 updates (#7333)
Tests / test (./cmd/caddy/caddy, ~1.25.0, ubuntu-latest, 0, 1.25, linux) (push) Failing after 19s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.25.0, 1.25, aix) (push) Failing after 16s
Cross-Build / build (~1.25.0, 1.25, darwin) (push) Failing after 16s
Cross-Build / build (~1.25.0, 1.25, dragonfly) (push) Failing after 16s
Cross-Build / build (~1.25.0, 1.25, freebsd) (push) Failing after 16s
Cross-Build / build (~1.25.0, 1.25, illumos) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, linux) (push) Failing after 16s
Cross-Build / build (~1.25.0, 1.25, netbsd) (push) Failing after 16s
Cross-Build / build (~1.25.0, 1.25, openbsd) (push) Failing after 26s
Cross-Build / build (~1.25.0, 1.25, solaris) (push) Failing after 24s
Cross-Build / build (~1.25.0, 1.25, windows) (push) Failing after 15s
Lint / lint (ubuntu-latest, linux) (push) Failing after 15s
Lint / govulncheck (push) Successful in 1m59s
Lint / dependency-review (push) Failing after 15s
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 15s
Tests / test (./cmd/caddy/caddy, ~1.25.0, macos-14, 0, 1.25, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.25.0, windows-latest, True, 1.25, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
Bumps the all-updates group with 4 updates: [github.com/DeRuina/timberjack](https://github.com/DeRuina/timberjack), [github.com/KimMachineGun/automemlimit](https://github.com/KimMachineGun/automemlimit), [github.com/klauspost/compress](https://github.com/klauspost/compress) and [go.step.sm/crypto](https://github.com/smallstep/crypto).


Updates `github.com/DeRuina/timberjack` from 1.3.8 to 1.3.9
- [Release notes](https://github.com/DeRuina/timberjack/releases)
- [Changelog](https://github.com/DeRuina/timberjack/blob/main/CHANGELOG.md)
- [Commits](https://github.com/DeRuina/timberjack/compare/v1.3.8...v1.3.9)

Updates `github.com/KimMachineGun/automemlimit` from 0.7.4 to 0.7.5
- [Release notes](https://github.com/KimMachineGun/automemlimit/releases)
- [Commits](https://github.com/KimMachineGun/automemlimit/compare/v0.7.4...v0.7.5)

Updates `github.com/klauspost/compress` from 1.18.0 to 1.18.1
- [Release notes](https://github.com/klauspost/compress/releases)
- [Changelog](https://github.com/klauspost/compress/blob/master/.goreleaser.yml)
- [Commits](https://github.com/klauspost/compress/compare/v1.18.0...v1.18.1)

Updates `go.step.sm/crypto` from 0.72.0 to 0.73.0
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.72.0...v0.73.0)

---
updated-dependencies:
- dependency-name: github.com/DeRuina/timberjack
  dependency-version: 1.3.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
- dependency-name: github.com/KimMachineGun/automemlimit
  dependency-version: 0.7.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
- dependency-name: github.com/klauspost/compress
  dependency-version: 1.18.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
- dependency-name: go.step.sm/crypto
  dependency-version: 0.73.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-08 11:13:16 +03:00
Marten Seemann f2199d48b2 chore: update quic-go to v0.56.0, enable qlog for HTTP/3 (#7345) 2025-11-08 00:41:15 -05:00
Kévin Dunglas 8285eba842 caddyhttp: allow customizing the Server header (#7338)
Tests / test (./cmd/caddy/caddy, ~1.25.0, ubuntu-latest, 0, 1.25, linux) (push) Failing after 16s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.25.0, 1.25, aix) (push) Failing after 24s
Cross-Build / build (~1.25.0, 1.25, darwin) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, dragonfly) (push) Failing after 17s
Cross-Build / build (~1.25.0, 1.25, freebsd) (push) Failing after 13s
Cross-Build / build (~1.25.0, 1.25, illumos) (push) Failing after 13s
Cross-Build / build (~1.25.0, 1.25, linux) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, netbsd) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, openbsd) (push) Failing after 13s
Cross-Build / build (~1.25.0, 1.25, solaris) (push) Failing after 13s
Cross-Build / build (~1.25.0, 1.25, windows) (push) Failing after 14s
Lint / lint (ubuntu-latest, linux) (push) Failing after 14s
Lint / govulncheck (push) Successful in 1m17s
Lint / dependency-review (push) Failing after 14s
Tests / test (./cmd/caddy/caddy, ~1.25.0, macos-14, 0, 1.25, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.25.0, windows-latest, True, 1.25, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 45s
2025-11-03 21:00:27 -07:00
Cooper de Nicola 895b56063a chore: fix golangci-lint error G602 in caddyhttp (#7334)
Tests / test (./cmd/caddy/caddy, ~1.25.0, ubuntu-latest, 0, 1.25, linux) (push) Failing after 16s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.25.0, 1.25, aix) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, darwin) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, dragonfly) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, freebsd) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, illumos) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, linux) (push) Failing after 13s
Cross-Build / build (~1.25.0, 1.25, netbsd) (push) Failing after 13s
Cross-Build / build (~1.25.0, 1.25, openbsd) (push) Failing after 13s
Cross-Build / build (~1.25.0, 1.25, solaris) (push) Failing after 13s
Cross-Build / build (~1.25.0, 1.25, windows) (push) Failing after 13s
Lint / lint (ubuntu-latest, linux) (push) Failing after 14s
Lint / govulncheck (push) Successful in 1m15s
Lint / dependency-review (push) Failing after 14s
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 14s
Tests / test (./cmd/caddy/caddy, ~1.25.0, macos-14, 0, 1.25, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.25.0, windows-latest, True, 1.25, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
2025-11-03 03:04:55 +00:00
Mohammed Al Sahaf ddec1838b3 caddytls: correct documentation of LeafFolderLoader (#7327)
Tests / test (./cmd/caddy/caddy, ~1.25.0, ubuntu-latest, 0, 1.25, linux) (push) Failing after 1m10s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.25.0, 1.25, aix) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, darwin) (push) Failing after 13s
Cross-Build / build (~1.25.0, 1.25, dragonfly) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, freebsd) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, illumos) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, linux) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, netbsd) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, openbsd) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, solaris) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, windows) (push) Failing after 14s
Lint / lint (ubuntu-latest, linux) (push) Failing after 13s
Lint / govulncheck (push) Successful in 1m35s
Lint / dependency-review (push) Failing after 13s
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 14s
Tests / test (./cmd/caddy/caddy, ~1.25.0, macos-14, 0, 1.25, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.25.0, windows-latest, True, 1.25, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
* caddytls: correct documentation of `LeafFolderLoader`

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* fmt...

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

---------

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>
2025-11-01 18:29:55 +03:00
Ted 92c8bc7322 caddyfile: fix nested quotes formatted incorrectly by fmt (#7045)
Tests / test (./cmd/caddy/caddy, ~1.25.0, ubuntu-latest, 0, 1.25, linux) (push) Failing after 49s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.25.0, 1.25, aix) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, darwin) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, dragonfly) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, freebsd) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, illumos) (push) Failing after 13s
Cross-Build / build (~1.25.0, 1.25, linux) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, netbsd) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, openbsd) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, solaris) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, windows) (push) Failing after 14s
Lint / lint (ubuntu-latest, linux) (push) Failing after 13s
Lint / govulncheck (push) Successful in 1m37s
Lint / dependency-review (push) Failing after 15s
Tests / test (./cmd/caddy/caddy, ~1.25.0, macos-14, 0, 1.25, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.25.0, windows-latest, True, 1.25, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 2m12s
* Fix incorrectly formatted quote within quotes with fmt

* Fix incorrectly formatted quote within quotes with fmt
2025-10-27 16:13:47 -06:00
WeidiDeng abe0acabb6 reverseproxy: set default values for keepalive if only some of them are set (#7318)
Tests / test (./cmd/caddy/caddy, ~1.25.0, ubuntu-latest, 0, 1.25, linux) (push) Failing after 15s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.25.0, 1.25, aix) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, darwin) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, dragonfly) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, freebsd) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, illumos) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, linux) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, netbsd) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, openbsd) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, solaris) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, windows) (push) Failing after 28s
Lint / lint (ubuntu-latest, linux) (push) Failing after 14s
Lint / govulncheck (push) Successful in 1m19s
Lint / dependency-review (push) Failing after 14s
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 13s
Tests / test (./cmd/caddy/caddy, ~1.25.0, macos-14, 0, 1.25, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.25.0, windows-latest, True, 1.25, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
2025-10-25 05:15:55 -04:00
Philipp Keidel b54e870b26 tracing: switch to autoexport for OpenTelemetry span exporter (#7317)
Tests / test (./cmd/caddy/caddy, ~1.25.0, ubuntu-latest, 0, 1.25, linux) (push) Failing after 14s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.25.0, 1.25, aix) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, darwin) (push) Failing after 16s
Cross-Build / build (~1.25.0, 1.25, dragonfly) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, freebsd) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, illumos) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, linux) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, netbsd) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, openbsd) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, solaris) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, windows) (push) Failing after 16s
Lint / lint (ubuntu-latest, linux) (push) Failing after 14s
Lint / govulncheck (push) Successful in 1m18s
Lint / dependency-review (push) Failing after 14s
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 14s
Tests / test (./cmd/caddy/caddy, ~1.25.0, macos-14, 0, 1.25, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.25.0, windows-latest, True, 1.25, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
2025-10-23 17:54:50 -06:00
dependabot[bot] 6d90c7707d build(deps): bump github.com/slackhq/nebula from 1.9.5 to 1.9.7 (#7315)
Tests / test (./cmd/caddy/caddy, ~1.25.0, ubuntu-latest, 0, 1.25, linux) (push) Failing after 16s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.25.0, 1.25, aix) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, darwin) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, dragonfly) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, freebsd) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, illumos) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, linux) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, netbsd) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, openbsd) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, solaris) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, windows) (push) Failing after 14s
Lint / lint (ubuntu-latest, linux) (push) Failing after 14s
Lint / govulncheck (push) Successful in 1m15s
Lint / dependency-review (push) Failing after 14s
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 15s
Tests / test (./cmd/caddy/caddy, ~1.25.0, macos-14, 0, 1.25, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.25.0, windows-latest, True, 1.25, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
Bumps [github.com/slackhq/nebula](https://github.com/slackhq/nebula) from 1.9.5 to 1.9.7.
- [Release notes](https://github.com/slackhq/nebula/releases)
- [Changelog](https://github.com/slackhq/nebula/blob/v1.9.7/CHANGELOG.md)
- [Commits](https://github.com/slackhq/nebula/compare/v1.9.5...v1.9.7)

---
updated-dependencies:
- dependency-name: github.com/slackhq/nebula
  dependency-version: 1.9.7
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-23 11:37:02 -06:00
dependabot[bot] cd1c203777 build(deps): bump the all-updates group across 1 directory with 2 updates (#7307)
Tests / test (./cmd/caddy/caddy, ~1.25.0, ubuntu-latest, 0, 1.25, linux) (push) Failing after 15s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.25.0, 1.25, aix) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, darwin) (push) Failing after 13s
Cross-Build / build (~1.25.0, 1.25, dragonfly) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, freebsd) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, illumos) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, linux) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, netbsd) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, openbsd) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, solaris) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, windows) (push) Failing after 14s
Lint / lint (ubuntu-latest, linux) (push) Failing after 14s
Lint / govulncheck (push) Successful in 1m12s
Lint / dependency-review (push) Failing after 15s
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 13s
Tests / test (./cmd/caddy/caddy, ~1.25.0, macos-14, 0, 1.25, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.25.0, windows-latest, True, 1.25, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
Bumps the all-updates group with 2 updates in the / directory: [github.com/spf13/pflag](https://github.com/spf13/pflag) and [go.step.sm/crypto](https://github.com/smallstep/crypto).


Updates `github.com/spf13/pflag` from 1.0.9 to 1.0.10
- [Release notes](https://github.com/spf13/pflag/releases)
- [Commits](https://github.com/spf13/pflag/compare/v1.0.9...v1.0.10)

Updates `go.step.sm/crypto` from 0.70.0 to 0.72.0
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.70.0...v0.72.0)

---
updated-dependencies:
- dependency-name: github.com/spf13/pflag
  dependency-version: 1.0.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
- dependency-name: go.step.sm/crypto
  dependency-version: 0.72.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-21 22:32:36 -06:00
wyrapeseed 57587ed18e refactor: use reflect.TypeFor (#7313)
Tests / test (./cmd/caddy/caddy, ~1.25.0, ubuntu-latest, 0, 1.25, linux) (push) Failing after 47s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.25.0, 1.25, aix) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, darwin) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, dragonfly) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, freebsd) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, illumos) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, linux) (push) Failing after 44s
Cross-Build / build (~1.25.0, 1.25, netbsd) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, openbsd) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, solaris) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, windows) (push) Failing after 14s
Lint / lint (ubuntu-latest, linux) (push) Failing after 14s
Lint / govulncheck (push) Successful in 1m31s
Lint / dependency-review (push) Failing after 14s
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 14s
Tests / test (./cmd/caddy/caddy, ~1.25.0, macos-14, 0, 1.25, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.25.0, windows-latest, True, 1.25, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
Signed-off-by: wyrapeseed <wyrapeseed@outlook.com>
2025-10-21 13:26:30 -06:00
WeidiDeng 1e21b660c4 reverseproxy: use http.Protocols to handle h2c requests (#6990)
Tests / test (./cmd/caddy/caddy, ~1.25.0, ubuntu-latest, 0, 1.25, linux) (push) Failing after 15s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.25.0, 1.25, aix) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, darwin) (push) Failing after 13s
Cross-Build / build (~1.25.0, 1.25, dragonfly) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, freebsd) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, illumos) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, linux) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, netbsd) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, openbsd) (push) Failing after 16s
Cross-Build / build (~1.25.0, 1.25, solaris) (push) Failing after 13s
Cross-Build / build (~1.25.0, 1.25, windows) (push) Failing after 16s
Lint / lint (ubuntu-latest, linux) (push) Failing after 14s
Lint / govulncheck (push) Successful in 1m10s
Lint / dependency-review (push) Failing after 15s
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 14s
Tests / test (./cmd/caddy/caddy, ~1.25.0, macos-14, 0, 1.25, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.25.0, windows-latest, True, 1.25, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
2025-10-21 16:05:43 +00:00
Mohammed Al Sahaf 595aab8bc0 metrics: resolve per-host inifinite cardinality (#7306)
Tests / test (./cmd/caddy/caddy, ~1.25.0, ubuntu-latest, 0, 1.25, linux) (push) Failing after 16s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.25.0, 1.25, aix) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, darwin) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, dragonfly) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, freebsd) (push) Failing after 13s
Cross-Build / build (~1.25.0, 1.25, illumos) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, linux) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, netbsd) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, openbsd) (push) Failing after 16s
Cross-Build / build (~1.25.0, 1.25, solaris) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, windows) (push) Failing after 15s
Lint / lint (ubuntu-latest, linux) (push) Failing after 14s
Lint / govulncheck (push) Successful in 1m16s
Lint / dependency-review (push) Failing after 14s
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 14s
Tests / test (./cmd/caddy/caddy, ~1.25.0, macos-14, 0, 1.25, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.25.0, windows-latest, True, 1.25, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
2025-10-21 06:06:56 +00:00
WeidiDeng 8aca108d2c reverseproxy: do not disable keepalive if proxy protocol is used (#7300) 2025-10-21 05:09:37 +00:00
Pavel 156ce99d3a listeners: Add support for named socket activation (#7243) 2025-10-21 04:55:42 +00:00
WeidiDeng a7885aabec intercept: use already buffered response if possible when intercepting (#7028) 2025-10-21 04:48:07 +00:00
Bashayer Alrumahi f5f25d845a logging: fix multiple regexp filters on same field (fixes #7049) (#7061)
Tests / test (./cmd/caddy/caddy, ~1.25.0, ubuntu-latest, 0, 1.25, linux) (push) Failing after 42s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.25.0, 1.25, aix) (push) Failing after 17s
Cross-Build / build (~1.25.0, 1.25, darwin) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, dragonfly) (push) Failing after 13s
Cross-Build / build (~1.25.0, 1.25, freebsd) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, illumos) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, linux) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, netbsd) (push) Failing after 13s
Cross-Build / build (~1.25.0, 1.25, openbsd) (push) Failing after 13s
Cross-Build / build (~1.25.0, 1.25, solaris) (push) Failing after 13s
Cross-Build / build (~1.25.0, 1.25, windows) (push) Failing after 13s
Lint / lint (ubuntu-latest, linux) (push) Failing after 13s
Lint / govulncheck (push) Successful in 1m33s
Lint / dependency-review (push) Failing after 13s
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 14s
Tests / test (./cmd/caddy/caddy, ~1.25.0, macos-14, 0, 1.25, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.25.0, windows-latest, True, 1.25, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
* logging: fix multiple regexp filters on same field (fixes #7049)

* fix: add proper error handling in MultiRegexpFilter tests

* fix: resolve linter and test issues - Fix GCI import formatting issues - Fix MultiRegexpFilter input size limit test by ensuring output doesn't exceed max length after each operation - All tests now pass and linter issues resolved

* fix: update integration test for proper JSON encoding - Fix expected JSON output to use Unicode escape sequence for ampersand character - Integration tests now pass
2025-10-16 05:08:53 +00:00
WeidiDeng 1ce2a13ad1 caddyhttp: wrap accepted connection to suppress tls.ConnectionState (#7247) 2025-10-16 03:13:40 +00:00
Chris Seufert d7185fd002 caddyhttp: Add trusted_proxies_unix for trusting unix socket X-Forwarded-* headers (#7265) 2025-10-16 02:47:32 +00:00
Anthony Biondo 7fb39ec1e5 reverseproxy: Use http1.1 upgrade for websocket for extended connect of http2 and http3 (#7305)
Co-authored-by: WeidiDeng <weidi_deng@icloud.com>
2025-10-16 02:20:20 +00:00
aeris 10ac7da037 logging: Switch from lumberjack to timberjack, add time-rolling options (#7244)
Co-authored-by: Francis Lavoie <lavofr@gmail.com>
2025-10-15 17:11:10 -04:00
wyrapeseed d115cd1042 chore: fix some comments (#7303) 2025-10-15 03:58:53 +00:00
joshuamcbeth de6b78009b caddyhttp: Add server options keepalive_idle and keepalive_count (#7298)
* Add Server options KeepAliveIdle (keepalive_idle) and KeepAliveCount (keepalive_count)

Signed-off-by: Joshua McBeth <joshua.mcbeth@gmail.com>

* Add Server option KeepAliveDisable (keepalive_disable)

Signed-off-by: Joshua McBeth <joshua.mcbeth@gmail.com>

* Remove Server option KeepAliveDisable (keepalive_disable), disable when interval is negative

Signed-off-by: Joshua McBeth <joshua.mcbeth@gmail.com>

* Add keepalive parameters to caddyfiletest

Signed-off-by: Joshua McBeth <joshua.mcbeth@gmail.com>

---------

Signed-off-by: Joshua McBeth <joshua.mcbeth@gmail.com>
2025-10-14 12:03:23 -06:00
WeidiDeng 2ec28bca43 reverse_proxy: use http1 for outbound tls requests with placeholder that are likely websockets (#7296) 2025-10-09 10:36:49 -06:00
Marten Seemann 178294e9d7 chore: Update quic-go to v0.55.0 (#7288)
Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
2025-10-06 19:43:28 -04:00
GreyXor 13a4ec7597 basicauth: Implement argon2id (#7186)
* feat: add argon2id hash-password command

* feat: ardon2id owasp safe value

* feat: add argon2id compare method

* chore: fmt argon2id

* docs: more argon2id docs

* chore: upgrade x/crypto dep

* revert: remove golangci

* refactor: argon2id decode

* chore: update deps

* refactor: simplify argon2id compare return

* chore: upgrade dependencies

* chore: upgrade dependencies
2025-10-06 17:27:06 -06:00
Monviech 2f1d270968 httpcaddyfile: Map default_bind to BindHost in globalACMEDefaults (#7278)
* Implement BindHost fallback in ACME issuer

* Fix indentation

* Skip creating empty challenges stub in adapted json config

* Skip setting BindHost for DNS Challenge

* golangci-lint fix

---------

Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
2025-10-06 16:48:38 -06:00
Aditya Bhargava 3c003deec6 httpcaddyfile: Add missing DNS challenge check for acme_dns (#7270)
* add optional argument to `mock` DNS provider

* preserve local DNS challenge settings when `acme_dns` is specified

* add missing check for `acme_dns`
2025-10-03 14:05:46 -06:00
dependabot[bot] afbdcec08b build(deps): bump the actions-deps group with 8 updates (#7284)
Bumps the actions-deps group with 8 updates:

| Package | From | To |
| --- | --- | --- |
| [step-security/harden-runner](https://github.com/step-security/harden-runner) | `2.13.0` | `2.13.1` |
| [actions/setup-go](https://github.com/actions/setup-go) | `5.5.0` | `6.0.0` |
| [actions/dependency-review-action](https://github.com/actions/dependency-review-action) | `4.7.3` | `4.8.0` |
| [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) | `3.9.2` | `3.10.0` |
| [anchore/sbom-action](https://github.com/anchore/sbom-action) | `0.20.5` | `0.20.6` |
| [peter-evans/repository-dispatch](https://github.com/peter-evans/repository-dispatch) | `3.0.0` | `4.0.0` |
| [ossf/scorecard-action](https://github.com/ossf/scorecard-action) | `2.4.2` | `2.4.3` |
| [github/codeql-action](https://github.com/github/codeql-action) | `3.30.0` | `3.30.5` |


Updates `step-security/harden-runner` from 2.13.0 to 2.13.1
- [Release notes](https://github.com/step-security/harden-runner/releases)
- [Commits](https://github.com/step-security/harden-runner/compare/ec9f2d5744a09debf3a187a3f4f675c53b671911...f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a)

Updates `actions/setup-go` from 5.5.0 to 6.0.0
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/d35c59abb061a4a6fb18e82ac0862c26744d6ab5...44694675825211faa026b3c33043df3e48a5fa00)

Updates `actions/dependency-review-action` from 4.7.3 to 4.8.0
- [Release notes](https://github.com/actions/dependency-review-action/releases)
- [Commits](https://github.com/actions/dependency-review-action/compare/595b5aeba73380359d98a5e087f648dbb0edce1b...56339e523c0409420f6c2c9a2f4292bbb3c07dd3)

Updates `sigstore/cosign-installer` from 3.9.2 to 3.10.0
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](https://github.com/sigstore/cosign-installer/compare/d58896d6a1865668819e1d91763c7751a165e159...d7543c93d881b35a8faa02e8e3605f69b7a1ce62)

Updates `anchore/sbom-action` from 0.20.5 to 0.20.6
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Changelog](https://github.com/anchore/sbom-action/blob/main/RELEASE.md)
- [Commits](https://github.com/anchore/sbom-action/compare/da167eac915b4e86f08b264dbdbc867b61be6f0c...f8bdd1d8ac5e901a77a92f111440fdb1b593736b)

Updates `peter-evans/repository-dispatch` from 3.0.0 to 4.0.0
- [Release notes](https://github.com/peter-evans/repository-dispatch/releases)
- [Commits](https://github.com/peter-evans/repository-dispatch/compare/ff45666b9427631e3450c54a1bcbee4d9ff4d7c0...5fc4efd1a4797ddb68ffd0714a238564e4cc0e6f)

Updates `ossf/scorecard-action` from 2.4.2 to 2.4.3
- [Release notes](https://github.com/ossf/scorecard-action/releases)
- [Changelog](https://github.com/ossf/scorecard-action/blob/main/RELEASE.md)
- [Commits](https://github.com/ossf/scorecard-action/compare/05b42c624433fc40578a4040d5cf5e36ddca8cde...4eaacf0543bb3f2c246792bd56e8cdeffafb205a)

Updates `github/codeql-action` from 3.30.0 to 3.30.5
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/2d92b76c45b91eb80fc44c74ce3fce0ee94e8f9d...3599b3baa15b485a2e49ef411a7a4bb2452e7f93)

---
updated-dependencies:
- dependency-name: step-security/harden-runner
  dependency-version: 2.13.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions-deps
- dependency-name: actions/setup-go
  dependency-version: 6.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions-deps
- dependency-name: actions/dependency-review-action
  dependency-version: 4.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions-deps
- dependency-name: sigstore/cosign-installer
  dependency-version: 3.10.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions-deps
- dependency-name: anchore/sbom-action
  dependency-version: 0.20.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions-deps
- dependency-name: peter-evans/repository-dispatch
  dependency-version: 4.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions-deps
- dependency-name: ossf/scorecard-action
  dependency-version: 2.4.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions-deps
- dependency-name: github/codeql-action
  dependency-version: 3.30.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-01 23:11:09 +00:00
Francis Lavoie 65e0ddc221 core: Reloading with SIGUSR1 if config never changed via admin (#7258)
Tests / test (./cmd/caddy/caddy, ~1.25.0, ubuntu-latest, 0, 1.25, linux) (push) Failing after 54s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.25.0, 1.25, aix) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, darwin) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, dragonfly) (push) Failing after 16s
Cross-Build / build (~1.25.0, 1.25, freebsd) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, illumos) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, linux) (push) Failing after 28s
Cross-Build / build (~1.25.0, 1.25, netbsd) (push) Failing after 18s
Cross-Build / build (~1.25.0, 1.25, openbsd) (push) Failing after 16s
Cross-Build / build (~1.25.0, 1.25, solaris) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, windows) (push) Failing after 13s
Lint / lint (ubuntu-latest, linux) (push) Failing after 14s
Lint / govulncheck (push) Successful in 1m38s
Lint / dependency-review (push) Failing after 15s
Tests / test (./cmd/caddy/caddy, ~1.25.0, macos-14, 0, 1.25, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.25.0, windows-latest, True, 1.25, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Has started running
2025-09-26 16:50:15 +00:00
WeidiDeng b2ab419922 core: use reflect.TypeFor to check for encoding/json.RawMessage (#7274)
* check if the raw message type is the json v2 type

* use reflect.TypeFor to check for encoding/json.RawMessage

---------

Co-authored-by: Mohammed Al Sahaf <msaa1990@gmail.com>
2025-09-26 10:46:18 -06:00
asttool bc0e184130 caddyhttp: omit unnecessary reassignment (#7276)
Signed-off-by: asttool <asttool@outlook.com>
2025-09-26 10:44:58 -06:00
Y.Horie 1e82f9652e caddypki: check intermediate lifetime to actual root cert lifetime (#7272)
Tests / test (./cmd/caddy/caddy, ~1.25.0, ubuntu-latest, 0, 1.25, linux) (push) Failing after 15s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.25.0, 1.25, aix) (push) Failing after 22s
Cross-Build / build (~1.25.0, 1.25, darwin) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, dragonfly) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, freebsd) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, illumos) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, linux) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, netbsd) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, openbsd) (push) Failing after 17s
Cross-Build / build (~1.25.0, 1.25, solaris) (push) Failing after 23s
Cross-Build / build (~1.25.0, 1.25, windows) (push) Failing after 14s
Lint / lint (ubuntu-latest, linux) (push) Failing after 14s
Lint / govulncheck (push) Successful in 1m14s
Lint / dependency-review (push) Failing after 14s
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 14s
Tests / test (./cmd/caddy/caddy, ~1.25.0, macos-14, 0, 1.25, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.25.0, windows-latest, True, 1.25, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
2025-09-26 10:24:52 -06:00
Mohammed Al Sahaf 25be2f26fc chore: ugh, lint fix... (#7275)
Tests / test (./cmd/caddy/caddy, ~1.25.0, ubuntu-latest, 0, 1.25, linux) (push) Failing after 14s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.25.0, 1.25, aix) (push) Failing after 22s
Cross-Build / build (~1.25.0, 1.25, darwin) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, dragonfly) (push) Failing after 13s
Cross-Build / build (~1.25.0, 1.25, freebsd) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, illumos) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, linux) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, netbsd) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, openbsd) (push) Failing after 15s
Cross-Build / build (~1.25.0, 1.25, solaris) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, windows) (push) Failing after 14s
Lint / lint (ubuntu-latest, linux) (push) Failing after 14s
Lint / govulncheck (push) Successful in 1m32s
Lint / dependency-review (push) Failing after 16s
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 14s
Tests / test (./cmd/caddy/caddy, ~1.25.0, macos-14, 0, 1.25, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.25.0, windows-latest, True, 1.25, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
* chore: ugh, lint fix...

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* more lint fixes

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

---------

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>
2025-09-26 03:14:48 -04:00
Marten Seemann 0c8798fce3 go.mod: update quic-go to v0.54.1 (#7273) 2025-09-25 19:24:26 -06:00
Gilbert Gilb's f5c3094050 cmd: prevent commas in header values from being split (#7268)
Tests / test (./cmd/caddy/caddy, ~1.25.0, ubuntu-latest, 0, 1.25, linux) (push) Failing after 1s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.25.0, 1.25, aix) (push) Failing after 0s
Cross-Build / build (~1.25.0, 1.25, darwin) (push) Failing after 0s
Cross-Build / build (~1.25.0, 1.25, dragonfly) (push) Failing after 0s
Cross-Build / build (~1.25.0, 1.25, freebsd) (push) Failing after 0s
Cross-Build / build (~1.25.0, 1.25, illumos) (push) Failing after 0s
Cross-Build / build (~1.25.0, 1.25, linux) (push) Failing after 0s
Cross-Build / build (~1.25.0, 1.25, netbsd) (push) Failing after 0s
Cross-Build / build (~1.25.0, 1.25, openbsd) (push) Failing after 0s
Cross-Build / build (~1.25.0, 1.25, solaris) (push) Failing after 0s
Cross-Build / build (~1.25.0, 1.25, windows) (push) Failing after 1s
Lint / lint (ubuntu-latest, linux) (push) Failing after 0s
Lint / govulncheck (push) Failing after 0s
Lint / dependency-review (push) Failing after 0s
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 47s
Tests / test (./cmd/caddy/caddy, ~1.25.0, macos-14, 0, 1.25, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.25.0, windows-latest, True, 1.25, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
`pflag.GetStringSlice` treats commas as delimiters, which causes issues
when passing headers whose values contain commas (`X-Robots-Tag:
noindex, nofollow`). These are incorrectly split into multiple headers
and errors out:

- `X-Robots-Tag: noindex`
- ` nofollow`

Switch to `pflag.GetStringArray`, which does not split on commas[1].

Note that this changes behavior for cases where multiple headers were
provided in a single argument with commas (`--header-down "X-Foo:
Bar,X-Bar: Foo"`). Such cases will now be treated as a single header
value. If this breaking change is unacceptable, we will need a smarter
fallback mechanism.

[1] https://github.com/spf13/pflag/pull/90
2025-09-22 21:12:06 -06:00
Francis Lavoie 39ace450de logging: Adjustments to BufferedLog to keep logs in the correct order (#7257)
* logging: Adjustments to BufferedLog to keep logs in the correct order

* Ignore lints
2025-09-15 09:29:50 -06:00
Artur H. 0ba8786b35 caddyfile: Allow block to do nothing if nothing passed to import (#7206)
Tests / test (./cmd/caddy/caddy, ~1.25.0, ubuntu-latest, 0, 1.25, linux) (push) Failing after 49s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.25.0, 1.25, aix) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, darwin) (push) Failing after 28s
Cross-Build / build (~1.25.0, 1.25, dragonfly) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, freebsd) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, illumos) (push) Failing after 16s
Cross-Build / build (~1.25.0, 1.25, linux) (push) Failing after 19s
Cross-Build / build (~1.25.0, 1.25, netbsd) (push) Failing after 54s
Cross-Build / build (~1.25.0, 1.25, openbsd) (push) Failing after 13s
Cross-Build / build (~1.25.0, 1.25, solaris) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, windows) (push) Failing after 14s
Lint / lint (ubuntu-latest, linux) (push) Failing after 15s
Lint / govulncheck (push) Successful in 1m42s
Lint / dependency-review (push) Failing after 14s
Tests / test (./cmd/caddy/caddy, ~1.25.0, macos-14, 0, 1.25, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.25.0, windows-latest, True, 1.25, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Has started running
2025-09-12 20:29:09 +00:00
mickychang9 bcd4055e89 Use WaitGroup.Go to simplify code (#7253)
Tests / test (./cmd/caddy/caddy, ~1.25.0, ubuntu-latest, 0, 1.25, linux) (push) Failing after 57s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.25.0, 1.25, aix) (push) Failing after 13s
Cross-Build / build (~1.25.0, 1.25, darwin) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, dragonfly) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, freebsd) (push) Failing after 13s
Cross-Build / build (~1.25.0, 1.25, illumos) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, linux) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, netbsd) (push) Failing after 13s
Cross-Build / build (~1.25.0, 1.25, openbsd) (push) Failing after 13s
Cross-Build / build (~1.25.0, 1.25, solaris) (push) Failing after 13s
Cross-Build / build (~1.25.0, 1.25, windows) (push) Failing after 13s
Lint / lint (ubuntu-latest, linux) (push) Failing after 13s
Lint / govulncheck (push) Successful in 1m31s
Lint / dependency-review (push) Failing after 14s
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 14s
Tests / test (./cmd/caddy/caddy, ~1.25.0, macos-14, 0, 1.25, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.25.0, windows-latest, True, 1.25, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
Signed-off-by: mickychang9 <mickychang9@outlook.com>
2025-09-11 10:15:09 -06:00
WeidiDeng b462615439 fileserver: set Content-Length for precompressed files (#7251)
* set Content-Length for precompressed files

* Update modules/caddyhttp/fileserver/staticfiles.go

Co-authored-by: Matt Holt <mholt@users.noreply.github.com>

---------

Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
2025-09-10 22:48:03 -06:00
Francis Lavoie 012b4b3d40 logging: Buffer the logs before config is loaded (#7245) 2025-09-10 16:03:52 +00:00
Pavel d9cc24f3df caddypki: Disable internal auto-CA when auto_https is disabled (fix #7211) (#7238)
Tests / test (./cmd/caddy/caddy, ~1.25.0, ubuntu-latest, 0, 1.25, linux) (push) Failing after 50s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.25.0, 1.25, aix) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, darwin) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, dragonfly) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, freebsd) (push) Failing after 13s
Cross-Build / build (~1.25.0, 1.25, illumos) (push) Failing after 13s
Cross-Build / build (~1.25.0, 1.25, linux) (push) Failing after 13s
Cross-Build / build (~1.25.0, 1.25, netbsd) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, openbsd) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, solaris) (push) Failing after 14s
Cross-Build / build (~1.25.0, 1.25, windows) (push) Failing after 14s
Lint / lint (ubuntu-latest, linux) (push) Failing after 14s
Lint / govulncheck (push) Successful in 1m53s
Lint / dependency-review (push) Failing after 14s
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 15s
Tests / test (./cmd/caddy/caddy, ~1.25.0, macos-14, 0, 1.25, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.25.0, windows-latest, True, 1.25, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
2025-09-05 09:41:06 -06:00
Matthew Holt 38848f7f25 caddytls: Allow disabling distributed solving (except http-01) 2025-09-04 08:51:36 -06:00
Siomachkin 5473eb95d8 encode: fix response corruption when handle_errors is used (#7235)
* encode: fix response corruption when handle_errors is used

* Move disabled check before hdr assignment
2025-09-02 15:34:56 -06:00
dependabot[bot] 2d0f3f887b build(deps): bump the actions-deps group with 5 updates (#7237)
Bumps the actions-deps group with 5 updates:

| Package | From | To |
| --- | --- | --- |
| [actions/checkout](https://github.com/actions/checkout) | `4.2.2` | `5.0.0` |
| [goreleaser/goreleaser-action](https://github.com/goreleaser/goreleaser-action) | `6.3.0` | `6.4.0` |
| [actions/dependency-review-action](https://github.com/actions/dependency-review-action) | `4.7.1` | `4.7.3` |
| [anchore/sbom-action](https://github.com/anchore/sbom-action) | `0.20.4` | `0.20.5` |
| [github/codeql-action](https://github.com/github/codeql-action) | `3.29.7` | `3.30.0` |


Updates `actions/checkout` from 4.2.2 to 5.0.0
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4.2.2...08c6903cd8c0fde910a37f88322edcfb5dd907a8)

Updates `goreleaser/goreleaser-action` from 6.3.0 to 6.4.0
- [Release notes](https://github.com/goreleaser/goreleaser-action/releases)
- [Commits](https://github.com/goreleaser/goreleaser-action/compare/9c156ee8a17a598857849441385a2041ef570552...e435ccd777264be153ace6237001ef4d979d3a7a)

Updates `actions/dependency-review-action` from 4.7.1 to 4.7.3
- [Release notes](https://github.com/actions/dependency-review-action/releases)
- [Commits](https://github.com/actions/dependency-review-action/compare/da24556b548a50705dd671f47852072ea4c105d9...595b5aeba73380359d98a5e087f648dbb0edce1b)

Updates `anchore/sbom-action` from 0.20.4 to 0.20.5
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Changelog](https://github.com/anchore/sbom-action/blob/main/RELEASE.md)
- [Commits](https://github.com/anchore/sbom-action/compare/7b36ad622f042cab6f59a75c2ac24ccb256e9b45...da167eac915b4e86f08b264dbdbc867b61be6f0c)

Updates `github/codeql-action` from 3.29.7 to 3.30.0
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/51f77329afa6477de8c49fc9c7046c15b9a4e79d...2d92b76c45b91eb80fc44c74ce3fce0ee94e8f9d)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 5.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions-deps
- dependency-name: goreleaser/goreleaser-action
  dependency-version: 6.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions-deps
- dependency-name: actions/dependency-review-action
  dependency-version: 4.7.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions-deps
- dependency-name: anchore/sbom-action
  dependency-version: 0.20.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions-deps
- dependency-name: github/codeql-action
  dependency-version: 3.30.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-02 13:05:58 -06:00
dependabot[bot] 39357d3e5c build(deps): bump the all-updates group with 17 updates (#7236)
Bumps the all-updates group with 17 updates:

| Package | From | To |
| --- | --- | --- |
| [github.com/go-chi/chi/v5](https://github.com/go-chi/chi) | `5.2.2` | `5.2.3` |
| [github.com/google/cel-go](https://github.com/google/cel-go) | `0.26.0` | `0.26.1` |
| [github.com/spf13/cobra](https://github.com/spf13/cobra) | `1.9.1` | `1.10.1` |
| [github.com/spf13/pflag](https://github.com/spf13/pflag) | `1.0.7` | `1.0.9` |
| [github.com/stretchr/testify](https://github.com/stretchr/testify) | `1.10.0` | `1.11.1` |
| [go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp](https://github.com/open-telemetry/opentelemetry-go-contrib) | `0.61.0` | `0.63.0` |
| [go.opentelemetry.io/contrib/propagators/autoprop](https://github.com/open-telemetry/opentelemetry-go-contrib) | `0.62.0` | `0.63.0` |
| [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go) | `1.37.0` | `1.38.0` |
| [go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc](https://github.com/open-telemetry/opentelemetry-go) | `1.37.0` | `1.38.0` |
| [go.opentelemetry.io/otel/sdk](https://github.com/open-telemetry/opentelemetry-go) | `1.37.0` | `1.38.0` |
| [golang.org/x/crypto](https://github.com/golang/crypto) | `0.40.0` | `0.41.0` |
| [golang.org/x/net](https://github.com/golang/net) | `0.42.0` | `0.43.0` |
| [golang.org/x/term](https://github.com/golang/term) | `0.33.0` | `0.34.0` |
| [github.com/libdns/libdns](https://github.com/libdns/libdns) | `1.1.0` | `1.1.1` |
| [go.opentelemetry.io/otel/trace](https://github.com/open-telemetry/opentelemetry-go) | `1.37.0` | `1.38.0` |
| [go.step.sm/crypto](https://github.com/smallstep/crypto) | `0.67.0` | `0.70.0` |
| [golang.org/x/sys](https://github.com/golang/sys) | `0.34.0` | `0.35.0` |


Updates `github.com/go-chi/chi/v5` from 5.2.2 to 5.2.3
- [Release notes](https://github.com/go-chi/chi/releases)
- [Changelog](https://github.com/go-chi/chi/blob/master/CHANGELOG.md)
- [Commits](https://github.com/go-chi/chi/compare/v5.2.2...v5.2.3)

Updates `github.com/google/cel-go` from 0.26.0 to 0.26.1
- [Release notes](https://github.com/google/cel-go/releases)
- [Commits](https://github.com/google/cel-go/compare/v0.26.0...v0.26.1)

Updates `github.com/spf13/cobra` from 1.9.1 to 1.10.1
- [Release notes](https://github.com/spf13/cobra/releases)
- [Commits](https://github.com/spf13/cobra/compare/v1.9.1...v1.10.1)

Updates `github.com/spf13/pflag` from 1.0.7 to 1.0.9
- [Release notes](https://github.com/spf13/pflag/releases)
- [Commits](https://github.com/spf13/pflag/compare/v1.0.7...v1.0.9)

Updates `github.com/stretchr/testify` from 1.10.0 to 1.11.1
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.10.0...v1.11.1)

Updates `go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp` from 0.61.0 to 0.63.0
- [Release notes](https://github.com/open-telemetry/opentelemetry-go-contrib/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go-contrib/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go-contrib/compare/zpages/v0.61.0...zpages/v0.63.0)

Updates `go.opentelemetry.io/contrib/propagators/autoprop` from 0.62.0 to 0.63.0
- [Release notes](https://github.com/open-telemetry/opentelemetry-go-contrib/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go-contrib/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go-contrib/compare/zpages/v0.62.0...zpages/v0.63.0)

Updates `go.opentelemetry.io/otel` from 1.37.0 to 1.38.0
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.37.0...v1.38.0)

Updates `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc` from 1.37.0 to 1.38.0
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.37.0...v1.38.0)

Updates `go.opentelemetry.io/otel/sdk` from 1.37.0 to 1.38.0
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.37.0...v1.38.0)

Updates `golang.org/x/crypto` from 0.40.0 to 0.41.0
- [Commits](https://github.com/golang/crypto/compare/v0.40.0...v0.41.0)

Updates `golang.org/x/net` from 0.42.0 to 0.43.0
- [Commits](https://github.com/golang/net/compare/v0.42.0...v0.43.0)

Updates `golang.org/x/term` from 0.33.0 to 0.34.0
- [Commits](https://github.com/golang/term/compare/v0.33.0...v0.34.0)

Updates `github.com/libdns/libdns` from 1.1.0 to 1.1.1
- [Release notes](https://github.com/libdns/libdns/releases)
- [Commits](https://github.com/libdns/libdns/compare/v1.1.0...v1.1.1)

Updates `go.opentelemetry.io/otel/trace` from 1.37.0 to 1.38.0
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.37.0...v1.38.0)

Updates `go.step.sm/crypto` from 0.67.0 to 0.70.0
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.67.0...v0.70.0)

Updates `golang.org/x/sys` from 0.34.0 to 0.35.0
- [Commits](https://github.com/golang/sys/compare/v0.34.0...v0.35.0)

---
updated-dependencies:
- dependency-name: github.com/go-chi/chi/v5
  dependency-version: 5.2.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
- dependency-name: github.com/google/cel-go
  dependency-version: 0.26.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
- dependency-name: github.com/spf13/cobra
  dependency-version: 1.10.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: github.com/spf13/pflag
  dependency-version: 1.0.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
- dependency-name: github.com/stretchr/testify
  dependency-version: 1.11.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp
  dependency-version: 0.63.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: go.opentelemetry.io/contrib/propagators/autoprop
  dependency-version: 0.63.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: go.opentelemetry.io/otel
  dependency-version: 1.38.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc
  dependency-version: 1.38.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: go.opentelemetry.io/otel/sdk
  dependency-version: 1.38.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: golang.org/x/crypto
  dependency-version: 0.41.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: golang.org/x/net
  dependency-version: 0.43.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: golang.org/x/term
  dependency-version: 0.34.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: github.com/libdns/libdns
  dependency-version: 1.1.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
- dependency-name: go.opentelemetry.io/otel/trace
  dependency-version: 1.38.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: go.step.sm/crypto
  dependency-version: 0.70.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: golang.org/x/sys
  dependency-version: 0.35.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-02 11:35:09 -06:00
Max Celant 3553cfb6ad caddyhttp: remove redundant middleware next copy (#7217) 2025-09-01 09:30:34 -06:00
aro-lew 806fef85be encode: add graphql-response header to list (#7214)
Tests / test (./cmd/caddy/caddy, ~1.25.0, ubuntu-latest, 0, 1.25, linux) (push) Failing after 2m15s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.25.0, 1.25, aix) (push) Successful in 1m18s
Cross-Build / build (~1.25.0, 1.25, darwin) (push) Successful in 1m16s
Cross-Build / build (~1.25.0, 1.25, dragonfly) (push) Successful in 1m22s
Cross-Build / build (~1.25.0, 1.25, freebsd) (push) Successful in 1m16s
Cross-Build / build (~1.25.0, 1.25, illumos) (push) Successful in 1m16s
Cross-Build / build (~1.25.0, 1.25, linux) (push) Successful in 1m14s
Cross-Build / build (~1.25.0, 1.25, netbsd) (push) Successful in 1m17s
Cross-Build / build (~1.25.0, 1.25, openbsd) (push) Successful in 1m15s
Cross-Build / build (~1.25.0, 1.25, solaris) (push) Successful in 1m18s
Cross-Build / build (~1.25.0, 1.25, windows) (push) Successful in 1m16s
Lint / lint (ubuntu-latest, linux) (push) Successful in 2m38s
Lint / govulncheck (push) Successful in 1m44s
Lint / dependency-review (push) Failing after 56s
Tests / test (./cmd/caddy/caddy, ~1.25.0, macos-14, 0, 1.25, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.25.0, windows-latest, True, 1.25, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Has started running
2025-08-27 14:58:14 -06:00
Arpan Saha 6d73d85c1f caddyfile: prevent adding trailing space on line before env variable (#7215) 2025-08-26 15:13:54 -06:00
Matthew Holt e0a8f9541d caddyhttp: Normalize (lowercase) {label.N} placeholders 2025-08-25 13:18:13 -06:00
Matthew Holt b866a9e099 It can't be in the subfolder!? 2025-08-25 13:13:27 -06:00
Matthew Holt 1db26128a6 Uhh I guess it has to be named something specific 2025-08-25 13:11:30 -06:00
Matthew Holt 02c9f0ff90 Tweak issue form 2025-08-25 13:07:17 -06:00
Matthew Holt 63ec1f4e1c Issue template chooser config 2025-08-25 13:05:02 -06:00
Matthew Holt 293de94f34 Fix issue form ... again 2025-08-25 13:02:54 -06:00
Matthew Holt d8d359eca2 Fix syntax of issue form 2025-08-25 12:59:41 -06:00
Matt Holt 11a95cee6d AI assistance disclosure (#7212)
* AI disclosure templates

* Update assistance disclosure

* Add AI moderator

* Set read permissions by default

* Pin to hash
2025-08-25 12:50:26 -06:00
Matthew Holt b7c022a61a Set read permissions as default 2025-08-25 10:18:40 -06:00
Bang Lee 5e2953670e caddyhttp: add replacer placeholders for escaped values (#7181) 2025-08-25 09:07:51 -06:00
Artur H. 551f793700 caddyfile: Fix importing nested tokens for {block} (#7189) 2025-08-22 21:29:34 +00:00
Francis Lavoie 4564261d83 httpcaddyfile: Fix acme_dns regression (#7199) 2025-08-22 15:09:25 -06:00
Francis Lavoie 16fe83c7af http: Make logger first, before TLS provisioning (#7198) 2025-08-22 14:24:08 -06:00
Matthew Holt 3723e89585 go.mod: Upgrade CertMagic to v0.24.0 2025-08-22 09:41:47 -06:00
WeidiDeng 14a63a26b9 caddyhttp: use the new http.Protocols to handle h1, h2 and h2c requests (#6961)
* use the new http.Protocols to handle h1, h2 and h2c requests

* fix lint

* keep ConnCtxKey for now

* fix handling for h2c

* check http version while reading the connection

* check if connection implements connectionStater when it should

* add comments about either h1 or h2 must be used in the listener

* fix if check

* return a net.Conn that implements connectionStater if applicable

* remove http/1.1 from alpn if h1 is disabled

* fix matching if only h1 is enabled

---------

Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
2025-08-22 14:30:42 +00:00
WeidiDeng 67debd0e11 fileserver: set Range header for precompressed static files to force Content Length header to appear (#7042)
Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
2025-08-22 08:23:13 -06:00
Luka T. Korošec b9710c6af4 fileserver: Add a few doc lines about Etag file content (#7173)
Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
2025-08-21 16:02:10 -06:00
Kévin Dunglas 493898d9bd ci: set proper build tags in golangci and minor cleanup (#7183)
* ci: set proper build tags in golangci and minor cleanup

* clean

* review

---------

Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
2025-08-21 20:43:38 +00:00
WeidiDeng 1c596e3c5a reverse_proxy: use the new KeepAliveConfig to set probe interval (#7157)
Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
2025-08-21 14:36:54 -06:00
WeidiDeng f11c780fdc http: clean up listeners if some of the listeners fail to bind (#7176)
* http: clean up listeners if some of the listeners fail to bind

* check for nil server due to failure to start

---------

Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
2025-08-21 12:14:40 -06:00
WeidiDeng fdf610850b http: disable keepalive when KeepAliveInterval is negative (#7158)
Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
2025-08-20 17:31:15 -04:00
joemicky 5125fbed41 use a more modern writing style to simplify code (#7182)
Signed-off-by: joemicky <joemickychang@outlook.com>
Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
2025-08-20 11:41:21 -06:00
cui b15ed9b084 caddyhttp: refactor to use reflect.TypeFor (#7187) 2025-08-18 17:08:46 -06:00
Kévin Dunglas 05acc5131e chore: bump Go to v1.25 (#7184) 2025-08-14 08:38:42 -06:00
WeidiDeng 7590c9ca1b caddyhttp: Free up quic listener when stopping (#7177) 2025-08-13 12:35:06 -06:00
avery b898873b90 caddytls: fix regression in external certificate manager support (#7179)
revert changes to automation.go from e276994174
2025-08-13 09:30:26 -06:00
youzichuan 09b53a753c chore: fix inconsistent function name in comment (#7174)
Signed-off-by: youzichuan <youzichuan6@outlook.com>
2025-08-13 07:05:54 +00:00
GreyXor 4bfc3b95b5 bcrypt: wrong cost flag name (#7168)
Tests / test (./cmd/caddy/caddy, ~1.24.1, ubuntu-latest, 0, 1.24, linux) (push) Failing after 2m14s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.24.1, 1.24, aix) (push) Successful in 1m22s
Cross-Build / build (~1.24.1, 1.24, darwin) (push) Successful in 1m36s
Cross-Build / build (~1.24.1, 1.24, dragonfly) (push) Successful in 1m27s
Cross-Build / build (~1.24.1, 1.24, freebsd) (push) Successful in 1m29s
Cross-Build / build (~1.24.1, 1.24, illumos) (push) Successful in 1m29s
Cross-Build / build (~1.24.1, 1.24, linux) (push) Successful in 1m31s
Cross-Build / build (~1.24.1, 1.24, netbsd) (push) Successful in 1m33s
Cross-Build / build (~1.24.1, 1.24, openbsd) (push) Successful in 1m36s
Cross-Build / build (~1.24.1, 1.24, solaris) (push) Successful in 1m26s
Cross-Build / build (~1.24.1, 1.24, windows) (push) Successful in 1m27s
Lint / lint (ubuntu-latest, linux) (push) Successful in 2m24s
Lint / govulncheck (push) Successful in 1m41s
Lint / dependency-review (push) Failing after 54s
Tests / test (./cmd/caddy/caddy, ~1.24.1, macos-14, 0, 1.24, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.24.1, windows-latest, True, 1.24, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Has started running
2025-08-11 15:46:32 +03:00
GreyXor 49dac61b07 bcrypt: add cost parameter to hash-password (#7149)
* feat: add bcrypt cost parameter to hash-password

* revert: typos

* refactor: take the cost out of interface

* fix: default bcrypt cost to 14

* fix: follow bcrypt library for min and max cost

* doc: mention defaultBcryptCost in cost parameter description

* chore: gci format

* fix: more specific bcrypt cost algorithm flag

* feat: bcrypt cost provisioning

* Revert "feat: bcrypt cost provisioning"

This reverts commit e09d4bd036.

* chore: gci format

* chore: gci format

* chore: gci format

* chore: golangcilint fmted

---------

Co-authored-by: Mohammed Al Sahaf <msaa1990@gmail.com>
2025-08-11 14:26:18 +03:00
Bobby Dhillon 19ff47a63b cmd: Allow caddy adapt to read from stdin (#7163)
Tests / test (./cmd/caddy/caddy, ~1.24.1, ubuntu-latest, 0, 1.24, linux) (push) Failing after 2m55s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.24.1, 1.24, aix) (push) Successful in 1m31s
Cross-Build / build (~1.24.1, 1.24, darwin) (push) Successful in 1m31s
Cross-Build / build (~1.24.1, 1.24, dragonfly) (push) Successful in 1m33s
Cross-Build / build (~1.24.1, 1.24, freebsd) (push) Successful in 1m34s
Cross-Build / build (~1.24.1, 1.24, illumos) (push) Successful in 1m34s
Cross-Build / build (~1.24.1, 1.24, linux) (push) Successful in 1m39s
Cross-Build / build (~1.24.1, 1.24, netbsd) (push) Successful in 1m36s
Cross-Build / build (~1.24.1, 1.24, openbsd) (push) Successful in 1m34s
Cross-Build / build (~1.24.1, 1.24, solaris) (push) Successful in 1m35s
Cross-Build / build (~1.24.1, 1.24, windows) (push) Successful in 1m33s
Lint / lint (ubuntu-latest, linux) (push) Successful in 2m29s
Lint / govulncheck (push) Successful in 1m48s
Lint / dependency-review (push) Failing after 59s
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Has started running
Tests / test (./cmd/caddy/caddy, ~1.24.1, macos-14, 0, 1.24, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.24.1, windows-latest, True, 1.24, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
2025-08-06 20:04:28 -04:00
dependabot[bot] 007f4066f6 build(deps): bump the all-updates group across 1 directory with 17 updates (#7155)
Tests / test (./cmd/caddy/caddy, ~1.24.1, ubuntu-latest, 0, 1.24, linux) (push) Failing after 2m16s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.24.1, 1.24, aix) (push) Successful in 1m46s
Cross-Build / build (~1.24.1, 1.24, darwin) (push) Successful in 1m21s
Cross-Build / build (~1.24.1, 1.24, dragonfly) (push) Successful in 1m21s
Cross-Build / build (~1.24.1, 1.24, freebsd) (push) Successful in 1m20s
Cross-Build / build (~1.24.1, 1.24, illumos) (push) Successful in 1m21s
Cross-Build / build (~1.24.1, 1.24, linux) (push) Successful in 1m21s
Cross-Build / build (~1.24.1, 1.24, netbsd) (push) Successful in 1m21s
Cross-Build / build (~1.24.1, 1.24, openbsd) (push) Successful in 1m23s
Cross-Build / build (~1.24.1, 1.24, solaris) (push) Successful in 1m24s
Cross-Build / build (~1.24.1, 1.24, windows) (push) Successful in 1m24s
Lint / lint (ubuntu-latest, linux) (push) Successful in 2m21s
Lint / govulncheck (push) Successful in 1m41s
Lint / dependency-review (push) Failing after 55s
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 1m39s
Tests / test (./cmd/caddy/caddy, ~1.24.1, macos-14, 0, 1.24, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.24.1, windows-latest, True, 1.24, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
Bumps the all-updates group with 10 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [github.com/KimMachineGun/automemlimit](https://github.com/KimMachineGun/automemlimit) | `0.7.1` | `0.7.4` |
| [github.com/alecthomas/chroma/v2](https://github.com/alecthomas/chroma) | `2.19.0` | `2.20.0` |
| [github.com/google/cel-go](https://github.com/google/cel-go) | `0.24.1` | `0.26.0` |
| [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) | `1.19.1` | `1.23.0` |
| [github.com/smallstep/certificates](https://github.com/smallstep/certificates) | `0.26.1` | `0.28.4` |
| [github.com/yuin/goldmark](https://github.com/yuin/goldmark) | `1.7.8` | `1.7.13` |
| [go.opentelemetry.io/contrib/propagators/autoprop](https://github.com/open-telemetry/opentelemetry-go-contrib) | `0.42.0` | `0.62.0` |
| [go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc](https://github.com/open-telemetry/opentelemetry-go) | `1.31.0` | `1.37.0` |
| [github.com/libdns/libdns](https://github.com/libdns/libdns) | `1.0.0-beta.1` | `1.1.0` |
| [github.com/pires/go-proxyproto](https://github.com/pires/go-proxyproto) | `0.7.1-0.20240628150027-b718e7ce4964` | `0.8.1` |



Updates `github.com/KimMachineGun/automemlimit` from 0.7.1 to 0.7.4
- [Release notes](https://github.com/KimMachineGun/automemlimit/releases)
- [Commits](https://github.com/KimMachineGun/automemlimit/compare/v0.7.1...v0.7.4)

Updates `github.com/alecthomas/chroma/v2` from 2.19.0 to 2.20.0
- [Release notes](https://github.com/alecthomas/chroma/releases)
- [Changelog](https://github.com/alecthomas/chroma/blob/master/.goreleaser.yml)
- [Commits](https://github.com/alecthomas/chroma/compare/v2.19.0...v2.20.0)

Updates `github.com/google/cel-go` from 0.24.1 to 0.26.0
- [Release notes](https://github.com/google/cel-go/releases)
- [Commits](https://github.com/google/cel-go/compare/v0.24.1...v0.26.0)

Updates `github.com/prometheus/client_golang` from 1.19.1 to 1.23.0
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.19.1...v1.23.0)

Updates `github.com/smallstep/certificates` from 0.26.1 to 0.28.4
- [Release notes](https://github.com/smallstep/certificates/releases)
- [Changelog](https://github.com/smallstep/certificates/blob/master/CHANGELOG.md)
- [Commits](https://github.com/smallstep/certificates/compare/v0.26.1...v0.28.4)

Updates `github.com/smallstep/nosql` from 0.6.1 to 0.7.0
- [Commits](https://github.com/smallstep/nosql/compare/v0.6.1...v0.7.0)

Updates `github.com/yuin/goldmark` from 1.7.8 to 1.7.13
- [Release notes](https://github.com/yuin/goldmark/releases)
- [Commits](https://github.com/yuin/goldmark/compare/v1.7.8...v1.7.13)

Updates `go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp` from 0.56.0 to 0.61.0
- [Release notes](https://github.com/open-telemetry/opentelemetry-go-contrib/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go-contrib/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go-contrib/compare/zpages/v0.56.0...zpages/v0.61.0)

Updates `go.opentelemetry.io/contrib/propagators/autoprop` from 0.42.0 to 0.62.0
- [Release notes](https://github.com/open-telemetry/opentelemetry-go-contrib/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go-contrib/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go-contrib/compare/zpages/v0.42.0...zpages/v0.62.0)

Updates `go.opentelemetry.io/otel` from 1.31.0 to 1.37.0
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.31.0...v1.37.0)

Updates `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc` from 1.31.0 to 1.37.0
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.31.0...v1.37.0)

Updates `go.opentelemetry.io/otel/sdk` from 1.31.0 to 1.37.0
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.31.0...v1.37.0)

Updates `github.com/libdns/libdns` from 1.0.0-beta.1 to 1.1.0
- [Release notes](https://github.com/libdns/libdns/releases)
- [Commits](https://github.com/libdns/libdns/compare/v1.0.0-beta.1...v1.1.0)

Updates `github.com/pires/go-proxyproto` from 0.7.1-0.20240628150027-b718e7ce4964 to 0.8.1
- [Release notes](https://github.com/pires/go-proxyproto/releases)
- [Commits](https://github.com/pires/go-proxyproto/commits/v0.8.1)

Updates `github.com/prometheus/client_model` from 0.5.0 to 0.6.2
- [Release notes](https://github.com/prometheus/client_model/releases)
- [Commits](https://github.com/prometheus/client_model/compare/v0.5.0...v0.6.2)

Updates `go.opentelemetry.io/otel/trace` from 1.31.0 to 1.37.0
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.31.0...v1.37.0)

Updates `go.step.sm/crypto` from 0.45.0 to 0.67.0
- [Release notes](https://github.com/smallstep/crypto/releases)
- [Commits](https://github.com/smallstep/crypto/compare/v0.45.0...v0.67.0)

---
updated-dependencies:
- dependency-name: github.com/KimMachineGun/automemlimit
  dependency-version: 0.7.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
- dependency-name: github.com/alecthomas/chroma/v2
  dependency-version: 2.20.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: github.com/google/cel-go
  dependency-version: 0.26.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: github.com/prometheus/client_golang
  dependency-version: 1.23.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: github.com/smallstep/certificates
  dependency-version: 0.28.4
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: github.com/smallstep/nosql
  dependency-version: 0.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: github.com/yuin/goldmark
  dependency-version: 1.7.13
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-updates
- dependency-name: go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp
  dependency-version: 0.61.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: go.opentelemetry.io/contrib/propagators/autoprop
  dependency-version: 0.62.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: go.opentelemetry.io/otel
  dependency-version: 1.37.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc
  dependency-version: 1.37.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: go.opentelemetry.io/otel/sdk
  dependency-version: 1.37.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: github.com/libdns/libdns
  dependency-version: 1.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: github.com/pires/go-proxyproto
  dependency-version: 0.8.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: github.com/prometheus/client_model
  dependency-version: 0.6.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: go.opentelemetry.io/otel/trace
  dependency-version: 1.37.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
- dependency-name: go.step.sm/crypto
  dependency-version: 0.67.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-05 09:45:32 +03:00
Matthew Holt 42c888ee1d Ignore irrelevant linter warning 2025-08-04 16:28:13 -06:00
Matthew Holt 731e6c2482 caddytls: Improve ECH error logging (close #7152) 2025-08-04 16:22:25 -06:00
Matthew Holt 0badb071ef httpcaddyfile: Fix generated config related to ACME global options
If global DNS provider is configured, it does not need to be repeated in the JSON.

If acme_* options are used, base automation policies should populate their issuers accordingly.

Global issuer settings like acme_* options don't need to specify subjects in the automation policy since they should apply as a global default.
2025-08-04 16:22:25 -06:00
joshuamcbeth e4447c4ba7 core: Use KeepAliveConfig to pass keepalive_interval to listener's accepted sockets (#7151)
Fix #7144
2025-08-02 09:43:34 -06:00
dependabot[bot] 5bc2afbbb6 build(deps): bump the actions-deps group with 6 updates (#7142)
Bumps the actions-deps group with 6 updates:

| Package | From | To |
| --- | --- | --- |
| [step-security/harden-runner](https://github.com/step-security/harden-runner) | `2.12.1` | `2.13.0` |
| [actions/upload-artifact](https://github.com/actions/upload-artifact) | `4.6.1` | `4.6.2` |
| [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) | `e9a05e6d32d7ed22b5656cd874ef31af58d05bfa` | `d58896d6a1865668819e1d91763c7751a165e159` |
| [anchore/sbom-action](https://github.com/anchore/sbom-action) | `0.20.1` | `0.20.4` |
| [ossf/scorecard-action](https://github.com/ossf/scorecard-action) | `2.4.1` | `2.4.2` |
| [github/codeql-action](https://github.com/github/codeql-action) | `3.29.0` | `3.29.4` |


Updates `step-security/harden-runner` from 2.12.1 to 2.13.0
- [Release notes](https://github.com/step-security/harden-runner/releases)
- [Commits](https://github.com/step-security/harden-runner/compare/002fdce3c6a235733a90a27c80493a3241e56863...ec9f2d5744a09debf3a187a3f4f675c53b671911)

Updates `actions/upload-artifact` from 4.6.1 to 4.6.2
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4.6.1...ea165f8d65b6e75b540449e92b4886f43607fa02)

Updates `sigstore/cosign-installer` from e9a05e6d32d7ed22b5656cd874ef31af58d05bfa to d58896d6a1865668819e1d91763c7751a165e159
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](https://github.com/sigstore/cosign-installer/compare/e9a05e6d32d7ed22b5656cd874ef31af58d05bfa...d58896d6a1865668819e1d91763c7751a165e159)

Updates `anchore/sbom-action` from 0.20.1 to 0.20.4
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Changelog](https://github.com/anchore/sbom-action/blob/main/RELEASE.md)
- [Commits](https://github.com/anchore/sbom-action/compare/9246b90769f852b3a8921f330c59e0b3f439d6e9...7b36ad622f042cab6f59a75c2ac24ccb256e9b45)

Updates `ossf/scorecard-action` from 2.4.1 to 2.4.2
- [Release notes](https://github.com/ossf/scorecard-action/releases)
- [Changelog](https://github.com/ossf/scorecard-action/blob/main/RELEASE.md)
- [Commits](https://github.com/ossf/scorecard-action/compare/f49aabe0b5af0936a0987cfb85d86b75731b0186...05b42c624433fc40578a4040d5cf5e36ddca8cde)

Updates `github/codeql-action` from 3.29.0 to 3.29.4
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/ce28f5bb42b7a9f2c824e633a3f6ee835bab6858...4e828ff8d448a8a6e532957b1811f387a63867e8)

---
updated-dependencies:
- dependency-name: step-security/harden-runner
  dependency-version: 2.13.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions-deps
- dependency-name: actions/upload-artifact
  dependency-version: 4.6.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions-deps
- dependency-name: sigstore/cosign-installer
  dependency-version: d58896d6a1865668819e1d91763c7751a165e159
  dependency-type: direct:production
  dependency-group: actions-deps
- dependency-name: anchore/sbom-action
  dependency-version: 0.20.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions-deps
- dependency-name: ossf/scorecard-action
  dependency-version: 2.4.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions-deps
- dependency-name: github/codeql-action
  dependency-version: 3.29.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-01 04:34:14 +03:00
Matthew Holt 4fd2acb5c9 Add test for 5b727bde29
Tests / test (./cmd/caddy/caddy, ~1.24.1, ubuntu-latest, 0, 1.24, linux) (push) Failing after 2m30s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.24.1, 1.24, aix) (push) Successful in 1m17s
Cross-Build / build (~1.24.1, 1.24, darwin) (push) Successful in 1m18s
Cross-Build / build (~1.24.1, 1.24, dragonfly) (push) Successful in 1m18s
Cross-Build / build (~1.24.1, 1.24, freebsd) (push) Successful in 1m21s
Cross-Build / build (~1.24.1, 1.24, illumos) (push) Successful in 1m14s
Cross-Build / build (~1.24.1, 1.24, linux) (push) Successful in 1m23s
Cross-Build / build (~1.24.1, 1.24, netbsd) (push) Successful in 1m27s
Cross-Build / build (~1.24.1, 1.24, openbsd) (push) Successful in 1m23s
Cross-Build / build (~1.24.1, 1.24, solaris) (push) Successful in 1m51s
Cross-Build / build (~1.24.1, 1.24, windows) (push) Successful in 2m11s
Lint / lint (ubuntu-latest, linux) (push) Successful in 2m15s
Lint / govulncheck (push) Successful in 1m33s
Lint / dependency-review (push) Failing after 51s
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Has started running
Tests / test (./cmd/caddy/caddy, ~1.24.1, macos-14, 0, 1.24, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.24.1, windows-latest, True, 1.24, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
2025-07-30 14:43:20 -06:00
Matthew Holt 3bd413546b go.mod: Upgrade dependencies 2025-07-29 11:59:43 -06:00
Matthew Holt 5b727bde29 httpcaddyfile: Allow naked acme_dns if dns is set (fix #7091) 2025-07-29 11:56:09 -06:00
Alexandre Daubois fe41ff3c5b core: Save app provisioning errors with context (#7070)
* fix(provisioning): remove app from apps map when its provision failed

* Clean up failed app provisioning with defer

* fix(provisioning): record apps that failed to provision with their error

* save the error when an app fails to initialize and return this error when this app is requested by a module

---------

Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
Co-authored-by: WeidiDeng <weidi_deng@icloud.com>
2025-07-29 10:31:13 -06:00
Mohammed Al Sahaf b7ae39e906 ci: reduce dependabot spam (#7078)
* ci: reduce dependabot spam

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* group actions deps

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

---------

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>
2025-07-24 16:40:00 -06:00
minxinyi ab3b2d64ba refactor: use slices.Equal to simplify code (#7141)
Signed-off-by: minxinyi <minxinyi6@outlook.com>
2025-07-23 14:07:46 +00:00
Ping Shuijie 6de2c9e135 chore: fix minor issue in comment (#7140)
Signed-off-by: pingshuijie <pingshuijie@outlook.com>
2025-07-22 11:27:36 +00:00
Marten Seemann 8ba7eefd07 update quic-go to v0.54.0 (#7138) 2025-07-20 17:40:45 -04:00
emmmm 291987ac23 chore: fix dead link (#7136)
* fix dead link

* Update cmd/commands.go

Co-authored-by: Mohammed Al Sahaf <mohammed@caffeinatedwonders.com>

---------

Co-authored-by: Mohammed Al Sahaf <mohammed@caffeinatedwonders.com>
2025-07-20 12:52:28 +00:00
Cédric Félizard 790f3e0885 fileserver: denote license for embedded JavaScript for LibreJS (#7127)
This commit adds support for LibreJS (https://en.wikipedia.org/wiki/GNU_LibreJS).

LibreJS would block this embedded JavaScript because its license is not stated in a machine-readable format.

Signed-off-by: Cédric Félizard <cedric@felizard.fr>
2025-07-16 11:49:49 -06:00
Zongze Wu bbf1dfcea2 headers: Support placeholders in replacement search patterns (#7117)
* fix: resolve http.request placeholders in header directive find operation

- Skip regex compilation during provision when placeholders are detected
- Compile regex at runtime after placeholder replacement
- Preserves performance for static regexes while enabling dynamic placeholders
- Fixes #7109

* test: add tests for placeholder detection in header replacements

- Test containsPlaceholders function edge cases
- Test provision skips compilation for dynamic regexes
- Test end-to-end placeholder replacement functionality
2025-07-14 14:55:00 -06:00
bytesingsong aff88d4b26 chore: fix function in comment (#7121)
Signed-off-by: bytesingsong <bytesing@icloud.com>
2025-07-12 11:54:57 +00:00
WeidiDeng 1209b5c566 reverseproxy: validate versions in http transport (#7112) 2025-07-09 14:13:27 -06:00
bytetigers a067fb1760 chore: fix struct name in comment (#7114)
Tests / test (./cmd/caddy/caddy, ~1.24.1, ubuntu-latest, 0, 1.24, linux) (push) Failing after 1m24s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.24.1, 1.24, aix) (push) Successful in 1m26s
Cross-Build / build (~1.24.1, 1.24, darwin) (push) Successful in 1m26s
Cross-Build / build (~1.24.1, 1.24, dragonfly) (push) Successful in 1m19s
Cross-Build / build (~1.24.1, 1.24, freebsd) (push) Successful in 1m19s
Cross-Build / build (~1.24.1, 1.24, illumos) (push) Successful in 1m20s
Cross-Build / build (~1.24.1, 1.24, linux) (push) Successful in 1m20s
Cross-Build / build (~1.24.1, 1.24, netbsd) (push) Successful in 1m20s
Cross-Build / build (~1.24.1, 1.24, openbsd) (push) Successful in 1m19s
Cross-Build / build (~1.24.1, 1.24, solaris) (push) Successful in 1m17s
Cross-Build / build (~1.24.1, 1.24, windows) (push) Successful in 1m18s
Lint / lint (ubuntu-latest, linux) (push) Successful in 1m54s
Lint / govulncheck (push) Successful in 1m14s
Lint / dependency-review (push) Failing after 25s
Tests / test (./cmd/caddy/caddy, ~1.24.1, macos-14, 0, 1.24, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.24.1, windows-latest, True, 1.24, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Has started running
Signed-off-by: bytetigers <bytetiger@icloud.com>
2025-07-08 08:00:58 +00:00
Francis Lavoie 77dd12cc78 httpcaddyfile: Validates TLS DNS challenge options (#7099)
Tests / test (./cmd/caddy/caddy, ~1.24.1, ubuntu-latest, 0, 1.24, linux) (push) Failing after 2m9s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.24.1, 1.24, aix) (push) Successful in 1m23s
Cross-Build / build (~1.24.1, 1.24, darwin) (push) Successful in 1m28s
Cross-Build / build (~1.24.1, 1.24, dragonfly) (push) Successful in 1m22s
Cross-Build / build (~1.24.1, 1.24, freebsd) (push) Successful in 1m15s
Cross-Build / build (~1.24.1, 1.24, illumos) (push) Successful in 1m19s
Cross-Build / build (~1.24.1, 1.24, linux) (push) Successful in 1m17s
Cross-Build / build (~1.24.1, 1.24, netbsd) (push) Successful in 1m15s
Cross-Build / build (~1.24.1, 1.24, openbsd) (push) Successful in 1m17s
Cross-Build / build (~1.24.1, 1.24, solaris) (push) Successful in 1m17s
Cross-Build / build (~1.24.1, 1.24, windows) (push) Successful in 1m20s
Lint / lint (ubuntu-latest, linux) (push) Successful in 2m15s
Lint / govulncheck (push) Successful in 1m34s
Lint / dependency-review (push) Failing after 50s
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 1m37s
Tests / test (./cmd/caddy/caddy, ~1.24.1, macos-14, 0, 1.24, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.24.1, windows-latest, True, 1.24, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
* httpcaddyfile: Validates TLS DNS challenge options

Adds validation to the TLS Caddyfile adapter to ensure that when DNS challenge options (such as propagation_delay or dns_ttl) are specified, a DNS provider is also configured.

Adds new integration tests to verify this validation logic, and implements a new mechanism for adapt tests to assert a config adapt error.

* Add some more AI-generated tests asserting config errors

* Parallel doesn't work here, we use global variables

* Windows fix
2025-06-30 23:58:16 +00:00
mountdisk c712cfcd76 docs: fix some minor issues in the comments (#7101) 2025-06-30 06:50:00 +00:00
gopherorg 33c88bd2bb refactor: replace HasPrefix+TrimPrefix with CutPrefix (#7095)
Signed-off-by: gopherorg <gopherworld@icloud.com>
2025-06-27 22:04:09 +03:00
Marten Seemann 11c6daecd7 go.mod: update quic-go to v0.53.0 (#7094) 2025-06-26 10:13:08 -06:00
filipRatajczak 3b4d966fba fileserver: Add sort buttons in grid mode (#7089)
Tests / test (./cmd/caddy/caddy, ~1.24.1, ubuntu-latest, 0, 1.24, linux) (push) Failing after 2m30s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.24.1, 1.24, aix) (push) Successful in 1m19s
Cross-Build / build (~1.24.1, 1.24, darwin) (push) Successful in 1m18s
Cross-Build / build (~1.24.1, 1.24, dragonfly) (push) Successful in 1m19s
Cross-Build / build (~1.24.1, 1.24, freebsd) (push) Successful in 1m22s
Cross-Build / build (~1.24.1, 1.24, illumos) (push) Successful in 1m18s
Cross-Build / build (~1.24.1, 1.24, linux) (push) Successful in 1m18s
Cross-Build / build (~1.24.1, 1.24, netbsd) (push) Successful in 1m17s
Cross-Build / build (~1.24.1, 1.24, openbsd) (push) Successful in 1m16s
Cross-Build / build (~1.24.1, 1.24, solaris) (push) Successful in 1m18s
Cross-Build / build (~1.24.1, 1.24, windows) (push) Successful in 1m21s
Lint / lint (ubuntu-latest, linux) (push) Successful in 2m13s
Lint / govulncheck (push) Successful in 1m36s
Lint / dependency-review (push) Failing after 53s
Tests / test (./cmd/caddy/caddy, ~1.24.1, macos-14, 0, 1.24, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.24.1, windows-latest, True, 1.24, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Has started running
* [ADD] sort buttons in grid mode

* [CHANGE] replace spaces with tabs
2025-06-23 13:26:45 -06:00
曹家巧 070d454c0d Use the built-in max/min to simplify the code (#7081)
Tests / test (./cmd/caddy/caddy, ~1.24.1, ubuntu-latest, 0, 1.24, linux) (push) Failing after 1m53s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.24.1, 1.24, aix) (push) Successful in 1m35s
Cross-Build / build (~1.24.1, 1.24, darwin) (push) Successful in 1m29s
Cross-Build / build (~1.24.1, 1.24, dragonfly) (push) Successful in 1m28s
Cross-Build / build (~1.24.1, 1.24, freebsd) (push) Successful in 1m28s
Cross-Build / build (~1.24.1, 1.24, illumos) (push) Successful in 1m23s
Cross-Build / build (~1.24.1, 1.24, linux) (push) Successful in 1m23s
Cross-Build / build (~1.24.1, 1.24, netbsd) (push) Successful in 1m21s
Cross-Build / build (~1.24.1, 1.24, openbsd) (push) Successful in 1m20s
Cross-Build / build (~1.24.1, 1.24, solaris) (push) Successful in 1m21s
Cross-Build / build (~1.24.1, 1.24, windows) (push) Successful in 1m21s
Lint / lint (ubuntu-latest, linux) (push) Successful in 1m57s
Lint / govulncheck (push) Successful in 1m31s
Lint / dependency-review (push) Failing after 41s
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 2s
Tests / test (./cmd/caddy/caddy, ~1.24.1, macos-14, 0, 1.24, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.24.1, windows-latest, True, 1.24, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
Signed-off-by: xiaoxiangirl <caojiaqiao@outlook.com>
2025-06-19 16:39:48 -06:00
Mohammed Al Sahaf 2f0fc62b34 chore: apply security best practices for CI (#7066)
Tests / test (./cmd/caddy/caddy, ~1.24.1, ubuntu-latest, 0, 1.24, linux) (push) Failing after 3m9s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.24.1, 1.24, aix) (push) Successful in 1m37s
Cross-Build / build (~1.24.1, 1.24, darwin) (push) Successful in 1m32s
Cross-Build / build (~1.24.1, 1.24, dragonfly) (push) Successful in 1m42s
Cross-Build / build (~1.24.1, 1.24, freebsd) (push) Successful in 1m47s
Cross-Build / build (~1.24.1, 1.24, illumos) (push) Successful in 1m44s
Cross-Build / build (~1.24.1, 1.24, linux) (push) Successful in 1m46s
Cross-Build / build (~1.24.1, 1.24, netbsd) (push) Successful in 1m32s
Cross-Build / build (~1.24.1, 1.24, openbsd) (push) Successful in 1m27s
Cross-Build / build (~1.24.1, 1.24, solaris) (push) Successful in 1m26s
Cross-Build / build (~1.24.1, 1.24, windows) (push) Successful in 1m30s
Lint / lint (ubuntu-latest, linux) (push) Successful in 2m18s
Lint / govulncheck (push) Successful in 1m24s
Lint / dependency-review (push) Failing after 1m1s
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 2s
Tests / test (./cmd/caddy/caddy, ~1.24.1, macos-14, 0, 1.24, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.24.1, windows-latest, True, 1.24, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
* chore: apply security best practices for CI

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* remove redundant codeql job

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* run scorecard flow on PRs

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

---------

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>
2025-06-16 20:14:09 +00:00
WeidiDeng 3d0b4fac5a core: Clean up new config if it failed to run (#7068) 2025-06-16 13:15:41 -06:00
Mohammed Al Sahaf 1a0f168b6e ci: add {base,head}-ref to dep review check (#7064)
Tests / test (./cmd/caddy/caddy, ~1.24.1, ubuntu-latest, 0, 1.24, linux) (push) Failing after 1m28s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.24.1, 1.24, aix) (push) Successful in 1m22s
Cross-Build / build (~1.24.1, 1.24, darwin) (push) Successful in 1m22s
Cross-Build / build (~1.24.1, 1.24, dragonfly) (push) Successful in 1m23s
Cross-Build / build (~1.24.1, 1.24, freebsd) (push) Successful in 1m17s
Cross-Build / build (~1.24.1, 1.24, illumos) (push) Successful in 1m17s
Cross-Build / build (~1.24.1, 1.24, linux) (push) Successful in 1m17s
Cross-Build / build (~1.24.1, 1.24, netbsd) (push) Successful in 1m15s
Cross-Build / build (~1.24.1, 1.24, openbsd) (push) Successful in 1m19s
Cross-Build / build (~1.24.1, 1.24, solaris) (push) Successful in 1m17s
Cross-Build / build (~1.24.1, 1.24, windows) (push) Successful in 1m17s
Lint / lint (ubuntu-latest, linux) (push) Successful in 1m52s
Lint / govulncheck (push) Successful in 1m19s
Lint / dependency-review (push) Failing after 49s
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 2s
Tests / test (./cmd/caddy/caddy, ~1.24.1, macos-14, 0, 1.24, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.24.1, windows-latest, True, 1.24, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>
2025-06-13 08:13:17 +03:00
Mohammed Al Sahaf 7a33f481f1 ci: add dep review, OSSF scorecard actions (#7063)
* ci: add dep review action

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* sprinkle permissions on Actions jobs

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* README: add OpenSSF best practices badge

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* add draft OpenSSF Scorecard workflow

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

---------

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>
2025-06-12 23:40:51 +00:00
Herman Slatman e633d013f6 cmd: fix Commands function not returning all registered commands (#7059) 2025-06-12 17:17:51 -06:00
Matt Holt fe26751491 Update SECURITY.md
Tests / test (./cmd/caddy/caddy, ~1.24.1, ubuntu-latest, 0, 1.24, linux) (push) Failing after 1m35s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.24.1, 1.24, aix) (push) Successful in 1m39s
Cross-Build / build (~1.24.1, 1.24, darwin) (push) Successful in 1m19s
Cross-Build / build (~1.24.1, 1.24, dragonfly) (push) Successful in 1m16s
Cross-Build / build (~1.24.1, 1.24, freebsd) (push) Successful in 1m16s
Cross-Build / build (~1.24.1, 1.24, illumos) (push) Successful in 1m15s
Cross-Build / build (~1.24.1, 1.24, linux) (push) Successful in 1m15s
Cross-Build / build (~1.24.1, 1.24, netbsd) (push) Successful in 1m14s
Cross-Build / build (~1.24.1, 1.24, openbsd) (push) Successful in 1m15s
Cross-Build / build (~1.24.1, 1.24, solaris) (push) Successful in 1m14s
Cross-Build / build (~1.24.1, 1.24, windows) (push) Successful in 1m13s
Lint / lint (ubuntu-latest, linux) (push) Successful in 1m49s
Lint / govulncheck (push) Successful in 1m16s
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy, ~1.24.1, macos-14, 0, 1.24, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.24.1, windows-latest, True, 1.24, windows) (push) Has been cancelled
2025-06-12 09:38:48 -06:00
dependabot[bot] 4b01d77b81 build(deps): bump github.com/cloudflare/circl from 1.6.0 to 1.6.1 (#7058)
Tests / test (./cmd/caddy/caddy, ~1.24.1, ubuntu-latest, 0, 1.24, linux) (push) Failing after 1m46s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.24.1, 1.24, aix) (push) Successful in 1m27s
Cross-Build / build (~1.24.1, 1.24, darwin) (push) Successful in 1m29s
Cross-Build / build (~1.24.1, 1.24, dragonfly) (push) Successful in 1m14s
Cross-Build / build (~1.24.1, 1.24, freebsd) (push) Successful in 1m15s
Cross-Build / build (~1.24.1, 1.24, illumos) (push) Successful in 1m19s
Cross-Build / build (~1.24.1, 1.24, linux) (push) Successful in 1m14s
Cross-Build / build (~1.24.1, 1.24, netbsd) (push) Successful in 1m14s
Cross-Build / build (~1.24.1, 1.24, openbsd) (push) Successful in 1m16s
Cross-Build / build (~1.24.1, 1.24, solaris) (push) Successful in 1m13s
Cross-Build / build (~1.24.1, 1.24, windows) (push) Successful in 1m16s
Lint / lint (ubuntu-latest, linux) (push) Successful in 1m47s
Lint / govulncheck (push) Successful in 1m16s
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy, ~1.24.1, macos-14, 0, 1.24, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.24.1, windows-latest, True, 1.24, windows) (push) Has been cancelled
Bumps [github.com/cloudflare/circl](https://github.com/cloudflare/circl) from 1.6.0 to 1.6.1.
- [Release notes](https://github.com/cloudflare/circl/releases)
- [Commits](https://github.com/cloudflare/circl/compare/v1.6.0...v1.6.1)

---
updated-dependencies:
- dependency-name: github.com/cloudflare/circl
  dependency-version: 1.6.1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-12 11:44:26 +03:00
Hina🐣 | Developer 0f209f62eb httpcaddyfile: reject blocks in log_skip directive (#7056)
Tests / test (./cmd/caddy/caddy, ~1.24.1, ubuntu-latest, 0, 1.24, linux) (push) Failing after 1m26s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.24.1, 1.24, aix) (push) Successful in 1m50s
Cross-Build / build (~1.24.1, 1.24, darwin) (push) Successful in 1m15s
Cross-Build / build (~1.24.1, 1.24, dragonfly) (push) Successful in 1m17s
Cross-Build / build (~1.24.1, 1.24, freebsd) (push) Successful in 1m14s
Cross-Build / build (~1.24.1, 1.24, illumos) (push) Successful in 1m13s
Cross-Build / build (~1.24.1, 1.24, linux) (push) Successful in 1m15s
Cross-Build / build (~1.24.1, 1.24, netbsd) (push) Successful in 1m14s
Cross-Build / build (~1.24.1, 1.24, openbsd) (push) Successful in 1m14s
Cross-Build / build (~1.24.1, 1.24, solaris) (push) Successful in 1m14s
Cross-Build / build (~1.24.1, 1.24, windows) (push) Successful in 1m14s
Lint / lint (ubuntu-latest, linux) (push) Successful in 1m48s
Lint / govulncheck (push) Successful in 1m16s
Tests / test (./cmd/caddy/caddy, ~1.24.1, macos-14, 0, 1.24, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.24.1, windows-latest, True, 1.24, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
2025-06-09 21:56:21 -06:00
Mohammed Al Sahaf 1481c0411a caddytls: wire up client_auth leaf verifier Caddyfile (#6772)
Tests / test (./cmd/caddy/caddy, ~1.24.1, ubuntu-latest, 0, 1.24, linux) (push) Failing after 1m41s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.24.1, 1.24, aix) (push) Successful in 2m7s
Cross-Build / build (~1.24.1, 1.24, darwin) (push) Successful in 1m23s
Cross-Build / build (~1.24.1, 1.24, dragonfly) (push) Successful in 1m20s
Cross-Build / build (~1.24.1, 1.24, freebsd) (push) Successful in 1m16s
Cross-Build / build (~1.24.1, 1.24, illumos) (push) Successful in 1m16s
Cross-Build / build (~1.24.1, 1.24, linux) (push) Successful in 1m15s
Cross-Build / build (~1.24.1, 1.24, netbsd) (push) Successful in 1m16s
Cross-Build / build (~1.24.1, 1.24, openbsd) (push) Successful in 1m15s
Cross-Build / build (~1.24.1, 1.24, solaris) (push) Successful in 1m19s
Cross-Build / build (~1.24.1, 1.24, windows) (push) Successful in 1m16s
Lint / lint (ubuntu-latest, linux) (push) Successful in 1m48s
Lint / govulncheck (push) Successful in 1m18s
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy, ~1.24.1, macos-14, 0, 1.24, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.24.1, windows-latest, True, 1.24, windows) (push) Has been cancelled
* client_auth: wire up leaf verifier Caddyfile

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* review feedback + tests

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

---------

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>
2025-06-09 08:18:36 -06:00
Youness Farini 092913a7a5 httpcaddyfile: Prevent error handler from overriding sub-handler matchers (#6999)
Tests / test (./cmd/caddy/caddy, ~1.24.1, ubuntu-latest, 0, 1.24, linux) (push) Failing after 1m52s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.24.1, 1.24, aix) (push) Successful in 1m33s
Cross-Build / build (~1.24.1, 1.24, darwin) (push) Successful in 1m20s
Cross-Build / build (~1.24.1, 1.24, dragonfly) (push) Successful in 1m17s
Cross-Build / build (~1.24.1, 1.24, freebsd) (push) Successful in 1m15s
Cross-Build / build (~1.24.1, 1.24, illumos) (push) Successful in 1m17s
Cross-Build / build (~1.24.1, 1.24, linux) (push) Successful in 1m14s
Cross-Build / build (~1.24.1, 1.24, netbsd) (push) Successful in 1m16s
Cross-Build / build (~1.24.1, 1.24, openbsd) (push) Successful in 1m14s
Cross-Build / build (~1.24.1, 1.24, solaris) (push) Successful in 1m15s
Cross-Build / build (~1.24.1, 1.24, windows) (push) Successful in 1m15s
Lint / lint (ubuntu-latest, linux) (push) Successful in 1m49s
Lint / govulncheck (push) Successful in 1m16s
Tests / test (./cmd/caddy/caddy, ~1.24.1, macos-14, 0, 1.24, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.24.1, windows-latest, True, 1.24, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
Fixes: #6957
2025-06-06 11:46:39 -06:00
Laurin 7099892958 core: Check for nil event origin (#7047)
Tests / test (./cmd/caddy/caddy, ~1.24.1, ubuntu-latest, 0, 1.24, linux) (push) Failing after 2m0s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.24.1, 1.24, aix) (push) Successful in 1m20s
Cross-Build / build (~1.24.1, 1.24, darwin) (push) Successful in 1m17s
Cross-Build / build (~1.24.1, 1.24, dragonfly) (push) Successful in 1m18s
Cross-Build / build (~1.24.1, 1.24, freebsd) (push) Successful in 1m14s
Cross-Build / build (~1.24.1, 1.24, illumos) (push) Successful in 1m15s
Cross-Build / build (~1.24.1, 1.24, linux) (push) Successful in 1m15s
Cross-Build / build (~1.24.1, 1.24, netbsd) (push) Successful in 1m18s
Cross-Build / build (~1.24.1, 1.24, openbsd) (push) Successful in 1m17s
Cross-Build / build (~1.24.1, 1.24, solaris) (push) Successful in 1m18s
Cross-Build / build (~1.24.1, 1.24, windows) (push) Successful in 1m15s
Lint / lint (ubuntu-latest, linux) (push) Successful in 1m50s
Lint / govulncheck (push) Successful in 1m19s
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy, ~1.24.1, macos-14, 0, 1.24, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.24.1, windows-latest, True, 1.24, windows) (push) Has been cancelled
* fix: crash - null check on event origin

* chore: use accessor instead of property
2025-06-05 19:10:08 +00:00
dependabot[bot] 45c9341deb build(deps): bump golangci/golangci-lint-action from 6 to 8 (#7044)
Tests / test (./cmd/caddy/caddy, ~1.24.1, ubuntu-latest, 0, 1.24, linux) (push) Failing after 1m44s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.24.1, 1.24, aix) (push) Successful in 1m30s
Cross-Build / build (~1.24.1, 1.24, darwin) (push) Successful in 1m21s
Cross-Build / build (~1.24.1, 1.24, dragonfly) (push) Successful in 1m16s
Cross-Build / build (~1.24.1, 1.24, freebsd) (push) Successful in 1m16s
Cross-Build / build (~1.24.1, 1.24, illumos) (push) Successful in 1m18s
Cross-Build / build (~1.24.1, 1.24, linux) (push) Successful in 1m16s
Cross-Build / build (~1.24.1, 1.24, netbsd) (push) Successful in 1m17s
Cross-Build / build (~1.24.1, 1.24, openbsd) (push) Successful in 1m17s
Cross-Build / build (~1.24.1, 1.24, solaris) (push) Successful in 1m16s
Cross-Build / build (~1.24.1, 1.24, windows) (push) Successful in 1m14s
Lint / lint (ubuntu-latest, linux) (push) Successful in 2m9s
Lint / govulncheck (push) Successful in 1m18s
Tests / test (./cmd/caddy/caddy, ~1.24.1, macos-14, 0, 1.24, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.24.1, windows-latest, True, 1.24, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 6 to 8.
- [Release notes](https://github.com/golangci/golangci-lint-action/releases)
- [Commits](https://github.com/golangci/golangci-lint-action/compare/v6...v8)

---
updated-dependencies:
- dependency-name: golangci/golangci-lint-action
  dependency-version: '8'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-03 02:33:40 +03:00
Mohammed Al Sahaf e039a5bb5c chore: upgrade .golangci.yml and workflow to v2 (#6924)
* chore: upgrade .golangci.yml and workflow to v2

run `golangci-lint fmt`

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* run `golangci-lint run --fix`

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* more lint fixes

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* bring back comments to .golangci.yml

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* appease the linter some more

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* oops

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* use embedded structs

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* use embedded structs where they were used before

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* disable rule  `-QF1006`

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* missed a spot

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

---------

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>
2025-06-03 02:24:32 +03:00
tongjicoder 5b2eb66418 Use slices.Contains to simplify code (#7039)
Tests / test (./cmd/caddy/caddy, ~1.24.1, ubuntu-latest, 0, 1.24, linux) (push) Failing after 2m25s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.24.1, 1.24, aix) (push) Successful in 1m27s
Cross-Build / build (~1.24.1, 1.24, darwin) (push) Successful in 1m21s
Cross-Build / build (~1.24.1, 1.24, dragonfly) (push) Successful in 1m24s
Cross-Build / build (~1.24.1, 1.24, freebsd) (push) Successful in 1m25s
Cross-Build / build (~1.24.1, 1.24, illumos) (push) Successful in 1m19s
Cross-Build / build (~1.24.1, 1.24, linux) (push) Successful in 1m20s
Cross-Build / build (~1.24.1, 1.24, netbsd) (push) Successful in 1m21s
Cross-Build / build (~1.24.1, 1.24, openbsd) (push) Successful in 1m17s
Cross-Build / build (~1.24.1, 1.24, solaris) (push) Successful in 1m18s
Cross-Build / build (~1.24.1, 1.24, windows) (push) Successful in 1m23s
Lint / lint (ubuntu-latest, linux) (push) Successful in 2m17s
Lint / govulncheck (push) Successful in 1m43s
Tests / test (./cmd/caddy/caddy, ~1.24.1, macos-14, 0, 1.24, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.24.1, windows-latest, True, 1.24, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
Signed-off-by: tongjicoder <tongjicoder@icloud.com>
2025-05-31 12:03:06 -06:00
eveneast a76d005a94 Use maps.Copy for simpler map handling (#7009)
Tests / test (./cmd/caddy/caddy, ~1.24.1, ubuntu-latest, 0, 1.24, linux) (push) Failing after 1m19s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.24.1, 1.24, aix) (push) Successful in 1m15s
Cross-Build / build (~1.24.1, 1.24, darwin) (push) Successful in 1m15s
Cross-Build / build (~1.24.1, 1.24, dragonfly) (push) Successful in 1m14s
Cross-Build / build (~1.24.1, 1.24, freebsd) (push) Successful in 1m14s
Cross-Build / build (~1.24.1, 1.24, illumos) (push) Successful in 1m14s
Cross-Build / build (~1.24.1, 1.24, linux) (push) Successful in 1m15s
Cross-Build / build (~1.24.1, 1.24, netbsd) (push) Successful in 1m14s
Cross-Build / build (~1.24.1, 1.24, openbsd) (push) Successful in 1m45s
Cross-Build / build (~1.24.1, 1.24, solaris) (push) Successful in 1m17s
Cross-Build / build (~1.24.1, 1.24, windows) (push) Successful in 1m14s
Lint / lint (ubuntu-latest, linux) (push) Successful in 1m48s
Lint / govulncheck (push) Successful in 1m16s
Tests / test (./cmd/caddy/caddy, ~1.24.1, macos-14, 0, 1.24, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.24.1, windows-latest, True, 1.24, windows) (push) Has been cancelled
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
Signed-off-by: eveneast <qcqs@foxmail.com>
2025-05-13 15:16:47 -06:00
WeidiDeng 8524386737 caddyhttp: Compare paths w/o wildcard if prefixes differ (#7015)
* fix route sort by comparing paths without wildcard if they don't share the same prefix

* sort lexically if paths have the same length
2025-05-13 13:17:52 -06:00
Jimmy Lipham 94147caf31 fileserver: map invalid path errors to fs.ErrInvalid, and return 400 for any invalid path errors. (close #7008) (#7017)
Tests / test (./cmd/caddy/caddy, ~1.24.1, ubuntu-latest, 0, 1.24, linux) (push) Failing after 1m18s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.24.1, 1.24, aix) (push) Successful in 1m12s
Cross-Build / build (~1.24.1, 1.24, darwin) (push) Successful in 1m13s
Cross-Build / build (~1.24.1, 1.24, dragonfly) (push) Successful in 1m12s
Cross-Build / build (~1.24.1, 1.24, freebsd) (push) Successful in 1m12s
Cross-Build / build (~1.24.1, 1.24, illumos) (push) Successful in 1m15s
Cross-Build / build (~1.24.1, 1.24, linux) (push) Successful in 1m12s
Cross-Build / build (~1.24.1, 1.24, netbsd) (push) Successful in 1m12s
Cross-Build / build (~1.24.1, 1.24, openbsd) (push) Successful in 1m36s
Cross-Build / build (~1.24.1, 1.24, solaris) (push) Successful in 1m22s
Cross-Build / build (~1.24.1, 1.24, windows) (push) Successful in 1m15s
Lint / lint (ubuntu-latest, linux) (push) Successful in 1m46s
Lint / govulncheck (push) Successful in 1m15s
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy, ~1.24.1, macos-14, 0, 1.24, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.24.1, windows-latest, True, 1.24, windows) (push) Has been cancelled
2025-05-13 07:43:27 -06:00
WeidiDeng 716d72e475 intercept: implement Unwrap for interceptedResponseHandler (#7016)
Tests / test (./cmd/caddy/caddy, ~1.24.1, ubuntu-latest, 0, 1.24, linux) (push) Failing after 1m20s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Lint / lint (ubuntu-latest, linux) (push) Successful in 1m50s
Lint / govulncheck (push) Successful in 1m16s
Lint / lint (macos-14, mac) (push) Has been cancelled
Lint / lint (windows-latest, windows) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy, ~1.24.1, macos-14, 0, 1.24, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.24.1, windows-latest, True, 1.24, windows) (push) Has been cancelled
2025-05-12 12:15:34 -06:00
187 changed files with 7524 additions and 1651 deletions
+31
View File
@@ -0,0 +1,31 @@
name: Issue
description: An actionable development item, like a bug report or feature request
body:
- type: markdown
attributes:
value: |
Thank you for opening an issue! This is for actionable development items like bug reports and feature requests.
If you have a question about using Caddy, please [post on our forums](https://caddy.community) instead.
- type: textarea
id: content
attributes:
label: Issue Details
placeholder: Describe the issue here. Be specific by providing complete logs and minimal instructions to reproduce, or a thoughtful proposal, etc.
validations:
required: true
- type: dropdown
id: assistance-disclosure
attributes:
label: Assistance Disclosure
description: "Our project allows assistance by AI/LLM tools as long as it is disclosed and described so we can better respond. Please certify whether you have used any such tooling related to this issue:"
options:
-
- AI used
- AI not used
validations:
required: true
- type: input
id: assistance-description
attributes:
label: If AI was used, describe the extent to which it was used.
description: 'Examples: "ChatGPT translated from my native language" or "Claude proposed this change/feature"'
+5
View File
@@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Caddy forum
url: https://caddy.community
about: If you have questions (or answers!) about using Caddy, please use our forum
+2 -2
View File
@@ -48,9 +48,9 @@ We consider publicly-registered domain names to be public information. This nece
It will speed things up if you suggest a working patch, such as a code diff, and explain why and how it works. Reports that are not actionable, do not contain enough information, are too pushy/demanding, or are not able to convince us that it is a viable and practical attack on the web server itself may be deferred to a later time or possibly ignored, depending on available resources. Priority will be given to credible, responsible reports that are constructive, specific, and actionable. (We get a lot of invalid reports.) Thank you for understanding.
When you are ready, please email Matt Holt (the author) directly: matt at dyanim dot com.
When you are ready, please submit a [new private vulnerability report](https://github.com/caddyserver/caddy/security/advisories/new).
Please don't encrypt the email body. It only makes the process more complicated.
Please don't encrypt the message. It only makes the process more complicated.
Please also understand that due to our nature as an open source project, we do not have a budget to award security bounties. We can only thank you.
+15
View File
@@ -3,5 +3,20 @@ version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
open-pull-requests-limit: 1
groups:
actions-deps:
patterns:
- "*"
schedule:
interval: "monthly"
- package-ecosystem: "gomod"
directory: "/"
open-pull-requests-limit: 1
groups:
all-updates:
patterns:
- "*"
schedule:
interval: "monthly"
+29
View File
@@ -0,0 +1,29 @@
## Assistance Disclosure
<!--
Thank you for contributing! Please note:
The use of AI/LLM tools is allowed so long as it is disclosed, so
that we can provide better code review and maintain project quality.
If you used AI/LLM tooling in any way related to this PR, please
let us know to what extent it was utilized.
Examples:
"No AI was used."
"I wrote the code, but Claude generated the tests."
"I consulted ChatGPT for a solution, but I authored/coded it myself."
"Cody generated the code, and I verified it is correct."
"Copilot provided tab completion for code and comments."
We expect that you have vetted your contributions for correctness.
Additionally, signing our CLA certifies that you have the rights to
contribute this change.
Replace the text below with your disclosure:
-->
_This PR is missing an assistance disclosure._
+30
View File
@@ -0,0 +1,30 @@
name: AI Moderator
permissions: read-all
on:
issues:
types: [opened]
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
jobs:
spam-detection:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
models: read
contents: read
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8
- uses: github/ai-moderator@6bcdb2a79c2e564db8d76d7d4439d91a044c4eb6
with:
token: ${{ secrets.GITHUB_TOKEN }}
spam-label: 'spam'
ai-label: 'ai-generated'
minimize-detected-comments: true
# Built-in prompt configuration (all enabled by default)
enable-spam-detection: true
enable-link-spam-detection: true
enable-ai-detection: true
# custom-prompt-path: '.github/prompts/my-custom.prompt.yml' # Optional
+221
View File
@@ -0,0 +1,221 @@
name: Release Proposal Approval Tracker
on:
pull_request_review:
types: [submitted, dismissed]
pull_request:
types: [labeled, unlabeled, synchronize, closed]
permissions:
contents: read
pull-requests: write
issues: write
jobs:
check-approvals:
name: Track Maintainer Approvals
runs-on: ubuntu-latest
# Only run on PRs with release-proposal label
if: contains(github.event.pull_request.labels.*.name, 'release-proposal') && github.event.pull_request.state == 'open'
steps:
- name: Check approvals and update PR
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
env:
MAINTAINER_LOGINS: ${{ secrets.MAINTAINER_LOGINS }}
with:
script: |
const pr = context.payload.pull_request;
// Extract version from PR title (e.g., "Release Proposal: v1.2.3")
const versionMatch = pr.title.match(/Release Proposal:\s*(v[\d.]+(?:-[\w.]+)?)/);
const commitMatch = pr.body.match(/\*\*Target Commit:\*\*\s*`([a-f0-9]+)`/);
if (!versionMatch || !commitMatch) {
console.log('Could not extract version from title or commit from body');
return;
}
const version = versionMatch[1];
const targetCommit = commitMatch[1];
console.log(`Version: ${version}, Target Commit: ${targetCommit}`);
// Get all reviews
const reviews = await github.rest.pulls.listReviews({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pr.number
});
// Get list of maintainers
const maintainerLoginsRaw = process.env.MAINTAINER_LOGINS || '';
const maintainerLogins = maintainerLoginsRaw
.split(/[,;]/)
.map(login => login.trim())
.filter(login => login.length > 0);
console.log(`Maintainer logins: ${maintainerLogins.join(', ')}`);
// Get the latest review from each user
const latestReviewsByUser = {};
reviews.data.forEach(review => {
const username = review.user.login;
if (!latestReviewsByUser[username] || new Date(review.submitted_at) > new Date(latestReviewsByUser[username].submitted_at)) {
latestReviewsByUser[username] = review;
}
});
// Count approvals from maintainers
const maintainerApprovals = Object.entries(latestReviewsByUser)
.filter(([username, review]) =>
maintainerLogins.includes(username) &&
review.state === 'APPROVED'
)
.map(([username, review]) => username);
const approvalCount = maintainerApprovals.length;
console.log(`Found ${approvalCount} maintainer approvals from: ${maintainerApprovals.join(', ')}`);
// Get current labels
const currentLabels = pr.labels.map(label => label.name);
const hasApprovedLabel = currentLabels.includes('approved');
const hasAwaitingApprovalLabel = currentLabels.includes('awaiting-approval');
if (approvalCount >= 2 && !hasApprovedLabel) {
console.log('✅ Quorum reached! Updating PR...');
// Remove awaiting-approval label if present
if (hasAwaitingApprovalLabel) {
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
name: 'awaiting-approval'
}).catch(e => console.log('Label not found:', e.message));
}
// Add approved label
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
labels: ['approved']
});
// Add comment with tagging instructions
const approversList = maintainerApprovals.map(u => `@${u}`).join(', ');
const commentBody = [
'## ✅ Approval Quorum Reached',
'',
`This release proposal has been approved by ${approvalCount} maintainers: ${approversList}`,
'',
'### Tagging Instructions',
'',
'A maintainer should now create and push the signed tag:',
'',
'```bash',
`git checkout ${targetCommit}`,
`git tag -s ${version} -m "Release ${version}"`,
`git push origin ${version}`,
`git checkout -`,
'```',
'',
'The release workflow will automatically start when the tag is pushed.'
].join('\n');
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
body: commentBody
});
console.log('Posted tagging instructions');
} else if (approvalCount < 2 && hasApprovedLabel) {
console.log('⚠️ Approval count dropped below quorum, removing approved label');
// Remove approved label
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
name: 'approved'
}).catch(e => console.log('Label not found:', e.message));
// Add awaiting-approval label
if (!hasAwaitingApprovalLabel) {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
labels: ['awaiting-approval']
});
}
} else {
console.log(`⏳ Waiting for more approvals (${approvalCount}/2 required)`);
}
handle-pr-closed:
name: Handle PR Closed Without Tag
runs-on: ubuntu-latest
if: |
contains(github.event.pull_request.labels.*.name, 'release-proposal') &&
github.event.action == 'closed' && !contains(github.event.pull_request.labels.*.name, 'released')
steps:
- name: Add cancelled label and comment
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const pr = context.payload.pull_request;
// Check if the release-in-progress label is present
const hasReleaseInProgress = pr.labels.some(label => label.name === 'release-in-progress');
if (hasReleaseInProgress) {
// PR was closed while release was in progress - this is unusual
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
body: '⚠️ **Warning:** This PR was closed while a release was in progress. This may indicate an error. Please verify the release status.'
});
} else {
// PR was closed before tag was created - this is normal cancellation
const versionMatch = pr.title.match(/Release Proposal:\s*(v[\d.]+(?:-[\w.]+)?)/);
const version = versionMatch ? versionMatch[1] : 'unknown';
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
body: `## 🚫 Release Proposal Cancelled\n\nThis release proposal for ${version} was closed without creating the tag.\n\nIf you want to proceed with this release later, you can create a new release proposal.`
});
}
// Add cancelled label
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
labels: ['cancelled']
});
// Remove other workflow labels if present
const labelsToRemove = ['awaiting-approval', 'approved', 'release-in-progress'];
for (const label of labelsToRemove) {
try {
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
name: label
});
} catch (e) {
console.log(`Label ${label} not found or already removed`);
}
}
console.log('Added cancelled label and cleaned up workflow labels');
+45 -16
View File
@@ -13,9 +13,13 @@ on:
- 2.*
env:
GOFLAGS: '-tags=nobadger,nomysql,nopgx'
# https://github.com/actions/setup-go/issues/491
GOTOOLCHAIN: local
permissions:
contents: read
jobs:
test:
strategy:
@@ -27,13 +31,13 @@ jobs:
- mac
- windows
go:
- '1.24'
- '1.25'
include:
# Set the minimum Go patch version for the given Go minor
# Usable via ${{ matrix.GO_SEMVER }}
- go: '1.24'
GO_SEMVER: '~1.24.1'
- go: '1.25'
GO_SEMVER: '~1.25.0'
# Set some variables per OS, usable via ${{ matrix.VAR }}
# OS_LABEL: the VM label from GitHub Actions (see https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories)
@@ -55,13 +59,21 @@ jobs:
SUCCESS: 'True'
runs-on: ${{ matrix.OS_LABEL }}
permissions:
contents: read
pull-requests: read
actions: write # to allow uploading artifacts and cache
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
with:
egress-policy: audit
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Install Go
uses: actions/setup-go@v5
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
with:
go-version: ${{ matrix.GO_SEMVER }}
check-latest: true
@@ -99,7 +111,7 @@ jobs:
env:
CGO_ENABLED: 0
run: |
go build -tags nobadger,nomysql,nopgx -trimpath -ldflags="-w -s" -v
go build -trimpath -ldflags="-w -s" -v
- name: Smoke test Caddy
working-directory: ./cmd/caddy
@@ -108,7 +120,7 @@ jobs:
./caddy stop
- name: Publish Build Artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: caddy_${{ runner.os }}_go${{ matrix.go }}_${{ steps.vars.outputs.short_sha }}
path: ${{ matrix.CADDY_BIN_PATH }}
@@ -122,7 +134,7 @@ jobs:
# continue-on-error: true
run: |
# (go test -v -coverprofile=cover-profile.out -race ./... 2>&1) > test-results/test-result.out
go test -tags nobadger,nomysql,nopgx -v -coverprofile="cover-profile.out" -short -race ./...
go test -v -coverprofile="cover-profile.out" -short -race ./...
# echo "status=$?" >> $GITHUB_OUTPUT
# Relevant step if we reinvestigate publishing test/coverage reports
@@ -142,12 +154,21 @@ jobs:
s390x-test:
name: test (s390x on IBM Z)
permissions:
contents: read
pull-requests: read
runs-on: ubuntu-latest
if: github.event.pull_request.head.repo.full_name == 'caddyserver/caddy' && github.actor != 'dependabot[bot]'
continue-on-error: true # August 2020: s390x VM is down due to weather and power issues
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
with:
egress-policy: audit
allowed-endpoints: ci-s390x.caddyserver.com:22
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Run Tests
run: |
set +e
@@ -170,7 +191,7 @@ jobs:
retries=3
exit_code=0
while ((retries > 0)); do
CGO_ENABLED=0 go test -p 1 -tags nobadger,nomysql,nopgx -v ./...
CGO_ENABLED=0 go test -p 1 -v ./...
exit_code=$?
if ((exit_code == 0)); then
break
@@ -194,25 +215,33 @@ jobs:
goreleaser-check:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
if: github.event.pull_request.head.repo.full_name == 'caddyserver/caddy' && github.actor != 'dependabot[bot]'
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
with:
egress-policy: audit
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: goreleaser/goreleaser-action@v6
- uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0
with:
version: latest
args: check
- name: Install Go
uses: actions/setup-go@v5
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
with:
go-version: "~1.24"
go-version: "~1.25"
check-latest: true
- name: Install xcaddy
run: |
go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest
xcaddy version
- uses: goreleaser/goreleaser-action@v6
- uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0
with:
version: latest
args: build --single-target --snapshot
+19 -8
View File
@@ -11,9 +11,14 @@ on:
- 2.*
env:
GOFLAGS: '-tags=nobadger,nomysql,nopgx'
CGO_ENABLED: '0'
# https://github.com/actions/setup-go/issues/491
GOTOOLCHAIN: local
permissions:
contents: read
jobs:
build:
strategy:
@@ -31,22 +36,30 @@ jobs:
- 'darwin'
- 'netbsd'
go:
- '1.24'
- '1.25'
include:
# Set the minimum Go patch version for the given Go minor
# Usable via ${{ matrix.GO_SEMVER }}
- go: '1.24'
GO_SEMVER: '~1.24.1'
- go: '1.25'
GO_SEMVER: '~1.25.0'
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
continue-on-error: true
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
with:
egress-policy: audit
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Install Go
uses: actions/setup-go@v5
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
with:
go-version: ${{ matrix.GO_SEMVER }}
check-latest: true
@@ -63,11 +76,9 @@ jobs:
- name: Run Build
env:
CGO_ENABLED: 0
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goos == 'aix' && 'ppc64' || 'amd64' }}
shell: bash
continue-on-error: true
working-directory: ./cmd/caddy
run: |
GOOS=$GOOS GOARCH=$GOARCH go build -tags=nobadger,nomysql,nopgx -trimpath -o caddy-"$GOOS"-$GOARCH 2> /dev/null
run: go build -trimpath -o caddy-"$GOOS"-$GOARCH 2> /dev/null
+41 -7
View File
@@ -44,14 +44,19 @@ jobs:
runs-on: ${{ matrix.OS_LABEL }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
with:
go-version: '~1.24'
egress-policy: audit
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
with:
go-version: '~1.25'
check-latest: true
- name: golangci-lint
uses: golangci/golangci-lint-action@v6
uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v8.0.0
with:
version: latest
@@ -62,10 +67,39 @@ jobs:
# only-new-issues: true
govulncheck:
permissions:
contents: read
pull-requests: read
runs-on: ubuntu-latest
steps:
- name: govulncheck
uses: golang/govulncheck-action@v1
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
with:
go-version-input: '~1.24.1'
egress-policy: audit
- name: govulncheck
uses: golang/govulncheck-action@b625fbe08f3bccbe446d94fbf87fcc875a4f50ee # v1.0.4
with:
go-version-input: '~1.25.0'
check-latest: true
dependency-review:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
with:
egress-policy: audit
- name: 'Checkout Repository'
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: 'Dependency Review'
uses: actions/dependency-review-action@56339e523c0409420f6c2c9a2f4292bbb3c07dd3 # v4.8.0
with:
comment-summary-in-pr: on-failure
# https://github.com/actions/dependency-review-action/issues/430#issuecomment-1468975566
base-ref: ${{ github.event.pull_request.base.sha || 'master' }}
head-ref: ${{ github.event.pull_request.head.sha || github.ref }}
+249
View File
@@ -0,0 +1,249 @@
name: Release Proposal
# This workflow creates a release proposal as a PR that requires approval from maintainers
# Triggered manually by maintainers when ready to prepare a release
on:
workflow_dispatch:
inputs:
version:
description: 'Version to release (e.g., v2.8.0)'
required: true
type: string
commit_hash:
description: 'Commit hash to release from'
required: true
type: string
permissions:
contents: read
jobs:
create-proposal:
name: Create Release Proposal
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
issues: write
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
with:
egress-policy: audit
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
fetch-depth: 0
- name: Trim and validate inputs
id: inputs
run: |
# Trim whitespace from inputs
VERSION=$(echo "${{ inputs.version }}" | xargs)
COMMIT_HASH=$(echo "${{ inputs.commit_hash }}" | xargs)
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "commit_hash=$COMMIT_HASH" >> $GITHUB_OUTPUT
# Validate version format
if [[ ! "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$ ]]; then
echo "Error: Version must follow semver format (e.g., v2.8.0 or v2.8.0-beta.1)"
exit 1
fi
# Validate commit hash format
if [[ ! "$COMMIT_HASH" =~ ^[a-f0-9]{7,40}$ ]]; then
echo "Error: Commit hash must be a valid SHA (7-40 characters)"
exit 1
fi
# Check if commit exists
if ! git cat-file -e "$COMMIT_HASH"; then
echo "Error: Commit $COMMIT_HASH does not exist"
exit 1
fi
- name: Check if tag already exists
run: |
if git rev-parse "${{ steps.inputs.outputs.version }}" >/dev/null 2>&1; then
echo "Error: Tag ${{ steps.inputs.outputs.version }} already exists"
exit 1
fi
- name: Check for existing proposal PR
id: check_existing
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const version = '${{ steps.inputs.outputs.version }}';
// Search for existing open PRs with release-proposal label that match this version
const openPRs = await github.rest.pulls.list({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
sort: 'updated',
direction: 'desc'
});
const existingOpenPR = openPRs.data.find(pr =>
pr.title.includes(version) &&
pr.labels.some(label => label.name === 'release-proposal')
);
if (existingOpenPR) {
const hasReleased = existingOpenPR.labels.some(label => label.name === 'released');
const hasReleaseInProgress = existingOpenPR.labels.some(label => label.name === 'release-in-progress');
if (hasReleased || hasReleaseInProgress) {
core.setFailed(`A release for ${version} is already in progress or completed: ${existingOpenPR.html_url}`);
} else {
core.setFailed(`An open release proposal already exists for ${version}: ${existingOpenPR.html_url}\n\nPlease use the existing PR or close it first.`);
}
return;
}
// Check for closed PRs with this version that were cancelled
const closedPRs = await github.rest.pulls.list({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'closed',
sort: 'updated',
direction: 'desc'
});
const cancelledPR = closedPRs.data.find(pr =>
pr.title.includes(version) &&
pr.labels.some(label => label.name === 'release-proposal') &&
pr.labels.some(label => label.name === 'cancelled')
);
if (cancelledPR) {
console.log(`Found previously cancelled proposal for ${version}: ${cancelledPR.html_url}`);
console.log('Creating new proposal to replace cancelled one...');
} else {
console.log(`No existing proposal found for ${version}, proceeding...`);
}
- name: Generate changelog and create branch
id: setup
run: |
VERSION="${{ steps.inputs.outputs.version }}"
COMMIT_HASH="${{ steps.inputs.outputs.commit_hash }}"
# Create a new branch for the release proposal
BRANCH_NAME="release_proposal-$VERSION"
git checkout -b "$BRANCH_NAME"
# Calculate how many commits behind HEAD
COMMITS_BEHIND=$(git rev-list --count ${COMMIT_HASH}..HEAD)
if [ "$COMMITS_BEHIND" -eq 0 ]; then
BEHIND_INFO="This is the latest commit (HEAD)"
else
BEHIND_INFO="This commit is **${COMMITS_BEHIND} commits behind HEAD**"
fi
echo "commits_behind=$COMMITS_BEHIND" >> $GITHUB_OUTPUT
echo "behind_info=$BEHIND_INFO" >> $GITHUB_OUTPUT
# Get the last tag
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
if [ -z "$LAST_TAG" ]; then
echo "No previous tag found, generating full changelog"
COMMITS=$(git log --pretty=format:"- %s (%h)" --reverse "$COMMIT_HASH")
else
echo "Generating changelog since $LAST_TAG"
COMMITS=$(git log --pretty=format:"- %s (%h)" --reverse "${LAST_TAG}..$COMMIT_HASH")
fi
# Store changelog for PR body
CLEANSED_COMMITS=$(echo "$COMMITS" | sed 's/`/\\`/g')
echo "changelog<<EOF" >> $GITHUB_OUTPUT
echo "$CLEANSED_COMMITS" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
# Create empty commit for the PR
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git commit --allow-empty -m "Release proposal for $VERSION"
# Push the branch
git push origin "$BRANCH_NAME"
echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT
- name: Create release proposal PR
id: create_pr
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const changelog = `${{ steps.setup.outputs.changelog }}`;
const pr = await github.rest.pulls.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: `Release Proposal: ${{ steps.inputs.outputs.version }}`,
head: '${{ steps.setup.outputs.branch_name }}',
base: 'master',
body: `## Release Proposal: ${{ steps.inputs.outputs.version }}
**Target Commit:** \`${{ steps.inputs.outputs.commit_hash }}\`
**Requested by:** @${{ github.actor }}
**Commit Status:** ${{ steps.setup.outputs.behind_info }}
This PR proposes creating release tag \`${{ steps.inputs.outputs.version }}\` at commit \`${{ steps.inputs.outputs.commit_hash }}\`.
### Approval Process
This PR requires **approval from 2+ maintainers** before the tag can be created.
### What happens next?
1. Maintainers review this proposal
2. When 2+ maintainer approvals are received, an automated workflow will post tagging instructions
3. A maintainer manually creates and pushes the signed tag
4. The release workflow is triggered automatically by the tag push
5. Upon release completion, this PR is closed and the branch is deleted
### Changes Since Last Release
${changelog}
### Release Checklist
- [ ] All tests pass
- [ ] Security review completed
- [ ] Documentation updated
- [ ] Breaking changes documented
---
**Note:** Tag creation is manual and requires a signed tag from a maintainer.`,
draft: true
});
// Add labels
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.data.number,
labels: ['release-proposal', 'awaiting-approval']
});
console.log(`Created PR: ${pr.data.html_url}`);
return { number: pr.data.number, url: pr.data.html_url };
result-encoding: json
- name: Post summary
run: |
echo "## Release Proposal PR Created! 🚀" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Version: **${{ steps.inputs.outputs.version }}**" >> $GITHUB_STEP_SUMMARY
echo "Commit: **${{ steps.inputs.outputs.commit_hash }}**" >> $GITHUB_STEP_SUMMARY
echo "Status: ${{ steps.setup.outputs.behind_info }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "PR: ${{ fromJson(steps.create_pr.outputs.result).url }}" >> $GITHUB_STEP_SUMMARY
+402 -19
View File
@@ -9,21 +9,338 @@ env:
# https://github.com/actions/setup-go/issues/491
GOTOOLCHAIN: local
permissions:
contents: read
jobs:
verify-tag:
name: Verify Tag Signature and Approvals
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
issues: write
outputs:
verification_passed: ${{ steps.verify.outputs.passed }}
tag_version: ${{ steps.info.outputs.version }}
proposal_issue_number: ${{ steps.find_proposal.outputs.result && fromJson(steps.find_proposal.outputs.result).number || '' }}
steps:
- name: Checkout code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
fetch-depth: 0
# Force fetch upstream tags -- because 65 minutes
# tl;dr: actions/checkout@v3 runs this line:
# git -c protocol.version=2 fetch --no-tags --prune --progress --no-recurse-submodules --depth=1 origin +ebc278ec98bb24f2852b61fde2a9bf2e3d83818b:refs/tags/
# which makes its own local lightweight tag, losing all the annotations in the process. Our earlier script ran:
# git fetch --prune --unshallow
# which doesn't overwrite that tag because that would be destructive.
# Credit to @francislavoie for the investigation.
# https://github.com/actions/checkout/issues/290#issuecomment-680260080
- name: Force fetch upstream tags
run: git fetch --tags --force
- name: Get tag info
id: info
run: |
echo "version=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
# https://github.community/t5/GitHub-Actions/How-to-get-just-the-tag-name/m-p/32167/highlight/true#M1027
- name: Print Go version and environment
id: vars
run: |
printf "Using go at: $(which go)\n"
printf "Go version: $(go version)\n"
printf "\n\nGo environment:\n\n"
go env
printf "\n\nSystem environment:\n\n"
env
echo "version_tag=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_OUTPUT
echo "short_sha=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
# Add "pip install" CLI tools to PATH
echo ~/.local/bin >> $GITHUB_PATH
# Parse semver
TAG=${GITHUB_REF/refs\/tags\//}
SEMVER_RE='[^0-9]*\([0-9]*\)[.]\([0-9]*\)[.]\([0-9]*\)\([0-9A-Za-z\.-]*\)'
TAG_MAJOR=`echo ${TAG#v} | sed -e "s#$SEMVER_RE#\1#"`
TAG_MINOR=`echo ${TAG#v} | sed -e "s#$SEMVER_RE#\2#"`
TAG_PATCH=`echo ${TAG#v} | sed -e "s#$SEMVER_RE#\3#"`
TAG_SPECIAL=`echo ${TAG#v} | sed -e "s#$SEMVER_RE#\4#"`
echo "tag_major=${TAG_MAJOR}" >> $GITHUB_OUTPUT
echo "tag_minor=${TAG_MINOR}" >> $GITHUB_OUTPUT
echo "tag_patch=${TAG_PATCH}" >> $GITHUB_OUTPUT
echo "tag_special=${TAG_SPECIAL}" >> $GITHUB_OUTPUT
- name: Validate commits and tag signatures
id: verify
env:
signing_keys: ${{ secrets.SIGNING_KEYS }}
run: |
# Read the string into an array, splitting by IFS
IFS=";" read -ra keys_collection <<< "$signing_keys"
# ref: https://docs.github.com/en/actions/reference/workflows-and-actions/contexts#example-usage-of-the-runner-context
touch "${{ runner.temp }}/allowed_signers"
# Iterate and print the split elements
for item in "${keys_collection[@]}"; do
# trim leading whitespaces
item="${item##*( )}"
# trim trailing whitespaces
item="${item%%*( )}"
IFS=" " read -ra key_components <<< "$item"
# git wants it in format: email address, type, public key
# ssh has it in format: type, public key, email address
echo "${key_components[2]} namespaces=\"git\" ${key_components[0]} ${key_components[1]}" >> "${{ runner.temp }}/allowed_signers"
done
git config set --global gpg.ssh.allowedSignersFile "${{ runner.temp }}/allowed_signers"
echo "Verifying the tag: ${{ steps.vars.outputs.version_tag }}"
# Verify the tag is signed
if ! git verify-tag -v "${{ steps.vars.outputs.version_tag }}" 2>&1; then
echo "❌ Tag verification failed!"
echo "passed=false" >> $GITHUB_OUTPUT
git push --delete origin "${{ steps.vars.outputs.version_tag }}"
exit 1
fi
# Run it again to capture the output
git verify-tag -v "${{ steps.vars.outputs.version_tag }}" 2>&1 | tee /tmp/verify-output.txt;
# SSH verification output typically includes the key fingerprint
# Use GNU grep with Perl regex for cleaner extraction (Linux environment)
KEY_SHA256=$(grep -oP "SHA256:[\"']?\K[A-Za-z0-9+/=]+(?=[\"']?)" /tmp/verify-output.txt | head -1 || echo "")
if [ -z "$KEY_SHA256" ]; then
# Try alternative pattern with "key" prefix
KEY_SHA256=$(grep -oP "key SHA256:[\"']?\K[A-Za-z0-9+/=]+(?=[\"']?)" /tmp/verify-output.txt | head -1 || echo "")
fi
if [ -z "$KEY_SHA256" ]; then
# Fallback: extract any base64-like string (40+ chars)
KEY_SHA256=$(grep -oP '[A-Za-z0-9+/]{40,}=?' /tmp/verify-output.txt | head -1 || echo "")
fi
if [ -z "$KEY_SHA256" ]; then
echo "Somehow could not extract SSH key fingerprint from git verify-tag output"
echo "Cancelling flow and deleting tag"
echo "passed=false" >> $GITHUB_OUTPUT
git push --delete origin "${{ steps.vars.outputs.version_tag }}"
exit 1
fi
echo "✅ Tag verification succeeded!"
echo "passed=true" >> $GITHUB_OUTPUT
echo "key_id=$KEY_SHA256" >> $GITHUB_OUTPUT
- name: Find related release proposal
id: find_proposal
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const version = '${{ steps.vars.outputs.version_tag }}';
// Search for PRs with release-proposal label that match this version
const prs = await github.rest.pulls.list({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open', // Changed to 'all' to find both open and closed PRs
sort: 'updated',
direction: 'desc'
});
// Find the most recent PR for this version
const proposal = prs.data.find(pr =>
pr.title.includes(version) &&
pr.labels.some(label => label.name === 'release-proposal')
);
if (!proposal) {
console.log(`⚠️ No release proposal PR found for ${version}`);
console.log('This might be a hotfix or emergency release');
return { number: null, approved: true, approvals: 0, proposedCommit: null };
}
console.log(`Found proposal PR #${proposal.number} for version ${version}`);
// Extract commit hash from PR body
const commitMatch = proposal.body.match(/\*\*Target Commit:\*\*\s*`([a-f0-9]+)`/);
const proposedCommit = commitMatch ? commitMatch[1] : null;
if (proposedCommit) {
console.log(`Proposal was for commit: ${proposedCommit}`);
} else {
console.log('⚠️ No target commit hash found in PR body');
}
// Get PR reviews to extract approvers
let approvers = 'Validated by automation';
let approvalCount = 2; // Minimum required
try {
const reviews = await github.rest.pulls.listReviews({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: proposal.number
});
// Get latest review per user and filter for approvals
const latestReviewsByUser = {};
reviews.data.forEach(review => {
const username = review.user.login;
if (!latestReviewsByUser[username] || new Date(review.submitted_at) > new Date(latestReviewsByUser[username].submitted_at)) {
latestReviewsByUser[username] = review;
}
});
const approvalReviews = Object.values(latestReviewsByUser).filter(review =>
review.state === 'APPROVED'
);
if (approvalReviews.length > 0) {
approvers = approvalReviews.map(r => '@' + r.user.login).join(', ');
approvalCount = approvalReviews.length;
console.log(`Found ${approvalCount} approvals from: ${approvers}`);
}
} catch (error) {
console.log(`Could not fetch reviews: ${error.message}`);
}
return {
number: proposal.number,
approved: true,
approvals: approvalCount,
approvers: approvers,
proposedCommit: proposedCommit
};
result-encoding: json
- name: Verify proposal commit
run: |
APPROVALS='${{ steps.find_proposal.outputs.result }}'
# Parse JSON
PROPOSED_COMMIT=$(echo "$APPROVALS" | jq -r '.proposedCommit')
CURRENT_COMMIT="${{ steps.info.outputs.sha }}"
echo "Proposed commit: $PROPOSED_COMMIT"
echo "Current commit: $CURRENT_COMMIT"
# Check if commits match (if proposal had a target commit)
if [ "$PROPOSED_COMMIT" != "null" ] && [ -n "$PROPOSED_COMMIT" ]; then
# Normalize both commits to full SHA for comparison
PROPOSED_FULL=$(git rev-parse "$PROPOSED_COMMIT" 2>/dev/null || echo "")
CURRENT_FULL=$(git rev-parse "$CURRENT_COMMIT" 2>/dev/null || echo "")
if [ -z "$PROPOSED_FULL" ]; then
echo "⚠️ Could not resolve proposed commit: $PROPOSED_COMMIT"
elif [ "$PROPOSED_FULL" != "$CURRENT_FULL" ]; then
echo "❌ Commit mismatch!"
echo "The tag points to commit $CURRENT_FULL but the proposal was for $PROPOSED_FULL"
echo "This indicates an error in tag creation."
# Delete the tag remotely
git push --delete origin "${{ steps.vars.outputs.version_tag }}"
echo "Tag ${{steps.vars.outputs.version_tag}} has been deleted"
exit 1
else
echo "✅ Commit hash matches proposal"
fi
else
echo "⚠️ No target commit found in proposal (might be legacy release)"
fi
echo "✅ Tag verification completed"
- name: Update release proposal PR
if: fromJson(steps.find_proposal.outputs.result).number != null
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const result = ${{ steps.find_proposal.outputs.result }};
if (result.number) {
// Add in-progress label
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: result.number,
labels: ['release-in-progress']
});
// Remove approved label if present
try {
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: result.number,
name: 'approved'
});
} catch (e) {
console.log('Approved label not found:', e.message);
}
const commentBody = [
'## 🚀 Release Workflow Started',
'',
'- **Tag:** ${{ steps.info.outputs.version }}',
'- **Signed by key:** ${{ steps.verify.outputs.key_id }}',
'- **Commit:** ${{ steps.info.outputs.sha }}',
'- **Approved by:** ' + result.approvers,
'',
'Release workflow is now running. This PR will be updated when the release is published.'
].join('\n');
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: result.number,
body: commentBody
});
}
- name: Summary
run: |
APPROVALS='${{ steps.find_proposal.outputs.result }}'
PROPOSED_COMMIT=$(echo "$APPROVALS" | jq -r '.proposedCommit // "N/A"')
APPROVERS=$(echo "$APPROVALS" | jq -r '.approvers // "N/A"')
echo "## Tag Verification Summary 🔐" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- **Tag:** ${{ steps.info.outputs.version }}" >> $GITHUB_STEP_SUMMARY
echo "- **Commit:** ${{ steps.info.outputs.sha }}" >> $GITHUB_STEP_SUMMARY
echo "- **Proposed Commit:** $PROPOSED_COMMIT" >> $GITHUB_STEP_SUMMARY
echo "- **Signature:** ✅ Verified" >> $GITHUB_STEP_SUMMARY
echo "- **Signed by:** ${{ steps.verify.outputs.key_id }}" >> $GITHUB_STEP_SUMMARY
echo "- **Approvals:** ✅ Sufficient" >> $GITHUB_STEP_SUMMARY
echo "- **Approved by:** $APPROVERS" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Proceeding with release build..." >> $GITHUB_STEP_SUMMARY
release:
name: Release
needs: verify-tag
if: ${{ needs.verify-tag.outputs.verification_passed == 'true' }}
strategy:
matrix:
os:
- ubuntu-latest
go:
- '1.24'
- '1.25'
include:
# Set the minimum Go patch version for the given Go minor
# Usable via ${{ matrix.GO_SEMVER }}
- go: '1.24'
GO_SEMVER: '~1.24.1'
- go: '1.25'
GO_SEMVER: '~1.25.0'
runs-on: ${{ matrix.os }}
# https://github.com/sigstore/cosign/issues/1258#issuecomment-1002251233
@@ -33,21 +350,28 @@ jobs:
# https://docs.github.com/en/rest/overview/permissions-required-for-github-apps#permission-on-contents
# "Releases" is part of `contents`, so it needs the `write`
contents: write
issues: write
pull-requests: write
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
with:
egress-policy: audit
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
fetch-depth: 0
- name: Install Go
uses: actions/setup-go@v5
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
with:
go-version: ${{ matrix.GO_SEMVER }}
check-latest: true
# Force fetch upstream tags -- because 65 minutes
# tl;dr: actions/checkout@v4 runs this line:
# tl;dr: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4.2.2 runs this line:
# git -c protocol.version=2 fetch --no-tags --prune --progress --no-recurse-submodules --depth=1 origin +ebc278ec98bb24f2852b61fde2a9bf2e3d83818b:refs/tags/
# which makes its own local lightweight tag, losing all the annotations in the process. Our earlier script ran:
# git fetch --prune --unshallow
@@ -90,22 +414,12 @@ jobs:
- name: Install Cloudsmith CLI
run: pip install --upgrade cloudsmith-cli
- name: Validate commits and tag signatures
run: |
# Import Matt Holt's key
curl 'https://github.com/mholt.gpg' | gpg --import
echo "Verifying the tag: ${{ steps.vars.outputs.version_tag }}"
# tags are only accepted if signed by Matt's key
git verify-tag "${{ steps.vars.outputs.version_tag }}" || exit 1
- name: Install Cosign
uses: sigstore/cosign-installer@main
uses: sigstore/cosign-installer@d7543c93d881b35a8faa02e8e3605f69b7a1ce62 # main
- name: Cosign version
run: cosign version
- name: Install Syft
uses: anchore/sbom-action/download-syft@main
uses: anchore/sbom-action/download-syft@f8bdd1d8ac5e901a77a92f111440fdb1b593736b # main
- name: Syft version
run: syft version
- name: Install xcaddy
@@ -114,7 +428,7 @@ jobs:
xcaddy version
# GoReleaser will take care of publishing those artifacts into the release
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v6
uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0
with:
version: latest
args: release --clean --timeout 60m
@@ -180,3 +494,72 @@ jobs:
echo "Pushing $filename to 'testing'"
cloudsmith push deb caddy/testing/any-distro/any-version $filename
done
- name: Update release proposal PR
if: needs.verify-tag.outputs.proposal_issue_number != ''
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const prNumber = parseInt('${{ needs.verify-tag.outputs.proposal_issue_number }}');
if (prNumber) {
// Get PR details to find the branch
const pr = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber
});
const branchName = pr.data.head.ref;
// Remove in-progress label
try {
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
name: 'release-in-progress'
});
} catch (e) {
console.log('Label not found:', e.message);
}
// Add released label
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
labels: ['released']
});
// Add final comment
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: '## ✅ Release Published\n\nThe release has been successfully published and is now available.'
});
// Close the PR if it's still open
if (pr.data.state === 'open') {
await github.rest.pulls.update({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber,
state: 'closed'
});
console.log(`Closed PR #${prNumber}`);
}
// Delete the branch
try {
await github.rest.git.deleteRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: `heads/${branchName}`
});
console.log(`Deleted branch: ${branchName}`);
} catch (e) {
console.log(`Could not delete branch ${branchName}: ${e.message}`);
}
}
+14 -3
View File
@@ -5,6 +5,9 @@ on:
release:
types: [published]
permissions:
contents: read
jobs:
release:
name: Release Published
@@ -13,12 +16,20 @@ jobs:
os:
- ubuntu-latest
runs-on: ${{ matrix.os }}
permissions:
contents: read
pull-requests: read
actions: write
steps:
# See https://github.com/peter-evans/repository-dispatch
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
with:
egress-policy: audit
- name: Trigger event on caddyserver/dist
uses: peter-evans/repository-dispatch@v3
uses: peter-evans/repository-dispatch@5fc4efd1a4797ddb68ffd0714a238564e4cc0e6f # v4.0.0
with:
token: ${{ secrets.REPO_DISPATCH_TOKEN }}
repository: caddyserver/dist
@@ -26,7 +37,7 @@ jobs:
client-payload: '{"tag": "${{ github.event.release.tag_name }}"}'
- name: Trigger event on caddyserver/caddy-docker
uses: peter-evans/repository-dispatch@v3
uses: peter-evans/repository-dispatch@5fc4efd1a4797ddb68ffd0714a238564e4cc0e6f # v4.0.0
with:
token: ${{ secrets.REPO_DISPATCH_TOKEN }}
repository: caddyserver/caddy-docker
+86
View File
@@ -0,0 +1,86 @@
# This workflow uses actions that are not certified by GitHub. They are provided
# by a third-party and are governed by separate terms of service, privacy
# policy, and support documentation.
name: OpenSSF Scorecard supply-chain security
on:
# For Branch-Protection check. Only the default branch is supported. See
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
branch_protection_rule:
# To guarantee Maintained check is occasionally updated. See
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
schedule:
- cron: '20 2 * * 5'
push:
branches: [ "master", "2.*" ]
pull_request:
branches: [ "master", "2.*" ]
# Declare default permissions as read only.
permissions: read-all
jobs:
analysis:
name: Scorecard analysis
runs-on: ubuntu-latest
# `publish_results: true` only works when run from the default branch. conditional can be removed if disabled.
if: github.event.repository.default_branch == github.ref_name || github.event_name == 'pull_request'
permissions:
# Needed to upload the results to code-scanning dashboard.
security-events: write
# Needed to publish results and get a badge (see publish_results below).
id-token: write
# Uncomment the permissions below if installing in a private repository.
# contents: read
# actions: read
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
with:
egress-policy: audit
- name: "Checkout code"
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- name: "Run analysis"
uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
with:
results_file: results.sarif
results_format: sarif
# (Optional) "write" PAT token. Uncomment the `repo_token` line below if:
# - you want to enable the Branch-Protection check on a *public* repository, or
# - you are installing Scorecard on a *private* repository
# To create the PAT, follow the steps in https://github.com/ossf/scorecard-action?tab=readme-ov-file#authentication-with-fine-grained-pat-optional.
# repo_token: ${{ secrets.SCORECARD_TOKEN }}
# Public repositories:
# - Publish results to OpenSSF REST API for easy access by consumers
# - Allows the repository to include the Scorecard badge.
# - See https://github.com/ossf/scorecard-action#publishing-results.
# For private repositories:
# - `publish_results` will always be set to `false`, regardless
# of the value entered here.
publish_results: true
# (Optional) Uncomment file_mode if you have a .gitattributes with files marked export-ignore
# file_mode: git
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: SARIF file
path: results.sarif
retention-days: 5
# Upload the results to GitHub's code scanning dashboard (optional).
# Commenting out will disable upload of results to your repo's Code Scanning dashboard
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@3599b3baa15b485a2e49ef411a7a4bb2452e7f93 # v3.29.5
with:
sarif_file: results.sarif
+91 -151
View File
@@ -1,27 +1,19 @@
linters-settings:
errcheck:
exclude-functions:
- fmt.*
- (go.uber.org/zap/zapcore.ObjectEncoder).AddObject
- (go.uber.org/zap/zapcore.ObjectEncoder).AddArray
gci:
sections:
- standard # Standard section: captures all standard packages.
- default # Default section: contains all imports that could not be matched to another section type.
- prefix(github.com/caddyserver/caddy/v2/cmd) # ensure that this is always at the top and always has a line break.
- prefix(github.com/caddyserver/caddy) # Custom section: groups all imports with the specified Prefix.
# Skip generated files.
# Default: true
skip-generated: true
# Enable custom order of sections.
# If `true`, make the section order the same as the order of `sections`.
# Default: false
custom-order: true
exhaustive:
ignore-enum-types: reflect.Kind|svc.Cmd
version: "2"
run:
issues-exit-code: 1
tests: false
build-tags:
- nobadger
- nomysql
- nopgx
output:
formats:
text:
path: stdout
print-linter-name: true
print-issued-lines: true
linters:
disable-all: true
default: none
enable:
- asasalint
- asciicheck
@@ -35,148 +27,96 @@ linters:
- errcheck
- errname
- exhaustive
- gci
- gofmt
- goimports
- gofumpt
- gosec
- gosimple
- govet
- ineffassign
- importas
- ineffassign
- misspell
- prealloc
- promlinter
- sloglint
- sqlclosecheck
- staticcheck
- tenv
- testableexamples
- testifylint
- tparallel
- typecheck
- unconvert
- unused
- wastedassign
- whitespace
- zerologlint
# these are implicitly disabled:
# - containedctx
# - contextcheck
# - cyclop
# - depguard
# - errchkjson
# - errorlint
# - exhaustruct
# - execinquery
# - exhaustruct
# - forbidigo
# - forcetypeassert
# - funlen
# - ginkgolinter
# - gocheckcompilerdirectives
# - gochecknoglobals
# - gochecknoinits
# - gochecksumtype
# - gocognit
# - goconst
# - gocritic
# - gocyclo
# - godot
# - godox
# - goerr113
# - goheader
# - gomnd
# - gomoddirectives
# - gomodguard
# - goprintffuncname
# - gosmopolitan
# - grouper
# - inamedparam
# - interfacebloat
# - ireturn
# - lll
# - loggercheck
# - maintidx
# - makezero
# - mirror
# - musttag
# - nakedret
# - nestif
# - nilerr
# - nilnil
# - nlreturn
# - noctx
# - nolintlint
# - nonamedreturns
# - nosprintfhostport
# - paralleltest
# - perfsprint
# - predeclared
# - protogetter
# - reassign
# - revive
# - rowserrcheck
# - stylecheck
# - tagalign
# - tagliatelle
# - testpackage
# - thelper
# - unparam
# - usestdlibvars
# - varnamelen
# - wrapcheck
# - wsl
run:
# default concurrency is a available CPU number.
# concurrency: 4 # explicitly omit this value to fully utilize available resources.
timeout: 5m
issues-exit-code: 1
tests: false
# output configuration options
output:
formats:
- format: 'colored-line-number'
print-issued-lines: true
print-linter-name: true
issues:
exclude-rules:
- text: 'G115' # TODO: Either we should fix the issues or nuke the linter if it's bad
linters:
- gosec
# we aren't calling unknown URL
- text: 'G107' # G107: Url provided to HTTP request as taint input
linters:
- gosec
# as a web server that's expected to handle any template, this is totally in the hands of the user.
- text: 'G203' # G203: Use of unescaped data in HTML templates
linters:
- gosec
# we're shelling out to known commands, not relying on user-defined input.
- text: 'G204' # G204: Audit use of command execution
linters:
- gosec
# the choice of weakrand is deliberate, hence the named import "weakrand"
- path: modules/caddyhttp/reverseproxy/selectionpolicies.go
text: 'G404' # G404: Insecure random number source (rand)
linters:
- gosec
- path: modules/caddyhttp/reverseproxy/streaming.go
text: 'G404' # G404: Insecure random number source (rand)
linters:
- gosec
- path: modules/logging/filters.go
linters:
- dupl
- path: modules/caddyhttp/matchers.go
linters:
- dupl
- path: modules/caddyhttp/vars.go
linters:
- dupl
- path: _test\.go
linters:
- errcheck
settings:
staticcheck:
checks: ["all", "-ST1000", "-ST1003", "-ST1016", "-ST1020", "-ST1021", "-ST1022", "-QF1006", "-QF1008"] # default, and exclude 1 more undesired check
errcheck:
exclude-functions:
- fmt.*
- (go.uber.org/zap/zapcore.ObjectEncoder).AddObject
- (go.uber.org/zap/zapcore.ObjectEncoder).AddArray
exhaustive:
ignore-enum-types: reflect.Kind|svc.Cmd
exclusions:
generated: lax
presets:
- comments
- common-false-positives
- legacy
- std-error-handling
rules:
- linters:
- gosec
text: G115 # TODO: Either we should fix the issues or nuke the linter if it's bad
- linters:
- gosec
text: G107 # we aren't calling unknown URL
- linters:
- gosec
text: G203 # as a web server that's expected to handle any template, this is totally in the hands of the user.
- linters:
- gosec
text: G204 # we're shelling out to known commands, not relying on user-defined input.
- linters:
- gosec
# the choice of weakrand is deliberate, hence the named import "weakrand"
path: modules/caddyhttp/reverseproxy/selectionpolicies.go
text: G404
- linters:
- gosec
path: modules/caddyhttp/reverseproxy/streaming.go
text: G404
- linters:
- dupl
path: modules/logging/filters.go
- linters:
- dupl
path: modules/caddyhttp/matchers.go
- linters:
- dupl
path: modules/caddyhttp/vars.go
- linters:
- errcheck
path: _test\.go
paths:
- third_party$
- builtin$
- examples$
formatters:
enable:
- gci
- gofmt
- gofumpt
- goimports
settings:
gci:
sections:
- standard # Standard section: captures all standard packages.
- default # Default section: contains all imports that could not be matched to another section type.
- prefix(github.com/caddyserver/caddy/v2/cmd) # ensure that this is always at the top and always has a line break.
- prefix(github.com/caddyserver/caddy) # Custom section: groups all imports with the specified Prefix.
custom-order: true
exclusions:
generated: lax
paths:
- third_party$
- builtin$
- examples$
+20
View File
@@ -0,0 +1,20 @@
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.16.3
hooks:
- id: gitleaks
- repo: https://github.com/golangci/golangci-lint
rev: v1.52.2
hooks:
- id: golangci-lint-config-verify
- id: golangci-lint
- id: golangci-lint-fmt
- repo: https://github.com/jumanjihouse/pre-commit-hooks
rev: 3.0.0
hooks:
- id: shellcheck
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: end-of-file-fixer
- id: trailing-whitespace
+2 -1
View File
@@ -14,6 +14,7 @@
<p align="center">Caddy is an extensible server platform that uses TLS by default.</p>
<p align="center">
<a href="https://github.com/caddyserver/caddy/actions/workflows/ci.yml"><img src="https://github.com/caddyserver/caddy/actions/workflows/ci.yml/badge.svg"></a>
<a href="https://www.bestpractices.dev/projects/7141"><img src="https://www.bestpractices.dev/projects/7141/badge"></a>
<a href="https://pkg.go.dev/github.com/caddyserver/caddy/v2"><img src="https://img.shields.io/badge/godoc-reference-%23007d9c.svg"></a>
<br>
<a href="https://x.com/caddyserver" title="@caddyserver on Twitter"><img src="https://img.shields.io/twitter/follow/caddyserver" alt="@caddyserver on Twitter"></a>
@@ -88,7 +89,7 @@ See [our online documentation](https://caddyserver.com/docs/install) for other i
Requirements:
- [Go 1.24.0 or newer](https://golang.org/dl/)
- [Go 1.25.0 or newer](https://golang.org/dl/)
### For development
+8 -1
View File
@@ -946,7 +946,7 @@ func (h adminHandler) originAllowed(origin *url.URL) bool {
return false
}
// etagHasher returns a the hasher we used on the config to both
// etagHasher returns the hasher we used on the config to both
// produce and verify ETags.
func etagHasher() hash.Hash { return xxhash.New() }
@@ -1029,6 +1029,13 @@ func handleConfig(w http.ResponseWriter, r *http.Request) error {
return err
}
// If this request changed the config, clear the last
// config info we have stored, if it is different from
// the original source.
ClearLastConfigIfDifferent(
r.Header.Get("Caddy-Config-Source-File"),
r.Header.Get("Caddy-Config-Source-Adapter"))
default:
return APIError{
HTTPStatus: http.StatusMethodNotAllowed,
+8 -17
View File
@@ -19,6 +19,7 @@ import (
"crypto/x509"
"encoding/json"
"fmt"
"maps"
"net/http"
"net/http/httptest"
"reflect"
@@ -148,11 +149,9 @@ func TestLoadConcurrent(t *testing.T) {
var wg sync.WaitGroup
for i := 0; i < 100; i++ {
wg.Add(1)
go func() {
wg.Go(func() {
_ = Load(testCfg, true)
wg.Done()
}()
})
}
wg.Wait()
}
@@ -206,7 +205,7 @@ func TestETags(t *testing.T) {
}
func BenchmarkLoad(b *testing.B) {
for i := 0; i < b.N; i++ {
for b.Loop() {
Load(testCfg, true)
}
}
@@ -335,9 +334,7 @@ func TestAdminHandlerBuiltinRouteErrors(t *testing.T) {
func testGetMetricValue(labels map[string]string) float64 {
promLabels := prometheus.Labels{}
for k, v := range labels {
promLabels[k] = v
}
maps.Copy(promLabels, labels)
metric, err := adminMetrics.requestErrors.GetMetricWith(promLabels)
if err != nil {
@@ -377,9 +374,7 @@ func (m *mockModule) CaddyModule() ModuleInfo {
func TestNewAdminHandlerRouterRegistration(t *testing.T) {
originalModules := make(map[string]ModuleInfo)
for k, v := range modules {
originalModules[k] = v
}
maps.Copy(originalModules, modules)
defer func() {
modules = originalModules
}()
@@ -479,9 +474,7 @@ func TestAdminRouterProvisioning(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
originalModules := make(map[string]ModuleInfo)
for k, v := range modules {
originalModules[k] = v
}
maps.Copy(originalModules, modules)
defer func() {
modules = originalModules
}()
@@ -774,9 +767,7 @@ func (m *mockIssuerModule) CaddyModule() ModuleInfo {
func TestManageIdentity(t *testing.T) {
originalModules := make(map[string]ModuleInfo)
for k, v := range modules {
originalModules[k] = v
}
maps.Copy(originalModules, modules)
defer func() {
modules = originalModules
}()
+115 -8
View File
@@ -81,7 +81,10 @@ type Config struct {
// associated value.
AppsRaw ModuleMap `json:"apps,omitempty" caddy:"namespace="`
apps map[string]App
apps map[string]App
// failedApps is a map of apps that failed to provision with their underlying error.
failedApps map[string]error
storage certmagic.Storage
eventEmitter eventEmitter
@@ -408,11 +411,23 @@ func run(newCfg *Config, start bool) (Context, error) {
return ctx, nil
}
defer func() {
// if newCfg fails to start completely, clean up the already provisioned modules
// partially copied from provisionContext
if err != nil {
globalMetrics.configSuccess.Set(0)
ctx.cfg.cancelFunc()
if currentCtx.cfg != nil {
certmagic.Default.Storage = currentCtx.cfg.storage
}
}
}()
// Provision any admin routers which may need to access
// some of the other apps at runtime
err = ctx.cfg.Admin.provisionAdminRouters(ctx)
if err != nil {
globalMetrics.configSuccess.Set(0)
return ctx, err
}
@@ -438,7 +453,6 @@ func run(newCfg *Config, start bool) (Context, error) {
return nil
}()
if err != nil {
globalMetrics.configSuccess.Set(0)
return ctx, err
}
globalMetrics.configSuccess.Set(1)
@@ -449,7 +463,8 @@ func run(newCfg *Config, start bool) (Context, error) {
// now that the user's config is running, finish setting up anything else,
// such as remote admin endpoint, config loader, etc.
return ctx, finishSettingUp(ctx, ctx.cfg)
err = finishSettingUp(ctx, ctx.cfg)
return ctx, err
}
// provisionContext creates a new context from the given configuration and provisions
@@ -510,6 +525,7 @@ func provisionContext(newCfg *Config, replaceAdminServer bool) (Context, error)
// prepare the new config for use
newCfg.apps = make(map[string]App)
newCfg.failedApps = make(map[string]error)
// set up global storage and make it CertMagic's default storage, too
err = func() error {
@@ -959,11 +975,11 @@ func Version() (simple, full string) {
if CustomVersion != "" {
full = CustomVersion
simple = CustomVersion
return
return simple, full
}
full = "unknown"
simple = "unknown"
return
return simple, full
}
// find the Caddy module in the dependency list
for _, dep := range bi.Deps {
@@ -1043,7 +1059,7 @@ func Version() (simple, full string) {
}
}
return
return simple, full
}
// Event represents something that has happened or is happening.
@@ -1104,9 +1120,15 @@ func (e Event) Origin() Module { return e.origin } // Returns the module t
// CloudEvents spec.
func (e Event) CloudEvent() CloudEvent {
dataJSON, _ := json.Marshal(e.Data)
var source string
if e.Origin() == nil {
source = "caddy"
} else {
source = string(e.Origin().CaddyModule().ID)
}
return CloudEvent{
ID: e.id.String(),
Source: e.origin.CaddyModule().String(),
Source: source,
SpecVersion: "1.0",
Type: e.name,
Time: e.ts,
@@ -1175,6 +1197,91 @@ var (
rawCfgMu sync.RWMutex
)
// lastConfigFile and lastConfigAdapter remember the source config
// file and adapter used when Caddy was started via the CLI "run" command.
// These are consulted by the SIGUSR1 handler to attempt reloading from
// the same source. They are intentionally not set for other entrypoints
// such as "caddy start" or subcommands like file-server.
var (
lastConfigMu sync.RWMutex
lastConfigFile string
lastConfigAdapter string
)
// reloadFromSourceFunc is the type of stored callback
// which is called when we receive a SIGUSR1 signal.
type reloadFromSourceFunc func(file, adapter string) error
// reloadFromSourceCallback is the stored callback
// which is called when we receive a SIGUSR1 signal.
var reloadFromSourceCallback reloadFromSourceFunc
// errReloadFromSourceUnavailable is returned when no reload-from-source callback is set.
var errReloadFromSourceUnavailable = errors.New("reload from source unavailable in this process") //nolint:unused
// SetLastConfig records the given source file and adapter as the
// last-known external configuration source. Intended to be called
// only when starting via "caddy run --config <file> --adapter <adapter>".
func SetLastConfig(file, adapter string, fn reloadFromSourceFunc) {
lastConfigMu.Lock()
lastConfigFile = file
lastConfigAdapter = adapter
reloadFromSourceCallback = fn
lastConfigMu.Unlock()
}
// ClearLastConfigIfDifferent clears the recorded last-config if the provided
// source file/adapter do not match the recorded last-config. If both srcFile
// and srcAdapter are empty, the last-config is cleared.
func ClearLastConfigIfDifferent(srcFile, srcAdapter string) {
if (srcFile != "" || srcAdapter != "") && lastConfigMatches(srcFile, srcAdapter) {
return
}
SetLastConfig("", "", nil)
}
// getLastConfig returns the last-known config file and adapter.
func getLastConfig() (file, adapter string, fn reloadFromSourceFunc) {
lastConfigMu.RLock()
f, a, cb := lastConfigFile, lastConfigAdapter, reloadFromSourceCallback
lastConfigMu.RUnlock()
return f, a, cb
}
// lastConfigMatches returns true if the provided source file and/or adapter
// matches the recorded last-config. Matching rules (in priority order):
// 1. If srcAdapter is provided and differs from the recorded adapter, no match.
// 2. If srcFile exactly equals the recorded file, match.
// 3. If both sides can be made absolute and equal, match.
// 4. If basenames are equal, match.
func lastConfigMatches(srcFile, srcAdapter string) bool {
lf, la, _ := getLastConfig()
// If adapter is provided, it must match.
if srcAdapter != "" && srcAdapter != la {
return false
}
// Quick equality check.
if srcFile == lf {
return true
}
// Try absolute path comparison.
sAbs, sErr := filepath.Abs(srcFile)
lAbs, lErr := filepath.Abs(lf)
if sErr == nil && lErr == nil && sAbs == lAbs {
return true
}
// Final fallback: basename equality.
if filepath.Base(srcFile) == filepath.Base(lf) {
return true
}
return false
}
// errSameConfig is returned if the new config is the same
// as the old one. This isn't usually an actual, actionable
// error; it's mostly a sentinel value.
+19
View File
@@ -15,6 +15,7 @@
package caddy
import (
"context"
"testing"
"time"
)
@@ -72,3 +73,21 @@ func TestParseDuration(t *testing.T) {
}
}
}
func TestEvent_CloudEvent_NilOrigin(t *testing.T) {
ctx, _ := NewContext(Context{Context: context.Background()}) // module will be nil by default
event, err := NewEvent(ctx, "started", nil)
if err != nil {
t.Fatalf("NewEvent() error = %v", err)
}
// This should not panic
ce := event.CloudEvent()
if ce.Source != "caddy" {
t.Errorf("Expected CloudEvent Source to be 'caddy', got '%s'", ce.Source)
}
if ce.Type != "started" {
t.Errorf("Expected CloudEvent Type to be 'started', got '%s'", ce.Type)
}
}
+1 -1
View File
@@ -68,7 +68,7 @@ func (a Adapter) Adapt(body []byte, options map[string]any) ([]byte, []caddyconf
// TODO: also perform this check on imported files
func FormattingDifference(filename string, body []byte) (caddyconfig.Warning, bool) {
// replace windows-style newlines to normalize comparison
normalizedBody := bytes.Replace(body, []byte("\r\n"), []byte("\n"), -1)
normalizedBody := bytes.ReplaceAll(body, []byte("\r\n"), []byte("\n"))
formatted := Format(normalizedBody)
if bytes.Equal(formatted, normalizedBody) {
+18 -6
View File
@@ -308,9 +308,9 @@ func (d *Dispenser) CountRemainingArgs() int {
}
// RemainingArgs loads any more arguments (tokens on the same line)
// into a slice and returns them. Open curly brace tokens also indicate
// the end of arguments, and the curly brace is not included in
// the return value nor is it loaded.
// into a slice of strings and returns them. Open curly brace tokens
// also indicate the end of arguments, and the curly brace is not
// included in the return value nor is it loaded.
func (d *Dispenser) RemainingArgs() []string {
var args []string
for d.NextArg() {
@@ -320,9 +320,9 @@ func (d *Dispenser) RemainingArgs() []string {
}
// RemainingArgsRaw loads any more arguments (tokens on the same line,
// retaining quotes) into a slice and returns them. Open curly brace
// tokens also indicate the end of arguments, and the curly brace is
// not included in the return value nor is it loaded.
// retaining quotes) into a slice of strings and returns them.
// Open curly brace tokens also indicate the end of arguments,
// and the curly brace is not included in the return value nor is it loaded.
func (d *Dispenser) RemainingArgsRaw() []string {
var args []string
for d.NextArg() {
@@ -331,6 +331,18 @@ func (d *Dispenser) RemainingArgsRaw() []string {
return args
}
// RemainingArgsAsTokens loads any more arguments (tokens on the same line)
// into a slice of Token-structs and returns them. Open curly brace tokens
// also indicate the end of arguments, and the curly brace is not included
// in the return value nor is it loaded.
func (d *Dispenser) RemainingArgsAsTokens() []Token {
var args []Token
for d.NextArg() {
args = append(args, d.Token())
}
return args
}
// NewFromNextSegment returns a new dispenser with a copy of
// the tokens from the current token until the end of the
// "directive" whether that be to the end of the line or
+60
View File
@@ -274,6 +274,66 @@ func TestDispenser_RemainingArgs(t *testing.T) {
}
}
func TestDispenser_RemainingArgsAsTokens(t *testing.T) {
input := `dir1 arg1 arg2 arg3
dir2 arg4 arg5
dir3 arg6 { arg7
dir4`
d := NewTestDispenser(input)
d.Next() // dir1
args := d.RemainingArgsAsTokens()
tokenTexts := make([]string, 0, len(args))
for _, arg := range args {
tokenTexts = append(tokenTexts, arg.Text)
}
if expected := []string{"arg1", "arg2", "arg3"}; !reflect.DeepEqual(tokenTexts, expected) {
t.Errorf("RemainingArgsAsTokens(): Expected %v, got %v", expected, tokenTexts)
}
d.Next() // dir2
args = d.RemainingArgsAsTokens()
tokenTexts = tokenTexts[:0]
for _, arg := range args {
tokenTexts = append(tokenTexts, arg.Text)
}
if expected := []string{"arg4", "arg5"}; !reflect.DeepEqual(tokenTexts, expected) {
t.Errorf("RemainingArgsAsTokens(): Expected %v, got %v", expected, tokenTexts)
}
d.Next() // dir3
args = d.RemainingArgsAsTokens()
tokenTexts = tokenTexts[:0]
for _, arg := range args {
tokenTexts = append(tokenTexts, arg.Text)
}
if expected := []string{"arg6"}; !reflect.DeepEqual(tokenTexts, expected) {
t.Errorf("RemainingArgsAsTokens(): Expected %v, got %v", expected, tokenTexts)
}
d.Next() // {
d.Next() // arg7
d.Next() // dir4
args = d.RemainingArgsAsTokens()
tokenTexts = tokenTexts[:0]
for _, arg := range args {
tokenTexts = append(tokenTexts, arg.Text)
}
if len(args) != 0 {
t.Errorf("RemainingArgsAsTokens(): Expected %v, got %v", []string{}, tokenTexts)
}
}
func TestDispenser_ArgErr_Err(t *testing.T) {
input := `dir1 {
}
+35 -18
View File
@@ -52,17 +52,16 @@ func Format(input []byte) []byte {
newLines int // count of newlines consumed
comment bool // whether we're in a comment
quoted bool // whether we're in a quoted segment
escaped bool // whether current char is escaped
comment bool // whether we're in a comment
quotes string // encountered quotes ('', '`', '"', '"`', '`"')
escaped bool // whether current char is escaped
heredoc heredocState // whether we're in a heredoc
heredocEscaped bool // whether heredoc is escaped
heredocMarker []rune
heredocClosingMarker []rune
nesting int // indentation level
withinBackquote bool
nesting int // indentation level
)
write := func(ch rune) {
@@ -89,12 +88,8 @@ func Format(input []byte) []byte {
}
panic(err)
}
if ch == '`' {
withinBackquote = !withinBackquote
}
// detect whether we have the start of a heredoc
if !quoted && !(heredoc != heredocClosed || heredocEscaped) &&
if quotes == "" && (heredoc == heredocClosed && !heredocEscaped) &&
space && last == '<' && ch == '<' {
write(ch)
heredoc = heredocOpening
@@ -180,16 +175,38 @@ func Format(input []byte) []byte {
continue
}
if quoted {
if ch == '`' {
switch quotes {
case "\"`":
quotes = "\""
case "`":
quotes = ""
case "\"":
quotes = "\"`"
default:
quotes = "`"
}
}
if quotes == "\"" {
if ch == '"' {
quoted = false
quotes = ""
}
write(ch)
continue
}
if space && ch == '"' {
quoted = true
if ch == '"' {
switch quotes {
case "":
if space {
quotes = "\""
}
case "`\"":
quotes = "`"
case "\"`":
quotes = ""
}
}
if unicode.IsSpace(ch) {
@@ -224,7 +241,7 @@ func Format(input []byte) []byte {
openBrace = false
if beginningOfLine {
indent()
} else if !openBraceSpace {
} else if !openBraceSpace || !unicode.IsSpace(last) {
write(' ')
}
write('{')
@@ -241,11 +258,11 @@ func Format(input []byte) []byte {
case ch == '{':
openBrace = true
openBraceSpace = spacePrior && !beginningOfLine
if openBraceSpace {
if openBraceSpace && newLines == 0 {
write(' ')
}
openBraceWritten = false
if withinBackquote {
if quotes == "`" {
write('{')
openBraceWritten = true
continue
@@ -253,7 +270,7 @@ func Format(input []byte) []byte {
continue
case ch == '}' && (spacePrior || !openBrace):
if withinBackquote {
if quotes == "`" {
write('}')
continue
}
+20
View File
@@ -444,6 +444,26 @@ block2 {
input: "block {respond \"All braces should remain: {{now | date `2006`}}\"}",
expect: "block {respond \"All braces should remain: {{now | date `2006`}}\"}",
},
{
description: "Preserve quoted backticks and backticked quotes",
input: "block { respond \"`\" } block { respond `\"`}",
expect: "block {\n\trespond \"`\"\n}\n\nblock {\n\trespond `\"`\n}",
},
{
description: "No trailing space on line before env variable",
input: `{
a
{$ENV_VAR}
}
`,
expect: `{
a
{$ENV_VAR}
}
`,
},
} {
// the formatter should output a trailing newline,
// even if the tests aren't written to expect that
+3 -2
View File
@@ -137,7 +137,7 @@ func (l *lexer) next() (bool, error) {
}
// detect whether we have the start of a heredoc
if !(quoted || btQuoted) && !(inHeredoc || heredocEscaped) &&
if (!quoted && !btQuoted) && (!inHeredoc && !heredocEscaped) &&
len(val) > 1 && string(val[:2]) == "<<" {
// a space means it's just a regular token and not a heredoc
if ch == ' ' {
@@ -323,7 +323,8 @@ func (l *lexer) finalizeHeredoc(val []rune, marker string) ([]rune, error) {
// if the padding doesn't match exactly at the start then we can't safely strip
if index != 0 {
return nil, fmt.Errorf("mismatched leading whitespace in heredoc <<%s on line #%d [%s], expected whitespace [%s] to match the closing marker", marker, l.line+lineNum+1, lineText, paddingToStrip)
cleanLineText := strings.TrimRight(lineText, "\r\n")
return nil, fmt.Errorf("mismatched leading whitespace in heredoc <<%s on line #%d [%s], expected whitespace [%s] to match the closing marker", marker, l.line+lineNum+1, cleanLineText, paddingToStrip)
}
// strip, then append the line, with the newline, to the output.
+18 -28
View File
@@ -379,28 +379,23 @@ func (p *parser) doImport(nesting int) error {
if len(blockTokens) > 0 {
// use such tokens to create a new dispenser, and then use it to parse each block
bd := NewDispenser(blockTokens)
// one iteration processes one sub-block inside the import
for bd.Next() {
// see if we can grab a key
var currentMappingKey string
if bd.Val() == "{" {
currentMappingKey := bd.Val()
if currentMappingKey == "{" {
return p.Err("anonymous blocks are not supported")
}
currentMappingKey = bd.Val()
currentMappingTokens := []Token{}
// read all args until end of line / {
if bd.NextArg() {
// load up all arguments (if there even are any)
currentMappingTokens := bd.RemainingArgsAsTokens()
// load up the entire block
for mappingNesting := bd.Nesting(); bd.NextBlock(mappingNesting); {
currentMappingTokens = append(currentMappingTokens, bd.Token())
for bd.NextArg() {
currentMappingTokens = append(currentMappingTokens, bd.Token())
}
// TODO(elee1766): we don't enter another mapping here because it's annoying to extract the { and } properly.
// maybe someone can do that in the future
} else {
// attempt to enter a block and add tokens to the currentMappingTokens
for mappingNesting := bd.Nesting(); bd.NextBlock(mappingNesting); {
currentMappingTokens = append(currentMappingTokens, bd.Token())
}
}
blockMapping[currentMappingKey] = currentMappingTokens
}
}
@@ -538,29 +533,24 @@ func (p *parser) doImport(nesting int) error {
}
// if it is {block}, we substitute with all tokens in the block
// if it is {blocks.*}, we substitute with the tokens in the mapping for the *
var skip bool
var tokensToAdd []Token
foundBlockDirective := false
switch {
case token.Text == "{block}":
foundBlockDirective = true
tokensToAdd = blockTokens
case strings.HasPrefix(token.Text, "{blocks.") && strings.HasSuffix(token.Text, "}"):
foundBlockDirective = true
// {blocks.foo.bar} will be extracted to key `foo.bar`
blockKey := strings.TrimPrefix(strings.TrimSuffix(token.Text, "}"), "{blocks.")
val, ok := blockMapping[blockKey]
if ok {
tokensToAdd = val
}
default:
skip = true
}
if !skip {
if len(tokensToAdd) == 0 {
// if there is no content in the snippet block, don't do any replacement
// this allows snippets which contained {block}/{block.*} before this change to continue functioning as normal
tokensCopy = append(tokensCopy, token)
} else {
tokensCopy = append(tokensCopy, tokensToAdd...)
}
if foundBlockDirective {
tokensCopy = append(tokensCopy, tokensToAdd...)
continue
}
+46
View File
@@ -18,6 +18,7 @@ import (
"bytes"
"os"
"path/filepath"
"strings"
"testing"
)
@@ -884,6 +885,51 @@ func TestRejectsGlobalMatcher(t *testing.T) {
}
}
func TestRejectAnonymousImportBlock(t *testing.T) {
p := testParser(`
(site) {
http://{args[0]} https://{args[0]} {
{block}
}
}
import site test.domain {
{
header_up Host {host}
header_up X-Real-IP {remote_host}
}
}
`)
_, err := p.parseAll()
if err == nil {
t.Fatal("Expected an error, but got nil")
}
expected := "anonymous blocks are not supported"
if !strings.HasPrefix(err.Error(), "anonymous blocks are not supported") {
t.Errorf("Expected error to start with '%s' but got '%v'", expected, err)
}
}
func TestAcceptSiteImportWithBraces(t *testing.T) {
p := testParser(`
(site) {
http://{args[0]} https://{args[0]} {
{block}
}
}
import site test.domain {
reverse_proxy http://192.168.1.1:8080 {
header_up Host {host}
}
}
`)
_, err := p.parseAll()
if err != nil {
t.Errorf("Expected error to be nil but got '%v'", err)
}
}
func testParser(input string) parser {
return parser{Dispenser: NewTestDispenser(input)}
}
+35 -4
View File
@@ -15,6 +15,7 @@
package httpcaddyfile
import (
"encoding/json"
"fmt"
"html"
"net/http"
@@ -90,7 +91,7 @@ func parseBind(h Helper) ([]ConfigValue, error) {
// curves <curves...>
// client_auth {
// mode [request|require|verify_if_given|require_and_verify]
// trust_pool <module_name> [...]
// trust_pool <module_name> [...]
// trusted_leaf_cert <base64_der>
// trusted_leaf_cert_file <filename>
// }
@@ -129,6 +130,9 @@ func parseTLS(h Helper) ([]ConfigValue, error) {
var reusePrivateKeys bool
var forceAutomate bool
// Track which DNS challenge options are set
var dnsOptionsSet []string
firstLine := h.RemainingArgs()
switch len(firstLine) {
case 0:
@@ -349,6 +353,7 @@ func parseTLS(h Helper) ([]ConfigValue, error) {
if acmeIssuer.Challenges.DNS == nil {
acmeIssuer.Challenges.DNS = new(caddytls.DNSChallengeConfig)
}
dnsOptionsSet = append(dnsOptionsSet, "resolvers")
acmeIssuer.Challenges.DNS.Resolvers = args
case "propagation_delay":
@@ -370,6 +375,7 @@ func parseTLS(h Helper) ([]ConfigValue, error) {
if acmeIssuer.Challenges.DNS == nil {
acmeIssuer.Challenges.DNS = new(caddytls.DNSChallengeConfig)
}
dnsOptionsSet = append(dnsOptionsSet, "propagation_delay")
acmeIssuer.Challenges.DNS.PropagationDelay = caddy.Duration(delay)
case "propagation_timeout":
@@ -397,6 +403,7 @@ func parseTLS(h Helper) ([]ConfigValue, error) {
if acmeIssuer.Challenges.DNS == nil {
acmeIssuer.Challenges.DNS = new(caddytls.DNSChallengeConfig)
}
dnsOptionsSet = append(dnsOptionsSet, "propagation_timeout")
acmeIssuer.Challenges.DNS.PropagationTimeout = caddy.Duration(timeout)
case "dns_ttl":
@@ -418,6 +425,7 @@ func parseTLS(h Helper) ([]ConfigValue, error) {
if acmeIssuer.Challenges.DNS == nil {
acmeIssuer.Challenges.DNS = new(caddytls.DNSChallengeConfig)
}
dnsOptionsSet = append(dnsOptionsSet, "dns_ttl")
acmeIssuer.Challenges.DNS.TTL = caddy.Duration(ttl)
case "dns_challenge_override_domain":
@@ -434,6 +442,7 @@ func parseTLS(h Helper) ([]ConfigValue, error) {
if acmeIssuer.Challenges.DNS == nil {
acmeIssuer.Challenges.DNS = new(caddytls.DNSChallengeConfig)
}
dnsOptionsSet = append(dnsOptionsSet, "dns_challenge_override_domain")
acmeIssuer.Challenges.DNS.OverrideDomain = arg[0]
case "ca_root":
@@ -469,6 +478,18 @@ func parseTLS(h Helper) ([]ConfigValue, error) {
}
}
// Validate DNS challenge config: any DNS challenge option except "dns" requires a DNS provider
if acmeIssuer != nil && acmeIssuer.Challenges != nil && acmeIssuer.Challenges.DNS != nil {
dnsCfg := acmeIssuer.Challenges.DNS
providerSet := dnsCfg.ProviderRaw != nil || h.Option("dns") != nil || h.Option("acme_dns") != nil
if len(dnsOptionsSet) > 0 && !providerSet {
return nil, h.Errf(
"setting DNS challenge options [%s] requires a DNS provider (set with the 'dns' subdirective or 'acme_dns' global option)",
strings.Join(dnsOptionsSet, ", "),
)
}
}
// a naked tls directive is not allowed
if len(firstLine) == 0 && !hasBlock {
return nil, h.ArgErr()
@@ -843,13 +864,18 @@ func parseHandleErrors(h Helper) ([]ConfigValue, error) {
return nil, h.Errf("segment was not parsed as a subroute")
}
// wrap the subroutes
wrappingRoute := caddyhttp.Route{
HandlersRaw: []json.RawMessage{caddyconfig.JSONModuleObject(subroute, "handler", "subroute", nil)},
}
subroute = &caddyhttp.Subroute{
Routes: []caddyhttp.Route{wrappingRoute},
}
if expression != "" {
statusMatcher := caddy.ModuleMap{
"expression": h.JSON(caddyhttp.MatchExpression{Expr: expression}),
}
for i := range subroute.Routes {
subroute.Routes[i].MatcherSetsRaw = []caddy.ModuleMap{statusMatcher}
}
subroute.Routes[0].MatcherSetsRaw = []caddy.ModuleMap{statusMatcher}
}
return []ConfigValue{
{
@@ -1160,6 +1186,11 @@ func parseLogSkip(h Helper) (caddyhttp.MiddlewareHandler, error) {
if h.NextArg() {
return nil, h.ArgErr()
}
if h.NextBlock(0) {
return nil, h.Err("log_skip directive does not accept blocks")
}
return caddyhttp.VarsMiddleware{"log_skip": true}, nil
}
+24 -6
View File
@@ -16,6 +16,7 @@ package httpcaddyfile
import (
"encoding/json"
"maps"
"net"
"slices"
"sort"
@@ -173,10 +174,12 @@ func RegisterDirectiveOrder(dir string, position Positional, standardDir string)
if d != standardDir {
continue
}
if position == Before {
switch position {
case Before:
newOrder = append(newOrder[:i], append([]string{dir}, newOrder[i:]...)...)
} else if position == After {
case After:
newOrder = append(newOrder[:i+1], append([]string{dir}, newOrder[i+1:]...)...)
case First, Last:
}
break
}
@@ -365,9 +368,7 @@ func parseSegmentAsConfig(h Helper) ([]ConfigValue, error) {
// copy existing matcher definitions so we can augment
// new ones that are defined only in this scope
matcherDefs := make(map[string]caddy.ModuleMap, len(h.matcherDefs))
for key, val := range h.matcherDefs {
matcherDefs[key] = val
}
maps.Copy(matcherDefs, h.matcherDefs)
// find and extract any embedded matcher definitions in this scope
for i := 0; i < len(segments); i++ {
@@ -483,12 +484,29 @@ func sortRoutes(routes []ConfigValue) {
// we can only confidently compare path lengths if both
// directives have a single path to match (issue #5037)
if iPathLen > 0 && jPathLen > 0 {
// trim the trailing wildcard if there is one
iPathTrimmed := strings.TrimSuffix(iPM[0], "*")
jPathTrimmed := strings.TrimSuffix(jPM[0], "*")
// if both paths are the same except for a trailing wildcard,
// sort by the shorter path first (which is more specific)
if strings.TrimSuffix(iPM[0], "*") == strings.TrimSuffix(jPM[0], "*") {
if iPathTrimmed == jPathTrimmed {
return iPathLen < jPathLen
}
// we use the trimmed length to compare the paths
// https://github.com/caddyserver/caddy/issues/7012#issuecomment-2870142195
// credit to https://github.com/Hellio404
// for sorts with many items, mixing matchers w/ and w/o wildcards will confuse the sort and result in incorrect orders
iPathLen = len(iPathTrimmed)
jPathLen = len(jPathTrimmed)
// if both paths have the same length, sort lexically
// https://github.com/caddyserver/caddy/pull/7015#issuecomment-2871993588
if iPathLen == jPathLen {
return iPathTrimmed < jPathTrimmed
}
// sort most-specific (longest) path first
return iPathLen > jPathLen
}
+7 -3
View File
@@ -458,8 +458,6 @@ func parseOptAutoHTTPS(d *caddyfile.Dispenser, _ any) (any, error) {
case "disable_certs":
case "ignore_loaded_certs":
case "prefer_wildcard":
break
default:
return "", d.Errf("auto_https must be one of 'off', 'disable_redirects', 'disable_certs', 'ignore_loaded_certs', or 'prefer_wildcard'")
}
@@ -557,8 +555,14 @@ func parseOptPreferredChains(d *caddyfile.Dispenser, _ any) (any, error) {
func parseOptDNS(d *caddyfile.Dispenser, _ any) (any, error) {
d.Next() // consume option name
optName := d.Val()
if !d.Next() { // get DNS module name
// get DNS module name
if !d.Next() {
// this is allowed if this is the "acme_dns" option since it may refer to the globally-configured "dns" option's value
if optName == "acme_dns" {
return nil, nil
}
return nil, d.ArgErr()
}
modID := "dns.providers." + d.Val()
+13 -1
View File
@@ -15,6 +15,8 @@
package httpcaddyfile
import (
"slices"
"github.com/caddyserver/caddy/v2"
"github.com/caddyserver/caddy/v2/caddyconfig"
"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
@@ -178,6 +180,15 @@ func (st ServerType) buildPKIApp(
if _, ok := options["skip_install_trust"]; ok {
skipInstallTrust = true
}
// check if auto_https is off - in that case we should not create
// any PKI infrastructure even with skip_install_trust directive
autoHTTPS := []string{}
if ah, ok := options["auto_https"].([]string); ok {
autoHTTPS = ah
}
autoHTTPSOff := slices.Contains(autoHTTPS, "off")
falseBool := false
// Load the PKI app configured via global options
@@ -218,7 +229,8 @@ func (st ServerType) buildPKIApp(
// if there was no CAs defined in any of the servers,
// and we were requested to not install trust, then
// add one for the default/local CA to do so
if len(pkiApp.CAs) == 0 && skipInstallTrust {
// only if auto_https is not completely disabled
if len(pkiApp.CAs) == 0 && skipInstallTrust && !autoHTTPSOff {
ca := new(caddypki.CA)
ca.ID = caddypki.DefaultCAID
ca.InstallTrust = &falseBool
@@ -18,6 +18,7 @@ import (
"encoding/json"
"fmt"
"slices"
"strconv"
"github.com/dustin/go-humanize"
@@ -42,12 +43,15 @@ type serverOptions struct {
WriteTimeout caddy.Duration
IdleTimeout caddy.Duration
KeepAliveInterval caddy.Duration
KeepAliveIdle caddy.Duration
KeepAliveCount int
MaxHeaderBytes int
EnableFullDuplex bool
Protocols []string
StrictSNIHost *bool
TrustedProxiesRaw json.RawMessage
TrustedProxiesStrict int
TrustedProxiesUnix bool
ClientIPHeaders []string
ShouldLogCredentials bool
Metrics *caddyhttp.Metrics
@@ -142,6 +146,7 @@ func unmarshalCaddyfileServerOptions(d *caddyfile.Dispenser) (any, error) {
return nil, d.Errf("unrecognized timeouts option '%s'", d.Val())
}
}
case "keepalive_interval":
if !d.NextArg() {
return nil, d.ArgErr()
@@ -152,6 +157,26 @@ func unmarshalCaddyfileServerOptions(d *caddyfile.Dispenser) (any, error) {
}
serverOpts.KeepAliveInterval = caddy.Duration(dur)
case "keepalive_idle":
if !d.NextArg() {
return nil, d.ArgErr()
}
dur, err := caddy.ParseDuration(d.Val())
if err != nil {
return nil, d.Errf("parsing keepalive idle duration: %v", err)
}
serverOpts.KeepAliveIdle = caddy.Duration(dur)
case "keepalive_count":
if !d.NextArg() {
return nil, d.ArgErr()
}
cnt, err := strconv.ParseInt(d.Val(), 10, 32)
if err != nil {
return nil, d.Errf("parsing keepalive count int: %v", err)
}
serverOpts.KeepAliveCount = int(cnt)
case "max_header_size":
var sizeStr string
if !d.AllArgs(&sizeStr) {
@@ -227,6 +252,12 @@ func unmarshalCaddyfileServerOptions(d *caddyfile.Dispenser) (any, error) {
}
serverOpts.TrustedProxiesStrict = 1
case "trusted_proxies_unix":
if d.NextArg() {
return nil, d.ArgErr()
}
serverOpts.TrustedProxiesUnix = true
case "client_ip_headers":
headers := d.RemainingArgs()
for _, header := range headers {
@@ -309,6 +340,8 @@ func applyServerOptions(
server.WriteTimeout = opts.WriteTimeout
server.IdleTimeout = opts.IdleTimeout
server.KeepAliveInterval = opts.KeepAliveInterval
server.KeepAliveIdle = opts.KeepAliveIdle
server.KeepAliveCount = opts.KeepAliveCount
server.MaxHeaderBytes = opts.MaxHeaderBytes
server.EnableFullDuplex = opts.EnableFullDuplex
server.Protocols = opts.Protocols
@@ -316,6 +349,7 @@ func applyServerOptions(
server.TrustedProxiesRaw = opts.TrustedProxiesRaw
server.ClientIPHeaders = opts.ClientIPHeaders
server.TrustedProxiesStrict = opts.TrustedProxiesStrict
server.TrustedProxiesUnix = opts.TrustedProxiesUnix
server.Metrics = opts.Metrics
if opts.ShouldLogCredentials {
if server.Logs == nil {
+3
View File
@@ -64,10 +64,13 @@ func placeholderShorthands() []string {
"{orig_?query}", "{http.request.orig_uri.prefixed_query}",
"{method}", "{http.request.method}",
"{uri}", "{http.request.uri}",
"{%uri}", "{http.request.uri_escaped}",
"{path}", "{http.request.uri.path}",
"{%path}", "{http.request.uri.path_escaped}",
"{dir}", "{http.request.uri.path.dir}",
"{file}", "{http.request.uri.path.file}",
"{query}", "{http.request.uri.query}",
"{%query}", "{http.request.uri.query_escaped}",
"{?query}", "{http.request.uri.prefixed_query}",
"{remote}", "{http.request.remote}",
"{remote_host}", "{http.request.remote.host}",
+49 -10
View File
@@ -464,10 +464,10 @@ func (st ServerType) buildTLSApp(
globalEmail := options["email"]
globalACMECA := options["acme_ca"]
globalACMECARoot := options["acme_ca_root"]
globalACMEDNS := options["acme_dns"]
_, globalACMEDNS := options["acme_dns"] // can be set to nil (to use globally-defined "dns" value instead), but it is still set
globalACMEEAB := options["acme_eab"]
globalPreferredChains := options["preferred_chains"]
hasGlobalACMEDefaults := globalEmail != nil || globalACMECA != nil || globalACMECARoot != nil || globalACMEDNS != nil || globalACMEEAB != nil || globalPreferredChains != nil
hasGlobalACMEDefaults := globalEmail != nil || globalACMECA != nil || globalACMECARoot != nil || globalACMEDNS || globalACMEEAB != nil || globalPreferredChains != nil
if hasGlobalACMEDefaults {
for i := range tlsApp.Automation.Policies {
ap := tlsApp.Automation.Policies[i]
@@ -549,11 +549,12 @@ func fillInGlobalACMEDefaults(issuer certmagic.Issuer, options map[string]any) e
globalEmail := options["email"]
globalACMECA := options["acme_ca"]
globalACMECARoot := options["acme_ca_root"]
globalACMEDNS := options["acme_dns"]
globalACMEDNS, globalACMEDNSok := options["acme_dns"] // can be set to nil (to use globally-defined "dns" value instead), but it is still set
globalACMEEAB := options["acme_eab"]
globalPreferredChains := options["preferred_chains"]
globalCertLifetime := options["cert_lifetime"]
globalHTTPPort, globalHTTPSPort := options["http_port"], options["https_port"]
globalDefaultBind := options["default_bind"]
if globalEmail != nil && acmeIssuer.Email == "" {
acmeIssuer.Email = globalEmail.(string)
@@ -564,11 +565,21 @@ func fillInGlobalACMEDefaults(issuer certmagic.Issuer, options map[string]any) e
if globalACMECARoot != nil && !slices.Contains(acmeIssuer.TrustedRootsPEMFiles, globalACMECARoot.(string)) {
acmeIssuer.TrustedRootsPEMFiles = append(acmeIssuer.TrustedRootsPEMFiles, globalACMECARoot.(string))
}
if globalACMEDNS != nil && (acmeIssuer.Challenges == nil || acmeIssuer.Challenges.DNS == nil) {
acmeIssuer.Challenges = &caddytls.ChallengesConfig{
DNS: &caddytls.DNSChallengeConfig{
ProviderRaw: caddyconfig.JSONModuleObject(globalACMEDNS, "name", globalACMEDNS.(caddy.Module).CaddyModule().ID.Name(), nil),
},
if globalACMEDNSok && (acmeIssuer.Challenges == nil || acmeIssuer.Challenges.DNS == nil || acmeIssuer.Challenges.DNS.ProviderRaw == nil) {
globalDNS := options["dns"]
if globalDNS == nil && globalACMEDNS == nil {
return fmt.Errorf("acme_dns specified without DNS provider config, but no provider specified with 'dns' global option")
}
if acmeIssuer.Challenges == nil {
acmeIssuer.Challenges = new(caddytls.ChallengesConfig)
}
if acmeIssuer.Challenges.DNS == nil {
acmeIssuer.Challenges.DNS = new(caddytls.DNSChallengeConfig)
}
// If global `dns` is set, do NOT set provider in issuer, just set empty dns config
if globalDNS == nil && acmeIssuer.Challenges.DNS.ProviderRaw == nil {
// Set a global DNS provider if `acme_dns` is set and `dns` is NOT set
acmeIssuer.Challenges.DNS.ProviderRaw = caddyconfig.JSONModuleObject(globalACMEDNS, "name", globalACMEDNS.(caddy.Module).CaddyModule().ID.Name(), nil)
}
}
if globalACMEEAB != nil && acmeIssuer.ExternalAccount == nil {
@@ -596,6 +607,20 @@ func fillInGlobalACMEDefaults(issuer certmagic.Issuer, options map[string]any) e
}
acmeIssuer.Challenges.TLSALPN.AlternatePort = globalHTTPSPort.(int)
}
// If BindHost is still unset, fall back to the first default_bind address if set
// This avoids binding the automation policy to the wildcard socket, which is unexpected behavior when a more selective socket is specified via default_bind
// In BSD it is valid to bind to the wildcard socket even though a more selective socket is already open (still unexpected behavior by the caller though)
// In Linux the same call will error with EADDRINUSE whenever the listener for the automation policy is opened
if acmeIssuer.Challenges == nil || (acmeIssuer.Challenges.DNS == nil && acmeIssuer.Challenges.BindHost == "") {
if defBinds, ok := globalDefaultBind.([]ConfigValue); ok && len(defBinds) > 0 {
if abp, ok := defBinds[0].Value.(addressesWithProtocols); ok && len(abp.addresses) > 0 {
if acmeIssuer.Challenges == nil {
acmeIssuer.Challenges = new(caddytls.ChallengesConfig)
}
acmeIssuer.Challenges.BindHost = abp.addresses[0]
}
}
}
if globalCertLifetime != nil && acmeIssuer.CertificateLifetime == 0 {
acmeIssuer.CertificateLifetime = globalCertLifetime.(caddy.Duration)
}
@@ -616,12 +641,18 @@ func newBaseAutomationPolicy(
_, hasLocalCerts := options["local_certs"]
keyType, hasKeyType := options["key_type"]
ocspStapling, hasOCSPStapling := options["ocsp_stapling"]
hasGlobalAutomationOpts := hasIssuers || hasLocalCerts || hasKeyType || hasOCSPStapling
globalACMECA := options["acme_ca"]
globalACMECARoot := options["acme_ca_root"]
_, globalACMEDNS := options["acme_dns"] // can be set to nil (to use globally-defined "dns" value instead), but it is still set
globalACMEEAB := options["acme_eab"]
globalPreferredChains := options["preferred_chains"]
hasGlobalACMEDefaults := globalACMECA != nil || globalACMECARoot != nil || globalACMEDNS || globalACMEEAB != nil || globalPreferredChains != nil
// if there are no global options related to automation policies
// set, then we can just return right away
if !hasGlobalAutomationOpts {
if !hasGlobalAutomationOpts && !hasGlobalACMEDefaults {
if always {
return new(caddytls.AutomationPolicy), nil
}
@@ -643,6 +674,14 @@ func newBaseAutomationPolicy(
ap.Issuers = []certmagic.Issuer{new(caddytls.InternalIssuer)}
}
if hasGlobalACMEDefaults {
for i := range ap.Issuers {
if err := fillInGlobalACMEDefaults(ap.Issuers[i], options); err != nil {
return nil, fmt.Errorf("filling in global issuer defaults for issuer %d: %v", i, err)
}
}
}
if hasOCSPStapling {
ocspConfig := ocspStapling.(certmagic.OCSPConfig)
ap.DisableOCSPStapling = ocspConfig.DisableStapling
+7
View File
@@ -121,6 +121,13 @@ func (adminLoad) handleLoad(w http.ResponseWriter, r *http.Request) error {
}
}
// If this request changed the config, clear the last
// config info we have stored, if it is different from
// the original source.
caddy.ClearLastConfigIfDifferent(
r.Header.Get("Caddy-Config-Source-File"),
r.Header.Get("Caddy-Config-Source-Adapter"))
caddy.Log().Named("admin.api").Info("load complete")
return nil
+1 -1
View File
@@ -281,7 +281,7 @@ func validateTestPrerequisites(tc *Tester) error {
tc.t.Cleanup(func() {
os.Remove(f.Name())
})
if _, err := f.WriteString(fmt.Sprintf(initConfig, tc.config.AdminPort)); err != nil {
if _, err := fmt.Fprintf(f, initConfig, tc.config.AdminPort); err != nil {
return err
}
+3 -2
View File
@@ -12,13 +12,14 @@ import (
"strings"
"testing"
"github.com/caddyserver/caddy/v2"
"github.com/caddyserver/caddy/v2/caddytest"
"github.com/mholt/acmez/v3"
"github.com/mholt/acmez/v3/acme"
smallstepacme "github.com/smallstep/certificates/acme"
"go.uber.org/zap"
"go.uber.org/zap/exp/zapslog"
"github.com/caddyserver/caddy/v2"
"github.com/caddyserver/caddy/v2/caddytest"
)
const acmeChallengePort = 9081
+2 -1
View File
@@ -9,11 +9,12 @@ import (
"strings"
"testing"
"github.com/caddyserver/caddy/v2/caddytest"
"github.com/mholt/acmez/v3"
"github.com/mholt/acmez/v3/acme"
"go.uber.org/zap"
"go.uber.org/zap/exp/zapslog"
"github.com/caddyserver/caddy/v2/caddytest"
)
func TestACMEServerDirectory(t *testing.T) {
@@ -0,0 +1,69 @@
{
acme_dns mock foo
}
example.com {
respond "Hello World"
}
----------
{
"apps": {
"http": {
"servers": {
"srv0": {
"listen": [
":443"
],
"routes": [
{
"match": [
{
"host": [
"example.com"
]
}
],
"handle": [
{
"handler": "subroute",
"routes": [
{
"handle": [
{
"body": "Hello World",
"handler": "static_response"
}
]
}
]
}
],
"terminal": true
}
]
}
}
},
"tls": {
"automation": {
"policies": [
{
"issuers": [
{
"challenges": {
"dns": {
"provider": {
"argument": "foo",
"name": "mock"
}
}
},
"module": "acme"
}
]
}
]
}
}
}
}
@@ -0,0 +1,53 @@
{
dns mock
acme_dns
}
example.com {
}
----------
{
"apps": {
"http": {
"servers": {
"srv0": {
"listen": [
":443"
],
"routes": [
{
"match": [
{
"host": [
"example.com"
]
}
],
"terminal": true
}
]
}
}
},
"tls": {
"automation": {
"policies": [
{
"issuers": [
{
"challenges": {
"dns": {}
},
"module": "acme"
}
]
}
]
},
"dns": {
"name": "mock"
}
}
}
}
@@ -0,0 +1,9 @@
{
acme_dns
}
example.com {
respond "Hello World"
}
----------
acme_dns specified without DNS provider config, but no provider specified with 'dns' global option
@@ -0,0 +1,12 @@
example.com
handle {
respond "one"
}
example.com
handle {
respond "two"
}
----------
Caddyfile:6: unrecognized directive: example.com
Did you mean to define a second site? If so, you must use curly braces around each site to separate their configurations.
@@ -0,0 +1,9 @@
:8080 {
respond "one"
}
:8080 {
respond "two"
}
----------
ambiguous site definition: :8080
@@ -0,0 +1,5 @@
handle
respond "should not work"
----------
Caddyfile:1: parsed 'handle' as a site address, but it is a known directive; directives must appear in a site block
@@ -0,0 +1,12 @@
{
servers {
srv0 {
listen :8080
}
srv1 {
listen :8080
}
}
}
----------
parsing caddyfile tokens for 'servers': unrecognized servers option 'srv0', at Caddyfile:3
@@ -106,20 +106,29 @@ example.com {
"handler": "subroute",
"routes": [
{
"group": "group0",
"handle": [
{
"handler": "rewrite",
"uri": "/{http.error.status_code}.html"
}
]
},
{
"handle": [
{
"handler": "file_server",
"hide": [
"./Caddyfile"
"handler": "subroute",
"routes": [
{
"group": "group0",
"handle": [
{
"handler": "rewrite",
"uri": "/{http.error.status_code}.html"
}
]
},
{
"handle": [
{
"handler": "file_server",
"hide": [
"./Caddyfile"
]
}
]
}
]
}
]
@@ -165,8 +165,17 @@ bar.localhost {
{
"handle": [
{
"body": "404 or 410 error",
"handler": "static_response"
"handler": "subroute",
"routes": [
{
"handle": [
{
"body": "404 or 410 error",
"handler": "static_response"
}
]
}
]
}
],
"match": [
@@ -178,8 +187,17 @@ bar.localhost {
{
"handle": [
{
"body": "Error In range [500 .. 599]",
"handler": "static_response"
"handler": "subroute",
"routes": [
{
"handle": [
{
"body": "Error In range [500 .. 599]",
"handler": "static_response"
}
]
}
]
}
],
"match": [
@@ -208,8 +226,17 @@ bar.localhost {
{
"handle": [
{
"body": "404 or 410 error from second site",
"handler": "static_response"
"handler": "subroute",
"routes": [
{
"handle": [
{
"body": "404 or 410 error from second site",
"handler": "static_response"
}
]
}
]
}
],
"match": [
@@ -221,8 +248,17 @@ bar.localhost {
{
"handle": [
{
"body": "Error In range [500 .. 599] from second site",
"handler": "static_response"
"handler": "subroute",
"routes": [
{
"handle": [
{
"body": "Error In range [500 .. 599] from second site",
"handler": "static_response"
}
]
}
]
}
],
"match": [
@@ -96,8 +96,17 @@ localhost:3010 {
{
"handle": [
{
"body": "Error in the [400 .. 499] range",
"handler": "static_response"
"handler": "subroute",
"routes": [
{
"handle": [
{
"body": "Error in the [400 .. 499] range",
"handler": "static_response"
}
]
}
]
}
],
"match": [
@@ -116,8 +116,17 @@ localhost:2099 {
{
"handle": [
{
"body": "Error in the [400 .. 499] range",
"handler": "static_response"
"handler": "subroute",
"routes": [
{
"handle": [
{
"body": "Error in the [400 .. 499] range",
"handler": "static_response"
}
]
}
]
}
],
"match": [
@@ -129,8 +138,17 @@ localhost:2099 {
{
"handle": [
{
"body": "Error code is equal to 500 or in the [300..399] range",
"handler": "static_response"
"handler": "subroute",
"routes": [
{
"handle": [
{
"body": "Error code is equal to 500 or in the [300..399] range",
"handler": "static_response"
}
]
}
]
}
],
"match": [
@@ -96,8 +96,17 @@ localhost:3010 {
{
"handle": [
{
"body": "404 or 410 error",
"handler": "static_response"
"handler": "subroute",
"routes": [
{
"handle": [
{
"body": "404 or 410 error",
"handler": "static_response"
}
]
}
]
}
],
"match": [
@@ -116,8 +116,17 @@ localhost:2099 {
{
"handle": [
{
"body": "Error in the [400 .. 499] range",
"handler": "static_response"
"handler": "subroute",
"routes": [
{
"handle": [
{
"body": "Error in the [400 .. 499] range",
"handler": "static_response"
}
]
}
]
}
],
"match": [
@@ -129,8 +138,17 @@ localhost:2099 {
{
"handle": [
{
"body": "Fallback route: code outside the [400..499] range",
"handler": "static_response"
"handler": "subroute",
"routes": [
{
"handle": [
{
"body": "Fallback route: code outside the [400..499] range",
"handler": "static_response"
}
]
}
]
}
]
}
@@ -0,0 +1,260 @@
{
http_port 2099
}
localhost:2099 {
root * /var/www/
file_server
handle_errors 404 {
handle /en/* {
respond "not found" 404
}
handle /es/* {
respond "no encontrado"
}
handle {
respond "default not found"
}
}
handle_errors {
handle /en/* {
respond "English error"
}
handle /es/* {
respond "Spanish error"
}
handle {
respond "Default error"
}
}
}
----------
{
"apps": {
"http": {
"http_port": 2099,
"servers": {
"srv0": {
"listen": [
":2099"
],
"routes": [
{
"match": [
{
"host": [
"localhost"
]
}
],
"handle": [
{
"handler": "subroute",
"routes": [
{
"handle": [
{
"handler": "vars",
"root": "/var/www/"
},
{
"handler": "file_server",
"hide": [
"./Caddyfile"
]
}
]
}
]
}
],
"terminal": true
}
],
"errors": {
"routes": [
{
"match": [
{
"host": [
"localhost"
]
}
],
"handle": [
{
"handler": "subroute",
"routes": [
{
"handle": [
{
"handler": "subroute",
"routes": [
{
"group": "group3",
"handle": [
{
"handler": "subroute",
"routes": [
{
"handle": [
{
"body": "not found",
"handler": "static_response",
"status_code": 404
}
]
}
]
}
],
"match": [
{
"path": [
"/en/*"
]
}
]
},
{
"group": "group3",
"handle": [
{
"handler": "subroute",
"routes": [
{
"handle": [
{
"body": "no encontrado",
"handler": "static_response"
}
]
}
]
}
],
"match": [
{
"path": [
"/es/*"
]
}
]
},
{
"group": "group3",
"handle": [
{
"handler": "subroute",
"routes": [
{
"handle": [
{
"body": "default not found",
"handler": "static_response"
}
]
}
]
}
]
}
]
}
],
"match": [
{
"expression": "{http.error.status_code} in [404]"
}
]
},
{
"handle": [
{
"handler": "subroute",
"routes": [
{
"group": "group8",
"handle": [
{
"handler": "subroute",
"routes": [
{
"handle": [
{
"body": "English error",
"handler": "static_response"
}
]
}
]
}
],
"match": [
{
"path": [
"/en/*"
]
}
]
},
{
"group": "group8",
"handle": [
{
"handler": "subroute",
"routes": [
{
"handle": [
{
"body": "Spanish error",
"handler": "static_response"
}
]
}
]
}
],
"match": [
{
"path": [
"/es/*"
]
}
]
},
{
"group": "group8",
"handle": [
{
"handler": "subroute",
"routes": [
{
"handle": [
{
"body": "Default error",
"handler": "static_response"
}
]
}
]
}
]
}
]
}
]
}
]
}
],
"terminal": true
}
]
}
}
}
}
}
}
@@ -31,9 +31,6 @@ example.com
"automation": {
"policies": [
{
"subjects": [
"example.com"
],
"issuers": [
{
"module": "acme",
@@ -18,6 +18,9 @@
trusted_proxies static private_ranges
client_ip_headers Custom-Real-Client-IP X-Forwarded-For
client_ip_headers A-Third-One
keepalive_interval 20s
keepalive_idle 20s
keepalive_count 10
}
}
@@ -45,6 +48,9 @@ foo.com {
"read_header_timeout": 30000000000,
"write_timeout": 30000000000,
"idle_timeout": 30000000000,
"keepalive_interval": 20000000000,
"keepalive_idle": 20000000000,
"keepalive_count": 10,
"max_header_bytes": 100000000,
"enable_full_duplex": true,
"routes": [
@@ -89,4 +95,4 @@ foo.com {
}
}
}
}
}
@@ -0,0 +1,64 @@
:80 {
header Test-Static ":443" "STATIC-WORKS"
header Test-Dynamic ":{http.request.local.port}" "DYNAMIC-WORKS"
header Test-Complex "port-{http.request.local.port}-end" "COMPLEX-{http.request.method}"
}
----------
{
"apps": {
"http": {
"servers": {
"srv0": {
"listen": [
":80"
],
"routes": [
{
"handle": [
{
"handler": "headers",
"response": {
"replace": {
"Test-Static": [
{
"replace": "STATIC-WORKS",
"search_regexp": ":443"
}
]
}
}
},
{
"handler": "headers",
"response": {
"replace": {
"Test-Dynamic": [
{
"replace": "DYNAMIC-WORKS",
"search_regexp": ":{http.request.local.port}"
}
]
}
}
},
{
"handler": "headers",
"response": {
"replace": {
"Test-Complex": [
{
"replace": "COMPLEX-{http.request.method}",
"search_regexp": "port-{http.request.local.port}-end"
}
]
}
}
}
]
}
]
}
}
}
}
}
@@ -0,0 +1,41 @@
:80
handle {
respond <<END
line1
line2
END
}
----------
{
"apps": {
"http": {
"servers": {
"srv0": {
"listen": [
":80"
],
"routes": [
{
"handle": [
{
"handler": "subroute",
"routes": [
{
"handle": [
{
"body": " line1\n line2",
"handler": "static_response"
}
]
}
]
}
]
}
]
}
}
}
}
}
@@ -0,0 +1,9 @@
:80
handle {
respond <<EOF
Hello
# missing EOF marker
}
----------
mismatched leading whitespace in heredoc <<EOF on line #5 [ Hello], expected whitespace [# missing ] to match the closing marker
@@ -0,0 +1,9 @@
:80
handle {
respond <<END!
Hello
END!
}
----------
heredoc marker on line #4 must contain only alpha-numeric characters, dashes and underscores; got 'END!'
@@ -0,0 +1,10 @@
:80
handle {
respond <<END
line1
line2
END
}
----------
mismatched leading whitespace in heredoc <<END on line #5 [ line1], expected whitespace [ ] to match the closing marker
@@ -0,0 +1,9 @@
:80
handle {
respond <<
Hello
END
}
----------
parsing caddyfile tokens for 'handle': unrecognized directive: Hello - are you sure your Caddyfile structure (nesting and braces) is correct?, at Caddyfile:7
@@ -0,0 +1,9 @@
:80
handle {
respond <<<END
Hello
END
}
----------
too many '<' for heredoc on line #4; only use two, for example <<END
@@ -0,0 +1,13 @@
(site) {
http://{args[0]} https://{args[0]} {
{block}
}
}
import site test.domain {
{
header_up Host {host}
header_up X-Real-IP {remote_host}
}
}
----------
anonymous blocks are not supported
@@ -0,0 +1,57 @@
(snippet) {
header {
reverse_proxy localhost:3000
{block}
}
}
example.com {
import snippet
}
----------
{
"apps": {
"http": {
"servers": {
"srv0": {
"listen": [
":443"
],
"routes": [
{
"match": [
{
"host": [
"example.com"
]
}
],
"handle": [
{
"handler": "subroute",
"routes": [
{
"handle": [
{
"handler": "headers",
"response": {
"set": {
"Reverse_proxy": [
"localhost:3000"
]
}
}
}
]
}
]
}
],
"terminal": true
}
]
}
}
}
}
}
@@ -0,0 +1,57 @@
(snippet) {
header {
reverse_proxy localhost:3000
{blocks.content_type}
}
}
example.com {
import snippet
}
----------
{
"apps": {
"http": {
"servers": {
"srv0": {
"listen": [
":443"
],
"routes": [
{
"match": [
{
"host": [
"example.com"
]
}
],
"handle": [
{
"handler": "subroute",
"routes": [
{
"handle": [
{
"handler": "headers",
"response": {
"set": {
"Reverse_proxy": [
"localhost:3000"
]
}
}
}
]
}
]
}
],
"terminal": true
}
]
}
}
}
}
}
@@ -0,0 +1,65 @@
(site) {
https://{args[0]} {
{block}
}
}
import site test.domain {
reverse_proxy http://192.168.1.1:8080 {
header_up Host {host}
}
}
----------
{
"apps": {
"http": {
"servers": {
"srv0": {
"listen": [
":443"
],
"routes": [
{
"match": [
{
"host": [
"test.domain"
]
}
],
"handle": [
{
"handler": "subroute",
"routes": [
{
"handle": [
{
"handler": "reverse_proxy",
"headers": {
"request": {
"set": {
"Host": [
"{http.request.host}"
]
}
}
},
"upstreams": [
{
"dial": "192.168.1.1:8080"
}
]
}
]
}
]
}
],
"terminal": true
}
]
}
}
}
}
}
@@ -0,0 +1,12 @@
(import1) {
import import2
}
(import2) {
import import1
}
import import1
----------
a cycle of imports exists between Caddyfile:import2 and Caddyfile:import1
@@ -0,0 +1,5 @@
example.com {
invoke foo
}
----------
cannot invoke named route 'foo', which was not defined
@@ -0,0 +1,95 @@
:80
log {
output stdout
format filter {
wrap console
# Multiple regexp filters for the same field - this should work now!
request>headers>Authorization regexp "Bearer\s+([A-Za-z0-9_-]+)" "Bearer [REDACTED]"
request>headers>Authorization regexp "Basic\s+([A-Za-z0-9+/=]+)" "Basic [REDACTED]"
request>headers>Authorization regexp "token=([^&\s]+)" "token=[REDACTED]"
# Single regexp filter - this should continue to work as before
request>headers>Cookie regexp "sessionid=[^;]+" "sessionid=[REDACTED]"
# Mixed filters (non-regexp) - these should work normally
request>headers>Server delete
request>remote_ip ip_mask {
ipv4 24
ipv6 32
}
}
}
----------
{
"logging": {
"logs": {
"default": {
"exclude": [
"http.log.access.log0"
]
},
"log0": {
"writer": {
"output": "stdout"
},
"encoder": {
"fields": {
"request\u003eheaders\u003eAuthorization": {
"filter": "multi_regexp",
"operations": [
{
"regexp": "Bearer\\s+([A-Za-z0-9_-]+)",
"value": "Bearer [REDACTED]"
},
{
"regexp": "Basic\\s+([A-Za-z0-9+/=]+)",
"value": "Basic [REDACTED]"
},
{
"regexp": "token=([^\u0026\\s]+)",
"value": "token=[REDACTED]"
}
]
},
"request\u003eheaders\u003eCookie": {
"filter": "regexp",
"regexp": "sessionid=[^;]+",
"value": "sessionid=[REDACTED]"
},
"request\u003eheaders\u003eServer": {
"filter": "delete"
},
"request\u003eremote_ip": {
"filter": "ip_mask",
"ipv4_cidr": 24,
"ipv6_cidr": 32
}
},
"format": "filter",
"wrap": {
"format": "console"
}
},
"include": [
"http.log.access.log0"
]
}
}
},
"apps": {
"http": {
"servers": {
"srv0": {
"listen": [
":80"
],
"logs": {
"default_logger_name": "log0"
}
}
}
}
}
}
@@ -0,0 +1,9 @@
@foo {
path /foo
}
handle {
respond "should not work"
}
----------
request matchers may not be defined globally, they must be in a site block; found @foo, at Caddyfile:1
@@ -0,0 +1,59 @@
{
servers {
trusted_proxies_unix
}
}
example.com {
reverse_proxy https://local:8080
}
----------
{
"apps": {
"http": {
"servers": {
"srv0": {
"listen": [
":443"
],
"routes": [
{
"match": [
{
"host": [
"example.com"
]
}
],
"handle": [
{
"handler": "subroute",
"routes": [
{
"handle": [
{
"handler": "reverse_proxy",
"transport": {
"protocol": "http",
"tls": {}
},
"upstreams": [
{
"dial": "local:8080"
}
]
}
]
}
]
}
],
"terminal": true
}
],
"trusted_proxies_unix": true
}
}
}
}
}
@@ -0,0 +1,7 @@
:70000
handle {
respond "should not work"
}
----------
port 70000 is out of range
@@ -0,0 +1,7 @@
:-1
handle {
respond "should not work"
}
----------
port -1 is out of range
@@ -0,0 +1,7 @@
foo://example.com
handle {
respond "hello"
}
----------
unsupported URL scheme foo://
@@ -0,0 +1,7 @@
wss://example.com:70000
handle {
respond "should not work"
}
----------
port 70000 is out of range
@@ -0,0 +1,7 @@
wss://example.com
handle {
respond "hello"
}
----------
the scheme wss:// is only supported in browsers; use https:// instead
@@ -0,0 +1,87 @@
localhost
respond "hello from localhost"
tls {
client_auth {
mode request
trust_pool inline {
trust_der MIIDSzCCAjOgAwIBAgIUfIRObjWNUA4jxQ/0x8BOCvE2Vw4wDQYJKoZIhvcNAQELBQAwFjEUMBIGA1UEAwwLRWFzeS1SU0EgQ0EwHhcNMTkwODI4MTYyNTU5WhcNMjkwODI1MTYyNTU5WjAWMRQwEgYDVQQDDAtFYXN5LVJTQSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK5m5elxhQfMp/3aVJ4JnpN9PUSz6LlP6LePAPFU7gqohVVFVtDkChJAG3FNkNQNlieVTja/bgH9IcC6oKbROwdY1h0MvNV8AHHigvl03WuJD8g2ReVFXXwsnrPmKXCFzQyMI6TYk3m2gYrXsZOU1GLnfMRC3KAMRgE2F45twOs9hqG169YJ6mM2eQjzjCHWI6S2/iUYvYxRkCOlYUbLsMD/AhgAf1plzg6LPqNxtdlwxZnA0ytgkmhK67HtzJu0+ovUCsMv0RwcMhsEo9T8nyFAGt9XLZ63X5WpBCTUApaAUhnG0XnerjmUWb6eUWw4zev54sEfY5F3x002iQaW6cECAwEAAaOBkDCBjTAdBgNVHQ4EFgQU4CBUbZsS2GaNIkGRz/cBsD5ivjswUQYDVR0jBEowSIAU4CBUbZsS2GaNIkGRz/cBsD5ivjuhGqQYMBYxFDASBgNVBAMMC0Vhc3ktUlNBIENBghR8hE5uNY1QDiPFD/THwE4K8TZXDjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAKB3V4HIzoiO/Ch6WMj9bLJ2FGbpkMrcb/Eq01hT5zcfKD66lVS1MlK+cRL446Z2b2KDP1oFyVs+qmrmtdwrWgD+nfe2sBmmIHo9m9KygMkEOfG3MghGTEcS+0cTKEcoHYWYyOqQh6jnedXY8Cdm4GM1hAc9MiL3/sqV8YCVSLNnkoNysmr06/rZ0MCUZPGUtRmfd0heWhrfzAKw2HLgX+RAmpOE2MZqWcjvqKGyaRiaZks4nJkP6521aC2Lgp0HhCz1j8/uQ5ldoDszCnu/iro0NAsNtudTMD+YoLQxLqdleIh6CW+illc2VdXwj7mn6J04yns9jfE2jRjW/yTLFuQ==
}
verifier leaf {
file ../caddy.ca.cer
}
}
}
----------
{
"apps": {
"http": {
"servers": {
"srv0": {
"listen": [
":443"
],
"routes": [
{
"match": [
{
"host": [
"localhost"
]
}
],
"handle": [
{
"handler": "subroute",
"routes": [
{
"handle": [
{
"body": "hello from localhost",
"handler": "static_response"
}
]
}
]
}
],
"terminal": true
}
],
"tls_connection_policies": [
{
"match": {
"sni": [
"localhost"
]
},
"client_authentication": {
"ca": {
"provider": "inline",
"trusted_ca_certs": [
"MIIDSzCCAjOgAwIBAgIUfIRObjWNUA4jxQ/0x8BOCvE2Vw4wDQYJKoZIhvcNAQELBQAwFjEUMBIGA1UEAwwLRWFzeS1SU0EgQ0EwHhcNMTkwODI4MTYyNTU5WhcNMjkwODI1MTYyNTU5WjAWMRQwEgYDVQQDDAtFYXN5LVJTQSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK5m5elxhQfMp/3aVJ4JnpN9PUSz6LlP6LePAPFU7gqohVVFVtDkChJAG3FNkNQNlieVTja/bgH9IcC6oKbROwdY1h0MvNV8AHHigvl03WuJD8g2ReVFXXwsnrPmKXCFzQyMI6TYk3m2gYrXsZOU1GLnfMRC3KAMRgE2F45twOs9hqG169YJ6mM2eQjzjCHWI6S2/iUYvYxRkCOlYUbLsMD/AhgAf1plzg6LPqNxtdlwxZnA0ytgkmhK67HtzJu0+ovUCsMv0RwcMhsEo9T8nyFAGt9XLZ63X5WpBCTUApaAUhnG0XnerjmUWb6eUWw4zev54sEfY5F3x002iQaW6cECAwEAAaOBkDCBjTAdBgNVHQ4EFgQU4CBUbZsS2GaNIkGRz/cBsD5ivjswUQYDVR0jBEowSIAU4CBUbZsS2GaNIkGRz/cBsD5ivjuhGqQYMBYxFDASBgNVBAMMC0Vhc3ktUlNBIENBghR8hE5uNY1QDiPFD/THwE4K8TZXDjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAKB3V4HIzoiO/Ch6WMj9bLJ2FGbpkMrcb/Eq01hT5zcfKD66lVS1MlK+cRL446Z2b2KDP1oFyVs+qmrmtdwrWgD+nfe2sBmmIHo9m9KygMkEOfG3MghGTEcS+0cTKEcoHYWYyOqQh6jnedXY8Cdm4GM1hAc9MiL3/sqV8YCVSLNnkoNysmr06/rZ0MCUZPGUtRmfd0heWhrfzAKw2HLgX+RAmpOE2MZqWcjvqKGyaRiaZks4nJkP6521aC2Lgp0HhCz1j8/uQ5ldoDszCnu/iro0NAsNtudTMD+YoLQxLqdleIh6CW+illc2VdXwj7mn6J04yns9jfE2jRjW/yTLFuQ=="
]
},
"verifiers": [
{
"leaf_certs_loaders": [
{
"files": [
"../caddy.ca.cer"
],
"loader": "file"
}
],
"verifier": "leaf"
}
],
"mode": "request"
}
},
{}
]
}
}
}
}
}
@@ -0,0 +1,85 @@
localhost
respond "hello from localhost"
tls {
client_auth {
mode request
trust_pool inline {
trust_der MIIDSzCCAjOgAwIBAgIUfIRObjWNUA4jxQ/0x8BOCvE2Vw4wDQYJKoZIhvcNAQELBQAwFjEUMBIGA1UEAwwLRWFzeS1SU0EgQ0EwHhcNMTkwODI4MTYyNTU5WhcNMjkwODI1MTYyNTU5WjAWMRQwEgYDVQQDDAtFYXN5LVJTQSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK5m5elxhQfMp/3aVJ4JnpN9PUSz6LlP6LePAPFU7gqohVVFVtDkChJAG3FNkNQNlieVTja/bgH9IcC6oKbROwdY1h0MvNV8AHHigvl03WuJD8g2ReVFXXwsnrPmKXCFzQyMI6TYk3m2gYrXsZOU1GLnfMRC3KAMRgE2F45twOs9hqG169YJ6mM2eQjzjCHWI6S2/iUYvYxRkCOlYUbLsMD/AhgAf1plzg6LPqNxtdlwxZnA0ytgkmhK67HtzJu0+ovUCsMv0RwcMhsEo9T8nyFAGt9XLZ63X5WpBCTUApaAUhnG0XnerjmUWb6eUWw4zev54sEfY5F3x002iQaW6cECAwEAAaOBkDCBjTAdBgNVHQ4EFgQU4CBUbZsS2GaNIkGRz/cBsD5ivjswUQYDVR0jBEowSIAU4CBUbZsS2GaNIkGRz/cBsD5ivjuhGqQYMBYxFDASBgNVBAMMC0Vhc3ktUlNBIENBghR8hE5uNY1QDiPFD/THwE4K8TZXDjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAKB3V4HIzoiO/Ch6WMj9bLJ2FGbpkMrcb/Eq01hT5zcfKD66lVS1MlK+cRL446Z2b2KDP1oFyVs+qmrmtdwrWgD+nfe2sBmmIHo9m9KygMkEOfG3MghGTEcS+0cTKEcoHYWYyOqQh6jnedXY8Cdm4GM1hAc9MiL3/sqV8YCVSLNnkoNysmr06/rZ0MCUZPGUtRmfd0heWhrfzAKw2HLgX+RAmpOE2MZqWcjvqKGyaRiaZks4nJkP6521aC2Lgp0HhCz1j8/uQ5ldoDszCnu/iro0NAsNtudTMD+YoLQxLqdleIh6CW+illc2VdXwj7mn6J04yns9jfE2jRjW/yTLFuQ==
}
verifier leaf file ../caddy.ca.cer
}
}
----------
{
"apps": {
"http": {
"servers": {
"srv0": {
"listen": [
":443"
],
"routes": [
{
"match": [
{
"host": [
"localhost"
]
}
],
"handle": [
{
"handler": "subroute",
"routes": [
{
"handle": [
{
"body": "hello from localhost",
"handler": "static_response"
}
]
}
]
}
],
"terminal": true
}
],
"tls_connection_policies": [
{
"match": {
"sni": [
"localhost"
]
},
"client_authentication": {
"ca": {
"provider": "inline",
"trusted_ca_certs": [
"MIIDSzCCAjOgAwIBAgIUfIRObjWNUA4jxQ/0x8BOCvE2Vw4wDQYJKoZIhvcNAQELBQAwFjEUMBIGA1UEAwwLRWFzeS1SU0EgQ0EwHhcNMTkwODI4MTYyNTU5WhcNMjkwODI1MTYyNTU5WjAWMRQwEgYDVQQDDAtFYXN5LVJTQSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK5m5elxhQfMp/3aVJ4JnpN9PUSz6LlP6LePAPFU7gqohVVFVtDkChJAG3FNkNQNlieVTja/bgH9IcC6oKbROwdY1h0MvNV8AHHigvl03WuJD8g2ReVFXXwsnrPmKXCFzQyMI6TYk3m2gYrXsZOU1GLnfMRC3KAMRgE2F45twOs9hqG169YJ6mM2eQjzjCHWI6S2/iUYvYxRkCOlYUbLsMD/AhgAf1plzg6LPqNxtdlwxZnA0ytgkmhK67HtzJu0+ovUCsMv0RwcMhsEo9T8nyFAGt9XLZ63X5WpBCTUApaAUhnG0XnerjmUWb6eUWw4zev54sEfY5F3x002iQaW6cECAwEAAaOBkDCBjTAdBgNVHQ4EFgQU4CBUbZsS2GaNIkGRz/cBsD5ivjswUQYDVR0jBEowSIAU4CBUbZsS2GaNIkGRz/cBsD5ivjuhGqQYMBYxFDASBgNVBAMMC0Vhc3ktUlNBIENBghR8hE5uNY1QDiPFD/THwE4K8TZXDjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAKB3V4HIzoiO/Ch6WMj9bLJ2FGbpkMrcb/Eq01hT5zcfKD66lVS1MlK+cRL446Z2b2KDP1oFyVs+qmrmtdwrWgD+nfe2sBmmIHo9m9KygMkEOfG3MghGTEcS+0cTKEcoHYWYyOqQh6jnedXY8Cdm4GM1hAc9MiL3/sqV8YCVSLNnkoNysmr06/rZ0MCUZPGUtRmfd0heWhrfzAKw2HLgX+RAmpOE2MZqWcjvqKGyaRiaZks4nJkP6521aC2Lgp0HhCz1j8/uQ5ldoDszCnu/iro0NAsNtudTMD+YoLQxLqdleIh6CW+illc2VdXwj7mn6J04yns9jfE2jRjW/yTLFuQ=="
]
},
"verifiers": [
{
"leaf_certs_loaders": [
{
"files": [
"../caddy.ca.cer"
],
"loader": "file"
}
],
"verifier": "leaf"
}
],
"mode": "request"
}
},
{}
]
}
}
}
}
}
@@ -0,0 +1,94 @@
localhost
respond "hello from localhost"
tls {
client_auth {
mode request
trust_pool inline {
trust_der MIIDSzCCAjOgAwIBAgIUfIRObjWNUA4jxQ/0x8BOCvE2Vw4wDQYJKoZIhvcNAQELBQAwFjEUMBIGA1UEAwwLRWFzeS1SU0EgQ0EwHhcNMTkwODI4MTYyNTU5WhcNMjkwODI1MTYyNTU5WjAWMRQwEgYDVQQDDAtFYXN5LVJTQSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK5m5elxhQfMp/3aVJ4JnpN9PUSz6LlP6LePAPFU7gqohVVFVtDkChJAG3FNkNQNlieVTja/bgH9IcC6oKbROwdY1h0MvNV8AHHigvl03WuJD8g2ReVFXXwsnrPmKXCFzQyMI6TYk3m2gYrXsZOU1GLnfMRC3KAMRgE2F45twOs9hqG169YJ6mM2eQjzjCHWI6S2/iUYvYxRkCOlYUbLsMD/AhgAf1plzg6LPqNxtdlwxZnA0ytgkmhK67HtzJu0+ovUCsMv0RwcMhsEo9T8nyFAGt9XLZ63X5WpBCTUApaAUhnG0XnerjmUWb6eUWw4zev54sEfY5F3x002iQaW6cECAwEAAaOBkDCBjTAdBgNVHQ4EFgQU4CBUbZsS2GaNIkGRz/cBsD5ivjswUQYDVR0jBEowSIAU4CBUbZsS2GaNIkGRz/cBsD5ivjuhGqQYMBYxFDASBgNVBAMMC0Vhc3ktUlNBIENBghR8hE5uNY1QDiPFD/THwE4K8TZXDjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAKB3V4HIzoiO/Ch6WMj9bLJ2FGbpkMrcb/Eq01hT5zcfKD66lVS1MlK+cRL446Z2b2KDP1oFyVs+qmrmtdwrWgD+nfe2sBmmIHo9m9KygMkEOfG3MghGTEcS+0cTKEcoHYWYyOqQh6jnedXY8Cdm4GM1hAc9MiL3/sqV8YCVSLNnkoNysmr06/rZ0MCUZPGUtRmfd0heWhrfzAKw2HLgX+RAmpOE2MZqWcjvqKGyaRiaZks4nJkP6521aC2Lgp0HhCz1j8/uQ5ldoDszCnu/iro0NAsNtudTMD+YoLQxLqdleIh6CW+illc2VdXwj7mn6J04yns9jfE2jRjW/yTLFuQ==
}
verifier leaf {
file ../caddy.ca.cer
file ../caddy.ca.cer
}
}
}
----------
{
"apps": {
"http": {
"servers": {
"srv0": {
"listen": [
":443"
],
"routes": [
{
"match": [
{
"host": [
"localhost"
]
}
],
"handle": [
{
"handler": "subroute",
"routes": [
{
"handle": [
{
"body": "hello from localhost",
"handler": "static_response"
}
]
}
]
}
],
"terminal": true
}
],
"tls_connection_policies": [
{
"match": {
"sni": [
"localhost"
]
},
"client_authentication": {
"ca": {
"provider": "inline",
"trusted_ca_certs": [
"MIIDSzCCAjOgAwIBAgIUfIRObjWNUA4jxQ/0x8BOCvE2Vw4wDQYJKoZIhvcNAQELBQAwFjEUMBIGA1UEAwwLRWFzeS1SU0EgQ0EwHhcNMTkwODI4MTYyNTU5WhcNMjkwODI1MTYyNTU5WjAWMRQwEgYDVQQDDAtFYXN5LVJTQSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK5m5elxhQfMp/3aVJ4JnpN9PUSz6LlP6LePAPFU7gqohVVFVtDkChJAG3FNkNQNlieVTja/bgH9IcC6oKbROwdY1h0MvNV8AHHigvl03WuJD8g2ReVFXXwsnrPmKXCFzQyMI6TYk3m2gYrXsZOU1GLnfMRC3KAMRgE2F45twOs9hqG169YJ6mM2eQjzjCHWI6S2/iUYvYxRkCOlYUbLsMD/AhgAf1plzg6LPqNxtdlwxZnA0ytgkmhK67HtzJu0+ovUCsMv0RwcMhsEo9T8nyFAGt9XLZ63X5WpBCTUApaAUhnG0XnerjmUWb6eUWw4zev54sEfY5F3x002iQaW6cECAwEAAaOBkDCBjTAdBgNVHQ4EFgQU4CBUbZsS2GaNIkGRz/cBsD5ivjswUQYDVR0jBEowSIAU4CBUbZsS2GaNIkGRz/cBsD5ivjuhGqQYMBYxFDASBgNVBAMMC0Vhc3ktUlNBIENBghR8hE5uNY1QDiPFD/THwE4K8TZXDjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAKB3V4HIzoiO/Ch6WMj9bLJ2FGbpkMrcb/Eq01hT5zcfKD66lVS1MlK+cRL446Z2b2KDP1oFyVs+qmrmtdwrWgD+nfe2sBmmIHo9m9KygMkEOfG3MghGTEcS+0cTKEcoHYWYyOqQh6jnedXY8Cdm4GM1hAc9MiL3/sqV8YCVSLNnkoNysmr06/rZ0MCUZPGUtRmfd0heWhrfzAKw2HLgX+RAmpOE2MZqWcjvqKGyaRiaZks4nJkP6521aC2Lgp0HhCz1j8/uQ5ldoDszCnu/iro0NAsNtudTMD+YoLQxLqdleIh6CW+illc2VdXwj7mn6J04yns9jfE2jRjW/yTLFuQ=="
]
},
"verifiers": [
{
"leaf_certs_loaders": [
{
"files": [
"../caddy.ca.cer"
],
"loader": "file"
},
{
"files": [
"../caddy.ca.cer"
],
"loader": "file"
}
],
"verifier": "leaf"
}
],
"mode": "request"
}
},
{}
]
}
}
}
}
}
@@ -0,0 +1,87 @@
localhost
respond "hello from localhost"
tls {
client_auth {
mode request
trust_pool inline {
trust_der MIIDSzCCAjOgAwIBAgIUfIRObjWNUA4jxQ/0x8BOCvE2Vw4wDQYJKoZIhvcNAQELBQAwFjEUMBIGA1UEAwwLRWFzeS1SU0EgQ0EwHhcNMTkwODI4MTYyNTU5WhcNMjkwODI1MTYyNTU5WjAWMRQwEgYDVQQDDAtFYXN5LVJTQSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK5m5elxhQfMp/3aVJ4JnpN9PUSz6LlP6LePAPFU7gqohVVFVtDkChJAG3FNkNQNlieVTja/bgH9IcC6oKbROwdY1h0MvNV8AHHigvl03WuJD8g2ReVFXXwsnrPmKXCFzQyMI6TYk3m2gYrXsZOU1GLnfMRC3KAMRgE2F45twOs9hqG169YJ6mM2eQjzjCHWI6S2/iUYvYxRkCOlYUbLsMD/AhgAf1plzg6LPqNxtdlwxZnA0ytgkmhK67HtzJu0+ovUCsMv0RwcMhsEo9T8nyFAGt9XLZ63X5WpBCTUApaAUhnG0XnerjmUWb6eUWw4zev54sEfY5F3x002iQaW6cECAwEAAaOBkDCBjTAdBgNVHQ4EFgQU4CBUbZsS2GaNIkGRz/cBsD5ivjswUQYDVR0jBEowSIAU4CBUbZsS2GaNIkGRz/cBsD5ivjuhGqQYMBYxFDASBgNVBAMMC0Vhc3ktUlNBIENBghR8hE5uNY1QDiPFD/THwE4K8TZXDjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAKB3V4HIzoiO/Ch6WMj9bLJ2FGbpkMrcb/Eq01hT5zcfKD66lVS1MlK+cRL446Z2b2KDP1oFyVs+qmrmtdwrWgD+nfe2sBmmIHo9m9KygMkEOfG3MghGTEcS+0cTKEcoHYWYyOqQh6jnedXY8Cdm4GM1hAc9MiL3/sqV8YCVSLNnkoNysmr06/rZ0MCUZPGUtRmfd0heWhrfzAKw2HLgX+RAmpOE2MZqWcjvqKGyaRiaZks4nJkP6521aC2Lgp0HhCz1j8/uQ5ldoDszCnu/iro0NAsNtudTMD+YoLQxLqdleIh6CW+illc2VdXwj7mn6J04yns9jfE2jRjW/yTLFuQ==
}
verifier leaf {
folder ../
}
}
}
----------
{
"apps": {
"http": {
"servers": {
"srv0": {
"listen": [
":443"
],
"routes": [
{
"match": [
{
"host": [
"localhost"
]
}
],
"handle": [
{
"handler": "subroute",
"routes": [
{
"handle": [
{
"body": "hello from localhost",
"handler": "static_response"
}
]
}
]
}
],
"terminal": true
}
],
"tls_connection_policies": [
{
"match": {
"sni": [
"localhost"
]
},
"client_authentication": {
"ca": {
"provider": "inline",
"trusted_ca_certs": [
"MIIDSzCCAjOgAwIBAgIUfIRObjWNUA4jxQ/0x8BOCvE2Vw4wDQYJKoZIhvcNAQELBQAwFjEUMBIGA1UEAwwLRWFzeS1SU0EgQ0EwHhcNMTkwODI4MTYyNTU5WhcNMjkwODI1MTYyNTU5WjAWMRQwEgYDVQQDDAtFYXN5LVJTQSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK5m5elxhQfMp/3aVJ4JnpN9PUSz6LlP6LePAPFU7gqohVVFVtDkChJAG3FNkNQNlieVTja/bgH9IcC6oKbROwdY1h0MvNV8AHHigvl03WuJD8g2ReVFXXwsnrPmKXCFzQyMI6TYk3m2gYrXsZOU1GLnfMRC3KAMRgE2F45twOs9hqG169YJ6mM2eQjzjCHWI6S2/iUYvYxRkCOlYUbLsMD/AhgAf1plzg6LPqNxtdlwxZnA0ytgkmhK67HtzJu0+ovUCsMv0RwcMhsEo9T8nyFAGt9XLZ63X5WpBCTUApaAUhnG0XnerjmUWb6eUWw4zev54sEfY5F3x002iQaW6cECAwEAAaOBkDCBjTAdBgNVHQ4EFgQU4CBUbZsS2GaNIkGRz/cBsD5ivjswUQYDVR0jBEowSIAU4CBUbZsS2GaNIkGRz/cBsD5ivjuhGqQYMBYxFDASBgNVBAMMC0Vhc3ktUlNBIENBghR8hE5uNY1QDiPFD/THwE4K8TZXDjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAKB3V4HIzoiO/Ch6WMj9bLJ2FGbpkMrcb/Eq01hT5zcfKD66lVS1MlK+cRL446Z2b2KDP1oFyVs+qmrmtdwrWgD+nfe2sBmmIHo9m9KygMkEOfG3MghGTEcS+0cTKEcoHYWYyOqQh6jnedXY8Cdm4GM1hAc9MiL3/sqV8YCVSLNnkoNysmr06/rZ0MCUZPGUtRmfd0heWhrfzAKw2HLgX+RAmpOE2MZqWcjvqKGyaRiaZks4nJkP6521aC2Lgp0HhCz1j8/uQ5ldoDszCnu/iro0NAsNtudTMD+YoLQxLqdleIh6CW+illc2VdXwj7mn6J04yns9jfE2jRjW/yTLFuQ=="
]
},
"verifiers": [
{
"leaf_certs_loaders": [
{
"folders": [
"../"
],
"loader": "folder"
}
],
"verifier": "leaf"
}
],
"mode": "request"
}
},
{}
]
}
}
}
}
}
@@ -0,0 +1,85 @@
localhost
respond "hello from localhost"
tls {
client_auth {
mode request
trust_pool inline {
trust_der MIIDSzCCAjOgAwIBAgIUfIRObjWNUA4jxQ/0x8BOCvE2Vw4wDQYJKoZIhvcNAQELBQAwFjEUMBIGA1UEAwwLRWFzeS1SU0EgQ0EwHhcNMTkwODI4MTYyNTU5WhcNMjkwODI1MTYyNTU5WjAWMRQwEgYDVQQDDAtFYXN5LVJTQSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK5m5elxhQfMp/3aVJ4JnpN9PUSz6LlP6LePAPFU7gqohVVFVtDkChJAG3FNkNQNlieVTja/bgH9IcC6oKbROwdY1h0MvNV8AHHigvl03WuJD8g2ReVFXXwsnrPmKXCFzQyMI6TYk3m2gYrXsZOU1GLnfMRC3KAMRgE2F45twOs9hqG169YJ6mM2eQjzjCHWI6S2/iUYvYxRkCOlYUbLsMD/AhgAf1plzg6LPqNxtdlwxZnA0ytgkmhK67HtzJu0+ovUCsMv0RwcMhsEo9T8nyFAGt9XLZ63X5WpBCTUApaAUhnG0XnerjmUWb6eUWw4zev54sEfY5F3x002iQaW6cECAwEAAaOBkDCBjTAdBgNVHQ4EFgQU4CBUbZsS2GaNIkGRz/cBsD5ivjswUQYDVR0jBEowSIAU4CBUbZsS2GaNIkGRz/cBsD5ivjuhGqQYMBYxFDASBgNVBAMMC0Vhc3ktUlNBIENBghR8hE5uNY1QDiPFD/THwE4K8TZXDjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAKB3V4HIzoiO/Ch6WMj9bLJ2FGbpkMrcb/Eq01hT5zcfKD66lVS1MlK+cRL446Z2b2KDP1oFyVs+qmrmtdwrWgD+nfe2sBmmIHo9m9KygMkEOfG3MghGTEcS+0cTKEcoHYWYyOqQh6jnedXY8Cdm4GM1hAc9MiL3/sqV8YCVSLNnkoNysmr06/rZ0MCUZPGUtRmfd0heWhrfzAKw2HLgX+RAmpOE2MZqWcjvqKGyaRiaZks4nJkP6521aC2Lgp0HhCz1j8/uQ5ldoDszCnu/iro0NAsNtudTMD+YoLQxLqdleIh6CW+illc2VdXwj7mn6J04yns9jfE2jRjW/yTLFuQ==
}
verifier leaf folder ../
}
}
----------
{
"apps": {
"http": {
"servers": {
"srv0": {
"listen": [
":443"
],
"routes": [
{
"match": [
{
"host": [
"localhost"
]
}
],
"handle": [
{
"handler": "subroute",
"routes": [
{
"handle": [
{
"body": "hello from localhost",
"handler": "static_response"
}
]
}
]
}
],
"terminal": true
}
],
"tls_connection_policies": [
{
"match": {
"sni": [
"localhost"
]
},
"client_authentication": {
"ca": {
"provider": "inline",
"trusted_ca_certs": [
"MIIDSzCCAjOgAwIBAgIUfIRObjWNUA4jxQ/0x8BOCvE2Vw4wDQYJKoZIhvcNAQELBQAwFjEUMBIGA1UEAwwLRWFzeS1SU0EgQ0EwHhcNMTkwODI4MTYyNTU5WhcNMjkwODI1MTYyNTU5WjAWMRQwEgYDVQQDDAtFYXN5LVJTQSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK5m5elxhQfMp/3aVJ4JnpN9PUSz6LlP6LePAPFU7gqohVVFVtDkChJAG3FNkNQNlieVTja/bgH9IcC6oKbROwdY1h0MvNV8AHHigvl03WuJD8g2ReVFXXwsnrPmKXCFzQyMI6TYk3m2gYrXsZOU1GLnfMRC3KAMRgE2F45twOs9hqG169YJ6mM2eQjzjCHWI6S2/iUYvYxRkCOlYUbLsMD/AhgAf1plzg6LPqNxtdlwxZnA0ytgkmhK67HtzJu0+ovUCsMv0RwcMhsEo9T8nyFAGt9XLZ63X5WpBCTUApaAUhnG0XnerjmUWb6eUWw4zev54sEfY5F3x002iQaW6cECAwEAAaOBkDCBjTAdBgNVHQ4EFgQU4CBUbZsS2GaNIkGRz/cBsD5ivjswUQYDVR0jBEowSIAU4CBUbZsS2GaNIkGRz/cBsD5ivjuhGqQYMBYxFDASBgNVBAMMC0Vhc3ktUlNBIENBghR8hE5uNY1QDiPFD/THwE4K8TZXDjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAKB3V4HIzoiO/Ch6WMj9bLJ2FGbpkMrcb/Eq01hT5zcfKD66lVS1MlK+cRL446Z2b2KDP1oFyVs+qmrmtdwrWgD+nfe2sBmmIHo9m9KygMkEOfG3MghGTEcS+0cTKEcoHYWYyOqQh6jnedXY8Cdm4GM1hAc9MiL3/sqV8YCVSLNnkoNysmr06/rZ0MCUZPGUtRmfd0heWhrfzAKw2HLgX+RAmpOE2MZqWcjvqKGyaRiaZks4nJkP6521aC2Lgp0HhCz1j8/uQ5ldoDszCnu/iro0NAsNtudTMD+YoLQxLqdleIh6CW+illc2VdXwj7mn6J04yns9jfE2jRjW/yTLFuQ=="
]
},
"verifiers": [
{
"leaf_certs_loaders": [
{
"folders": [
"../"
],
"loader": "folder"
}
],
"verifier": "leaf"
}
],
"mode": "request"
}
},
{}
]
}
}
}
}
}
@@ -0,0 +1,94 @@
localhost
respond "hello from localhost"
tls {
client_auth {
mode request
trust_pool inline {
trust_der MIIDSzCCAjOgAwIBAgIUfIRObjWNUA4jxQ/0x8BOCvE2Vw4wDQYJKoZIhvcNAQELBQAwFjEUMBIGA1UEAwwLRWFzeS1SU0EgQ0EwHhcNMTkwODI4MTYyNTU5WhcNMjkwODI1MTYyNTU5WjAWMRQwEgYDVQQDDAtFYXN5LVJTQSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK5m5elxhQfMp/3aVJ4JnpN9PUSz6LlP6LePAPFU7gqohVVFVtDkChJAG3FNkNQNlieVTja/bgH9IcC6oKbROwdY1h0MvNV8AHHigvl03WuJD8g2ReVFXXwsnrPmKXCFzQyMI6TYk3m2gYrXsZOU1GLnfMRC3KAMRgE2F45twOs9hqG169YJ6mM2eQjzjCHWI6S2/iUYvYxRkCOlYUbLsMD/AhgAf1plzg6LPqNxtdlwxZnA0ytgkmhK67HtzJu0+ovUCsMv0RwcMhsEo9T8nyFAGt9XLZ63X5WpBCTUApaAUhnG0XnerjmUWb6eUWw4zev54sEfY5F3x002iQaW6cECAwEAAaOBkDCBjTAdBgNVHQ4EFgQU4CBUbZsS2GaNIkGRz/cBsD5ivjswUQYDVR0jBEowSIAU4CBUbZsS2GaNIkGRz/cBsD5ivjuhGqQYMBYxFDASBgNVBAMMC0Vhc3ktUlNBIENBghR8hE5uNY1QDiPFD/THwE4K8TZXDjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAKB3V4HIzoiO/Ch6WMj9bLJ2FGbpkMrcb/Eq01hT5zcfKD66lVS1MlK+cRL446Z2b2KDP1oFyVs+qmrmtdwrWgD+nfe2sBmmIHo9m9KygMkEOfG3MghGTEcS+0cTKEcoHYWYyOqQh6jnedXY8Cdm4GM1hAc9MiL3/sqV8YCVSLNnkoNysmr06/rZ0MCUZPGUtRmfd0heWhrfzAKw2HLgX+RAmpOE2MZqWcjvqKGyaRiaZks4nJkP6521aC2Lgp0HhCz1j8/uQ5ldoDszCnu/iro0NAsNtudTMD+YoLQxLqdleIh6CW+illc2VdXwj7mn6J04yns9jfE2jRjW/yTLFuQ==
}
verifier leaf {
folder ../
folder ../
}
}
}
----------
{
"apps": {
"http": {
"servers": {
"srv0": {
"listen": [
":443"
],
"routes": [
{
"match": [
{
"host": [
"localhost"
]
}
],
"handle": [
{
"handler": "subroute",
"routes": [
{
"handle": [
{
"body": "hello from localhost",
"handler": "static_response"
}
]
}
]
}
],
"terminal": true
}
],
"tls_connection_policies": [
{
"match": {
"sni": [
"localhost"
]
},
"client_authentication": {
"ca": {
"provider": "inline",
"trusted_ca_certs": [
"MIIDSzCCAjOgAwIBAgIUfIRObjWNUA4jxQ/0x8BOCvE2Vw4wDQYJKoZIhvcNAQELBQAwFjEUMBIGA1UEAwwLRWFzeS1SU0EgQ0EwHhcNMTkwODI4MTYyNTU5WhcNMjkwODI1MTYyNTU5WjAWMRQwEgYDVQQDDAtFYXN5LVJTQSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK5m5elxhQfMp/3aVJ4JnpN9PUSz6LlP6LePAPFU7gqohVVFVtDkChJAG3FNkNQNlieVTja/bgH9IcC6oKbROwdY1h0MvNV8AHHigvl03WuJD8g2ReVFXXwsnrPmKXCFzQyMI6TYk3m2gYrXsZOU1GLnfMRC3KAMRgE2F45twOs9hqG169YJ6mM2eQjzjCHWI6S2/iUYvYxRkCOlYUbLsMD/AhgAf1plzg6LPqNxtdlwxZnA0ytgkmhK67HtzJu0+ovUCsMv0RwcMhsEo9T8nyFAGt9XLZ63X5WpBCTUApaAUhnG0XnerjmUWb6eUWw4zev54sEfY5F3x002iQaW6cECAwEAAaOBkDCBjTAdBgNVHQ4EFgQU4CBUbZsS2GaNIkGRz/cBsD5ivjswUQYDVR0jBEowSIAU4CBUbZsS2GaNIkGRz/cBsD5ivjuhGqQYMBYxFDASBgNVBAMMC0Vhc3ktUlNBIENBghR8hE5uNY1QDiPFD/THwE4K8TZXDjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAKB3V4HIzoiO/Ch6WMj9bLJ2FGbpkMrcb/Eq01hT5zcfKD66lVS1MlK+cRL446Z2b2KDP1oFyVs+qmrmtdwrWgD+nfe2sBmmIHo9m9KygMkEOfG3MghGTEcS+0cTKEcoHYWYyOqQh6jnedXY8Cdm4GM1hAc9MiL3/sqV8YCVSLNnkoNysmr06/rZ0MCUZPGUtRmfd0heWhrfzAKw2HLgX+RAmpOE2MZqWcjvqKGyaRiaZks4nJkP6521aC2Lgp0HhCz1j8/uQ5ldoDszCnu/iro0NAsNtudTMD+YoLQxLqdleIh6CW+illc2VdXwj7mn6J04yns9jfE2jRjW/yTLFuQ=="
]
},
"verifiers": [
{
"leaf_certs_loaders": [
{
"folders": [
"../"
],
"loader": "folder"
},
{
"folders": [
"../"
],
"loader": "folder"
}
],
"verifier": "leaf"
}
],
"mode": "request"
}
},
{}
]
}
}
}
}
}
@@ -0,0 +1,9 @@
localhost
tls {
propagation_delay 10s
dns_ttl 5m
}
----------
parsing caddyfile tokens for 'tls': setting DNS challenge options [propagation_delay, dns_ttl] requires a DNS provider (set with the 'dns' subdirective or 'acme_dns' global option), at Caddyfile:6
@@ -0,0 +1,79 @@
{
acme_dns mock foo
}
localhost {
tls {
dns mock bar
resolvers 8.8.8.8 8.8.4.4
}
}
----------
{
"apps": {
"http": {
"servers": {
"srv0": {
"listen": [
":443"
],
"routes": [
{
"match": [
{
"host": [
"localhost"
]
}
],
"terminal": true
}
]
}
}
},
"tls": {
"automation": {
"policies": [
{
"subjects": [
"localhost"
],
"issuers": [
{
"challenges": {
"dns": {
"provider": {
"argument": "bar",
"name": "mock"
},
"resolvers": [
"8.8.8.8",
"8.8.4.4"
]
}
},
"module": "acme"
}
]
},
{
"issuers": [
{
"challenges": {
"dns": {
"provider": {
"argument": "foo",
"name": "mock"
}
}
},
"module": "acme"
}
]
}
]
}
}
}
}
@@ -0,0 +1,68 @@
{
dns mock foo
}
localhost {
tls {
dns mock bar
resolvers 8.8.8.8 8.8.4.4
}
}
----------
{
"apps": {
"http": {
"servers": {
"srv0": {
"listen": [
":443"
],
"routes": [
{
"match": [
{
"host": [
"localhost"
]
}
],
"terminal": true
}
]
}
}
},
"tls": {
"automation": {
"policies": [
{
"subjects": [
"localhost"
],
"issuers": [
{
"challenges": {
"dns": {
"provider": {
"argument": "bar",
"name": "mock"
},
"resolvers": [
"8.8.8.8",
"8.8.4.4"
]
}
},
"module": "acme"
}
]
}
]
},
"dns": {
"argument": "foo",
"name": "mock"
}
}
}
}
@@ -0,0 +1,7 @@
:443 {
tls {
propagation_timeout 30s
}
}
----------
parsing caddyfile tokens for 'tls': setting DNS challenge options [propagation_timeout] requires a DNS provider (set with the 'dns' subdirective or 'acme_dns' global option), at Caddyfile:4
@@ -0,0 +1,7 @@
:443 {
tls {
propagation_delay 30s
}
}
----------
parsing caddyfile tokens for 'tls': setting DNS challenge options [propagation_delay] requires a DNS provider (set with the 'dns' subdirective or 'acme_dns' global option), at Caddyfile:4
@@ -0,0 +1,76 @@
{
acme_dns mock
}
localhost {
tls {
resolvers 8.8.8.8 8.8.4.4
}
}
----------
{
"apps": {
"http": {
"servers": {
"srv0": {
"listen": [
":443"
],
"routes": [
{
"match": [
{
"host": [
"localhost"
]
}
],
"terminal": true
}
]
}
}
},
"tls": {
"automation": {
"policies": [
{
"subjects": [
"localhost"
],
"issuers": [
{
"challenges": {
"dns": {
"provider": {
"name": "mock"
},
"resolvers": [
"8.8.8.8",
"8.8.4.4"
]
}
},
"module": "acme"
}
]
},
{
"issuers": [
{
"challenges": {
"dns": {
"provider": {
"name": "mock"
}
}
},
"module": "acme"
}
]
}
]
}
}
}
}
@@ -2,6 +2,7 @@ localhost
respond "hello from localhost"
tls {
dns mock
dns_ttl 5m10s
}
----------
@@ -54,6 +55,9 @@ tls {
{
"challenges": {
"dns": {
"provider": {
"name": "mock"
},
"ttl": 310000000000
}
},
@@ -2,6 +2,7 @@ localhost
respond "hello from localhost"
tls {
dns mock
propagation_delay 5m10s
propagation_timeout 10m20s
}
@@ -56,7 +57,10 @@ tls {
"challenges": {
"dns": {
"propagation_delay": 310000000000,
"propagation_timeout": 620000000000
"propagation_timeout": 620000000000,
"provider": {
"name": "mock"
}
}
},
"module": "acme"
+39 -21
View File
@@ -9,8 +9,8 @@ import (
"strings"
"testing"
"github.com/caddyserver/caddy/v2/caddyconfig"
"github.com/caddyserver/caddy/v2/caddytest"
_ "github.com/caddyserver/caddy/v2/internal/testmocks"
)
@@ -28,30 +28,48 @@ func TestCaddyfileAdaptToJSON(t *testing.T) {
if f.IsDir() {
continue
}
// read the test file
filename := f.Name()
data, err := os.ReadFile("./caddyfile_adapt/" + filename)
if err != nil {
t.Errorf("failed to read %s dir: %s", filename, err)
}
// split the Caddyfile (first) and JSON (second) parts
// (append newline to Caddyfile to match formatter expectations)
parts := strings.Split(string(data), "----------")
caddyfile, json := strings.TrimSpace(parts[0])+"\n", strings.TrimSpace(parts[1])
// run each file as a subtest, so that we can see which one fails more easily
t.Run(filename, func(t *testing.T) {
// read the test file
data, err := os.ReadFile("./caddyfile_adapt/" + filename)
if err != nil {
t.Errorf("failed to read %s dir: %s", filename, err)
}
// replace windows newlines in the json with unix newlines
json = winNewlines.ReplaceAllString(json, "\n")
// split the Caddyfile (first) and JSON (second) parts
// (append newline to Caddyfile to match formatter expectations)
parts := strings.Split(string(data), "----------")
caddyfile, expected := strings.TrimSpace(parts[0])+"\n", strings.TrimSpace(parts[1])
// replace os-specific default path for file_server's hide field
replacePath, _ := jsonMod.Marshal(fmt.Sprint(".", string(filepath.Separator), "Caddyfile"))
json = strings.ReplaceAll(json, `"./Caddyfile"`, string(replacePath))
// replace windows newlines in the json with unix newlines
expected = winNewlines.ReplaceAllString(expected, "\n")
// run the test
ok := caddytest.CompareAdapt(t, filename, caddyfile, "caddyfile", json)
if !ok {
t.Errorf("failed to adapt %s", filename)
}
// replace os-specific default path for file_server's hide field
replacePath, _ := jsonMod.Marshal(fmt.Sprint(".", string(filepath.Separator), "Caddyfile"))
expected = strings.ReplaceAll(expected, `"./Caddyfile"`, string(replacePath))
// if the expected output is JSON, compare it
if len(expected) > 0 && expected[0] == '{' {
ok := caddytest.CompareAdapt(t, filename, caddyfile, "caddyfile", expected)
if !ok {
t.Errorf("failed to adapt %s", filename)
}
return
}
// otherwise, adapt the Caddyfile and check for errors
cfgAdapter := caddyconfig.GetAdapter("caddyfile")
_, _, err = cfgAdapter.Adapt([]byte(caddyfile), nil)
if err == nil {
t.Errorf("expected error for %s but got none", filename)
} else {
normalizedErr := winNewlines.ReplaceAllString(err.Error(), "\n")
if !strings.Contains(normalizedErr, expected) {
t.Errorf("expected error for %s to contain:\n%s\nbut got:\n%s", filename, expected, normalizedErr)
}
}
})
}
}
+40 -1
View File
@@ -615,7 +615,6 @@ func TestReplaceWithReplacementPlaceholder(t *testing.T) {
respond "{query}"`, "caddyfile")
tester.AssertGetResponse("http://localhost:9080/endpoint?placeholder=baz&foo=bar", 200, "foo=baz&placeholder=baz")
}
func TestReplaceWithKeyPlaceholder(t *testing.T) {
@@ -783,6 +782,46 @@ func TestHandleErrorRangeAndCodes(t *testing.T) {
tester.AssertGetResponse("http://localhost:9080/private", 410, "Error in the [400 .. 499] range")
}
func TestHandleErrorSubHandlers(t *testing.T) {
tester := caddytest.NewTester(t)
tester.InitServer(`{
admin localhost:2999
http_port 9080
}
localhost:9080 {
root * /srv
file_server
error /*/internalerr* "Internal Server Error" 500
handle_errors 404 {
handle /en/* {
respond "not found" 404
}
handle /es/* {
respond "no encontrado" 404
}
handle {
respond "default not found"
}
}
handle_errors {
handle {
respond "Default error"
}
handle /en/* {
respond "English error"
}
}
}
`, "caddyfile")
// act and assert
tester.AssertGetResponse("http://localhost:9080/en/notfound", 404, "not found")
tester.AssertGetResponse("http://localhost:9080/es/notfound", 404, "no encontrado")
tester.AssertGetResponse("http://localhost:9080/notfound", 404, "default not found")
tester.AssertGetResponse("http://localhost:9080/es/internalerr", 500, "Default error")
tester.AssertGetResponse("http://localhost:9080/en/internalerr", 500, "English error")
}
func TestInvalidSiteAddressesAsDirectives(t *testing.T) {
type testCase struct {
config, expectedError string
+129
View File
@@ -0,0 +1,129 @@
package integration
import (
"fmt"
"net/http"
"slices"
"strings"
"testing"
"github.com/caddyserver/caddy/v2/caddytest"
)
func newH2ListenerWithVersionsWithTLSTester(t *testing.T, serverVersions []string, clientVersions []string) *caddytest.Tester {
const baseConfig = `
{
skip_install_trust
admin localhost:2999
http_port 9080
https_port 9443
servers :9443 {
protocols %s
}
}
localhost {
respond "{http.request.tls.proto} {http.request.proto}"
}
`
tester := caddytest.NewTester(t)
tester.InitServer(fmt.Sprintf(baseConfig, strings.Join(serverVersions, " ")), "caddyfile")
tr := tester.Client.Transport.(*http.Transport)
tr.TLSClientConfig.NextProtos = clientVersions
tr.Protocols = new(http.Protocols)
if slices.Contains(clientVersions, "h2") {
tr.ForceAttemptHTTP2 = true
tr.Protocols.SetHTTP2(true)
}
if !slices.Contains(clientVersions, "http/1.1") {
tr.Protocols.SetHTTP1(false)
}
return tester
}
func TestH2ListenerWithTLS(t *testing.T) {
tests := []struct {
serverVersions []string
clientVersions []string
expectedBody string
failed bool
}{
{[]string{"h2"}, []string{"h2"}, "h2 HTTP/2.0", false},
{[]string{"h2"}, []string{"http/1.1"}, "", true},
{[]string{"h1"}, []string{"http/1.1"}, "http/1.1 HTTP/1.1", false},
{[]string{"h1"}, []string{"h2"}, "", true},
{[]string{"h2", "h1"}, []string{"h2"}, "h2 HTTP/2.0", false},
{[]string{"h2", "h1"}, []string{"http/1.1"}, "http/1.1 HTTP/1.1", false},
}
for _, tc := range tests {
tester := newH2ListenerWithVersionsWithTLSTester(t, tc.serverVersions, tc.clientVersions)
t.Logf("running with server versions %v and client versions %v:", tc.serverVersions, tc.clientVersions)
if tc.failed {
resp, err := tester.Client.Get("https://localhost:9443")
if err == nil {
t.Errorf("unexpected response: %d", resp.StatusCode)
}
} else {
tester.AssertGetResponse("https://localhost:9443", 200, tc.expectedBody)
}
}
}
func newH2ListenerWithVersionsWithoutTLSTester(t *testing.T, serverVersions []string, clientVersions []string) *caddytest.Tester {
const baseConfig = `
{
skip_install_trust
admin localhost:2999
http_port 9080
servers :9080 {
protocols %s
}
}
http://localhost {
respond "{http.request.proto}"
}
`
tester := caddytest.NewTester(t)
tester.InitServer(fmt.Sprintf(baseConfig, strings.Join(serverVersions, " ")), "caddyfile")
tr := tester.Client.Transport.(*http.Transport)
tr.Protocols = new(http.Protocols)
if slices.Contains(clientVersions, "h2c") {
tr.Protocols.SetHTTP1(false)
tr.Protocols.SetUnencryptedHTTP2(true)
} else if slices.Contains(clientVersions, "http/1.1") {
tr.Protocols.SetHTTP1(true)
tr.Protocols.SetUnencryptedHTTP2(false)
}
return tester
}
func TestH2ListenerWithoutTLS(t *testing.T) {
tests := []struct {
serverVersions []string
clientVersions []string
expectedBody string
failed bool
}{
{[]string{"h2c"}, []string{"h2c"}, "HTTP/2.0", false},
{[]string{"h2c"}, []string{"http/1.1"}, "", true},
{[]string{"h1"}, []string{"http/1.1"}, "HTTP/1.1", false},
{[]string{"h1"}, []string{"h2c"}, "", true},
{[]string{"h2c", "h1"}, []string{"h2c"}, "HTTP/2.0", false},
{[]string{"h2c", "h1"}, []string{"http/1.1"}, "HTTP/1.1", false},
}
for _, tc := range tests {
tester := newH2ListenerWithVersionsWithoutTLSTester(t, tc.serverVersions, tc.clientVersions)
t.Logf("running with server versions %v and client versions %v:", tc.serverVersions, tc.clientVersions)
if tc.failed {
resp, err := tester.Client.Get("http://localhost:9080")
if err == nil {
t.Errorf("unexpected response: %d", resp.StatusCode)
}
} else {
tester.AssertGetResponse("http://localhost:9080", 200, tc.expectedBody)
}
}
}
+21 -8
View File
@@ -3,10 +3,11 @@ package integration
import (
"context"
"github.com/caddyserver/caddy/v2"
"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
"github.com/caddyserver/certmagic"
"github.com/libdns/libdns"
"github.com/caddyserver/caddy/v2"
"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
)
func init() {
@@ -14,7 +15,9 @@ func init() {
}
// MockDNSProvider is a mock DNS provider, for testing config with DNS modules.
type MockDNSProvider struct{}
type MockDNSProvider struct {
Argument string `json:"argument,omitempty"` // optional argument useful for testing
}
// CaddyModule returns the Caddy module information.
func (MockDNSProvider) CaddyModule() caddy.ModuleInfo {
@@ -30,7 +33,15 @@ func (MockDNSProvider) Provision(ctx caddy.Context) error {
}
// UnmarshalCaddyfile sets up the module from Caddyfile tokens.
func (MockDNSProvider) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
func (p *MockDNSProvider) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
d.Next() // consume directive name
if d.NextArg() {
p.Argument = d.Val()
}
if d.NextArg() {
return d.Errf("unexpected argument '%s'", d.Val())
}
return nil
}
@@ -55,7 +66,9 @@ func (MockDNSProvider) SetRecords(ctx context.Context, zone string, recs []libdn
}
// Interface guard
var _ caddyfile.Unmarshaler = (*MockDNSProvider)(nil)
var _ certmagic.DNSProvider = (*MockDNSProvider)(nil)
var _ caddy.Provisioner = (*MockDNSProvider)(nil)
var _ caddy.Module = (*MockDNSProvider)(nil)
var (
_ caddyfile.Unmarshaler = (*MockDNSProvider)(nil)
_ certmagic.DNSProvider = (*MockDNSProvider)(nil)
_ caddy.Provisioner = (*MockDNSProvider)(nil)
_ caddy.Module = (*MockDNSProvider)(nil)
)
+2 -1
View File
@@ -13,9 +13,10 @@ import (
"testing"
"time"
"github.com/caddyserver/caddy/v2/caddytest"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
"github.com/caddyserver/caddy/v2/caddytest"
)
// (see https://github.com/caddyserver/caddy/issues/3556 for use case)
+72 -14
View File
@@ -24,6 +24,7 @@ import (
"io"
"io/fs"
"log"
"maps"
"net"
"net/http"
"os"
@@ -171,9 +172,19 @@ func cmdStart(fl Flags) (int, error) {
func cmdRun(fl Flags) (int, error) {
caddy.TrapSignals()
logger := caddy.Log()
// set up buffered logging for early startup
// so that we can hold onto logs until after
// the config is loaded (or fails to load)
// so that we can write the logs to the user's
// configured output. we must be sure to flush
// on any error before the config is loaded.
logger, defaultLogger, logBuffer := caddy.BufferedLog()
undoMaxProcs := setResourceLimits(logger)
defer undoMaxProcs()
// release the local reference to the undo function so it can be GC'd;
// the deferred call above has already captured the actual function value.
undoMaxProcs = nil //nolint:ineffassign,wastedassign
configFlag := fl.String("config")
configAdapterFlag := fl.String("adapter")
@@ -186,6 +197,7 @@ func cmdRun(fl Flags) (int, error) {
// load all additional envs as soon as possible
err := handleEnvFileFlag(fl)
if err != nil {
logBuffer.FlushTo(defaultLogger)
return caddy.ExitCodeFailedStartup, err
}
@@ -203,6 +215,7 @@ func cmdRun(fl Flags) (int, error) {
logger.Info("no autosave file exists", zap.String("autosave_file", caddy.ConfigAutosavePath))
resumeFlag = false
} else if err != nil {
logBuffer.FlushTo(defaultLogger)
return caddy.ExitCodeFailedStartup, err
} else {
if configFlag == "" {
@@ -218,9 +231,11 @@ func cmdRun(fl Flags) (int, error) {
}
// we don't use 'else' here since this value might have been changed in 'if' block; i.e. not mutually exclusive
var configFile string
var adapterUsed string
if !resumeFlag {
config, configFile, err = LoadConfig(configFlag, configAdapterFlag)
config, configFile, adapterUsed, err = LoadConfig(configFlag, configAdapterFlag)
if err != nil {
logBuffer.FlushTo(defaultLogger)
return caddy.ExitCodeFailedStartup, err
}
}
@@ -235,11 +250,35 @@ func cmdRun(fl Flags) (int, error) {
}
}
// If we have a source config file (we're running via 'caddy run --config ...'),
// record it so SIGUSR1 can reload from the same file. Also provide a callback
// that knows how to load/adapt that source when requested by the main process.
if configFile != "" {
caddy.SetLastConfig(configFile, adapterUsed, func(file, adapter string) error {
cfg, _, _, err := LoadConfig(file, adapter)
if err != nil {
return err
}
return caddy.Load(cfg, true)
})
}
// run the initial config
err = caddy.Load(config, true)
if err != nil {
logBuffer.FlushTo(defaultLogger)
return caddy.ExitCodeFailedStartup, fmt.Errorf("loading initial config: %v", err)
}
// release the reference to the config so it can be GC'd
config = nil //nolint:ineffassign,wastedassign
// at this stage the config will have replaced the
// default logger to the configured one, so we can
// log normally, now that the config is running.
// also clear our ref to the buffer so it can get GC'd
logger = caddy.Log()
defaultLogger = nil //nolint:ineffassign,wastedassign
logBuffer = nil //nolint:wastedassign,ineffassign
logger.Info("serving initial configuration")
// if we are to report to another process the successful start
@@ -255,18 +294,22 @@ func cmdRun(fl Flags) (int, error) {
return caddy.ExitCodeFailedStartup,
fmt.Errorf("dialing confirmation address: %v", err)
}
defer conn.Close()
_, err = conn.Write(confirmationBytes)
if err != nil {
return caddy.ExitCodeFailedStartup,
fmt.Errorf("writing confirmation bytes to %s: %v", pingbackFlag, err)
}
// close (non-defer because we `select {}` below)
// and release references so they can be GC'd
conn.Close()
confirmationBytes = nil //nolint:ineffassign,wastedassign
conn = nil //nolint:wastedassign,ineffassign
}
// if enabled, reload config file automatically on changes
// (this better only be used in dev!)
if watchFlag {
go watchConfigFile(configFile, configAdapterFlag)
go watchConfigFile(configFile, adapterUsed)
}
// warn if the environment does not provide enough information about the disk
@@ -288,6 +331,9 @@ func cmdRun(fl Flags) (int, error) {
}
}
// release the last local logger reference
logger = nil //nolint:wastedassign,ineffassign
select {}
}
@@ -318,7 +364,7 @@ func cmdReload(fl Flags) (int, error) {
forceFlag := fl.Bool("force")
// get the config in caddy's native format
config, configFile, err := LoadConfig(configFlag, configAdapterFlag)
config, configFile, adapterUsed, err := LoadConfig(configFlag, configAdapterFlag)
if err != nil {
return caddy.ExitCodeFailedStartup, err
}
@@ -336,6 +382,10 @@ func cmdReload(fl Flags) (int, error) {
if forceFlag {
headers.Set("Cache-Control", "must-revalidate")
}
// Provide the source file/adapter to the running process so it can
// preserve its last-config knowledge if this reload came from the same source.
headers.Set("Caddy-Config-Source-File", configFile)
headers.Set("Caddy-Config-Source-Adapter", adapterUsed)
resp, err := AdminAPIRequest(adminAddr, http.MethodPost, "/load", headers, bytes.NewReader(config))
if err != nil {
@@ -440,16 +490,20 @@ func cmdEnviron(fl Flags) (int, error) {
}
func cmdAdaptConfig(fl Flags) (int, error) {
inputFlag := fl.String("config")
configFlag := fl.String("config")
adapterFlag := fl.String("adapter")
prettyFlag := fl.Bool("pretty")
validateFlag := fl.Bool("validate")
var err error
inputFlag, err = configFileWithRespectToDefault(caddy.Log(), inputFlag)
configFlag, err = configFileWithRespectToDefault(caddy.Log(), configFlag)
if err != nil {
return caddy.ExitCodeFailedStartup, err
}
if configFlag == "" {
return caddy.ExitCodeFailedStartup,
fmt.Errorf("input file required when there is no Caddyfile in current directory (use --config flag)")
}
// load all additional envs as soon as possible
err = handleEnvFileFlag(fl)
@@ -468,13 +522,19 @@ func cmdAdaptConfig(fl Flags) (int, error) {
fmt.Errorf("unrecognized config adapter: %s", adapterFlag)
}
input, err := os.ReadFile(inputFlag)
var input []byte
// read from stdin if the file name is "-"
if configFlag == "-" {
input, err = io.ReadAll(os.Stdin)
} else {
input, err = os.ReadFile(configFlag)
}
if err != nil {
return caddy.ExitCodeFailedStartup,
fmt.Errorf("reading input file: %v", err)
}
opts := map[string]any{"filename": inputFlag}
opts := map[string]any{"filename": configFlag}
adaptedConfig, warnings, err := cfgAdapter.Adapt(input, opts)
if err != nil {
@@ -540,7 +600,7 @@ func cmdValidateConfig(fl Flags) (int, error) {
fmt.Errorf("input file required when there is no Caddyfile in current directory (use --config flag)")
}
input, _, err := LoadConfig(configFlag, adapterFlag)
input, _, _, err := LoadConfig(configFlag, adapterFlag)
if err != nil {
return caddy.ExitCodeFailedStartup, err
}
@@ -703,9 +763,7 @@ func AdminAPIRequest(adminAddr, method, uri string, headers http.Header, body io
if body != nil {
req.Header.Set("Content-Type", "application/json")
}
for k, v := range headers {
req.Header[k] = v
}
maps.Copy(req.Header, headers)
// make an HTTP client that dials our network type, since admin
// endpoints aren't always TCP, which is what the default transport
@@ -757,7 +815,7 @@ func DetermineAdminAPIAddress(address string, config []byte, configFile, configA
loadedConfig := config
if len(loadedConfig) == 0 {
// get the config in caddy's native format
loadedConfig, loadedConfigFile, err = LoadConfig(configFile, configAdapter)
loadedConfig, loadedConfigFile, _, err = LoadConfig(configFile, configAdapter)
if err != nil {
return "", err
}
+50 -23
View File
@@ -20,6 +20,7 @@ import (
"os"
"regexp"
"strings"
"sync"
"github.com/spf13/cobra"
"github.com/spf13/cobra/doc"
@@ -80,10 +81,16 @@ type CommandFunc func(Flags) (int, error)
// Commands returns a list of commands initialised by
// RegisterCommand
func Commands() map[string]Command {
commandsMu.RLock()
defer commandsMu.RUnlock()
return commands
}
var commands = make(map[string]Command)
var (
commandsMu sync.RWMutex
commands = make(map[string]Command)
)
func init() {
RegisterCommand(Command{
@@ -286,6 +293,8 @@ zero exit status will be returned.
If --envfile is specified, an environment file with environment variables
in the KEY=VALUE format will be loaded into the Caddy process.
If you wish to use stdin instead of a regular file, use - as the path.
`,
CobraFunc: func(cmd *cobra.Command) {
cmd.Flags().StringP("config", "c", "", "Configuration file to adapt (required)")
@@ -383,7 +392,7 @@ lines will be prefixed with '-' and '+' where they differ. Note that
unchanged lines are prefixed with two spaces for alignment, and that this
is not a valid patch format.
If you wish you use stdin instead of a regular file, use - as the path.
If you wish to use stdin instead of a regular file, use - as the path.
When reading from stdin, the --overwrite flag has no effect: the result
is always printed to stdout.
`,
@@ -441,7 +450,7 @@ EXPERIMENTAL: May be changed or removed.
})
defaultFactory.Use(func(rootCmd *cobra.Command) {
rootCmd.AddCommand(caddyCmdToCobra(Command{
manpageCommand := Command{
Name: "manpage",
Usage: "--directory <path>",
Short: "Generates the manual pages for Caddy commands",
@@ -471,11 +480,12 @@ argument of --directory. If the directory does not exist, it will be created.
return caddy.ExitCodeSuccess, nil
})
},
}))
}
// source: https://github.com/spf13/cobra/blob/main/shell_completions.md
rootCmd.AddCommand(&cobra.Command{
Use: "completion [bash|zsh|fish|powershell]",
// source: https://github.com/spf13/cobra/blob/6dec1ae26659a130bdb4c985768d1853b0e1bc06/site/content/completions/_index.md
completionCommand := Command{
Name: "completion",
Usage: "[bash|zsh|fish|powershell]",
Short: "Generate completion script",
Long: fmt.Sprintf(`To load completions:
@@ -516,24 +526,37 @@ argument of --directory. If the directory does not exist, it will be created.
PS> %[1]s completion powershell > %[1]s.ps1
# and source this file from your PowerShell profile.
`, rootCmd.Root().Name()),
DisableFlagsInUseLine: true,
ValidArgs: []string{"bash", "zsh", "fish", "powershell"},
Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs),
RunE: func(cmd *cobra.Command, args []string) error {
switch args[0] {
case "bash":
return cmd.Root().GenBashCompletion(os.Stdout)
case "zsh":
return cmd.Root().GenZshCompletion(os.Stdout)
case "fish":
return cmd.Root().GenFishCompletion(os.Stdout, true)
case "powershell":
return cmd.Root().GenPowerShellCompletionWithDesc(os.Stdout)
default:
return fmt.Errorf("unrecognized shell: %s", args[0])
CobraFunc: func(cmd *cobra.Command) {
cmd.DisableFlagsInUseLine = true
cmd.ValidArgs = []string{"bash", "zsh", "fish", "powershell"}
cmd.Args = cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs)
cmd.RunE = func(cmd *cobra.Command, args []string) error {
switch args[0] {
case "bash":
return cmd.Root().GenBashCompletion(os.Stdout)
case "zsh":
return cmd.Root().GenZshCompletion(os.Stdout)
case "fish":
return cmd.Root().GenFishCompletion(os.Stdout, true)
case "powershell":
return cmd.Root().GenPowerShellCompletionWithDesc(os.Stdout)
default:
return fmt.Errorf("unrecognized shell: %s", args[0])
}
}
},
})
}
rootCmd.AddCommand(caddyCmdToCobra(manpageCommand))
rootCmd.AddCommand(caddyCmdToCobra(completionCommand))
// add manpage and completion commands to the map of
// available commands, because they're not registered
// through RegisterCommand.
commandsMu.Lock()
commands[manpageCommand.Name] = manpageCommand
commands[completionCommand.Name] = completionCommand
commandsMu.Unlock()
})
}
@@ -552,6 +575,9 @@ argument of --directory. If the directory does not exist, it will be created.
//
// This function should be used in init().
func RegisterCommand(cmd Command) {
commandsMu.Lock()
defer commandsMu.Unlock()
if cmd.Name == "" {
panic("command name is required")
}
@@ -570,6 +596,7 @@ func RegisterCommand(cmd Command) {
defaultFactory.Use(func(rootCmd *cobra.Command) {
rootCmd.AddCommand(caddyCmdToCobra(cmd))
})
commands[cmd.Name] = cmd
}
var commandNameRegex = regexp.MustCompile(`^[a-z0-9]$|^([a-z0-9]+-?[a-z0-9]*)+[a-z0-9]$`)
+39
View File
@@ -0,0 +1,39 @@
package caddycmd
import (
"maps"
"reflect"
"slices"
"testing"
)
func TestCommandsAreAvailable(t *testing.T) {
// trigger init, and build the default factory, so that
// all commands from this package are available
cmd := defaultFactory.Build()
if cmd == nil {
t.Fatal("default factory failed to build")
}
// check that the default factory has 17 commands; it doesn't
// include the commands registered through calls to init in
// other packages
cmds := Commands()
if len(cmds) != 17 {
t.Errorf("expected 17 commands, got %d", len(cmds))
}
commandNames := slices.Collect(maps.Keys(cmds))
slices.Sort(commandNames)
expectedCommandNames := []string{
"adapt", "add-package", "build-info", "completion",
"environ", "fmt", "list-modules", "manpage",
"reload", "remove-package", "run", "start",
"stop", "storage", "upgrade", "validate", "version",
}
if !reflect.DeepEqual(expectedCommandNames, commandNames) {
t.Errorf("expected %v, got %v", expectedCommandNames, commandNames)
}
}
+19 -14
View File
@@ -100,7 +100,12 @@ func handlePingbackConn(conn net.Conn, expect []byte) error {
// there is no config available. It prints any warnings to stderr,
// and returns the resulting JSON config bytes along with
// the name of the loaded config file (if any).
func LoadConfig(configFile, adapterName string) ([]byte, string, error) {
// The return values are:
// - config bytes (nil if no config)
// - config file used ("" if none)
// - adapter used ("" if none)
// - error, if any
func LoadConfig(configFile, adapterName string) ([]byte, string, string, error) {
return loadConfigWithLogger(caddy.Log(), configFile, adapterName)
}
@@ -138,7 +143,7 @@ func isCaddyfile(configFile, adapterName string) (bool, error) {
return false, nil
}
func loadConfigWithLogger(logger *zap.Logger, configFile, adapterName string) ([]byte, string, error) {
func loadConfigWithLogger(logger *zap.Logger, configFile, adapterName string) ([]byte, string, string, error) {
// if no logger is provided, use a nop logger
// just so we don't have to check for nil
if logger == nil {
@@ -147,7 +152,7 @@ func loadConfigWithLogger(logger *zap.Logger, configFile, adapterName string) ([
// specifying an adapter without a config file is ambiguous
if adapterName != "" && configFile == "" {
return nil, "", fmt.Errorf("cannot adapt config without config file (use --config)")
return nil, "", "", fmt.Errorf("cannot adapt config without config file (use --config)")
}
// load initial config and adapter
@@ -158,13 +163,13 @@ func loadConfigWithLogger(logger *zap.Logger, configFile, adapterName string) ([
if configFile == "-" {
config, err = io.ReadAll(os.Stdin)
if err != nil {
return nil, "", fmt.Errorf("reading config from stdin: %v", err)
return nil, "", "", fmt.Errorf("reading config from stdin: %v", err)
}
logger.Info("using config from stdin")
} else {
config, err = os.ReadFile(configFile)
if err != nil {
return nil, "", fmt.Errorf("reading config from file: %v", err)
return nil, "", "", fmt.Errorf("reading config from file: %v", err)
}
logger.Info("using config from file", zap.String("file", configFile))
}
@@ -179,7 +184,7 @@ func loadConfigWithLogger(logger *zap.Logger, configFile, adapterName string) ([
cfgAdapter = nil
} else if err != nil {
// default Caddyfile exists, but error reading it
return nil, "", fmt.Errorf("reading default Caddyfile: %v", err)
return nil, "", "", fmt.Errorf("reading default Caddyfile: %v", err)
} else {
// success reading default Caddyfile
configFile = "Caddyfile"
@@ -191,14 +196,14 @@ func loadConfigWithLogger(logger *zap.Logger, configFile, adapterName string) ([
if yes, err := isCaddyfile(configFile, adapterName); yes {
adapterName = "caddyfile"
} else if err != nil {
return nil, "", err
return nil, "", "", err
}
// load config adapter
if adapterName != "" {
cfgAdapter = caddyconfig.GetAdapter(adapterName)
if cfgAdapter == nil {
return nil, "", fmt.Errorf("unrecognized config adapter: %s", adapterName)
return nil, "", "", fmt.Errorf("unrecognized config adapter: %s", adapterName)
}
}
@@ -208,7 +213,7 @@ func loadConfigWithLogger(logger *zap.Logger, configFile, adapterName string) ([
"filename": configFile,
})
if err != nil {
return nil, "", fmt.Errorf("adapting config using %s: %v", adapterName, err)
return nil, "", "", fmt.Errorf("adapting config using %s: %v", adapterName, err)
}
logger.Info("adapted config to JSON", zap.String("adapter", adapterName))
for _, warn := range warnings {
@@ -226,11 +231,11 @@ func loadConfigWithLogger(logger *zap.Logger, configFile, adapterName string) ([
// validate that the config is at least valid JSON
err = json.Unmarshal(config, new(any))
if err != nil {
return nil, "", fmt.Errorf("config is not valid JSON: %v; did you mean to use a config adapter (the --adapter flag)?", err)
return nil, "", "", fmt.Errorf("config is not valid JSON: %v; did you mean to use a config adapter (the --adapter flag)?", err)
}
}
return config, configFile, nil
return config, configFile, adapterName, nil
}
// watchConfigFile watches the config file at filename for changes
@@ -256,7 +261,7 @@ func watchConfigFile(filename, adapterName string) {
}
// get current config
lastCfg, _, err := loadConfigWithLogger(nil, filename, adapterName)
lastCfg, _, _, err := loadConfigWithLogger(nil, filename, adapterName)
if err != nil {
logger().Error("unable to load latest config", zap.Error(err))
return
@@ -268,7 +273,7 @@ func watchConfigFile(filename, adapterName string) {
//nolint:staticcheck
for range time.Tick(1 * time.Second) {
// get current config
newCfg, _, err := loadConfigWithLogger(nil, filename, adapterName)
newCfg, _, _, err := loadConfigWithLogger(nil, filename, adapterName)
if err != nil {
logger().Error("unable to load latest config", zap.Error(err))
return
@@ -418,7 +423,7 @@ func parseEnvFile(envInput io.Reader) (map[string]string, error) {
// quoted value: support newlines
if strings.HasPrefix(val, `"`) || strings.HasPrefix(val, "'") {
quote := string(val[0])
for !(strings.HasSuffix(line, quote) && !strings.HasSuffix(line, `\`+quote)) {
for !strings.HasSuffix(line, quote) || strings.HasSuffix(line, `\`+quote) {
val = strings.ReplaceAll(val, `\`+quote, quote)
if !scanner.Scan() {
break

Some files were not shown because too many files have changed in this diff Show More