Gin限制post数据大小的实践 | 青训营笔记

1,149 阅读1分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 12 天

溯源

今天在写项目的时候,遇到一个这样的场景:客户端上传视频,然后服务端保存到本地,当客户端要获取视频的时候,会请求之前已经保存在服务端的静态视频资源。这个时候问题就来了,当客户端请求视频资源的时候,一些视频就会加载的十分缓慢,原因是视频资源太大,下载速度跟不上。这样使得整个软件使用起来都十分不流畅。而这个是一个前后端分离的项目,我无法在前端做手脚,于是就想着从服务端限制从客户端上传的文件大小。但是随即又踩了许多坑。

gin框架:router.MaxMultipartMemory

于是我去查了gin框架的文档,查到有关文件上传的内容,其中有这样一段代码

	// 为 multipart forms 设置较低的内存限制 (默认是 32 MiB)
	router.MaxMultipartMemory = 8 << 20  // 8 MiB

于是我拿着这段代码去做了测试,发现结果不尽人意,它不能控制文件上传的大小。MaxMultipartMemory只是限制内存,不是针对文件上传文件大小,即使文件大小比这个大,也会写入临时文件。

中间件:gin-contrib/size

于是我再次翻阅资源,发现了一个关于gin框架的一个中间件,他能限制post请求数据的大小。其github上是开源的。demo: package main

  "net/http"  
  
  limits "github.com/gin-contrib/size"  
  "github.com/gin-gonic/gin"  
)  
  
func handler(ctx *gin.Context) {  
  val := ctx.PostForm("b")  
  if len(ctx.Errors) > 0 {  
    return  
  }  
  ctx.String(http.StatusOK, "got %s\n", val)  
}  
  
func main() {  
  r := gin.Default()  
  r.Use(limits.RequestSizeLimiter(10))  
  r.POST("/", handler)  
  if err := r.Run(":8080"); err != nil {  
    log.Fatal(err)  
  }  
}

后来一经我测试发现确实能行得通。不过有一个需要注意的点limits.RequestSizeLimiter(int64)这个参数代表的含义是字节,也就是说限制1MB的话就要填1024,当然也能这样limits.RequestSizeLimiter(4<<20)代表4MB。

总结:

经过不断的摸索终于解决了问题,还是挺开心,继续加油。

参考:

  1. gin-contrib/size
  2. router.MaxMultipartMemory不能限制文件大小