xrfang
xrfang

Reputation: 2322

go 1.16: how to use strip prefix in go:embed

I have a go project which uses VueJS to provide web interface. While build the project, I first use npm run build to compile the frontend code, which is generated under gui/dist of my project dir. Then I use this code to serve the static contents:

//go:embed gui/dist/*
var dist embed.FS

gui := http.FileServer(http.FS(dist))
http.Handle("/", gui)
http.HandleFunc("/api/", func(w http.ResponseWriter, r *http.Request) {
    msg := fmt.Sprintf("TODO: %s", r.URL)
    http.Error(w, msg, http.StatusNotImplemented)
})

svr := http.Server{
    Addr:         fmt.Sprintf(":%v", cf.HTTPPort),
    ReadTimeout:  time.Minute,
    WriteTimeout: time.Minute,
}
assert(svr.ListenAndServe())

The problem is, when open the site in browser, it shows me a browse file interface, i.e. starting with gui, and then into dist, then shows the index.html file, which is a blank page, because it requires files such as /css/..., while the go web server serves it at /gui/dist/css/....

I tried to use http.StripPrefix() but apparently it is not intended to handle this situation, or I didn't use it correctly:

http.Handle("/", http.StripPrefix("/gui/dist", gui))

which generated a 404 page not found.

Upvotes: 15

Views: 5657

Answers (1)

wasmup
wasmup

Reputation: 16253

You may use fs.Sub(dist, "gui/dist") (docs), try it:

package main

import (
    "embed"
    "fmt"
    "io/fs"
    "log"
    "net/http"
)

func main() {
    http.Handle("/", http.FileServer(getFileSystem()))
    http.HandleFunc("/api/", api)
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        log.Fatal(err)
    }
}

func getFileSystem() http.FileSystem {
    fsys, err := fs.Sub(dist, "gui/dist")
    if err != nil {
        log.Fatal(err)
    }
    return http.FS(fsys)
}
func api(w http.ResponseWriter, r *http.Request) {
    msg := fmt.Sprintf("TODO: %s", r.URL)
    http.Error(w, msg, http.StatusNotImplemented)
}

//go:embed gui/dist/*
var dist embed.FS

Upvotes: 22

Related Questions