diff --git a/caddyhttp/httpserver/replacer.go b/caddyhttp/httpserver/replacer.go index b112e8354..0278eb510 100644 --- a/caddyhttp/httpserver/replacer.go +++ b/caddyhttp/httpserver/replacer.go @@ -23,6 +23,8 @@ var requestReplacer = strings.NewReplacer( "\n", "\\n", ) +var now = time.Now + // Replacer is a type which can replace placeholder // substrings in a string with actual values from a // http.Request and ResponseRecorder. Always use @@ -249,7 +251,9 @@ func (r *replacer) getSubstitution(key string) string { case "{uri_escaped}": return url.QueryEscape(r.request.URL.RequestURI()) case "{when}": - return time.Now().Format(timeFormat) + return now().Format(timeFormat) + case "{when_iso}": + return now().UTC().Format(timeFormatISOUTC) case "{file}": _, file := path.Split(r.request.URL.Path) return file @@ -311,6 +315,7 @@ func (r *replacer) Set(key, value string) { const ( timeFormat = "02/Jan/2006:15:04:05 -0700" + timeFormatISOUTC = "2006-01-02T15:04:05Z" // ISO 8601 with timezone to be assumed as UTC headerContentType = "Content-Type" contentTypeJSON = "application/json" contentTypeXML = "application/xml" diff --git a/caddyhttp/httpserver/replacer_test.go b/caddyhttp/httpserver/replacer_test.go index fb5535496..e03aed81c 100644 --- a/caddyhttp/httpserver/replacer_test.go +++ b/caddyhttp/httpserver/replacer_test.go @@ -53,6 +53,13 @@ func TestReplace(t *testing.T) { t.Fatal("Failed to determine hostname\n") } + old := now + now = func() time.Time { + return time.Date(2006, 1, 2, 15, 4, 5, 02, time.FixedZone("hardcoded", -7)) + } + defer func() { + now = old + }() testCases := []struct { template string expect string @@ -61,6 +68,8 @@ func TestReplace(t *testing.T) { {"This host is {host}.", "This host is localhost."}, {"This request method is {method}.", "This request method is POST."}, {"The response status is {status}.", "The response status is 200."}, + {"{when}", "02/Jan/2006:15:04:05 +0000"}, + {"{when_iso}", "2006-01-02T15:04:12Z"}, {"The Custom header is {>Custom}.", "The Custom header is foobarbaz."}, {"The CustomAdd header is {>CustomAdd}.", "The CustomAdd header is caddy."}, {"The request is {request}.", "The request is POST / HTTP/1.1\\r\\nHost: localhost\\r\\nCustom: foobarbaz\\r\\nCustomadd: caddy\\r\\nShorterval: 1\\r\\n\\r\\n."},