Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dcb502d3c8 | ||
|
|
a011d560c6 | ||
|
|
53060d50db | ||
|
|
68868388d3 | ||
|
|
75833b937b | ||
|
|
45b4acc31f | ||
|
|
0cd5a7334d | ||
|
|
40f5b597ab |
@@ -84,8 +84,8 @@ func DefaultConfig() *AppConfig {
|
|||||||
RequestLimit int `toml:"requestLimit"`
|
RequestLimit int `toml:"requestLimit"`
|
||||||
PeriodHours float64 `toml:"periodHours"`
|
PeriodHours float64 `toml:"periodHours"`
|
||||||
}{
|
}{
|
||||||
RequestLimit: 200,
|
RequestLimit: 500,
|
||||||
PeriodHours: 1.0,
|
PeriodHours: 3.0,
|
||||||
},
|
},
|
||||||
Security: struct {
|
Security: struct {
|
||||||
WhiteList []string `toml:"whiteList"`
|
WhiteList []string `toml:"whiteList"`
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ var (
|
|||||||
regexp.MustCompile(`^(?:https?://)?github\.com/([^/]+)/([^/]+)/(?:blob|raw)/.*`),
|
regexp.MustCompile(`^(?:https?://)?github\.com/([^/]+)/([^/]+)/(?:blob|raw)/.*`),
|
||||||
regexp.MustCompile(`^(?:https?://)?github\.com/([^/]+)/([^/]+)/(?:info|git-).*`),
|
regexp.MustCompile(`^(?:https?://)?github\.com/([^/]+)/([^/]+)/(?:info|git-).*`),
|
||||||
regexp.MustCompile(`^(?:https?://)?raw\.github(?:usercontent|)\.com/([^/]+)/([^/]+)/.+?/.+`),
|
regexp.MustCompile(`^(?:https?://)?raw\.github(?:usercontent|)\.com/([^/]+)/([^/]+)/.+?/.+`),
|
||||||
regexp.MustCompile(`^(?:https?://)?gist\.(?:githubusercontent|github)\.com/(.+?)/(.+?)/.+\.[a-zA-Z0-9]+$`),
|
regexp.MustCompile(`^(?:https?://)?gist\.(?:githubusercontent|github)\.com/([^/]+)/([^/]+).*`),
|
||||||
regexp.MustCompile(`^(?:https?://)?api\.github\.com/repos/([^/]+)/([^/]+)/.*`),
|
regexp.MustCompile(`^(?:https?://)?api\.github\.com/repos/([^/]+)/([^/]+)/.*`),
|
||||||
regexp.MustCompile(`^(?:https?://)?huggingface\.co(?:/spaces)?/([^/]+)/(.+)`),
|
regexp.MustCompile(`^(?:https?://)?huggingface\.co(?:/spaces)?/([^/]+)/(.+)`),
|
||||||
regexp.MustCompile(`^(?:https?://)?cdn-lfs\.hf\.co(?:/spaces)?/([^/]+)/([^/]+)(?:/(.*))?`),
|
regexp.MustCompile(`^(?:https?://)?cdn-lfs\.hf\.co(?:/spaces)?/([^/]+)/([^/]+)(?:/(.*))?`),
|
||||||
@@ -29,6 +29,14 @@ var (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 全局变量:被阻止的内容类型
|
||||||
|
var blockedContentTypes = map[string]bool{
|
||||||
|
"text/html": true,
|
||||||
|
"application/xhtml+xml": true,
|
||||||
|
"text/xml": true,
|
||||||
|
"application/xml": true,
|
||||||
|
}
|
||||||
|
|
||||||
// GitHubProxyHandler GitHub代理处理器
|
// GitHubProxyHandler GitHub代理处理器
|
||||||
func GitHubProxyHandler(c *gin.Context) {
|
func GitHubProxyHandler(c *gin.Context) {
|
||||||
rawPath := strings.TrimPrefix(c.Request.URL.RequestURI(), "/")
|
rawPath := strings.TrimPrefix(c.Request.URL.RequestURI(), "/")
|
||||||
@@ -122,11 +130,16 @@ func proxyGitHubWithRedirect(c *gin.Context, u string, redirectCount int) {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// 如果Github上游404,则返回错误信息
|
// 检查并处理被阻止的内容类型
|
||||||
if resp.StatusCode == http.StatusNotFound {
|
if c.Request.Method == "GET" {
|
||||||
c.String(http.StatusForbidden, "无效的GitHub地址")
|
if contentType := resp.Header.Get("Content-Type"); blockedContentTypes[strings.ToLower(strings.Split(contentType, ";")[0])] {
|
||||||
|
c.JSON(http.StatusForbidden, map[string]string{
|
||||||
|
"error": "Content type not allowed",
|
||||||
|
"message": "检测到网页类型,本服务不支持加速网页,请检查您的链接是否正确。",
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 检查文件大小限制
|
// 检查文件大小限制
|
||||||
cfg := config.GetConfig()
|
cfg := config.GetConfig()
|
||||||
@@ -152,8 +165,8 @@ func proxyGitHubWithRedirect(c *gin.Context, u string, redirectCount int) {
|
|||||||
realHost = "https://" + realHost
|
realHost = "https://" + realHost
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理.sh文件的智能处理
|
// 处理.sh和.ps1文件的智能处理
|
||||||
if strings.HasSuffix(strings.ToLower(u), ".sh") {
|
if strings.HasSuffix(strings.ToLower(u), ".sh") || strings.HasSuffix(strings.ToLower(u), ".ps1") {
|
||||||
isGzipCompressed := resp.Header.Get("Content-Encoding") == "gzip"
|
isGzipCompressed := resp.Header.Get("Content-Encoding") == "gzip"
|
||||||
|
|
||||||
processedBody, processedSize, err := utils.ProcessSmart(resp.Body, isGzipCompressed, realHost)
|
processedBody, processedSize, err := utils.ProcessSmart(resp.Body, isGzipCompressed, realHost)
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ func main() {
|
|||||||
fmt.Printf("H2c: 已启用\n")
|
fmt.Printf("H2c: 已启用\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("版本号: v1.1.7\n")
|
fmt.Printf("版本号: v1.1.9\n")
|
||||||
fmt.Printf("项目地址: https://github.com/sky22333/hubproxy\n")
|
fmt.Printf("项目地址: https://github.com/sky22333/hubproxy\n")
|
||||||
|
|
||||||
// 创建HTTP2服务器
|
// 创建HTTP2服务器
|
||||||
|
|||||||
8
src/public/images.html
vendored
8
src/public/images.html
vendored
@@ -1,13 +1,13 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="zh">
|
<html lang="zh-CN">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<meta name="description" content="Docker镜像流式下载工具,即点即下,无需等待">
|
<meta name="description" content="Docker镜像流式下载工具、即点即下无需等待">
|
||||||
<meta name="keywords" content="Docker,镜像下载,流式下载,即时下载">
|
<meta name="keywords" content="Docker镜像下载、流式下载、即时下载">
|
||||||
<meta name="color-scheme" content="dark light">
|
<meta name="color-scheme" content="dark light">
|
||||||
<title>Docker离线镜像下载</title>
|
<title>Docker离线镜像下载</title>
|
||||||
<link rel="icon" href="./favicon.ico">
|
<link rel="icon" href="/favicon.ico">
|
||||||
<style>
|
<style>
|
||||||
:root {
|
:root {
|
||||||
--background: #ffffff;
|
--background: #ffffff;
|
||||||
|
|||||||
15
src/public/index.html
vendored
15
src/public/index.html
vendored
@@ -1,14 +1,13 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="zh">
|
<html lang="zh-CN">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<meta name="description" content="Github文件加速,docker镜像加速">
|
<meta name="description" content="Github文件加速、docker镜像加速">
|
||||||
<meta name="keywords" content="Github,文件加速,ghproxy,docker镜像加速">
|
<meta name="keywords" content="Github、文件加速、ghproxy、docker镜像加速">
|
||||||
<meta name="color-scheme" content="dark light">
|
<meta name="color-scheme" content="dark light">
|
||||||
<title>Github文件加速</title>
|
<title>Github、Docker加速</title>
|
||||||
<link rel="icon" href="./favicon.ico">
|
<link rel="icon" href="/favicon.ico">
|
||||||
<style>
|
<style>
|
||||||
:root {
|
:root {
|
||||||
--background: #ffffff;
|
--background: #ffffff;
|
||||||
@@ -602,7 +601,7 @@
|
|||||||
<div class="hero">
|
<div class="hero">
|
||||||
<h1 class="hero-title">GitHub 文件加速</h1>
|
<h1 class="hero-title">GitHub 文件加速</h1>
|
||||||
<p class="hero-subtitle">
|
<p class="hero-subtitle">
|
||||||
快速下载GitHub上的文件和仓库,解决国内访问GitHub速度慢的问题,支持AI模型库Hugging Face
|
快速下载GitHub上的文件和仓库,解决国内访问GitHub速度慢的问题,支持Docker镜像加速和Hugging Face仓库。
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -685,7 +684,7 @@
|
|||||||
<strong>Quay.io 镜像:</strong>
|
<strong>Quay.io 镜像:</strong>
|
||||||
docker pull <span class="domain-base"></span>/quay.io/org/image
|
docker pull <span class="domain-base"></span>/quay.io/org/image
|
||||||
|
|
||||||
<strong>K8s 镜像:</strong>
|
<strong>Kubernetes 镜像:</strong>
|
||||||
docker pull <span class="domain-base"></span>/registry.k8s.io/pause:3.8
|
docker pull <span class="domain-base"></span>/registry.k8s.io/pause:3.8
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
6
src/public/search.html
vendored
6
src/public/search.html
vendored
@@ -1,13 +1,13 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="zh">
|
<html lang="zh-CN">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<meta name="description" content="Docker镜像搜索">
|
<meta name="description" content="Docker镜像搜索">
|
||||||
<meta name="keywords" content="Docker,镜像搜索,docker search">
|
<meta name="keywords" content="Docker、镜像搜索、docker search">
|
||||||
<meta name="color-scheme" content="dark light">
|
<meta name="color-scheme" content="dark light">
|
||||||
<title>Docker镜像搜索</title>
|
<title>Docker镜像搜索</title>
|
||||||
<link rel="icon" href="./favicon.ico">
|
<link rel="icon" href="/favicon.ico">
|
||||||
<style>
|
<style>
|
||||||
:root {
|
:root {
|
||||||
--background: #ffffff;
|
--background: #ffffff;
|
||||||
|
|||||||
@@ -86,9 +86,12 @@ func transformURL(url, host string) string {
|
|||||||
} else if !strings.HasPrefix(url, "https://") && !strings.HasPrefix(url, "//") {
|
} else if !strings.HasPrefix(url, "https://") && !strings.HasPrefix(url, "//") {
|
||||||
url = "https://" + url
|
url = "https://" + url
|
||||||
}
|
}
|
||||||
cleanHost := strings.TrimPrefix(host, "https://")
|
|
||||||
cleanHost = strings.TrimPrefix(cleanHost, "http://")
|
|
||||||
cleanHost = strings.TrimSuffix(cleanHost, "/")
|
|
||||||
|
|
||||||
return cleanHost + "/" + url
|
// 确保 host 有协议头
|
||||||
|
if !strings.HasPrefix(host, "http://") && !strings.HasPrefix(host, "https://") {
|
||||||
|
host = "https://" + host
|
||||||
|
}
|
||||||
|
host = strings.TrimSuffix(host, "/")
|
||||||
|
|
||||||
|
return host + "/" + url
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
CleanupInterval = 10 * time.Minute
|
CleanupInterval = 20 * time.Minute
|
||||||
MaxIPCacheSize = 10000
|
MaxIPCacheSize = 10000
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ func (i *IPRateLimiter) cleanupRoutine() {
|
|||||||
|
|
||||||
i.mu.RLock()
|
i.mu.RLock()
|
||||||
for ip, entry := range i.ips {
|
for ip, entry := range i.ips {
|
||||||
if now.Sub(entry.lastAccess) > 1*time.Hour {
|
if now.Sub(entry.lastAccess) > 2*time.Hour {
|
||||||
expired = append(expired, ip)
|
expired = append(expired, ip)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user