send method
Sends request and reads the whole response into memory.
Every status code, 4xx and 5xx included, completes normally with
an HttpResponse. The future fails with an HttpTransportException
only when there is no response: the connection could not be opened
or broke, or the request's timeout or readTimeout ran out.
Implementation
@override
Future<HttpResponse> send(HttpRequest request) async {
final (response, headers, timer, abort) = await _fetchResponse(request);
// The read timeout: the longest wait for each chunk of the body.
final idle = _Deadline(request.readTimeout, () => abort.abort());
try {
final Uint8List body;
// Reading chunk by chunk restarts the read timeout.
final reader = request.readTimeout == null
? null
: response.body?.getReader();
if (reader == null) {
body = (await response.arrayBuffer().toDart).toDart.asUint8List();
} else {
final bytes = BytesBuilder(copy: false);
while (true) {
final chunk = await reader.read().toDart;
if (chunk.done) {
break;
}
idle.restart();
if (chunk.value case final value?) {
bytes.add(value.toDart);
}
}
body = bytes.takeBytes();
}
return HttpResponse(
response.status,
headers: headers,
body: body,
request: request,
);
} catch (error) {
throw HttpTransportException(
idle.timedOut
? 'no data within ${request.readTimeout!.inMilliseconds} ms '
'(read timeout)'
: 'request failed: $error',
request: request,
cause: error,
isTimeout: timer.timedOut || idle.timedOut,
);
} finally {
timer.cancel();
idle.cancel();
}
}