提问人:Subhankar 提问时间:5/5/2023 最后编辑:Subhankar 更新时间:5/5/2023 访问量:781
Golang :如何在块中读取和处理请求正文,并在请求正文中再次将其设置回去,而无需将其作为一个整体加载到内存中?[已结束]
Golang : How to read and process request body in chunks and set it back again in request body without loading it as a whole in memory? [closed]
问:
我们有一个 go Web 服务器,我们尝试在其中读取块中的请求正文内容以处理某些内容。但是,必须在工作完成后转发请求,因此必须再次重置请求正文。由于在不重置它的情况下无法从 request.body 中多次读取它,因此我们使用的是 Wrapper Reader 对象,该对象以块形式读取并将其并行写入缓冲区。在处理结束时,我们再次将此缓冲区添加到请求正文中。但是,由于缓冲区最终会加载整个内容,因此如果内容非常大,这将是一个问题。
package main
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"log"
"net/http"
)
func main() {
http.HandleFunc("/", handleRequest)
log.Fatal(http.ListenAndServe(":8080", nil))
}
func handleRequest(w http.ResponseWriter, req *http.Request) {
maxSize := int64(1000000)
b := bytes.Buffer{}
b.Write(make([]byte, 0, maxSize))
reader := MyReader{
r: req.Body,
buf: b,
size: 0,
maxSize: maxSize,
}
err := Validate(&reader)
if err != nil {
panic(err)
}
r := reader.GetBuffer()
fmt.Println(len(r.Bytes()))
req.Body = io.NopCloser(&r)
//pass the body back for the next handler!
}
type MyReader struct {
r io.Reader
buf bytes.Buffer
size int64
maxSize int64
}
func (rd *MyReader) Read(p []byte) (n int, err error) {
n, err = rd.r.Read(p)
if n > 0 {
rd.size = rd.size + int64(n)
if n, err := rd.buf.Write(p[:n]); err != nil {
return n, err
}
}
return n, err
}
func (rd *MyReader) GetBuffer() bytes.Buffer {
return rd.buf
}
func Validate(reader *MyReader) error {
//Get standard json decoder
decoder := json.NewDecoder(reader)
for {
//decode next token
t, err := decoder.Token()
//Validate the token - should not throw any error
if err == io.EOF {
return nil
}
if err != nil {
return errors.New("Some error")
}
fmt.Println(t)
//processing being done on the token
}
}
有没有办法避免缓冲区并将内容流式传输回请求正文,而无需在内存中读取它?
答: 暂无答案
评论
io.TeeReader