为了账号安全,请及时绑定邮箱和手机立即绑定

如何在 Go 中使用虚拟主机功能服务静态文件

如何在 Go 中使用虚拟主机功能服务静态文件

Go
波斯汪 2022-12-19 21:12:45
如何FileServer在 Go 中为虚拟主机提供静态文件(带有 )?如果我有自己的处理函数,任务似乎很容易解决 [ 1 ]:package mainimport (    "fmt"    "net/http")func main() {    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {        fmt.Fprintf(w, "Hello, world!")    })    http.HandleFunc("qa.example.com/", func(w http.ResponseWriter, r *http.Request) {        fmt.Fprintf(w, "Hello, improved world!")    })    http.ListenAndServe(":8080", nil)}但是,如果我需要为FileServer虚拟主机提供静态文件(带有 )怎么办?这个r.PathPrefix("qa.example.com/").Handler(http.FileServer(http.Dir("/static/qa/")))不起作用——它只是被忽略了。我究竟做错了什么?这种方法通常是错误的吗?
查看完整描述

2 回答

?
catspeake

TA贡献1111条经验 获得超0个赞

package main


import (

    "embed"

    "fmt"

    "net/http"

    "strings"

    "time"

)


//go:embed *.go

var f embed.FS


func main() {

    // embed.Fs defaule modtime use now or env value.

    now := time.Now()

    // use mapping host to http.FileSystem

    vhosts := make(map[string]http.FileSystem)

    vhosts["qa.example.com"] = http.FS(f)    // from embed.FS

    vhosts["my.example.com"] = http.Dir(".") // from http.Dir


    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {

        fmt.Fprintf(w, "Hello, world!")

    })

    http.HandleFunc("/static/", func(w http.ResponseWriter, r *http.Request) {

        // find host

        fs, ok := vhosts[r.Host]

        if !ok {

            w.WriteHeader(404)

            w.Write([]byte("404 not found vhost"))

            return

        }

        // open file from http.FileSystem

        file, err := fs.Open(strings.TrimPrefix(r.URL.Path, "/static/"))

        if err != nil {

            // reference go1.18.3/net/http/fs.go toHTTPError function hander file error.

            w.Write([]byte("check err is 403 or 404 or 500"))

            return

        }

        stat, _ := file.Stat()

        // fix embed modtime is zero.

        modtime := stat.ModTime()

        if modtime.IsZero() {

            modtime = now

        }

        // response

        http.ServeContent(w, r, stat.Name(), modtime, file)


    })


    http.ListenAndServe(":8080", nil)

}

运行 test exec 命令curl -H "Host: my.example.com" 127.0.0.1:8080/static/01.go,01.go 替换您的静态文件名。


查看完整回答
反对 回复 2022-12-19
?
largeQ

TA贡献2039条经验 获得超7个赞

为 注册处理程序host/path/path仅在调用文件处理程序时剥离该部分。

此注册为qa.example.com/static/*目录中的文件提供服务./static/qa/

http.HandleFunc("qa.example.com/static/", http.StripPrefix("/static", http.FileServer(http.Dir("./static/qa/")))



查看完整回答
反对 回复 2022-12-19
  • 2 回答
  • 0 关注
  • 75 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信