aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Crute <mike@crute.us>2023-08-17 07:49:29 -0700
committerMike Crute <mike@crute.us>2023-08-17 07:49:29 -0700
commit9956e64f2c9f8c055c60bc82fcbb1e979bfb0b47 (patch)
tree8b572d85346fb327957c30aba587bc2016b48a9b
parentfb4e88c5b1bec3c5d0e35b2c12561778b83f88c0 (diff)
downloadgolib-9956e64f2c9f8c055c60bc82fcbb1e979bfb0b47.tar.bz2
golib-9956e64f2c9f8c055c60bc82fcbb1e979bfb0b47.tar.xz
golib-9956e64f2c9f8c055c60bc82fcbb1e979bfb0b47.zip
echo: support etags for static filesecho/v0.9.5
-rw-r--r--echo/static_file.go30
1 files changed, 30 insertions, 0 deletions
diff --git a/echo/static_file.go b/echo/static_file.go
index 9723db7..258c832 100644
--- a/echo/static_file.go
+++ b/echo/static_file.go
@@ -1,6 +1,8 @@
1package echo 1package echo
2 2
3import ( 3import (
4 "crypto/sha256"
5 "encoding/base64"
4 "io" 6 "io"
5 "io/fs" 7 "io/fs"
6 "net/http" 8 "net/http"
@@ -12,7 +14,16 @@ import (
12 14
13type routeFunc func(string, echo.HandlerFunc, ...echo.MiddlewareFunc) *echo.Route 15type routeFunc func(string, echo.HandlerFunc, ...echo.MiddlewareFunc) *echo.Route
14 16
17func StaticFSSha256Etags(get routeFunc, f fs.FS, prefix, root string, m ...echo.MiddlewareFunc) *echo.Route {
18 return staticFS(get, f, prefix, root, true, m...)
19}
20
15func StaticFS(get routeFunc, f fs.FS, prefix, root string, m ...echo.MiddlewareFunc) *echo.Route { 21func StaticFS(get routeFunc, f fs.FS, prefix, root string, m ...echo.MiddlewareFunc) *echo.Route {
22 return staticFS(get, f, prefix, root, false, m...)
23}
24
25// TODO: This should support HEAD requests
26func staticFS(get routeFunc, f fs.FS, prefix, root string, addEtags bool, m ...echo.MiddlewareFunc) *echo.Route {
16 if root == "" { 27 if root == "" {
17 root = "." // For security we want to restrict to CWD. 28 root = "." // For security we want to restrict to CWD.
18 } 29 }
@@ -52,6 +63,25 @@ func StaticFS(get routeFunc, f fs.FS, prefix, root string, m ...echo.MiddlewareF
52 return echo.ErrInternalServerError 63 return echo.ErrInternalServerError
53 } 64 }
54 65
66 // Only do this if the consumer requests it since it could be expensive
67 // for high traffic sites as it requires a full read and SHA256
68 // computation
69 // TODO: Cache this?
70 if addEtags {
71 h := sha256.New()
72 if _, err := io.Copy(h, fs); err != nil {
73 c.Logger().Errorf("Error checksumming file %s: %s", p, err)
74 return echo.ErrInternalServerError
75 }
76 etag := base64.RawStdEncoding.EncodeToString(h.Sum(nil))
77 c.Response().Header().Add("ETag", etag)
78
79 if _, err := fs.Seek(0, io.SeekStart); err != nil {
80 c.Logger().Errorf("Error seeking 0 in file %s: %s", p, err)
81 return echo.ErrInternalServerError
82 }
83 }
84
55 http.ServeContent(c.Response(), c.Request(), fi.Name(), fi.ModTime(), fs) 85 http.ServeContent(c.Response(), c.Request(), fi.Name(), fi.ModTime(), fs)
56 return nil 86 return nil
57 } 87 }