首页 > 解决方案 > 动态路由的文件服务器目录

问题描述

我的场景

编译的角度项目保存为

.
├── 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

数据库

TABLE data(id , branch, commit)

条目:例如

ID 分支 犯罪
美国广播公司 分支1 提交C
定义 分支1 提交D
掌握 提交A

现在我想访问

:8080/apps/{id}

例如:localhost:8080/apps/ abc

路径应该在请求 DB 条目后生成

和一个文件服务器服务于目录 ./files/ branch1 / commitC /

现在我希望看到文件夹 app1 和 app2

我有的

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)
}

我怎样才能像这样为整个目录提供服务,以便可以正确访问所有 css 和 js 文件?

我想我需要这样的东西

http.Handle("/tmpfiles/", http.StripPrefix("/tmpfiles/", http.FileServer(http.Dir("/tmp"))))

但是如何访问 mux.Vars(request) 来建立目录路径?

############ 关于CSS服务问题

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 文件作为“文本/纯文本”提供

文件:

索引.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}

标签: httpgohandlemux

解决方案


http.FileServer返回一个处理程序。可以手动调用此处理程序,而不是注册到修复路径。

您将原始w http.ResponseWriter, r *http.Request参数传递给它,因此 http.FileServer 能够访问请求并写入响应。

您可能需要将其包装http.FileServer到一个http.StripPrefix处理程序中,以便原始请求中的路径被剥离为相对于path变量的路径。

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)
}

推荐阅读