新手问题 Golang HTTP请求中间件相关问题请教

1272881215 · 2018年06月25日 · 最后由 pathbox 回复于 2018年06月25日 · 549 次阅读

公司这边有一个需求是这样的:

有一个form表单,上传文件,在前端不做文件扩展名和文件大小的校验,放在后端做,但是考虑到如果用户上传的文件比较大,需要较长的时间,所以要求用户表单提交触发HTTP请求之后,在未上传附件的情况下后端即根据请求对扩展名和文件大小校验,如果校验不通过,则返回错误请求提示。

这个说是要用 HTTP 中间件实现,请问下如何实现?有没有 Go 的 http 中间件推荐?

更多原创文章干货分享,请关注公众号
  • 加微信实战群请加微信(注明:实战群):gocnio

简单点说,就是用户通过 form 表单上传 1 个 G 的文件,在触发请求到后端的时候,就对文件扩展名和文件大小等进行校验,而不需要上传完整个文件才告诉用户说文件大小超过限制...

能实现吗?

我觉得可以这样,先发一个 option 请求,后端校验通过,浏览器再发送真正的 post 请求。

看 http 头的 content-length?

> 在未上传附件的情况下后端即根据请求对扩展名和文件大小校验

很好奇能不能实现...

如果前面挂 nginx 的话,可以直接先在 nginx 做对大小的限制配置。

  1. 手动写中间件 (其实没那么难,只是可能没那么灵活),根据 header 的 content-length 和文件名 做验证
  2. 第三方的中间件库 alice、negroni
  3. 如果用的 web 框架,找一下对应框架的 中间件实现
  4. 不要在中间件去 read body,如果要这样操作,最好使用 context 将 body 内容继续传下去。因为 read 过 body,这个 body 就被读取出来了,再 handler 里面再 read 的时候,就没有数据了,如果遇到这种情况,很有可能就是这个原因

看下 这段代码

func HelloServer(w http.ResponseWriter, r *http.Request) {
    if "POST" == r.Method {
        file, _, err := r.FormFile("userfile")
        if err != nil {
            http.Error(w, err.Error(), 500)
            return
        }

        if statInterface, ok := file.(Stat); ok {
            fileInfo, _ := statInterface.Stat()
            fmt.Fprintf(w, "上传文件的大小为: %d", fileInfo.Size())
        }
        if sizeInterface, ok := file.(Size); ok {
            fmt.Fprintf(w, "上传文件的大小为: %d", sizeInterface.Size())
        }

        return
    }
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册