send method

  1. @override
Future<StreamedResponse> send(
  1. BaseRequest request
)

Sends an HTTP request and asynchronously returns the response.

Implementers should call BaseRequest.finalize to get the body of the request as a ByteStream. They shouldn't make any assumptions about the state of the stream; it could have data written to it asynchronously at a later point, or it could already be closed when it's returned. Any internal HTTP errors should be wrapped as ClientExceptions.

Implementation

@override
Future<http.StreamedResponse> send(http.BaseRequest request) async {
  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();
        } else {
          await _proxyManager.fetchProxies();
        }

        _currentProxy = _proxyManager.getNextProxy(
          validated: _useValidatedProxies,
        );
      } catch (_) {
        // If still no proxies, use direct connection
        return _inner.send(request);
      }
    }
  }

  // Set up the proxy
  final proxy = _currentProxy!;
  final proxyUrl = '${proxy.ip}:${proxy.port}';

  // Create a new HttpClient with the proxy
  final httpClient = HttpClient();
  httpClient.findProxy = (uri) => 'PROXY $proxyUrl';

  // Set up authentication if needed
  if (proxy.isAuthenticated) {
    httpClient.authenticate = (Uri url, String scheme, String? realm) {
      httpClient.addCredentials(
        url,
        realm ?? '',
        HttpClientBasicCredentials(proxy.username!, proxy.password!),
      );
      return Future.value(true);
    };
  }

  // Convert the request to an HttpClientRequest
  final url = request.url;
  final httpRequest = await httpClient.openUrl(request.method, url);

  // Copy headers
  request.headers.forEach((name, value) {
    httpRequest.headers.set(name, value);
  });

  // Copy the body
  if (request is http.Request) {
    httpRequest.write(request.body);
  }

  // Send the request
  final httpResponse = await httpRequest.close();

  // Convert the response to a StreamedResponse
  final headers = <String, String>{};
  httpResponse.headers.forEach((name, values) {
    headers[name] = values.join(',');
  });

  final response = http.StreamedResponse(
    httpResponse,
    httpResponse.statusCode,
    contentLength: httpResponse.contentLength,
    request: request,
    headers: headers,
    isRedirect: httpResponse.isRedirect,
    persistentConnection: httpResponse.persistentConnection,
    reasonPhrase: httpResponse.reasonPhrase,
  );

  // Close the client
  httpClient.close();

  return response;
}