Fileserver directory for dynamic route

心不动则不痛 提交于 2021-01-29 20:06:37

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!