Go 標準庫 http.FileServer 實現靜態檔案服務

來源:互聯網
上載者:User
http.FileServer 方法屬於標準庫 net/http,返回一個使用 FileSystem 介面 root 提供檔案訪問服務的 HTTP 處理器。可以方便的實現靜態檔案伺服器。
http.ListenAndServe(":8080", http.FileServer(http.Dir("/files/path")))

訪問 http://127.0.0.1:8080,即可看到類似 Nginx 中 autoindex 瀏覽目錄功能。

源碼解析

我們現在開始將上述的那僅有的一行代碼進行剖析,看看到底是如何?的。源碼中英文注釋也比較詳細,可以參考。

我們先看 http.Dir(),再看 http.FileServer(),而 http.ListenAndServe() 監聽 TCP 通訊埠並提供路由服務,此處不贅述。

http.Dir()

從以下源碼我們可以看出,type Dir string 實現了 type FileSystem interface 的介面函數 Openhttp.Dir("/") 實際返回的是 http.Dir 類型,將字串路徑轉換成檔案系統。

// 所屬檔案: src/net/http/fs.go, 26-87行type Dir stringfunc (d Dir) Open(name string) (File, error) {    // ...}type FileSystem interface {    Open(name string) (File, error)}

http.FileServer()

http.FileServer() 方法返回的是 fileHandler 執行個體,而 fileHandler 結構體實現了 Handler 介面的方法 ServeHTTP()ServeHTTP 方法內的核心是 serveFile() 方法。

// 所屬檔案: src/net/http/fs.go, 690-716行type fileHandler struct {    root FileSystem}func FileServer(root FileSystem) Handler {    return &fileHandler{root}}func (f *fileHandler) ServeHTTP(w ResponseWriter, r *Request) {    upath := r.URL.Path    if !strings.HasPrefix(upath, "/") {        upath = "/" + upath        r.URL.Path = upath    }    serveFile(w, r, f.root, path.Clean(upath), true)}
// 所屬檔案: src/net/http/server.go, 82行type Handler interface {    ServeHTTP(ResponseWriter, *Request)}

serveFile() 方法判斷,如果訪問路徑是目錄,則列出目錄內容,如果是檔案則使用 serveContent() 方法輸出檔案內容。serveContent() 方法則是個讀取檔案內容並輸出的方法,此處不再貼代碼。

// 所屬檔案: src/net/http/fs.go, 540行// name is '/'-separated, not filepath.Separator.func serveFile(w ResponseWriter, r *Request, fs FileSystem, name string, redirect bool) {    // 中間代碼已省略    if d.IsDir() {        if checkIfModifiedSince(r, d.ModTime()) == condFalse {            writeNotModified(w)            return        }        w.Header().Set("Last-Modified", d.ModTime().UTC().Format(TimeFormat))        dirList(w, r, f)        return    }    // serveContent will check modification time    sizeFunc := func() (int64, error) { return d.Size(), nil }    serveContent(w, r, d.Name(), d.ModTime(), sizeFunc, f)}

支援子目錄路徑

http.StripPrefix() 方法配合 http.Handle()http.HandleFunc() 可以實現帶路由首碼的檔案服務。

package mainimport (    "net/http"    "fmt")func main() {    http.Handle("/tmpfiles/", http.StripPrefix("/tmpfiles/", http.FileServer(http.Dir("/tmp"))))    err := http.ListenAndServe(":8080", nil)    if err != nil {        fmt.Println(err)    }}
原文地址: https://shockerli.net/post/go...
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.