github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/pkg/assets/middleware.go (about) 1 package assets 2 3 import ( 4 "net/http" 5 "strings" 6 ) 7 8 // Middleware that attaches a server at a subpath. 9 // Modeled after http.StripPrefix, but attaches the work it did to the Request Context. 10 func StripPrefix(prefix string, h http.Handler) http.Handler { 11 if prefix == "" { 12 return h 13 } 14 15 delegate := http.StripPrefix(prefix, h) 16 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 17 if p := strings.TrimPrefix(r.URL.Path, prefix); len(p) < len(r.URL.Path) { 18 // If the prefix was stripped successfully, add it to the context. 19 r = appendPublicPathPrefix(prefix, r) 20 } 21 delegate.ServeHTTP(w, r) 22 }) 23 } 24 25 func isAssetPath(path string) bool { 26 return strings.HasPrefix(path, "/static/") || path == "/favicon.ico" || path == "/manifest.json" 27 } 28 29 type cacheWriter struct { 30 writer http.ResponseWriter 31 assetPath, reqMethod string 32 } 33 34 func (w cacheWriter) Header() http.Header { 35 return w.writer.Header() 36 } 37 38 func (w cacheWriter) Write(b []byte) (int, error) { 39 return w.writer.Write(b) 40 } 41 42 func (w cacheWriter) WriteHeader(statusCode int) { 43 if statusCode == 200 && w.reqMethod == http.MethodGet { 44 // Set caching headers according to this doc: 45 // https://create-react-app.dev/docs/production-build/#static-file-caching 46 // 47 // Static artifacts are checksummed and can be cached indefinitely 48 // The main index html page should never be cached. 49 cacheControl := "no-store, max-age=0" 50 if isAssetPath(w.assetPath) { 51 cacheControl = "public, max-age=31536000" 52 } 53 w.writer.Header().Set("Cache-Control", cacheControl) 54 } 55 w.writer.WriteHeader(statusCode) 56 } 57 58 func cacheAssets(w http.ResponseWriter, assetPath, reqMethod string) http.ResponseWriter { 59 return cacheWriter{ 60 writer: w, 61 assetPath: assetPath, 62 reqMethod: reqMethod, 63 } 64 }