mux icon indicating copy to clipboard operation
mux copied to clipboard

[question] Gorilla/Mux SPA not working

Open AstroNik opened this issue 5 years ago • 7 comments

Problem

So I'm not really sure if this is a bug or anything, and this is also my first bug report so I apologize for my lack of knowledge on correctly reporting a bug.

I was trying to create a SPA using gorilla/mux and kept running into issues with displaying my webpage. I knew my code was correct but it had something to do with the file paths inside the SPA handler itself because when I was running my code I was getting a StatusInternalServerError. All my file paths were correct so it had to be something with the ServeHTTP function itself. I later found it to be an issue with the path as shown below.

Versions

go version go1.13.4 windows/amd64

github.com/gorilla/mux v1.7.4 …

main.go

type spaHandler struct {
	staticPath string
	indexPath  string
}

func (h spaHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	path, err := filepath.Abs(r.URL.Path)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	path = filepath.Join(h.staticPath, path) //this is the part of the code I changed to fix my issue

	_, err = os.Stat(path)
	if os.IsNotExist(err) {
		http.ServeFile(w, r, filepath.Join(h.staticPath, h.indexPath))
		return
	} else if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	http.FileServer(http.Dir(h.staticPath)).ServeHTTP(w, r)
}

func main() {
	router := mux.NewRouter()
	spa := spaHandler{staticPath: "./admin/build", indexPath: "index.html"}
	router.PathPrefix("/").Handler(spa)
	log.Fatal(http.ListenAndServe(":8080", router))
}

Code was changed to below, and started to work perfectly fine.

path = filepath.Join(h.staticPath, r.URL.Path) 

I don't know whether or not to report this as a fix to the actual public code or not. Still new to contributing.

AstroNik avatar Aug 29 '20 18:08 AstroNik

Confirming I have the same problem with the example SPA code (using Windows).

	// get the absolute path to prevent directory traversal
	path, err := filepath.Abs(r.URL.Path)
	if err != nil {
		// if we failed to get the absolute path respond with a 400 bad request
		// and stop
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	fmt.Println(path) // returns: D:\

	// prepend the path with the path to the static directory

	path = filepath.Join(h.StaticPath, path)
	fmt.Println(path) // returns: build\D:

	path = filepath.Join(h.StaticPath, r.URL.Path)
	fmt.Println(path) // returns: build

LantosIstvan avatar Nov 10 '20 17:11 LantosIstvan

This issue has been automatically marked as stale because it hasn't seen a recent update. It'll be automatically closed in a few days.

stale[bot] avatar Jun 09 '21 02:06 stale[bot]

Not so stale.

LantosIstvan avatar Jun 09 '21 12:06 LantosIstvan

is there an update on this?

LucaFilitz avatar Nov 28 '21 22:11 LucaFilitz

This problem appears on windows. For an unknown reason filepath.abs returns the storage letter, so the path begins with "C:/" (or "D:/", or whatever letter followed by ":/"), just replace "C:/" by "/" and it will works great !

path, err := filepath.Abs(r.URL.Path)
path = strings.Replace(path, `C:\`, "/", 1)

Solution found on reddit : https://www.reddit.com/r/golang/comments/pvltgk/having_trouble_getting_the_gorillamux_single_page/

I'm beginner in golang (even more with windows stuff) so i don't feel comfortable to make a pull request but at least here is quick and dirty hotfix !

thibaultleblanc avatar Feb 14 '22 16:02 thibaultleblanc

This issue has been automatically marked as stale because it hasn't seen a recent update. It'll be automatically closed in a few days.

stale[bot] avatar May 01 '22 01:05 stale[bot]

I can finally triage this issue. Will work on fixing docs and add a new test case for the same.

amustaque97 avatar May 31 '22 20:05 amustaque97