package proxy import ( "fmt" "net" "strconv" "strings" "time" ) type Scheme string const ( SchemeHTTP Scheme = "http" SchemeHTTPS Scheme = "https" SchemeSOCKS5 Scheme = "socks5" ) type Proxy struct { ID string Scheme Scheme Host string Port uint16 Username string CredentialVersion string SecretRef string SourceUpstream string CreatedAt time.Time ExpiresAt *time.Time UsableUntil *time.Time LastCheckedAt *time.Time LastSuccessAt *time.Time Latency time.Duration MaxConcurrency int64 State State Tags map[string]string } func (p Proxy) UniqueKey() string { host := strings.TrimSuffix(strings.ToLower(strings.TrimSpace(p.Host)), ".") return strings.Join([]string{ string(p.Scheme), host, strconv.FormatUint(uint64(p.Port), 10), p.Username, p.CredentialVersion, }, "|") } func (p Proxy) Address() string { return net.JoinHostPort(p.Host, strconv.FormatUint(uint64(p.Port), 10)) } func (p *Proxy) Transition(next State) error { if p == nil { return fmt.Errorf("transition proxy: nil proxy") } if !CanTransition(p.State, next) { return fmt.Errorf("transition proxy: %s -> %s is not allowed", p.State, next) } p.State = next return nil } func EffectiveExpiry(now time.Time, expiresAt *time.Time, responseTTL, configuredTTL time.Duration) *time.Time { if expiresAt != nil { value := expiresAt.UTC() return &value } if responseTTL > 0 { value := now.UTC().Add(responseTTL) return &value } if configuredTTL > 0 { value := now.UTC().Add(configuredTTL) return &value } return nil }