Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
57ba06e01e | ||
|
|
52fdaf5f81 | ||
|
|
d6b8f2b812 | ||
|
|
00d2113904 | ||
|
|
670bca31ca | ||
|
|
f77de0d37a | ||
|
|
1c18ccc363 | ||
|
|
a386304d42 |
18
CHANGELOG.md
18
CHANGELOG.md
@@ -1,5 +1,23 @@
|
||||
# 更新日志
|
||||
|
||||
24w18c
|
||||
---
|
||||
- PRE-RELEASE: 此版本是预发布版本,请勿在生产环境中使用
|
||||
- CHANGE: 修正配置命名,改为驼峰式命名
|
||||
- CHANGE: 修正函数命名
|
||||
|
||||
24w18b
|
||||
---
|
||||
- PRE-RELEASE: 此版本是预发布版本,请勿在生产环境中使用
|
||||
- CHANGE: 经团队考量,移除 Docker 代理功能,若造成了不便敬请谅解
|
||||
- CHANGE: 修改日志检查周期
|
||||
|
||||
24w18a
|
||||
---
|
||||
- PRE-RELEASE: 此版本是预发布版本,请勿在生产环境中使用
|
||||
- CHANGE: 改进Docker 代理
|
||||
- CHANGE: 改进前端页面的copy提示,弃用alert提示
|
||||
|
||||
v1.5.2
|
||||
---
|
||||
- FIX: 修正flag传入问题
|
||||
|
||||
@@ -1 +1 @@
|
||||
24w17b
|
||||
24w18c
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
[DEMO](https://ghproxy.1888866.xyz)
|
||||
|
||||
[TG讨论群组](https://t.me/ghproxy_go)
|
||||
|
||||
## 项目说明
|
||||
|
||||
### 项目特点
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
使用本项目,请遵循 **[WSL (WJQSERVER-STUDIO LICENSE)](https://wjqserver-studio.github.io/LICENSE/LICENSE.html)** 协议。
|
||||
|
||||
本项目所有文件均受到 WSL (WJQSERVER-STUDIO LICENSE) 协议保护,任何人不得在任何情况下以非 WSL (WJQSERVER-STUDIO LICENSE) 协议内规定的方式使用,复制,修改,编译,发布,分发,再许可,或者出售本项目的任何部分。
|
||||
## 报告漏洞
|
||||
|
||||
如果您发现本项目存在安全漏洞,请通过发送ISSUES或尝试联系项目维护者来报告。请在您的报告中包含以下信息:
|
||||
|
||||
@@ -88,22 +88,11 @@
|
||||
file_server
|
||||
import cache 0s 24h
|
||||
}
|
||||
handle_errors {
|
||||
@redirects `{err.status_code} in [301, 302, 307]`
|
||||
reverse_proxy @redirects {
|
||||
header_up Location {http.response.header.Location}
|
||||
}
|
||||
}
|
||||
|
||||
route /v2* {
|
||||
reverse_proxy https://registry-1.docker.io {
|
||||
header_up Host registry-1.docker.io
|
||||
header_up X-Real-IP {remote}
|
||||
header_up X-Forwarded-For {http.request.header.X-Forwarded-For}
|
||||
header_up X-Forwarded-Proto {scheme}
|
||||
header_up Authorization {http.request.header.Authorization}
|
||||
}
|
||||
}
|
||||
route /api* {
|
||||
rate_limit 15r/m 10000 429
|
||||
import cache 0s 6h
|
||||
}
|
||||
}
|
||||
|
||||
import /data/caddy/config.d/*
|
||||
|
||||
@@ -16,12 +16,12 @@ type Config struct {
|
||||
type ServerConfig struct {
|
||||
Port int `toml:"port"`
|
||||
Host string `toml:"host"`
|
||||
SizeLimit int `toml:"sizelimit"`
|
||||
SizeLimit int `toml:"sizeLimit"`
|
||||
}
|
||||
|
||||
type LogConfig struct {
|
||||
LogFilePath string `toml:"logfilepath"`
|
||||
MaxLogSize int `toml:"maxlogsize"`
|
||||
LogFilePath string `toml:"logFilePath"`
|
||||
MaxLogSize int `toml:"maxLogSize"`
|
||||
}
|
||||
|
||||
type CORSConfig struct {
|
||||
@@ -30,17 +30,17 @@ type CORSConfig struct {
|
||||
|
||||
type AuthConfig struct {
|
||||
Enabled bool `toml:"enabled"`
|
||||
AuthToken string `toml:"authtoken"`
|
||||
AuthToken string `toml:"authToken"`
|
||||
}
|
||||
|
||||
type BlacklistConfig struct {
|
||||
Enabled bool `toml:"enabled"`
|
||||
BlacklistFile string `toml:"blacklistfile"`
|
||||
BlacklistFile string `toml:"blacklistFile"`
|
||||
}
|
||||
|
||||
type WhitelistConfig struct {
|
||||
Enabled bool `toml:"enabled"`
|
||||
WhitelistFile string `toml:"whitelistfile"`
|
||||
WhitelistFile string `toml:"whitelistFile"`
|
||||
}
|
||||
|
||||
// LoadConfig 从 TOML 配置文件加载配置
|
||||
|
||||
@@ -1,23 +1,26 @@
|
||||
[server]
|
||||
host = "127.0.0.1"
|
||||
port = 8080
|
||||
sizelimit = 131072000 # 125MB
|
||||
sizeLimit = 131072000 # 125MB
|
||||
|
||||
[log]
|
||||
logfilepath = "/data/ghproxy/log/ghproxy.log"
|
||||
maxlogsize = 5 # MB
|
||||
logFilePath = "/data/ghproxy/log/ghproxy.log"
|
||||
maxLogSize = 5 # MB
|
||||
|
||||
[cors]
|
||||
enabled = true
|
||||
|
||||
[auth]
|
||||
authtoken = "test"
|
||||
authToken = "test"
|
||||
enabled = false
|
||||
|
||||
[blacklist]
|
||||
blacklistfile = "/data/ghproxy/config/blacklist.json"
|
||||
blacklistFile = "/data/ghproxy/config/blacklist.json"
|
||||
enabled = false
|
||||
|
||||
[whitelist]
|
||||
enabled = false
|
||||
whitelistfile = "/data/ghproxy/config/whitelist.json"
|
||||
whitelistFile = "/data/ghproxy/config/whitelist.json"
|
||||
|
||||
[downloadFolder]
|
||||
enabled = false
|
||||
|
||||
@@ -18,11 +18,11 @@ var (
|
||||
logger *log.Logger
|
||||
logChannel = make(chan string, 100)
|
||||
quitChannel = make(chan struct{})
|
||||
logFileMutex sync.Mutex // 保护 logFile 的互斥锁
|
||||
logFileMutex sync.Mutex
|
||||
logFilePath = "/data/ghproxy/log/ghproxy.log"
|
||||
)
|
||||
|
||||
// Init 初始化日志记录器,接受日志文件路径作为参数
|
||||
// 初始化,接受日志文件路径作为参数
|
||||
func Init(logFilePath_input string, maxLogsize int) error {
|
||||
logFileMutex.Lock()
|
||||
defer logFileMutex.Unlock()
|
||||
@@ -40,7 +40,6 @@ func Init(logFilePath_input string, maxLogsize int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// logWorker 处理日志记录
|
||||
func logWorker() {
|
||||
for {
|
||||
select {
|
||||
@@ -53,38 +52,37 @@ func logWorker() {
|
||||
}
|
||||
}
|
||||
|
||||
// Log 直接记录日志的函数
|
||||
func Log(customMessage string) {
|
||||
logChannel <- customMessage
|
||||
}
|
||||
|
||||
// Logw 用于格式化日志记录
|
||||
// 格式化日志记录
|
||||
func Logw(format string, args ...interface{}) {
|
||||
message := fmt.Sprintf(format, args...)
|
||||
Log(message)
|
||||
}
|
||||
|
||||
// 日志等级INFO
|
||||
// INFO
|
||||
func LogInfo(format string, args ...interface{}) {
|
||||
message := fmt.Sprintf(format, args...)
|
||||
output := fmt.Sprintf("[INFO] %s", message)
|
||||
Log(output)
|
||||
}
|
||||
|
||||
// 日志等级WARNING
|
||||
// WARNING
|
||||
func LogWarning(format string, args ...interface{}) {
|
||||
message := fmt.Sprintf(format, args...)
|
||||
output := fmt.Sprintf("[WARNING] %s", message)
|
||||
Log(output)
|
||||
}
|
||||
|
||||
// 日志等级ERROR
|
||||
// ERROR
|
||||
func LogError(format string, args ...interface{}) {
|
||||
message := fmt.Sprintf(format, args...)
|
||||
Log(message)
|
||||
}
|
||||
|
||||
// Close 关闭日志文件
|
||||
// 关闭日志文件
|
||||
func Close() {
|
||||
logFileMutex.Lock()
|
||||
defer logFileMutex.Unlock()
|
||||
@@ -100,7 +98,7 @@ func Close() {
|
||||
func monitorLogSize(logFilePath string, maxLogsize int) {
|
||||
var maxLogsizeBytes int64 = int64(maxLogsize) * 1024 * 1024 // 最大日志文件大小,单位为MB
|
||||
for {
|
||||
time.Sleep(600 * time.Second) // 每10分钟检查一次
|
||||
time.Sleep(120 * time.Minute) // 每120分钟检查一次日志文件大小
|
||||
logFileMutex.Lock()
|
||||
info, err := logFile.Stat()
|
||||
logFileMutex.Unlock()
|
||||
|
||||
8
main.go
8
main.go
@@ -30,7 +30,7 @@ var (
|
||||
logError = logger.LogError
|
||||
)
|
||||
|
||||
func ReadFlag() {
|
||||
func readFlag() {
|
||||
flag.StringVar(&cfgfile, "cfg", configfile, "config file path")
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ func setupLogger(cfg *config.Config) {
|
||||
logInfo("Init Completed")
|
||||
}
|
||||
|
||||
func Loadlist(cfg *config.Config) {
|
||||
func loadlist(cfg *config.Config) {
|
||||
auth.Init(cfg)
|
||||
}
|
||||
|
||||
@@ -67,11 +67,11 @@ func setupApi(cfg *config.Config, router *gin.Engine) {
|
||||
}
|
||||
|
||||
func init() {
|
||||
ReadFlag()
|
||||
readFlag()
|
||||
flag.Parse()
|
||||
loadConfig()
|
||||
setupLogger(cfg)
|
||||
Loadlist(cfg)
|
||||
loadlist(cfg)
|
||||
|
||||
// 设置 Gin 模式
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
|
||||
@@ -131,6 +131,28 @@
|
||||
text-align: center;
|
||||
line-height: 0.5;
|
||||
}
|
||||
|
||||
#toast {
|
||||
position: fixed;
|
||||
top: 10%;
|
||||
/* 垂直居中 */
|
||||
left: 50%;
|
||||
/* 水平居中 */
|
||||
transform: translate(-50%, -50%);
|
||||
/* 调整使其中心对齐 */
|
||||
background-color: rgba(97, 97, 97, 0.7);
|
||||
/* 半透明黑色背景 */
|
||||
color: white;
|
||||
/* 字体颜色 */
|
||||
padding: 15px 20px;
|
||||
/* 内边距 */
|
||||
border-radius: 10px;
|
||||
/* 圆角 */
|
||||
font-size: 16px;
|
||||
/* 字体大小 */
|
||||
z-index: 1000;
|
||||
/* 确保显示在其他元素上面 */
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
@@ -143,7 +165,7 @@
|
||||
<button class="btn rounded-button" id="formatButton">获取文件链接</button>
|
||||
|
||||
<div class="code" id="outputBlock">
|
||||
<button class="copy-button" id="copyButton" onclick="copyCode(this)">Copy</button>
|
||||
<button class="copy-button" id="copyButton">Copy</button>
|
||||
<pre id="formattedLinkOutput"></pre>
|
||||
</div>
|
||||
<div class="tips">
|
||||
@@ -155,6 +177,10 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="toast" style="display:none;">
|
||||
链接已复制到剪贴板
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
function formatGithubLink() {
|
||||
@@ -186,9 +212,20 @@
|
||||
window.getSelection().addRange(range);
|
||||
document.execCommand('copy');
|
||||
window.getSelection().removeAllRanges();
|
||||
alert('链接已复制到剪贴板');
|
||||
//alert('链接已复制到剪贴板');
|
||||
showToast('链接已复制到剪贴板');
|
||||
});
|
||||
|
||||
function showToast(message) {
|
||||
const toast = document.getElementById('toast');
|
||||
toast.textContent = message;
|
||||
toast.style.display = 'block';
|
||||
|
||||
setTimeout(() => {
|
||||
toast.style.display = 'none';
|
||||
}, 3000); // 3秒后隐藏
|
||||
}
|
||||
|
||||
function fetchSizeLimit() {
|
||||
fetch(window.location.origin + '/api/size_limit')
|
||||
.then(response => response.json())
|
||||
@@ -249,7 +286,7 @@
|
||||
Copyright © 2024 WJQSERVER-STUDIO
|
||||
</p>
|
||||
<p>
|
||||
GitHub仓库地址:<a href="https://github.com/WJQSERVER-STUDIO/ghproxy">https://github.com/WJQSERVER-STUDIO/ghproxy</a>
|
||||
GitHub仓库地址:<a href="https://github.com/WJQSERVER-STUDIO/ghproxy">https://github.com/WJQSERVER-STUDIO/ghproxy</a> <br><a href="https://t.me/ghproxy_go">Telegram交流群</a>
|
||||
</p>
|
||||
<div id="visitor-info" style="text-align: center; margin-top: 15px;">
|
||||
<p>您的IP地址: <span id="visitor-ip"></span></p>
|
||||
|
||||
@@ -155,7 +155,7 @@ func createHTTPClient(mode string) *req.Client {
|
||||
client := req.C()
|
||||
switch mode {
|
||||
case "chrome":
|
||||
client.SetUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36").
|
||||
client.SetUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36").
|
||||
SetTLSFingerprintChrome().
|
||||
ImpersonateChrome()
|
||||
case "git":
|
||||
|
||||
Reference in New Issue
Block a user