Add maximum upload size saftey and guards

This commit is contained in:
James Mills 2020-03-29 17:41:10 +10:00
parent b8aee1d2b5
commit a22a2ae031
No known key found for this signature in database
GPG key ID: AC4C014F1440EBD6
4 changed files with 55 additions and 12 deletions

View file

@ -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)

View file

@ -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",

View file

@ -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

View file

@ -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 {