commit 3fb782b

delthas  ·  2024-09-17 16:02:41 +0000 UTC
parent 7b0ff99
Make max upload file size dynamic
2 files changed,  +31, -4
M app.go
M app.go
+31, -0
 1@@ -18,6 +18,7 @@ import (
 2 	"os/exec"
 3 	"path/filepath"
 4 	"regexp"
 5+	"strconv"
 6 	"strings"
 7 	"sync"
 8 	"time"
 9@@ -1048,6 +1049,7 @@ func (app *App) upload(url string, f *os.File, size int64) (string, error) {
10 	if app.cfg.Password != nil {
11 		req.SetBasicAuth(app.cfg.User, *app.cfg.Password)
12 	}
13+	req.ContentLength = size
14 	req.Header.Set("Content-Disposition", mime.FormatMediaType("attachment", map[string]string{
15 		"filename": filepath.Base(f.Name()),
16 	}))
17@@ -1055,6 +1057,24 @@ func (app *App) upload(url string, f *os.File, size int64) (string, error) {
18 	if err != nil {
19 		return "", fmt.Errorf("uploading: %v", err)
20 	}
21+	if res.StatusCode == http.StatusRequestEntityTooLarge {
22+		var maxSize int64
23+		for _, entry := range strings.Split(res.Header.Get("Upload-Limit"), ",") {
24+			entry = strings.TrimSpace(entry)
25+			key, value, ok := strings.Cut(entry, "=")
26+			if !ok || key != "maxsize" {
27+				continue
28+			}
29+			if v, err := strconv.ParseInt(value, 10, 64); err == nil && v > 0 {
30+				maxSize = v
31+			}
32+		}
33+		if maxSize > 0 {
34+			return "", fmt.Errorf("uploading: file too large: maximum %v per file (file was %v)", formatSize(maxSize), formatSize(size))
35+		} else {
36+			return "", fmt.Errorf("uploading: file too large")
37+		}
38+	}
39 	if res.StatusCode != http.StatusCreated {
40 		return "", fmt.Errorf("uploading: unexpected status code: %d", res.StatusCode)
41 	}
42@@ -2212,6 +2232,17 @@ func keyMatches(k vaxis.Key, r rune, mods vaxis.ModifierMask) bool {
43 	return false
44 }
45 
46+func formatSize(v int64) string {
47+	suffixes := []string{"B", "kB", "MB", "GB"}
48+	for i, suffix := range suffixes {
49+		if v < 1024 || i == len(suffixes)-1 {
50+			return fmt.Sprintf("%v%v", v, suffix)
51+		}
52+		v /= 1024
53+	}
54+	panic("unreachable")
55+}
56+
57 type ReadProgress struct {
58 	io.Reader
59 	period time.Duration
+0, -4
 1@@ -511,10 +511,6 @@ func commandDoUpload(app *App, args []string) (err error) {
 2 	if err != nil {
 3 		return fmt.Errorf("opening file: %v", err)
 4 	}
 5-	if fi.Size() > 50*1024*1024 {
 6-		// Best-effort limit, taking from current soju
 7-		return fmt.Errorf("file too large: maximum 50MB per file")
 8-	}
 9 	f, err := os.Open(path)
10 	if err != nil {
11 		return fmt.Errorf("opening file: %v", err)