Upload 10 files
Browse files- .gitattributes +2 -35
- .gitignore +4 -0
- Dockerfile +50 -0
- README.md +18 -10
- config.json +18 -0
- config.json.dist +18 -0
- docker-entrypoint.sh +31 -0
- go.mod +34 -0
- go.sum +89 -0
- main.go +260 -0
.gitattributes
CHANGED
|
@@ -1,35 +1,2 @@
|
|
| 1 |
-
|
| 2 |
-
*
|
| 3 |
-
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
-
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
-
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
-
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
-
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
-
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
-
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
-
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
-
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
-
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
-
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
-
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
-
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
-
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
-
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
-
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
-
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
-
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
-
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
-
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
-
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
-
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
-
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
-
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
-
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
-
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
-
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
-
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
-
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
-
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 33 |
-
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
-
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
-
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
| 1 |
+
# Auto detect text files and perform LF normalization
|
| 2 |
+
* text=auto
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.gitignore
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
/.idea
|
| 3 |
+
buiid.bat
|
| 4 |
+
main_linux
|
Dockerfile
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM golang:1.22-alpine AS builder
|
| 2 |
+
RUN go env -w GO111MODULE=auto \
|
| 3 |
+
&& go env -w CGO_ENABLED=0
|
| 4 |
+
# && go env -w GOPROXY=https://goproxy.cn,direct
|
| 5 |
+
|
| 6 |
+
WORKDIR /build
|
| 7 |
+
|
| 8 |
+
COPY ./ .
|
| 9 |
+
|
| 10 |
+
RUN set -ex \
|
| 11 |
+
&& cd /build \
|
| 12 |
+
&& go build -ldflags "-s -w -extldflags '-static'" -o gh-proxy
|
| 13 |
+
|
| 14 |
+
FROM alpine:latest
|
| 15 |
+
|
| 16 |
+
COPY docker-entrypoint.sh /docker-entrypoint.sh
|
| 17 |
+
|
| 18 |
+
RUN chmod +x /docker-entrypoint.sh && \
|
| 19 |
+
apk add --no-cache --update \
|
| 20 |
+
coreutils \
|
| 21 |
+
shadow \
|
| 22 |
+
su-exec \
|
| 23 |
+
tzdata && \
|
| 24 |
+
rm -rf /var/cache/apk/* && \
|
| 25 |
+
mkdir -p /app && \
|
| 26 |
+
mkdir -p /config && \
|
| 27 |
+
useradd -d /config -s /bin/sh abc && \
|
| 28 |
+
chown -R abc /config
|
| 29 |
+
|
| 30 |
+
ENV TZ="Asia/Shanghai"
|
| 31 |
+
ENV UID=99
|
| 32 |
+
ENV GID=100
|
| 33 |
+
ENV UMASK=002
|
| 34 |
+
ENV WHITE_LIST=""
|
| 35 |
+
ENV BLACK_LIST="\"example3\",\"example4\""
|
| 36 |
+
ENV ALLOW_PROXY_ALL="false"
|
| 37 |
+
ENV OTHER_WHITE_LIST=""
|
| 38 |
+
ENV OTHER_BLACK_LIST="\"example3\",\"example4\""
|
| 39 |
+
ENV HTTP_HOST=""
|
| 40 |
+
ENV HTTP_PORT="8080"
|
| 41 |
+
ENV SIZE_LIMIT="10737418240"
|
| 42 |
+
|
| 43 |
+
COPY --from=builder /build/gh-proxy /app/
|
| 44 |
+
COPY --from=builder /build/config.json.dist /app/
|
| 45 |
+
|
| 46 |
+
WORKDIR /app
|
| 47 |
+
|
| 48 |
+
VOLUME [ "/app" ]
|
| 49 |
+
|
| 50 |
+
ENTRYPOINT [ "/docker-entrypoint.sh" ]
|
README.md
CHANGED
|
@@ -1,12 +1,20 @@
|
|
| 1 |
-
--
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
---
|
| 11 |
|
| 12 |
-
|
|
|
|
| 1 |
+
# gh-proxy-go
|
| 2 |
+
|
| 3 |
+
这是 [gh-proxy](https://github.com/hunshcn/gh-proxy) 的 Go 语言版本。
|
| 4 |
+
|
| 5 |
+
## 部署详情
|
| 6 |
+
|
| 7 |
+
[github.moeyy.xyz](https://github.moeyy.xyz/) 正在使用 **gh-proxy-go**,托管在 [BuyVM](https://buyvm.net/) 每月 3.5 美元的 1 核 1G 内存、10Gbps 带宽服务器上。
|
| 8 |
+
|
| 9 |
+
### 服务器概况:
|
| 10 |
+
|
| 11 |
+
- **日流量处理**:约 3TB
|
| 12 |
+
- **CPU 平均使用率**:20%
|
| 13 |
+
- **带宽平均占用**:400Mbps
|
| 14 |
+
|
| 15 |
+

|
| 16 |
+

|
| 17 |
+
|
| 18 |
---
|
| 19 |
|
| 20 |
+
如有问题或改进建议,欢迎提交 issue 或 PR!
|
config.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"host": "0.0.0.0",
|
| 3 |
+
"port": 8080,
|
| 4 |
+
"sizeLimit": 10737418240,
|
| 5 |
+
"whiteList": [
|
| 6 |
+
],
|
| 7 |
+
"blackList": [
|
| 8 |
+
"example3",
|
| 9 |
+
"example4"
|
| 10 |
+
],
|
| 11 |
+
"AllowProxyAll": false,
|
| 12 |
+
"otherWhiteList": [
|
| 13 |
+
],
|
| 14 |
+
"otherBlackList": [
|
| 15 |
+
"example3",
|
| 16 |
+
"example4"
|
| 17 |
+
]
|
| 18 |
+
}
|
config.json.dist
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"host": "%HTTP_HOST%",
|
| 3 |
+
"port": %HTTP_PORT%,
|
| 4 |
+
"sizeLimit": %SIZE_LIMIT%,
|
| 5 |
+
"whiteList": [
|
| 6 |
+
%WHITE_LIST%
|
| 7 |
+
],
|
| 8 |
+
"blackList": [
|
| 9 |
+
%BLACK_LIST%
|
| 10 |
+
],
|
| 11 |
+
"AllowProxyAll": %ALLOW_PROXY_ALL%,
|
| 12 |
+
"otherWhiteList": [
|
| 13 |
+
%OTHER_WHITE_LIST%
|
| 14 |
+
],
|
| 15 |
+
"otherBlackList": [
|
| 16 |
+
%OTHER_BLACK_LIST%
|
| 17 |
+
]
|
| 18 |
+
}
|
docker-entrypoint.sh
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/sh
|
| 2 |
+
|
| 3 |
+
USER=abc
|
| 4 |
+
|
| 5 |
+
echo "---Setup Timezone to ${TZ}---"
|
| 6 |
+
echo "${TZ}" > /etc/timezone
|
| 7 |
+
echo "---Checking if UID: ${UID} matches user---"
|
| 8 |
+
usermod -o -u ${UID} ${USER}
|
| 9 |
+
echo "---Checking if GID: ${GID} matches user---"
|
| 10 |
+
groupmod -o -g ${GID} ${USER} > /dev/null 2>&1 ||:
|
| 11 |
+
usermod -g ${GID} ${USER}
|
| 12 |
+
echo "---Setting umask to ${UMASK}---"
|
| 13 |
+
umask ${UMASK}
|
| 14 |
+
|
| 15 |
+
echo "---Taking ownership of data...---"
|
| 16 |
+
chown -R ${UID}:${GID} /app /data
|
| 17 |
+
chmod +x /app/gh-proxy
|
| 18 |
+
|
| 19 |
+
echo "make config"
|
| 20 |
+
cp /app/config.json.dist /app/config.json
|
| 21 |
+
sed -i "s|%WHITE_LIST%|$WHITE_LIST|g" /app/config.json
|
| 22 |
+
sed -i "s|%BLACK_LIST%|$BLACK_LIST|g" /app/config.json
|
| 23 |
+
sed -i "s|%ALLOW_PROXY_ALL%|$ALLOW_PROXY_ALL|g" /app/config.json
|
| 24 |
+
sed -i "s|%OTHER_WHITE_LIST%|$OTHER_WHITE_LIST|g" /app/config.json
|
| 25 |
+
sed -i "s|%OTHER_BLACK_LIST%|$OTHER_BLACK_LIST|g" /app/config.json
|
| 26 |
+
sed -i "s|%HTTP_HOST%|$HTTP_HOST|g" /app/config.json
|
| 27 |
+
sed -i "s|%HTTP_PORT%|$HTTP_PORT|g" /app/config.json
|
| 28 |
+
sed -i "s|%SIZE_LIMIT%|$SIZE_LIMIT|g" /app/config.json
|
| 29 |
+
|
| 30 |
+
echo "Starting..."
|
| 31 |
+
su-exec ${USER} /app/gh-proxy "$@"
|
go.mod
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
module gh-proxy-go
|
| 2 |
+
|
| 3 |
+
go 1.22.5
|
| 4 |
+
|
| 5 |
+
require github.com/gin-gonic/gin v1.10.0
|
| 6 |
+
|
| 7 |
+
require (
|
| 8 |
+
github.com/bytedance/sonic v1.11.6 // indirect
|
| 9 |
+
github.com/bytedance/sonic/loader v0.1.1 // indirect
|
| 10 |
+
github.com/cloudwego/base64x v0.1.4 // indirect
|
| 11 |
+
github.com/cloudwego/iasm v0.2.0 // indirect
|
| 12 |
+
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
| 13 |
+
github.com/gin-contrib/sse v0.1.0 // indirect
|
| 14 |
+
github.com/go-playground/locales v0.14.1 // indirect
|
| 15 |
+
github.com/go-playground/universal-translator v0.18.1 // indirect
|
| 16 |
+
github.com/go-playground/validator/v10 v10.20.0 // indirect
|
| 17 |
+
github.com/goccy/go-json v0.10.2 // indirect
|
| 18 |
+
github.com/json-iterator/go v1.1.12 // indirect
|
| 19 |
+
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
| 20 |
+
github.com/leodido/go-urn v1.4.0 // indirect
|
| 21 |
+
github.com/mattn/go-isatty v0.0.20 // indirect
|
| 22 |
+
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
| 23 |
+
github.com/modern-go/reflect2 v1.0.2 // indirect
|
| 24 |
+
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
| 25 |
+
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
| 26 |
+
github.com/ugorji/go/codec v1.2.12 // indirect
|
| 27 |
+
golang.org/x/arch v0.8.0 // indirect
|
| 28 |
+
golang.org/x/crypto v0.23.0 // indirect
|
| 29 |
+
golang.org/x/net v0.25.0 // indirect
|
| 30 |
+
golang.org/x/sys v0.20.0 // indirect
|
| 31 |
+
golang.org/x/text v0.15.0 // indirect
|
| 32 |
+
google.golang.org/protobuf v1.34.1 // indirect
|
| 33 |
+
gopkg.in/yaml.v3 v3.0.1 // indirect
|
| 34 |
+
)
|
go.sum
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0=
|
| 2 |
+
github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
|
| 3 |
+
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
|
| 4 |
+
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
| 5 |
+
github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
|
| 6 |
+
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
| 7 |
+
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
|
| 8 |
+
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
| 9 |
+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
| 10 |
+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
| 11 |
+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
| 12 |
+
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
|
| 13 |
+
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
|
| 14 |
+
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
| 15 |
+
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
| 16 |
+
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
|
| 17 |
+
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
| 18 |
+
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
| 19 |
+
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
| 20 |
+
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
| 21 |
+
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
| 22 |
+
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
| 23 |
+
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
| 24 |
+
github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8=
|
| 25 |
+
github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
| 26 |
+
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
| 27 |
+
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
| 28 |
+
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
| 29 |
+
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
| 30 |
+
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
| 31 |
+
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
| 32 |
+
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
| 33 |
+
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
| 34 |
+
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
|
| 35 |
+
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
| 36 |
+
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
| 37 |
+
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
| 38 |
+
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
| 39 |
+
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
| 40 |
+
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
| 41 |
+
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
| 42 |
+
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
| 43 |
+
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
| 44 |
+
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
| 45 |
+
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
| 46 |
+
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
| 47 |
+
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
| 48 |
+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
| 49 |
+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
| 50 |
+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
| 51 |
+
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
| 52 |
+
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
| 53 |
+
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
| 54 |
+
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
| 55 |
+
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
| 56 |
+
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
| 57 |
+
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
| 58 |
+
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
| 59 |
+
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
| 60 |
+
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
| 61 |
+
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
| 62 |
+
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
| 63 |
+
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
| 64 |
+
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
|
| 65 |
+
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
| 66 |
+
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
| 67 |
+
golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
|
| 68 |
+
golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
| 69 |
+
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
|
| 70 |
+
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
| 71 |
+
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
|
| 72 |
+
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
| 73 |
+
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
| 74 |
+
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
| 75 |
+
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
| 76 |
+
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
| 77 |
+
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
|
| 78 |
+
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
| 79 |
+
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
| 80 |
+
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
| 81 |
+
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
|
| 82 |
+
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
| 83 |
+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
| 84 |
+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
| 85 |
+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
| 86 |
+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
| 87 |
+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
| 88 |
+
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
| 89 |
+
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
main.go
ADDED
|
@@ -0,0 +1,260 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package main
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"embed"
|
| 5 |
+
"encoding/json"
|
| 6 |
+
"fmt"
|
| 7 |
+
"github.com/gin-gonic/gin"
|
| 8 |
+
"io"
|
| 9 |
+
"io/fs"
|
| 10 |
+
"net"
|
| 11 |
+
"net/http"
|
| 12 |
+
"os"
|
| 13 |
+
"regexp"
|
| 14 |
+
"strconv"
|
| 15 |
+
"strings"
|
| 16 |
+
"sync"
|
| 17 |
+
"time"
|
| 18 |
+
)
|
| 19 |
+
|
| 20 |
+
const (
|
| 21 |
+
sizeLimit int64 = 1024 * 1024 * 1024 * 10 // 允许的文件大小,默认10GB
|
| 22 |
+
host = "0.0.0.0" // 监听地址
|
| 23 |
+
port = 8080 // 监听端口
|
| 24 |
+
)
|
| 25 |
+
|
| 26 |
+
//go:embed public/*
|
| 27 |
+
var public embed.FS
|
| 28 |
+
|
| 29 |
+
var (
|
| 30 |
+
exps = []*regexp.Regexp{
|
| 31 |
+
regexp.MustCompile(`^(?:https?://)?github\.com/([^/]+)/([^/]+)/(?:releases|archive)/.*$`),
|
| 32 |
+
regexp.MustCompile(`^(?:https?://)?github\.com/([^/]+)/([^/]+)/(?:blob|raw)/.*$`),
|
| 33 |
+
regexp.MustCompile(`^(?:https?://)?github\.com/([^/]+)/([^/]+)/(?:info|git-).*$`),
|
| 34 |
+
regexp.MustCompile(`^(?:https?://)?raw\.github(?:usercontent|)\.com/([^/]+)/([^/]+)/.+?/.+$`),
|
| 35 |
+
regexp.MustCompile(`^(?:https?://)?gist\.github\.com/([^/]+)/.+?/.+$`),
|
| 36 |
+
}
|
| 37 |
+
httpClient *http.Client
|
| 38 |
+
config *Config
|
| 39 |
+
configLock sync.RWMutex
|
| 40 |
+
)
|
| 41 |
+
|
| 42 |
+
type Config struct {
|
| 43 |
+
Host string `json:"host"`
|
| 44 |
+
Port int64 `json:"port"`
|
| 45 |
+
SizeLimit int64 `json:"sizeLimit"`
|
| 46 |
+
WhiteList []string `json:"whiteList"`
|
| 47 |
+
BlackList []string `json:"blackList"`
|
| 48 |
+
AllowProxyAll bool `json:"allowProxyAll"` // 是否允许代理非github的其他地址
|
| 49 |
+
OtherWhiteList []string `json:"otherWhiteList"`
|
| 50 |
+
OtherBlackList []string `json:"otherBlackList"`
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
func main() {
|
| 54 |
+
gin.SetMode(gin.ReleaseMode)
|
| 55 |
+
router := gin.Default()
|
| 56 |
+
|
| 57 |
+
httpClient = &http.Client{
|
| 58 |
+
Transport: &http.Transport{
|
| 59 |
+
DialContext: (&net.Dialer{
|
| 60 |
+
Timeout: 30 * time.Second,
|
| 61 |
+
KeepAlive: 30 * time.Second,
|
| 62 |
+
}).DialContext,
|
| 63 |
+
MaxIdleConns: 1000,
|
| 64 |
+
MaxIdleConnsPerHost: 1000,
|
| 65 |
+
IdleConnTimeout: 90 * time.Second,
|
| 66 |
+
TLSHandshakeTimeout: 10 * time.Second,
|
| 67 |
+
ExpectContinueTimeout: 1 * time.Second,
|
| 68 |
+
ResponseHeaderTimeout: 300 * time.Second,
|
| 69 |
+
},
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
loadConfig()
|
| 73 |
+
go func() {
|
| 74 |
+
for {
|
| 75 |
+
time.Sleep(10 * time.Minute)
|
| 76 |
+
loadConfig()
|
| 77 |
+
}
|
| 78 |
+
}()
|
| 79 |
+
// if config.Host==""{
|
| 80 |
+
// config.Host=host
|
| 81 |
+
// }
|
| 82 |
+
if config.Port == 0 {
|
| 83 |
+
config.Port = port
|
| 84 |
+
}
|
| 85 |
+
if config.SizeLimit <= 0 {
|
| 86 |
+
config.SizeLimit = sizeLimit
|
| 87 |
+
}
|
| 88 |
+
// 修改静态文件服务方式
|
| 89 |
+
subFS, err := fs.Sub(public, "public")
|
| 90 |
+
if err != nil {
|
| 91 |
+
panic(fmt.Sprintf("无法创建子文件系统: %v", err))
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
// 使用 StaticFS 提供静态文件
|
| 95 |
+
router.StaticFS("/", http.FS(subFS))
|
| 96 |
+
// router.StaticFile("/", "./public/index.html")
|
| 97 |
+
// router.StaticFile("/favicon.ico", "./public/favicon.ico")
|
| 98 |
+
// router.StaticFile("/logo.png", "./public/logo.png")
|
| 99 |
+
router.NoRoute(handler)
|
| 100 |
+
fmt.Printf("starting http server on %s:%d \n", config.Host, config.Port)
|
| 101 |
+
err = router.Run(fmt.Sprintf("%s:%d", config.Host, config.Port))
|
| 102 |
+
if err != nil {
|
| 103 |
+
fmt.Printf("Error starting server: %v\n", err)
|
| 104 |
+
}
|
| 105 |
+
}
|
| 106 |
+
|
| 107 |
+
func handler(c *gin.Context) {
|
| 108 |
+
rawPath := strings.TrimPrefix(c.Request.URL.RequestURI(), "/")
|
| 109 |
+
|
| 110 |
+
for strings.HasPrefix(rawPath, "/") {
|
| 111 |
+
rawPath = strings.TrimPrefix(rawPath, "/")
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
if !strings.HasPrefix(rawPath, "http") {
|
| 115 |
+
// c.String(http.StatusForbidden, "Invalid input.")
|
| 116 |
+
// return
|
| 117 |
+
rawPath = fmt.Sprintf("https://%s", rawPath)
|
| 118 |
+
}
|
| 119 |
+
|
| 120 |
+
matches := checkURL(rawPath)
|
| 121 |
+
if matches != nil {
|
| 122 |
+
if len(config.WhiteList) > 0 && !checkList(matches, config.WhiteList) {
|
| 123 |
+
c.String(http.StatusForbidden, "Forbidden by white list.")
|
| 124 |
+
return
|
| 125 |
+
}
|
| 126 |
+
if len(config.BlackList) > 0 && checkList(matches, config.BlackList) {
|
| 127 |
+
c.String(http.StatusForbidden, "Forbidden by black list.")
|
| 128 |
+
return
|
| 129 |
+
}
|
| 130 |
+
} else {
|
| 131 |
+
if !config.AllowProxyAll {
|
| 132 |
+
c.String(http.StatusForbidden, "Invalid input.")
|
| 133 |
+
return
|
| 134 |
+
}
|
| 135 |
+
if len(config.OtherWhiteList) > 0 && !checkOhterList(rawPath, config.OtherWhiteList) {
|
| 136 |
+
c.String(http.StatusForbidden, "Forbidden by white list.")
|
| 137 |
+
return
|
| 138 |
+
}
|
| 139 |
+
if len(config.OtherBlackList) > 0 && checkOhterList(rawPath, config.OtherBlackList) {
|
| 140 |
+
c.String(http.StatusForbidden, "Forbidden by black list.")
|
| 141 |
+
return
|
| 142 |
+
}
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
+
if exps[1].MatchString(rawPath) {
|
| 146 |
+
rawPath = strings.Replace(rawPath, "/blob/", "/raw/", 1)
|
| 147 |
+
}
|
| 148 |
+
|
| 149 |
+
proxy(c, rawPath)
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
+
func proxy(c *gin.Context, u string) {
|
| 153 |
+
req, err := http.NewRequest(c.Request.Method, u, c.Request.Body)
|
| 154 |
+
if err != nil {
|
| 155 |
+
c.String(http.StatusInternalServerError, fmt.Sprintf("server error %v", err))
|
| 156 |
+
return
|
| 157 |
+
}
|
| 158 |
+
|
| 159 |
+
for key, values := range c.Request.Header {
|
| 160 |
+
for _, value := range values {
|
| 161 |
+
req.Header.Add(key, value)
|
| 162 |
+
}
|
| 163 |
+
}
|
| 164 |
+
req.Header.Del("Host")
|
| 165 |
+
|
| 166 |
+
resp, err := httpClient.Do(req)
|
| 167 |
+
if err != nil {
|
| 168 |
+
c.String(http.StatusInternalServerError, fmt.Sprintf("server error %v", err))
|
| 169 |
+
return
|
| 170 |
+
}
|
| 171 |
+
defer func(Body io.ReadCloser) {
|
| 172 |
+
err := Body.Close()
|
| 173 |
+
if err != nil {
|
| 174 |
+
|
| 175 |
+
}
|
| 176 |
+
}(resp.Body)
|
| 177 |
+
|
| 178 |
+
if contentLength, ok := resp.Header["Content-Length"]; ok {
|
| 179 |
+
if size, err := strconv.ParseInt(contentLength[0], 10, 64); err == nil && size > config.SizeLimit {
|
| 180 |
+
c.String(http.StatusRequestEntityTooLarge, "File too large.")
|
| 181 |
+
return
|
| 182 |
+
}
|
| 183 |
+
}
|
| 184 |
+
|
| 185 |
+
resp.Header.Del("Content-Security-Policy")
|
| 186 |
+
resp.Header.Del("Referrer-Policy")
|
| 187 |
+
resp.Header.Del("Strict-Transport-Security")
|
| 188 |
+
|
| 189 |
+
for key, values := range resp.Header {
|
| 190 |
+
for _, value := range values {
|
| 191 |
+
c.Header(key, value)
|
| 192 |
+
}
|
| 193 |
+
}
|
| 194 |
+
|
| 195 |
+
if location := resp.Header.Get("Location"); location != "" {
|
| 196 |
+
if checkURL(location) != nil {
|
| 197 |
+
c.Header("Location", "/"+location)
|
| 198 |
+
} else {
|
| 199 |
+
proxy(c, location)
|
| 200 |
+
return
|
| 201 |
+
}
|
| 202 |
+
}
|
| 203 |
+
|
| 204 |
+
c.Status(resp.StatusCode)
|
| 205 |
+
if _, err := io.Copy(c.Writer, resp.Body); err != nil {
|
| 206 |
+
return
|
| 207 |
+
}
|
| 208 |
+
}
|
| 209 |
+
|
| 210 |
+
func loadConfig() {
|
| 211 |
+
file, err := os.Open("config.json")
|
| 212 |
+
if err != nil {
|
| 213 |
+
fmt.Printf("Error loading config: %v\n", err)
|
| 214 |
+
return
|
| 215 |
+
}
|
| 216 |
+
defer func(file *os.File) {
|
| 217 |
+
err := file.Close()
|
| 218 |
+
if err != nil {
|
| 219 |
+
|
| 220 |
+
}
|
| 221 |
+
}(file)
|
| 222 |
+
|
| 223 |
+
var newConfig Config
|
| 224 |
+
decoder := json.NewDecoder(file)
|
| 225 |
+
if err := decoder.Decode(&newConfig); err != nil {
|
| 226 |
+
fmt.Printf("Error decoding config: %v\n", err)
|
| 227 |
+
return
|
| 228 |
+
}
|
| 229 |
+
|
| 230 |
+
configLock.Lock()
|
| 231 |
+
config = &newConfig
|
| 232 |
+
configLock.Unlock()
|
| 233 |
+
}
|
| 234 |
+
|
| 235 |
+
func checkURL(u string) []string {
|
| 236 |
+
for _, exp := range exps {
|
| 237 |
+
if matches := exp.FindStringSubmatch(u); matches != nil {
|
| 238 |
+
return matches[1:]
|
| 239 |
+
}
|
| 240 |
+
}
|
| 241 |
+
return nil
|
| 242 |
+
}
|
| 243 |
+
|
| 244 |
+
func checkList(matches, list []string) bool {
|
| 245 |
+
for _, item := range list {
|
| 246 |
+
if strings.HasPrefix(matches[0], item) {
|
| 247 |
+
return true
|
| 248 |
+
}
|
| 249 |
+
}
|
| 250 |
+
return false
|
| 251 |
+
}
|
| 252 |
+
|
| 253 |
+
func checkOhterList(url string, list []string) bool {
|
| 254 |
+
for _, item := range list {
|
| 255 |
+
if strings.Contains(url, item) {
|
| 256 |
+
return true
|
| 257 |
+
}
|
| 258 |
+
}
|
| 259 |
+
return false
|
| 260 |
+
}
|