Compare commits

...

23 Commits
v1.6.0 ... main

Author SHA1 Message Date
Gocho Mugo
6743a4cf46 Trim prefixed '/' from proxy path (#661)
* Trim prefix '/' from proxy path

* doc: Prefix 'v' in docker image tags

* doc(readme): mention trimming of / prefix in proxy path setting
2025-11-19 18:25:23 +01:00
Aetherinox
f833cd4dac Fix: Change virustotal go dependency & endpoint (#657)
* build(deps): replace `dutchcoders/go-virustotal` with `Aetherinox/go-virustotal`

replace go dependency `dutchcoders/go-virustotal` with updated package `Aetherinox/go-virustotal`

fixes issue with being able to utilize virustotal endpoint when transfering

* build(deps): replace `dutchcoders/go-virustotal` with `Aetherinox/go-virustotal`

replace go dependency `dutchcoders/go-virustotal` with updated package `Aetherinox/go-virustotal`

fixes issue with being able to utilize virustotal endpoint when transfering

* docs(readme): add parameter`virustotal-key` to docs

* docs(readme): correct auto-formatting on YYYY
2025-09-05 14:24:32 +02:00
dependabot[bot]
4a95d2dc9c Bump github.com/cloudflare/circl from 1.3.7 to 1.6.1 (#650)
Bumps [github.com/cloudflare/circl](https://github.com/cloudflare/circl) from 1.3.7 to 1.6.1.
- [Release notes](https://github.com/cloudflare/circl/releases)
- [Commits](https://github.com/cloudflare/circl/compare/v1.3.7...v1.6.1)

---
updated-dependencies:
- dependency-name: github.com/cloudflare/circl
  dependency-version: 1.6.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-19 19:28:36 +02:00
Stefan Benten
c545d38ab4 .github/, Dockerfile: bump go version (#654) 2025-07-19 18:18:54 +02:00
Jack
db3f86235f Fix some errors in Readme.md and some performance optimization (#646)
I like this project very much, it's great, but there are some errors in readme.md
And the following about performance optimization
Optimize token generation with strings. Builder
Replace inefficient string concatenation with strings. Builder for token generation.
This improves performance by reducing memory allocations during string creation.
Using WriteByte also avoids unnecessary type conversions from character to string.

Co-authored-by: guocheng <cheng.guo@quantix.ae>
2025-04-03 13:48:46 +02:00
Ramon Smits
01f90648cc Docker tag usage (#639)
* Docker tag usage

* Update README.md

* Update README.md

* Changed based on feedback

* Feedback
2025-02-14 13:40:53 +01:00
Andrea Spacca
089ff324e1 Check ci 20241026 (#632)
* bump go version and se gotip

* bump go version and se gotip

* bump go version and se gotip

* bump go version and se gotip

* linting

* gobin

* GOPATH
2024-10-28 03:10:26 +09:00
Andrea Spacca
7f043ca543 Update README.md 2024-10-26 17:38:19 +09:00
Andrea Spacca
73b99b8bec Update README.md (#627) 2024-09-26 17:21:26 +09:00
dependabot[bot]
2a76d14b0d Bump golang.org/x/net from 0.17.0 to 0.23.0 (#615)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.17.0 to 0.23.0.
- [Commits](https://github.com/golang/net/compare/v0.17.0...v0.23.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-11 13:46:33 +02:00
Alexey Kostin
1eecc22fb3 Normalize upload file name (#606)
* Generate secure token using crypto rand

* Normalize names of uploaded files

* revert token.go accidentally added to commit

* better input filename normalization using transfrom chain

* remove unused line

---------

Co-authored-by: Alexey Kostin <a.kostin@corp.mail.ru>
Co-authored-by: Andrea Spacca <andrea.spacca@gmail.com>
2024-03-20 09:02:57 +09:00
dependabot[bot]
bedbc8162d Bump google.golang.org/protobuf from 1.30.0 to 1.33.0 (#608)
Bumps google.golang.org/protobuf from 1.30.0 to 1.33.0.

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-15 15:16:01 +09:00
Alex Mayer
54b4f1aa86 Update Encryption Examples (#592)
Use long flags (i.e. --armor) which are easier to understand in examples

Co-authored-by: Andrea Spacca <andrea.spacca@gmail.com>
2024-02-22 18:39:39 +09:00
ArGei26
b5187546b1 Update examples.md (#603)
Added example script to display URL and deletion token
2024-02-22 18:38:42 +09:00
dependabot[bot]
f207ec6122 Bump github.com/cloudflare/circl from 1.3.3 to 1.3.7 (#600)
Bumps [github.com/cloudflare/circl](https://github.com/cloudflare/circl) from 1.3.3 to 1.3.7.
- [Release notes](https://github.com/cloudflare/circl/releases)
- [Commits](https://github.com/cloudflare/circl/compare/v1.3.3...v1.3.7)

---
updated-dependencies:
- dependency-name: github.com/cloudflare/circl
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-13 12:29:42 +01:00
dependabot[bot]
24e93f376a Bump golang.org/x/crypto from 0.14.0 to 0.17.0 (#593)
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.14.0 to 0.17.0.
- [Commits](https://github.com/golang/crypto/compare/v0.14.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-03 12:42:43 +01:00
Adams
29d93c6da0 Add new example (#574)
Add new example with option to upload password protected files of any format

Co-authored-by: Alexey Gynu <alexey.gynu@itentika.ru>
Co-authored-by: Andrea Spacca <andrea.spacca@gmail.com>
2023-12-04 14:58:11 +09:00
Luiz Angelo Daros de Luca
a6f197a482 Fixes transfer() issues (#579)
- use subshell to avoid leaking vars to current shell
- use POSIX 'test -t' instead of tty
- have a single place to call curl
- echo the output url to add the carrier return when needed.
- use printf to process \n
- silence curl instead of teeing /dev/null

Co-authored-by: Andrea Spacca <andrea.spacca@gmail.com>
2023-12-04 14:54:54 +09:00
Andrea Spacca
95c7e675a0 fix http-auth-ip-whitelist 2023-12-04 14:36:57 +09:00
dependabot[bot]
4d8b442576 Bump google.golang.org/grpc from 1.53.0 to 1.56.3 (#586)
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.53.0 to 1.56.3.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.53.0...v1.56.3)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-26 07:57:28 +09:00
Gavin Inglis
436c73c39b deps: remove ioutil package (#583)
ioutil has been deprecated since Go 1.16:
https://pkg.go.dev/io/ioutil

Signed-off-by: ginglis13 <ginglis05@gmail.com>
2023-10-13 23:52:59 +02:00
dependabot[bot]
1c49575939 Bump golang.org/x/net from 0.8.0 to 0.17.0 (#581)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.8.0 to 0.17.0.
- [Commits](https://github.com/golang/net/compare/v0.8.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-12 11:59:57 +02:00
Stefan Benten
891ef14cfb server/server.go: use TLS config provided by acme/autocert (#567)
Suggestion based on go docs of acme autocert.
2023-06-20 20:07:19 +02:00
15 changed files with 462 additions and 149 deletions

View File

@@ -105,9 +105,9 @@ jobs:
echo "ASSET_NAME=$_NAME" >> $GITHUB_ENV
- name: Set up Go
uses: actions/setup-go@v2
uses: actions/setup-go@v5
with:
go-version: ^1.18
go-version: ^1.22
- name: Get project dependencies
run: go mod download

View File

@@ -13,9 +13,9 @@ jobs:
fail-fast: false
matrix:
go_version:
- '1.18'
- '1.19'
- '1.20'
- '1.22'
- '1.23'
- '1.24'
- tip
name: Test with ${{ matrix.go_version }}
steps:
@@ -29,16 +29,20 @@ jobs:
- name: Install Go ${{ matrix.go_version }}
if: ${{ matrix.go_version == 'tip' }}
run: |
curl -sL https://storage.googleapis.com/go-build-snap/go/linux-amd64/$(git ls-remote https://github.com/golang/go.git HEAD | awk '{print $1;}').tar.gz -o gotip.tar.gz
ls -lah gotip.tar.gz
mkdir -p ~/sdk/gotip
tar -C ~/sdk/gotip -xzf gotip.tar.gz
echo "PATH=$HOME/go/bin:$HOME/sdk/gotip/bin/:$PATH" >> $GITHUB_ENV
- name: Vet and test
go install golang.org/dl/gotip@latest
`go env GOPATH`/bin/gotip download
- name: Vet and test no tip
if: ${{ matrix.go_version != 'tip' }}
run: |
go version
go vet ./...
go test ./...
- name: Vet and test gotip
if: ${{ matrix.go_version == 'tip' }}
run: |
`go env GOPATH`/bin/gotip version
`go env GOPATH`/bin/gotip vet ./...
`go env GOPATH`/bin/gotip test ./...
golangci:
name: Linting
runs-on: ubuntu-latest
@@ -46,7 +50,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-go@master
with:
go-version: '1.20'
go-version: '1.24'
check-latest: true
- name: golangci-lint
uses: golangci/golangci-lint-action@v2

View File

@@ -1,5 +1,5 @@
# Default to Go 1.20
ARG GO_VERSION=1.20
# Default to Go 1.24
ARG GO_VERSION=1.24
FROM golang:${GO_VERSION}-alpine as build
# Necessary to run 'go get' and to compile the linked binary

324
README.md
View File

@@ -4,76 +4,150 @@ Easy and fast file sharing from the command-line. This code contains the server
Transfer.sh currently supports the s3 (Amazon S3), gdrive (Google Drive), storj (Storj) providers, and local file system (local).
<br />
---
<br />
## Disclaimer
The service at transfersh.com is of unknown origin and reported as cloud malware.
@stefanbenten happens to be a maintainer of this repository _and_ the person who host a well known public installation of the software in the repo.
The two are anyway unrelated, and the repo is not the place to direct requests and issues for any of the pubblic installation.
No third-party public installation of the software in the repo will be advertised or mentioned in the repo itself, for security reasons.
The official position of me, @aspacca, as maintainer of the repo, is that if you want to use the software you should host your own installation.
<br />
---
<br />
## Usage
### Upload:
This section outlines how to use transfer.sh
<br />
### Upload
```bash
$ curl -v --upload-file ./hello.txt https://transfer.sh/hello.txt
```
### Encrypt & Upload:
```bash
$ cat /tmp/hello.txt|gpg -ac -o-|curl -X PUT --upload-file "-" https://transfer.sh/test.txt
````
<br />
### Encrypt & Upload
### Download & Decrypt:
```bash
$ curl https://transfer.sh/1lDau/test.txt|gpg -o- > /tmp/hello.txt
$ gpg --armor --symmetric --output - /tmp/hello.txt | curl --upload-file - https://transfer.sh/test.txt
```
### Upload to Virustotal:
<br />
### Download & Decrypt
```bash
$ curl https://transfer.sh/1lDau/test.txt | gpg --decrypt --output /tmp/hello.txt
```
<br />
### Upload to Virustotal
```bash
$ curl -X PUT --upload-file nhgbhhj https://transfer.sh/test.txt/virustotal
```
<br />
### Deleting
```bash
$ curl -X DELETE <X-Url-Delete Response Header URL>
```
<br />
---
<br />
## Request Headers
This section explains how to handle request headers with curl:
<br />
### Max-Downloads
```bash
$ curl --upload-file ./hello.txt https://transfer.sh/hello.txt -H "Max-Downloads: 1" # Limit the number of downloads
```
<br />
### Max-Days
```bash
$ curl --upload-file ./hello.txt https://transfer.sh/hello.txt -H "Max-Days: 1" # Set the number of days before deletion
```
<br />
### X-Encrypt-Password
#### Beware, use this feature only on your self-hosted server: trusting a third-party service for server side encryption is at your own risk
```bash
$ curl --upload-file ./hello.txt https://your-transfersh-instance.tld/hello.txt -H "X-Encrypt-Password: test" # Encrypt the content sever side with AES265 using "test" as password
$ curl --upload-file ./hello.txt https://your-transfersh-instance.tld/hello.txt -H "X-Encrypt-Password: test" # Encrypt the content server side with AES256 using "test" as password
```
<br />
### X-Decrypt-Password
#### Beware, use this feature only on your self-hosted server: trusting a third-party service for server side encryption is at your own risk
```bash
$ curl https://your-transfersh-instance.tld/BAYh0/hello.txt -H "X-Decrypt-Password: test" # Decrypt the content sever side with AES265 using "test" as password
$ curl https://your-transfersh-instance.tld/BAYh0/hello.txt -H "X-Decrypt-Password: test" # Decrypt the content server side with AES256 using "test" as password
```
<br />
---
<br />
## Response Headers
This section explains how to handle response headers:
<br />
### X-Url-Delete
The URL used to request the deletion of a file and returned as a response header.
The URL used to request the deletion of a file and returned as a response header:
```bash
curl -sD - --upload-file ./hello.txt https://transfer.sh/hello.txt | grep -i -E 'transfer\.sh|x-url-delete'
x-url-delete: https://transfer.sh/hello.txt/BAYh0/hello.txt/PDw0NHPcqU
https://transfer.sh/hello.txt/BAYh0/hello.txt
```
<br />
---
<br />
## Examples
See good usage examples on [examples.md](examples.md)
<br />
## Link aliases
Create direct download link:
@@ -84,59 +158,72 @@ Inline file:
https://transfer.sh/1lDau/test.txt --> https://transfer.sh/inline/1lDau/test.txt
<br />
---
<br />
## Usage
Parameter | Description | Value | Env
--- |---------------------------------------------------------------------------------------------|------------------------------|-----------------------------
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 |
http-auth-htpasswd | htpasswd file path for basic http auth on upload | | HTTP_AUTH_HTPASSWD |
http-auth-ip-whitelist | comma separated list of ips allowed to upload without being challenged an http auth | | HTTP_AUTH_IP_WHITELIST |
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 |
proxy-port | port of the proxy when the service is run behind a proxy | | PROXY_PORT |
email-contact | email contact for the front end | | EMAIL_CONTACT |
ga-key | google analytics key for the front end | | GA_KEY |
provider | which storage provider to use | (s3, storj, gdrive or local) |
uservoice-key | user voice key for the front end | | USERVOICE_KEY |
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 |
storj-access | Access for the project | | STORJ_ACCESS |
storj-bucket | Bucket to use within the project | | STORJ_BUCKET |
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 |
perform-clamav-prescan | prescan every upload through clamav feature (clamav-host must be a local clamd unix socket) | | PERFORM_CLAMAV_PRESCAN |
rate-limit | request per minute | | RATE_LIMIT |
max-upload-size | max upload size in kilobytes | | MAX_UPLOAD_SIZE |
purge-days | number of days after the uploads are purged automatically | | PURGE_DAYS |
purge-interval | interval in hours to run the automatic purge for (not applicable to S3 and Storj) | | PURGE_INTERVAL |
random-token-length | length of the random token for the upload path (double the size for delete path) | 6 | RANDOM_TOKEN_LENGTH |
Parameter | Description | Value | Env
--- |-----------------------------------------------------------------------------------------------|-------------------------------|-------------------------------|
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 |
http-auth-htpasswd | htpasswd file path for basic http auth on upload | | HTTP_AUTH_HTPASSWD |
http-auth-ip-whitelist | comma separated list of allowed ips to upload without auth challenge | | HTTP_AUTH_IP_WHITELIST |
virustotal-key | VirusTotal API key | | VIRUSTOTAL_KEY |
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 (a `/` prefix will be trimmed) | | PROXY_PATH |
proxy-port | port of the proxy when the service is run behind a proxy | | PROXY_PORT |
email-contact | email contact for the front end | | EMAIL_CONTACT |
ga-key | google analytics key for the front end | | GA_KEY |
provider | which storage provider to use | (s3, storj, gdrive or local) | |
uservoice-key | user voice key for the front end | | USERVOICE_KEY |
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 |
storj-access | Access for the project | | STORJ_ACCESS |
storj-bucket | Bucket to use within the project | | STORJ_BUCKET |
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 separated) | | 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 |
perform-clamav-prescan | prescan every upload using clamav (clamav-host must be local clamd unix socket) | | PERFORM_CLAMAV_PRESCAN |
rate-limit | request per minute | | RATE_LIMIT |
max-upload-size | max upload size in kilobytes | | MAX_UPLOAD_SIZE |
purge-days | number of days after the uploads are purged automatically | | PURGE_DAYS |
purge-interval | interval (hours) to run automatic purge for (excluding S3 and Storj) | | PURGE_INTERVAL |
random-token-length | length of random token for upload path (double the size for delete path) | 6 | RANDOM_TOKEN_LENGTH |
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.
<br />
---
<br />
## Development
Switched to GO111MODULE
@@ -145,6 +232,12 @@ Switched to GO111MODULE
go run main.go --provider=local --listener :8080 --temp-path=/tmp/ --basedir=/tmp/
```
<br />
---
<br />
## Build
```bash
@@ -153,23 +246,69 @@ $ cd transfer.sh
$ go build -o transfersh main.go
```
<br />
---
<br />
## Docker
For easy deployment, we've created an official Docker container. There are two variants, differing only by which user runs the process.
The default one will run as `root`:
> [!WARNING]
> It is discouraged to use `latest` tag for WatchTower or similar tools. The `latest` tag can reference unreleased developer, test builds, and patch releases for older versions. Use an actual version tag until transfer.sh supports major or minor version tags.
```bash
docker run --publish 8080:8080 dutchcoders/transfer.sh:latest --provider local --basedir /tmp/
```
<br />
### No root
The `-noroot` tags indicate image builds that run with least priviledge to reduce the attack surface might an application get compromised.
> [!NOTE]
> Using `-noroot` is **recommended**
<br />
The one tagged with the suffix `-noroot` will use `5000` as both UID and GID:
```bash
docker run --publish 8080:8080 dutchcoders/transfer.sh:latest-noroot --provider local --basedir /tmp/
```
<br />
> [!NOTE]
> Development history details at:
> - https://github.com/dutchcoders/transfer.sh/pull/418
<br />
### Tags
Name | Usage
--|--
latest| Latest CI build, can be nightly, at commit, at tag, etc.
latest-noroot| Latest CI build, can be nightly, at commit, at tag, etc. using [no root]
nightly| Scheduled CI build every midnight UTC
nightly-noroot| Scheduled CI build every midnight UTC using [no root]
edge| Latest CI build after every commit on `main`
edge-noroot| Latest CI build after every commit on `main` using [no root]
v`x.y.z`| CI build after tagging a release
v`x.y.z`-noroot| CI build after tagging a release using [no root]
<br />
### Building the Container
You can also build the container yourself. This allows you to choose which UID/GID will be used, e.g. when using NFS mounts:
```bash
# Build arguments:
# * RUNAS: If empty, the container will run as root.
@@ -180,6 +319,12 @@ You can also build the container yourself. This allows you to choose which UID/G
docker build -t transfer.sh-noroot --build-arg RUNAS=doesntmatter --build-arg PUID=1337 --build-arg PGID=1338 .
```
<br />
---
<br />
## S3 Usage
For the usage with a AWS S3 Bucket, you just need to specify the following options:
@@ -191,10 +336,18 @@ For the usage with a AWS S3 Bucket, you just need to specify the following optio
If you specify the s3-region, you don't need to set the endpoint URL since the correct endpoint will used automatically.
<br />
### Custom S3 providers
To use a custom non-AWS S3 provider, you need to specify the endpoint as defined from your cloud provider.
<br />
---
<br />
## Storj Network Provider
To use the Storj Network as a storage provider you need to specify the following flags:
@@ -202,6 +355,8 @@ To use the Storj Network as a storage provider you need to specify the following
- storj-access _(either via flag or environment variable STORJ_ACCESS)_
- storj-bucket _(either via flag or environment variable STORJ_BUCKET)_
<br />
### Creating Bucket and Scope
You need to create an access grant (or copy it from the uplink configuration) and a bucket in preparation.
@@ -216,12 +371,19 @@ Afterwards, you can copy the access grant and then start the startup of the tran
It is recommended to provide both the access grant and the bucket name as ENV Variables for enhanced security.
Example:
```
export STORJ_BUCKET=<BUCKET NAME>
export STORJ_ACCESS=<ACCESS GRANT>
transfer.sh --provider storj
```
<br />
---
<br />
## Google Drive Usage
For the usage with Google drive, you need to specify the following options:
@@ -230,27 +392,40 @@ For the usage with Google drive, you need to specify the following options:
- gdrive-local-config-path
- basedir
<br />
### Creating Gdrive Client Json
You need to create an OAuth Client id from console.cloud.google.com, download the file, and place it into a safe directory.
<br />
### Usage example
```go run main.go --provider gdrive --basedir /tmp/ --gdrive-client-json-filepath /[credential_dir] --gdrive-local-config-path [directory_to_save_config] ```
<br />
---
<br />
## Shell functions
### Bash and zsh (multiple files uploaded as zip archive)
### Bash, ash and zsh (multiple files uploaded as zip archive)
##### Add this to .bashrc or .zshrc or its equivalent
```bash
transfer(){ if [ $# -eq 0 ];then echo "No arguments specified.\nUsage:\n transfer <file|directory>\n ... | transfer <file_name>">&2;return 1;fi;if tty -s;then file="$1";file_name=$(basename "$file");if [ ! -e "$file" ];then echo "$file: No such file or directory">&2;return 1;fi;if [ -d "$file" ];then file_name="$file_name.zip" ,;(cd "$file"&&zip -r -q - .)|curl --progress-bar --upload-file "-" "https://transfer.sh/$file_name"|tee /dev/null,;else cat "$file"|curl --progress-bar --upload-file "-" "https://transfer.sh/$file_name"|tee /dev/null;fi;else file_name=$1;curl --progress-bar --upload-file "-" "https://transfer.sh/$file_name"|tee /dev/null;fi;}
transfer() (if [ $# -eq 0 ]; then printf "No arguments specified.\nUsage:\n transfer <file|directory>\n ... | transfer <file_name>\n">&2; return 1; fi; file_name=$(basename "$1"); if [ -t 0 ]; then file="$1"; if [ ! -e "$file" ]; then echo "$file: No such file or directory">&2; return 1; fi; if [ -d "$file" ]; then cd "$file" || return 1; file_name="$file_name.zip"; set -- zip -r -q - .; else set -- cat "$file"; fi; else set -- cat; fi; url=$("$@" | curl --silent --show-error --progress-bar --upload-file "-" "https://transfer.sh/$file_name"); echo "$url"; )
```
<br />
#### Now you can use transfer function
```
$ transfer hello.txt
```
<br />
### Bash and zsh (with delete url, delete token output and prompt before uploading)
##### Add this to .bashrc or .zshrc or its equivalent
@@ -402,10 +577,22 @@ tauN5dE3fWJe
https://transfer.sh/MYkuqn/image.img
```
<br />
---
<br />
## Contributions
Contributions are welcome.
<br />
---
<br />
## Creators
**Remco Verhoef**
@@ -414,11 +601,22 @@ Contributions are welcome.
**Uvis Grinfelds**
## Maintainer
<br />
**Andrea Spacca**
---
**Stefan Benten**
<br />
## Maintainers
- **Andrea Spacca**
- **Stefan Benten**
<br />
---
<br />
## Copyright and License

View File

@@ -461,7 +461,7 @@ func New() *Cmd {
if httpAuthIPWhitelist := c.String("http-auth-ip-whitelist"); httpAuthIPWhitelist != "" {
ipFilterOptions := server.IPFilterOptions{}
ipFilterOptions.AllowedIPs = strings.Split(httpAuthIPWhitelist, ",")
ipFilterOptions.BlockByDefault = false
ipFilterOptions.BlockByDefault = true
options = append(options, server.HTTPAUTHFilterOptions(ipFilterOptions))
}

View File

@@ -6,6 +6,7 @@
* [Encrypting and decrypting](#encrypting-and-decrypting)
* [Scanning for viruses](#scanning-for-viruses)
* [Uploading and copy download command](#uploading-and-copy-download-command)
* [Uploading and displaying URL and deletion token](#uploading-and-displaying-url-and-deletion-token)
## Aliases
<a name="aliases"/>
@@ -147,12 +148,12 @@ $ transfer /tmp/hello.txt | mail -s "Hello World" user@yourmaildomain.com
### Encrypting files with password using gpg
```bash
$ cat /tmp/hello.txt | gpg -ac -o- | curl -X PUT --upload-file "-" https://transfer.sh/test.txt
$ gpg --armor --symmetric --output - /tmp/hello.txt | curl --upload-file - https://transfer.sh/test.txt
```
### Downloading and decrypting
```bash
$ curl https://transfer.sh/1lDau/test.txt | gpg -o- > /tmp/hello.txt
$ curl https://transfer.sh/1lDau/test.txt | gpg --decrypt --output /tmp/hello.txt
```
### Import keys from [keybase](https://keybase.io/)
@@ -175,6 +176,58 @@ $ curl -X PUT --upload-file ./eicar.com https://transfer.sh/eicar.com/scan
```bash
$ curl -X PUT --upload-file nhgbhhj https://transfer.sh/test.txt/virustotal
```
### Upload encrypted password protected files
By default files upload for only 1 download, you can specify download limit using -D flag like `transfer-encrypted -D 50 %file/folder%`
#### One line for bashrc
```bash
transfer-encrypted() { if [ $# -eq 0 ]; then echo "No arguments specified.\nUsage:\n transfer <file|directory>\n ... | transfer <file_name>" >&2; return 1; fi; while getopts ":D:" opt; do case $opt in D) max_downloads=$OPTARG;; \?) echo "Invalid option: -$OPTARG" >&2;; esac; done; shift "$((OPTIND - 1))"; file="$1"; file_name=$(basename "$file"); if [ ! -e "$file" ]; then echo "$file: No such file or directory" >&2; return 1; fi; if [ -d "$file" ]; then file_name="$file_name.zip"; (cd "$file" && zip -r -q - .) | openssl aes-256-cbc -pbkdf2 -e > "tmp-$file_name" && cat "tmp-$file_name" | curl -H "Max-Downloads: $max_downloads" -w '\n' --upload-file "tmp-$file_name" "https://transfer.sh/$file_name" | tee /dev/null; rm "tmp-$file_name"; else cat "$file" | openssl aes-256-cbc -pbkdf2 -e > "tmp-$file" && cat "tmp-$file" | curl -H "Max-Downloads: $max_downloads" -w '\n' --upload-file - "https://transfer.sh/$file_name" | tee /dev/null; rm "tmp-$file"; fi; }
```
#### Human readable code
```bash
transfer-encrypted() {
if [ $# -eq 0 ]; then
echo "No arguments specified.\nUsage:\n transfer <file|directory>\n ... | transfer <file_name>" >&2
return 1
fi
while getopts ":D:" opt; do
case $opt in
D)
max_downloads=$OPTARG
;;
\?)
echo "Invalid option: -$OPTARG" >&2
;;
esac
done
shift "$((OPTIND - 1))"
file="$1"
file_name=$(basename "$file")
if [ ! -e "$file" ]; then
echo "$file: No such file or directory" >&2
return 1
fi
if [ -d "$file" ]; then
file_name="$file_name.zip"
(cd "$file" && zip -r -q - .) | openssl aes-256-cbc -pbkdf2 -e > "tmp-$file_name" && cat "tmp-$file_name" | curl -H "Max-Downloads: $max_downloads" -w '\n' --upload-file "tmp-$file_name" "https://transfer.sh/$file_name" | tee /dev/null
rm "tmp-$file_name"
else
cat "$file" | openssl aes-256-cbc -pbkdf2 -e > "tmp-$file" && cat "tmp-$file" | curl -H "Max-Downloads: $max_downloads" -w '\n' --upload-file - "https://transfer.sh/$file_name" | tee /dev/null
rm "tmp-$file"
fi
}
```
#### Decrypt using
```bash
curl -s https://transfer.sh/some/file | openssl aes-256-cbc -pbkdf2 -d > output_filename
```
## Uploading and copy download command
Download commands can be automatically copied to the clipboard after files are uploaded using transfer.sh.
@@ -259,5 +312,34 @@ https://transfer.sh/y0qr2c/a.log
wget https://transfer.sh/y0qr2c/a.log
3) Windows download command:
Invoke-WebRequest -Uri https://transfer.sh/y0qr2c/a.log -OutFile a.log
Invoke-WebRequest -Uri https://transfer.sh/y0qr2c/a.log -OutFile a.log
```
## Uploading and displaying URL and deletion token
```bash
# tempfile
URLFILE=$HOME/temp/transfersh.url
# insert number of downloads and days saved
if [ -f $1 ]; then
read -p "Allowed number of downloads: " num_down
read -p "Number of days on server: " num_save
# transfer
curl -sD - -H "Max-Downloads: $num_down" -H "Max-Days: $num_save"--progress-bar --upload-file $1 https://transfer.sh/$(basename $1) | grep -i -E 'transfer\.sh|x-url-delete' &> $URLFILE
# display URL and deletion token
if [ -f $URLFILE ]; then
URL=$(tail -n1 $URLFILE)
TOKEN=$(grep delete $URLFILE | awk -F "/" '{print $NF}')
echo "*********************************"
echo "Data is saved in $URLFILE"
echo "**********************************"
echo "URL is: $URL"
echo "Deletion Token is: $TOKEN"
echo "**********************************"
else
echo "NO URL-File found !!"
fi
else
echo "!!!!!!"
echo "\"$1\" not found !!"
echo "!!!!!!"
fi
```

30
go.mod
View File

@@ -1,6 +1,6 @@
module github.com/dutchcoders/transfer.sh
go 1.18
go 1.22.0
require (
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8
@@ -13,7 +13,7 @@ require (
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.67
github.com/aws/aws-sdk-go-v2/service/s3 v1.33.1
github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e
github.com/dutchcoders/go-virustotal v0.0.0-20140923143438-24cc8e6fa329
github.com/Aetherinox/go-virustotal v0.0.0-20250520084801-0eb8c8f901c8
github.com/dutchcoders/transfer.sh-web v0.0.0-20221119114740-ca3a2621d2a6
github.com/elazarl/go-bindata-assetfs v1.0.1
github.com/fatih/color v1.14.1
@@ -26,17 +26,18 @@ require (
github.com/tg123/go-htpasswd v1.2.1
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce
github.com/urfave/cli/v2 v2.25.3
golang.org/x/crypto v0.6.0
golang.org/x/net v0.8.0
golang.org/x/oauth2 v0.5.0
google.golang.org/api v0.111.0
golang.org/x/crypto v0.21.0
golang.org/x/net v0.23.0
golang.org/x/oauth2 v0.7.0
golang.org/x/text v0.14.0
google.golang.org/api v0.114.0
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c
storj.io/common v0.0.0-20230301105927-7f966760c100
storj.io/uplink v1.10.0
)
require (
cloud.google.com/go/compute v1.18.0 // indirect
cloud.google.com/go/compute v1.19.1 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
github.com/GehirnInc/crypt v0.0.0-20200316065508-bb7000b8a962 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 // indirect
@@ -55,17 +56,17 @@ require (
github.com/aws/smithy-go v1.13.5 // indirect
github.com/aymerick/douceur v0.2.0 // indirect
github.com/calebcase/tmpfile v1.0.3 // indirect
github.com/cloudflare/circl v1.3.3 // indirect
github.com/cloudflare/circl v1.6.1 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/felixge/httpsnoop v1.0.3 // indirect
github.com/flynn/noise v1.0.0 // indirect
github.com/garyburd/redigo v1.6.4 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
github.com/googleapis/gax-go/v2 v2.7.0 // indirect
github.com/googleapis/gax-go/v2 v2.7.1 // indirect
github.com/gorilla/css v1.0.0 // indirect
github.com/gorilla/securecookie v1.1.1 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
@@ -85,12 +86,11 @@ require (
github.com/zeebo/errs v1.3.0 // indirect
go.opencensus.io v0.24.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.6.0 // indirect
golang.org/x/text v0.8.0 // indirect
golang.org/x/sys v0.18.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20230227214838-9b19f0bdc514 // indirect
google.golang.org/grpc v1.53.0 // indirect
google.golang.org/protobuf v1.28.1 // indirect
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
google.golang.org/grpc v1.56.3 // indirect
google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
storj.io/drpc v0.0.33-0.20230204035225-c9649dee8f2a // indirect
storj.io/picobuf v0.0.1 // indirect

61
go.sum
View File

@@ -1,11 +1,12 @@
cloud.google.com/go v0.16.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys=
cloud.google.com/go/compute v1.18.0 h1:FEigFqoDbys2cvFkZ9Fjq4gnHBP55anJ0yQyau2f9oY=
cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs=
cloud.google.com/go/compute v1.19.1 h1:am86mquDUgjGNWxiGn+5PGLbmgiWXlE/yNWpIpNvuXY=
cloud.google.com/go/compute v1.19.1/go.mod h1:6ylj3a05WF8leseCdIf77NK0g1ey+nj5IKd5/kvShxE=
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
cloud.google.com/go/longrunning v0.4.1 h1:v+yFJOfKC3yZdY6ZUI933pIYdhyhV8S3NpWrXWmg7jM=
cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/GehirnInc/crypt v0.0.0-20200316065508-bb7000b8a962 h1:KeNholpO2xKjgaaSyd+DyQRrsQjhbSeS7qe4nEw8aQw=
@@ -67,8 +68,8 @@ github.com/calebcase/tmpfile v1.0.3/go.mod h1:UAUc01aHeC+pudPagY/lWvt2qS9ZO5Zzof
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I=
github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs=
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
@@ -77,10 +78,11 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dsnet/try v0.0.3 h1:ptR59SsrcFUYbT/FhAbKTV6iLkeD6O18qfIWRml2fqI=
github.com/dsnet/try v0.0.3/go.mod h1:WBM8tRpUmnXXhY1U6/S8dt6UWdHTQ7y8A5YSkRCkq40=
github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e h1:rcHHSQqzCgvlwP0I/fQ8rQMn/MpHE5gWSLdtpxtP6KQ=
github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e/go.mod h1:Byz7q8MSzSPkouskHJhX0er2mZY/m0Vj5bMeMCkkyY4=
github.com/dutchcoders/go-virustotal v0.0.0-20140923143438-24cc8e6fa329 h1:ERqCkG/uSyT74P1m/j9yR+so+7ynY4fbTvLY/Mr1ZMg=
github.com/dutchcoders/go-virustotal v0.0.0-20140923143438-24cc8e6fa329/go.mod h1:G5qOfE5bQZ5scycLpB7fYWgN4y3xdfXo+pYWM8z2epY=
github.com/Aetherinox/go-virustotal v0.0.0-20250520084801-0eb8c8f901c8 h1:wEwYJxNLG29OesabDdAJWFBIO42HOL4x5kjvGuZLIyk=
github.com/Aetherinox/go-virustotal v0.0.0-20250520084801-0eb8c8f901c8/go.mod h1:myGG2GhfY2AgAPe8lFZw6Y1+IxhU+ED7ilotbpdQsDw=
github.com/dutchcoders/transfer.sh-web v0.0.0-20221119114740-ca3a2621d2a6 h1:7uTRy44YpQi6/mtDq0N9zeQRCGEh93o7gKq/usGgpF8=
github.com/dutchcoders/transfer.sh-web v0.0.0-20221119114740-ca3a2621d2a6/go.mod h1:F6Q37CxDh2MHr5KXkcZmNB3tdkK7v+bgE+OpBY+9ilI=
github.com/elazarl/go-bindata-assetfs v1.0.1 h1:m0kkaHRKEu7tUIUFVwhGGGYClXvyl4RE03qmvRTNfbw=
@@ -122,8 +124,8 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.1.1-0.20171103154506-982329095285/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
@@ -135,15 +137,17 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/pprof v0.0.0-20211108044417-e9b028704de0 h1:rsq1yB2xiFLDYYaYdlGBsSkwVzsCo500wMhxvW5A/bk=
github.com/google/pprof v0.0.0-20211108044417-e9b028704de0/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k=
github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k=
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
github.com/googleapis/gax-go/v2 v2.7.0 h1:IcsPKeInNvYi7eqSaDjiZqDDKu5rsmunY0Y1YupQSSQ=
github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8=
github.com/googleapis/gax-go/v2 v2.7.1 h1:gF4c0zjUP2H/s/hEGyLA3I0fA2ZWjzYiONAD6cvPr8A=
github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI=
github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
@@ -233,6 +237,7 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
github.com/zeebo/assert v1.3.1 h1:vukIABvugfNMZMQO1ABsyQDJDTVQbn+LWSMy1ol1h6A=
github.com/zeebo/assert v1.3.1/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
github.com/zeebo/blake3 v0.2.3 h1:TFoLXsjeXqRNFxSbk35Dk4YtszE/MQQGK10BH4ptoTg=
github.com/zeebo/blake3 v0.2.3/go.mod h1:mjJjZpnsyIVtVgTOSpJ9vmRE4wgDeyt2HU3qXvvKCaQ=
github.com/zeebo/errs v1.3.0 h1:hmiaKqgYZzcVgRL1Vkc1Mn2914BbzB0IBxs+ebeutGs=
@@ -247,8 +252,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
@@ -275,12 +280,12 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/oauth2 v0.0.0-20170912212905-13449ad91cb2/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s=
golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I=
golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g=
golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4=
golang.org/x/sync v0.0.0-20170517211232-f52d1811a629/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -304,16 +309,16 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.0.0-20170424234030-8be79e1e0910/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -330,8 +335,8 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.0.0-20170921000349-586095a6e407/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.111.0 h1:bwKi+z2BsdwYFRKrqwutM+axAlYLz83gt5pDSXCJT+0=
google.golang.org/api v0.111.0/go.mod h1:qtFHvU9mhgTJegR31csQ+rwxyUTHOKFqCKWp1J0fdw0=
google.golang.org/api v0.114.0 h1:1xQPji6cO2E2vLiI+C/XiFAnsn1WV3mjaEwGLhi3grE=
google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
@@ -341,16 +346,16 @@ google.golang.org/genproto v0.0.0-20170918111702-1e559d0a00ee/go.mod h1:JiN7NxoA
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20230227214838-9b19f0bdc514 h1:rtNKfB++wz5mtDY2t5C8TXlU5y52ojSu7tZo0z7u8eQ=
google.golang.org/genproto v0.0.0-20230227214838-9b19f0bdc514/go.mod h1:TvhZT5f700eVlTNwND1xoEZQeWTB2RY/65kplwl/bFA=
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A=
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=
google.golang.org/grpc v1.2.1-0.20170921194603-d4b75ebd4f9f/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc=
google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw=
google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc=
google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@@ -362,8 +367,8 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=

View File

@@ -30,8 +30,8 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"time"
"github.com/dutchcoders/go-clamd"
@@ -50,7 +50,7 @@ func (s *Server) scanHandler(w http.ResponseWriter, r *http.Request) {
s.logger.Printf("Scanning %s %d %s", filename, contentLength, contentType)
file, err := ioutil.TempFile(s.tempPath, "clamav-")
file, err := os.CreateTemp(s.tempPath, "clamav-")
defer s.cleanTmpFile(file)
if err != nil {
s.logger.Printf("%s", err.Error())

View File

@@ -51,6 +51,7 @@ import (
"sync"
textTemplate "text/template"
"time"
"unicode"
"github.com/ProtonMail/go-crypto/openpgp"
"github.com/ProtonMail/go-crypto/openpgp/armor"
@@ -66,6 +67,9 @@ import (
blackfriday "github.com/russross/blackfriday/v2"
qrcode "github.com/skip2/go-qrcode"
"golang.org/x/net/idna"
"golang.org/x/text/runes"
"golang.org/x/text/transform"
"golang.org/x/text/unicode/norm"
)
const getPathPart = "get"
@@ -418,7 +422,24 @@ func (s *Server) notFoundHandler(w http.ResponseWriter, _ *http.Request) {
}
func sanitize(fileName string) string {
return path.Base(fileName)
t := transform.Chain(
norm.NFD,
runes.Remove(runes.In(unicode.Cc)),
runes.Remove(runes.In(unicode.Cf)),
runes.Remove(runes.In(unicode.Co)),
runes.Remove(runes.In(unicode.Cs)),
runes.Remove(runes.In(unicode.Other)),
runes.Remove(runes.In(unicode.Zl)),
runes.Remove(runes.In(unicode.Zp)),
norm.NFC)
newName, _, err := transform.String(t, fileName)
if err != nil {
return path.Base(fileName)
}
if len(newName) == 0 {
newName = "_"
}
return path.Base(newName)
}
func (s *Server) postHandler(w http.ResponseWriter, r *http.Request) {
@@ -750,7 +771,7 @@ func resolveWebAddress(r *http.Request, proxyPath string, proxyPort string) stri
webAddress = fmt.Sprintf("%s://%s/%s",
rUrl.ResolveReference(rUrl).Scheme,
rUrl.ResolveReference(rUrl).Host,
proxyPath)
strings.TrimPrefix(proxyPath, "/"))
}
return webAddress

View File

@@ -26,7 +26,7 @@ func (s *suiteRedirectWithForceHTTPS) SetUpTest(c *C) {
c.Assert(err, IsNil)
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello, client")
_, _ = fmt.Fprintln(w, "Hello, client")
})
s.handler = srvr.RedirectHandler(handler)
@@ -83,7 +83,7 @@ func (s *suiteRedirectWithoutForceHTTPS) SetUpTest(c *C) {
c.Assert(err, IsNil)
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello, client")
_, _ = fmt.Fprintln(w, "Hello, client")
})
s.handler = srvr.RedirectHandler(handler)

View File

@@ -144,7 +144,7 @@ func ProfileListener(s string) OptionFn {
func WebPath(s string) OptionFn {
return func(srvr *Server) {
if s[len(s)-1:] != "/" {
s = s + string(filepath.Separator)
s = filepath.Join(s, "")
}
srvr.webPath = s
@@ -155,7 +155,7 @@ func WebPath(s string) OptionFn {
func ProxyPath(s string) OptionFn {
return func(srvr *Server) {
if s[len(s)-1:] != "/" {
s = s + string(filepath.Separator)
s = filepath.Join(s, "")
}
srvr.proxyPath = s
@@ -173,7 +173,7 @@ func ProxyPort(s string) OptionFn {
func TempPath(s string) OptionFn {
return func(srvr *Server) {
if s[len(s)-1:] != "/" {
s = s + string(filepath.Separator)
s = filepath.Join(s, "")
}
srvr.tempPath = s
@@ -274,9 +274,8 @@ func UseLetsEncrypt(hosts []string) OptionFn {
},
}
srvr.tlsConfig = &tls.Config{
GetCertificate: m.GetCertificate,
}
srvr.tlsConfig = m.TLSConfig()
srvr.tlsConfig.GetCertificate = m.GetCertificate
}
}
@@ -403,12 +402,15 @@ func New(options ...OptionFn) (*Server, error) {
return s, nil
}
var theRand *rand.Rand
func init() {
var seedBytes [8]byte
if _, err := cryptoRand.Read(seedBytes[:]); err != nil {
panic("cannot obtain cryptographically secure seed")
}
rand.Seed(int64(binary.LittleEndian.Uint64(seedBytes[:])))
theRand = rand.New(rand.NewSource(int64(binary.LittleEndian.Uint64(seedBytes[:]))))
}
// Run starts Server
@@ -434,8 +436,8 @@ func (s *Server) Run() {
fs = http.Dir(s.webPath)
htmlTemplates, _ = htmlTemplates.ParseGlob(s.webPath + "*.html")
textTemplates, _ = textTemplates.ParseGlob(s.webPath + "*.txt")
htmlTemplates, _ = htmlTemplates.ParseGlob(filepath.Join(s.webPath, "*.html"))
textTemplates, _ = textTemplates.ParseGlob(filepath.Join(s.webPath, "*.txt"))
} else {
fs = &assetfs.AssetFS{
Asset: web.Asset,

View File

@@ -5,7 +5,6 @@ import (
"encoding/json"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"os"
@@ -37,7 +36,7 @@ const gDriveDirectoryMimeType = "application/vnd.google-apps.folder"
// NewGDriveStorage is the factory for GDrive
func NewGDriveStorage(ctx context.Context, clientJSONFilepath string, localConfigPath string, basedir string, chunkSize int, logger *log.Logger) (*GDrive, error) {
b, err := ioutil.ReadFile(clientJSONFilepath)
b, err := os.ReadFile(clientJSONFilepath)
if err != nil {
return nil, err
}
@@ -67,7 +66,7 @@ func NewGDriveStorage(ctx context.Context, clientJSONFilepath string, localConfi
func (s *GDrive) setupRoot() error {
rootFileConfig := filepath.Join(s.localConfigPath, gDriveRootConfigFile)
rootID, err := ioutil.ReadFile(rootFileConfig)
rootID, err := os.ReadFile(rootFileConfig)
if err != nil && !os.IsNotExist(err) {
return err
}
@@ -88,7 +87,7 @@ func (s *GDrive) setupRoot() error {
}
s.rootID = di.Id
err = ioutil.WriteFile(rootFileConfig, []byte(s.rootID), os.FileMode(0600))
err = os.WriteFile(rootFileConfig, []byte(s.rootID), os.FileMode(0600))
if err != nil {
return err
}

View File

@@ -25,7 +25,7 @@ THE SOFTWARE.
package server
import (
"math/rand"
"strings"
)
const (
@@ -35,11 +35,13 @@ const (
// generate a token
func token(length int) string {
result := ""
var builder strings.Builder
builder.Grow(length)
for i := 0; i < length; i++ {
x := rand.Intn(len(SYMBOLS) - 1)
result = string(SYMBOLS[x]) + result
x := theRand.Intn(len(SYMBOLS) - 1)
builder.WriteByte(SYMBOLS[x])
}
return result
return builder.String()
}

View File

@@ -30,7 +30,7 @@ import (
"github.com/gorilla/mux"
"github.com/dutchcoders/go-virustotal"
"github.com/Aetherinox/go-virustotal"
)
func (s *Server) virusTotalHandler(w http.ResponseWriter, r *http.Request) {