381 lines
10 KiB
Go
381 lines
10 KiB
Go
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/BurntSushi/toml"
|
|
|
|
"github.com/WJQSERVER/wanf"
|
|
)
|
|
|
|
// Config 结构体定义了整个应用程序的配置
|
|
type Config struct {
|
|
Server ServerConfig `toml:"server" wanf:"server"`
|
|
Httpc HttpcConfig `toml:"httpc" wanf:"httpc"`
|
|
GitClone GitCloneConfig `toml:"gitclone" wanf:"gitclone"`
|
|
Shell ShellConfig `toml:"shell" wanf:"shell"`
|
|
Pages PagesConfig `toml:"pages" wanf:"pages"`
|
|
Log LogConfig `toml:"log" wanf:"log"`
|
|
Auth AuthConfig `toml:"auth" wanf:"auth"`
|
|
Blacklist BlacklistConfig `toml:"blacklist" wanf:"blacklist"`
|
|
Whitelist WhitelistConfig `toml:"whitelist" wanf:"whitelist"`
|
|
IPFilter IPFilterConfig `toml:"ipFilter" wanf:"ipFilter"`
|
|
RateLimit RateLimitConfig `toml:"rateLimit" wanf:"rateLimit"`
|
|
Outbound OutboundConfig `toml:"outbound" wanf:"outbound"`
|
|
Docker DockerConfig `toml:"docker" wanf:"docker"`
|
|
}
|
|
|
|
/*
|
|
[server]
|
|
host = "0.0.0.0"
|
|
port = 8080
|
|
sizeLimit = 125 # MB
|
|
memLimit = 0 # MB
|
|
cors = "*" # "*"/"" -> "*" ; "nil" -> "" ;
|
|
debug = false
|
|
*/
|
|
|
|
// ServerConfig 定义服务器相关的配置
|
|
type ServerConfig struct {
|
|
Port int `toml:"port" wanf:"port"`
|
|
Host string `toml:"host" wanf:"host"`
|
|
SizeLimit int `toml:"sizeLimit" wanf:"sizeLimit"`
|
|
MemLimit int64 `toml:"memLimit" wanf:"memLimit"`
|
|
Cors string `toml:"cors" wanf:"cors"`
|
|
Debug bool `toml:"debug" wanf:"debug"`
|
|
}
|
|
|
|
/*
|
|
[httpc]
|
|
mode = "auto" # "auto" or "advanced"
|
|
maxIdleConns = 100 # only for advanced mode
|
|
maxIdleConnsPerHost = 60 # only for advanced mode
|
|
maxConnsPerHost = 0 # only for advanced mode
|
|
useCustomRawHeaders = false
|
|
*/
|
|
// HttpcConfig 定义 HTTP 客户端相关的配置
|
|
type HttpcConfig struct {
|
|
Mode string `toml:"mode" wanf:"mode"`
|
|
MaxIdleConns int `toml:"maxIdleConns" wanf:"maxIdleConns"`
|
|
MaxIdleConnsPerHost int `toml:"maxIdleConnsPerHost" wanf:"maxIdleConnsPerHost"`
|
|
MaxConnsPerHost int `toml:"maxConnsPerHost" wanf:"maxConnsPerHost"`
|
|
UseCustomRawHeaders bool `toml:"useCustomRawHeaders" wanf:"useCustomRawHeaders"`
|
|
}
|
|
|
|
/*
|
|
[gitclone]
|
|
mode = "bypass" # bypass / cache
|
|
smartGitAddr = "http://127.0.0.1:8080"
|
|
//cacheTimeout = 10
|
|
ForceH2C = true
|
|
*/
|
|
// GitCloneConfig 定义 Git 克隆相关的配置
|
|
type GitCloneConfig struct {
|
|
Mode string `toml:"mode" wanf:"mode"`
|
|
SmartGitAddr string `toml:"smartGitAddr" wanf:"smartGitAddr"`
|
|
//CacheTimeout int `toml:"cacheTimeout"`
|
|
ForceH2C bool `toml:"ForceH2C" wanf:"ForceH2C"`
|
|
}
|
|
|
|
/*
|
|
[shell]
|
|
editor = true
|
|
rewriteAPI = false
|
|
*/
|
|
// ShellConfig 定义 Shell 相关的配置
|
|
type ShellConfig struct {
|
|
Editor bool `toml:"editor" wanf:"editor"`
|
|
RewriteAPI bool `toml:"rewriteAPI" wanf:"rewriteAPI"`
|
|
}
|
|
|
|
/*
|
|
[pages]
|
|
mode = "internal" # "internal" or "external"
|
|
theme = "bootstrap" # "bootstrap" or "nebula"
|
|
staticDir = "/data/www"
|
|
*/
|
|
// PagesConfig 定义静态页面相关的配置
|
|
type PagesConfig struct {
|
|
Mode string `toml:"mode" wanf:"mode"`
|
|
Theme string `toml:"theme" wanf:"theme"`
|
|
StaticDir string `toml:"staticDir" wanf:"staticDir"`
|
|
}
|
|
|
|
// LogConfig 定义日志相关的配置
|
|
type LogConfig struct {
|
|
LogFilePath string `toml:"logFilePath" wanf:"logFilePath"`
|
|
MaxLogSize int64 `toml:"maxLogSize" wanf:"maxLogSize"`
|
|
Level string `toml:"level" wanf:"level"`
|
|
}
|
|
|
|
/*
|
|
[auth]
|
|
Method = "parameters" # "header" or "parameters"
|
|
Key = ""
|
|
Token = "token"
|
|
enabled = false
|
|
passThrough = false
|
|
ForceAllowApi = false
|
|
ForceAllowApiPassList = false
|
|
*/
|
|
// AuthConfig 定义认证相关的配置
|
|
type AuthConfig struct {
|
|
Enabled bool `toml:"enabled" wanf:"enabled"`
|
|
Method string `toml:"method" wanf:"method"`
|
|
Key string `toml:"key" wanf:"key"`
|
|
Token string `toml:"token" wanf:"token"`
|
|
PassThrough bool `toml:"passThrough" wanf:"passThrough"`
|
|
ForceAllowApi bool `toml:"ForceAllowApi" wanf:"ForceAllowApi"`
|
|
ForceAllowApiPassList bool `toml:"ForceAllowApiPassList" wanf:"ForceAllowApiPassList"`
|
|
}
|
|
|
|
// BlacklistConfig 定义黑名单相关的配置
|
|
type BlacklistConfig struct {
|
|
Enabled bool `toml:"enabled" wanf:"enabled"`
|
|
BlacklistFile string `toml:"blacklistFile" wanf:"blacklistFile"`
|
|
}
|
|
|
|
// WhitelistConfig 定义白名单相关的配置
|
|
type WhitelistConfig struct {
|
|
Enabled bool `toml:"enabled" wanf:"enabled"`
|
|
WhitelistFile string `toml:"whitelistFile" wanf:"whitelistFile"`
|
|
}
|
|
|
|
// IPFilterConfig 定义 IP 过滤相关的配置
|
|
type IPFilterConfig struct {
|
|
Enabled bool `toml:"enabled" wanf:"enabled"`
|
|
EnableAllowList bool `toml:"enableAllowList" wanf:"enableAllowList"`
|
|
EnableBlockList bool `toml:"enableBlockList" wanf:"enableBlockList"`
|
|
IPFilterFile string `toml:"ipFilterFile" wanf:"ipFilterFile"`
|
|
}
|
|
|
|
/*
|
|
[rateLimit]
|
|
enabled = false
|
|
ratePerMinute = 100
|
|
burst = 10
|
|
|
|
[rateLimit.bandwidthLimit]
|
|
enabled = false
|
|
totalLimit = "100mbps"
|
|
totalBurst = "100mbps"
|
|
singleLimit = "10mbps"
|
|
singleBurst = "10mbps"
|
|
*/
|
|
|
|
// RateLimitConfig 定义限速相关的配置
|
|
type RateLimitConfig struct {
|
|
Enabled bool `toml:"enabled" wanf:"enabled"`
|
|
RatePerMinute int `toml:"ratePerMinute" wanf:"ratePerMinute"`
|
|
Burst int `toml:"burst" wanf:"burst"`
|
|
BandwidthLimit BandwidthLimitConfig `toml:"bandwidthLimit" wanf:"bandwidthLimit"`
|
|
}
|
|
|
|
// BandwidthLimitConfig 定义带宽限制相关的配置
|
|
type BandwidthLimitConfig struct {
|
|
Enabled bool `toml:"enabled" wanf:"enabled"`
|
|
TotalLimit string `toml:"totalLimit" wanf:"totalLimit"`
|
|
TotalBurst string `toml:"totalBurst" wanf:"totalBurst"`
|
|
SingleLimit string `toml:"singleLimit" wanf:"singleLimit"`
|
|
SingleBurst string `toml:"singleBurst" wanf:"singleBurst"`
|
|
}
|
|
|
|
/*
|
|
[outbound]
|
|
enabled = false
|
|
url = "socks5://127.0.0.1:1080" # "http://127.0.0.1:7890"
|
|
*/
|
|
// OutboundConfig 定义出站代理相关的配置
|
|
type OutboundConfig struct {
|
|
Enabled bool `toml:"enabled" wanf:"enabled"`
|
|
Url string `toml:"url" wanf:"url"`
|
|
}
|
|
|
|
/*
|
|
[docker]
|
|
enabled = false
|
|
target = "ghcr" # ghcr/dockerhub
|
|
auth = false
|
|
[docker.credentials]
|
|
user1 = "testpass"
|
|
test = "test123"
|
|
*/
|
|
// DockerConfig 定义 Docker 相关的配置
|
|
type DockerConfig struct {
|
|
Enabled bool `toml:"enabled" wanf:"enabled"`
|
|
Target string `toml:"target" wanf:"target"`
|
|
Auth bool `toml:"auth" wanf:"auth"`
|
|
Credentials map[string]string `toml:"credentials" wanf:"credentials"`
|
|
AuthPassThrough bool `toml:"authPassThrough" wanf:"authPassThrough"`
|
|
}
|
|
|
|
// LoadConfig 从配置文件加载配置
|
|
func LoadConfig(filePath string) (*Config, error) {
|
|
exist, filePath2read := FileExists(filePath)
|
|
if !exist {
|
|
// 楔入配置文件
|
|
err := DefaultConfig().WriteConfig(filePath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return DefaultConfig(), nil
|
|
}
|
|
var config Config
|
|
ext := filepath.Ext(filePath2read)
|
|
if ext == ".wanf" {
|
|
if err := wanf.DecodeFile(filePath2read, &config); err != nil {
|
|
return nil, err
|
|
}
|
|
return &config, nil
|
|
}
|
|
|
|
if _, err := toml.DecodeFile(filePath2read, &config); err != nil {
|
|
return nil, err
|
|
}
|
|
return &config, nil
|
|
}
|
|
|
|
// WriteConfig 写入配置文件
|
|
func (c *Config) WriteConfig(filePath string) error {
|
|
file, err := os.Create(filePath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer file.Close()
|
|
|
|
ext := filepath.Ext(filePath)
|
|
if ext == ".wanf" {
|
|
err := wanf.NewStreamEncoder(file).Encode(c)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
encoder := toml.NewEncoder(file)
|
|
return encoder.Encode(c)
|
|
}
|
|
|
|
// FileExists 检测文件是否存在
|
|
func FileExists(filename string) (bool, string) {
|
|
_, err := os.Stat(filename)
|
|
if err == nil {
|
|
return true, filename
|
|
}
|
|
if os.IsNotExist(err) {
|
|
// 获取文件名(不包含路径)
|
|
base := filepath.Base(filename)
|
|
dir := filepath.Dir(filename)
|
|
|
|
// 获取扩展名
|
|
fileNameBody := strings.TrimSuffix(base, filepath.Ext(base))
|
|
|
|
// 重新组合路径, 扩展名改为.wanf, 确认是否存在
|
|
wanfFilename := filepath.Join(dir, fileNameBody+".wanf")
|
|
|
|
_, err = os.Stat(wanfFilename)
|
|
if err == nil {
|
|
// .wanf 文件存在
|
|
fmt.Printf("\n Found .wanf file: %s\n", wanfFilename)
|
|
return true, wanfFilename
|
|
} else if os.IsNotExist(err) {
|
|
// .wanf 文件不存在
|
|
return false, ""
|
|
} else {
|
|
// 其他错误
|
|
return false, ""
|
|
}
|
|
} else {
|
|
return true, filename
|
|
}
|
|
}
|
|
|
|
// DefaultConfig 返回默认配置结构体
|
|
func DefaultConfig() *Config {
|
|
return &Config{
|
|
Server: ServerConfig{
|
|
Port: 8080,
|
|
Host: "0.0.0.0",
|
|
SizeLimit: 125,
|
|
MemLimit: 0,
|
|
Cors: "*",
|
|
Debug: false,
|
|
},
|
|
Httpc: HttpcConfig{
|
|
Mode: "auto",
|
|
MaxIdleConns: 100,
|
|
MaxIdleConnsPerHost: 60,
|
|
MaxConnsPerHost: 0,
|
|
},
|
|
GitClone: GitCloneConfig{
|
|
Mode: "bypass",
|
|
SmartGitAddr: "http://127.0.0.1:8080",
|
|
ForceH2C: false,
|
|
},
|
|
Shell: ShellConfig{
|
|
Editor: false,
|
|
RewriteAPI: false,
|
|
},
|
|
Pages: PagesConfig{
|
|
Mode: "internal",
|
|
Theme: "hub",
|
|
StaticDir: "/data/www",
|
|
},
|
|
Log: LogConfig{
|
|
LogFilePath: "/data/ghproxy/log/ghproxy.log",
|
|
MaxLogSize: 10,
|
|
Level: "info",
|
|
},
|
|
Auth: AuthConfig{
|
|
Enabled: false,
|
|
Method: "parameters",
|
|
Key: "",
|
|
Token: "token",
|
|
PassThrough: false,
|
|
ForceAllowApi: false,
|
|
ForceAllowApiPassList: false,
|
|
},
|
|
Blacklist: BlacklistConfig{
|
|
Enabled: false,
|
|
BlacklistFile: "/data/ghproxy/config/blacklist.json",
|
|
},
|
|
Whitelist: WhitelistConfig{
|
|
Enabled: false,
|
|
WhitelistFile: "/data/ghproxy/config/whitelist.json",
|
|
},
|
|
IPFilter: IPFilterConfig{
|
|
Enabled: false,
|
|
IPFilterFile: "/data/ghproxy/config/ipfilter.json",
|
|
EnableAllowList: false,
|
|
EnableBlockList: false,
|
|
},
|
|
RateLimit: RateLimitConfig{
|
|
Enabled: false,
|
|
RatePerMinute: 100,
|
|
Burst: 10,
|
|
BandwidthLimit: BandwidthLimitConfig{
|
|
Enabled: false,
|
|
TotalLimit: "100mbps",
|
|
TotalBurst: "100mbps",
|
|
SingleLimit: "10mbps",
|
|
SingleBurst: "10mbps",
|
|
},
|
|
},
|
|
Outbound: OutboundConfig{
|
|
Enabled: false,
|
|
Url: "socks5://127.0.0.1:1080",
|
|
},
|
|
Docker: DockerConfig{
|
|
Enabled: false,
|
|
Target: "dockerhub",
|
|
Auth: false,
|
|
Credentials: map[string]string{
|
|
"testpass": "test123",
|
|
},
|
|
},
|
|
}
|
|
}
|