diff --git a/api/fileshare/route.go b/api/fileshare/route.go new file mode 100644 index 0000000..e0a2249 --- /dev/null +++ b/api/fileshare/route.go @@ -0,0 +1,12 @@ +package fileshare + +import ( + "net/http" + + "github.com/mcoder2014/home_server/data" +) + +func InitRoute() error { + data.AddRoute(http.MethodGet, "/fileshare/test/*path", GetShareFile) + return nil +} diff --git a/api/fileshare/share.go b/api/fileshare/share.go new file mode 100644 index 0000000..3ce1c5d --- /dev/null +++ b/api/fileshare/share.go @@ -0,0 +1,7 @@ +package fileshare + +import "github.com/gin-gonic/gin" + +func GetShareFile(c *gin.Context) { + +} diff --git a/build.sh b/build.sh index 2f57a8e..c7d06a0 100755 --- a/build.sh +++ b/build.sh @@ -4,7 +4,9 @@ SERVER_NAME="home_server" CLIENT_NAME="home_client" mkdir -p output/bin -cp script/* output +mkdir -p output/testdata + +cp -r script/* output cp config/config.yaml output cp client/config/config.yaml output/client_config.yaml diff --git a/client/biz/ddns/ddns.go b/client/biz/ddns/ddns.go index f74231d..98f1ee1 100644 --- a/client/biz/ddns/ddns.go +++ b/client/biz/ddns/ddns.go @@ -18,6 +18,7 @@ import ( func StartDDNSRoutine() { logrus.Infof("StartDDNSRoutine") + RefreshOnce(context.Background()) ticker := time.NewTicker(120 * time.Second) for range ticker.C { ctx := log.GetCtxWithLogID(context.Background()) @@ -27,8 +28,7 @@ func StartDDNSRoutine() { func RefreshOnce(ctx context.Context) { defer utils.Recovery(ctx) - - log.Ctx(ctx).Infof("DDNS refresh once") + log.Ctx(ctx).Infof("DDNS refresh once start") // 处理 DDNS ddnsConfs := config.Global().DDNSConfig @@ -37,6 +37,7 @@ func RefreshOnce(ctx context.Context) { return } + log.Ctx(ctx).Infof("get ddns configs: len(%d)", len(ddnsConfs)) // 查询 ddns record records, err := rpc.GetAllDNSRecord(ctx, config.Global().Cloudflare.Zone) recordMap := convertToDNSRecordMap(records) @@ -44,6 +45,7 @@ func RefreshOnce(ctx context.Context) { log.Ctx(ctx).WithError(err).Errorf("GetAllDNSRecord failed") return } + for _, domainConfig := range ddnsConfs { err = domainCheck(ctx, domainConfig, recordMap) if err != nil { @@ -57,6 +59,7 @@ func domainCheck(ctx context.Context, domainConfig *config.DomainConfig, recordM if err != nil { return err } + log.Ctx(ctx).Infof("get current ip type = %s ip = %s", domainConfig.IPVersion, ipAddress) // check records record, ok := recordMap[domainConfig.Domain] @@ -68,11 +71,16 @@ func domainCheck(ctx context.Context, domainConfig *config.DomainConfig, recordM log.Ctx(ctx).WithError(err).Errorf("domain:%v has no record, create new record failed", domainConfig.Domain) return err } - log.Ctx(ctx).Infof("domain:%v has no record, create content:%v , create new record success", domainConfig.Domain, ipAddress) + log.Ctx(ctx).Infof("domain:%s has no record, create record, ip=%s , create new record success", domainConfig.Domain, ipAddress) return nil } // update + if strings.EqualFold(ipAddress, record.Content) { + log.Ctx(ctx).Infof("domain=%s ip=%s address not change, skip update", domainConfig.Domain, ipAddress) + return nil + } + return updateNewRecord(ctx, domainConfig, ipAddress, *record) } @@ -93,12 +101,6 @@ func getIp(ctx context.Context, domainConfig *config.DomainConfig) (ipAddress st } func updateNewRecord(ctx context.Context, domainConfig *config.DomainConfig, ipAddr string, record cloudflare.DNSRecord) error { - // update - if strings.EqualFold(ipAddr, record.Content) { - log.Ctx(ctx).Infof("domain %v is not changed, ip:%v no need update", domainConfig.Domain, ipAddr) - return nil - } - log.Ctx(ctx).Infof("domain %v has changed from %v to %v, prepare to update", domainConfig.Domain, record.Content, ipAddr) record.Content = ipAddr diff --git a/client/config/config.go b/client/config/config.go index e3117e2..977cdc3 100644 --- a/client/config/config.go +++ b/client/config/config.go @@ -17,6 +17,7 @@ type CloudflareConfig struct { APIToken string `json:"api_token" yaml:"api_token"` Zone string `json:"zone" yaml:"zone"` Debug bool `json:"debug" yaml:"debug"` + Proxy string `json:"proxy" yaml:"proxy"` // 通过代理访问 cloudflare } func (c *CloudflareConfig) String() string { diff --git a/client/rpc/cloudflare.go b/client/rpc/cloudflare.go index e368e28..cc33d26 100644 --- a/client/rpc/cloudflare.go +++ b/client/rpc/cloudflare.go @@ -3,14 +3,54 @@ package rpc import ( "context" "fmt" + "log" + "net/http" + "strings" + "time" "github.com/cloudflare/cloudflare-go" "github.com/mcoder2014/home_server/client/config" + "github.com/sirupsen/logrus" + "golang.org/x/net/proxy" ) func getApi() (*cloudflare.API, error) { + if config.Global().Cloudflare == nil { + return nil, fmt.Errorf("cloudflare config is nil") + } apiToken := config.Global().Cloudflare.APIToken - api, err := cloudflare.NewWithAPIToken(apiToken) + var opts []cloudflare.Option + proxyStr := config.Global().Cloudflare.Proxy // 格式 "127.0.0.1:1080" + if proxyStr != "" { + // 1. 创建一个 SOCKS5 proxy + dialer, err := proxy.SOCKS5("tcp", proxyStr, nil, proxy.Direct) + if err != nil { + log.Fatalf("Failed to create SOCKS5 dialer: %v", err) + } + + // 2. 将 proxy 转换为 DialContext 类型,以便在 http.Transport 中使用 + dialContext, ok := dialer.(proxy.ContextDialer) + if !ok { + log.Fatal("SOCKS5 dialer does not implement ContextDialer") + } + + // 3. 创建一个自定义的 http.Transport,并设置其 DialContext + transport := &http.Transport{ + DialContext: dialContext.DialContext, + // 你可以根据需要设置其他 Transport 字段,例如 TLSClientConfig, MaxIdleConns 等 + // 注意:不要在这里设置 Proxy 字段,因为我们已经用 DialContext 接管了连接 + } + + // 4. 使用自定义的 Transport 创建 http.Client + httpClient := &http.Client{ + Transport: transport, + Timeout: 20 * time.Second, // 设置一个超时时间 + } + opts = append(opts, cloudflare.HTTPClient(httpClient)) + logrus.Infof("get cloudflare api using proxy=%s", proxyStr) + } + + api, err := cloudflare.NewWithAPIToken(apiToken, opts...) if err != nil { return nil, err } @@ -31,7 +71,24 @@ func GetAllDNSRecord(ctx context.Context, zone string) ([]cloudflare.DNSRecord, //} // Fetch all DNS records for example.org - return api.DNSRecords(context.Background(), zone, cloudflare.DNSRecord{}) + records, err := api.DNSRecords(context.Background(), zone, cloudflare.DNSRecord{}) + if err != nil { + return nil, err + } + + var sb strings.Builder + for _, record := range records { + sb.WriteString("[domain=") + sb.WriteString(record.Name) + sb.WriteString(" type=") + sb.WriteString(record.Type) + sb.WriteString(" content=") + sb.WriteString(record.Content) + sb.WriteString("],\t") + } + logrus.Infof("get ddns configs: len(%d), content=%s", len(records), sb.String()) + + return records, nil } func CreateRecord(ctx context.Context, zone string, record cloudflare.DNSRecord) error {