重构优化

This commit is contained in:
starry
2025-06-11 11:58:57 +08:00
committed by GitHub
parent 86ca361057
commit a87f76dbd0
26 changed files with 5530 additions and 4569 deletions

192
src/proxysh.go Normal file
View File

@@ -0,0 +1,192 @@
package main
import (
"bufio"
"compress/gzip"
"fmt"
"io"
"regexp"
"strings"
)
var (
// gitHubDomains 定义所有支持的GitHub相关域名
gitHubDomains = []string{
"github.com",
"raw.githubusercontent.com",
"raw.github.com",
"gist.githubusercontent.com",
"gist.github.com",
"api.github.com",
}
// urlPattern 使用gitHubDomains构建正则表达式
urlPattern = regexp.MustCompile(`https?://(?:` + strings.Join(gitHubDomains, "|") + `)[^\s'"]+`)
// 是否启用脚本嵌套代理的调试日志
DebugLog = true
)
// 打印调试日志的辅助函数
func debugPrintf(format string, args ...interface{}) {
if DebugLog {
fmt.Printf(format, args...)
}
}
// ProcessGitHubURLs 处理数据流中的GitHub URL将其替换为代理URL。
// 此处思路借鉴了 https://github.com/WJQSERVER-STUDIO/ghproxy/blob/main/proxy/nest.go
func ProcessGitHubURLs(input io.ReadCloser, isCompressed bool, host string, isShellFile bool) (io.Reader, int64, error) {
debugPrintf("开始处理文件: isCompressed=%v, host=%s, isShellFile=%v\n", isCompressed, host, isShellFile)
if !isShellFile {
debugPrintf("非shell文件跳过处理\n")
return input, 0, nil
}
// 使用更大的缓冲区以提高性能
pipeReader, pipeWriter := io.Pipe()
var written int64
go func() {
var err error
defer func() {
if err != nil {
debugPrintf("处理过程中发生错误: %v\n", err)
_ = pipeWriter.CloseWithError(err)
} else {
_ = pipeWriter.Close()
}
}()
defer input.Close()
var reader io.Reader = input
if isCompressed {
debugPrintf("检测到压缩文件,进行解压处理\n")
gzipReader, gzipErr := gzip.NewReader(input)
if gzipErr != nil {
err = gzipErr
return
}
defer gzipReader.Close()
reader = gzipReader
}
// 使用更大的缓冲区
bufReader := bufio.NewReaderSize(reader, 32*1024) // 32KB buffer
var writer io.Writer = pipeWriter
if isCompressed {
gzipWriter := gzip.NewWriter(writer)
defer gzipWriter.Close()
writer = gzipWriter
}
bufWriter := bufio.NewWriterSize(writer, 32*1024) // 32KB buffer
defer bufWriter.Flush()
written, err = processContent(bufReader, bufWriter, host)
if err != nil {
debugPrintf("处理内容时发生错误: %v\n", err)
return
}
debugPrintf("文件处理完成,共处理 %d 字节\n", written)
}()
return pipeReader, written, nil
}
// processContent 优化处理文件内容的函数
func processContent(reader *bufio.Reader, writer *bufio.Writer, host string) (int64, error) {
var written int64
lineNum := 0
for {
lineNum++
line, err := reader.ReadString('\n')
if err != nil && err != io.EOF {
return written, fmt.Errorf("读取行时发生错误: %w", err)
}
if line != "" {
// 在处理前先检查是否包含GitHub URL
if strings.Contains(line, "github.com") ||
strings.Contains(line, "raw.githubusercontent.com") {
matches := urlPattern.FindAllString(line, -1)
if len(matches) > 0 {
debugPrintf("\n在第 %d 行发现 %d 个GitHub URL:\n", lineNum, len(matches))
for _, match := range matches {
debugPrintf("原始URL: %s\n", match)
}
}
modifiedLine := processLine(line, host, lineNum)
n, writeErr := writer.WriteString(modifiedLine)
if writeErr != nil {
return written, fmt.Errorf("写入修改后的行时发生错误: %w", writeErr)
}
written += int64(n)
} else {
// 如果行中没有GitHub URL直接写入
n, writeErr := writer.WriteString(line)
if writeErr != nil {
return written, fmt.Errorf("写入原始行时发生错误: %w", writeErr)
}
written += int64(n)
}
}
if err == io.EOF {
break
}
}
// 确保所有数据都被写入
if err := writer.Flush(); err != nil {
return written, fmt.Errorf("刷新缓冲区时发生错误: %w", err)
}
return written, nil
}
// processLine 处理单行文本替换所有匹配的GitHub URL
func processLine(line string, host string, lineNum int) string {
return urlPattern.ReplaceAllStringFunc(line, func(url string) string {
newURL := modifyGitHubURL(url, host)
if newURL != url {
debugPrintf("第 %d 行URL替换:\n 原始: %s\n 替换后: %s\n", lineNum, url, newURL)
}
return newURL
})
}
// 判断代理域名前缀
func modifyGitHubURL(url string, host string) string {
for _, domain := range gitHubDomains {
hasHttps := strings.HasPrefix(url, "https://"+domain)
hasHttp := strings.HasPrefix(url, "http://"+domain)
if hasHttps || hasHttp || strings.HasPrefix(url, domain) {
if !hasHttps && !hasHttp {
url = "https://" + url
}
if hasHttp {
url = "https://" + strings.TrimPrefix(url, "http://")
}
// 移除host开头的协议头如果有
host = strings.TrimPrefix(host, "https://")
host = strings.TrimPrefix(host, "http://")
// 返回组合后的URL
return host + "/" + url
}
}
return url
}
// IsShellFile 检查文件是否为shell文件基于文件名
func IsShellFile(filename string) bool {
return strings.HasSuffix(filename, ".sh")
}