onRequest method

  1. @override
void onRequest(
  1. RequestOptions options,
  2. RequestInterceptorHandler handler
)

Called when the request is about to be sent.

Implementation

@override
void onRequest(
  RequestOptions options,
  RequestInterceptorHandler handler,
) async {
  // Start timing the request
  options.extra['requestStartTime'] = DateTime.now().millisecondsSinceEpoch;

  if (_rotateProxies || _currentProxy == null) {
    try {
      _currentProxy = _proxyManager.getNextProxy(
        validated: _useValidatedProxies,
      );
    } catch (e) {
      // If no proxies are available, try to fetch some
      try {
        if (_useValidatedProxies) {
          await _proxyManager.fetchValidatedProxies(
            options: ProxyFilterOptions(count: 20, onlyHttps: true),
            onProgress: (completed, total) {
              _log('Validated $completed of $total proxies');
            },
          );
        } else {
          await _proxyManager.fetchProxies(
            options: ProxyFilterOptions(count: 20),
          );
        }

        try {
          _currentProxy = _proxyManager.getNextProxy(
            validated: _useValidatedProxies,
          );
        } catch (e) {
          // If still no validated proxies, try unvalidated as fallback
          if (_useValidatedProxies) {
            _log('No validated proxies available, trying unvalidated...');
            try {
              _currentProxy = _proxyManager.getNextProxy(validated: false);
              _log('Using unvalidated proxy as fallback');
            } catch (_) {
              // If still no proxies, proceed without a proxy
              _log('No proxies available at all, proceeding without proxy');
              handler.next(options);
              return;
            }
          } else {
            // If still no proxies, proceed without a proxy
            _log('No proxies available at all, proceeding without proxy');
            handler.next(options);
            return;
          }
        }
      } catch (fetchError) {
        // If fetching fails, proceed without a proxy
        _log('Error fetching proxies: $fetchError');
        handler.next(options);
        return;
      }
    }
  }

  // Set up the proxy
  final proxy = _currentProxy!;

  // Set proxy for Dio
  final proxyUrl = '${proxy.ip}:${proxy.port}';
  options.headers['proxy'] = proxyUrl;
  options.extra['proxy'] = proxyUrl;

  // Store the proxy for later use in response/error handlers
  options.extra['currentProxy'] = proxy;

  // Add authentication if needed
  if (proxy.isAuthenticated) {
    final auth =
        'Basic ${base64Encode(utf8.encode('${proxy.username}:${proxy.password}'))}';
    options.headers['Proxy-Authorization'] = auth;
    options.extra['proxyAuth'] = auth;
  }

  // Reset retry count for new requests
  _retryCount = 0;

  handler.next(options);
}