fix(upload): clear error and higher limit for large files
- raise upload limit to 100 MB - return 413 file_too_large on MaxBytesError instead of misleading "expected multipart form" - client-side per-file and total size pre-check with a clear message
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
package photos
|
package photos
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -12,7 +13,7 @@ import (
|
|||||||
"shared-album/internal/httpx"
|
"shared-album/internal/httpx"
|
||||||
)
|
)
|
||||||
|
|
||||||
const maxUploadSize = 50 << 20
|
const maxUploadSize = 100 << 20
|
||||||
|
|
||||||
type Handler struct {
|
type Handler struct {
|
||||||
svc *Service
|
svc *Service
|
||||||
@@ -43,7 +44,12 @@ func (h *Handler) Upload(c *gin.Context) {
|
|||||||
c.Request.Body = http.MaxBytesReader(c.Writer, c.Request.Body, maxUploadSize)
|
c.Request.Body = http.MaxBytesReader(c.Writer, c.Request.Body, maxUploadSize)
|
||||||
form, err := c.MultipartForm()
|
form, err := c.MultipartForm()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
httpx.RespondError(c, httpx.BadRequest("invalid_request", "expected multipart form"))
|
var maxErr *http.MaxBytesError
|
||||||
|
if errors.As(err, &maxErr) {
|
||||||
|
httpx.RespondError(c, httpx.NewError(http.StatusRequestEntityTooLarge, "file_too_large", "files exceed the maximum upload size (100 MB)"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
httpx.RespondError(c, httpx.BadRequest("invalid_request", "invalid multipart form"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
files := form.File["files"]
|
files := form.File["files"]
|
||||||
|
|||||||
@@ -14,6 +14,8 @@
|
|||||||
let progress = $state(0);
|
let progress = $state(0);
|
||||||
let error = $state('');
|
let error = $state('');
|
||||||
|
|
||||||
|
const MAX_SIZE = 100 * 1024 * 1024;
|
||||||
|
|
||||||
export function pick() {
|
export function pick() {
|
||||||
fileInput?.click();
|
fileInput?.click();
|
||||||
}
|
}
|
||||||
@@ -21,6 +23,16 @@
|
|||||||
export function upload(files: FileList | File[]) {
|
export function upload(files: FileList | File[]) {
|
||||||
const list = Array.from(files);
|
const list = Array.from(files);
|
||||||
if (list.length === 0) return;
|
if (list.length === 0) return;
|
||||||
|
const tooBig = list.filter((f) => f.size > MAX_SIZE);
|
||||||
|
if (tooBig.length > 0) {
|
||||||
|
error = `Файл слишком большой: ${tooBig.map((f) => f.name).join(', ')}. Максимум 100 МБ.`;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const total = list.reduce((sum, f) => sum + f.size, 0);
|
||||||
|
if (total > MAX_SIZE) {
|
||||||
|
error = 'Суммарный размер файлов превышает 100 МБ. Загрузите меньшими порциями.';
|
||||||
|
return;
|
||||||
|
}
|
||||||
error = '';
|
error = '';
|
||||||
busy = true;
|
busy = true;
|
||||||
progress = 0;
|
progress = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user