Go http.MaxBytesReader 重置连接

huangapple go评论87阅读模式
英文:

Go http.MaxBytesReader resetting connection

问题

我正在尝试在上传文件时对文件大小进行限制。以下代码可以正确检测到文件(或者更准确地说是请求体)是否大于1MB。然而,如果是这种情况,返回的页面是一个"连接被重置"的页面,而不是我自定义的错误消息页面。如果文件小于1MB,我会正确地得到一个显示"文件上传成功"的页面。

我希望能得到一些关于为什么连接被重置而不是按照我在下面的代码中指定的内容进行服务的指导。

func baseHandler(writer http.ResponseWriter, request *http.Request) {
    request.Body = http.MaxBytesReader(writer, request.Body, 1024 * 1024)
    _, _, err := request.FormFile("uploadfile")
    
    if err != nil {
        fmt.Fprintf(writer, "ERROR: %v", err) // 应该在浏览器中显示,但实际上没有显示
        fmt.Printf("ERROR: %v", err) // 写入终端,所以任何错误都能正确识别

        return
    }

    fmt.Fprintf(writer, "文件上传成功")
}


func main() {
    http.HandleFunc("/", baseHandler)
    http.ListenAndServe(":8080", nil)
}
英文:

I am trying to implement a restriction on file size when uploading files. The following code correctly detects whenever the file (or rather the request body, but close enough for my purposes) is larger than 1 MB. If this is the case however, the page returned is a "The connection was reset" page, instead of a page with my custom error message. If the file is under 1 MB I correctly get a page saying "File upload OK".

I would love some pointers on why the connection to the server is reset instead of serving what I specify in the code below.

func baseHandler(writer http.ResponseWriter, request *http.Request) {
    request.Body = http.MaxBytesReader(writer, request.Body, 1024 * 1024)
    _, _, err := request.FormFile("uploadfile")
    
    if err != nil {
	    fmt.Fprintf(writer, "ERROR: %v", err) // Should be displayed in browser, is not
        fmt.Printf("ERROR: %v", err) // Gets written to terminal, so any errors are correctly identified

	    return
    }

    fmt.Fprintf(writer, "File upload OK")
}


func main() {
    http.HandleFunc("/", baseHandler)
    http.ListenAndServe(":8080", nil)
}

答案1

得分: 4

服务器确实会写入响应。问题在于客户端没有读取响应。

当超过MaxBytesReader限制时,服务器停止从客户端读取数据。此外,服务器在将响应写入客户端后的半秒钟内完全关闭连接。

许多HTTP客户端在读取响应之前会将完整的请求体写入,并在写入请求体时出现任何错误时停止。当请求体足够大并且忽略服务器写入的响应时,这些客户端会报告“连接重置”等错误。

服务器代码指针:当超过MaxBytesReader限制时,响应的requestBodyLimitHit字段被设置为true。所有相关的代码都在使用此字段的附近。

英文:

The server does write the response. The issue is that the client does not read the response.

When the MaxBytesReader limit is breached, the server stops reading data from the client. Also, the server fully closes the connection a half second after writing the response to the client.

Many HTTP clients write the complete request body before reading the response and stop on any error writing the request body. These clients report "connection reset" errors and the like when the request body is sufficiently large and ignore the response written by the server.

Server code pointers: When the MaxBytesReader limit is breached, the response's requestBodyLimitHit field is set to true. All relevant code is near uses of this field.

huangapple
  • 本文由 发表于 2017年5月4日 16:17:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/43777433.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定