chore: 初始提交 Fonu 1.0.2
- 公网反代:Nginx 状态卡片(版本 / 运行状态 / 配置校验 / 端口监听) - 部署设置第一、二梯队(HTTPS 开关、安全头、限流、连接数、仅中国大陆 IP) - 隧道检测兼容 frps v0.68 / v0.71(V2 与旧版端点) - 恢复被清空的 internal/frp/store.go、internal/api/ddns_handler.go、web/src/views/DdnsView.vue
This commit is contained in:
@@ -0,0 +1,161 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
ListenAddr string
|
||||
DataDir string
|
||||
SessionSecret string
|
||||
NginxBin string
|
||||
NginxPIDFile string
|
||||
NginxMimeTypes string
|
||||
NginxDefaultHTTPPort int
|
||||
NginxDefaultHTTPSPort int
|
||||
FrpcBin string
|
||||
FrpPIDFile string
|
||||
}
|
||||
|
||||
func Load() Config {
|
||||
dataDir := envOr("FONU_DATA_DIR", defaultDataDir())
|
||||
if abs, err := filepath.Abs(dataDir); err == nil {
|
||||
dataDir = abs
|
||||
}
|
||||
return Config{
|
||||
ListenAddr: envOr("FONU_LISTEN", ":6893"),
|
||||
DataDir: dataDir,
|
||||
SessionSecret: envOr("FONU_SESSION_SECRET", "change-me-in-production"),
|
||||
NginxBin: envOr("FONU_NGINX_BIN", "nginx"),
|
||||
NginxPIDFile: envOr("FONU_NGINX_PID", dataDir+"/nginx/nginx.pid"),
|
||||
NginxMimeTypes: envOr("FONU_NGINX_MIME_TYPES", defaultMimeTypes()),
|
||||
NginxDefaultHTTPPort: envIntOr("FONU_NGINX_HTTP_PORT", 80),
|
||||
NginxDefaultHTTPSPort: envIntOr("FONU_NGINX_HTTPS_PORT", 443),
|
||||
FrpcBin: envOr("FONU_FRPC_BIN", "frpc"),
|
||||
FrpPIDFile: envOr("FONU_FRP_PID", dataDir+"/frp/frpc.pid"),
|
||||
}
|
||||
}
|
||||
|
||||
func (c Config) DefaultListenPort(httpsEnabled bool) int {
|
||||
if httpsEnabled {
|
||||
return c.NginxDefaultHTTPSPort
|
||||
}
|
||||
return c.NginxDefaultHTTPPort
|
||||
}
|
||||
|
||||
func (c Config) DBPath() string {
|
||||
return c.DataDir + "/fonu.db"
|
||||
}
|
||||
|
||||
func (c Config) NginxDir() string {
|
||||
return c.DataDir + "/nginx"
|
||||
}
|
||||
|
||||
func (c Config) NginxConfigPath() string {
|
||||
return c.NginxDir() + "/nginx.conf"
|
||||
}
|
||||
|
||||
func (c Config) NginxCustomDir() string {
|
||||
return c.NginxDir() + "/custom"
|
||||
}
|
||||
|
||||
func (c Config) NginxGlobalCustomPath() string {
|
||||
return c.NginxCustomDir() + "/global.conf"
|
||||
}
|
||||
|
||||
func (c Config) NginxRulesDir() string {
|
||||
return c.NginxDir() + "/rules"
|
||||
}
|
||||
|
||||
func (c Config) NginxRuleCustomPath(ruleID int64) string {
|
||||
return filepath.Join(c.NginxRulesDir(), fmt.Sprintf("rule_%d.conf", ruleID))
|
||||
}
|
||||
|
||||
func (c Config) NginxBackupsDir() string {
|
||||
return c.NginxDir() + "/backups"
|
||||
}
|
||||
|
||||
func (c Config) NginxGlobalBackupsDir() string {
|
||||
return c.NginxBackupsDir() + "/global"
|
||||
}
|
||||
|
||||
func (c Config) NginxRuleBackupsDir(ruleID int64) string {
|
||||
return filepath.Join(c.NginxBackupsDir(), "rules", fmt.Sprintf("%d", ruleID))
|
||||
}
|
||||
|
||||
func (c Config) LogsDir() string {
|
||||
return c.DataDir + "/logs"
|
||||
}
|
||||
|
||||
func (c Config) CertsDir() string {
|
||||
return c.DataDir + "/certs"
|
||||
}
|
||||
|
||||
func (c Config) ErrorsDir() string {
|
||||
return c.NginxDir() + "/errors"
|
||||
}
|
||||
|
||||
func (c Config) ChinaCIDRPath() string {
|
||||
return c.NginxDir() + "/china_cidr.conf"
|
||||
}
|
||||
|
||||
func (c Config) ChinaCIDRTempPath() string {
|
||||
return c.NginxDir() + "/china_cidr.conf.tmp"
|
||||
}
|
||||
|
||||
func (c Config) FrpDir() string {
|
||||
return c.DataDir + "/frp"
|
||||
}
|
||||
|
||||
func (c Config) FrpConfigPath() string {
|
||||
return c.FrpDir() + "/frpc.toml"
|
||||
}
|
||||
|
||||
func (c Config) FrpLogPath() string {
|
||||
return filepath.Join(c.LogsDir(), "frpc.log")
|
||||
}
|
||||
|
||||
func defaultDataDir() string {
|
||||
if _, err := os.Stat("/data"); err == nil {
|
||||
return "/data"
|
||||
}
|
||||
if cwd, err := os.Getwd(); err == nil {
|
||||
return filepath.Join(cwd, ".data")
|
||||
}
|
||||
return "/data"
|
||||
}
|
||||
|
||||
func envOr(key, fallback string) string {
|
||||
if v := os.Getenv(key); v != "" {
|
||||
return v
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
func defaultMimeTypes() string {
|
||||
candidates := []string{
|
||||
"/etc/nginx/mime.types",
|
||||
"deploy/nginx/mime.types",
|
||||
}
|
||||
for _, path := range candidates {
|
||||
if _, err := os.Stat(path); err == nil {
|
||||
return path
|
||||
}
|
||||
}
|
||||
return "/etc/nginx/mime.types"
|
||||
}
|
||||
|
||||
func envIntOr(key string, fallback int) int {
|
||||
v := os.Getenv(key)
|
||||
if v == "" {
|
||||
return fallback
|
||||
}
|
||||
n, err := strconv.Atoi(v)
|
||||
if err != nil {
|
||||
return fallback
|
||||
}
|
||||
return n
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLoadNginxDefaultPorts(t *testing.T) {
|
||||
t.Setenv("FONU_NGINX_HTTP_PORT", "18080")
|
||||
t.Setenv("FONU_NGINX_HTTPS_PORT", "9443")
|
||||
|
||||
cfg := Load()
|
||||
if cfg.NginxDefaultHTTPPort != 18080 {
|
||||
t.Fatalf("http port %d", cfg.NginxDefaultHTTPPort)
|
||||
}
|
||||
if cfg.NginxDefaultHTTPSPort != 9443 {
|
||||
t.Fatalf("https port %d", cfg.NginxDefaultHTTPSPort)
|
||||
}
|
||||
if cfg.DefaultListenPort(false) != 18080 {
|
||||
t.Fatalf("default http listen %d", cfg.DefaultListenPort(false))
|
||||
}
|
||||
if cfg.DefaultListenPort(true) != 9443 {
|
||||
t.Fatalf("default https listen %d", cfg.DefaultListenPort(true))
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadNginxDefaultPortsFallback(t *testing.T) {
|
||||
os.Unsetenv("FONU_NGINX_HTTP_PORT")
|
||||
os.Unsetenv("FONU_NGINX_HTTPS_PORT")
|
||||
|
||||
cfg := Load()
|
||||
if cfg.NginxDefaultHTTPPort != 80 || cfg.NginxDefaultHTTPSPort != 443 {
|
||||
t.Fatalf("ports %d %d", cfg.NginxDefaultHTTPPort, cfg.NginxDefaultHTTPSPort)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user