drj58429 2014-10-15 21:11
浏览 304
已采纳

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

I want to allow uploading files. Go is being used server-side to handle requests. I would like to send a response "File too large" whenever the file they're trying to upload is too large. I would like to do so, before the entire file is uploaded (bandwidth).

I am using the following snippet, but it's only sending a response after the client is done uploading. It saves a 5 kB file.

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..."))
  • 写回答

1条回答 默认 最新

  • douhuifen9942 2014-10-15 22:33
    关注

    Most clients do not read the response until done writing the request. Responding with an error from the server will not cause these clients to stop writing.

    The net/http server supports the 100 continue status. To use this feature, the server application should respond with an error before reading the request body:

    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
    

    If the client sent the "Expect: 100-continue" header, then the client should wait for the 100 continue status before writing the request body. The net/http server automatically sends the 100 continue status when the server application reads the request body. The server can stop the client from writing the request body by replying with an error before reading the request.

    The net/http client does not support the 100 continue status.

    If the client did not send the expect header and the server application returns from the request handler without reading the complete request body, then the net/http server reads and discards up to 256 << 10 bytes of the request body. The server will closes the connection if the entire request body was not read.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 HLs设计手写数字识别程序编译通不过
  • ¥15 Stata外部命令安装问题求帮助!
  • ¥15 从键盘随机输入A-H中的一串字符串,用七段数码管方法进行绘制。提交代码及运行截图。
  • ¥15 TYPCE母转母,插入认方向
  • ¥15 如何用python向钉钉机器人发送可以放大的图片?
  • ¥15 matlab(相关搜索:紧聚焦)
  • ¥15 基于51单片机的厨房煤气泄露检测报警系统设计
  • ¥15 Arduino无法同时连接多个hx711模块,如何解决?
  • ¥50 需求一个up主付费课程
  • ¥20 模型在y分布之外的数据上预测能力不好如何解决