美文网首页
Go FileServer

Go FileServer

作者: JunChow520 | 来源:发表于2021-03-15 19:19 被阅读0次

    文件服务器

    Golang标准库net/http中提供了http.FileServer方法会返回一个使用FileSystem接口root提供文件访问服务器的HTTP处理器,可方便地实现静态文件服务器。

    http.ListenAndServe(":8080", http.FileServer(http.Dir("/files/path")))
    
    • http.Dir()方法会返回http.Dir类型用于将字符串路径转换为文件系统
    • http.FileServer()方法返回的是fileHandler实例,fileHandler结构体实现了Handler接口中的ServerHTTP()方法。

    对目录提供静态映射服务

    http.Handler("/", http.FileServer(http.Dir("/tmp")))
    

    使用http.FileServer创建一个使用给定文件系统的内容响应所有HTTP请求的处理程序。

    对文件提供静态映射服务

    http.HandleFunc("/static/", func(rw http.ResponseWriter, rq *http.Rquest){
      http.ServeFile(rw, rq, rq.URL.Path[1:])
    })
    

    支持子目录路径

    • 可使用http.StripPrefix()方法配合http.Handle()http.HandleFunc()实现待路由前缀的文件服务
    http.Handle("/tmpfile/", http.StripPrefix("/tmpfile/", http.FileServer(http.Dir("/tmp"))))
    

    静态资源服务器

    • 支持客户端请求文件请求,将服务器磁盘上的静态文件直接响应给客户端。

    例如:创建静态资源服务器

    $ vim main.go
    
    package main
    
    import (
        "net/http"
    )
    
    func main() {
        //获取当前程序的运行目录
        dir, _ := os.Getwd()
        //创建公共资源目录
        publicDir := path.Join(dir, "/public")
        //创建静态资源目录
        assetsDir := path.Join(publicDir, "/assets")
        fmt.Println(assetsDir)
        fmt.Printf("%s %T\n", assetsDir, assetsDir)
        //创建给定文件系统的内容响应所有HTTP请求的处理程序
        httpDir := http.Dir(assetsDir)
        fmt.Printf("%s %T\n", httpDir, httpDir)
        fs := http.FileServer(httpDir)
        //让文件服务器使用assets目录下的文件响应URL路径以/static/开头的所有HTTP请求
        //使用http.StripPrefix()方法将static前缀去掉后才能在assets目录下搜索请求的目标文件
        handle := http.StripPrefix("/static/", fs)
        //assets被设置为文件服务器的文件系统根目录
        //文件服务器会处理以/static开头的URL的请求
        http.Handle("/static/", handle)
        //监听端口开启服务
        http.ListenAndServe(":9000", nil)
    }
    

    服务端创建静态资源

    $ vim /public/test.txt
    hello test
    

    客户端模拟请求访问静态资源

    $ curl -i http://127.0.0.1:9000/static/test.txt
    HTTP/1.1 200 OK
    Accept-Ranges: bytes
    Content-Length: 10
    Content-Type: text/plain; charset=utf-8
    Last-Modified: Mon, 15 Mar 2021 10:38:42 GMT
    Date: Mon, 15 Mar 2021 10:39:34 GMT
    
    hello test
    

    http.FileServer

    fs := http.FileServer(httpDir)
    

    http.FileServer()方法最终会返回一个fileHandler结构实例

    func FileServer(root FileSystem) Handler {
        return &fileHandler{root}
    }
    

    fileHandler结构拥有一个FileSystem类型的root属性,用于指定文件服务器的根。

    type fileHandler struct {
        root FileSystem
    }
    

    fileHandler结构同时实现了Handler接口的ServeHTTP()方法,应该也是一个Handler

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

    fileHandler实现SererHTTP的关键是serveFile()函数

    func serveFile(w ResponseWriter, r *Request, fs FileSystem, name string, redirect bool) 
    

    http.StripPrefix

    func StripPrefix(prefix string, h Handler) Handler
    

    http.StripPrefix()方法用于过滤指定处理程序对应请求的特定前序以显示出文件目录

    http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./static"))))
    

    StripPrefix()方法返回一个处理器,该处理器会将请求的URL.Path字段中给定前缀prefix去除后再交给处理器来处理。若没有给定前缀存在则回复404页面未发现错误。

    相关文章

      网友评论

          本文标题:Go FileServer

          本文链接:https://www.haomeiwen.com/subject/rgtlcltx.html