mirror of
https://github.com/WJQSERVER-STUDIO/ghproxy.git
synced 2026-02-03 08:11:11 +08:00
25w12a
This commit is contained in:
parent
f5c32915b9
commit
c184e46917
20 changed files with 65 additions and 36 deletions
|
|
@ -1,5 +1,12 @@
|
||||||
# 更新日志
|
# 更新日志
|
||||||
|
|
||||||
|
25w12a
|
||||||
|
---
|
||||||
|
- PRE-RELEASE: 此版本是v2.0.8/v2.1.0的预发布版本,请勿在生产环境中使用;
|
||||||
|
- CHANGE: 更新looger版本至v1.3.0
|
||||||
|
- CHANGE: 改进日志相关
|
||||||
|
- ADD: 加入日志等级配置项
|
||||||
|
|
||||||
2.0.7
|
2.0.7
|
||||||
---
|
---
|
||||||
- RELEASE: v2.0.7正式版发布;
|
- RELEASE: v2.0.7正式版发布;
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
25w11a
|
25w12a
|
||||||
|
|
@ -92,6 +92,7 @@ staticPath = "/data/www" # 静态页面文件路径
|
||||||
[log]
|
[log]
|
||||||
logFilePath = "/data/ghproxy/log/ghproxy.log" # 日志文件路径
|
logFilePath = "/data/ghproxy/log/ghproxy.log" # 日志文件路径
|
||||||
maxLogSize = 5 # MB 日志文件最大大小
|
maxLogSize = 5 # MB 日志文件最大大小
|
||||||
|
level = "info" # 日志级别 dump, debug, info, warn, error, none
|
||||||
|
|
||||||
[cors]
|
[cors]
|
||||||
enabled = true # 是否开启跨域
|
enabled = true # 是否开启跨域
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@ var (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
logw = logger.Logw
|
logw = logger.Logw
|
||||||
|
LogDump = logger.LogDump
|
||||||
|
logDebug = logger.LogDebug
|
||||||
logInfo = logger.LogInfo
|
logInfo = logger.LogInfo
|
||||||
logWarning = logger.LogWarning
|
logWarning = logger.LogWarning
|
||||||
logError = logger.LogError
|
logError = logger.LogError
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ func AuthHeaderHandler(c *gin.Context, cfg *config.Config) (isValid bool, err st
|
||||||
}
|
}
|
||||||
// 获取"GH-Auth"的值
|
// 获取"GH-Auth"的值
|
||||||
authToken := c.GetHeader("GH-Auth")
|
authToken := c.GetHeader("GH-Auth")
|
||||||
logInfo("%s %s %s %s %s AUTH_TOKEN: %s", c.Request.Method, c.Request.Host, c.Request.URL.Path, c.Request.Proto, c.Request.RemoteAddr, authToken)
|
logDebug("%s %s %s %s %s AUTH_TOKEN: %s", c.Request.Method, c.Request.Host, c.Request.URL.Path, c.Request.Proto, c.Request.RemoteAddr, authToken)
|
||||||
if authToken == "" {
|
if authToken == "" {
|
||||||
err := "Auth Header == nil"
|
err := "Auth Header == nil"
|
||||||
return false, err
|
return false, err
|
||||||
|
|
@ -25,6 +25,5 @@ func AuthHeaderHandler(c *gin.Context, cfg *config.Config) (isValid bool, err st
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
logInfo("auth SUCCESS: %t", isValid)
|
|
||||||
return isValid, ""
|
return isValid, ""
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ func AuthParametersHandler(c *gin.Context, cfg *config.Config) (isValid bool, er
|
||||||
}
|
}
|
||||||
|
|
||||||
authToken := c.Query("auth_token")
|
authToken := c.Query("auth_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)
|
logDebug("%s %s %s %s %s AUTH_TOKEN: %s", c.ClientIP(), c.Request.Method, c.Request.URL.Path, c.Request.UserAgent(), c.Request.Proto, authToken)
|
||||||
|
|
||||||
if authToken == "" {
|
if authToken == "" {
|
||||||
err := "Auth token == nil"
|
err := "Auth token == nil"
|
||||||
|
|
@ -26,6 +26,5 @@ func AuthParametersHandler(c *gin.Context, cfg *config.Config) (isValid bool, er
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
logInfo("auth SUCCESS: %t", isValid)
|
|
||||||
return isValid, ""
|
return isValid, ""
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ import (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
logw = logger.Logw
|
logw = logger.Logw
|
||||||
|
LogDump = logger.LogDump
|
||||||
|
logDebug = logger.LogDebug
|
||||||
logInfo = logger.LogInfo
|
logInfo = logger.LogInfo
|
||||||
logWarning = logger.LogWarning
|
logWarning = logger.LogWarning
|
||||||
logError = logger.LogError
|
logError = logger.LogError
|
||||||
|
|
@ -21,7 +23,7 @@ func Init(cfg *config.Config) {
|
||||||
if cfg.Whitelist.Enabled {
|
if cfg.Whitelist.Enabled {
|
||||||
LoadWhitelist(cfg)
|
LoadWhitelist(cfg)
|
||||||
}
|
}
|
||||||
logInfo("Auth Init")
|
logDebug("Auth Init")
|
||||||
}
|
}
|
||||||
|
|
||||||
func AuthHandler(c *gin.Context, cfg *config.Config) (isValid bool, err string) {
|
func AuthHandler(c *gin.Context, cfg *config.Config) (isValid bool, err string) {
|
||||||
|
|
@ -32,10 +34,10 @@ func AuthHandler(c *gin.Context, cfg *config.Config) (isValid bool, err string)
|
||||||
isValid, err = AuthHeaderHandler(c, cfg)
|
isValid, err = AuthHeaderHandler(c, cfg)
|
||||||
return isValid, err
|
return isValid, err
|
||||||
} else if cfg.Auth.AuthMethod == "" {
|
} else if cfg.Auth.AuthMethod == "" {
|
||||||
logWarning("Auth method not set")
|
logError("Auth method not set")
|
||||||
return true, ""
|
return true, ""
|
||||||
} else {
|
} else {
|
||||||
logWarning("Auth method not supported")
|
logError("Auth method not supported")
|
||||||
return false, "Auth method not supported"
|
return false, "Auth method not supported"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ type PagesConfig struct {
|
||||||
type LogConfig struct {
|
type LogConfig struct {
|
||||||
LogFilePath string `toml:"logFilePath"`
|
LogFilePath string `toml:"logFilePath"`
|
||||||
MaxLogSize int `toml:"maxLogSize"`
|
MaxLogSize int `toml:"maxLogSize"`
|
||||||
|
Level string `toml:"level"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CORSConfig struct {
|
type CORSConfig struct {
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ staticDir = "/data/www"
|
||||||
[log]
|
[log]
|
||||||
logFilePath = "/data/ghproxy/log/ghproxy.log"
|
logFilePath = "/data/ghproxy/log/ghproxy.log"
|
||||||
maxLogSize = 5 # MB
|
maxLogSize = 5 # MB
|
||||||
|
level = "info" # dump, debug, info, warn, error, none
|
||||||
|
|
||||||
[cors]
|
[cors]
|
||||||
enabled = true
|
enabled = true
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ debug = false
|
||||||
[pages]
|
[pages]
|
||||||
enabled = false
|
enabled = false
|
||||||
staticDir = "/usr/local/ghproxy/pages"
|
staticDir = "/usr/local/ghproxy/pages"
|
||||||
|
level = "info"
|
||||||
|
|
||||||
[log]
|
[log]
|
||||||
logFilePath = "/usr/local/ghproxy/log/ghproxy.log"
|
logFilePath = "/usr/local/ghproxy/log/ghproxy.log"
|
||||||
|
|
|
||||||
4
go.mod
4
go.mod
|
|
@ -4,7 +4,7 @@ go 1.23.6
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/BurntSushi/toml v1.4.0
|
github.com/BurntSushi/toml v1.4.0
|
||||||
github.com/WJQSERVER-STUDIO/go-utils/logger v1.2.0
|
github.com/WJQSERVER-STUDIO/go-utils/logger v1.3.0
|
||||||
github.com/gin-gonic/gin v1.10.0
|
github.com/gin-gonic/gin v1.10.0
|
||||||
golang.org/x/time v0.10.0
|
golang.org/x/time v0.10.0
|
||||||
)
|
)
|
||||||
|
|
@ -34,6 +34,6 @@ require (
|
||||||
golang.org/x/net v0.34.0 // indirect
|
golang.org/x/net v0.34.0 // indirect
|
||||||
golang.org/x/sys v0.30.0 // indirect
|
golang.org/x/sys v0.30.0 // indirect
|
||||||
golang.org/x/text v0.22.0 // indirect
|
golang.org/x/text v0.22.0 // indirect
|
||||||
google.golang.org/protobuf v1.36.4 // indirect
|
google.golang.org/protobuf v1.36.5 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
|
|
||||||
8
go.sum
8
go.sum
|
|
@ -1,7 +1,7 @@
|
||||||
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
|
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
|
||||||
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||||
github.com/WJQSERVER-STUDIO/go-utils/logger v1.2.0 h1:6JkiVGRasfdBxEV8Qnv5x00Bq4qX1Tg6f58Ar/D2YX0=
|
github.com/WJQSERVER-STUDIO/go-utils/logger v1.3.0 h1:rOvutC4zYfvtSGN2CNZrycjtq8dLpfu7ypy7tTEErPY=
|
||||||
github.com/WJQSERVER-STUDIO/go-utils/logger v1.2.0/go.mod h1:oW884JCCPDU6c906LI0uKXndWLiRvjb9LkGYC2cqRO8=
|
github.com/WJQSERVER-STUDIO/go-utils/logger v1.3.0/go.mod h1:oW884JCCPDU6c906LI0uKXndWLiRvjb9LkGYC2cqRO8=
|
||||||
github.com/bytedance/sonic v1.12.8 h1:4xYRVRlXIgvSZ4e8iVTlMF5szgpXd4AfvuWgA8I8lgs=
|
github.com/bytedance/sonic v1.12.8 h1:4xYRVRlXIgvSZ4e8iVTlMF5szgpXd4AfvuWgA8I8lgs=
|
||||||
github.com/bytedance/sonic v1.12.8/go.mod h1:uVvFidNmlt9+wa31S1urfwwthTWteBgG0hWuoKAXTx8=
|
github.com/bytedance/sonic v1.12.8/go.mod h1:uVvFidNmlt9+wa31S1urfwwthTWteBgG0hWuoKAXTx8=
|
||||||
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||||
|
|
@ -80,8 +80,8 @@ golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
||||||
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
||||||
golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4=
|
golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4=
|
||||||
golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||||
google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
|
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
|
||||||
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
|
|
||||||
22
main.go
22
main.go
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"log"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
|
@ -40,6 +39,8 @@ var (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
logw = logger.Logw
|
logw = logger.Logw
|
||||||
|
LogDump = logger.LogDump
|
||||||
|
logDebug = logger.LogDebug
|
||||||
logInfo = logger.LogInfo
|
logInfo = logger.LogInfo
|
||||||
logWarning = logger.LogWarning
|
logWarning = logger.LogWarning
|
||||||
logError = logger.LogError
|
logError = logger.LogError
|
||||||
|
|
@ -53,20 +54,24 @@ func loadConfig() {
|
||||||
var err error
|
var err error
|
||||||
cfg, err = config.LoadConfig(cfgfile)
|
cfg, err = config.LoadConfig(cfgfile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to load config: %v", err)
|
fmt.Printf("Failed to load config: %v\n", err)
|
||||||
}
|
}
|
||||||
|
if cfg.Server.Debug {
|
||||||
fmt.Println("Config File Path: ", cfgfile)
|
fmt.Println("Config File Path: ", cfgfile)
|
||||||
fmt.Printf("Loaded config: %v\n", cfg)
|
fmt.Printf("Loaded config: %v\n", cfg)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupLogger(cfg *config.Config) {
|
func setupLogger(cfg *config.Config) {
|
||||||
var err error
|
var err error
|
||||||
err = logger.Init(cfg.Log.LogFilePath, cfg.Log.MaxLogSize)
|
err = logger.Init(cfg.Log.LogFilePath, cfg.Log.MaxLogSize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to initialize logger: %v", err)
|
fmt.Printf("Failed to initialize logger: %v\n", err)
|
||||||
}
|
}
|
||||||
logInfo("Config File Path: ", cfgfile)
|
logger.SetLogLevel(cfg.Log.Level)
|
||||||
logInfo("Loaded config: %v\n", cfg)
|
fmt.Printf("Log Level: %s\n", cfg.Log.Level)
|
||||||
|
logDebug("Config File Path: ", cfgfile)
|
||||||
|
logDebug("Loaded config: %v\n", cfg)
|
||||||
logInfo("Init Completed")
|
logInfo("Init Completed")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -87,7 +92,6 @@ func setupRateLimit(cfg *config.Config) {
|
||||||
} else {
|
} else {
|
||||||
logError("Invalid RateLimit Method: %s", cfg.RateLimit.RateMethod)
|
logError("Invalid RateLimit Method: %s", cfg.RateLimit.RateMethod)
|
||||||
}
|
}
|
||||||
logInfo("Rate Limit Loaded")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -116,6 +120,8 @@ func init() {
|
||||||
runMode = "release"
|
runMode = "release"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logDebug("Run Mode: %s", runMode)
|
||||||
|
|
||||||
gin.LoggerWithWriter(io.Discard)
|
gin.LoggerWithWriter(io.Discard)
|
||||||
router = gin.New()
|
router = gin.New()
|
||||||
router.Use(gin.Recovery())
|
router.Use(gin.Recovery())
|
||||||
|
|
@ -141,7 +147,7 @@ func init() {
|
||||||
} else if !cfg.Pages.Enabled {
|
} else if !cfg.Pages.Enabled {
|
||||||
pages, err := fs.Sub(pagesFS, "pages")
|
pages, err := fs.Sub(pagesFS, "pages")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed when processing pages: %s", err)
|
logError("Failed when processing pages: %s", err)
|
||||||
}
|
}
|
||||||
router.GET("/", gin.WrapH(http.FileServer(http.FS(pages))))
|
router.GET("/", gin.WrapH(http.FileServer(http.FS(pages))))
|
||||||
router.GET("/favicon.ico", gin.WrapH(http.FileServer(http.FS(pages))))
|
router.GET("/favicon.ico", gin.WrapH(http.FileServer(http.FS(pages))))
|
||||||
|
|
@ -152,6 +158,8 @@ func init() {
|
||||||
})
|
})
|
||||||
|
|
||||||
fmt.Printf("GHProxy Version: %s\n", version)
|
fmt.Printf("GHProxy Version: %s\n", version)
|
||||||
|
fmt.Printf("A Go Based High-Performance Github Proxy \n")
|
||||||
|
fmt.Printf("Made by WJQSERVER-STUDIO\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ func AuthPassThrough(c *gin.Context, cfg *config.Config, req *http.Request) {
|
||||||
if cfg.Auth.PassThrough {
|
if cfg.Auth.PassThrough {
|
||||||
token := c.Query("token")
|
token := c.Query("token")
|
||||||
if token != "" {
|
if token != "" {
|
||||||
|
logDebug("%s %s %s %s %s Auth-PassThrough: token %s", c.ClientIP(), c.Request.Method, c.Request.URL.String(), c.Request.Header.Get("User-Agent"), c.Request.Proto, token)
|
||||||
switch cfg.Auth.AuthMethod {
|
switch cfg.Auth.AuthMethod {
|
||||||
case "parameters":
|
case "parameters":
|
||||||
if !cfg.Auth.Enabled {
|
if !cfg.Auth.Enabled {
|
||||||
|
|
|
||||||
|
|
@ -54,12 +54,12 @@ func initChunkedHTTPClient() {
|
||||||
|
|
||||||
func ChunkedProxyRequest(c *gin.Context, u string, cfg *config.Config, mode string, runMode string) {
|
func ChunkedProxyRequest(c *gin.Context, u string, cfg *config.Config, mode string, runMode string) {
|
||||||
method := c.Request.Method
|
method := c.Request.Method
|
||||||
logInfo("%s %s %s %s %s", c.ClientIP(), method, u, c.Request.Header.Get("User-Agent"), c.Request.Proto)
|
logInfo("%s %s %s %s %s Chunked-Proxy-Request", c.ClientIP(), method, u, c.Request.Header.Get("User-Agent"), c.Request.Proto)
|
||||||
|
|
||||||
// 发送HEAD请求, 预获取Content-Length
|
// 发送HEAD请求, 预获取Content-Length
|
||||||
headReq, err := http.NewRequest("HEAD", u, nil)
|
headReq, err := http.NewRequest("HEAD", u, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
HandleError(c, fmt.Sprintf("创建HEAD请求失败: %v", err))
|
HandleError(c, fmt.Sprintf("Failed to create request: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
setRequestHeaders(c, headReq)
|
setRequestHeaders(c, headReq)
|
||||||
|
|
@ -108,7 +108,7 @@ func ChunkedProxyRequest(c *gin.Context, u string, cfg *config.Config, mode stri
|
||||||
// 创建请求
|
// 创建请求
|
||||||
req, err := http.NewRequest(method, u, bodyReader)
|
req, err := http.NewRequest(method, u, bodyReader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
HandleError(c, fmt.Sprintf("创建请求失败: %v", err))
|
HandleError(c, fmt.Sprintf("Failed to create request: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -118,7 +118,7 @@ func ChunkedProxyRequest(c *gin.Context, u string, cfg *config.Config, mode stri
|
||||||
|
|
||||||
resp, err := cclient.Do(req)
|
resp, err := cclient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
HandleError(c, fmt.Sprintf("发送请求失败: %v", err))
|
HandleError(c, fmt.Sprintf("Failed to send request: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
@ -171,7 +171,7 @@ func ChunkedProxyRequest(c *gin.Context, u string, cfg *config.Config, mode stri
|
||||||
|
|
||||||
_, err = io.CopyBuffer(c.Writer, resp.Body, buffer)
|
_, err = io.CopyBuffer(c.Writer, resp.Body, buffer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logError("%s %s %s %s %s 响应复制错误: %v", c.ClientIP(), method, u, c.Request.Header.Get("User-Agent"), c.Request.Proto, err)
|
logError("%s %s %s %s %s Failed to copy response body: %v", c.ClientIP(), method, u, c.Request.Header.Get("User-Agent"), c.Request.Proto, err)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
c.Writer.Flush() // 确保刷入
|
c.Writer.Flush() // 确保刷入
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ func GitReq(c *gin.Context, u string, cfg *config.Config, mode string, runMode s
|
||||||
// 发送HEAD请求, 预获取Content-Length
|
// 发送HEAD请求, 预获取Content-Length
|
||||||
headReq, err := http.NewRequest("HEAD", u, nil)
|
headReq, err := http.NewRequest("HEAD", u, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
HandleError(c, fmt.Sprintf("创建HEAD请求失败: %v", err))
|
HandleError(c, fmt.Sprintf("Failed to create request: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
setRequestHeaders(c, headReq)
|
setRequestHeaders(c, headReq)
|
||||||
|
|
@ -80,7 +80,7 @@ func GitReq(c *gin.Context, u string, cfg *config.Config, mode string, runMode s
|
||||||
// 创建请求
|
// 创建请求
|
||||||
req, err := http.NewRequest(method, u, bodyReader)
|
req, err := http.NewRequest(method, u, bodyReader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
HandleError(c, fmt.Sprintf("创建请求失败: %v", err))
|
HandleError(c, fmt.Sprintf("Failed to create request: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
setRequestHeaders(c, req)
|
setRequestHeaders(c, req)
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,8 @@ func NoRouteHandler(cfg *config.Config, limiter *rate.RateLimiter, iplimiter *ra
|
||||||
username, repo := MatchUserRepo(rawPath, cfg, c, matches) // 匹配用户名和仓库名
|
username, repo := MatchUserRepo(rawPath, cfg, c, matches) // 匹配用户名和仓库名
|
||||||
|
|
||||||
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)
|
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)
|
||||||
|
// dump log 记录详细信息 c.ClientIP(), c.Request.Method, rawPath, c.Request.Header.Get("User-Agent"), c.Request.Proto, full Header
|
||||||
|
LogDump("%s %s %s %s %s %s", c.ClientIP(), c.Request.Method, rawPath, c.Request.Header.Get("User-Agent"), c.Request.Proto, c.Request.Header)
|
||||||
repouser := fmt.Sprintf("%s/%s", username, repo)
|
repouser := fmt.Sprintf("%s/%s", username, repo)
|
||||||
|
|
||||||
// 白名单检查
|
// 白名单检查
|
||||||
|
|
@ -83,7 +85,7 @@ func NoRouteHandler(cfg *config.Config, limiter *rate.RateLimiter, iplimiter *ra
|
||||||
matches = CheckURL(rawPath, c)
|
matches = CheckURL(rawPath, c)
|
||||||
if matches == nil {
|
if matches == nil {
|
||||||
c.AbortWithStatus(http.StatusNotFound)
|
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)
|
logWarning("%s %s %s %s %s 404-NOMATCH", c.ClientIP(), c.Request.Method, rawPath, c.Request.Header.Get("User-Agent"), c.Request.Proto)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -91,7 +93,7 @@ func NoRouteHandler(cfg *config.Config, limiter *rate.RateLimiter, iplimiter *ra
|
||||||
if exps[5].MatchString(rawPath) {
|
if exps[5].MatchString(rawPath) {
|
||||||
if cfg.Auth.AuthMethod != "header" || !cfg.Auth.Enabled {
|
if cfg.Auth.AuthMethod != "header" || !cfg.Auth.Enabled {
|
||||||
c.JSON(http.StatusForbidden, gin.H{"error": "HeaderAuth is not enabled."})
|
c.JSON(http.StatusForbidden, gin.H{"error": "HeaderAuth is not enabled."})
|
||||||
logWarning("%s %s %s %s %s HeaderAuth-Error: HeaderAuth is not enabled.", c.ClientIP(), c.Request.Method, rawPath, c.Request.Header.Get("User-Agent"), c.Request.Proto)
|
logError("%s %s %s %s %s HeaderAuth-Error: HeaderAuth is not enabled.", c.ClientIP(), c.Request.Method, rawPath, c.Request.Header.Get("User-Agent"), c.Request.Proto)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -110,7 +112,7 @@ func NoRouteHandler(cfg *config.Config, limiter *rate.RateLimiter, iplimiter *ra
|
||||||
}
|
}
|
||||||
|
|
||||||
// IP METHOD URL USERAGENT PROTO 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)
|
logDebug("%s %s %s %s %s Matches: %v", c.ClientIP(), c.Request.Method, rawPath, c.Request.Header.Get("User-Agent"), c.Request.Proto, matches)
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case exps[0].MatchString(rawPath), exps[1].MatchString(rawPath), exps[3].MatchString(rawPath), exps[4].MatchString(rawPath):
|
case exps[0].MatchString(rawPath), exps[1].MatchString(rawPath), exps[3].MatchString(rawPath), exps[4].MatchString(rawPath):
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ var (
|
||||||
// 提取用户名和仓库名
|
// 提取用户名和仓库名
|
||||||
func MatchUserRepo(rawPath string, cfg *config.Config, c *gin.Context, matches []string) (string, string) {
|
func MatchUserRepo(rawPath string, cfg *config.Config, c *gin.Context, matches []string) (string, string) {
|
||||||
if gistMatches := gistRegex.FindStringSubmatch(rawPath); len(gistMatches) == 3 {
|
if gistMatches := gistRegex.FindStringSubmatch(rawPath); len(gistMatches) == 3 {
|
||||||
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])
|
LogDump("%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], ""
|
return gistMatches[1], ""
|
||||||
}
|
}
|
||||||
// 定义路径
|
// 定义路径
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ import (
|
||||||
// 日志模块
|
// 日志模块
|
||||||
var (
|
var (
|
||||||
logw = logger.Logw
|
logw = logger.Logw
|
||||||
|
LogDump = logger.LogDump
|
||||||
|
logDebug = logger.LogDebug
|
||||||
logInfo = logger.LogInfo
|
logInfo = logger.LogInfo
|
||||||
logWarning = logger.LogWarning
|
logWarning = logger.LogWarning
|
||||||
logError = logger.LogError
|
logError = logger.LogError
|
||||||
|
|
@ -31,6 +33,7 @@ var exps = []*regexp.Regexp{
|
||||||
func readRequestBody(c *gin.Context) ([]byte, error) {
|
func readRequestBody(c *gin.Context) ([]byte, error) {
|
||||||
body, err := io.ReadAll(c.Request.Body)
|
body, err := io.ReadAll(c.Request.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
logError("failed to read request body: %v", err)
|
||||||
return nil, fmt.Errorf("failed to read request body: %v", err)
|
return nil, fmt.Errorf("failed to read request body: %v", err)
|
||||||
}
|
}
|
||||||
defer c.Request.Body.Close()
|
defer c.Request.Body.Close()
|
||||||
|
|
@ -59,7 +62,7 @@ func SendRequest(c *gin.Context, req *req.Request, method, url string) (*req.Res
|
||||||
|
|
||||||
func HandleError(c *gin.Context, message string) {
|
func HandleError(c *gin.Context, message string) {
|
||||||
c.String(http.StatusInternalServerError, fmt.Sprintf("server error %v", message))
|
c.String(http.StatusInternalServerError, fmt.Sprintf("server error %v", message))
|
||||||
logWarning(message)
|
logError(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckURL(u string, c *gin.Context) []string {
|
func CheckURL(u string, c *gin.Context) []string {
|
||||||
|
|
@ -69,7 +72,7 @@ func CheckURL(u string, c *gin.Context) []string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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)
|
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)
|
logError(errMsg)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@ import (
|
||||||
// 日志输出
|
// 日志输出
|
||||||
var (
|
var (
|
||||||
logw = logger.Logw
|
logw = logger.Logw
|
||||||
|
LogDump = logger.LogDump
|
||||||
|
logDebug = logger.LogDebug
|
||||||
logInfo = logger.LogInfo
|
logInfo = logger.LogInfo
|
||||||
logWarning = logger.LogWarning
|
logWarning = logger.LogWarning
|
||||||
logError = logger.LogError
|
logError = logger.LogError
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue