我想允许上传文件。 Go 在服务器端被用来处理请求。每当他们尝试上传的文件太大时,我想发送一个响应“文件太大”。我想这样做,之前 整个文件被上传(带宽)。
我正在使用以下代码片段,但它仅在客户端完成上传后发送响应。它保存了一个 5 kB 的文件。
const MaxFileSize = 5 * 1024
// This feels like a bad hack...
if r.ContentLength > MaxFileSize {
if flusher, ok := w.(http.Flusher); ok {
response := []byte("Request too large")
w.Header().Set("Connection", "close")
w.Header().Set("Content-Length", fmt.Sprintf("%d", len(response)))
w.WriteHeader(http.StatusExpectationFailed)
w.Write(response)
flusher.Flush()
}
conn, _, _ := w.(http.Hijacker).Hijack()
conn.Close()
return
}
r.Body = http.MaxBytesReader(w, r.Body, MaxFileSize)
err := r.ParseMultipartForm(1024)
if err != nil {
w.Write([]byte("File too large"));
return
}
file, header, err := r.FormFile("file")
if err != nil {
panic(err)
}
dst, err := os.Create("upload/" + header.Filename)
defer dst.Close()
if err != nil {
panic(err)
}
written, err := io.Copy(dst, io.LimitReader(file, MaxFileSize))
if err != nil {
panic(err)
}
if written == MaxFileSize {
w.Write([]byte("File too large"))
return
}
w.Write([]byte("Success..."))
最佳答案
大多数客户端在写完请求之前不会读取响应。响应来自服务器的错误不会导致这些客户端停止写入。
net/http 服务器支持 100 continue status .要使用此功能,服务器应用程序应在读取请求正文之前以错误响应:
func handler(w http.ResponseWriter, r *http.Request) {
if r.ContentLength > MaxFileSize {
http.Error(w, "request too large", http.StatusExpectationFailed)
return
}
r.Body = http.MaxBytesReader(w, r.Body, MaxFileSize)
err := r.ParseMultipartForm(1024)
// ... continue as before
如果客户端发送了“Expect: 100-continue” header ,则客户端应在写入请求正文之前等待 100 continue 状态。当服务器应用程序读取请求主体时,net/http 服务器自动发送 100 继续状态。服务器可以通过在读取请求之前回复错误来阻止客户端写入请求主体。
net/http 客户端 does not support the 100 continue status .
如果客户端没有发送期望 header 并且服务器应用程序在没有读取完整的请求主体的情况下从请求处理程序返回,那么 net/http 服务器读取并丢弃最多 256 << 10 字节的请求主体。如果未读取整个请求正文,服务器将关闭连接。
关于http - Golang文件上传: close connection if file is too large,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26392196/