diff --git a/cmd/web.go b/cmd/web.go index 9942f19a50c..f21244a54a9 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -99,6 +99,7 @@ func newMacaron() *macaron.Macaron { macaron.StaticOptions{ Prefix: "avatars", SkipLogging: setting.DisableRouterLog, + ETag: true, }, )) diff --git a/vendor/github.com/go-macaron/bindata/bindata.go b/vendor/github.com/go-macaron/bindata/bindata.go index f20d132436c..637489e1cdf 100644 --- a/vendor/github.com/go-macaron/bindata/bindata.go +++ b/vendor/github.com/go-macaron/bindata/bindata.go @@ -17,13 +17,16 @@ package bindata import ( + "bytes" + "fmt" + "io" "os" "github.com/elazarl/go-bindata-assetfs" "gopkg.in/macaron.v1" ) -const _VERSION = "0.1.0" +const _VERSION = "0.1.1" func Version() string { return _VERSION @@ -69,6 +72,15 @@ func (templates templateFileSystem) ListFiles() []macaron.TemplateFile { return templates.files } +func (templates templateFileSystem) Get(name string) (io.Reader, error) { + for i := range templates.files { + if templates.files[i].Name()+templates.files[i].Ext() == name { + return bytes.NewReader(templates.files[i].Data()), nil + } + } + return nil, fmt.Errorf("file '%s' not found", name) +} + func (f *templateFile) Name() string { return f.name } diff --git a/vendor/gopkg.in/macaron.v1/macaron.go b/vendor/gopkg.in/macaron.v1/macaron.go index 442402ead78..9ff5668ad08 100644 --- a/vendor/gopkg.in/macaron.v1/macaron.go +++ b/vendor/gopkg.in/macaron.v1/macaron.go @@ -32,7 +32,7 @@ import ( "github.com/go-macaron/inject" ) -const _VERSION = "1.1.8.0826" +const _VERSION = "1.1.12.0122" func Version() string { return _VERSION diff --git a/vendor/gopkg.in/macaron.v1/render.go b/vendor/gopkg.in/macaron.v1/render.go index ff2dcaacddb..f45e431240a 100644 --- a/vendor/gopkg.in/macaron.v1/render.go +++ b/vendor/gopkg.in/macaron.v1/render.go @@ -21,6 +21,7 @@ import ( "encoding/xml" "fmt" "html/template" + "io" "io/ioutil" "net/http" "os" @@ -72,6 +73,7 @@ type ( // TemplateFileSystem represents a interface of template file system that able to list all files. TemplateFileSystem interface { ListFiles() []TemplateFile + Get(string) (io.Reader, error) } // Delims represents a set of Left and Right delimiters for HTML template rendering @@ -246,6 +248,15 @@ func (fs TplFileSystem) ListFiles() []TemplateFile { return fs.files } +func (fs TplFileSystem) Get(name string) (io.Reader, error) { + for i := range fs.files { + if fs.files[i].Name()+fs.files[i].Ext() == name { + return bytes.NewReader(fs.files[i].Data()), nil + } + } + return nil, fmt.Errorf("file '%s' not found", name) +} + func PrepareCharset(charset string) string { if len(charset) != 0 { return "; charset=" + charset diff --git a/vendor/gopkg.in/macaron.v1/router.go b/vendor/gopkg.in/macaron.v1/router.go index f9b421a3302..befa55f476b 100644 --- a/vendor/gopkg.in/macaron.v1/router.go +++ b/vendor/gopkg.in/macaron.v1/router.go @@ -258,7 +258,9 @@ func (r *Router) NotFound(handlers ...Handler) { validateHandlers(handlers) r.notFound = func(rw http.ResponseWriter, req *http.Request) { c := r.m.createContext(rw, req) - c.handlers = append(r.m.handlers, handlers...) + c.handlers = make([]Handler, 0, len(r.m.handlers)+len(handlers)) + c.handlers = append(c.handlers, r.m.handlers...) + c.handlers = append(c.handlers, handlers...) c.run() } } diff --git a/vendor/gopkg.in/macaron.v1/static.go b/vendor/gopkg.in/macaron.v1/static.go index 4ff8342fc5e..60c521110e7 100644 --- a/vendor/gopkg.in/macaron.v1/static.go +++ b/vendor/gopkg.in/macaron.v1/static.go @@ -16,6 +16,7 @@ package macaron import ( + "encoding/base64" "log" "net/http" "path" @@ -35,6 +36,9 @@ type StaticOptions struct { // Expires defines which user-defined function to use for producing a HTTP Expires Header // https://developers.google.com/speed/docs/insights/LeverageBrowserCaching Expires func() string + // ETag defines if we should add an ETag header + // https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching#validating-cached-responses-with-etags + ETag bool // FileSystem is the interface for supporting any implmentation of file system. FileSystem http.FileSystem } @@ -172,10 +176,21 @@ func staticHandler(ctx *Context, log *log.Logger, opt StaticOptions) bool { ctx.Resp.Header().Set("Expires", opt.Expires()) } + if opt.ETag { + tag := GenerateETag(string(fi.Size()), fi.Name(), fi.ModTime().UTC().Format(http.TimeFormat)) + ctx.Resp.Header().Set("ETag", tag) + } + http.ServeContent(ctx.Resp, ctx.Req.Request, file, fi.ModTime(), f) return true } +// GenerateETag generates an ETag based on size, filename and file modification time +func GenerateETag(fileSize, fileName, modTime string) string { + etag := fileSize + fileName + modTime + return base64.StdEncoding.EncodeToString([]byte(etag)) +} + // Static returns a middleware handler that serves static files in the given directory. func Static(directory string, staticOpt ...StaticOptions) Handler { opt := prepareStaticOptions(directory, staticOpt) diff --git a/vendor/vendor.json b/vendor/vendor.json index 566da92a5ac..778edbd0b84 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -353,10 +353,10 @@ "revisionTime": "2015-10-06T22:16:25Z" }, { - "checksumSHA1": "qTJizMr1DBhDTZiRNmC+khEClz8=", + "checksumSHA1": "3w6jybRjyrhohNQJMnIxMC8cYXM=", "path": "github.com/go-macaron/bindata", - "revision": "de74a053830c7d338bf209adf3b711c969f63e59", - "revisionTime": "2016-01-05T04:39:20Z" + "revision": "85786f57eee3e5544a9cc24fa2afe425b97a8652", + "revisionTime": "2016-12-22T09:30:48Z" }, { "checksumSHA1": "qM/kf31cT2cxjtHxdzbu8q8jPq0=", @@ -1369,10 +1369,10 @@ "revisionTime": "2016-08-08T14:54:09Z" }, { - "checksumSHA1": "wzuoHPA/Ccoe1CFnDL35rnL0JoI=", + "checksumSHA1": "u1dW5zfo2SWot04r5cL8dTbmtcc=", "path": "gopkg.in/macaron.v1", - "revision": "4974334b10dbb6f5c0e17f4c10555ff050a16329", - "revisionTime": "2016-08-26T18:07:28Z" + "revision": "aa6b7ee41a182898a33d798c655df1cac9d2230b", + "revisionTime": "2017-01-22T14:42:53Z" }, { "checksumSHA1": "6QPjE+qflEBHg+JPJd9e4iQuRAk=",