问题
My scenario
Compiled angular projects are saved like
.
├── branch1
│ ├── commitC
│ │ ├── app1
│ │ │ ├── index.html
│ │ │ └── stylesheet.css
│ └── commitD
│ ├── app1
│ │ ├── index.html
│ │ └── stylesheet.css
│ └── app2
│ ├── index.html
│ └── stylesheet.css
├── branch2
│ ├── commitE
│ ├── app1
│ │ ├── index.html
│ │ └── stylesheet.css
│ └── app2
│ ├── index.html
│ └── stylesheet.css
└── master
├── commitA
│ ├── app1
│ │ ├── index.html
│ │ └── stylesheet.css
└── commitB
├── app1
├── index.html
└── stylesheet.css
Database
TABLE data(id , branch, commit)
Entries: e.g.
id | branch | commit |
---|---|---|
abc | branch1 | commitC |
def | branch1 | commitD |
ghi | master | commitA |
Now I want to access
:8080/apps/{id}
e.g.: localhost:8080/apps/abc
the path should will be generated after requesting the DB entry
and a fileserver serves the directory ./files/branch1/commitC/
now i would expect to see the folders app1 and app2
What I have
func main() {
mux = mux.NewRouter()
mux.HandleFunc("/apps/{id}/{app}", s.serveApp).Methods("GET")
}
func (s *Server) serveApp(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
app := params["app"]
id := params["id"]
entry, err := getFromDB(id)
if err != nil {
w.Header().Set("Content-Type", "text/html")
respondWithError(w, http.StatusInternalServerError, err.Error())
return
}
file := filepath.Join(DefaultFolder, entry.Branch, entry.Commit, app, "index.html")
fmt.Printf("redirecting to %s", file)
http.ServeFile(w, r, file)
}
how can I serve the whole directory like that, so all css and js files can be accessed correctly?
I think I need something like this
http.Handle("/tmpfiles/", http.StripPrefix("/tmpfiles/", http.FileServer(http.Dir("/tmp"))))
but how can a access mux.Vars(request) to build up the directory path?
############ Regarding CSS serving problem
import (
"log"
"net/http"
"github.com/gorilla/mux"
)
func main() {
mux := mux.NewRouter()
fs := http.FileServer(http.Dir("static"))
mux.Handle("/", fs)
log.Println("Listening...")
http.ListenAndServe(":3000", mux)
}
CSS files are served as 'text/plain'
Files:
- main.go
- static/
- index.html
- main.css
index.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>A static page</title>
<link rel="stylesheet" href="main.css">
</head>
<body>
<h1>Hello from a static page</h1>
</body>
</html>
main.css
body {color: #c0392b}
回答1:
http.FileServer
returns a handler. This handler can be called manually instead of registered to a fix path.
You pass the original w http.ResponseWriter, r *http.Request
parameters to it, so the http.FileServer is able to access the request and write the response.
You will probably need to wrap the http.FileServer
into a http.StripPrefix
handler so the path in the original request gets stripped down to a path relativ to the path
variable.
func main() {
mux = mux.NewRouter()
mux.HandleFunc("/apps/{id}/{app}", s.serveApp).Methods("GET")
}
func (s *Server) serveApp(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
app := params["app"]
id := params["id"]
entry, err := getFromDB(id)
if err != nil {
w.Header().Set("Content-Type", "text/html")
respondWithError(w, http.StatusInternalServerError, err.Error())
return
}
path := filepath.Join(DefaultFolder, entry.Branch, entry.Commit, app)
// the part already handled by serveApp handler must be stripped.
baseURL := fmt.Sprintf("/apps/%s/%s/", id, app)
pathHandler := http.FileServer(http.Dir(path))
http.StripPrefix(baseURL, pathHandler).ServeHTTP(w, r)
// or in one line
// http.FileServer(http.StripPrefix(baseURL, http.Dir(path)).ServeHTTP(w, r)
}
来源:https://stackoverflow.com/questions/65216829/fileserver-directory-for-dynamic-route