Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add StaticFS method #2059

Closed
3 tasks done
flimzy opened this issue Jan 3, 2022 · 7 comments
Closed
3 tasks done

Add StaticFS method #2059

flimzy opened this issue Jan 3, 2022 · 7 comments

Comments

@flimzy
Copy link
Contributor

flimzy commented Jan 3, 2022

Issue Description

Checklist

  • Dependencies installed
  • No typos
  • Searched existing issues and docs

Expected behaviour

As of Echo 4.6.1, we have the (*Echo).Static(prefix, root string) *Route method. With the advent of Go 1.16, we have the new fs.FS type which expands upon the older concept of http.Dir as used by http.FileServer, to allow serving of files from any FS-like location, not just on disk.

I think it would be logical for Echo to support this new standard as well. The simplest approach I think would be to add a StaticFS method, probably with the following signature:

func (e *Echo) StaticFS(prefix string, root fs.FS) *Route

Version/commit

v4.6.1

@aldas
Copy link
Contributor

aldas commented Jan 3, 2022

(default)filesystem will be added in v5 (already exists there) but most of it, if not all, could be used in v4 also

currently e.StaticFS can be emulated if you add route with no-op handler and static middleware with filesystem

Filesystem http.FileSystem `yaml:"-"`

something like that. Probably needs some Root and/or IgnoreBase config values also. I did not test it before posting here.

	e.GET("/files/*", echo.NotFoundHandler, middleware.StaticWithConfig(middleware.StaticConfig{
		Filesystem: http.Dir("./"),
	}))

@lammel
Copy link
Contributor

lammel commented Jan 27, 2022

This is now implemented with #2064 and will be made available with echo v4.7

@clemensg
Copy link

In Angular, you get all built files in one directory by default. Let's say I embed this directory as embed.FS and want to serve all those files (/index.html, /main.xyz.js, etc.) but additionally want to redirect every not-found file to index.html (so that if you reload the current /frontend-route-xyz page it should not return a 404 but serve index.html and the Angular Router deals with the fake /frontend-route-xyz URL)

I am unsure how to do this even with #2064 or am I missing something?

@aldas
Copy link
Contributor

aldas commented Feb 21, 2022

@clemensg this is what "static" middleware" can do. Please check index and HTML5 fields

// Index file for serving a directory.
// Optional. Default value "index.html".
Index string `yaml:"index"`
// Enable HTML5 mode by forwarding all not-found requests to root so that
// SPA (single-page application) can handle the routing.
// Optional. Default value false.
HTML5 bool `yaml:"html5"`

@clemensg
Copy link

@aldas Thank you! I missed the new Filesystem option in the Static Middleware (not in the docs yet), which makes it possible to use it with embed.FS 👍

@aldas
Copy link
Contributor

aldas commented Mar 4, 2022

Closing, this stuff is now released with v4.7.0

@aldas aldas closed this as completed Mar 4, 2022
@justin-calleja
Copy link

In case anyone else needs this, here's a working example (tested with go v1.18):

package main

import (
	"embed"
	"flag"
	"fmt"
	"net/http"

	"github.com/labstack/echo/v4"
	echoMw "github.com/labstack/echo/v4/middleware"
)

// If you have files starting with "_" that you want to serve, use "all:"
//go:embed all:public
var public embed.FS

func main() {
	var port int
	flag.IntVar(&port, "port", 8000, "The port to listen on")
	flag.Parse()

	e := echo.New()

	e.Use(echoMw.StaticWithConfig(echoMw.StaticConfig{
		Root:       "public",     // This is the path to your SPA build folder, the folder that is created from running "npm build"
		Index:      "index.html", // This is the default html page for your SPA
		Browse:     false,
		HTML5:      true,
		Filesystem: http.FS(public),
	}))

	e.Logger.Fatal(e.Start(fmt.Sprintf(":%d", port)))
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants