rawRequest method

Future<HttpClientResponse> rawRequest({
  1. required String method,
  2. required String url,
  3. Map<String, String>? headers,
  4. Uint8List? body,
  5. int? timeoutMs,
  6. bool followRedirects = true,
})

Low-level raw request. Caller owns URL + headers + body.

Implementation

Future<HttpClientResponse> rawRequest({
  required String method,
  required String url,
  Map<String, String>? headers,
  Uint8List? body,
  int? timeoutMs,
  bool followRedirects = true,
}) async {
  final requestHeaders = headers ?? const <String, String>{};
  final spec = _HttpRequestSpec(
    method: method.toUpperCase(),
    url: url,
    headers: requestHeaders,
    body: body,
    timeoutMs: timeoutMs ?? _timeoutMs,
    // Enforce the credential policy at the lowest Dart transport boundary.
    // This also protects internal callers that intentionally use rawRequest.
    followRedirects: _redirectsAllowedForHeaders(
      followRedirects,
      requestHeaders,
    ),
  );
  _logger.debug('${spec.method} HTTP request');
  // Commons HTTP now routes through platform transports:
  //   - iOS: URLSession via RACommons.xcframework (H3)
  //   - Android: OkHttp via librac_commons_jni.so (H4)
  //   - Desktop / other: libcurl fallback inside commons
  // The former Android-HTTPS bypass via `dart:io HttpClient` has been
  // removed now that commons HTTP is functional on Android (B02/H1).
  final res = await Isolate.run<_HttpRequestResult>(
    () => _sendBlocking(spec),
  );
  if (res.rc != 0) {
    throw HttpClientException(
      'rac_http_request_send failed with code ${res.rc}',
      statusCode: res.status,
    );
  }
  return HttpClientResponse(
    statusCode: res.status,
    headers: res.headers,
    bodyBytes: res.body,
    elapsedMs: res.elapsedMs,
  );
}