selectProxyForDomain method

Proxy selectProxyForDomain(
  1. String domain,
  2. List<Proxy> proxies
)

Selects a proxy for a domain

Implementation

Proxy selectProxyForDomain(String domain, List<Proxy> proxies) {
  if (proxies.isEmpty) {
    throw Exception('No proxies available');
  }

  // Get the fingerprint for this domain
  final fingerprint = getFingerprintForDomain(domain);

  // Filter proxies based on the fingerprint
  List<Proxy> filteredProxies = proxies;

  // Filter by country if geo restrictions are used
  if (fingerprint.usesGeoRestrictions) {
    // Filter out blocked countries
    if (fingerprint.blockedCountries.isNotEmpty) {
      filteredProxies =
          filteredProxies
              .where(
                (proxy) =>
                    proxy.country == null ||
                    !fingerprint.blockedCountries.contains(
                      proxy.country!.toLowerCase(),
                    ),
              )
              .toList();
    }

    // Prefer proxies from preferred countries
    if (fingerprint.preferredCountries.isNotEmpty) {
      final preferredProxies =
          filteredProxies
              .where(
                (proxy) =>
                    proxy.country != null &&
                    fingerprint.preferredCountries.contains(
                      proxy.country!.toLowerCase(),
                    ),
              )
              .toList();

      if (preferredProxies.isNotEmpty) {
        filteredProxies = preferredProxies;
      }
    }
  }

  // Filter by success rate if IP blocking is used
  if (fingerprint.usesIpBlocking) {
    // Get success rates for this domain
    final successRates = _successRatesByDomain[domain] ?? {};

    // Filter proxies with success rate above threshold
    final goodProxies =
        filteredProxies.where((proxy) {
          final proxyKey = '${proxy.host}:${proxy.port}';
          final successRate = successRates[proxyKey] ?? 0.0;
          final totalRequests =
              (_successCountsByDomain[domain]?[proxyKey] ?? 0) +
              (_failureCountsByDomain[domain]?[proxyKey] ?? 0);

          // If we have enough data, use the success rate
          if (totalRequests >= 3) {
            return successRate >= fingerprint.successRateThreshold;
          }

          // Otherwise, use the proxy's overall score if available
          return (proxy.score?.successRate ?? 0.0) >=
              fingerprint.successRateThreshold;
        }).toList();

    if (goodProxies.isNotEmpty) {
      filteredProxies = goodProxies;
    }
  }

  // If no proxies match the criteria, use the original list
  if (filteredProxies.isEmpty) {
    filteredProxies = proxies;
  }

  // Select a proxy based on weighted scores
  return _selectByScore(filteredProxies, domain);
}