13397158231   jevian_ma@worldflying.cn

利用go语言的新特性embed实现fasthttp静态文件包入可执行文件中

2022-03-29 22:13:02

go语言的embed特性在go1.16就已经成熟了,但是官方只提供了实现net.http内部包入的特性。作为go语言下最快的http库,fasthttp由于不兼容net.http,所以导致无法直接使用embed特性的官方例子将静态的文件包入可执行文件并直接使用。小沃最近遇到了这样的需求,记录下如何实现该功能的。

首先是启动embed功能,如

//go:embed www
var embededFiles embed.FS

注意上面的//go:embed www并不是注释,是必须写的,这个是go语言的特殊声明法,是用来声明编译路径下的www文件夹将包入可执行文件,并且通过embededFiles进行访问的,embededFiles支持文件的常规命令如Open,Read,Close等,但是不能Write与Delete。

剩下的只有两部,第一是要自己判断并设置http mime类型,也就是Content-Type头部,第二就是读文件,然后将读到的二进制给对象。

示例代码如下:

package main

import (
    "embed"
    "io"
    "log"
    "mime"
    "path"

    "github.com/valyala/fasthttp"
)

//go:embed www
var embededFiles embed.FS

func fasthttpHttpDialer(ctx *fasthttp.RequestCtx) {
    reqpath := string(ctx.Path())
    switch reqpath {
    case "/api/user/login":
        log.Println("登录api")
    default: // 作为文件服务使用的部分
        /*
           下方是访问当前可执行文件同级的真实www目录下的文件的方法,由于已经不需要了,所以注释掉。
           handler := fasthttp.FSHandler("www", 0)
           handler(ctx)
        */
        if reqpath[len(reqpath)-1:] == "/" { // 当请求路径没有添加文件时,默认认为请求的是index.html
            reqpath += "index.html"
        }
        f, err := embededFiles.Open("www" + reqpath) // 这里的www要求与包入可执行文件的资源一致。
        if err != nil {
            ctx.WriteString("file is not found!!!")
            return
        }
        // 1.利用path.Ext()获取文件的后缀
        // 2.利用mime.TypeByExtension()获取对应后缀的html mime类型
        // 3.利用ctx.SetContentType()设置http响应的Content-Type
        ctx.SetContentType(mime.TypeByExtension(path.Ext(reqpath)))
        io.Copy(ctx, f) // 这里使用io.Copy是为了防止文件太大时内存不够用。
        f.Close()
    }
}

func main() {
    log.SetFlags(log.LstdFlags | log.Lshortfile)
    log.Println("程序启动了。")
    fh := &fasthttp.Server{
        Handler:            fasthttpHttpDialer,
        MaxRequestBodySize: 100 * 1024 * 1024,
    }
    err := fh.ListenAndServe(":8080")
    if err != nil {
        log.Println(err)
        return
    }
}

然后正常的go build,编译器会自动将静态文件打包到可执行文件中去,因此如果静态文件太大,也会导致可执行文件也很大。


文章作者:沃航科技

优秀产品推荐:可编程网络IO控制器

上一篇:Cordova使用新版本Android支持http请求的方法

下一篇:在rt-thread中用spi通信驱动sd卡elmfatfs文件系统

联系我们

  • 地址:武汉市东湖高新开发区光谷总部国际1栋2412室
  • QQ:932773931
  • 电话:027-59761089-806
  • 手机:13397158231
  • 邮箱:jevian_ma@worldflying.cn

关注公众号

扫码添加微信

沃航(武汉)科技有限公司版权所有

备案号:鄂ICP备16014230号-1

本网站由提供CDN加速/云存储服务