支持禁用前端静态文件路由

This commit is contained in:
user123
2026-01-26 23:06:05 +08:00
parent 6659e977ae
commit 11c34459ca
5 changed files with 99 additions and 67 deletions

View File

@@ -6,6 +6,7 @@ port = 5000
fileSize = 2147483648
# HTTP/2 多路复用
enableH2C = false
enableFrontend = true
[rateLimit]
# 每个IP每周期允许的请求数

View File

@@ -22,10 +22,11 @@ type RegistryMapping struct {
// AppConfig 应用配置结构体
type AppConfig struct {
Server struct {
Host string `toml:"host"`
Port int `toml:"port"`
FileSize int64 `toml:"fileSize"`
EnableH2C bool `toml:"enableH2C"`
Host string `toml:"host"`
Port int `toml:"port"`
FileSize int64 `toml:"fileSize"`
EnableH2C bool `toml:"enableH2C"`
EnableFrontend bool `toml:"enableFrontend"`
} `toml:"server"`
RateLimit struct {
@@ -70,15 +71,17 @@ var (
func DefaultConfig() *AppConfig {
return &AppConfig{
Server: struct {
Host string `toml:"host"`
Port int `toml:"port"`
FileSize int64 `toml:"fileSize"`
EnableH2C bool `toml:"enableH2C"`
Host string `toml:"host"`
Port int `toml:"port"`
FileSize int64 `toml:"fileSize"`
EnableH2C bool `toml:"enableH2C"`
EnableFrontend bool `toml:"enableFrontend"`
}{
Host: "0.0.0.0",
Port: 5000,
FileSize: 2 * 1024 * 1024 * 1024, // 2GB
EnableH2C: false, // 默认关闭H2C
Host: "0.0.0.0",
Port: 5000,
FileSize: 2 * 1024 * 1024 * 1024,
EnableH2C: false,
EnableFrontend: true,
},
RateLimit: struct {
RequestLimit int `toml:"requestLimit"`
@@ -227,6 +230,11 @@ func overrideFromEnv(cfg *AppConfig) {
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 size, err := strconv.ParseInt(val, 10, 64); err == nil && size > 0 {
cfg.Server.FileSize = size

View File

@@ -129,7 +129,7 @@ func proxyGitHubWithRedirect(c *gin.Context, u string, redirectCount int) {
fmt.Printf("关闭响应体失败: %v\n", err)
}
}()
// 检查并处理被阻止的内容类型
if c.Request.Method == "GET" {
if contentType := resp.Header.Get("Content-Type"); blockedContentTypes[strings.ToLower(strings.Split(contentType, ";")[0])] {

View File

@@ -40,6 +40,80 @@ var (
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() {
// 加载配置
if err := config.LoadConfig(); err != nil {
@@ -62,60 +136,9 @@ func main() {
// 初始化防抖器
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()
router := buildRouter(cfg)
fmt.Printf("HubProxy 启动成功\n")
fmt.Printf("监听地址: %s:%d\n", cfg.Server.Host, cfg.Server.Port)
fmt.Printf("限流配置: %d请求/%g小时\n", cfg.RateLimit.RequestLimit, cfg.RateLimit.PeriodHours)

View File

@@ -104,4 +104,4 @@ func transformURL(url, host string) string {
host = strings.TrimSuffix(host, "/")
return host + "/" + url
}
}