send method
Sends the given request
and returns the response.
Implementation
@override
Future<Response> send(Request request) {
if (_closed) {
return Future<Response>.error(StateError('Client is already closed.'));
}
Future<Response> handler(Request request) {
var requestStream = request.read();
var requestBodyCompleter = Completer<Uint8List>();
void onRequestBytes(List<int> bytes) {
requestBodyCompleter.complete(Uint8List.fromList(bytes));
}
var sink = ByteConversionSink.withCallback(onRequestBytes);
requestStream.listen(
sink.add,
onError: requestBodyCompleter.completeError,
onDone: sink.close,
cancelOnError: true,
);
Future<Response> onBytes(Uint8List bytes) {
var jsHeaders = web.Headers();
request.headers.forEach((name, value) {
jsHeaders.set(name, value);
});
var jsRequestBodyBytes = bytes.toJS;
var jsResponsePromise = _fetch(
request.method,
'${request.requestedUri}',
jsHeaders,
jsRequestBodyBytes,
_abortController.signal,
);
var responseCompleter = Completer<Response>();
void onResponse(_JSResponse jsResponse) {
var status = jsResponse.status;
var headers = <String, String>{};
var body = jsResponse.body.toDart;
jsResponse.headers.forEach(
(String value, String name) {
headers[name.toLowerCase()] = value;
}.toJS,
);
responseCompleter.complete(
Response(status, headers: headers, body: body),
);
}
jsResponsePromise.then(onResponse.toJS);
return responseCompleter.future;
}
return requestBodyCompleter.future.then<Response>(onBytes);
}
FutureOr<Response> Function(Request) handle;
if (_pipeline != null) {
handle = _pipeline.addHandler(handler);
} else {
handle = handler;
}
return Future<Response>.value(handle(request));
}