summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Mills <prologic@shortcircuit.net.au>2020-03-29 17:41:10 +1000
committerJames Mills <prologic@shortcircuit.net.au>2020-03-29 17:41:10 +1000
commita22a2ae031f2c02b41aa9a7c1746b2989bcf0126 (patch)
tree8af65c4e69a6661e7554330f6d0d61c60bdde6f3
parentb8aee1d2b5f09ae68f46e00f83eccff2dcf0bb55 (diff)
Add maximum upload size saftey and guards
-rw-r--r--app/app.go34
-rw-r--r--app/config.go20
-rw-r--r--config.json3
-rw-r--r--utils/utils.go10
4 files changed, 55 insertions, 12 deletions
diff --git a/app/app.go b/app/app.go
index bc2802d..4e0657c 100644
--- a/app/app.go
+++ b/app/app.go
@@ -210,8 +210,7 @@ func (a *App) uploadHandler(w http.ResponseWriter, r *http.Request) {
ctx := &struct{}{}
a.render("upload", w, ctx)
} else if r.Method == "POST" {
- // TODO: Move to a constant
- r.ParseMultipartForm((10 << 20) * 10) // 100MB
+ r.ParseMultipartForm(a.Config.Server.MaxUploadSize)
file, handler, err := r.FormFile("video_file")
if err != nil {
@@ -414,6 +413,37 @@ func (a *App) importHandler(w http.ResponseWriter, r *http.Request) {
}
defer os.Remove(uf.Name())
+ log.WithField("video_url", videoInfo.VideoURL).Info("requesting video size")
+
+ res, err := http.Head(videoInfo.VideoURL)
+ if err != nil {
+ err := fmt.Errorf("error getting size of video %w", err)
+ log.Error(err)
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ contentLength := utils.SafeParseInt64(res.Header.Get("Content-Length"), -1)
+ if contentLength == -1 {
+ err := fmt.Errorf("error calculating size of video")
+ log.WithField("contentLength", contentLength).Error(err)
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ if contentLength > a.Config.Server.MaxUploadSize {
+ err := fmt.Errorf(
+ "imported video would exceed maximum upload size of %s",
+ humanize.Bytes(uint64(a.Config.Server.MaxUploadSize)),
+ )
+ log.
+ WithField("contentLength", contentLength).
+ WithField("max_upload_size", a.Config.Server.MaxUploadSize).
+ Error(err)
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ log.WithField("contentLength", contentLength).Info("downloading video")
+
if err := utils.Download(videoInfo.VideoURL, uf.Name()); err != nil {
err := fmt.Errorf("error downloading video %s: %w", url, err)
log.Error(err)
diff --git a/app/config.go b/app/config.go
index 73871eb..4d72657 100644
--- a/app/config.go
+++ b/app/config.go
@@ -22,10 +22,11 @@ type PathConfig struct {
// ServerConfig settings for App Server.
type ServerConfig struct {
- Host string `json:"host"`
- Port int `json:"port"`
- StorePath string `json:"store_path"`
- UploadPath string `json:"upload_path"`
+ Host string `json:"host"`
+ Port int `json:"port"`
+ StorePath string `json:"store_path"`
+ UploadPath string `json:"upload_path"`
+ MaxUploadSize int64 `json:"max_upload_size"`
}
// ThumbnailerConfig settings for Transcoder
@@ -61,15 +62,16 @@ func DefaultConfig() *Config {
},
},
Server: &ServerConfig{
- Host: "127.0.0.1",
- Port: 0,
- UploadPath: "uploads",
+ Host: "0.0.0.0",
+ Port: 8000,
+ UploadPath: "uploads",
+ MaxUploadSize: 104857600,
},
Thumbnailer: &ThumbnailerConfig{
- Timeout: 30,
+ Timeout: 60,
},
Transcoder: &TranscoderConfig{
- Timeout: 60,
+ Timeout: 300,
},
Feed: &FeedConfig{
ExternalURL: "http://localhost",
diff --git a/config.json b/config.json
index 9edf9dc..76d608d 100644
--- a/config.json
+++ b/config.json
@@ -9,7 +9,8 @@
"host": "0.0.0.0",
"port": 8000,
"store_path": "tube.db",
- "upload_path": "uploads"
+ "upload_path": "uploads",
+ "max_upload_size": 104857600
},
"thumbnailer": {
"timeout": 60
diff --git a/utils/utils.go b/utils/utils.go
index 5293b0a..f80834c 100644
--- a/utils/utils.go
+++ b/utils/utils.go
@@ -7,9 +7,19 @@ import (
"net/http"
"os"
"os/exec"
+ "strconv"
"time"
)
+// SafeParseInt64 ...
+func SafeParseInt64(s string, d int64) int64 {
+ n, err := strconv.ParseInt(s, 10, 64)
+ if err != nil {
+ return d
+ }
+ return n
+}
+
func Download(url, filename string) error {
res, err := http.Get(url)
if err != nil {