ISSUE-332

This commit is contained in:
Andrea Spacca 2020-12-31 20:08:42 +01:00
parent bfb34634de
commit e53d599e09
4 changed files with 106 additions and 76 deletions

View file

@ -112,6 +112,7 @@ log | path to log file| | LOG |
cors-domains | comma separated list of domains for CORS, setting it enable CORS | | CORS_DOMAINS | cors-domains | comma separated list of domains for CORS, setting it enable CORS | | CORS_DOMAINS |
clamav-host | host for clamav feature | | CLAMAV_HOST | clamav-host | host for clamav feature | | CLAMAV_HOST |
rate-limit | request per minute | | RATE_LIMIT | rate-limit | request per minute | | RATE_LIMIT |
max-upload-size | max upload size in kilobytes | | MAX_UPLOAD_SIZE |
If you want to use TLS using lets encrypt certificates, set lets-encrypt-hosts to your domain, set tls-listener to :443 and enable force-https. If you want to use TLS using lets encrypt certificates, set lets-encrypt-hosts to your domain, set tls-listener to :443 and enable force-https.

View file

@ -34,85 +34,85 @@ VERSION:
var globalFlags = []cli.Flag{ var globalFlags = []cli.Flag{
cli.StringFlag{ cli.StringFlag{
Name: "listener", Name: "listener",
Usage: "127.0.0.1:8080", Usage: "127.0.0.1:8080",
Value: "127.0.0.1:8080", Value: "127.0.0.1:8080",
EnvVar: "LISTENER", EnvVar: "LISTENER",
}, },
// redirect to https? // redirect to https?
// hostnames // hostnames
cli.StringFlag{ cli.StringFlag{
Name: "profile-listener", Name: "profile-listener",
Usage: "127.0.0.1:6060", Usage: "127.0.0.1:6060",
Value: "", Value: "",
EnvVar: "PROFILE_LISTENER", EnvVar: "PROFILE_LISTENER",
}, },
cli.BoolFlag{ cli.BoolFlag{
Name: "force-https", Name: "force-https",
Usage: "", Usage: "",
EnvVar: "FORCE_HTTPS", EnvVar: "FORCE_HTTPS",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "tls-listener", Name: "tls-listener",
Usage: "127.0.0.1:8443", Usage: "127.0.0.1:8443",
Value: "", Value: "",
EnvVar: "TLS_LISTENER", EnvVar: "TLS_LISTENER",
}, },
cli.BoolFlag{ cli.BoolFlag{
Name: "tls-listener-only", Name: "tls-listener-only",
Usage: "", Usage: "",
EnvVar: "TLS_LISTENER_ONLY", EnvVar: "TLS_LISTENER_ONLY",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "tls-cert-file", Name: "tls-cert-file",
Value: "", Value: "",
EnvVar: "TLS_CERT_FILE", EnvVar: "TLS_CERT_FILE",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "tls-private-key", Name: "tls-private-key",
Value: "", Value: "",
EnvVar: "TLS_PRIVATE_KEY", EnvVar: "TLS_PRIVATE_KEY",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "temp-path", Name: "temp-path",
Usage: "path to temp files", Usage: "path to temp files",
Value: os.TempDir(), Value: os.TempDir(),
EnvVar: "TEMP_PATH", EnvVar: "TEMP_PATH",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "web-path", Name: "web-path",
Usage: "path to static web files", Usage: "path to static web files",
Value: "", Value: "",
EnvVar: "WEB_PATH", EnvVar: "WEB_PATH",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "proxy-path", Name: "proxy-path",
Usage: "path prefix when service is run behind a proxy", Usage: "path prefix when service is run behind a proxy",
Value: "", Value: "",
EnvVar: "PROXY_PATH", EnvVar: "PROXY_PATH",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "proxy-port", Name: "proxy-port",
Usage: "port of the proxy when the service is run behind a proxy", Usage: "port of the proxy when the service is run behind a proxy",
Value: "", Value: "",
EnvVar: "PROXY_PORT", EnvVar: "PROXY_PORT",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "ga-key", Name: "ga-key",
Usage: "key for google analytics (front end)", Usage: "key for google analytics (front end)",
Value: "", Value: "",
EnvVar: "GA_KEY", EnvVar: "GA_KEY",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "uservoice-key", Name: "uservoice-key",
Usage: "key for user voice (front end)", Usage: "key for user voice (front end)",
Value: "", Value: "",
EnvVar: "USERVOICE_KEY", EnvVar: "USERVOICE_KEY",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "provider", Name: "provider",
Usage: "s3|gdrive|local", Usage: "s3|gdrive|local",
Value: "", Value: "",
EnvVar: "PROVIDER", EnvVar: "PROVIDER",
}, },
cli.StringFlag{ cli.StringFlag{
@ -146,31 +146,31 @@ var globalFlags = []cli.Flag{
EnvVar: "BUCKET", EnvVar: "BUCKET",
}, },
cli.BoolFlag{ cli.BoolFlag{
Name: "s3-no-multipart", Name: "s3-no-multipart",
Usage: "Disables S3 Multipart Puts", Usage: "Disables S3 Multipart Puts",
EnvVar: "S3_NO_MULTIPART", EnvVar: "S3_NO_MULTIPART",
}, },
cli.BoolFlag{ cli.BoolFlag{
Name: "s3-path-style", Name: "s3-path-style",
Usage: "Forces path style URLs, required for Minio.", Usage: "Forces path style URLs, required for Minio.",
EnvVar: "S3_PATH_STYLE", EnvVar: "S3_PATH_STYLE",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "gdrive-client-json-filepath", Name: "gdrive-client-json-filepath",
Usage: "", Usage: "",
Value: "", Value: "",
EnvVar: "GDRIVE_CLIENT_JSON_FILEPATH", EnvVar: "GDRIVE_CLIENT_JSON_FILEPATH",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "gdrive-local-config-path", Name: "gdrive-local-config-path",
Usage: "", Usage: "",
Value: "", Value: "",
EnvVar: "GDRIVE_LOCAL_CONFIG_PATH", EnvVar: "GDRIVE_LOCAL_CONFIG_PATH",
}, },
cli.IntFlag{ cli.IntFlag{
Name: "gdrive-chunk-size", Name: "gdrive-chunk-size",
Usage: "", Usage: "",
Value: googleapi.DefaultUploadChunkSize / 1024 / 1024, Value: googleapi.DefaultUploadChunkSize / 1024 / 1024,
EnvVar: "GDRIVE_CHUNK_SIZE", EnvVar: "GDRIVE_CHUNK_SIZE",
}, },
cli.StringFlag{ cli.StringFlag{
@ -191,6 +191,12 @@ var globalFlags = []cli.Flag{
Value: 0, Value: 0,
EnvVar: "RATE_LIMIT", EnvVar: "RATE_LIMIT",
}, },
cli.Int64Flag{
Name: "max-upload-size",
Usage: "max limit for upload, in kilobytes",
Value: 0,
EnvVar: "MAX_UPLOAD_SIZE",
},
cli.StringFlag{ cli.StringFlag{
Name: "lets-encrypt-hosts", Name: "lets-encrypt-hosts",
Usage: "host1, host2", Usage: "host1, host2",
@ -198,15 +204,15 @@ var globalFlags = []cli.Flag{
EnvVar: "HOSTS", EnvVar: "HOSTS",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "log", Name: "log",
Usage: "/var/log/transfersh.log", Usage: "/var/log/transfersh.log",
Value: "", Value: "",
EnvVar: "LOG", EnvVar: "LOG",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "basedir", Name: "basedir",
Usage: "path to storage", Usage: "path to storage",
Value: "", Value: "",
EnvVar: "BASEDIR", EnvVar: "BASEDIR",
}, },
cli.StringFlag{ cli.StringFlag{
@ -222,38 +228,38 @@ var globalFlags = []cli.Flag{
EnvVar: "VIRUSTOTAL_KEY", EnvVar: "VIRUSTOTAL_KEY",
}, },
cli.BoolFlag{ cli.BoolFlag{
Name: "profiler", Name: "profiler",
Usage: "enable profiling", Usage: "enable profiling",
EnvVar: "PROFILER", EnvVar: "PROFILER",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "http-auth-user", Name: "http-auth-user",
Usage: "user for http basic auth", Usage: "user for http basic auth",
Value: "", Value: "",
EnvVar: "HTTP_AUTH_USER", EnvVar: "HTTP_AUTH_USER",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "http-auth-pass", Name: "http-auth-pass",
Usage: "pass for http basic auth", Usage: "pass for http basic auth",
Value: "", Value: "",
EnvVar: "HTTP_AUTH_PASS", EnvVar: "HTTP_AUTH_PASS",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "ip-whitelist", Name: "ip-whitelist",
Usage: "comma separated list of ips allowed to connect to the service", Usage: "comma separated list of ips allowed to connect to the service",
Value: "", Value: "",
EnvVar: "IP_WHITELIST", EnvVar: "IP_WHITELIST",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "ip-blacklist", Name: "ip-blacklist",
Usage: "comma separated list of ips not allowed to connect to the service", Usage: "comma separated list of ips not allowed to connect to the service",
Value: "", Value: "",
EnvVar: "IP_BLACKLIST", EnvVar: "IP_BLACKLIST",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "cors-domains", Name: "cors-domains",
Usage: "comma separated list of domains allowed for CORS requests", Usage: "comma separated list of domains allowed for CORS requests",
Value: "", Value: "",
EnvVar: "CORS_DOMAINS", EnvVar: "CORS_DOMAINS",
}, },
} }
@ -351,6 +357,10 @@ func New() *Cmd {
options = append(options, server.ClamavHost(v)) options = append(options, server.ClamavHost(v))
} }
if v := c.Int64("max-upload-size"); v > 0 {
options = append(options, server.MaxUploadSize(v))
}
if v := c.Int("rate-limit"); v > 0 { if v := c.Int("rate-limit"); v > 0 {
options = append(options, server.RateLimit(v)) options = append(options, server.RateLimit(v))
} }

View file

@ -311,6 +311,12 @@ func (s *Server) postHandler(w http.ResponseWriter, r *http.Request) {
contentLength := n contentLength := n
if s.maxUploadSize > 0 && contentLength > s.maxUploadSize {
log.Print("Entity too large")
http.Error(w, http.StatusText(http.StatusRequestEntityTooLarge), http.StatusRequestEntityTooLarge)
return
}
metadata := MetadataForRequest(contentType, r) metadata := MetadataForRequest(contentType, r)
buffer := &bytes.Buffer{} buffer := &bytes.Buffer{}
@ -455,6 +461,12 @@ func (s *Server) putHandler(w http.ResponseWriter, r *http.Request) {
contentLength = n contentLength = n
} }
if s.maxUploadSize > 0 && contentLength > s.maxUploadSize {
log.Print("Entity too large")
http.Error(w, http.StatusText(http.StatusRequestEntityTooLarge), http.StatusRequestEntityTooLarge)
return
}
if contentLength == 0 { if contentLength == 0 {
log.Print("Empty content-length") log.Print("Empty content-length")
http.Error(w, errors.New("Could not upload empty file").Error(), 400) http.Error(w, errors.New("Could not upload empty file").Error(), 400)

View file

@ -25,11 +25,11 @@ THE SOFTWARE.
package server package server
import ( import (
crypto_rand "crypto/rand"
"encoding/binary"
"errors" "errors"
gorillaHandlers "github.com/gorilla/handlers" gorillaHandlers "github.com/gorilla/handlers"
"log" "log"
crypto_rand "crypto/rand"
"encoding/binary"
"math/rand" "math/rand"
"mime" "mime"
"net/http" "net/http"
@ -175,6 +175,12 @@ func Logger(logger *log.Logger) OptionFn {
} }
} }
func MaxUploadSize(kbytes int64) OptionFn {
return func(srvr *Server) {
srvr.maxUploadSize = kbytes * 1024
}
}
func RateLimit(requests int) OptionFn { func RateLimit(requests int) OptionFn {
return func(srvr *Server) { return func(srvr *Server) {
srvr.rateLimitRequests = requests srvr.rateLimitRequests = requests
@ -271,6 +277,7 @@ type Server struct {
locks map[string]*sync.Mutex locks map[string]*sync.Mutex
maxUploadSize int64
rateLimitRequests int rateLimitRequests int
storage Storage storage Storage