send method

Future<Response> send(
  1. String method,
  2. Object url, {
  3. Object? json,
  4. Object? body,
  5. Map<String, String> headers = const <String, String>{},
  6. String? idempotencyKey,
  7. int? attempts,
  8. String? connectAddress,
  9. bool allowUndeclaredHost = false,
})

Sends to an absolute URL, as the declared host whose base URL it is under: that host's credential, timeout, retries, breaker and pool.

A URL no declared host covers is refused with DV-HTTP-001 and never sent -- the same answer host gives a name nobody declared. Covered means the same scheme, host and port, and a path at or below the base URL's; where two declared hosts cover it, the longer base URL does.

allowUndeclaredHost is for a destination that is data rather than configuration, such as a webhook subscriber's endpoint, which no pubspec can list. It sends on the default policy -- a 30-second timeout, idempotency-aware retries, no breaker, no pool -- and never as a declared host, even one whose base URL covers it: a URL somebody else supplied must not be able to borrow the application's credential for that host. Whoever passes it owns checking where the URL leads.

Implementation

Future<Response> send(
  String method,
  Object url, {
  Object? json,
  Object? body,
  Map<String, String> headers = const <String, String>{},
  String? idempotencyKey,
  int? attempts,
  String? connectAddress,
  bool allowUndeclaredHost = false,
}) {
  final Uri uri = url is Uri ? url : Uri.parse('$url');
  if (!uri.hasScheme || uri.host.isEmpty) {
    throw ArgumentError('"$url" is not an absolute URL.');
  }

  String key;
  DVHttpHostConfig config;
  final (String, DVHttpHostConfig)? declared =
      allowUndeclaredHost ? null : _covering(uri);
  if (declared != null) {
    (key, config) = declared;
  } else if (allowUndeclaredHost) {
    key = uri.authority;
    config = DVHttpHostConfig(baseUrl: '${uri.scheme}://${uri.authority}');
  } else {
    DVObservability.log(
      'Refused $method ${uri.scheme}://${uri.authority}${uri.path}: no '
      'declared host covers it.',
      level: DVLogLevel.error,
      code: 'DV-HTTP-001',
      context: <String, Object?>{'host': uri.authority},
    );
    return Future<Response>.error(
        DVHttpUndeclaredHostException(uri.authority, url: uri));
  }

  return _execute(
    key,
    config,
    method,
    uri,
    json: json,
    body: body,
    headers: headers,
    idempotencyKey: idempotencyKey,
    attempts: attempts,
    connectAddress: connectAddress,
  );
}