From 9297c253aa5da94c036afa5a9b11a21745df95d5 Mon Sep 17 00:00:00 2001 From: Steven Eksteen Date: Wed, 13 Nov 2019 21:19:04 +0200 Subject: [PATCH 01/15] Remove explicit OS and Arch builds This could allow multi-arch supporting using `docker buildx` --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 25661aa..897fc6a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,7 +12,7 @@ WORKDIR /go/src/github.com/dutchcoders/transfer.sh ENV GO111MODULE=on # build & install server -RUN go get -u ./... && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags -a -tags netgo -ldflags '-w -extldflags "-static"' -o /go/bin/transfersh github.com/dutchcoders/transfer.sh +RUN go get -u ./... && CGO_ENABLED=0 go build -ldflags -a -tags netgo -ldflags '-w -extldflags "-static"' -o /go/bin/transfersh github.com/dutchcoders/transfer.sh FROM scratch AS final LABEL maintainer="Andrea Spacca " From 663c59e754b36dfd215f912bf0c8f98bbfb6fbf0 Mon Sep 17 00:00:00 2001 From: Andrea Spacca Date: Mon, 23 Mar 2020 09:22:58 +0100 Subject: [PATCH 02/15] ISSUE 278 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 767ee35..112d30a 100644 --- a/README.md +++ b/README.md @@ -109,7 +109,7 @@ log | path to log file| | 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 your own certificates, set tls-listener to :443, force-https, tls-cert=file and tls-private-key. +If you want to use TLS using your own certificates, set tls-listener to :443, force-https, tls-cert-file and tls-private-key. ## Development From ef28bcb28fbea95e5618215ead78ea14035671d9 Mon Sep 17 00:00:00 2001 From: Andrea Spacca Date: Sat, 4 Apr 2020 14:29:33 +0200 Subject: [PATCH 03/15] ISSUE-296 add CORS --- README.md | 1 + cmd/cmd.go | 9 +++++++++ go.mod | 1 + go.sum | 2 ++ server/server.go | 24 +++++++++++++++++++++++- 5 files changed, 36 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 112d30a..4370578 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,7 @@ gdrive-local-config-path | path to store local transfer.sh config cache for gdri gdrive-chunk-size | chunk size for gdrive upload in megabytes, must be lower than available memory (8 MB) | | lets-encrypt-hosts | hosts to use for lets encrypt certificates (comma seperated) | | log | path to log file| | +cors-domains | comma separated list of domains for CORS, setting it enable CORS | | 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. diff --git a/cmd/cmd.go b/cmd/cmd.go index 6507025..efebca9 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -207,6 +207,11 @@ var globalFlags = []cli.Flag{ Usage: "comma separated list of ips not allowed to connect to the service", Value: "", }, + cli.StringFlag{ + Name: "cors-domains", + Usage: "comma separated list of domains allowed for CORS requests", + Value: "", + }, } type Cmd struct { @@ -245,6 +250,10 @@ func New() *Cmd { options = append(options, server.Listener(v)) } + if v := c.String("cors-domains"); v != "" { + options = append(options, server.CorsDomains(v)) + } + if v := c.String("tls-listener"); v == "" { } else if c.Bool("tls-listener-only") { options = append(options, server.TLSListener(v, true)) diff --git a/go.mod b/go.mod index 8f9b3fe..9f6634c 100644 --- a/go.mod +++ b/go.mod @@ -16,6 +16,7 @@ require ( github.com/garyburd/redigo v1.6.0 // indirect github.com/golang/gddo v0.0.0-20200310004957-95ce5a452273 github.com/golang/protobuf v1.3.5 // indirect + github.com/gorilla/handlers v1.4.2 github.com/gorilla/mux v1.7.4 github.com/gorilla/securecookie v1.1.1 // indirect github.com/hashicorp/golang-lru v0.5.3 // indirect diff --git a/go.sum b/go.sum index 6a9f1b0..3af19ae 100644 --- a/go.sum +++ b/go.sum @@ -127,6 +127,8 @@ github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gorilla/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg= +github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc= diff --git a/server/server.go b/server/server.go index 16c3197..5a7168a 100644 --- a/server/server.go +++ b/server/server.go @@ -26,6 +26,7 @@ package server import ( "errors" + gorillaHandlers "github.com/gorilla/handlers" "log" "math/rand" "mime" @@ -85,6 +86,13 @@ func Listener(s string) OptionFn { } +func CorsDomains(s string) OptionFn { + return func(srvr *Server) { + srvr.CorsDomains = s + } + +} + func GoogleAnalytics(gaKey string) OptionFn { return func(srvr *Server) { srvr.gaKey = gaKey @@ -275,6 +283,7 @@ type Server struct { TLSListenerOnly bool + CorsDomains string ListenerString string TLSListenerString string ProfileListenerString string @@ -413,11 +422,24 @@ func (s *Server) Run() { s.logger.Printf("Transfer.sh server started.\nusing temp folder: %s\nusing storage provider: %s", s.tempPath, s.storage.Type()) + var cors func(http.Handler) http.Handler + if len(s.CorsDomains) > 0 { + cors = gorillaHandlers.CORS( + gorillaHandlers.AllowedHeaders([]string{"*"}), + gorillaHandlers.AllowedOrigins(strings.Split(s.CorsDomains, ",")), + gorillaHandlers.AllowedMethods([]string{"GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS"}), + ) + } else { + cors = func(h http.Handler) http.Handler { + return h + } + } + h := handlers.PanicHandler( IPFilterHandler( handlers.LogHandler( LoveHandler( - s.RedirectHandler(r)), + s.RedirectHandler(cors(r))), handlers.NewLogOptions(s.logger.Printf, "_default_"), ), s.ipFilterOptions, From 45e0967a37e9cc5c411fdf9567d6d75a80ff4639 Mon Sep 17 00:00:00 2001 From: Tobias Perschon Date: Fri, 24 Apr 2020 10:32:31 +0200 Subject: [PATCH 04/15] Update cmd.go added EnvVar to all flags --- cmd/cmd.go | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/cmd/cmd.go b/cmd/cmd.go index efebca9..0ff6d5b 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -37,6 +37,7 @@ var globalFlags = []cli.Flag{ Name: "listener", Usage: "127.0.0.1:8080", Value: "127.0.0.1:8080", + EnvVar: "LISTENER", }, // redirect to https? // hostnames @@ -44,57 +45,69 @@ var globalFlags = []cli.Flag{ Name: "profile-listener", Usage: "127.0.0.1:6060", Value: "", + EnvVar: "PROFILE_LISTENER", }, cli.BoolFlag{ Name: "force-https", Usage: "", + EnvVar: "FORCE_HTTPS", }, cli.StringFlag{ Name: "tls-listener", Usage: "127.0.0.1:8443", Value: "", + EnvVar: "TLS_LISTENER", }, cli.BoolFlag{ Name: "tls-listener-only", Usage: "", + EnvVar: "TLS_LISTENER_ONLY", }, cli.StringFlag{ Name: "tls-cert-file", Value: "", + EnvVar: "TLS_CERT_FILE", }, cli.StringFlag{ Name: "tls-private-key", Value: "", + EnvVar: "TLS_PRIVATE_KEY", }, cli.StringFlag{ Name: "temp-path", Usage: "path to temp files", Value: os.TempDir(), + EnvVar: "TEMP_PATH", }, cli.StringFlag{ Name: "web-path", Usage: "path to static web files", Value: "", + EnvVar: "WEB_PATH", }, cli.StringFlag{ Name: "proxy-path", Usage: "path prefix when service is run behind a proxy", Value: "", + EnvVar: "PROXY_PATH", }, cli.StringFlag{ Name: "ga-key", Usage: "key for google analytics (front end)", Value: "", + EnvVar: "GA_KEY", }, cli.StringFlag{ Name: "uservoice-key", Usage: "key for user voice (front end)", Value: "", + EnvVar: "USERVOICE_KEY", }, cli.StringFlag{ Name: "provider", Usage: "s3|gdrive|local", Value: "", + EnvVar: "PROVIDER", }, cli.StringFlag{ Name: "s3-endpoint", @@ -129,31 +142,36 @@ var globalFlags = []cli.Flag{ cli.BoolFlag{ Name: "s3-no-multipart", Usage: "Disables S3 Multipart Puts", + EnvVar: "S3_NO_MULTIPART", }, cli.BoolFlag{ Name: "s3-path-style", Usage: "Forces path style URLs, required for Minio.", + EnvVar: "S3_PATH_STYLE", }, cli.StringFlag{ Name: "gdrive-client-json-filepath", Usage: "", Value: "", + EnvVar: "GDRIVE_CLIENT_JSON_FILEPATH", }, cli.StringFlag{ Name: "gdrive-local-config-path", Usage: "", Value: "", + EnvVar: "GDRIVE_LOCAL_CONFIG_PATH", }, cli.IntFlag{ Name: "gdrive-chunk-size", Usage: "", Value: googleapi.DefaultUploadChunkSize / 1024 / 1024, + EnvVar: "GDRIVE_CHUNK_SIZE", }, cli.IntFlag{ Name: "rate-limit", Usage: "requests per minute", Value: 0, - EnvVar: "", + EnvVar: "RATE_LIMIT", }, cli.StringFlag{ Name: "lets-encrypt-hosts", @@ -165,11 +183,13 @@ var globalFlags = []cli.Flag{ Name: "log", Usage: "/var/log/transfersh.log", Value: "", + EnvVar: "LOG", }, cli.StringFlag{ Name: "basedir", Usage: "path to storage", Value: "", + EnvVar: "BASEDIR", }, cli.StringFlag{ Name: "clamav-host", @@ -186,31 +206,37 @@ var globalFlags = []cli.Flag{ cli.BoolFlag{ Name: "profiler", Usage: "enable profiling", + EnvVar: "PROFILER", }, cli.StringFlag{ Name: "http-auth-user", Usage: "user for http basic auth", Value: "", + EnvVar: "HTTP_AUTH_USER", }, cli.StringFlag{ Name: "http-auth-pass", Usage: "pass for http basic auth", Value: "", + EnvVar: "HTTP_AUTH_PASS", }, cli.StringFlag{ Name: "ip-whitelist", Usage: "comma separated list of ips allowed to connect to the service", Value: "", + EnvVar: "IP_WHITELIST", }, cli.StringFlag{ Name: "ip-blacklist", Usage: "comma separated list of ips not allowed to connect to the service", Value: "", + EnvVar: "IP_BLACKLIST", }, cli.StringFlag{ Name: "cors-domains", Usage: "comma separated list of domains allowed for CORS requests", Value: "", + EnvVar: "CORS_DOMAINS", }, } From 8a5c7371408c4e76a798ace93fecd94ea9c6c38e Mon Sep 17 00:00:00 2001 From: Andrea Spacca Date: Sun, 3 May 2020 15:28:59 +0200 Subject: [PATCH 05/15] UPDATE README.md --- README.md | 64 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 4370578..f93392d 100644 --- a/README.md +++ b/README.md @@ -76,37 +76,39 @@ https://transfer.sh/1lDau/test.txt --> https://transfer.sh/inline/1lDau/test.txt Parameter | Description | Value | Env --- | --- | --- | --- -listener | port to use for http (:80) | | -profile-listener | port to use for profiler (:6060)| | -force-https | redirect to https | false | -tls-listener | port to use for https (:443) | | -tls-listener-only | flag to enable tls listener only | | -tls-cert-file | path to tls certificate | | -tls-private-key | path to tls private key | | -http-auth-user | user for basic http auth on upload | | -http-auth-pass | pass for basic http auth on upload | | -ip-whitelist | comma separated list of ips allowed to connect to the service | | -ip-blacklist | comma separated list of ips not allowed to connect to the service | | -temp-path | path to temp folder | system temp | -web-path | path to static web files (for development or custom front end) | | -proxy-path | path prefix when service is run behind a proxy | | -ga-key | google analytics key for the front end | | -uservoice-key | user voice key for the front end | | -provider | which storage provider to use | (s3, gdrive or local) | -aws-access-key | aws access key | | AWS_ACCESS_KEY -aws-secret-key | aws access key | | AWS_SECRET_KEY -bucket | aws bucket | | BUCKET -s3-endpoint | Custom S3 endpoint. | | -s3-region | region of the s3 bucket | eu-west-1 | S3_REGION -s3-no-multipart | disables s3 multipart upload | false | | -s3-path-style | Forces path style URLs, required for Minio. | false | | -basedir | path storage for local/gdrive provider| | -gdrive-client-json-filepath | path to oauth client json config for gdrive provider| | -gdrive-local-config-path | path to store local transfer.sh config cache for gdrive provider| | -gdrive-chunk-size | chunk size for gdrive upload in megabytes, must be lower than available memory (8 MB) | | -lets-encrypt-hosts | hosts to use for lets encrypt certificates (comma seperated) | | -log | path to log file| | -cors-domains | comma separated list of domains for CORS, setting it enable CORS | | +listener | port to use for http (:80) | | LISTENER | +profile-listener | port to use for profiler (:6060) | | PROFILE_LISTENER | +force-https | redirect to https | false | FORCE_HTTPS +tls-listener | port to use for https (:443) | | TLS_LISTENER | +tls-listener-only | flag to enable tls listener only | | TLS_LISTENER_ONLY | +tls-cert-file | path to tls certificate | | TLS_CERT_FILE | +tls-private-key | path to tls private key | | TLS_PRIVATE_KEY | +http-auth-user | user for basic http auth on upload | | HTTP_AUTH_USER | +http-auth-pass | pass for basic http auth on upload | | HTTP_AUTH_PASS | +ip-whitelist | comma separated list of ips allowed to connect to the service | | IP_WHITELIST | +ip-blacklist | comma separated list of ips not allowed to connect to the service | | IP_BLACKLIST | +temp-path | path to temp folder | system temp | TEMP_PATH | +web-path | path to static web files (for development or custom front end) | | WEB_PATH | +proxy-path | path prefix when service is run behind a proxy | | PROXY_PATH | +ga-key | google analytics key for the front end | | GA_KEY | +uservoice-key | user voice key for the front end | | USERVOICE_KEY | +provider | which storage provider to use | (s3, gdrive or local) | PROVIDER | +aws-access-key | aws access key | | AWS_ACCESS_KEY | +aws-secret-key | aws access key | | AWS_SECRET_KEY | +bucket | aws bucket | | BUCKET | +s3-endpoint | Custom S3 endpoint. | | S3_ENDPOINT | +s3-region | region of the s3 bucket | eu-west-1 | S3_REGION | +s3-no-multipart | disables s3 multipart upload | false | S3_NO_MULTIPART | +s3-path-style | Forces path style URLs, required for Minio. | false | S3_PATH_STYLE | +basedir | path storage for local/gdrive provider | | BASEDIR | +gdrive-client-json-filepath | path to oauth client json config for gdrive provider | | GDRIVE_CLIENT_JSON_FILEPATH | +gdrive-local-config-path | path to store local transfer.sh config cache for gdrive provider| | GDRIVE_LOCAL_CONFIG_PATH | +gdrive-chunk-size | chunk size for gdrive upload in megabytes, must be lower than available memory (8 MB) | | GDRIVE_CHUNK_SIZE | +lets-encrypt-hosts | hosts to use for lets encrypt certificates (comma seperated) | | HOSTS | +log | path to log file| | LOG | +cors-domains | comma separated list of domains for CORS, setting it enable CORS | | CORS_DOMAINS | +clamav-host | host for clamav feature | | CLAMAV_HOST | +rate-limit | request per minute | | RATE_LIMIT | 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. From f366e8217e85aeb4ddf5a0f348f283f4a9275aa5 Mon Sep 17 00:00:00 2001 From: Adam Crowder Date: Sun, 3 May 2020 02:19:32 -0700 Subject: [PATCH 06/15] add proxy-port for port override when running behind a proxy Signed-off-by: Adam Crowder --- README.md | 1 + cmd/cmd.go | 10 +++++++++ server/handlers.go | 55 +++++++++++++++++++++++++++------------------- server/server.go | 7 ++++++ 4 files changed, 50 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index f93392d..c90fcf1 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,7 @@ ip-blacklist | comma separated list of ips not allowed to connect to the service temp-path | path to temp folder | system temp | TEMP_PATH | web-path | path to static web files (for development or custom front end) | | WEB_PATH | proxy-path | path prefix when service is run behind a proxy | | PROXY_PATH | +proxy-port | port of the proxy when the service is run behind a proxy | | PROXY_PORT | ga-key | google analytics key for the front end | | GA_KEY | uservoice-key | user voice key for the front end | | USERVOICE_KEY | provider | which storage provider to use | (s3, gdrive or local) | PROVIDER | diff --git a/cmd/cmd.go b/cmd/cmd.go index 0ff6d5b..90db645 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -91,6 +91,12 @@ var globalFlags = []cli.Flag{ Value: "", EnvVar: "PROXY_PATH", }, + cli.StringFlag{ + Name: "proxy-port", + Usage: "port of the proxy when the service is run behind a proxy", + Value: "", + EnvVar: "PROXY_PORT", + }, cli.StringFlag{ Name: "ga-key", Usage: "key for google analytics (front end)", @@ -299,6 +305,10 @@ func New() *Cmd { options = append(options, server.ProxyPath(v)) } + if v := c.String("proxy-port"); v != "" { + options = append(options, server.ProxyPort(v)) + } + if v := c.String("ga-key"); v != "" { options = append(options, server.GoogleAnalytics(v)) } diff --git a/server/handlers.go b/server/handlers.go index 4f0af3d..73cf750 100644 --- a/server/handlers.go +++ b/server/handlers.go @@ -158,9 +158,9 @@ func (s *Server) previewHandler(w http.ResponseWriter, r *http.Request) { } relativeURL, _ := url.Parse(path.Join(s.proxyPath, token, filename)) - resolvedURL := resolveURL(r, relativeURL) + resolvedURL := resolveURL(r, relativeURL, s.proxyPort) relativeURLGet, _ := url.Parse(path.Join(s.proxyPath, getPathPart, token, filename)) - resolvedURLGet := resolveURL(r, relativeURLGet) + resolvedURLGet := resolveURL(r, relativeURLGet, s.proxyPort) var png []byte png, err = qrcode.Encode(resolvedURL, qrcode.High, 150) if err != nil { @@ -170,8 +170,8 @@ func (s *Server) previewHandler(w http.ResponseWriter, r *http.Request) { qrCode := base64.StdEncoding.EncodeToString(png) - hostname := getURL(r).Host - webAddress := resolveWebAddress(r, s.proxyPath) + hostname := getURL(r, s.proxyPort).Host + webAddress := resolveWebAddress(r, s.proxyPath, s.proxyPort) data := struct { ContentType string @@ -212,8 +212,8 @@ func (s *Server) previewHandler(w http.ResponseWriter, r *http.Request) { func (s *Server) viewHandler(w http.ResponseWriter, r *http.Request) { // vars := mux.Vars(r) - hostname := getURL(r).Host - webAddress := resolveWebAddress(r, s.proxyPath) + hostname := getURL(r, s.proxyPort).Host + webAddress := resolveWebAddress(r, s.proxyPath, s.proxyPort) data := struct { Hostname string @@ -339,7 +339,7 @@ func (s *Server) postHandler(w http.ResponseWriter, r *http.Request) { filename = url.PathEscape(filename) relativeURL, _ := url.Parse(path.Join(s.proxyPath, token, filename)) - fmt.Fprintln(w, getURL(r).ResolveReference(relativeURL).String()) + fmt.Fprintln(w, getURL(r, s.proxyPort).ResolveReference(relativeURL).String()) cleanTmpFile(file) } @@ -500,15 +500,15 @@ func (s *Server) putHandler(w http.ResponseWriter, r *http.Request) { relativeURL, _ := url.Parse(path.Join(s.proxyPath, token, filename)) deleteURL, _ := url.Parse(path.Join(s.proxyPath, token, filename, metadata.DeletionToken)) - w.Header().Set("X-Url-Delete", resolveURL(r, deleteURL)) + w.Header().Set("X-Url-Delete", resolveURL(r, deleteURL, s.proxyPort)) - fmt.Fprint(w, resolveURL(r, relativeURL)) + fmt.Fprintln(w, resolveURL(r, relativeURL, s.proxyPort)) } -func resolveURL(r *http.Request, u *url.URL) string { +func resolveURL(r *http.Request, u *url.URL, proxyPort string) string { r.URL.Path = "" - return getURL(r).ResolveReference(u).String() + return getURL(r, proxyPort).ResolveReference(u).String() } func resolveKey(key, proxyPath string) string { @@ -525,8 +525,8 @@ func resolveKey(key, proxyPath string) string { return key } -func resolveWebAddress(r *http.Request, proxyPath string) string { - url := getURL(r) +func resolveWebAddress(r *http.Request, proxyPath string, proxyPort string) string { + url := getURL(r, proxyPort) var webAddress string @@ -544,7 +544,7 @@ func resolveWebAddress(r *http.Request, proxyPath string) string { return webAddress } -func getURL(r *http.Request) *url.URL { +func getURL(r *http.Request, proxyPort string) *url.URL { u, _ := url.Parse(r.URL.String()) if r.TLS != nil { @@ -555,16 +555,25 @@ func getURL(r *http.Request) *url.URL { u.Scheme = "http" } - if u.Host != "" { - } else if host, port, err := net.SplitHostPort(r.Host); err != nil { - u.Host = r.Host - } else { - if port == "80" && u.Scheme == "http" { - u.Host = host - } else if port == "443" && u.Scheme == "https" { + if u.Host == "" { + host, port, err := net.SplitHostPort(r.Host) + if err != nil { + host = r.Host + port = "" + } + if len(proxyPort) != 0 { + port = proxyPort + } + if len(port) == 0 { u.Host = host } else { - u.Host = net.JoinHostPort(host, port) + if port == "80" && u.Scheme == "http" { + u.Host = host + } else if port == "443" && u.Scheme == "https" { + u.Host = host + } else { + u.Host = net.JoinHostPort(host, port) + } } } @@ -1011,7 +1020,7 @@ func (s *Server) RedirectHandler(h http.Handler) http.HandlerFunc { } else if r.Header.Get("X-Forwarded-Proto") == "https" { } else if r.URL.Scheme == "https" { } else { - u := getURL(r) + u := getURL(r, s.proxyPort) u.Scheme = "https" http.Redirect(w, r, u.String(), http.StatusPermanentRedirect) diff --git a/server/server.go b/server/server.go index 5a7168a..ace52aa 100644 --- a/server/server.go +++ b/server/server.go @@ -139,6 +139,12 @@ func ProxyPath(s string) OptionFn { } } +func ProxyPort(s string) OptionFn { + return func(srvr *Server) { + srvr.proxyPort = s + } +} + func TempPath(s string) OptionFn { return func(srvr *Server) { if s[len(s)-1:] != "/" { @@ -278,6 +284,7 @@ type Server struct { webPath string proxyPath string + proxyPort string gaKey string userVoiceKey string From d830bf1afc508c7e0ee39a3ae36974f77726deed Mon Sep 17 00:00:00 2001 From: Adam Crowder Date: Fri, 8 May 2020 11:49:21 -0700 Subject: [PATCH 07/15] revert println Signed-off-by: Adam Crowder --- server/handlers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/handlers.go b/server/handlers.go index 73cf750..c0537f7 100644 --- a/server/handlers.go +++ b/server/handlers.go @@ -502,7 +502,7 @@ func (s *Server) putHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("X-Url-Delete", resolveURL(r, deleteURL, s.proxyPort)) - fmt.Fprintln(w, resolveURL(r, relativeURL, s.proxyPort)) + fmt.Fprint(w, resolveURL(r, relativeURL, s.proxyPort)) } func resolveURL(r *http.Request, u *url.URL, proxyPort string) string { From f909ad3ce277bfefeabbb44cb5eacbda7b673a09 Mon Sep 17 00:00:00 2001 From: Adam Crowder Date: Fri, 8 May 2020 16:23:32 -0700 Subject: [PATCH 08/15] fix missing metadata security vuln --- server/handlers.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/server/handlers.go b/server/handlers.go index 4f0af3d..1d45b49 100644 --- a/server/handlers.go +++ b/server/handlers.go @@ -614,9 +614,7 @@ func (s *Server) CheckMetadata(token, filename string, increaseDownload bool) (M var metadata Metadata r, _, err := s.storage.Get(token, fmt.Sprintf("%s.metadata", filename)) - if s.storage.IsNotExist(err) { - return metadata, nil - } else if err != nil { + if err != nil { return metadata, err } From 5e7e3a1b39b14b752f77b661927ada20823b31b7 Mon Sep 17 00:00:00 2001 From: Andrea Spacca Date: Sat, 9 May 2020 12:00:53 +0200 Subject: [PATCH 09/15] v1.1.7 --- cmd/cmd.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/cmd.go b/cmd/cmd.go index 0ff6d5b..3add359 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -12,7 +12,7 @@ import ( "google.golang.org/api/googleapi" ) -var Version = "1.1.4" +var Version = "1.1.7" var helpTemplate = `NAME: {{.Name}} - {{.Usage}} From 0a6b5817a9b0d2de78e6b18d321c27c8a05bd97a Mon Sep 17 00:00:00 2001 From: Adam Crowder Date: Mon, 11 May 2020 18:57:04 -0700 Subject: [PATCH 10/15] use cryptographically secure rng seed Signed-off-by: Adam Crowder --- server/server.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/server/server.go b/server/server.go index 5a7168a..731fde2 100644 --- a/server/server.go +++ b/server/server.go @@ -28,6 +28,8 @@ import ( "errors" gorillaHandlers "github.com/gorilla/handlers" "log" + crypto_rand "crypto/rand" + "encoding/binary" "math/rand" "mime" "net/http" @@ -306,7 +308,11 @@ func New(options ...OptionFn) (*Server, error) { } func init() { - rand.Seed(time.Now().UTC().UnixNano()) + var seedBytes [8]byte + if _, err := crypto_rand.Read(seedBytes[:]); err != nil { + panic("cannot obtain cryptographically secure seed") + } + rand.Seed(int64(binary.LittleEndian.Uint64(seedBytes[:]))) } func (s *Server) Run() { From 18f4b42cf121dd9a5f9f9850292bba35d5eccdfe Mon Sep 17 00:00:00 2001 From: Andrea Spacca Date: Sun, 14 Jun 2020 19:53:36 +0200 Subject: [PATCH 11/15] ISSUE-313-BUILDX --- .github/workflow/buildx.yml | 67 +++++++++++++++++++++++++++++++++++++ Dockerfile | 8 ++++- 2 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 .github/workflow/buildx.yml diff --git a/.github/workflow/buildx.yml b/.github/workflow/buildx.yml new file mode 100644 index 0000000..8941515 --- /dev/null +++ b/.github/workflow/buildx.yml @@ -0,0 +1,67 @@ +# ref: https://github.com/crazy-max/diun/blob/master/.github/workflows/build.yml + +name: Docker +on: [push] +jobs: + build: + runs-on: ubuntu-18.04 + steps: + - name: Prepare + id: prepare + run: | + if [[ $GITHUB_REF == refs/tags/* ]]; then + echo ::set-output name=version::${GITHUB_REF#refs/tags/v} + elif [[ $GITHUB_REF == refs/heads/master ]]; then + echo ::set-output name=version::latest + elif [[ $GITHUB_REF == refs/heads/* ]]; then + echo ::set-output name=version::${GITHUB_REF#refs/heads/} + else + echo ::set-output name=version::snapshot + fi + echo ::set-output name=docker_platforms::linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/386 + echo ::set-output name=docker_image::${{ secrets.DOCKER_USERNAME }}/${{ github.event.repository.name }} + # https://github.com/crazy-max/ghaction-docker-buildx + - name: Set up Docker Buildx + id: buildx + uses: crazy-max/ghaction-docker-buildx@v1 + with: + version: latest + + - name: Environment + run: | + echo home=$HOME + echo git_ref=$GITHUB_REF + echo git_sha=$GITHUB_SHA + echo version=${{ steps.prepare.outputs.version }} + echo image=${{ steps.prepare.outputs.docker_image }} + echo platforms=${{ steps.prepare.outputs.docker_platforms }} + echo avail_platforms=${{ steps.buildx.outputs.platforms }} + # https://github.com/actions/checkout + - name: Checkout + uses: actions/checkout@v2 + + - name: Docker Buildx (no push) + run: | + docker buildx bake \ + --set ${{ github.event.repository.name }}.platform=${{ steps.prepare.outputs.docker_platforms }} \ + --set ${{ github.event.repository.name }}.output=type=image,push=false \ + --set ${{ github.event.repository.name }}.tags="${{ steps.prepare.outputs.docker_image }}:${{ steps.prepare.outputs.version }}" \ + --file Dockerfile + - name: Docker Login + if: success() + env: + DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} + run: | + echo "${DOCKER_PASSWORD}" | docker login --username "${{ secrets.DOCKER_USERNAME }}" --password-stdin + - name: Docker Buildx (push) + if: success() + run: | + docker buildx bake \ + --set ${{ github.event.repository.name }}.platform=${{ steps.prepare.outputs.docker_platforms }} \ + --set ${{ github.event.repository.name }}.output=type=image,push=true \ + --set ${{ github.event.repository.name }}.tags="${{ steps.prepare.outputs.docker_image }}:${{ steps.prepare.outputs.version }}" \ + --file docker-compose.yaml + - name: Clear + if: always() + run: | + rm -f ${HOME}/.docker/config.json \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 0018ba1..6ba642c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,12 @@ # Default to Go 1.13 ARG GO_VERSION=1.13 -FROM golang:${GO_VERSION}-alpine as build +FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine as build + +# Convert TARGETPLATFORM to GOARCH format +# https://github.com/tonistiigi/xx +COPY --from=tonistiigi/xx:golang / / + +ARG TARGETPLATFORM # Necessary to run 'go get' and to compile the linked binary RUN apk add git musl-dev From c8497fb27d635efc9f8cfa14f34b0cdf7e0af4c3 Mon Sep 17 00:00:00 2001 From: Andrea Spacca Date: Sun, 14 Jun 2020 20:01:38 +0200 Subject: [PATCH 12/15] Revert "ISSUE-313-BUILDX" --- .github/workflow/buildx.yml | 67 ------------------------------------- Dockerfile | 8 +---- 2 files changed, 1 insertion(+), 74 deletions(-) delete mode 100644 .github/workflow/buildx.yml diff --git a/.github/workflow/buildx.yml b/.github/workflow/buildx.yml deleted file mode 100644 index 8941515..0000000 --- a/.github/workflow/buildx.yml +++ /dev/null @@ -1,67 +0,0 @@ -# ref: https://github.com/crazy-max/diun/blob/master/.github/workflows/build.yml - -name: Docker -on: [push] -jobs: - build: - runs-on: ubuntu-18.04 - steps: - - name: Prepare - id: prepare - run: | - if [[ $GITHUB_REF == refs/tags/* ]]; then - echo ::set-output name=version::${GITHUB_REF#refs/tags/v} - elif [[ $GITHUB_REF == refs/heads/master ]]; then - echo ::set-output name=version::latest - elif [[ $GITHUB_REF == refs/heads/* ]]; then - echo ::set-output name=version::${GITHUB_REF#refs/heads/} - else - echo ::set-output name=version::snapshot - fi - echo ::set-output name=docker_platforms::linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/386 - echo ::set-output name=docker_image::${{ secrets.DOCKER_USERNAME }}/${{ github.event.repository.name }} - # https://github.com/crazy-max/ghaction-docker-buildx - - name: Set up Docker Buildx - id: buildx - uses: crazy-max/ghaction-docker-buildx@v1 - with: - version: latest - - - name: Environment - run: | - echo home=$HOME - echo git_ref=$GITHUB_REF - echo git_sha=$GITHUB_SHA - echo version=${{ steps.prepare.outputs.version }} - echo image=${{ steps.prepare.outputs.docker_image }} - echo platforms=${{ steps.prepare.outputs.docker_platforms }} - echo avail_platforms=${{ steps.buildx.outputs.platforms }} - # https://github.com/actions/checkout - - name: Checkout - uses: actions/checkout@v2 - - - name: Docker Buildx (no push) - run: | - docker buildx bake \ - --set ${{ github.event.repository.name }}.platform=${{ steps.prepare.outputs.docker_platforms }} \ - --set ${{ github.event.repository.name }}.output=type=image,push=false \ - --set ${{ github.event.repository.name }}.tags="${{ steps.prepare.outputs.docker_image }}:${{ steps.prepare.outputs.version }}" \ - --file Dockerfile - - name: Docker Login - if: success() - env: - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - run: | - echo "${DOCKER_PASSWORD}" | docker login --username "${{ secrets.DOCKER_USERNAME }}" --password-stdin - - name: Docker Buildx (push) - if: success() - run: | - docker buildx bake \ - --set ${{ github.event.repository.name }}.platform=${{ steps.prepare.outputs.docker_platforms }} \ - --set ${{ github.event.repository.name }}.output=type=image,push=true \ - --set ${{ github.event.repository.name }}.tags="${{ steps.prepare.outputs.docker_image }}:${{ steps.prepare.outputs.version }}" \ - --file docker-compose.yaml - - name: Clear - if: always() - run: | - rm -f ${HOME}/.docker/config.json \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 6ba642c..0018ba1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,12 +1,6 @@ # Default to Go 1.13 ARG GO_VERSION=1.13 -FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine as build - -# Convert TARGETPLATFORM to GOARCH format -# https://github.com/tonistiigi/xx -COPY --from=tonistiigi/xx:golang / / - -ARG TARGETPLATFORM +FROM golang:${GO_VERSION}-alpine as build # Necessary to run 'go get' and to compile the linked binary RUN apk add git musl-dev From 085e9f8414054b3bb459d7537a77e0a5d1654282 Mon Sep 17 00:00:00 2001 From: Gabriel Duque Date: Sun, 14 Jun 2020 21:42:00 +0200 Subject: [PATCH 13/15] ci: deploy multi-architecture Docker images using buildx Signed-off-by: Gabriel Duque --- .github/workflows/build-docker-images.yml | 78 +++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 .github/workflows/build-docker-images.yml diff --git a/.github/workflows/build-docker-images.yml b/.github/workflows/build-docker-images.yml new file mode 100644 index 0000000..4e4ec1d --- /dev/null +++ b/.github/workflows/build-docker-images.yml @@ -0,0 +1,78 @@ +name: Deploy multi-architecture Docker images for transfer.sh with buildx + +on: + schedule: + - cron: '0 0 * * *' # everyday at midnight UTC + pull_request: + branches: master + push: + branches: master + tags: + - v* + +jobs: + buildx: + runs-on: ubuntu-latest + steps: + - + name: Checkout + uses: actions/checkout@v2 + - + name: Prepare + id: prepare + run: | + DOCKER_IMAGE=dutchcoders/transfer.sh + DOCKER_PLATFORMS=linux/amd64,linux/arm/v7,linux/arm64,linux/386 + VERSION=edge + + if [[ $GITHUB_REF == refs/tags/* ]]; then + VERSION=${GITHUB_REF#refs/tags/v} + fi + + if [ "${{ github.event_name }}" = "schedule" ]; then + VERSION=nightly + fi + + TAGS="--tag ${DOCKER_IMAGE}:${VERSION}" + + if [ $VERSION = edge -o $VERSION = nightly ]; then + TAGS="$TAGS --tag ${DOCKER_IMAGE}:latest" + fi + + echo ::set-output name=docker_image::${DOCKER_IMAGE} + echo ::set-output name=version::${VERSION} + echo ::set-output name=buildx_args::--platform ${DOCKER_PLATFORMS} \ + --build-arg VERSION=${VERSION} \ + --build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') \ + --build-arg VCS_REF=${GITHUB_SHA::8} \ + ${TAGS} . + - + name: Set up Docker Buildx + uses: crazy-max/ghaction-docker-buildx@v3 + - + name: Docker Buildx (build) + run: | + docker buildx build --no-cache --pull --output "type=image,push=false" ${{ steps.prepare.outputs.buildx_args }} + - + name: Docker Login + if: success() && github.event_name != 'pull_request' + env: + DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} + DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} + run: | + echo "${DOCKER_PASSWORD}" | docker login --username "${DOCKER_USERNAME}" --password-stdin + - + name: Docker Buildx (push) + if: success() && github.event_name != 'pull_request' + run: | + docker buildx build --output "type=image,push=true" ${{ steps.prepare.outputs.buildx_args }} + - + name: Docker Check Manifest + if: always() && github.event_name != 'pull_request' + run: | + docker run --rm mplatform/mquery ${{ steps.prepare.outputs.docker_image }}:${{ steps.prepare.outputs.version }} + - + name: Clear + if: always() && github.event_name != 'pull_request' + run: | + rm -f ${HOME}/.docker/config.json From fe1cde6614da0b09e02aef64a25439abe5772a45 Mon Sep 17 00:00:00 2001 From: stillwondering <44878817+stillwondering@users.noreply.github.com> Date: Mon, 12 Oct 2020 13:25:29 +0200 Subject: [PATCH 14/15] Include version string in version command output The command `transfer.sh version` does not include the application's version string in its output. Fix this. --- cmd/cmd.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/cmd.go b/cmd/cmd.go index fff687d..e7a04b6 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -251,7 +251,7 @@ type Cmd struct { } func VersionAction(c *cli.Context) { - fmt.Println(color.YellowString(fmt.Sprintf("transfer.sh: Easy file sharing from the command line"))) + fmt.Println(color.YellowString(fmt.Sprintf("transfer.sh %s: Easy file sharing from the command line", Version))) } func New() *Cmd { From ec9db7a42e373cd068758e15a1933513cbd3aec3 Mon Sep 17 00:00:00 2001 From: Gabriel Duque Date: Wed, 21 Oct 2020 00:30:52 +0200 Subject: [PATCH 15/15] ci: switch to official docker buildx GitHub action Signed-off-by: Gabriel Duque --- .github/workflows/build-docker-images.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-docker-images.yml b/.github/workflows/build-docker-images.yml index 4e4ec1d..0a0571b 100644 --- a/.github/workflows/build-docker-images.yml +++ b/.github/workflows/build-docker-images.yml @@ -46,9 +46,20 @@ jobs: --build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') \ --build-arg VCS_REF=${GITHUB_SHA::8} \ ${TAGS} . + - + name: Set up QEMU + uses: docker/setup-qemu-action@v1 + with: + platforms: all - name: Set up Docker Buildx - uses: crazy-max/ghaction-docker-buildx@v3 + id: buildx + uses: docker/setup-buildx-action@v1 + with: + version: latest + - + name: Available platforms + run: echo ${{ steps.buildx.outputs.platforms }} - name: Docker Buildx (build) run: |