Add maximum upload size saftey and guards
This commit is contained in:
parent
b8aee1d2b5
commit
a22a2ae031
4 changed files with 55 additions and 12 deletions
34
app/app.go
34
app/app.go
|
@ -210,8 +210,7 @@ func (a *App) uploadHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := &struct{}{}
|
ctx := &struct{}{}
|
||||||
a.render("upload", w, ctx)
|
a.render("upload", w, ctx)
|
||||||
} else if r.Method == "POST" {
|
} else if r.Method == "POST" {
|
||||||
// TODO: Move to a constant
|
r.ParseMultipartForm(a.Config.Server.MaxUploadSize)
|
||||||
r.ParseMultipartForm((10 << 20) * 10) // 100MB
|
|
||||||
|
|
||||||
file, handler, err := r.FormFile("video_file")
|
file, handler, err := r.FormFile("video_file")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -414,6 +413,37 @@ func (a *App) importHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
defer os.Remove(uf.Name())
|
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 {
|
if err := utils.Download(videoInfo.VideoURL, uf.Name()); err != nil {
|
||||||
err := fmt.Errorf("error downloading video %s: %w", url, err)
|
err := fmt.Errorf("error downloading video %s: %w", url, err)
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
|
|
|
@ -26,6 +26,7 @@ type ServerConfig struct {
|
||||||
Port int `json:"port"`
|
Port int `json:"port"`
|
||||||
StorePath string `json:"store_path"`
|
StorePath string `json:"store_path"`
|
||||||
UploadPath string `json:"upload_path"`
|
UploadPath string `json:"upload_path"`
|
||||||
|
MaxUploadSize int64 `json:"max_upload_size"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ThumbnailerConfig settings for Transcoder
|
// ThumbnailerConfig settings for Transcoder
|
||||||
|
@ -61,15 +62,16 @@ func DefaultConfig() *Config {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Server: &ServerConfig{
|
Server: &ServerConfig{
|
||||||
Host: "127.0.0.1",
|
Host: "0.0.0.0",
|
||||||
Port: 0,
|
Port: 8000,
|
||||||
UploadPath: "uploads",
|
UploadPath: "uploads",
|
||||||
|
MaxUploadSize: 104857600,
|
||||||
},
|
},
|
||||||
Thumbnailer: &ThumbnailerConfig{
|
Thumbnailer: &ThumbnailerConfig{
|
||||||
Timeout: 30,
|
Timeout: 60,
|
||||||
},
|
},
|
||||||
Transcoder: &TranscoderConfig{
|
Transcoder: &TranscoderConfig{
|
||||||
Timeout: 60,
|
Timeout: 300,
|
||||||
},
|
},
|
||||||
Feed: &FeedConfig{
|
Feed: &FeedConfig{
|
||||||
ExternalURL: "http://localhost",
|
ExternalURL: "http://localhost",
|
||||||
|
|
|
@ -9,7 +9,8 @@
|
||||||
"host": "0.0.0.0",
|
"host": "0.0.0.0",
|
||||||
"port": 8000,
|
"port": 8000,
|
||||||
"store_path": "tube.db",
|
"store_path": "tube.db",
|
||||||
"upload_path": "uploads"
|
"upload_path": "uploads",
|
||||||
|
"max_upload_size": 104857600
|
||||||
},
|
},
|
||||||
"thumbnailer": {
|
"thumbnailer": {
|
||||||
"timeout": 60
|
"timeout": 60
|
||||||
|
|
|
@ -7,9 +7,19 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"strconv"
|
||||||
"time"
|
"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 {
|
func Download(url, filename string) error {
|
||||||
res, err := http.Get(url)
|
res, err := http.Get(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in a new issue