Limit total size of unsent attachments
This commit is contained in:
parent
7b3e580fe4
commit
297afc5ce6
|
@ -692,7 +692,13 @@ func handleComposeAttachment(ctx *alps.Context) error {
|
||||||
var uuids []string
|
var uuids []string
|
||||||
for _, fh := range form.File["attachments"] {
|
for _, fh := range form.File["attachments"] {
|
||||||
uuid, err := ctx.Session.PutAttachment(fh, form)
|
uuid, err := ctx.Session.PutAttachment(fh, form)
|
||||||
if err != nil {
|
if err == alps.ErrAttachmentCacheSize {
|
||||||
|
form.RemoveAll()
|
||||||
|
return ctx.JSON(http.StatusBadRequest, map[string]string{
|
||||||
|
"error": "The total size of unset attachments on your session exceeds the maximum file size. Remove some attachments and try again.",
|
||||||
|
})
|
||||||
|
} else if err != nil {
|
||||||
|
form.RemoveAll()
|
||||||
ctx.Logger().Printf("PutAttachment: %v\n", err)
|
ctx.Logger().Printf("PutAttachment: %v\n", err)
|
||||||
return ctx.JSON(http.StatusBadRequest, map[string]string{
|
return ctx.JSON(http.StatusBadRequest, map[string]string{
|
||||||
"error": "failed to store attachment",
|
"error": "failed to store attachment",
|
||||||
|
|
|
@ -426,7 +426,7 @@ func New(e *echo.Echo, options *Options) (*Server, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Session, err = ctx.Server.Sessions.get(cookie.Value)
|
ctx.Session, err = ctx.Server.Sessions.get(cookie.Value)
|
||||||
if err == errSessionExpired {
|
if err == ErrSessionExpired {
|
||||||
ctx.SetSession(nil)
|
ctx.SetSession(nil)
|
||||||
return handleUnauthenticated(next, ctx)
|
return handleUnauthenticated(next, ctx)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
|
|
24
session.go
24
session.go
|
@ -20,6 +20,7 @@ import (
|
||||||
|
|
||||||
// TODO: make this configurable
|
// TODO: make this configurable
|
||||||
const sessionDuration = 30 * time.Minute
|
const sessionDuration = 30 * time.Minute
|
||||||
|
const maxAttachmentSize = 32 << 20 // 32 MiB
|
||||||
|
|
||||||
func generateToken() (string, error) {
|
func generateToken() (string, error) {
|
||||||
b := make([]byte, 32)
|
b := make([]byte, 32)
|
||||||
|
@ -30,7 +31,10 @@ func generateToken() (string, error) {
|
||||||
return base64.URLEncoding.EncodeToString(b), nil
|
return base64.URLEncoding.EncodeToString(b), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var errSessionExpired = errors.New("session expired")
|
var (
|
||||||
|
ErrSessionExpired = errors.New("session expired")
|
||||||
|
ErrAttachmentCacheSize = errors.New("Attachments on session exceed maximum file size")
|
||||||
|
)
|
||||||
|
|
||||||
// AuthError wraps an authentication error.
|
// AuthError wraps an authentication error.
|
||||||
type AuthError struct {
|
type AuthError struct {
|
||||||
|
@ -145,15 +149,17 @@ func (s *Session) Close() {
|
||||||
// Puts an attachment and returns a generated UUID
|
// Puts an attachment and returns a generated UUID
|
||||||
func (s *Session) PutAttachment(in *multipart.FileHeader,
|
func (s *Session) PutAttachment(in *multipart.FileHeader,
|
||||||
form *multipart.Form) (string, error) {
|
form *multipart.Form) (string, error) {
|
||||||
// TODO: Prevent users from uploading too many attachments, or too large
|
|
||||||
//
|
|
||||||
// Probably just set a cap on the maximum combined size of all files in the
|
|
||||||
// user's session
|
|
||||||
//
|
|
||||||
// TODO: Figure out what to do if the user abandons the compose window
|
|
||||||
// after adding some attachments
|
|
||||||
id := uuid.New()
|
id := uuid.New()
|
||||||
s.attachmentsLocker.Lock()
|
s.attachmentsLocker.Lock()
|
||||||
|
|
||||||
|
var size int64
|
||||||
|
for _, a := range s.attachments {
|
||||||
|
size += a.File.Size
|
||||||
|
}
|
||||||
|
if size + in.Size > maxAttachmentSize {
|
||||||
|
return "", ErrAttachmentCacheSize
|
||||||
|
}
|
||||||
|
|
||||||
s.attachments[id.String()] = &Attachment{
|
s.attachments[id.String()] = &Attachment{
|
||||||
File: in,
|
File: in,
|
||||||
Form: form,
|
Form: form,
|
||||||
|
@ -241,7 +247,7 @@ func (sm *SessionManager) get(token string) (*Session, error) {
|
||||||
|
|
||||||
session, ok := sm.sessions[token]
|
session, ok := sm.sessions[token]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errSessionExpired
|
return nil, ErrSessionExpired
|
||||||
}
|
}
|
||||||
return session, nil
|
return session, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue