支持禁用前端静态文件路由
This commit is contained in:
@@ -6,6 +6,7 @@ port = 5000
|
|||||||
fileSize = 2147483648
|
fileSize = 2147483648
|
||||||
# HTTP/2 多路复用
|
# HTTP/2 多路复用
|
||||||
enableH2C = false
|
enableH2C = false
|
||||||
|
enableFrontend = true
|
||||||
|
|
||||||
[rateLimit]
|
[rateLimit]
|
||||||
# 每个IP每周期允许的请求数
|
# 每个IP每周期允许的请求数
|
||||||
|
|||||||
@@ -22,10 +22,11 @@ type RegistryMapping struct {
|
|||||||
// AppConfig 应用配置结构体
|
// AppConfig 应用配置结构体
|
||||||
type AppConfig struct {
|
type AppConfig struct {
|
||||||
Server struct {
|
Server struct {
|
||||||
Host string `toml:"host"`
|
Host string `toml:"host"`
|
||||||
Port int `toml:"port"`
|
Port int `toml:"port"`
|
||||||
FileSize int64 `toml:"fileSize"`
|
FileSize int64 `toml:"fileSize"`
|
||||||
EnableH2C bool `toml:"enableH2C"`
|
EnableH2C bool `toml:"enableH2C"`
|
||||||
|
EnableFrontend bool `toml:"enableFrontend"`
|
||||||
} `toml:"server"`
|
} `toml:"server"`
|
||||||
|
|
||||||
RateLimit struct {
|
RateLimit struct {
|
||||||
@@ -70,15 +71,17 @@ var (
|
|||||||
func DefaultConfig() *AppConfig {
|
func DefaultConfig() *AppConfig {
|
||||||
return &AppConfig{
|
return &AppConfig{
|
||||||
Server: struct {
|
Server: struct {
|
||||||
Host string `toml:"host"`
|
Host string `toml:"host"`
|
||||||
Port int `toml:"port"`
|
Port int `toml:"port"`
|
||||||
FileSize int64 `toml:"fileSize"`
|
FileSize int64 `toml:"fileSize"`
|
||||||
EnableH2C bool `toml:"enableH2C"`
|
EnableH2C bool `toml:"enableH2C"`
|
||||||
|
EnableFrontend bool `toml:"enableFrontend"`
|
||||||
}{
|
}{
|
||||||
Host: "0.0.0.0",
|
Host: "0.0.0.0",
|
||||||
Port: 5000,
|
Port: 5000,
|
||||||
FileSize: 2 * 1024 * 1024 * 1024, // 2GB
|
FileSize: 2 * 1024 * 1024 * 1024,
|
||||||
EnableH2C: false, // 默认关闭H2C
|
EnableH2C: false,
|
||||||
|
EnableFrontend: true,
|
||||||
},
|
},
|
||||||
RateLimit: struct {
|
RateLimit: struct {
|
||||||
RequestLimit int `toml:"requestLimit"`
|
RequestLimit int `toml:"requestLimit"`
|
||||||
@@ -227,6 +230,11 @@ func overrideFromEnv(cfg *AppConfig) {
|
|||||||
cfg.Server.EnableH2C = enable
|
cfg.Server.EnableH2C = enable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if val := os.Getenv("ENABLE_FRONTEND"); val != "" {
|
||||||
|
if enable, err := strconv.ParseBool(val); err == nil {
|
||||||
|
cfg.Server.EnableFrontend = enable
|
||||||
|
}
|
||||||
|
}
|
||||||
if val := os.Getenv("MAX_FILE_SIZE"); val != "" {
|
if val := os.Getenv("MAX_FILE_SIZE"); val != "" {
|
||||||
if size, err := strconv.ParseInt(val, 10, 64); err == nil && size > 0 {
|
if size, err := strconv.ParseInt(val, 10, 64); err == nil && size > 0 {
|
||||||
cfg.Server.FileSize = size
|
cfg.Server.FileSize = size
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ func proxyGitHubWithRedirect(c *gin.Context, u string, redirectCount int) {
|
|||||||
fmt.Printf("关闭响应体失败: %v\n", err)
|
fmt.Printf("关闭响应体失败: %v\n", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// 检查并处理被阻止的内容类型
|
// 检查并处理被阻止的内容类型
|
||||||
if c.Request.Method == "GET" {
|
if c.Request.Method == "GET" {
|
||||||
if contentType := resp.Header.Get("Content-Type"); blockedContentTypes[strings.ToLower(strings.Split(contentType, ";")[0])] {
|
if contentType := resp.Header.Get("Content-Type"); blockedContentTypes[strings.ToLower(strings.Split(contentType, ";")[0])] {
|
||||||
|
|||||||
129
src/main.go
129
src/main.go
@@ -40,6 +40,80 @@ var (
|
|||||||
serviceStartTime = time.Now()
|
serviceStartTime = time.Now()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func buildRouter(cfg *config.AppConfig) *gin.Engine {
|
||||||
|
gin.SetMode(gin.ReleaseMode)
|
||||||
|
router := gin.Default()
|
||||||
|
|
||||||
|
// 全局Panic恢复保护
|
||||||
|
router.Use(gin.CustomRecovery(func(c *gin.Context, recovered interface{}) {
|
||||||
|
log.Printf("🚨 Panic recovered: %v", recovered)
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{
|
||||||
|
"error": "Internal server error",
|
||||||
|
"code": "INTERNAL_ERROR",
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
|
||||||
|
// 全局限流中间件
|
||||||
|
router.Use(utils.RateLimitMiddleware(globalLimiter))
|
||||||
|
|
||||||
|
// 初始化监控端点
|
||||||
|
initHealthRoutes(router)
|
||||||
|
|
||||||
|
// 初始化镜像tar下载路由
|
||||||
|
handlers.InitImageTarRoutes(router)
|
||||||
|
|
||||||
|
if cfg.Server.EnableFrontend {
|
||||||
|
router.GET("/", func(c *gin.Context) {
|
||||||
|
serveEmbedFile(c, "public/index.html")
|
||||||
|
})
|
||||||
|
router.GET("/public/*filepath", func(c *gin.Context) {
|
||||||
|
filepath := strings.TrimPrefix(c.Param("filepath"), "/")
|
||||||
|
serveEmbedFile(c, "public/"+filepath)
|
||||||
|
})
|
||||||
|
|
||||||
|
router.GET("/images.html", func(c *gin.Context) {
|
||||||
|
serveEmbedFile(c, "public/images.html")
|
||||||
|
})
|
||||||
|
router.GET("/search.html", func(c *gin.Context) {
|
||||||
|
serveEmbedFile(c, "public/search.html")
|
||||||
|
})
|
||||||
|
router.GET("/favicon.ico", func(c *gin.Context) {
|
||||||
|
serveEmbedFile(c, "public/favicon.ico")
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
router.GET("/", func(c *gin.Context) {
|
||||||
|
c.Status(http.StatusNotFound)
|
||||||
|
})
|
||||||
|
router.GET("/public/*filepath", func(c *gin.Context) {
|
||||||
|
c.Status(http.StatusNotFound)
|
||||||
|
})
|
||||||
|
router.GET("/images.html", func(c *gin.Context) {
|
||||||
|
c.Status(http.StatusNotFound)
|
||||||
|
})
|
||||||
|
router.GET("/search.html", func(c *gin.Context) {
|
||||||
|
c.Status(http.StatusNotFound)
|
||||||
|
})
|
||||||
|
router.GET("/favicon.ico", func(c *gin.Context) {
|
||||||
|
c.Status(http.StatusNotFound)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 注册dockerhub搜索路由
|
||||||
|
handlers.RegisterSearchRoute(router)
|
||||||
|
|
||||||
|
// 注册Docker认证路由
|
||||||
|
router.Any("/token", handlers.ProxyDockerAuthGin)
|
||||||
|
router.Any("/token/*path", handlers.ProxyDockerAuthGin)
|
||||||
|
|
||||||
|
// 注册Docker Registry代理路由
|
||||||
|
router.Any("/v2/*path", handlers.ProxyDockerRegistryGin)
|
||||||
|
|
||||||
|
// 注册GitHub代理路由(NoRoute处理器)
|
||||||
|
router.NoRoute(handlers.GitHubProxyHandler)
|
||||||
|
|
||||||
|
return router
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// 加载配置
|
// 加载配置
|
||||||
if err := config.LoadConfig(); err != nil {
|
if err := config.LoadConfig(); err != nil {
|
||||||
@@ -62,60 +136,9 @@ func main() {
|
|||||||
// 初始化防抖器
|
// 初始化防抖器
|
||||||
handlers.InitDebouncer()
|
handlers.InitDebouncer()
|
||||||
|
|
||||||
gin.SetMode(gin.ReleaseMode)
|
|
||||||
router := gin.Default()
|
|
||||||
|
|
||||||
// 全局Panic恢复保护
|
|
||||||
router.Use(gin.CustomRecovery(func(c *gin.Context, recovered interface{}) {
|
|
||||||
log.Printf("🚨 Panic recovered: %v", recovered)
|
|
||||||
c.JSON(http.StatusInternalServerError, gin.H{
|
|
||||||
"error": "Internal server error",
|
|
||||||
"code": "INTERNAL_ERROR",
|
|
||||||
})
|
|
||||||
}))
|
|
||||||
|
|
||||||
// 全局限流中间件
|
|
||||||
router.Use(utils.RateLimitMiddleware(globalLimiter))
|
|
||||||
|
|
||||||
// 初始化监控端点
|
|
||||||
initHealthRoutes(router)
|
|
||||||
|
|
||||||
// 初始化镜像tar下载路由
|
|
||||||
handlers.InitImageTarRoutes(router)
|
|
||||||
|
|
||||||
// 静态文件路由
|
|
||||||
router.GET("/", func(c *gin.Context) {
|
|
||||||
serveEmbedFile(c, "public/index.html")
|
|
||||||
})
|
|
||||||
router.GET("/public/*filepath", func(c *gin.Context) {
|
|
||||||
filepath := strings.TrimPrefix(c.Param("filepath"), "/")
|
|
||||||
serveEmbedFile(c, "public/"+filepath)
|
|
||||||
})
|
|
||||||
|
|
||||||
router.GET("/images.html", func(c *gin.Context) {
|
|
||||||
serveEmbedFile(c, "public/images.html")
|
|
||||||
})
|
|
||||||
router.GET("/search.html", func(c *gin.Context) {
|
|
||||||
serveEmbedFile(c, "public/search.html")
|
|
||||||
})
|
|
||||||
router.GET("/favicon.ico", func(c *gin.Context) {
|
|
||||||
serveEmbedFile(c, "public/favicon.ico")
|
|
||||||
})
|
|
||||||
|
|
||||||
// 注册dockerhub搜索路由
|
|
||||||
handlers.RegisterSearchRoute(router)
|
|
||||||
|
|
||||||
// 注册Docker认证路由
|
|
||||||
router.Any("/token", handlers.ProxyDockerAuthGin)
|
|
||||||
router.Any("/token/*path", handlers.ProxyDockerAuthGin)
|
|
||||||
|
|
||||||
// 注册Docker Registry代理路由
|
|
||||||
router.Any("/v2/*path", handlers.ProxyDockerRegistryGin)
|
|
||||||
|
|
||||||
// 注册GitHub代理路由(NoRoute处理器)
|
|
||||||
router.NoRoute(handlers.GitHubProxyHandler)
|
|
||||||
|
|
||||||
cfg := config.GetConfig()
|
cfg := config.GetConfig()
|
||||||
|
router := buildRouter(cfg)
|
||||||
|
|
||||||
fmt.Printf("HubProxy 启动成功\n")
|
fmt.Printf("HubProxy 启动成功\n")
|
||||||
fmt.Printf("监听地址: %s:%d\n", cfg.Server.Host, cfg.Server.Port)
|
fmt.Printf("监听地址: %s:%d\n", cfg.Server.Host, cfg.Server.Port)
|
||||||
fmt.Printf("限流配置: %d请求/%g小时\n", cfg.RateLimit.RequestLimit, cfg.RateLimit.PeriodHours)
|
fmt.Printf("限流配置: %d请求/%g小时\n", cfg.RateLimit.RequestLimit, cfg.RateLimit.PeriodHours)
|
||||||
|
|||||||
@@ -104,4 +104,4 @@ func transformURL(url, host string) string {
|
|||||||
host = strings.TrimSuffix(host, "/")
|
host = strings.TrimSuffix(host, "/")
|
||||||
|
|
||||||
return host + "/" + url
|
return host + "/" + url
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user