From 2943c41884278ec5fc44bcb55d2b9b088838cdc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Mourey?= Date: Mon, 24 Apr 2023 18:36:37 +0200 Subject: templates: Add `fileStat` function (#5497) * Add isDir template function * Update modules/caddyhttp/templates/tplcontext.go Co-authored-by: Mohammed Al Sahaf * Fix funcIsDir return value on error * Fix funcIsDir return false when root file system not specified * Add stat function, remove isDir function * Remove isDir function (really) * Rename stat to fileStat --------- Co-authored-by: Mohammed Al Sahaf --- modules/caddyhttp/templates/tplcontext.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'modules/caddyhttp/templates') diff --git a/modules/caddyhttp/templates/tplcontext.go b/modules/caddyhttp/templates/tplcontext.go index ddad24f..c500381 100644 --- a/modules/caddyhttp/templates/tplcontext.go +++ b/modules/caddyhttp/templates/tplcontext.go @@ -18,6 +18,7 @@ import ( "bytes" "fmt" "io" + "io/fs" "net" "net/http" "os" @@ -79,6 +80,7 @@ func (c *TemplateContext) NewTemplate(tplName string) *template.Template { "markdown": c.funcMarkdown, "splitFrontMatter": c.funcSplitFrontMatter, "listFiles": c.funcListFiles, + "fileStat": c.funcFileStat, "env": c.funcEnv, "placeholder": c.funcPlaceholder, "fileExists": c.funcFileExists, @@ -395,6 +397,21 @@ func (c TemplateContext) funcFileExists(filename string) (bool, error) { return false, nil } +// funcStat returns Stat of a filename +func (c TemplateContext) funcFileStat(filename string) (fs.FileInfo, error) { + if c.Root == nil { + return nil, fmt.Errorf("root file system not specified") + } + + file, err := c.Root.Open(path.Clean(filename)) + if err != nil { + return nil, err + } + defer file.Close() + + return file.Stat() +} + // funcHTTPError returns a structured HTTP handler error. EXPERIMENTAL; SUBJECT TO CHANGE. // Example usage: `{{if not (fileExists $includeFile)}}{{httpError 404}}{{end}}` func (c TemplateContext) funcHTTPError(statusCode int) (bool, error) { -- cgit v1.2.3 From 3443a8a056c7fe1a67cbf64f7e7f8acdc3762416 Mon Sep 17 00:00:00 2001 From: cui fliter Date: Tue, 25 Apr 2023 23:54:42 +0800 Subject: fix some comments (#5508) Signed-off-by: cui fliter --- modules/caddyhttp/templates/tplcontext.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'modules/caddyhttp/templates') diff --git a/modules/caddyhttp/templates/tplcontext.go b/modules/caddyhttp/templates/tplcontext.go index c500381..fb00f4f 100644 --- a/modules/caddyhttp/templates/tplcontext.go +++ b/modules/caddyhttp/templates/tplcontext.go @@ -397,7 +397,7 @@ func (c TemplateContext) funcFileExists(filename string) (bool, error) { return false, nil } -// funcStat returns Stat of a filename +// funcFileStat returns Stat of a filename func (c TemplateContext) funcFileStat(filename string) (fs.FileInfo, error) { if c.Root == nil { return nil, fmt.Errorf("root file system not specified") -- cgit v1.2.3 From 31d75acc9ca5529c300be1ff46ae2dd799fbf9d8 Mon Sep 17 00:00:00 2001 From: kassienull <109551954+kassienull@users.noreply.github.com> Date: Fri, 26 May 2023 12:16:28 -0400 Subject: templates: Add `readFile` action that does not evaluate templates (#5553) * Create an includeRaw template function to include a file without parsing it as a template. Some formatting fixes * Rename to readFile, various docs adjustments --------- Co-authored-by: Francis Lavoie --- modules/caddyhttp/templates/templates.go | 35 +++++++++++++++++++++++++------ modules/caddyhttp/templates/tplcontext.go | 22 +++++++++++++++++-- 2 files changed, 49 insertions(+), 8 deletions(-) (limited to 'modules/caddyhttp/templates') diff --git a/modules/caddyhttp/templates/templates.go b/modules/caddyhttp/templates/templates.go index 449536a..65359d9 100644 --- a/modules/caddyhttp/templates/templates.go +++ b/modules/caddyhttp/templates/templates.go @@ -88,7 +88,11 @@ func init() { // // ##### `httpInclude` // -// Includes the contents of another file by making a virtual HTTP request (also known as a sub-request). The URI path must exist on the same virtual server because the request does not use sockets; instead, the request is crafted in memory and the handler is invoked directly for increased efficiency. +// Includes the contents of another file, and renders it in-place, +// by making a virtual HTTP request (also known as a sub-request). +// The URI path must exist on the same virtual server because the +// request does not use sockets; instead, the request is crafted in +// memory and the handler is invoked directly for increased efficiency. // // ``` // {{httpInclude "/foo/bar?q=val"}} @@ -96,7 +100,13 @@ func init() { // // ##### `import` // -// Imports the contents of another file and adds any template definitions to the template stack. If there are no defitions, the filepath will be the defition name. Any {{ define }} blocks will be accessible by {{ template }} or {{ block }}. Imports must happen before the template or block action is called +// Reads and returns the contents of another file, and parses it +// as a template, adding any template definitions to the template +// stack. If there are no definitions, the filepath will be the +// definition name. Any {{ define }} blocks will be accessible by +// {{ template }} or {{ block }}. Imports must happen before the +// template or block action is called. Note that the contents are +// NOT escaped, so you should only import trusted template files. // // **filename.html** // ``` @@ -113,13 +123,26 @@ func init() { // // ##### `include` // -// Includes the contents of another file and renders in-place. Optionally can pass key-value pairs as arguments to be accessed by the included file. +// Includes the contents of another file, rendering it in-place. +// Optionally can pass key-value pairs as arguments to be accessed +// by the included file. Note that the contents are NOT escaped, +// so you should only include trusted template files. // // ``` // {{include "path/to/file.html"}} // no arguments // {{include "path/to/file.html" "arg1" 2 "value 3"}} // with arguments // ``` // +// ##### `readFile` +// +// Reads and returns the contents of another file, as-is. +// Note that the contents are NOT escaped, so you should +// only read trusted files. +// +// ``` +// {{readFile "path/to/file.html"}} +// ``` +// // ##### `listFiles` // // Returns a list of the files in the given directory, which is relative to the template context's file root. @@ -130,10 +153,10 @@ func init() { // // ##### `markdown` // -// Renders the given Markdown text as HTML. This uses the +// Renders the given Markdown text as HTML and returns it. This uses the // [Goldmark](https://github.com/yuin/goldmark) library, -// which is CommonMark compliant. It also has these plugins -// enabled: Github Flavored Markdown, Footnote and syntax +// which is CommonMark compliant. It also has these extensions +// enabled: Github Flavored Markdown, Footnote, and syntax // highlighting provided by [Chroma](https://github.com/alecthomas/chroma). // // ``` diff --git a/modules/caddyhttp/templates/tplcontext.go b/modules/caddyhttp/templates/tplcontext.go index fb00f4f..5dc4ae5 100644 --- a/modules/caddyhttp/templates/tplcontext.go +++ b/modules/caddyhttp/templates/tplcontext.go @@ -30,7 +30,7 @@ import ( "time" "github.com/Masterminds/sprig/v3" - "github.com/alecthomas/chroma/v2/formatters/html" + chromahtml "github.com/alecthomas/chroma/v2/formatters/html" "github.com/caddyserver/caddy/v2" "github.com/caddyserver/caddy/v2/modules/caddyhttp" "github.com/dustin/go-humanize" @@ -74,6 +74,7 @@ func (c *TemplateContext) NewTemplate(tplName string) *template.Template { // add our own library c.tpl.Funcs(template.FuncMap{ "include": c.funcInclude, + "readFile": c.funcReadFile, "import": c.funcImport, "httpInclude": c.funcHTTPInclude, "stripHTML": c.funcStripHTML, @@ -123,6 +124,23 @@ func (c TemplateContext) funcInclude(filename string, args ...any) (string, erro return bodyBuf.String(), nil } +// funcReadFile returns the contents of a filename relative to the site root. +// Note that included files are NOT escaped, so you should only include +// trusted files. If it is not trusted, be sure to use escaping functions +// in your template. +func (c TemplateContext) funcReadFile(filename string) (string, error) { + bodyBuf := bufPool.Get().(*bytes.Buffer) + bodyBuf.Reset() + defer bufPool.Put(bodyBuf) + + err := c.readFileToBuffer(filename, bodyBuf) + if err != nil { + return "", err + } + + return bodyBuf.String(), nil +} + // readFileToBuffer reads a file into a buffer func (c TemplateContext) readFileToBuffer(filename string, bodyBuf *bytes.Buffer) error { if c.Root == nil { @@ -315,7 +333,7 @@ func (TemplateContext) funcMarkdown(input any) (string, error) { extension.Footnote, highlighting.NewHighlighting( highlighting.WithFormatOptions( - html.WithClasses(true), + chromahtml.WithClasses(true), ), ), ), -- cgit v1.2.3 From 4548b7de8e9880922a563c9d2d9f094b3c1f1622 Mon Sep 17 00:00:00 2001 From: guangwu Date: Sat, 17 Jun 2023 11:27:57 +0800 Subject: chore: remove refs of deprecated io/ioutil (#5576) --- modules/caddyhttp/templates/tplcontext_test.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'modules/caddyhttp/templates') diff --git a/modules/caddyhttp/templates/tplcontext_test.go b/modules/caddyhttp/templates/tplcontext_test.go index 15a369e..fdf2c10 100644 --- a/modules/caddyhttp/templates/tplcontext_test.go +++ b/modules/caddyhttp/templates/tplcontext_test.go @@ -18,7 +18,6 @@ import ( "bytes" "context" "fmt" - "io/ioutil" "net/http" "os" "path/filepath" @@ -221,21 +220,21 @@ func TestNestedInclude(t *testing.T) { // create files and for test case if test.parentFile != "" { absFilePath = filepath.Join(fmt.Sprintf("%s", context.Root), test.parentFile) - if err := ioutil.WriteFile(absFilePath, []byte(test.parent), os.ModePerm); err != nil { + if err := os.WriteFile(absFilePath, []byte(test.parent), os.ModePerm); err != nil { os.Remove(absFilePath) t.Fatalf("Test %d: Expected no error creating file, got: '%s'", i, err.Error()) } } if test.childFile != "" { absFilePath0 = filepath.Join(fmt.Sprintf("%s", context.Root), test.childFile) - if err := ioutil.WriteFile(absFilePath0, []byte(test.child), os.ModePerm); err != nil { + if err := os.WriteFile(absFilePath0, []byte(test.child), os.ModePerm); err != nil { os.Remove(absFilePath0) t.Fatalf("Test %d: Expected no error creating file, got: '%s'", i, err.Error()) } } if test.child2File != "" { absFilePath1 = filepath.Join(fmt.Sprintf("%s", context.Root), test.child2File) - if err := ioutil.WriteFile(absFilePath1, []byte(test.child2), os.ModePerm); err != nil { + if err := os.WriteFile(absFilePath1, []byte(test.child2), os.ModePerm); err != nil { os.Remove(absFilePath0) t.Fatalf("Test %d: Expected no error creating file, got: '%s'", i, err.Error()) } -- cgit v1.2.3 From b32f265ecad60404c3818cc9d42e367a8e4eb7d4 Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Tue, 8 Aug 2023 03:40:31 +0800 Subject: ci: Use gofumpt to format code (#5707) --- modules/caddyhttp/templates/tplcontext.go | 3 --- 1 file changed, 3 deletions(-) (limited to 'modules/caddyhttp/templates') diff --git a/modules/caddyhttp/templates/tplcontext.go b/modules/caddyhttp/templates/tplcontext.go index 5dc4ae5..89158f4 100644 --- a/modules/caddyhttp/templates/tplcontext.go +++ b/modules/caddyhttp/templates/tplcontext.go @@ -103,13 +103,11 @@ func (c TemplateContext) OriginalReq() http.Request { // trusted files. If it is not trusted, be sure to use escaping functions // in your template. func (c TemplateContext) funcInclude(filename string, args ...any) (string, error) { - bodyBuf := bufPool.Get().(*bytes.Buffer) bodyBuf.Reset() defer bufPool.Put(bodyBuf) err := c.readFileToBuffer(filename, bodyBuf) - if err != nil { return "", err } @@ -215,7 +213,6 @@ func (c TemplateContext) funcHTTPInclude(uri string) (string, error) { // {{ template }} from the standard template library. If the imported file has // no {{ define }} blocks, the name of the import will be the path func (c *TemplateContext) funcImport(filename string) (string, error) { - bodyBuf := bufPool.Get().(*bytes.Buffer) bodyBuf.Reset() defer bufPool.Put(bodyBuf) -- cgit v1.2.3 From d6f86cccf5fa5b4eb30141da390cf2439746c5da Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 14 Aug 2023 23:41:15 +0800 Subject: ci: use gci linter (#5708) * use gofmput to format code * use gci to format imports * reconfigure gci * linter autofixes * rearrange imports a little * export GOOS=windows golangci-lint run ./... --fix --- modules/caddyhttp/templates/tplcontext.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'modules/caddyhttp/templates') diff --git a/modules/caddyhttp/templates/tplcontext.go b/modules/caddyhttp/templates/tplcontext.go index 89158f4..6b2b495 100644 --- a/modules/caddyhttp/templates/tplcontext.go +++ b/modules/caddyhttp/templates/tplcontext.go @@ -31,14 +31,15 @@ import ( "github.com/Masterminds/sprig/v3" chromahtml "github.com/alecthomas/chroma/v2/formatters/html" - "github.com/caddyserver/caddy/v2" - "github.com/caddyserver/caddy/v2/modules/caddyhttp" "github.com/dustin/go-humanize" "github.com/yuin/goldmark" highlighting "github.com/yuin/goldmark-highlighting/v2" "github.com/yuin/goldmark/extension" "github.com/yuin/goldmark/parser" gmhtml "github.com/yuin/goldmark/renderer/html" + + "github.com/caddyserver/caddy/v2" + "github.com/caddyserver/caddy/v2/modules/caddyhttp" ) // TemplateContext is the TemplateContext with which HTTP templates are executed. -- cgit v1.2.3 From 5653c36bc23d19a679f81023a760e4b20dc2c733 Mon Sep 17 00:00:00 2001 From: Thanmay Nath <110758050+ThanmayNath@users.noreply.github.com> Date: Sun, 8 Oct 2023 02:17:34 +0530 Subject: templates: Add dummy `RemoteAddr` to `httpInclude` request, proxy compatibility (#5845) * Enhancement: Allow X-Forwarded-For Header in httpInclude Virtual Requests The goal of this enhancement is to modify the funcHTTPInclude function in the Caddy codebase to include the X-Forwarded-For header in the virtual request. This change will enable reverse proxies to set the X-Forwarded-For header, ensuring that the client's IP address is correctly provided to the target endpoint. This modification is essential for applications that depend on the X-Forwarded-For header for various functionalities, such as authentication, logging, or content customization. * Updated tplcontext.go - set `virtReq.RemoteAddr = "127.0.0.1"` i have made the suggested changes * Apply suggestions from code review * Update modules/caddyhttp/templates/tplcontext.go --------- Co-authored-by: Francis Lavoie --- modules/caddyhttp/templates/tplcontext.go | 1 + 1 file changed, 1 insertion(+) (limited to 'modules/caddyhttp/templates') diff --git a/modules/caddyhttp/templates/tplcontext.go b/modules/caddyhttp/templates/tplcontext.go index 6b2b495..a7d5314 100644 --- a/modules/caddyhttp/templates/tplcontext.go +++ b/modules/caddyhttp/templates/tplcontext.go @@ -188,6 +188,7 @@ func (c TemplateContext) funcHTTPInclude(uri string) (string, error) { return "", err } virtReq.Host = c.Req.Host + virtReq.RemoteAddr = "127.0.0.1:10000" // https://github.com/caddyserver/caddy/issues/5835 virtReq.Header = c.Req.Header.Clone() virtReq.Header.Set("Accept-Encoding", "identity") // https://github.com/caddyserver/caddy/issues/4352 virtReq.Trailer = c.Req.Trailer.Clone() -- cgit v1.2.3