diff --git a/_examples/file-server/embedding-gzipped-files-into-app/main.go b/_examples/file-server/embedding-gzipped-files-into-app/main.go index b0315fe00e..76c4e3ac78 100644 --- a/_examples/file-server/embedding-gzipped-files-into-app/main.go +++ b/_examples/file-server/embedding-gzipped-files-into-app/main.go @@ -24,7 +24,7 @@ func newApp() *iris.Application { AssetInfo: GzipAssetInfo, AssetNames: GzipAssetNames, AssetValidator: func(ctx iris.Context, name string) bool { - ctx.Header("Vary", "Accept-Encoding") + // ctx.Header("Vary", "Accept-Encoding") ctx.Header("Content-Encoding", "gzip") return true }, diff --git a/_examples/file-server/http2push-embedded-gzipped/main.go b/_examples/file-server/http2push-embedded-gzipped/main.go index a238012141..26a4fa1833 100644 --- a/_examples/file-server/http2push-embedded-gzipped/main.go +++ b/_examples/file-server/http2push-embedded-gzipped/main.go @@ -17,10 +17,11 @@ import ( var opts = iris.DirOptions{ IndexName: "/index.html", PushTargets: map[string][]string{ - "/": { - "/public/favicon.ico", - "/public/js/main.js", - "/public/css/main.css", + "/": { // Relative path without route prefix. + "favicon.ico", + "js/main.js", + "css/main.css", + // ^ Relative to the index, if need absolute ones start with a slash ('/'). }, }, Compress: false, // SHOULD be set to false, files already compressed. @@ -30,7 +31,7 @@ var opts = iris.DirOptions{ AssetNames: GzipAssetNames, // Required for pre-compressed files: AssetValidator: func(ctx iris.Context, _ string) bool { - ctx.Header("Vary", "Content-Encoding") + // ctx.Header("Vary", "Content-Encoding") ctx.Header("Content-Encoding", "gzip") return true }, diff --git a/_examples/file-server/http2push-embedded/main.go b/_examples/file-server/http2push-embedded/main.go index 8eae807bba..7de0e010e1 100644 --- a/_examples/file-server/http2push-embedded/main.go +++ b/_examples/file-server/http2push-embedded/main.go @@ -17,10 +17,11 @@ import ( var opts = iris.DirOptions{ IndexName: "/index.html", PushTargets: map[string][]string{ - "/": { - "/public/favicon.ico", - "/public/js/main.js", - "/public/css/main.css", + "/": { // Relative path without route prefix. + "favicon.ico", + "js/main.js", + "css/main.css", + // ^ Relative to the index, if need absolute ones start with a slash ('/'). }, }, Compress: false, diff --git a/_examples/file-server/http2push/main.go b/_examples/file-server/http2push/main.go index 70e641e7f6..779c7fbc72 100644 --- a/_examples/file-server/http2push/main.go +++ b/_examples/file-server/http2push/main.go @@ -6,7 +6,7 @@ import ( var opts = iris.DirOptions{ IndexName: "/index.html", - // Optionally register files (map's absolute values) to be served + // Optionally register files (map's values) to be served // when a specific path (map's key WITHOUT prefix) is requested // is fired before client asks (HTTP/2 Push). // E.g. "/" (which serves the `IndexName` if not empty). @@ -14,10 +14,11 @@ var opts = iris.DirOptions{ // Note: Requires running server under TLS, // that's why we use `iris.TLS` below. PushTargets: map[string][]string{ - "/": { - "/public/favicon.ico", - "/public/js/main.js", - "/public/css/main.css", + "/": { // Relative path without route prefix. + "favicon.ico", + "js/main.js", + "css/main.css", + // ^ Relative to the index, if need absolute ones start with a slash ('/'). }, }, Compress: true, diff --git a/context/compress.go b/context/compress.go index a1d9b27223..80c76959b0 100644 --- a/context/compress.go +++ b/context/compress.go @@ -182,8 +182,8 @@ var _ ResponseWriter = (*CompressResponseWriter)(nil) // It returns the best candidate among "gzip", "defate", "br", "snappy" and "s2" // based on the request's "Accept-Encoding" header value. func AcquireCompressResponseWriter(w ResponseWriter, r *http.Request, level int) (*CompressResponseWriter, error) { - acceptEncoding := r.Header.Values(AcceptEncodingHeaderKey) - + // acceptEncoding := r.Header.Values(AcceptEncodingHeaderKey) + acceptEncoding := r.Header[AcceptEncodingHeaderKey] if len(acceptEncoding) == 0 { return nil, ErrResponseNotCompressed } diff --git a/core/router/fs.go b/core/router/fs.go index 51b1858590..476d9c41f2 100644 --- a/core/router/fs.go +++ b/core/router/fs.go @@ -44,10 +44,10 @@ type DirOptions struct { // that another handler, called index handler, is auto-registered by the framework // if end developer does not managed to handle it by hand. IndexName string - // PushTargets optionally absolute filenames (map's value) to be served without any - // additional client's requests (HTTP/2 Push) - // when a specific path (map's key) is requested and - // it's not a directory (it's an `IndexFile`). + // PushTargets filenames (map's value) to + // be served without additional client's requests (HTTP/2 Push) + // when a specific request path (map's key WITHOUT prefix) + // is requested and it's not a directory (it's an `IndexFile`). PushTargets map[string][]string // When files should served under compression. Compress bool @@ -88,6 +88,14 @@ func getDirOptions(opts ...DirOptions) (options DirOptions) { options.Attachments.Burst = 0 } + // Make sure PushTarget's paths are in the proper form. + for path, filenames := range options.PushTargets { + for idx, filename := range filenames { + filenames[idx] = filepath.ToSlash(filename) + } + options.PushTargets[path] = filenames + } + return } @@ -382,8 +390,9 @@ func FileServer(directory string, opts ...DirOptions) context.Handler { } h := func(ctx *context.Context) { - name := prefix(ctx.Request().URL.Path, "/") - ctx.Request().URL.Path = name + r := ctx.Request() + name := prefix(r.URL.Path, "/") + r.URL.Path = name f, err := fs.Open(name) if err != nil { @@ -423,6 +432,30 @@ func FileServer(directory string, opts ...DirOptions) context.Handler { } } + if indexFound && !options.Attachments.Enable { + if indexAssets, ok := options.PushTargets[name]; ok { + if pusher, ok := ctx.ResponseWriter().(http.Pusher); ok { + for _, indexAsset := range indexAssets { + // pushOpts := &http.PushOptions{ + // Method: "GET", + // Header: http.Header{ + // "Vary": []string{"Accept-Encoding"}, + // "Content-Encoding": []string{"gzip"}, + // }, + // } + if indexAsset[0] != '/' { + // it's relative path. + indexAsset = path.Join(r.RequestURI, indexAsset) + } + + if err = pusher.Push(indexAsset, nil); err != nil { + break + } + } + } + } + } + // Still a directory? (we didn't find an index.html file) if info.IsDir() { if !options.ShowList { @@ -486,16 +519,6 @@ func FileServer(directory string, opts ...DirOptions) context.Handler { ctx.Compress(options.Compress) - if indexFound && len(options.PushTargets) > 0 && !options.Attachments.Enable { - if indexAssets, ok := options.PushTargets[name]; ok { - if pusher, ok := ctx.ResponseWriter().(http.Pusher); ok { - for _, indexAsset := range indexAssets { - pusher.Push(indexAsset, nil) - } - } - } - } - // If limit is 0 then same as ServeContent. ctx.ServeContentWithRate(f, info.Name(), info.ModTime(), options.Attachments.Limit, options.Attachments.Burst) if serveCode := ctx.GetStatusCode(); context.StatusCodeNotSuccessful(serveCode) {