简体   繁体   English

配置 echo http 服务器来控制传输编码

[英]configure echo http server to control transfer encoding

I have a simple HTTP server written in golang using echo v4.我有一个使用 echo v4 用 golang 编写的简单 HTTP 服务器。 When the response size is bigger than a certain size (threshold is 2.12K as I have tested), server sets the Transfer-Encoding header to chunked and sends the response in multiple chunks, but for smaller responses, the server does not set the Transfer-Encoding header and sends the response body plain.当响应大小大于一定大小时(我测试过的阈值是 2.12K),服务器将Transfer-Encoding header 设置为chunked并以多个块发送响应,但对于较小的响应,服务器不会设置Transfer-Encoding并发送响应正文。

I want to control this behavior, so that I can define the threshold where the echo HTTP server starts to chunk the response body.我想控制这种行为,以便我可以定义 echo HTTP 服务器开始分块响应正文的阈值。 My google searches show that I can obtain this by manipulating the ResponseWriter , but I could not figure out how to do that in my code.我的谷歌搜索显示我可以通过操作ResponseWriter来获得它,但我无法在我的代码中弄清楚如何做到这一点。

This is my code:这是我的代码:

func main() {
    e := echo.New()

    e.Use(middleware.Logger())
    e.Use(middleware.Recover())

    e.GET("/hi", func(c echo.Context) error {
        data := make(map[int]string)
    
        for i := 0; i < repeatCount; i++ {
            data[i] = strings.Repeat("z", i)
        }
    
        return c.JSON(http.StatusOK, data)
    })
    
    e.Logger.Fatal(e.Start(":3000"))
}

Can anyone please help me here?任何人都可以在这里帮助我吗?

The net/http server uses the identify transfer encoding when Content-Length header is set.当设置 Content-Length header 时,net/http 服务器使用识别传输编码。 If the length of the response body is known, set the content length header before writing to the response:如果响应正文的长度已知,则在写入响应之前设置内容长度 header:

  w := c.Response().Writer
  w.Header().Set("Content-Length", strconv.Atoi(contentLength))

The application can buffer the response to compute the content length:应用程序可以缓冲响应以计算内容长度:

data := make(map[int]string)
for i := 0; i < repeatCount; i++ {
    data[i] = strings.Repeat("z", i)
}
p, err := json.Marshal(data)
// <-- insert code to handle error here
w := c.Response().Writer
w.Header().Set("Content-Length", strconv.Atoi(len(p)))
return c.JSONBlob(http.StatusOK, p)

The net/http server uses the identity transfer encoding when the Transfer-Encoding header is set to identity.当 Transfer-Encoding header 设置为 identity 时,net/http 服务器使用身份传输编码。 The server terminates the response body by closing the connection.服务器通过关闭连接来终止响应正文。 The client reads the response body to EOF.客户端将响应正文读取到 EOF。 Set the header before writing to the response.在写入响应之前设置 header。

  w := c.Response().Writer
  w.Header().Set("Transfer-Encoding", "identity")

The net/http server buffers 2048 bytes of the response body. net/http 服务器缓冲 2048 字节的响应正文。 The application cannot change the size of this buffer.应用程序无法更改此缓冲区的大小。 If the entire response body fits within this buffer, the server sets the Content-Length header and uses the identity transfer encoding.如果整个响应主体都适合此缓冲区,则服务器设置 Content-Length header 并使用身份传输编码。

Otherwise, the server uses chunked encoding.否则,服务器使用分块编码。

Use an application controlled buffer to change the threshold at which chunking occurs:使用应用程序控制的缓冲区来更改发生分块的阈值:

w := c.Response().Writer
b := bufio.NewWriterSize(c.Response(), threshold)
w.Header().Set("Content-Type", echo.MIMEApplicationJSONCharsetUTF8)
err := json.NewEncoder(c.Response).Encode(data)
// <-- insert code to handle error here.

// If no data was written to the net/http server's reponse
// writer, then the entire response is in the bufio.Writer.
// Set the Content-Length header to the length of the buffered
// data.
if !c.Response().Committed {
   w.Header().Set("Content-Length", strconv.Atoi(b.Buffered())
}

// In all cases, flush bufio.Writer.
b.Flush()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM