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

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 宇视监控服务器无法登录
  • ¥15 PADS Logic 原理图
  • ¥15 PADS Logic 图标
  • ¥15 电脑和power bi环境都是英文如何将日期层次结构转换成英文
  • ¥15 DruidDataSource一直closing
  • ¥20 气象站点数据求取中~
  • ¥15 如何获取APP内弹出的网址链接
  • ¥15 wifi 图标不见了 不知道怎么办 上不了网 变成小地球了
  • ¥50 STM32单片机传感器读取错误
  • ¥50 power BI 从Mysql服务器导入数据,但连接进去后显示表无数据