Go FileServer

JunChow520 · · 1997 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

文件服务器

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页面未发现错误。


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:JunChow520

查看原文:Go FileServer

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1997 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传