Golang文件上传:如果文件太大,则关闭连接

Eti*_*nes 9 upload http go

我想允许上传文件.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..."))
Run Code Online (Sandbox Code Playgroud)

Cer*_*món 16

大多数客户端在完成写入请求之前不会读取响应.响应服务器的错误不会导致这些客户端停止写入.

net/http服务器支持100 continue状态.要使用此功能,服务器应用程序应在读取请求正文之前响应错误:

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
Run Code Online (Sandbox Code Playgroud)

如果客户端发送了"Expect:100-continue"标头,则客户端应在写入请求主体之前等待100 continue状态.当服务器应用程序读取请求主体时,net/http服务器自动发送100继续状态.在读取请求之前,服务器可以通过回复错误来阻止客户端编写请求正文.

net/http客户端不支持100继续状态.

如果客户端没有发送expect头并且服务器应用程序从请求处理程序返回而没有读取完整的请求主体,则net/http服务器读取并丢弃最多256个<< 10字节的请求主体.如果未读取整个请求正文,服务器将关闭连接.