Search code examples
gofasthttp

How do I make go fasthttp server to trigger the handler faster at a fileupload?


I use fasthttp for a file server project. The file server has an upload function. For uploading files I pass a key as a URL Query to validate the permission for upload.

The main():

// start http server
log.Printf("Starting HTTP server on %q", listento)
go func() {
    h := &fasthttp.Server{
        Handler: requestHandler,
        MaxRequestBodySize: 2 * 1024 * 1024 * 1024,
    }
    if err := h.ListenAndServe(listento); err != nil {
        log.Panicf("error in ListenAndServe: %s", err)
    }

}()

The requestHandler function:

func requestHandler(ctx *fasthttp.RequestCtx) {
    switch string(ctx.Path()) {
    case "/uploadx":    
        log.Println("Upload: ["+ctx.RemoteIP().String()+"] ["+string(ctx.Path())+"]")
    }   
}

I upload a big file and unfortunately the requestHandler gets triggered when the file upload process is completed. But it should be triggered on start of the upload process, because i want to avoid someone upload a 500MB file without check permission first.

Is there any way to make the requestHandler trigger faster? On the start of the Upload Process?

The Server itself received the first part of the HTTP Request, so the big question is, why does fasthttp trigger requestHandler so late?


I tried now net/http:

mux.HandleFunc("/upload", uploadFile)

func uploadFile(w http.ResponseWriter, r *http.Request) {
    fmt.Println("File Upload Endpoint Hit")
    fmt.Println(r)
}

With net/http i receive the File Upload Endpoint Hit already on start of the FileUpload - exactly like required but i really prefer to use fasthttp.

Am i doing something wrong? Thanks


Solution

  • For big file uploads browsers send a Expect: 100-continue header to ask the server if it's ok for them to continue with the upload. You could use https://godoc.org/github.com/valyala/fasthttp#Server.ContinueHandler to check for permissions and either allow or reject the upload.

    Fasthttp will always read the full response before calling a handler. This allows for a more performant API with less allocations.