go fmt .
This commit is contained in:
@@ -385,12 +385,11 @@ func (is *ImageStreamer) streamDockerFormatWithReturn(ctx context.Context, tarWr
|
||||
log.Printf("已处理层 %d/%d", i+1, len(layers))
|
||||
}
|
||||
|
||||
|
||||
// 构建单个镜像的manifest信息
|
||||
singleManifest := map[string]interface{}{
|
||||
"Config": configDigest.String() + ".json",
|
||||
"RepoTags": []string{imageRef},
|
||||
"Layers": func() []string {
|
||||
"Layers": func() []string {
|
||||
var layers []string
|
||||
for _, digest := range layerDigests {
|
||||
layers = append(layers, digest+"/layer.tar")
|
||||
@@ -549,8 +548,8 @@ func (is *ImageStreamer) selectPlatformImage(desc *remote.Descriptor, options *S
|
||||
}
|
||||
|
||||
if m.Platform.OS == targetOS &&
|
||||
m.Platform.Architecture == targetArch &&
|
||||
m.Platform.Variant == targetVariant {
|
||||
m.Platform.Architecture == targetArch &&
|
||||
m.Platform.Variant == targetVariant {
|
||||
selectedDesc = &m
|
||||
break
|
||||
}
|
||||
@@ -632,7 +631,7 @@ func handleDirectImageDownload(c *gin.Context) {
|
||||
|
||||
if !singleImageDebouncer.ShouldAllow(userID, contentKey) {
|
||||
c.JSON(http.StatusTooManyRequests, gin.H{
|
||||
"error": "请求过于频繁,请稍后再试",
|
||||
"error": "请求过于频繁,请稍后再试",
|
||||
"retry_after": 5,
|
||||
})
|
||||
return
|
||||
@@ -692,7 +691,7 @@ func handleSimpleBatchDownload(c *gin.Context) {
|
||||
|
||||
if !batchImageDebouncer.ShouldAllow(userID, contentKey) {
|
||||
c.JSON(http.StatusTooManyRequests, gin.H{
|
||||
"error": "批量下载请求过于频繁,请稍后再试",
|
||||
"error": "批量下载请求过于频繁,请稍后再试",
|
||||
"retry_after": 60,
|
||||
})
|
||||
return
|
||||
|
||||
@@ -122,7 +122,6 @@ func main() {
|
||||
// 注册Docker Registry代理路由
|
||||
router.Any("/v2/*path", ProxyDockerRegistryGin)
|
||||
|
||||
|
||||
// 注册NoRoute处理器
|
||||
router.NoRoute(handler)
|
||||
|
||||
@@ -177,12 +176,10 @@ func handler(c *gin.Context) {
|
||||
proxyRequest(c, rawPath)
|
||||
}
|
||||
|
||||
|
||||
func proxyRequest(c *gin.Context, u string) {
|
||||
proxyWithRedirect(c, u, 0)
|
||||
}
|
||||
|
||||
|
||||
func proxyWithRedirect(c *gin.Context, u string, redirectCount int) {
|
||||
// 限制最大重定向次数,防止无限递归
|
||||
const maxRedirects = 20
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
const (
|
||||
// 清理间隔
|
||||
CleanupInterval = 10 * time.Minute
|
||||
MaxIPCacheSize = 10000
|
||||
MaxIPCacheSize = 10000
|
||||
)
|
||||
|
||||
// IPRateLimiter IP限流器结构体
|
||||
@@ -233,7 +233,7 @@ func RateLimitMiddleware(limiter *IPRateLimiter) gin.HandlerFunc {
|
||||
// 静态文件豁免:跳过限流检查
|
||||
path := c.Request.URL.Path
|
||||
if path == "/" || path == "/favicon.ico" || path == "/images.html" || path == "/search.html" ||
|
||||
strings.HasPrefix(path, "/public/") {
|
||||
strings.HasPrefix(path, "/public/") {
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
@@ -299,5 +299,3 @@ func RateLimitMiddleware(limiter *IPRateLimiter) gin.HandlerFunc {
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -25,27 +25,27 @@ type SearchResult struct {
|
||||
|
||||
// Repository 仓库信息
|
||||
type Repository struct {
|
||||
Name string `json:"repo_name"`
|
||||
Description string `json:"short_description"`
|
||||
IsOfficial bool `json:"is_official"`
|
||||
IsAutomated bool `json:"is_automated"`
|
||||
StarCount int `json:"star_count"`
|
||||
PullCount int `json:"pull_count"`
|
||||
RepoOwner string `json:"repo_owner"`
|
||||
LastUpdated string `json:"last_updated"`
|
||||
Status int `json:"status"`
|
||||
Organization string `json:"affiliation"`
|
||||
PullsLastWeek int `json:"pulls_last_week"`
|
||||
Namespace string `json:"namespace"`
|
||||
Name string `json:"repo_name"`
|
||||
Description string `json:"short_description"`
|
||||
IsOfficial bool `json:"is_official"`
|
||||
IsAutomated bool `json:"is_automated"`
|
||||
StarCount int `json:"star_count"`
|
||||
PullCount int `json:"pull_count"`
|
||||
RepoOwner string `json:"repo_owner"`
|
||||
LastUpdated string `json:"last_updated"`
|
||||
Status int `json:"status"`
|
||||
Organization string `json:"affiliation"`
|
||||
PullsLastWeek int `json:"pulls_last_week"`
|
||||
Namespace string `json:"namespace"`
|
||||
}
|
||||
|
||||
// TagInfo 标签信息
|
||||
type TagInfo struct {
|
||||
Name string `json:"name"`
|
||||
FullSize int64 `json:"full_size"`
|
||||
LastUpdated time.Time `json:"last_updated"`
|
||||
LastPusher string `json:"last_pusher"`
|
||||
Images []Image `json:"images"`
|
||||
Name string `json:"name"`
|
||||
FullSize int64 `json:"full_size"`
|
||||
LastUpdated time.Time `json:"last_updated"`
|
||||
LastPusher string `json:"last_pusher"`
|
||||
Images []Image `json:"images"`
|
||||
Vulnerabilities struct {
|
||||
Critical int `json:"critical"`
|
||||
High int `json:"high"`
|
||||
@@ -77,9 +77,9 @@ const (
|
||||
)
|
||||
|
||||
type Cache struct {
|
||||
data map[string]cacheEntry
|
||||
mu sync.RWMutex
|
||||
maxSize int
|
||||
data map[string]cacheEntry
|
||||
mu sync.RWMutex
|
||||
maxSize int
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -385,9 +385,9 @@ func isRetryableError(err error) bool {
|
||||
|
||||
// 网络错误、超时等可以重试
|
||||
if strings.Contains(err.Error(), "timeout") ||
|
||||
strings.Contains(err.Error(), "connection refused") ||
|
||||
strings.Contains(err.Error(), "no such host") ||
|
||||
strings.Contains(err.Error(), "too many requests") {
|
||||
strings.Contains(err.Error(), "connection refused") ||
|
||||
strings.Contains(err.Error(), "no such host") ||
|
||||
strings.Contains(err.Error(), "too many requests") {
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
@@ -13,10 +13,10 @@ import (
|
||||
|
||||
// CachedItem 通用缓存项,支持Token和Manifest
|
||||
type CachedItem struct {
|
||||
Data []byte // 缓存数据(token字符串或manifest字节)
|
||||
ContentType string // 内容类型
|
||||
Data []byte // 缓存数据(token字符串或manifest字节)
|
||||
ContentType string // 内容类型
|
||||
Headers map[string]string // 额外的响应头
|
||||
ExpiresAt time.Time // 过期时间
|
||||
ExpiresAt time.Time // 过期时间
|
||||
}
|
||||
|
||||
// UniversalCache 通用缓存,支持Token和Manifest
|
||||
@@ -86,7 +86,7 @@ func getManifestTTL(reference string) time.Duration {
|
||||
|
||||
// mutable tag的智能判断
|
||||
if reference == "latest" || reference == "main" || reference == "master" ||
|
||||
reference == "dev" || reference == "develop" {
|
||||
reference == "dev" || reference == "develop" {
|
||||
// 热门可变标签: 短期缓存
|
||||
return 10 * time.Minute
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user