Improve file too large error handling

This commit is contained in:
Dominic Ferrando
2025-04-22 21:26:33 -04:00
parent 0c657ae1c5
commit 4018632080
2 changed files with 23 additions and 40 deletions
-14
View File
@@ -261,17 +261,3 @@ func FormatFileInfo(fileInfo PostFileInfo) string {
} }
return fmt.Sprintf("(%s, %dx%d)", humanSize, fileInfo.Width, fileInfo.Height) return fmt.Sprintf("(%s, %dx%d)", humanSize, fileInfo.Width, fileInfo.Height)
} }
func IsMediaTooLarge(file multipart.File) (bool, error) {
limitedReader := io.LimitReader(file, FILE_MEM_LIMIT+1)
fileBytes, err := io.ReadAll(limitedReader)
if err != nil {
return true, err
}
if int64(len(fileBytes)) > FILE_MEM_LIMIT {
return true, nil
}
return false, nil
}
+23 -26
View File
@@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"io" "io"
"log" "log"
"mime/multipart"
"net/http" "net/http"
"path/filepath" "path/filepath"
"strconv" "strconv"
@@ -142,6 +143,16 @@ func main() {
// parse form // parse form
r.Body = http.MaxBytesReader(w, r.Body, util.MAX_REQUEST_BYTES) r.Body = http.MaxBytesReader(w, r.Body, util.MAX_REQUEST_BYTES)
if err := r.ParseMultipartForm(util.FILE_MEM_LIMIT); err != nil { if err := r.ParseMultipartForm(util.FILE_MEM_LIMIT); err != nil {
var maxErr *http.MaxBytesError
if errors.As(err, &maxErr) {
http.Error(w, fmt.Sprintf("File too large (max %s)", util.FormatBytes(util.FILE_MEM_LIMIT)), http.StatusRequestEntityTooLarge)
return
}
if errors.Is(err, multipart.ErrMessageTooLarge) {
http.Error(w, fmt.Sprintf("File too large (max %s)", util.FormatBytes(util.FILE_MEM_LIMIT)), http.StatusRequestEntityTooLarge)
return
}
http.Error(w, "Failed to parse form", http.StatusBadRequest) http.Error(w, "Failed to parse form", http.StatusBadRequest)
log.Printf("ParseMultipartForm: %v", err) log.Printf("ParseMultipartForm: %v", err)
return return
@@ -175,19 +186,7 @@ func main() {
defer file.Close() defer file.Close()
if header.Size > util.FILE_MEM_LIMIT { if header.Size > util.FILE_MEM_LIMIT {
http.Error(w, "File too large (max 10 MB)", http.StatusRequestEntityTooLarge) http.Error(w, fmt.Sprintf("File too large (max %s)", util.FormatBytes(util.FILE_MEM_LIMIT)), http.StatusRequestEntityTooLarge)
return
}
isMediaTooLarge, err := util.IsMediaTooLarge(file)
if err != nil {
http.Error(w, "Failed to detect if file is too large", http.StatusInternalServerError)
return
}
file.Seek(0, io.SeekStart)
if isMediaTooLarge {
http.Error(w, "File too large (max 10MB)", http.StatusRequestEntityTooLarge)
return return
} }
@@ -237,6 +236,16 @@ func main() {
// parse form // parse form
r.Body = http.MaxBytesReader(w, r.Body, util.MAX_REQUEST_BYTES) r.Body = http.MaxBytesReader(w, r.Body, util.MAX_REQUEST_BYTES)
if err := r.ParseMultipartForm(util.FILE_MEM_LIMIT); err != nil { if err := r.ParseMultipartForm(util.FILE_MEM_LIMIT); err != nil {
var maxErr *http.MaxBytesError
if errors.As(err, &maxErr) {
http.Error(w, fmt.Sprintf("File too large (max %s)", util.FormatBytes(util.FILE_MEM_LIMIT)), http.StatusRequestEntityTooLarge)
return
}
if errors.Is(err, multipart.ErrMessageTooLarge) {
http.Error(w, fmt.Sprintf("File too large (max %s)", util.FormatBytes(util.FILE_MEM_LIMIT)), http.StatusRequestEntityTooLarge)
return
}
http.Error(w, "Failed to parse form", http.StatusBadRequest) http.Error(w, "Failed to parse form", http.StatusBadRequest)
log.Printf("ParseMultipartForm: %v", err) log.Printf("ParseMultipartForm: %v", err)
return return
@@ -268,19 +277,7 @@ func main() {
defer file.Close() defer file.Close()
if header.Size > util.FILE_MEM_LIMIT { if header.Size > util.FILE_MEM_LIMIT {
http.Error(w, "File too large (max 10 MB)", http.StatusRequestEntityTooLarge) http.Error(w, fmt.Sprintf("File too large (max %s)", util.FormatBytes(util.FILE_MEM_LIMIT)), http.StatusRequestEntityTooLarge)
return
}
isMediaTooLarge, err := util.IsMediaTooLarge(file)
if err != nil {
http.Error(w, "Failed to detect if file is too large", http.StatusInternalServerError)
return
}
file.Seek(0, io.SeekStart)
if isMediaTooLarge {
http.Error(w, "File too large (max 5MB)", http.StatusRequestEntityTooLarge)
return return
} }