Golang文件上传:如果文件太大,关闭连接 [英] Golang file upload: close connection if file is too large

查看:349
本文介绍了Golang文件上传:如果文件太大,关闭连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想允许上传文件。 Go被服务器端用来处理请求。我想发送一个响应文件太大,只要他们试图上传的文件太大。我希望这样做,在整个文件上传之前(带宽)。

我正在使用下面的代码片段,但它仅在客户端完成上传后才发送响应。它保存了一个5 kB文件。

  const MaxFileSize = 5 * 1024 
//这感觉就像一个不好的破解...
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(响应)))
w.WriteHeader(http.StatusExpectationFailed)
w.Write(响应)
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)
推迟dst.Close()
if err!= nil {
panic(err)
}

写成,err:= io.Copy(dst,io.LimitReader(file,MaxFileSize))
if err! = nil {
panic(err)
}

if if == MaxFileSize {
w.Write([] byte(File too large))
返回
}
w.Write([] byte(Success ...))

$ b $在写完请求之前,大多数客户端不会读取响应。



net / http服务器支持 100继续状态。要使用此功能,服务器应用程序应在读取请求体之前响应一个错误:

  func处理程序(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)

// ...继续之前

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



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



如果客户确实不发送期望头并且服务器应用程序从请求处理程序返回而没有读取完整的请求体,则net / http服务器读取并丢弃高达256 <请求主体的10个字节。如果整个请求体未被读取,服务器将关闭连接。


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..."))

解决方案

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.

这篇关于Golang文件上传:如果文件太大,关闭连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆