mirror of
https://github.com/dutchcoders/transfer.sh.git
synced 2020-11-18 19:53:40 -08:00
Compare commits
17 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
ae00f8ceaa | ||
|
ec9db7a42e | ||
|
bcf40c15a2 | ||
|
fe1cde6614 | ||
|
ffb2cf0011 | ||
|
085e9f8414 | ||
|
a4bf102d29 | ||
|
c8497fb27d | ||
|
68212d100e | ||
|
18f4b42cf1 | ||
|
92055f1b3c | ||
|
9430e53689 | ||
|
a26b32dd86 | ||
|
0a6b5817a9 | ||
|
d830bf1afc | ||
|
f366e8217e | ||
|
9297c253aa |
89
.github/workflows/build-docker-images.yml
vendored
Normal file
89
.github/workflows/build-docker-images.yml
vendored
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
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 QEMU
|
||||||
|
uses: docker/setup-qemu-action@v1
|
||||||
|
with:
|
||||||
|
platforms: all
|
||||||
|
-
|
||||||
|
name: Set up Docker Buildx
|
||||||
|
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: |
|
||||||
|
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
|
@ -12,7 +12,7 @@ WORKDIR /go/src/github.com/dutchcoders/transfer.sh
|
|||||||
ENV GO111MODULE=on
|
ENV GO111MODULE=on
|
||||||
|
|
||||||
# build & install server
|
# 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
|
FROM scratch AS final
|
||||||
LABEL maintainer="Andrea Spacca <andrea.spacca@gmail.com>"
|
LABEL maintainer="Andrea Spacca <andrea.spacca@gmail.com>"
|
||||||
|
@ -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 |
|
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 |
|
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-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 |
|
ga-key | google analytics key for the front end | | GA_KEY |
|
||||||
uservoice-key | user voice key for the front end | | USERVOICE_KEY |
|
uservoice-key | user voice key for the front end | | USERVOICE_KEY |
|
||||||
provider | which storage provider to use | (s3, gdrive or local) | PROVIDER |
|
provider | which storage provider to use | (s3, gdrive or local) | PROVIDER |
|
||||||
|
12
cmd/cmd.go
12
cmd/cmd.go
@ -91,6 +91,12 @@ var globalFlags = []cli.Flag{
|
|||||||
Value: "",
|
Value: "",
|
||||||
EnvVar: "PROXY_PATH",
|
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{
|
cli.StringFlag{
|
||||||
Name: "ga-key",
|
Name: "ga-key",
|
||||||
Usage: "key for google analytics (front end)",
|
Usage: "key for google analytics (front end)",
|
||||||
@ -245,7 +251,7 @@ type Cmd struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func VersionAction(c *cli.Context) {
|
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 {
|
func New() *Cmd {
|
||||||
@ -299,6 +305,10 @@ func New() *Cmd {
|
|||||||
options = append(options, server.ProxyPath(v))
|
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 != "" {
|
if v := c.String("ga-key"); v != "" {
|
||||||
options = append(options, server.GoogleAnalytics(v))
|
options = append(options, server.GoogleAnalytics(v))
|
||||||
}
|
}
|
||||||
|
@ -158,9 +158,9 @@ func (s *Server) previewHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
relativeURL, _ := url.Parse(path.Join(s.proxyPath, token, filename))
|
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))
|
relativeURLGet, _ := url.Parse(path.Join(s.proxyPath, getPathPart, token, filename))
|
||||||
resolvedURLGet := resolveURL(r, relativeURLGet)
|
resolvedURLGet := resolveURL(r, relativeURLGet, s.proxyPort)
|
||||||
var png []byte
|
var png []byte
|
||||||
png, err = qrcode.Encode(resolvedURL, qrcode.High, 150)
|
png, err = qrcode.Encode(resolvedURL, qrcode.High, 150)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -170,8 +170,8 @@ func (s *Server) previewHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
qrCode := base64.StdEncoding.EncodeToString(png)
|
qrCode := base64.StdEncoding.EncodeToString(png)
|
||||||
|
|
||||||
hostname := getURL(r).Host
|
hostname := getURL(r, s.proxyPort).Host
|
||||||
webAddress := resolveWebAddress(r, s.proxyPath)
|
webAddress := resolveWebAddress(r, s.proxyPath, s.proxyPort)
|
||||||
|
|
||||||
data := struct {
|
data := struct {
|
||||||
ContentType string
|
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) {
|
func (s *Server) viewHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
// vars := mux.Vars(r)
|
// vars := mux.Vars(r)
|
||||||
|
|
||||||
hostname := getURL(r).Host
|
hostname := getURL(r, s.proxyPort).Host
|
||||||
webAddress := resolveWebAddress(r, s.proxyPath)
|
webAddress := resolveWebAddress(r, s.proxyPath, s.proxyPort)
|
||||||
|
|
||||||
data := struct {
|
data := struct {
|
||||||
Hostname string
|
Hostname string
|
||||||
@ -339,7 +339,7 @@ func (s *Server) postHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
filename = url.PathEscape(filename)
|
filename = url.PathEscape(filename)
|
||||||
relativeURL, _ := url.Parse(path.Join(s.proxyPath, token, 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)
|
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))
|
relativeURL, _ := url.Parse(path.Join(s.proxyPath, token, filename))
|
||||||
deleteURL, _ := url.Parse(path.Join(s.proxyPath, token, filename, metadata.DeletionToken))
|
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.Fprint(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 = ""
|
r.URL.Path = ""
|
||||||
|
|
||||||
return getURL(r).ResolveReference(u).String()
|
return getURL(r, proxyPort).ResolveReference(u).String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func resolveKey(key, proxyPath string) string {
|
func resolveKey(key, proxyPath string) string {
|
||||||
@ -525,8 +525,8 @@ func resolveKey(key, proxyPath string) string {
|
|||||||
return key
|
return key
|
||||||
}
|
}
|
||||||
|
|
||||||
func resolveWebAddress(r *http.Request, proxyPath string) string {
|
func resolveWebAddress(r *http.Request, proxyPath string, proxyPort string) string {
|
||||||
url := getURL(r)
|
url := getURL(r, proxyPort)
|
||||||
|
|
||||||
var webAddress string
|
var webAddress string
|
||||||
|
|
||||||
@ -544,7 +544,7 @@ func resolveWebAddress(r *http.Request, proxyPath string) string {
|
|||||||
return webAddress
|
return webAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
func getURL(r *http.Request) *url.URL {
|
func getURL(r *http.Request, proxyPort string) *url.URL {
|
||||||
u, _ := url.Parse(r.URL.String())
|
u, _ := url.Parse(r.URL.String())
|
||||||
|
|
||||||
if r.TLS != nil {
|
if r.TLS != nil {
|
||||||
@ -555,16 +555,25 @@ func getURL(r *http.Request) *url.URL {
|
|||||||
u.Scheme = "http"
|
u.Scheme = "http"
|
||||||
}
|
}
|
||||||
|
|
||||||
if u.Host != "" {
|
if u.Host == "" {
|
||||||
} else if host, port, err := net.SplitHostPort(r.Host); err != nil {
|
host, port, err := net.SplitHostPort(r.Host)
|
||||||
u.Host = r.Host
|
if err != nil {
|
||||||
} else {
|
host = r.Host
|
||||||
if port == "80" && u.Scheme == "http" {
|
port = ""
|
||||||
u.Host = host
|
}
|
||||||
} else if port == "443" && u.Scheme == "https" {
|
if len(proxyPort) != 0 {
|
||||||
|
port = proxyPort
|
||||||
|
}
|
||||||
|
if len(port) == 0 {
|
||||||
u.Host = host
|
u.Host = host
|
||||||
} else {
|
} 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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1009,7 +1018,7 @@ func (s *Server) RedirectHandler(h http.Handler) http.HandlerFunc {
|
|||||||
} else if r.Header.Get("X-Forwarded-Proto") == "https" {
|
} else if r.Header.Get("X-Forwarded-Proto") == "https" {
|
||||||
} else if r.URL.Scheme == "https" {
|
} else if r.URL.Scheme == "https" {
|
||||||
} else {
|
} else {
|
||||||
u := getURL(r)
|
u := getURL(r, s.proxyPort)
|
||||||
u.Scheme = "https"
|
u.Scheme = "https"
|
||||||
|
|
||||||
http.Redirect(w, r, u.String(), http.StatusPermanentRedirect)
|
http.Redirect(w, r, u.String(), http.StatusPermanentRedirect)
|
||||||
|
@ -28,6 +28,8 @@ import (
|
|||||||
"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"
|
||||||
@ -139,6 +141,12 @@ func ProxyPath(s string) OptionFn {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ProxyPort(s string) OptionFn {
|
||||||
|
return func(srvr *Server) {
|
||||||
|
srvr.proxyPort = s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TempPath(s string) OptionFn {
|
func TempPath(s string) OptionFn {
|
||||||
return func(srvr *Server) {
|
return func(srvr *Server) {
|
||||||
if s[len(s)-1:] != "/" {
|
if s[len(s)-1:] != "/" {
|
||||||
@ -278,6 +286,7 @@ type Server struct {
|
|||||||
|
|
||||||
webPath string
|
webPath string
|
||||||
proxyPath string
|
proxyPath string
|
||||||
|
proxyPort string
|
||||||
gaKey string
|
gaKey string
|
||||||
userVoiceKey string
|
userVoiceKey string
|
||||||
|
|
||||||
@ -306,7 +315,11 @@ func New(options ...OptionFn) (*Server, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
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() {
|
func (s *Server) Run() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user