From b83c2424160a6a0f03254c6f256f3d03f97e79b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=8C=E8=A6=8B=20=E7=81=AF=E8=8A=B1?= <172008506+satomitoka@users.noreply.github.com> Date: Thu, 10 Oct 2024 20:06:08 +0800 Subject: [PATCH 001/395] Update go.mod --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index bbfa29e..93e23f4 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module ghproxy +module github.com/satomitoka/ghproxy go 1.23.2 From 1fd1e3bc2a0bb26111eb6ae3e0ccf4391030efa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=8C=E8=A6=8B=20=E7=81=AF=E8=8A=B1?= <172008506+satomitoka@users.noreply.github.com> Date: Thu, 10 Oct 2024 20:07:44 +0800 Subject: [PATCH 002/395] Update main.go --- main.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/main.go b/main.go index 38bc5c6..074c44c 100644 --- a/main.go +++ b/main.go @@ -6,10 +6,10 @@ import ( "log" "net/http" - "ghproxy/auth" - "ghproxy/config" - "ghproxy/logger" - "ghproxy/proxy" + "github.com/satomitoka/ghproxy/auth" + "github.com/satomitoka/ghproxy/config" + "github.com/satomitoka/ghproxy/logger" + "github.com/satomitoka/ghproxy/proxy" "github.com/gin-gonic/gin" ) From 00538f3d91b310916a7a51251caa9b89f36650d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=8C=E8=A6=8B=20=E7=81=AF=E8=8A=B1?= <172008506+satomitoka@users.noreply.github.com> Date: Thu, 10 Oct 2024 20:08:02 +0800 Subject: [PATCH 003/395] Update auth.go --- auth/auth.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/auth/auth.go b/auth/auth.go index 4a8a7b0..f92eab7 100644 --- a/auth/auth.go +++ b/auth/auth.go @@ -1,8 +1,8 @@ package auth import ( - "ghproxy/config" - "ghproxy/logger" + "github.com/satomitoka/ghproxy/config" + "github.com/satomitoka/ghproxy/logger" "github.com/gin-gonic/gin" ) From 4155b9cf4f6c2c71fe3a7a5060e094d9ccd62527 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=8C=E8=A6=8B=20=E7=81=AF=E8=8A=B1?= <172008506+satomitoka@users.noreply.github.com> Date: Thu, 10 Oct 2024 20:08:21 +0800 Subject: [PATCH 004/395] Update blacklist.go --- auth/blacklist.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auth/blacklist.go b/auth/blacklist.go index 830537f..88de8eb 100644 --- a/auth/blacklist.go +++ b/auth/blacklist.go @@ -2,7 +2,7 @@ package auth import ( "encoding/json" - "ghproxy/config" + "github.com/satomitoka/ghproxy/config" "os" ) From f4cb77a72ea6f7fa808212bc229ad67b0fa8217c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=8C=E8=A6=8B=20=E7=81=AF=E8=8A=B1?= <172008506+satomitoka@users.noreply.github.com> Date: Thu, 10 Oct 2024 20:08:33 +0800 Subject: [PATCH 005/395] Update whitelist.go --- auth/whitelist.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auth/whitelist.go b/auth/whitelist.go index 326b3aa..1193bfe 100644 --- a/auth/whitelist.go +++ b/auth/whitelist.go @@ -2,7 +2,7 @@ package auth import ( "encoding/json" - "ghproxy/config" + "github.com/satomitoka/ghproxy/config" "os" ) From dd9a0c8adb25cf03908a4bdd07589689da1a623a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=8C=E8=A6=8B=20=E7=81=AF=E8=8A=B1?= <172008506+satomitoka@users.noreply.github.com> Date: Thu, 10 Oct 2024 20:09:16 +0800 Subject: [PATCH 006/395] Update proxy.go --- proxy/proxy.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proxy/proxy.go b/proxy/proxy.go index d830103..00e7be5 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -9,9 +9,9 @@ import ( "strconv" "strings" - "ghproxy/auth" - "ghproxy/config" - "ghproxy/logger" + "github.com/satomitoka/ghproxy/auth" + "github.com/satomitoka/ghproxy/config" + "github.com/satomitoka/ghproxy/logger" "github.com/gin-gonic/gin" "github.com/imroc/req/v3" From 1b5b34d2656eee7a699c14445d5402255e109bb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=8C=E8=A6=8B=20=E7=81=AF=E8=8A=B1?= <172008506+satomitoka@users.noreply.github.com> Date: Fri, 11 Oct 2024 00:14:39 +0800 Subject: [PATCH 007/395] Update build-dev.yml --- .github/workflows/build-dev.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/build-dev.yml b/.github/workflows/build-dev.yml index 8f8de42..0dac3d8 100644 --- a/.github/workflows/build-dev.yml +++ b/.github/workflows/build-dev.yml @@ -17,7 +17,6 @@ jobs: goarch: [amd64, arm64] env: OUTPUT_BINARY: ghproxy - #OUTPUT_ARCHIVE: ghproxy.tar.gz GO_VERSION: 1.23.2 steps: @@ -35,7 +34,7 @@ jobs: go-version: ${{ env.GO_VERSION }} - name: Build run: | - CGO_ENABLED=0 go build -o ${{ env.OUTPUT_BINARY }}-${{matrix.goos}}-${{matrix.goarch}} ./main.go + CGO_ENABLED=0 go build -ldflags="-s -w" -o ${{ env.OUTPUT_BINARY }}-${{matrix.goos}}-${{matrix.goarch}} ./main.go - name: Package run: | tar -czvf ${{ env.OUTPUT_BINARY }}-${{matrix.goos}}-${{matrix.goarch}}.tar.gz ./${{ env.OUTPUT_BINARY }}-${{matrix.goos}}-${{matrix.goarch}} From 575e36ef903040cbb6564375611e6da6d89bd859 Mon Sep 17 00:00:00 2001 From: WJQSERVER Date: Thu, 24 Oct 2024 21:50:38 +0800 Subject: [PATCH 008/395] 24w19d --- .github/workflows/build-nocache.yml | 51 ++++++++++++++ CHANGELOG.md | 7 ++ caddyfile/nocache/Caddyfile | 99 ++++++++++++++++++++++++++++ docker/dockerfile/nocache/Dockerfile | 49 ++++++++++++++ docker/dockerfile/nocache/init.sh | 27 ++++++++ logger/logger.go | 4 +- proxy/proxy.go | 38 +++++------ 7 files changed, 252 insertions(+), 23 deletions(-) create mode 100644 .github/workflows/build-nocache.yml create mode 100644 caddyfile/nocache/Caddyfile create mode 100644 docker/dockerfile/nocache/Dockerfile create mode 100644 docker/dockerfile/nocache/init.sh diff --git a/.github/workflows/build-nocache.yml b/.github/workflows/build-nocache.yml new file mode 100644 index 0000000..8f84886 --- /dev/null +++ b/.github/workflows/build-nocache.yml @@ -0,0 +1,51 @@ +name: Build NoCache Docker Image + +on: + workflow_dispatch: + push: + branches: + - 'main' + paths: + - 'VERSION' + +jobs: + docker: + runs-on: ubuntu-latest + env: + IMAGE_NAME: wjqserver/ghproxy # 定义镜像名称变量 + DOCKERFILE: docker/dockerfile/nocache/Dockerfile # 定义 Dockerfile 路径变量 + + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Load VERSION + run: | + if [ -f VERSION ]; then + echo "VERSION=$(cat VERSION)" >> $GITHUB_ENV + else + echo "VERSION file not found!" && exit 1 + fi + - name: Wait for Compile + run: sleep 300s + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: 构建镜像 + uses: docker/build-push-action@v6 + with: + file: ./${{ env.DOCKERFILE }} + platforms: linux/amd64,linux/arm64 + push: true + tags: | + ${{ env.IMAGE_NAME }}:${{ env.VERSION }}-nocache + ${{ env.IMAGE_NAME }}:nocache diff --git a/CHANGELOG.md b/CHANGELOG.md index d3e2e96..22d7583 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # 更新日志 +24w19d +--- +- PRE-RELEASE: 此版本是v1.6.1的预发布版本,请勿在生产环境中使用 +- ADD: 新增nocache版本,供由用户自行优化缓存策略 +- CHANGE: 优化`Proxy`核心模块内部结构,提升性能 +- REMOVE: 移除`Proxy`模块内部分无用`logInfo` + 24w19c --- - PRE-RELEASE: 此版本是v1.6.1的预发布版本,请勿在生产环境中使用 diff --git a/caddyfile/nocache/Caddyfile b/caddyfile/nocache/Caddyfile new file mode 100644 index 0000000..14f5bc5 --- /dev/null +++ b/caddyfile/nocache/Caddyfile @@ -0,0 +1,99 @@ +{ + debug + http_port 80 + https_port 443 + order cache before rewrite + cache { + cache_name GhProxyCache + } + log { + level INFO + output file /data/caddy/log/caddy.log { + roll_size 5MB + roll_keep 10 + } + } + server :80 { + protocols h1 h2 h2c + } +} + + +(log) { + log { + format transform `{request>headers>X-Forwarded-For>[0]:request>remote_ip} - {user_id} [{ts}] "{request>method} {request>uri} {request>proto}" {status} {size} "{request>headers>Referer>[0]}" "{request>headers>User-Agent>[0]}"` { + time_format "02/Jan/2006:15:04:05 -0700" + } + output file /data/caddy/log/{args[0]}/access.log { + roll_size 5MB + roll_keep 10 + roll_keep_for 24h + } + } +} + +(error_page) { + handle_errors { + rewrite * /{err.status_code}.html + root * /data/caddy/pages/errors + file_server + } +} + +(encode) { + encode { + zstd best + br 5 v2 + gzip 5 + minimum_length 256 + } +} + +(cache) { + cache { + allowed_http_verbs GET + stale {args[0]} + ttl {args[1]} + } +} + +(header_realip) { + header_up X-Real-IP {remote_host} + header_up X-Real-IP {http.request.header.CF-Connecting-IP} + header_up X-Forwarded-For {http.request.header.CF-Connecting-IP} + header_up X-Forwarded-Proto {http.request.header.CF-Visitor} +} + +(rate_limit) { + route /* { + rate_limit {remote.ip} {args[0]}r/m 10000 429 + } +} + +:80 { + reverse_proxy { + to h2c://127.0.0.1:8080 + import header_realip + } + import log ghproxy + import error_page + import encode + import rate_limit 60 + route / { + root /data/www + file_server + import cache 300s + } + route /favicon.ico { + root /data/www + file_server + import cache 300s + } + + route /api* { + rate_limit {remote.ip} 15r/m 10000 429 + import cache 300s + } +} + +import /data/caddy/config.d/* diff --git a/docker/dockerfile/nocache/Dockerfile b/docker/dockerfile/nocache/Dockerfile new file mode 100644 index 0000000..31680a6 --- /dev/null +++ b/docker/dockerfile/nocache/Dockerfile @@ -0,0 +1,49 @@ +FROM wjqserver/caddy:2.9.0-rc-alpine AS builder + +ARG USER=WJQSERVER-STUDIO +ARG REPO=ghproxy +ARG APPLICATION=ghproxy +ARG TARGETOS +ARG TARGETARCH +ARG TARGETPLATFORM + +# 创建文件夹 +RUN mkdir -p /data/www +RUN mkdir -p /data/${APPLICATION}/config +RUN mkdir -p /data/${APPLICATION}/log + +# 安装依赖 +RUN apk add --no-cache curl wget + +# 前端 +RUN wget -O /data/www/index.html https://raw.githubusercontent.com/${USER}/${REPO}/main/pages/index.html +RUN wget -O /data/www/favicon.ico https://raw.githubusercontent.com/${USER}/${REPO}/main/pages/favicon.ico + +# 后端 +RUN VERSION=$(curl -s https://raw.githubusercontent.com/${USER}/${REPO}/main/VERSION) && \ + wget -O /data/${APPLICATION}/${APPLICATION} https://github.com/${USER}/${REPO}/releases/download/$VERSION/${APPLICATION}-${TARGETOS}-${TARGETARCH} +RUN wget -O /usr/local/bin/init.sh https://raw.githubusercontent.com/${USER}/${REPO}/main/docker/dockerfile/nocache/init.sh + +# 拉取配置 +RUN wget -O /data/caddy/Caddyfile https://raw.githubusercontent.com/${USER}/${REPO}/main/caddyfile/nocache/Caddyfile +RUN wget -O /data/${APPLICATION}/config.toml https://raw.githubusercontent.com/${USER}/${REPO}/main/config/config.toml +RUN wget -O /data/${APPLICATION}/blacklist.json https://raw.githubusercontent.com/${USER}/${REPO}/main/config/blacklist.json +RUN wget -O /data/${APPLICATION}/whitelist.json https://raw.githubusercontent.com/${USER}/${REPO}/main/config/whitelist.json + +# 权限 +RUN chmod +x /data/${APPLICATION}/${APPLICATION} +RUN chmod +x /usr/local/bin/init.sh + +FROM wjqserver/caddy:2.9.0-rc-alpine + +COPY --from=builder /data/www /data/www +COPY --from=builder /data/caddy /data/caddy +COPY --from=builder /data/${APPLICATION} /data/${APPLICATION} +COPY --from=builder /usr/local/bin/init.sh /usr/local/bin/init.sh + +# 权限 +RUN chmod +x /data/${APPLICATION}/${APPLICATION} +RUN chmod +x /usr/local/bin/init.sh + +CMD ["/usr/local/bin/init.sh"] + diff --git a/docker/dockerfile/nocache/init.sh b/docker/dockerfile/nocache/init.sh new file mode 100644 index 0000000..34d3477 --- /dev/null +++ b/docker/dockerfile/nocache/init.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +APPLICATION=ghproxy + +if [ ! -f /data/caddy/config/Caddyfile ]; then + cp /data/caddy/Caddyfile /data/caddy/config/Caddyfile +fi + +if [ ! -f /data/${APPLICATION}/config/blacklist.json ]; then + cp /data/${APPLICATION}/blacklist.json /data/${APPLICATION}/config/blacklist.json +fi + +if [ ! -f /data/${APPLICATION}/config/whitelist.json ]; then + cp /data/${APPLICATION}/whitelist.json /data/${APPLICATION}/config/whitelist.json +fi + +if [ ! -f /data/${APPLICATION}/config/config.toml ]; then + cp /data/${APPLICATION}/config.toml /data/${APPLICATION}/config/config.toml +fi + +/data/caddy/caddy run --config /data/caddy/config/Caddyfile > /data/${APPLICATION}/log/caddy.log 2>&1 & + +/data/${APPLICATION}/${APPLICATION} -cfg /data/${APPLICATION}/config/config.toml > /data/${APPLICATION}/log/run.log 2>&1 & + +while true; do + sleep 1 +done \ No newline at end of file diff --git a/logger/logger.go b/logger/logger.go index 81aa5a3..5eac8e8 100644 --- a/logger/logger.go +++ b/logger/logger.go @@ -22,7 +22,7 @@ var ( logFilePath = "/data/ghproxy/log/ghproxy.log" ) -// 初始化,接受日志文件路径作为参数 +// 初始化 func Init(logFilePath_input string, maxLogsize int) error { logFileMutex.Lock() defer logFileMutex.Unlock() @@ -121,7 +121,6 @@ func rotateLogFile(logFilePath string) error { } } - // 打开当前日志文件 logFile, err := os.Open(logFilePath) if err != nil { return fmt.Errorf("failed to open log file: %s, error: %w", logFilePath, err) @@ -168,7 +167,6 @@ func rotateLogFile(logFilePath string) error { return fmt.Errorf("failed to truncate log file: %s, error: %w", logFilePath, err) } - // 重新打开日志文件 logFile, err = os.OpenFile(logFilePath, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666) if err != nil { return fmt.Errorf("failed to reopen log file: %s, error: %w", logFilePath, err) diff --git a/proxy/proxy.go b/proxy/proxy.go index 12b157c..a511dca 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -94,10 +94,8 @@ func NoRouteHandler(cfg *config.Config) gin.HandlerFunc { switch { case exps[0].MatchString(rawPath), exps[1].MatchString(rawPath), exps[3].MatchString(rawPath), exps[4].MatchString(rawPath): - logInfo("%s Matched - USE proxy-chrome", rawPath) ProxyRequest(c, rawPath, cfg, "chrome") case exps[2].MatchString(rawPath): - logInfo("%s Matched - USE proxy-git", rawPath) ProxyRequest(c, rawPath, cfg, "git") default: c.String(http.StatusForbidden, "Invalid input.") @@ -106,7 +104,7 @@ func NoRouteHandler(cfg *config.Config) gin.HandlerFunc { } } -// 提取用户名和仓库名,格式为 handle///* +// 提取用户名和仓库名 func MatchUserRepo(rawPath string, cfg *config.Config, c *gin.Context, matches []string) (string, string) { var gistregex = regexp.MustCompile(`^(?:https?://)?gist\.github(?:usercontent|)\.com/([^/]+)/([^/]+)/.*`) var gistmatches []string @@ -115,16 +113,16 @@ func MatchUserRepo(rawPath string, cfg *config.Config, c *gin.Context, matches [ logInfo("Gist Matched > Username: %s, URL: %s", gistmatches[1], rawPath) return gistmatches[1], "" } - pathmatches := regexp.MustCompile(`^([^/]+)/([^/]+)/([^/]+)/.*`) - pathParts := pathmatches.FindStringSubmatch(matches[2]) - - if len(pathParts) < 4 { - logWarning("Invalid path: %s", rawPath) - c.String(http.StatusForbidden, "Invalid path; expected username/repo.") - return "", "" - } else { - return pathParts[2], pathParts[3] + // 定义路径匹配的正则表达式 + pathRegex := regexp.MustCompile(`^([^/]+)/([^/]+)/([^/]+)/.*`) + if pathMatches := pathRegex.FindStringSubmatch(matches[2]); len(pathMatches) >= 4 { + return pathMatches[2], pathMatches[3] } + + // 返回错误信息 + logWarning("Invalid path: %s", rawPath) + c.String(http.StatusForbidden, "Invalid path; expected username/repo.") + return "", "" } func ProxyRequest(c *gin.Context, u string, cfg *config.Config, mode string) { @@ -166,7 +164,7 @@ func createHTTPClient(mode string) *req.Client { client := req.C() switch mode { case "chrome": - client.SetUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36"). + client.SetUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36"). SetTLSFingerprintChrome(). ImpersonateChrome() case "git": @@ -175,7 +173,7 @@ func createHTTPClient(mode string) *req.Client { return client } -// readRequestBody 读取请求体 +// 读取请求体 func readRequestBody(c *gin.Context) ([]byte, error) { body, err := io.ReadAll(c.Request.Body) if err != nil { @@ -185,7 +183,7 @@ func readRequestBody(c *gin.Context) ([]byte, error) { return body, nil } -// setRequestHeaders 设置请求头 +// 设置请求头 func setRequestHeaders(c *gin.Context, req *req.Request) { for key, values := range c.Request.Header { for _, value := range values { @@ -194,7 +192,7 @@ func setRequestHeaders(c *gin.Context, req *req.Request) { } } -// copyResponseBody 复制响应体到客户端 +// 复制响应体 func copyResponseBody(c *gin.Context, respBody io.Reader) error { _, err := io.Copy(c.Writer, respBody) return err @@ -242,7 +240,7 @@ func CopyResponseHeaders(resp *req.Response, c *gin.Context, cfg *config.Config) setDefaultHeaders(c) } -// removeHeaders 移除指定的响应头 +// 移除指定响应头 func removeHeaders(resp *req.Response) { headersToRemove := map[string]struct{}{ "Content-Security-Policy": {}, @@ -255,7 +253,7 @@ func removeHeaders(resp *req.Response) { } } -// copyHeaders 复制响应头到 Gin 上下文 +// 复制响应头 func copyHeaders(resp *req.Response, c *gin.Context) { for key, values := range resp.Header { for _, value := range values { @@ -264,7 +262,7 @@ func copyHeaders(resp *req.Response, c *gin.Context) { } } -// setCORSHeaders 设置 CORS 相关的响应头 +// CORS配置 func setCORSHeaders(c *gin.Context, cfg *config.Config) { if cfg.CORS.Enabled { c.Header("Access-Control-Allow-Origin", "*") @@ -273,7 +271,7 @@ func setCORSHeaders(c *gin.Context, cfg *config.Config) { } } -// setDefaultHeaders 设置默认的响应头 +// 默认响应 func setDefaultHeaders(c *gin.Context) { c.Header("Age", "10") c.Header("Cache-Control", "max-age=300") From 8187464007ff758e59466a7813c09f94edd058b9 Mon Sep 17 00:00:00 2001 From: WJQSERVER Date: Thu, 24 Oct 2024 21:50:53 +0800 Subject: [PATCH 009/395] 24w19d --- DEV-VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEV-VERSION b/DEV-VERSION index f90e6c0..9cde107 100644 --- a/DEV-VERSION +++ b/DEV-VERSION @@ -1 +1 @@ -24w19c \ No newline at end of file +24w19d \ No newline at end of file From 2355447f972ad88feb3d8637c235cdcbe0cb9393 Mon Sep 17 00:00:00 2001 From: WJQSERVER Date: Thu, 24 Oct 2024 22:10:36 +0800 Subject: [PATCH 010/395] 24w19d --- caddyfile/dev/Caddyfile | 5 ++++- caddyfile/nocache/Caddyfile | 3 --- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/caddyfile/dev/Caddyfile b/caddyfile/dev/Caddyfile index aba4935..d625f29 100644 --- a/caddyfile/dev/Caddyfile +++ b/caddyfile/dev/Caddyfile @@ -12,7 +12,10 @@ roll_size 5MB roll_keep 10 } - } + } + servers :80 { + protocols h1 h2 h2c + } } (log) { diff --git a/caddyfile/nocache/Caddyfile b/caddyfile/nocache/Caddyfile index 14f5bc5..4098acf 100644 --- a/caddyfile/nocache/Caddyfile +++ b/caddyfile/nocache/Caddyfile @@ -13,9 +13,6 @@ roll_keep 10 } } - server :80 { - protocols h1 h2 h2c - } } From 29046382a53c07126911605babb0e2fbf1b99f4e Mon Sep 17 00:00:00 2001 From: WJQSERVER Date: Thu, 24 Oct 2024 22:21:12 +0800 Subject: [PATCH 011/395] 24w19d --- caddyfile/dev/Caddyfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/caddyfile/dev/Caddyfile b/caddyfile/dev/Caddyfile index d625f29..b97746e 100644 --- a/caddyfile/dev/Caddyfile +++ b/caddyfile/dev/Caddyfile @@ -14,7 +14,7 @@ } } servers :80 { - protocols h1 h2 h2c + protocols h1 h2c } } From 57cd7e1ce719e9b66176759c5b0cd21bddaa86c0 Mon Sep 17 00:00:00 2001 From: WJQSERVER Date: Thu, 24 Oct 2024 22:30:41 +0800 Subject: [PATCH 012/395] 1.6.1 --- CHANGELOG.md | 10 ++++++++++ README.md | 4 ++-- VERSION | 2 +- caddyfile/dev/Caddyfile | 7 ++----- caddyfile/nocache/Caddyfile | 2 +- caddyfile/release/Caddyfile | 6 +++--- 6 files changed, 19 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 22d7583..361d8bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # 更新日志 +v1.6.1 +--- +- CHANGE: 根据社区建议,将`sizeLimit`由过去的以`byte`为单位,改为以`MB`为单位,以便于直观理解 +- ADD: 新增`nocache`版本,供由用户自行优化缓存策略 +- CHANGE: 优化`Proxy`核心模块内部结构,提升性能 +- REMOVE: 移除`Proxy`模块内部分无用`logInfo` +- FIX & ADD: 修复前端对gist的匹配问题,添加对`gist.githubusercontent.com`的前端转换支持 +- CHANGE: 改变部分前端匹配逻辑 +- CHANGE: 更新相关依赖库 + 24w19d --- - PRE-RELEASE: 此版本是v1.6.1的预发布版本,请勿在生产环境中使用 diff --git a/README.md b/README.md index f15824d..326794c 100644 --- a/README.md +++ b/README.md @@ -79,10 +79,10 @@ wget -O install.sh https://raw.githubusercontent.com/WJQSERVER-STUDIO/ghproxy/ma [server] host = "127.0.0.1" # 监听地址 port = 8080 # 监听端口 -sizeLimit = 131072000 # 125MB +sizeLimit = 125 # 125MB [pages] -enabled = true # 是否开启内置静态页面 +enabled = false # 是否开启内置静态页面(Docker版本请关闭此项) staticPath = "/data/www" # 静态页面文件路径 [log] diff --git a/VERSION b/VERSION index ce6a70b..2eda823 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.6.0 \ No newline at end of file +1.6.1 \ No newline at end of file diff --git a/caddyfile/dev/Caddyfile b/caddyfile/dev/Caddyfile index b97746e..212f40d 100644 --- a/caddyfile/dev/Caddyfile +++ b/caddyfile/dev/Caddyfile @@ -4,7 +4,7 @@ https_port 443 order cache before rewrite cache { - cache_name GhProxyCache + cache_name GHProxyCache } log { level INFO @@ -12,10 +12,7 @@ roll_size 5MB roll_keep 10 } - } - servers :80 { - protocols h1 h2c - } + } } (log) { diff --git a/caddyfile/nocache/Caddyfile b/caddyfile/nocache/Caddyfile index 4098acf..db1fe4b 100644 --- a/caddyfile/nocache/Caddyfile +++ b/caddyfile/nocache/Caddyfile @@ -4,7 +4,7 @@ https_port 443 order cache before rewrite cache { - cache_name GhProxyCache + cache_name GHProxyCache } log { level INFO diff --git a/caddyfile/release/Caddyfile b/caddyfile/release/Caddyfile index 03d51ff..9fc8120 100644 --- a/caddyfile/release/Caddyfile +++ b/caddyfile/release/Caddyfile @@ -4,15 +4,15 @@ https_port 443 order cache before rewrite cache { - cache_name GhProxyCache + cache_name GHProxyCache } log { level INFO output file /data/caddy/log/caddy.log { roll_size 5MB roll_keep 10 - } - } + } + } } (log) { From b1c8658a1c9be051a247440d147720405080e0b7 Mon Sep 17 00:00:00 2001 From: WJQSERVER Date: Fri, 25 Oct 2024 17:01:06 +0800 Subject: [PATCH 013/395] hotfix --- deploy/install.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/deploy/install.sh b/deploy/install.sh index e929f6f..07e8fcb 100644 --- a/deploy/install.sh +++ b/deploy/install.sh @@ -28,7 +28,7 @@ install() { } # 安装依赖包 -install curl wget -q sed +install curl wget sed # 查看当前架构是否为linux/amd64或linux/arm64 ARCH=$(uname -m) @@ -53,6 +53,7 @@ fi mkdir -p /root/data/ghproxy mkdir -p /root/data/ghproxy/config mkdir -p /root/data/ghproxy/log +mkdir -p /root/data/ghproxy/pages # 获取最新版本号 VERSION=$(curl -s https://raw.githubusercontent.com/WJQSERVER-STUDIO/ghproxy/main/VERSION) @@ -62,10 +63,15 @@ wget -q -O /root/data/ghproxy/VERSION https://raw.githubusercontent.com/WJQSERVE wget -q -O /root/data/ghproxy/ghproxy https://github.com/WJQSERVER-STUDIO/ghproxy/releases/download/$VERSION/ghproxy-linux-$ARCH chmod +x /root/data/ghproxy/ghproxy +# 下载pages +wget -q -O /root/data/ghproxy/pages/index.html https://raw.githubusercontent.com/WJQSERVER-STUDIO/ghproxy/main/pages/index.html +wget -q -O /root/data/ghproxy/pages/favicon.ico https://raw.githubusercontent.com/WJQSERVER-STUDIO/ghproxy/main/pages/favicon.ico + + # 下载配置文件 if [ -f /root/data/ghproxy/config/config.toml ]; then echo "配置文件已存在, 跳过下载" - echo "请检查配置文件是否正确,跨大版本升级时请注意配置文件兼容性" + echo "[WARNING] > 请检查配置文件是否正确,大版本升级时请注意配置文件兼容性" sleep 2 else wget -q -O /root/data/ghproxy/config/config.toml https://raw.githubusercontent.com/WJQSERVER-STUDIO/ghproxy/main/deploy/config.toml From f80782b80390ba2a8808b9ecb172be596f9e023b Mon Sep 17 00:00:00 2001 From: WJQSERVER Date: Fri, 25 Oct 2024 18:00:31 +0800 Subject: [PATCH 014/395] deploy shell update --- deploy/config.toml | 8 ++--- deploy/ghproxy.service | 4 +-- deploy/install-dev.sh | 71 ++++++++++++++++++++++++++++++++++-------- deploy/uninstall.sh | 16 +++++++++- 4 files changed, 79 insertions(+), 20 deletions(-) diff --git a/deploy/config.toml b/deploy/config.toml index 65b2fca..ad7ff2e 100644 --- a/deploy/config.toml +++ b/deploy/config.toml @@ -5,10 +5,10 @@ sizeLimit = 125 # MB [pages] enabled = true -staticDir = "/root/data/ghproxy/pages" +staticDir = "/usr/local/ghproxy/pages" [log] -logFilePath = "/root/data/ghproxy/log/ghproxy.log" +logFilePath = "/usr/local/ghproxy/log/ghproxy.log" maxLogSize = 5 # MB [cors] @@ -19,9 +19,9 @@ authToken = "token" enabled = false [blacklist] -blacklistFile = "/root/data/ghproxy/config/blacklist.json" +blacklistFile = "/usr/local/ghproxy/config/blacklist.json" enabled = false [whitelist] enabled = false -whitelistFile = "/root/data/ghproxy/config/whitelist.json" +whitelistFile = "/usr/local/ghproxy/config/whitelist.json" diff --git a/deploy/ghproxy.service b/deploy/ghproxy.service index b2a24a7..df85e32 100644 --- a/deploy/ghproxy.service +++ b/deploy/ghproxy.service @@ -3,8 +3,8 @@ Description=Github Proxy Service After=network.target [Service] -ExecStart=/bin/bash -c '/root/data/ghproxy/ghproxy -cfg /root/data/ghproxy/config/config.toml > /root/data/ghproxy/log/run.log 2>&1' -WorkingDirectory=/root/data/ghproxy +ExecStart=/bin/bash -c '/usr/local/ghproxy/ghproxy -cfg /usr/local/ghproxy/config/config.toml > /usr/local/ghproxy/log/run.log 2>&1' +WorkingDirectory=/usr/local/ghproxy Restart=always User=root Group=root diff --git a/deploy/install-dev.sh b/deploy/install-dev.sh index 50c18a8..1b66af6 100644 --- a/deploy/install-dev.sh +++ b/deploy/install-dev.sh @@ -1,4 +1,7 @@ # /bin/bash +# https://github.com/WJQSERVER-STUDIO/ghproxy + +ghproxy_dir="/usr/local/ghproxy" # install packages install() { @@ -27,6 +30,26 @@ install() { return 0 } +make_systemd_service() { + cat < /etc/systemd/system/ghproxy.service +[Unit] +Description=Github Proxy Service +After=network.target + +[Service] +ExecStart=/bin/bash -c '$ghproxy_dir/ghproxy -cfg $ghproxy_dir/config/config.toml > $ghproxy_dir/log/run.log 2>&1' +WorkingDirectory=$ghproxy_dir +Restart=always +User=root +Group=root + +[Install] +WantedBy=multi-user.target + +EOF + +} + # 安装依赖包 install curl wget sed @@ -44,44 +67,66 @@ elif [ "$ARCH" == "aarch64" ]; then ARCH="arm64" fi +# 获取监听端口 read -p "请输入程序监听的端口(默认8080): " PORT if [ -z "$PORT" ]; then PORT=8080 fi +# 本机监听/泛监听(127.0.0.1/0.0.0.0) +read -p "请键入程序监听的IP(默认127.0.0.1)(0.0.0.0为泛监听): " IP +if [ -z "$IP" ]; then + IP="127.0.0.1" +fi + +# 安装目录 +read -p "请输入安装目录(默认/usr/local/ghproxy): " ghproxy_dir +if [ -z "$ghproxy_dir" ]; then + ghproxy_dir="/usr/local/ghproxy" +fi + # 创建目录 -mkdir -p /root/data/ghproxy -mkdir -p /root/data/ghproxy/config -mkdir -p /root/data/ghproxy/log -mkdir -p /root/data/ghproxy/pages +mkdir -p ${ghproxy_dir} +mkdir -p ${ghproxy_dir}/config +mkdir -p ${ghproxy_dir}/log +mkdir -p ${ghproxy_dir}/pages # 获取最新版本号 VERSION=$(curl -s https://raw.githubusercontent.com/WJQSERVER-STUDIO/ghproxy/main/DEV-VERSION) -wget -q -O /root/data/ghproxy/VERSION https://raw.githubusercontent.com/WJQSERVER-STUDIO/ghproxy/main/DEV-VERSION +wget -q -O ${ghproxy_dir}/VERSION https://raw.githubusercontent.com/WJQSERVER-STUDIO/ghproxy/main/DEV-VERSION # 下载ghproxy -wget -q -O /root/data/ghproxy/ghproxy https://github.com/WJQSERVER-STUDIO/ghproxy/releases/download/$VERSION/ghproxy-linux-$ARCH -chmod +x /root/data/ghproxy/ghproxy +wget -q -O ${ghproxy_dir}/ghproxy https://github.com/WJQSERVER-STUDIO/ghproxy/releases/download/$VERSION/ghproxy-linux-$ARCH +chmod +x ${ghproxy_dir}/ghproxy # 下载pages -wget -q -O /root/data/ghproxy/pages/index.html https://raw.githubusercontent.com/WJQSERVER-STUDIO/ghproxy/main/pages/index.html -wget -q -O /root/data/ghproxy/pages/favicon.ico https://raw.githubusercontent.com/WJQSERVER-STUDIO/ghproxy/main/pages/favicon.ico +wget -q -O ${ghproxy_dir}/pages/index.html https://raw.githubusercontent.com/WJQSERVER-STUDIO/ghproxy/main/pages/index.html +wget -q -O ${ghproxy_dir}/pages/favicon.ico https://raw.githubusercontent.com/WJQSERVER-STUDIO/ghproxy/main/pages/favicon.ico # 下载配置文件 -if [ -f /root/data/ghproxy/config/config.toml ]; then +if [ -f ${ghproxy_dir}/config/config.toml ]; then echo "配置文件已存在, 跳过下载" echo "[WARNING] 请检查配置文件是否正确,DEV版本升级时请注意配置文件兼容性" sleep 2 else - wget -q -O /root/data/ghproxy/config/config.toml https://raw.githubusercontent.com/WJQSERVER-STUDIO/ghproxy/main/deploy/config.toml + wget -q -O ${ghproxy_dir}/config/config.toml https://raw.githubusercontent.com/WJQSERVER-STUDIO/ghproxy/main/deploy/config.toml fi # 替换 port = 8080 -sed -i "s/port = 8080/port = $PORT/g" /root/data/ghproxy/config/config.toml +sed -i "s/port = 8080/port = $PORT/g" ${ghproxy_dir}/config/config.toml +sed -i 's/host = "127.0.0.1"/host = "'"$IP"'"/g' ${ghproxy_dir}/config/config.toml +sed -i "s|staticDir = \"/usr/local/ghproxy/pages\"|staticDir = \"${ghproxy_dir}/pages\"|g" ${ghproxy_dir}/config/config.toml +sed -i "s|logFilePath = \"/usr/local/ghproxy/log/ghproxy.log\"|logFilePath = \"${ghproxy_dir}/log/ghproxy.log\"|g" ${ghproxy_dir}/config/config.toml +sed -i "s|blacklistFile = \"/usr/local/ghproxy/config/blacklist.json\"|blacklistFile = \"${ghproxy_dir}/config/blacklist.json\"|g" ${ghproxy_dir}/config/config.toml +sed -i "s|whitelistFile = \"/usr/local/ghproxy/config/whitelist.json\"|whitelistFile = \"${ghproxy_dir}/config/whitelist.json\"|g" ${ghproxy_dir}/config/config.toml # 下载systemd服务文件 -wget -q -O /etc/systemd/system/ghproxy.service https://raw.githubusercontent.com/WJQSERVER-STUDIO/ghproxy/main/deploy/ghproxy.service +if [ "$ghproxy_dir" = "/usr/local/ghproxy" ]; then + wget -q -O /etc/systemd/system/ghproxy.service https://raw.githubusercontent.com/WJQSERVER-STUDIO/ghproxy/main/deploy/ghproxy.service +else + make_systemd_service +fi # 启动ghproxy systemctl daemon-reload diff --git a/deploy/uninstall.sh b/deploy/uninstall.sh index 7d1804e..d9b784e 100644 --- a/deploy/uninstall.sh +++ b/deploy/uninstall.sh @@ -7,7 +7,21 @@ systemctl stop ghproxy systemctl disable ghproxy rm /etc/systemd/system/ghproxy.service +# 获取安装文件夹 +read -p "请输入 ghproxy 安装文件夹路径(默认 /usr/local/ghproxy): " install_path +if [ -z "$install_path" ]; then + install_path="/usr/local/ghproxy" +fi + # 删除 ghproxy 文件夹 -rm -r /root/data/ghproxy +# 检查目录是否存在ghproxy文件 +if [ -f "$install_path" ]; then + echo "ghproxy 未安装或安装路径错误" + exit 1 +else + echo "ghproxy 安装目录已确认,正在卸载..." + rm -r $install_path +fi + echo "ghproxy 已成功卸载" \ No newline at end of file From 157cbf9d3a3b44430a9cc00593510991614e3dcc Mon Sep 17 00:00:00 2001 From: WJQSERVER Date: Fri, 25 Oct 2024 18:12:25 +0800 Subject: [PATCH 015/395] deploy shell update --- deploy/install.sh | 73 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 59 insertions(+), 14 deletions(-) diff --git a/deploy/install.sh b/deploy/install.sh index 07e8fcb..4ff84ae 100644 --- a/deploy/install.sh +++ b/deploy/install.sh @@ -1,4 +1,7 @@ # /bin/bash +# https://github.com/WJQSERVER-STUDIO/ghproxy + +ghproxy_dir="/usr/local/ghproxy" # install packages install() { @@ -27,6 +30,26 @@ install() { return 0 } +make_systemd_service() { + cat < /etc/systemd/system/ghproxy.service +[Unit] +Description=Github Proxy Service +After=network.target + +[Service] +ExecStart=/bin/bash -c '$ghproxy_dir/ghproxy -cfg $ghproxy_dir/config/config.toml > $ghproxy_dir/log/run.log 2>&1' +WorkingDirectory=$ghproxy_dir +Restart=always +User=root +Group=root + +[Install] +WantedBy=multi-user.target + +EOF + +} + # 安装依赖包 install curl wget sed @@ -44,44 +67,66 @@ elif [ "$ARCH" == "aarch64" ]; then ARCH="arm64" fi +# 获取监听端口 read -p "请输入程序监听的端口(默认8080): " PORT if [ -z "$PORT" ]; then PORT=8080 fi +# 本机监听/泛监听(127.0.0.1/0.0.0.0) +read -p "请键入程序监听的IP(默认127.0.0.1)(0.0.0.0为泛监听): " IP +if [ -z "$IP" ]; then + IP="127.0.0.1" +fi + +# 安装目录 +read -p "请输入安装目录(默认/usr/local/ghproxy): " ghproxy_dir +if [ -z "$ghproxy_dir" ]; then + ghproxy_dir="/usr/local/ghproxy" +fi + # 创建目录 -mkdir -p /root/data/ghproxy -mkdir -p /root/data/ghproxy/config -mkdir -p /root/data/ghproxy/log -mkdir -p /root/data/ghproxy/pages +mkdir -p ${ghproxy_dir} +mkdir -p ${ghproxy_dir}/config +mkdir -p ${ghproxy_dir}/log +mkdir -p ${ghproxy_dir}/pages # 获取最新版本号 VERSION=$(curl -s https://raw.githubusercontent.com/WJQSERVER-STUDIO/ghproxy/main/VERSION) -wget -q -O /root/data/ghproxy/VERSION https://raw.githubusercontent.com/WJQSERVER-STUDIO/ghproxy/main/VERSION +wget -q -O ${ghproxy_dir}/VERSION https://raw.githubusercontent.com/WJQSERVER-STUDIO/ghproxy/main/VERSION # 下载ghproxy -wget -q -O /root/data/ghproxy/ghproxy https://github.com/WJQSERVER-STUDIO/ghproxy/releases/download/$VERSION/ghproxy-linux-$ARCH -chmod +x /root/data/ghproxy/ghproxy +wget -q -O ${ghproxy_dir}/ghproxy https://github.com/WJQSERVER-STUDIO/ghproxy/releases/download/$VERSION/ghproxy-linux-$ARCH +chmod +x ${ghproxy_dir}/ghproxy # 下载pages -wget -q -O /root/data/ghproxy/pages/index.html https://raw.githubusercontent.com/WJQSERVER-STUDIO/ghproxy/main/pages/index.html -wget -q -O /root/data/ghproxy/pages/favicon.ico https://raw.githubusercontent.com/WJQSERVER-STUDIO/ghproxy/main/pages/favicon.ico +wget -q -O ${ghproxy_dir}/pages/index.html https://raw.githubusercontent.com/WJQSERVER-STUDIO/ghproxy/main/pages/index.html +wget -q -O ${ghproxy_dir}/pages/favicon.ico https://raw.githubusercontent.com/WJQSERVER-STUDIO/ghproxy/main/pages/favicon.ico # 下载配置文件 -if [ -f /root/data/ghproxy/config/config.toml ]; then +if [ -f ${ghproxy_dir}/config/config.toml ]; then echo "配置文件已存在, 跳过下载" - echo "[WARNING] > 请检查配置文件是否正确,大版本升级时请注意配置文件兼容性" + echo "[WARNING] 请检查配置文件是否正确,DEV版本升级时请注意配置文件兼容性" sleep 2 else - wget -q -O /root/data/ghproxy/config/config.toml https://raw.githubusercontent.com/WJQSERVER-STUDIO/ghproxy/main/deploy/config.toml + wget -q -O ${ghproxy_dir}/config/config.toml https://raw.githubusercontent.com/WJQSERVER-STUDIO/ghproxy/main/deploy/config.toml fi # 替换 port = 8080 -sed -i "s/port = 8080/port = $PORT/g" /root/data/ghproxy/config/config.toml +sed -i "s/port = 8080/port = $PORT/g" ${ghproxy_dir}/config/config.toml +sed -i 's/host = "127.0.0.1"/host = "'"$IP"'"/g' ${ghproxy_dir}/config/config.toml +sed -i "s|staticDir = \"/usr/local/ghproxy/pages\"|staticDir = \"${ghproxy_dir}/pages\"|g" ${ghproxy_dir}/config/config.toml +sed -i "s|logFilePath = \"/usr/local/ghproxy/log/ghproxy.log\"|logFilePath = \"${ghproxy_dir}/log/ghproxy.log\"|g" ${ghproxy_dir}/config/config.toml +sed -i "s|blacklistFile = \"/usr/local/ghproxy/config/blacklist.json\"|blacklistFile = \"${ghproxy_dir}/config/blacklist.json\"|g" ${ghproxy_dir}/config/config.toml +sed -i "s|whitelistFile = \"/usr/local/ghproxy/config/whitelist.json\"|whitelistFile = \"${ghproxy_dir}/config/whitelist.json\"|g" ${ghproxy_dir}/config/config.toml # 下载systemd服务文件 -wget -q -O /etc/systemd/system/ghproxy.service https://raw.githubusercontent.com/WJQSERVER-STUDIO/ghproxy/main/deploy/ghproxy.service +if [ "$ghproxy_dir" = "/usr/local/ghproxy" ]; then + wget -q -O /etc/systemd/system/ghproxy.service https://raw.githubusercontent.com/WJQSERVER-STUDIO/ghproxy/main/deploy/ghproxy.service +else + make_systemd_service +fi # 启动ghproxy systemctl daemon-reload From 19f753a515c82cf01806941b435fc838a158e62b Mon Sep 17 00:00:00 2001 From: WJQSERVER Date: Sun, 27 Oct 2024 18:08:12 +0800 Subject: [PATCH 016/395] update --- README.md | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 326794c..51b653b 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ [TG讨论群组](https://t.me/ghproxy_go) +[版本更新介绍](https://blog.wjqserver.com/categories/my-program/) + ## 项目说明 ### 项目特点 @@ -26,7 +28,6 @@ ### 项目开发过程 **本项目是[WJQSERVER-STUDIO/ghproxy-go](https://github.com/WJQSERVER-STUDIO/ghproxy-go)的重构版本,实现了原项目原定功能的同时,进一步优化了性能** -本项目源于[WJQSERVER-STUDIO/ghproxy-go](https://github.com/WJQSERVER-STUDIO/ghproxy-go)与[WJQSERVER/ghproxy-go-0RTT](https://github.com/WJQSERVER/ghproxy-go-0RTT)两个项目,前者带来了实现框架与资源,后者带来了解决Git clone问题的办法,使得本项目从net/http标准库切换至Gin框架,已解决此困扰已久的问题,在此基础上,本项目进一步优化了性能,并添加了用户鉴权功能,使得部署更加安全可靠。 关于此项目的详细开发过程,请参看Commit记录与[CHANGELOG.md](https://github.com/WJQSERVER-STUDIO/ghproxy/blob/main/CHANGELOG.md) - V1.0.0 迁移至本仓库,并再次重构内容实现 @@ -153,13 +154,9 @@ example.com { ![ghproxy-demo-v1.5.0.png](https://webp.wjqserver.com/ghproxy/ghproxy-demo-v1.5.0.png) -## TODO & DEV +结语 +--- -### TODO -- [x] 用户鉴权 -- [x] 仓库黑名单 -- [x] 仓库白名单 - -### DEV - -- [x] Docker Pull 代理 +本项目基于Go语言实现的GHProxy,使用Gin框架与req库 +Docker镜像基于[WJQSERVER-STUDIO/caddy](https://github.com/WJQSERVER-STUDIO/caddy) +本项目使用WSL LICENSE Version1.2 (WJQSERVER STUDIO LICENSE Version1.2) 授权协议,请遵守相关条例。 From 92b3e19954a06031fe1af4b54558e90f24b877fd Mon Sep 17 00:00:00 2001 From: WJQSERVER Date: Mon, 28 Oct 2024 18:02:58 +0800 Subject: [PATCH 017/395] 24w20a --- CHANGELOG.md | 7 +++++ DEV-VERSION | 2 +- README.md | 2 +- SECURITY.MD | 2 +- api/api.go | 5 ++++ auth/auth.go | 19 ++++++++------ main.go | 14 ++++------ proxy/proxy.go | 69 ++++++++++++++++++++++++++++---------------------- 8 files changed, 70 insertions(+), 50 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 361d8bc..6b988a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # 更新日志 +24w20a +--- +- PRE-RELEASE: 此版本是v1.6.2的预发布版本,请勿在生产环境中使用 +- CHANGE: 大幅修改日志记录,对各个部分的日志记录进行统一格式,并对部分重复日志进行合并 +- CHANGE: 大幅优化一键部署脚本,使其更加易用,并增加更多的功能(已于早些时候hotfix) +- CHANGE: 优化部分代码结构,提升性能 + v1.6.1 --- - CHANGE: 根据社区建议,将`sizeLimit`由过去的以`byte`为单位,改为以`MB`为单位,以便于直观理解 diff --git a/DEV-VERSION b/DEV-VERSION index 9cde107..dc757e9 100644 --- a/DEV-VERSION +++ b/DEV-VERSION @@ -1 +1 @@ -24w19d \ No newline at end of file +24w20a \ No newline at end of file diff --git a/README.md b/README.md index 51b653b..c7e63cb 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ git clone https://ghproxy.1888866.xyz/github.com/WJQSERVER-STUDIO/ghproxy.git docker run -p 7210:80 -v ./ghproxy/log/run:/data/ghproxy/log -v ./ghproxy/log/caddy:/data/caddy/log -v ./ghproxy/config:/data/ghproxy/config --restart always wjqserver/ghproxy ``` -- Docker-Compose +- Docker-Compose (建议使用) 参看[docker-compose.yml](https://github.com/WJQSERVER-STUDIO/ghproxy/blob/main/docker/compose/docker-compose.yml) diff --git a/SECURITY.MD b/SECURITY.MD index 2bd9114..8fc021c 100644 --- a/SECURITY.MD +++ b/SECURITY.MD @@ -7,7 +7,7 @@ | 版本 | 是否支持 | | --- | --- | | v1.x.x | :white_check_mark: | -| **w**a/b/c... | :warning: 此为PRE-RELEASE版本,用于开发与测试,可能存在未知的问题 | +| 24w*a/b/c... | :warning: 此为PRE-RELEASE版本,用于开发与测试,可能存在未知的问题 | | v0.x.x | :x: 这些版本不再受支持 | ### 用户须知 diff --git a/api/api.go b/api/api.go index 3214d92..42f11ae 100644 --- a/api/api.go +++ b/api/api.go @@ -46,6 +46,7 @@ func InitHandleRouter(cfg *config.Config, router *gin.Engine) { func SizeLimitHandler(cfg *config.Config, c *gin.Context) { sizeLimit := cfg.Server.SizeLimit + logInfo("%s %s %s %s %s", c.ClientIP(), c.Request.Method, c.Request.URL.Path, c.Request.UserAgent(), c.Request.Proto) c.Writer.Header().Set("Content-Type", "application/json") json.NewEncoder(c.Writer).Encode(map[string]interface{}{ "MaxResponseBodySize": sizeLimit, @@ -53,6 +54,7 @@ func SizeLimitHandler(cfg *config.Config, c *gin.Context) { } func WhiteListStatusHandler(c *gin.Context, cfg *config.Config) { + logInfo("%s %s %s %s %s", c.ClientIP(), c.Request.Method, c.Request.URL.Path, c.Request.UserAgent(), c.Request.Proto) c.Writer.Header().Set("Content-Type", "application/json") json.NewEncoder(c.Writer).Encode(map[string]interface{}{ "Whitelist": cfg.Whitelist.Enabled, @@ -60,6 +62,7 @@ func WhiteListStatusHandler(c *gin.Context, cfg *config.Config) { } func BlackListStatusHandler(c *gin.Context, cfg *config.Config) { + logInfo("%s %s %s %s %s", c.ClientIP(), c.Request.Method, c.Request.URL.Path, c.Request.UserAgent(), c.Request.Proto) c.Writer.Header().Set("Content-Type", "application/json") json.NewEncoder(c.Writer).Encode(map[string]interface{}{ "Blacklist": cfg.Blacklist.Enabled, @@ -67,6 +70,7 @@ func BlackListStatusHandler(c *gin.Context, cfg *config.Config) { } func CorsStatusHandler(c *gin.Context, cfg *config.Config) { + logInfo("%s %s %s %s %s", c.ClientIP(), c.Request.Method, c.Request.URL.Path, c.Request.UserAgent(), c.Request.Proto) c.Writer.Header().Set("Content-Type", "application/json") json.NewEncoder(c.Writer).Encode(map[string]interface{}{ "Cors": cfg.CORS.Enabled, @@ -74,6 +78,7 @@ func CorsStatusHandler(c *gin.Context, cfg *config.Config) { } func HealthcheckHandler(c *gin.Context) { + logInfo("%s %s %s %s %s", c.ClientIP(), c.Request.Method, c.Request.URL.Path, c.Request.UserAgent(), c.Request.Proto) c.Writer.Header().Set("Content-Type", "application/json") json.NewEncoder(c.Writer).Encode(map[string]interface{}{ "Status": "OK", diff --git a/auth/auth.go b/auth/auth.go index 4f5a80d..35cd8d0 100644 --- a/auth/auth.go +++ b/auth/auth.go @@ -1,6 +1,7 @@ package auth import ( + "fmt" "ghproxy/config" "ghproxy/logger" @@ -26,27 +27,29 @@ func Init(cfg *config.Config) { logInfo("Auth Init") } -func AuthHandler(c *gin.Context, cfg *config.Config) bool { +func AuthHandler(c *gin.Context, cfg *config.Config) (isValid bool, err string) { // 如果身份验证未启用,直接返回 true if !cfg.Auth.Enabled { - return true + return true, "" } // 获取 auth_token 参数 authToken := c.Query("auth_token") - logInfo("auth_token received: %s", authToken) + // IP METHOD URL USERAGENT PROTO TOKEN + logInfo("%s %s %s %s %s AUTH_TOKEN: %s", c.ClientIP(), c.Request.Method, c.Request.URL.Path, c.Request.UserAgent(), c.Request.Proto, authToken) // 验证 token if authToken == "" { - logWarning("auth FAILED: no auth_token provided") - return false + err := "Auth token == nil" + return false, err } - isValid := authToken == cfg.Auth.AuthToken + isValid = authToken == cfg.Auth.AuthToken if !isValid { - logWarning("auth FAILED: invalid auth_token: %s", authToken) + err := fmt.Sprintf("Auth token incorrect: %s", authToken) + return false, err } logInfo("auth SUCCESS: %t", isValid) - return isValid + return isValid, "" } diff --git a/main.go b/main.go index 3363c6b..7dca0a0 100644 --- a/main.go +++ b/main.go @@ -22,7 +22,6 @@ var ( cfgfile string ) -// 日志模块 var ( logw = logger.Logw logInfo = logger.LogInfo @@ -36,7 +35,6 @@ func readFlag() { func loadConfig() { var err error - // 初始化配置 cfg, err = config.LoadConfig(cfgfile) if err != nil { log.Fatalf("Failed to load config: %v", err) @@ -46,9 +44,8 @@ func loadConfig() { } func setupLogger(cfg *config.Config) { - // 初始化日志模块 var err error - err = logger.Init(cfg.Log.LogFilePath, cfg.Log.MaxLogSize) // 传递日志文件路径 + err = logger.Init(cfg.Log.LogFilePath, cfg.Log.MaxLogSize) if err != nil { log.Fatalf("Failed to initialize logger: %v", err) } @@ -89,8 +86,8 @@ func init() { router.StaticFile("/favicon.ico", faviconPath) } else if !cfg.Pages.Enabled { router.GET("/", func(c *gin.Context) { - c.String(http.StatusForbidden, "403 Forbidden This route is not allowed to access.") - logWarning("Forbidden: IP:%s UA:%s METHOD:%s HTTPv:%s", c.ClientIP(), c.Request.UserAgent(), c.Request.Method, c.Request.Proto) + c.String(http.StatusForbidden, "403 Forbidden Access") + logWarning("403 > Path:/ IP:%s UA:%s METHOD:%s HTTPv:%s", c.ClientIP(), c.Request.UserAgent(), c.Request.Method, c.Request.Proto) }) } @@ -100,11 +97,10 @@ func init() { } func main() { - // 启动服务器 err := router.Run(fmt.Sprintf("%s:%d", cfg.Server.Host, cfg.Server.Port)) if err != nil { - logError("Error starting server: %v\n", err) + logError("Failed to start server: %v\n", err) } - fmt.Println("Program finished") + fmt.Println("Program Exit") } diff --git a/proxy/proxy.go b/proxy/proxy.go index a511dca..91e40cb 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -1,4 +1,3 @@ -// proxy/proxy.go 实验性 package proxy import ( @@ -40,8 +39,9 @@ func NoRouteHandler(cfg *config.Config) gin.HandlerFunc { matches := re.FindStringSubmatch(rawPath) if len(matches) < 3 { - logWarning("Invalid URL: %s", rawPath) - c.String(http.StatusForbidden, "Invalid URL.") + errMsg := fmt.Sprintf("%s %s %s %s %s Invalid URL", c.ClientIP(), c.Request.Method, rawPath, c.Request.Header.Get("User-Agent"), c.Request.Proto) + logWarning(errMsg) + c.String(http.StatusForbidden, "Invalid URL Format. Path: %s", rawPath) return } @@ -49,34 +49,37 @@ func NoRouteHandler(cfg *config.Config) gin.HandlerFunc { username, repo := MatchUserRepo(rawPath, cfg, c, matches) - logWarning("Blacklist Check > Username: %s, Repo: %s", username, repo) + logInfo("%s %s %s %s %s Matched-Username: %s, Matched-Repo: %s", c.ClientIP(), c.Request.Method, rawPath, c.Request.Header.Get("User-Agent"), c.Request.Proto, username, repo) fullrepo := fmt.Sprintf("%s/%s", username, repo) // 白名单检查 if cfg.Whitelist.Enabled { - whitelistpass := auth.CheckWhitelist(fullrepo) - if !whitelistpass { + whitelist := auth.CheckWhitelist(fullrepo) + if !whitelist { + logErrMsg := fmt.Sprintf("%s %s %s %s %s Whitelist Blocked repo: %s", c.ClientIP(), c.Request.Method, rawPath, c.Request.Header.Get("User-Agent"), c.Request.Proto, fullrepo) errMsg := fmt.Sprintf("Whitelist Blocked repo: %s", fullrepo) c.JSON(http.StatusForbidden, gin.H{"error": errMsg}) - logWarning(errMsg) + logWarning(logErrMsg) return } } // 黑名单检查 if cfg.Blacklist.Enabled { - blacklistpass := auth.CheckBlacklist(fullrepo) - if blacklistpass { + blacklist := auth.CheckBlacklist(fullrepo) + if blacklist { + logErrMsg := fmt.Sprintf("%s %s %s %s %s Whitelist Blocked repo: %s", c.ClientIP(), c.Request.Method, rawPath, c.Request.Header.Get("User-Agent"), c.Request.Proto, fullrepo) errMsg := fmt.Sprintf("Blacklist Blocked repo: %s", fullrepo) c.JSON(http.StatusForbidden, gin.H{"error": errMsg}) - logWarning(errMsg) + logWarning(logErrMsg) return } } - matches = CheckURL(rawPath) + matches = CheckURL(rawPath, c) if matches == nil { c.AbortWithStatus(http.StatusNotFound) + logError("%s %s %s %s %s 404-NOMATCH", c.ClientIP(), c.Request.Method, rawPath, c.Request.Header.Get("User-Agent"), c.Request.Proto) return } @@ -84,13 +87,16 @@ func NoRouteHandler(cfg *config.Config) gin.HandlerFunc { rawPath = strings.Replace(rawPath, "/blob/", "/raw/", 1) } - if !auth.AuthHandler(c, cfg) { + // 鉴权 + authcheck, err := auth.AuthHandler(c, cfg) + if !authcheck { c.AbortWithStatusJSON(401, gin.H{"error": "Unauthorized"}) - logWarning("Unauthorized request: %s", rawPath) + logWarning("%s %s %s %s %s Auth-Error: %v", c.ClientIP(), c.Request.Method, rawPath, c.Request.Header.Get("User-Agent"), c.Request.Proto, err) return } - logInfo("Matches: %v", matches) + // IP METHOD URL USERAGENT PROTO MATCHES + logInfo("%s %s %s %s %s Matches: %v", c.ClientIP(), c.Request.Method, rawPath, c.Request.Header.Get("User-Agent"), c.Request.Proto, matches) switch { case exps[0].MatchString(rawPath), exps[1].MatchString(rawPath), exps[3].MatchString(rawPath), exps[4].MatchString(rawPath): @@ -99,6 +105,7 @@ func NoRouteHandler(cfg *config.Config) gin.HandlerFunc { ProxyRequest(c, rawPath, cfg, "git") default: c.String(http.StatusForbidden, "Invalid input.") + fmt.Println("Invalid input.") return } } @@ -110,24 +117,24 @@ func MatchUserRepo(rawPath string, cfg *config.Config, c *gin.Context, matches [ var gistmatches []string if gistregex.MatchString(rawPath) { gistmatches = gistregex.FindStringSubmatch(rawPath) - logInfo("Gist Matched > Username: %s, URL: %s", gistmatches[1], rawPath) + logInfo("%s %s %s %s %s Matched-Username: %s", c.ClientIP(), c.Request.Method, rawPath, c.Request.Header.Get("User-Agent"), c.Request.Proto, gistmatches[1]) return gistmatches[1], "" } - // 定义路径匹配的正则表达式 + // 定义路径 pathRegex := regexp.MustCompile(`^([^/]+)/([^/]+)/([^/]+)/.*`) if pathMatches := pathRegex.FindStringSubmatch(matches[2]); len(pathMatches) >= 4 { return pathMatches[2], pathMatches[3] } // 返回错误信息 - logWarning("Invalid path: %s", rawPath) - c.String(http.StatusForbidden, "Invalid path; expected username/repo.") + errMsg := fmt.Sprintf("%s %s %s %s %s Invalid URL", c.ClientIP(), c.Request.Method, rawPath, c.Request.Header.Get("User-Agent"), c.Request.Proto) + logWarning(errMsg) + c.String(http.StatusForbidden, "Invalid path; expected username/repo, Path: %s", rawPath) return "", "" } func ProxyRequest(c *gin.Context, u string, cfg *config.Config, mode string) { method := c.Request.Method - // 记录日志 IP 地址、请求方法、请求 URL、请求头 User-Agent 、HTTP版本 logInfo("%s %s %s %s %s", c.ClientIP(), method, u, c.Request.Header.Get("User-Agent"), c.Request.Proto) client := createHTTPClient(mode) @@ -141,7 +148,7 @@ func ProxyRequest(c *gin.Context, u string, cfg *config.Config, mode string) { req := client.R().SetBody(body) setRequestHeaders(c, req) - resp, err := SendRequest(req, method, u) + resp, err := SendRequest(c, req, method, u) if err != nil { HandleError(c, fmt.Sprintf("Failed to send request: %v", err)) return @@ -149,17 +156,18 @@ func ProxyRequest(c *gin.Context, u string, cfg *config.Config, mode string) { defer resp.Body.Close() if err := HandleResponseSize(resp, cfg, c); err != nil { - logWarning("Error handling response size: %v", err) + logWarning("%s %s %s %s %s Response-Size-Error: %v", c.ClientIP(), method, u, c.Request.Header.Get("User-Agent"), c.Request.Proto, err) return } CopyResponseHeaders(resp, c, cfg) c.Status(resp.StatusCode) if err := copyResponseBody(c, resp.Body); err != nil { - logError("Failed to copy response body: %v", err) + logError("%s %s %s %s %s Response-Copy-Error: %v", c.ClientIP(), method, u, c.Request.Header.Get("User-Agent"), c.Request.Proto, err) } } +// 判断并选择TLS指纹 func createHTTPClient(mode string) *req.Client { client := req.C() switch mode { @@ -198,7 +206,7 @@ func copyResponseBody(c *gin.Context, respBody io.Reader) error { return err } -func SendRequest(req *req.Request, method, url string) (*req.Response, error) { +func SendRequest(c *gin.Context, req *req.Request, method, url string) (*req.Response, error) { switch method { case "GET": return req.Get(url) @@ -209,8 +217,10 @@ func SendRequest(req *req.Request, method, url string) (*req.Response, error) { case "DELETE": return req.Delete(url) default: - logInfo("Unsupported method: %s", method) - return nil, fmt.Errorf("unsupported method: %s", method) + // IP METHOD URL USERAGENT PROTO UNSUPPORTED-METHOD + errmsg := fmt.Sprintf("%s %s %s %s %s Unsupported method", c.ClientIP(), method, url, c.Request.Header.Get("User-Agent"), c.Request.Proto) + logWarning(errmsg) + return nil, fmt.Errorf(errmsg) } } @@ -222,8 +232,8 @@ func HandleResponseSize(resp *req.Response, cfg *config.Config, c *gin.Context) if err == nil && size > sizelimit { finalURL := resp.Request.URL.String() c.Redirect(http.StatusMovedPermanently, finalURL) - logWarning("Size limit exceeded: %s, Size: %d", finalURL, size) - return fmt.Errorf("size limit exceeded: %d", size) + logWarning("%s %s %s %s %s Final-URL: %s Size-Limit-Exceeded: %d", c.ClientIP(), c.Request.Method, c.Request.URL.String(), c.Request.Header.Get("User-Agent"), c.Request.Proto, finalURL, size) + return fmt.Errorf("Path: %s size limit exceeded: %d", finalURL, size) } } return nil @@ -282,14 +292,13 @@ func HandleError(c *gin.Context, message string) { logWarning(message) } -func CheckURL(u string) []string { +func CheckURL(u string, c *gin.Context) []string { for _, exp := range exps { if matches := exp.FindStringSubmatch(u); matches != nil { - logInfo("URL matched: %s, Matches: %v", u, matches[1:]) return matches[1:] } } - errMsg := fmt.Sprintf("Invalid URL: %s", u) + errMsg := fmt.Sprintf("%s %s %s %s %s Invalid URL", c.ClientIP(), c.Request.Method, u, c.Request.Header.Get("User-Agent"), c.Request.Proto) logWarning(errMsg) return nil } From fe652821bdb4f760554d7fe4fb4c9f2d295adf1a Mon Sep 17 00:00:00 2001 From: WJQSERVER Date: Tue, 29 Oct 2024 03:08:03 +0800 Subject: [PATCH 018/395] 24w20b --- CHANGELOG.md | 5 +++ DEV-VERSION | 2 +- pages/index.html | 106 ++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 102 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b988a9..f80dd41 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # 更新日志 +24w20b +--- +- PRE-RELEASE: 此版本是v1.6.2的预发布版本,请勿在生产环境中使用 +- CHANGE: 优化前端界面,加入黑夜模式,并优化部分样式 + 24w20a --- - PRE-RELEASE: 此版本是v1.6.2的预发布版本,请勿在生产环境中使用 diff --git a/DEV-VERSION b/DEV-VERSION index dc757e9..27812aa 100644 --- a/DEV-VERSION +++ b/DEV-VERSION @@ -1 +1 @@ -24w20a \ No newline at end of file +24w20b \ No newline at end of file diff --git a/pages/index.html b/pages/index.html index f6a7ad5..2c1d3e1 100644 --- a/pages/index.html +++ b/pages/index.html @@ -5,12 +5,31 @@ + + Github文件加速 @@ -160,7 +244,9 @@

         
         
-

GitHub链接带不带协议头均可,支持release、archive以及文件,转换后链接均可使用。

+
+

GitHub链接带不带协议头均可,支持release、archive以及文件,转换后链接均可使用。

+

文件大小限制: ...

白名单状态: ...

@@ -279,7 +365,7 @@