@marcel91200 / caddy Mirror · read-only / commits / b9f7a1c2
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 11, 03:30 UTC

core: add RFC 3339 time placeholder (#8140)

Zen Dodd committed Oct 5, 2026 at 07:22 UTC b9f7a1c24830d6be8daad27d31dc64603092c9db
2 files changed +36
replacer.go
+2
@@ -406,6 +406,8 @@ func (f globalDefaultReplacementProvider) replace(key string) (any, bool) {
406 // to generate the correct format.
407 // https://github.com/caddyserver/caddy/issues/5773
408 return nowFunc().UTC().Format(http.TimeFormat), true
409 + case "time.now.rfc3339":
410 + return nowFunc().Format(time.RFC3339), true
411 case "time.now.common_log":
412 return nowFunc().Format("02/Jan/2006:15:04:05 -0700"), true
413 case "time.now.year":
replacer_test.go
+34
@@ -21,6 +21,7 @@ import (
21 "runtime"
22 "sync"
23 "testing"
24 + "time"
25 )
26
27 func TestReplacer(t *testing.T) {
@@ -484,6 +485,39 @@ func TestReplacerNewWithoutFile(t *testing.T) {
485 }
486 }
487
488 +func TestReplacerTimeNowRFC3339(t *testing.T) {
489 + originalNowFunc := nowFunc
490 + t.Cleanup(func() { nowFunc = originalNowFunc })
491 +
492 + for _, tc := range []struct {
493 + name string
494 + now time.Time
495 + want string
496 + }{
497 + {
498 + name: "UTC",
499 + now: time.Date(2026, time.October, 3, 4, 30, 0, 123456789, time.UTC),
500 + want: "2026-10-03T04:30:00Z",
501 + },
502 + {
503 + name: "numeric offset",
504 + now: time.Date(2026, time.October, 3, 10, 15, 0, 123456789, time.FixedZone("NPT", 5*60*60+45*60)),
505 + want: "2026-10-03T10:15:00+05:45",
506 + },
507 + } {
508 + t.Run(tc.name, func(t *testing.T) {
509 + nowFunc = func() time.Time { return tc.now }
510 + got, ok := NewReplacer().GetString("time.now.rfc3339")
511 + if !ok {
512 + t.Fatal("time.now.rfc3339 placeholder was not found")
513 + }
514 + if got != tc.want {
515 + t.Fatalf("time.now.rfc3339 = %q; want %q", got, tc.want)
516 + }
517 + })
518 + }
519 +}
520 +
521 func BenchmarkReplacer(b *testing.B) {
522 type testCase struct {
523 name, input, empty string