英文:
Read file in request body with Go Gin
问题
我在尝试使用Go Gin读取HTTP请求的请求体时,得到了一个空文件。在我的请求中,我通过请求体发送了一个附加的文件(内容类型:application/octet-stream)。
请求头
Authorization: Bearer XXX
User-Agent: PostmanRuntime/7.29.0
Accept: */*
Postman-Token: XXX
Host: localhost:8080
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 12
Content-Type: application/octet-stream
请求体
src: "文件路径"
后端Go代码:
bodySize, _ = strconv.ParseInt(c.Request.Header.Get("Content-Length"), 10, 64)
buf := bytes.NewBuffer(make([]byte, 0, bodySize))
_, err = io.Copy(buf, c.Request.Body)
fmt.Println(buf.String())
打印语句输出空字符串,但文件不为空(内容长度为12)。
英文:
I'm getting empty file when I try to read the request body of my HTTP request using Go Gin. On my request I'm sending a file attached to the Request Body (Content Type: application/octet-stream).
Request Headers
Authorization: Bearer XXX
User-Agent: PostmanRuntime/7.29.0
Accept: */*
Postman-Token: XXX
Host: localhost:8080
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 12
Content-Type: application/octet-stream
Request Body
src: "Path to my file"
Backend Go code:
bodySize, _ = strconv.ParseInt(c.Request.Header.Get("Content-Length"), 10, 64)
buf := bytes.NewBuffer(make([]byte, 0, bodySize))
_, err = io.Copy(buf, c.Request.Body)
fmt.Println(buf.String())
The print sentence prints empty string but the file is not empty (Content Length is 12).
答案1
得分: 1
> @novalagung 是的,我在主函数之前的中间件中读取它,在中间件之后,执行会继续使用 c.Next()。在中间件中,读取工作正常。
http.Request.Body
在读取内容后将为空。你需要在读取后将请求体存储在某个地方,这样就不需要再次读取它。
或者,还有另一种替代方法,你可以在读取后将内容放回 req.Body
中。
// 中间件读取请求体
bodyBytes, _ := ioutil.ReadAll(req.Body)
req.Body.Close() // 必须关闭
// 将 bodyBytes 放回 req.Body
req.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))
但我不建议这样做!
英文:
> @novalagung yes, I'm reading it in a middleware before the main function, after the middleware the execution continues with c.Next() . In the middleware the reading works fine. –
The http.Request.Body
will be empty after you read its content. You will need to store the request body somewhere after being read, so you do not need to read it twice.
Or, there is another alternative workaround, you can put back the content into the req.Body
after reading it.
// middleware do read the body
bodyBytes, _ := ioutil.ReadAll(req.Body)
req.Body.Close() // must close
// put back the bodyBytes to req.Body
req.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))
But I do not recommend it!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论