transfer.sh
从命令行轻松快速地分享文件。此代码包含服务器及创建您自己的实例所需的一切。
Transfer.sh 目前支持 s3(亚马逊 S3)、gdrive(谷歌云端硬盘)、storj(Storj)提供商和本地文件系统(local)。
免责声明
transfersh.com 的服务来源不明,并被报告为云端恶意软件。
使用方法
上传:
$ curl -v --upload-file ./hello.txt https://transfer.sh/hello.txt
加密并上传:
$ gpg --armor --symmetric --output - /tmp/hello.txt | curl --upload-file - https://transfer.sh/test.txt
下载并解密:
$ curl https://transfer.sh/1lDau/test.txt | gpg --decrypt --output /tmp/hello.txt
上传到 Virustotal:
$ curl -X PUT --upload-file nhgbhhj https://transfer.sh/test.txt/virustotal
删除
$ curl -X DELETE <X-Url-Delete 响应头 URL>
请求头
Max-Downloads
$ curl --upload-file ./hello.txt https://transfer.sh/hello.txt -H "Max-Downloads: 1" # 限制下载次数
Max-Days
$ curl --upload-file ./hello.txt https://transfer.sh/hello.txt -H "Max-Days: 1" # 设置删除前的天数
X-Encrypt-Password
注意,此功能仅在自托管服务器上使用:信任第三方服务进行服务器端加密需自担风险
$ curl --upload-file ./hello.txt https://your-transfersh-instance.tld/hello.txt -H "X-Encrypt-Password: test" # 使用 "test" 作为密码,在服务器端用 AES265 加密内容
X-Decrypt-Password
注意,此功能仅在自托管服务器上使用:信任第三方服务进行服务器端解密需自担风险
$ curl https://your-transfersh-instance.tld/BAYh0/hello.txt -H "X-Decrypt-Password: test" # 使用 "test" 作为密码,在服务器端用 AES265 解密内容
响应头
X-Url-Delete
用于请求删除文件的 URL,作为响应头返回。
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
示例
查看 examples.md 中的优秀使用示例
链接别名
创建直接下载链接:
https://transfer.sh/1lDau/test.txt --> https://transfer.sh/get/1lDau/test.txt
内联文件:
https://transfer.sh/1lDau/test.txt --> https://transfer.sh/inline/1lDau/test.txt
用法
参数 | 描述 | 值 | 环境变量 |
---|---|---|---|
listener | 用于http的端口 (:80) | LISTENER | |
profile-listener | 用于性能分析器的端口 (:6060) | PROFILE_LISTENER | |
force-https | 重定向到https | false | FORCE_HTTPS |
tls-listener | 用于https的端口 (:443) | TLS_LISTENER | |
tls-listener-only | 仅启用tls监听器的标志 | TLS_LISTENER_ONLY | |
tls-cert-file | tls证书路径 | TLS_CERT_FILE | |
tls-private-key | tls私钥路径 | TLS_PRIVATE_KEY | |
http-auth-user | 上传时基本http认证的用户名 | HTTP_AUTH_USER | |
http-auth-pass | 上传时基本http认证的密码 | HTTP_AUTH_PASS | |
http-auth-htpasswd | 上传时基本http认证的htpasswd文件路径 | HTTP_AUTH_HTPASSWD | |
http-auth-ip-whitelist | 允许上传而不需要http认证的IP地址列表,以逗号分隔 | HTTP_AUTH_IP_WHITELIST | |
ip-whitelist | 允许连接服务的IP地址列表,以逗号分隔 | IP_WHITELIST | |
ip-blacklist | 不允许连接服务的IP地址列表,以逗号分隔 | IP_BLACKLIST | |
temp-path | 临时文件夹路径 | 系统临时目录 | TEMP_PATH |
web-path | 静态网页文件路径(用于开发或自定义前端) | WEB_PATH | |
proxy-path | 当服务在代理后运行时的路径前缀 | PROXY_PATH | |
proxy-port | 当服务在代理后运行时代理的端口 | PROXY_PORT | |
email-contact | 前端的联系邮箱 | EMAIL_CONTACT | |
ga-key | 前端的Google Analytics密钥 | GA_KEY | |
provider | 使用的存储提供商 | (s3, storj, gdrive 或 local) | |
uservoice-key | 前端的User Voice密钥 | USERVOICE_KEY | |
aws-access-key | AWS访问密钥 | AWS_ACCESS_KEY | |
aws-secret-key | AWS秘密密钥 | AWS_SECRET_KEY | |
bucket | AWS存储桶 | BUCKET | |
s3-endpoint | 自定义S3端点 | S3_ENDPOINT | |
s3-region | S3存储桶的区域 | eu-west-1 | S3_REGION |
s3-no-multipart | 禁用S3分段上传 | false | S3_NO_MULTIPART |
s3-path-style | 强制使用路径风格URL,Minio需要 | false | S3_PATH_STYLE |
storj-access | 项目的访问权限 | STORJ_ACCESS | |
storj-bucket | 项目中使用的存储桶 | STORJ_BUCKET | |
basedir | 本地/gdrive提供商的存储路径 | BASEDIR | |
gdrive-client-json-filepath | gdrive提供商的oauth客户端json配置路径 | GDRIVE_CLIENT_JSON_FILEPATH | |
gdrive-local-config-path | gdrive提供商存储本地transfer.sh配置缓存的路径 | GDRIVE_LOCAL_CONFIG_PATH | |
gdrive-chunk-size | gdrive上传的分块大小(MB),必须小于可用内存(8 MB) | GDRIVE_CHUNK_SIZE | |
lets-encrypt-hosts | 用于Let's Encrypt证书的主机(逗号分隔) | HOSTS | |
log | 日志文件路径 | LOG | |
cors-domains | CORS域名列表,以逗号分隔,设置此项启用CORS | CORS_DOMAINS | |
clamav-host | clamav功能的主机 | CLAMAV_HOST | |
perform-clamav-prescan | 通过clamav功能对每次上传进行预扫描(clamav-host必须是本地clamd unix套接字) | PERFORM_CLAMAV_PRESCAN | |
rate-limit | 每分钟请求数 | RATE_LIMIT | |
max-upload-size | 最大上传大小(KB) | MAX_UPLOAD_SIZE | |
purge-days | 自动清除上传文件的天数 | PURGE_DAYS | |
purge-interval | 运行自动清除的间隔小时数(不适用于S3和Storj) | PURGE_INTERVAL | |
random-token-length | 上传路径随机令牌的长度(删除路径长度为两倍) | 6 | RANDOM_TOKEN_LENGTH |
如果你想使用Let's Encrypt证书的TLS,请将lets-encrypt-hosts设置为你的域名,将tls-listener设置为:443,并启用force-https。
如果你想使用自己的证书进行TLS,请将tls-listener设置为:443,启用force-https,并设置tls-cert-file和tls-private-key。
开发
已切换到GO111MODULE
go run main.go --provider=local --listener :8080 --temp-path=/tmp/ --basedir=/tmp/
构建
$ git clone git@github.com:dutchcoders/transfer.sh.git
$ cd transfer.sh
$ go build -o transfersh main.go
Docker
为了便于部署,我们创建了官方Docker容器。有两种变体,仅在运行进程的用户上有所不同。
默认变体将以root
身份运行:
docker run --publish 8080:8080 dutchcoders/transfer.sh:latest --provider local --basedir /tmp/
带有-noroot
后缀的变体将使用5000
作为UID和GID:
docker run --publish 8080:8080 dutchcoders/transfer.sh:latest-noroot --provider local --basedir /tmp/
构建容器
你也可以自己构建容器。这允许你选择使用的UID/GID,例如在使用NFS挂载时:
# 构建参数:
# * RUNAS:如果为空,容器将以root身份运行。
# 设置为任何值以启用UID/GID选择。
# * PUID:进程的UID。需要RUNAS != ""。默认为5000。
# * PGID:进程的GID。需要RUNAS != ""。默认为5000。
docker build -t transfer.sh-noroot --build-arg RUNAS=doesntmatter --build-arg PUID=1337 --build-arg PGID=1338 .
S3使用
要使用AWS S3存储桶,你只需指定以下选项:
- provider
--provider s3
- aws-access-key(通过标志或环境变量
AWS_ACCESS_KEY
) - aws-secret-key(通过标志或环境变量
AWS_SECRET_KEY
) - bucket(通过标志或环境变量
BUCKET
) - s3-region(通过标志或环境变量
S3_REGION
)
如果你指定了s3-region,就不需要设置端点URL,因为会自动使用正确的端点。
自定义S3提供商
要使用自定义的非AWS S3提供商,你需要指定由你的云提供商定义的端点。
Storj网络提供商
要使用Storj网络作为存储提供商,你需要指定以下标志:
- provider
--provider storj
- storj-access(通过标志或环境变量STORJ_ACCESS)
- storj-bucket(通过标志或环境变量STORJ_BUCKET)
创建存储桶和范围
你需要创建一个访问授权(或从uplink配置中复制)和一个存储桶作为准备。
要开始,登录你的账户并进入访问授权菜单,然后在右上角启动向导。 输入您选择的访问授权名称,点击下一步,并根据需要/偏好进行限制。 之后可以在命令行界面或浏览器中继续操作。接下来,您将被要求输入一个作为加密密钥的密码。 请务必将其保存在安全的地方。没有它,您将无法解密您的文件!
之后,您可以复制访问授权,然后开始启动transfer.sh终端。 建议将访问授权和存储桶名称作为环境变量提供,以增强安全性。
示例:
export STORJ_BUCKET=<存储桶名称>
export STORJ_ACCESS=<访问授权>
transfer.sh --provider storj
Google Drive 使用
要使用Google Drive,您需要指定以下选项:
- provider
- gdrive-client-json-filepath
- gdrive-local-config-path
- basedir
创建Gdrive客户端Json
您需要从console.cloud.google.com创建一个OAuth客户端ID,下载文件,并将其放置在安全的目录中。
使用示例
go run main.go --provider gdrive --basedir /tmp/ --gdrive-client-json-filepath /[凭证目录] --gdrive-local-config-path [保存配置的目录]
Shell函数
Bash、ash和zsh(多个文件作为zip归档上传)
将以下内容添加到.bashrc或.zshrc或其等效文件中
transfer() (if [ $# -eq 0 ]; then printf "未指定参数。\n用法:\n transfer <文件|目录>\n ... | transfer <文件名>\n">&2; return 1; fi; file_name=$(basename "$1"); if [ -t 0 ]; then file="$1"; if [ ! -e "$file" ]; then echo "$file: 没有此文件或目录">&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"; )
现在您可以使用transfer函数
$ transfer hello.txt
Bash和zsh(带删除URL、删除令牌输出和上传前提示)
将以下内容添加到.bashrc或.zshrc或其等效文件中
展开
transfer()
{
local file
declare -a file_array
file_array=("${@}")
if [[ "${file_array[@]}" == "" || "${1}" == "--help" || "${1}" == "-h" ]]
then
echo "${0} - 将任意文件上传到\"transfer.sh\"。"
echo ""
echo "用法: ${0} [选项] [<文件>]..."
echo ""
echo "选项:"
echo " -h, --help"
echo " 显示此消息"
echo ""
echo "示例:"
echo " 从当前工作目录上传单个文件:"
echo " ${0} \"image.img\""
echo ""
echo " 从当前工作目录上传多个文件:"
echo " ${0} \"image.img\" \"image2.img\""
echo ""
echo " 从不同目录上传文件:"
echo " ${0} \"/tmp/some_file\""
echo ""
echo " 上传当前工作目录的所有文件。注意网络服务器的速率限制!:"
echo " ${0} *"
echo ""
echo " 从当前工作目录上传单个文件并过滤出删除令牌和下载链接:"
echo " ${0} \"image.img\" | awk --field-separator=\": \" '/Delete token:/ { print \$2 } /Download link:/ { print \$2 }'"
echo ""
echo " 显示\"transfer.sh\"的帮助文本:"
echo " curl --request GET \"https://transfer.sh\""
return 0
else
for file in "${file_array[@]}"
do
if [[ ! -f "${file}" ]]
then
echo -e "\e[01;31m'${file}' 找不到或不是文件。\e[0m" >&2
return 1
fi
done
unset file
fi
local upload_files
local curl_output
local awk_output
du -c -k -L "${file_array[@]}" >&2
# 与"bash"兼容
if [[ "${ZSH_NAME}" == "zsh" ]]
then
read $'upload_files?\e[01;31m您确定要将以上文件('"${#file_array[@]}"$'个)上传到"transfer.sh"吗?(Y/n): \e[0m'
elif [[ "${BASH}" == *"bash"* ]]
then
read -p $'\e[01;31m您确定要将以上文件('"${#file_array[@]}"$'个)上传到"transfer.sh"吗?(Y/n): \e[0m' upload_files
fi
case "${upload_files:-y}" in
"y"|"Y")
# 为了进度条,为每个文件执行"curl"。
# 参数"--include"和"--form"将抑制进度条。
for file in "${file_array[@]}"
do
# 显示删除链接并在上传后从响应头中过滤出删除令牌。
# 重要的是要通过子shell将"curl"的"stdout"保存到变量中或重定向到另一个命令,
# 该命令只是重定向到"stdout",以便之后有一个合理的输出。
# 进度条重定向到"stderr",只有在"stdout"重定向到某处时才显示;
# 例如">/dev/null"、"tee /dev/null"或"| <some_command>"。
# 响应头重定向到"stdout",所以将"stdout"重定向到"/dev/null"没有意义。
# 将"curl"的"stderr"重定向到"stdout"("2>&1")将抑制进度条。
curl_output=$(curl --request PUT --progress-bar --dump-header - --upload-file "${file}" "https://transfer.sh/")
awk_output=$(awk \
'gsub("\r", "", $0) && tolower($1) ~ /x-url-delete/ \
{
delete_link=$2;
print "删除命令: curl --request DELETE " "\""delete_link"\"";
gsub(".*/", "", delete_link);
delete_token=delete_link;
print "删除令牌: " delete_token;
}
END{
print "下载链接: " $0;
}' <<< "${curl_output}")
# 通过"stdout"返回结果,"awk"出于某种原因不这样做。
echo -e "${awk_output}\n"
# 尽可能避免速率限制;nginx: 请求过多。
if (( ${#file_array[@]} > 4 ))
then
sleep 5
fi
done
;;
"n"|"N")
return 1
;;
*)
echo -e "\e[01;31m输入错误: '${upload_files}'。\e[0m" >&2
return 1
esac
}
######################################################################################################################################################################################################################################## 100.0% 删除命令: curl --request DELETE "https://transfer.sh/ljJc5I/image.img/nw7qaoiKUwCU" 删除令牌: nw7qaoiKUwCU 下载链接: https://transfer.sh/ljJc5I/image.img
$ transfer "image.img" | awk --field-separator=": " '/Delete token:/ { print $2 } /Download link:/ { print $2 }' 10240K image.img 10240K 总计 您确定要将以上文件(1个)上传到"transfer.sh"吗?(Y/n): ######################################################################################################################################################################################################################################## 100.0% tauN5dE3fWJe https://transfer.sh/MYkuqn/image.img
## 贡献
欢迎贡献。
## 创作者
**Remco Verhoef**
- <https://twitter.com/remco_verhoef>
- <https://twitter.com/dutchcoders>
**Uvis Grinfelds**
## 维护者
**Andrea Spacca**
**Stefan Benten**
## 版权和许可
代码和文档版权 2011-2018 Remco Verhoef。
代码和文档版权 2018-2020 Andrea Spacca。
代码和文档版权 2020年至今 Andrea Spacca 和 Stefan Benten。
代码基于[MIT许可证](LICENSE)发布。