send<T> method

  1. @override
Future<Response<T>> send<T>(
  1. Request<T> request
)
override

Sends an HTTP request and asynchronously returns the response.

Implementation

@override
Future<Response<T>> send<T>(Request<T> request) async {
  var bytes = await request.bodyBytes.toBytes();
  HttpRequest xhr;

  xhr = HttpRequest()
    ..timeout = timeout?.inMilliseconds
    ..open(request.method, '${request.url}', async: true); // check this

  _xhrs.add(xhr);

  xhr
    ..responseType = 'blob'
    ..withCredentials = withCredentials;
  request.headers.forEach(xhr.setRequestHeader);

  var completer = Completer<Response<T>>();
  xhr.onLoad.first.then((_) {
    var blob = xhr.response as Blob? ?? Blob([]);
    var reader = FileReader();

    reader.onLoad.first.then((_) async {
      var bodyBytes = BodyBytesStream.fromBytes(reader.result as List<int>);

      final stringBody =
          await bodyBytesToString(bodyBytes, xhr.responseHeaders);

      String? contentType;

      if (xhr.responseHeaders.containsKey('content-type')) {
        contentType = xhr.responseHeaders['content-type'];
      } else {
        contentType = 'application/json';
      }
      // xhr.responseHeaders.containsKey(key)
      final body = bodyDecoded<T>(
        request,
        stringBody,
        contentType,
      );

      final response = Response<T>(
        bodyBytes: bodyBytes,
        statusCode: xhr.status,
        request: request,
        headers: xhr.responseHeaders,
        statusText: xhr.statusText,
        body: body,
        bodyString: stringBody,
      );
      completer.complete(response);
    });

    reader.onError.first.then((error) {
      completer.completeError(
        GetHttpException(error.toString(), request.url),
        StackTrace.current,
      );
    });

    reader.readAsArrayBuffer(blob);
  });

  xhr.onError.first.then((_) {
    completer.completeError(
        GetHttpException('XMLHttpRequest error.', request.url),
        StackTrace.current);
  });

  xhr.send(bytes);

  try {
    return await completer.future;
  } finally {
    _xhrs.remove(xhr);
  }
}