diff pkg/misc/http.go @ 4875:6237e6165041

* Raise the upload limit for sounding results from 25GB up to 50GB. * Issue an error if sounding results uploads are over the limit instead of silently truncating them. * Fix a file handle leak when storing all uploads.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Fri, 31 Jan 2020 23:17:37 +0100
parents 9cbed444b8a4
children 1222b777f51f
line wrap: on
line diff
--- a/pkg/misc/http.go	Fri Jan 31 17:11:30 2020 +0100
+++ b/pkg/misc/http.go	Fri Jan 31 23:17:37 2020 +0100
@@ -15,6 +15,7 @@
 
 import (
 	"bufio"
+	"fmt"
 	"io"
 	"io/ioutil"
 	"net/http"
@@ -30,7 +31,14 @@
 // the given file name.
 // If the file is long than the given limit maxSize
 // this function returns an error.
-func StoreUploadedFile(req *http.Request, field, fname string, maxSize int64) (string, error) {
+func StoreUploadedFile(
+	req *http.Request,
+	field, fname string,
+	maxSize int64) (string, error) {
+	return StoreUploadedFileCheck(req, field, fname, maxSize, false)
+}
+
+func StoreUploadedFileCheck(req *http.Request, field, fname string, maxSize int64, errorOverMax bool) (string, error) {
 
 	// Check for direct upload.
 	f, _, err := req.FormFile(field)
@@ -52,14 +60,34 @@
 
 	out := bufio.NewWriter(o)
 
-	if _, err = io.Copy(out, io.LimitReader(f, maxSize)); err != nil {
+	// Little trick to check if we are over the limit.
+	size := maxSize
+	if errorOverMax {
+		size++
+	}
+
+	cleanup := func() {
 		o.Close()
 		os.RemoveAll(dir)
+	}
+
+	r, err := io.Copy(out, io.LimitReader(f, size))
+	if err != nil {
+		cleanup()
 		return "", err
 	}
 
+	if errorOverMax && r > maxSize {
+		cleanup()
+		return "", fmt.Errorf("upload exceeded limit of %d bytes", maxSize)
+	}
+
 	if err = out.Flush(); err != nil {
-		o.Close()
+		cleanup()
+		return "", err
+	}
+
+	if err := o.Close(); err != nil {
 		os.RemoveAll(dir)
 		return "", err
 	}