【发布时间】:2014-10-15 21:11:36
【问题描述】:
我想允许上传文件。 Go 被用于服务器端来处理请求。每当他们尝试上传的文件太大时,我想发送响应“文件太大”。我想这样做,之前整个文件被上传(带宽)。
我正在使用以下 sn-p,但它只是在客户端完成上传后才发送响应。它保存一个 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..."))
【问题讨论】:
-
棘手。也许您可以使用 io.CopyN 读取
MaxFileSize + 1字节。如果err != EOF,则超出限制或存在其他问题。不过,我不确定如果您这样做,用户会在浏览器中看到什么行为——试一试看看。另外,我知道这是测试代码,但是从panics 切换到错误返回对于您的生产代码来说是个好主意。 -
感谢您的建议。用
CopyN替换Copy并读取MaxFileSize + 1字节没有帮助(在浏览器端)。至于恐慌,我通常有一个特殊的RecoverHandler,它可以从恐慌中恢复并产生一个很好的错误 400 页面。不过感谢您的关注。