summaryrefslogtreecommitdiff
path: root/modules/caddyhttp/templates/templates.go
diff options
context:
space:
mode:
authorMatthew Holt <mholt@users.noreply.github.com>2019-06-27 13:09:10 -0600
committerMatthew Holt <mholt@users.noreply.github.com>2019-06-27 13:09:10 -0600
commita63cb3e3fdea70991a95c3f0bc8f3866a5aec6ef (patch)
treedbb40f0f0edb26ab3e16b6671b155f8cd0785728 /modules/caddyhttp/templates/templates.go
parent2b22d2e6ea7ffd17ae769bd8a2adae60e5a7d0bf (diff)
Implement etag; fix related bugs in encode and templates middlewares
Diffstat (limited to 'modules/caddyhttp/templates/templates.go')
-rw-r--r--modules/caddyhttp/templates/templates.go33
1 files changed, 31 insertions, 2 deletions
diff --git a/modules/caddyhttp/templates/templates.go b/modules/caddyhttp/templates/templates.go
index e329e2e..79bbde6 100644
--- a/modules/caddyhttp/templates/templates.go
+++ b/modules/caddyhttp/templates/templates.go
@@ -22,9 +22,18 @@ func init() {
// Templates is a middleware which execute response bodies as templates.
type Templates struct {
FileRoot string `json:"file_root,omitempty"`
+ MIMETypes []string `json:"mime_types,omitempty"`
Delimiters []string `json:"delimiters,omitempty"`
}
+// Provision provisions t.
+func (t *Templates) Provision(ctx caddy.Context) error {
+ if t.MIMETypes == nil {
+ t.MIMETypes = defaultMIMETypes
+ }
+ return nil
+}
+
// Validate ensures t has a valid configuration.
func (t *Templates) Validate() error {
if len(t.Delimiters) != 0 && len(t.Delimiters) != 2 {
@@ -38,8 +47,16 @@ func (t *Templates) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddy
buf.Reset()
defer bufPool.Put(buf)
+ // shouldBuf determines whether to execute templates on this response,
+ // since generally we will not want to execute for images or CSS, etc.
shouldBuf := func(status int) bool {
- return strings.HasPrefix(w.Header().Get("Content-Type"), "text/")
+ ct := w.Header().Get("Content-Type")
+ for _, mt := range t.MIMETypes {
+ if strings.Contains(ct, mt) {
+ return true
+ }
+ }
+ return false
}
rec := caddyhttp.NewResponseRecorder(w, buf, shouldBuf)
@@ -59,9 +76,14 @@ func (t *Templates) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddy
w.Header().Set("Content-Length", strconv.Itoa(buf.Len()))
w.Header().Del("Accept-Ranges") // we don't know ranges for dynamically-created content
- w.Header().Del("Etag") // don't know a way to quickly generate etag for dynamic content
w.Header().Del("Last-Modified") // useless for dynamic content since it's always changing
+ // we don't know a way to guickly generate etag for dynamic content,
+ // but we can convert this to a weak etag to kind of indicate that
+ if etag := w.Header().Get("ETag"); etag != "" {
+ w.Header().Set("ETag", "W/"+etag)
+ }
+
w.WriteHeader(rec.Status())
io.Copy(w, buf)
@@ -110,8 +132,15 @@ func (vrw *virtualResponseWriter) Write(data []byte) (int, error) {
return vrw.body.Write(data)
}
+var defaultMIMETypes = []string{
+ "text/html",
+ "text/plain",
+ "text/markdown",
+}
+
// Interface guards
var (
+ _ caddy.Provisioner = (*Templates)(nil)
_ caddy.Validator = (*Templates)(nil)
_ caddyhttp.MiddlewareHandler = (*Templates)(nil)
)