createHttpClient function
Creates a HttpClient based on the fetch APIs.
This doesn't support client/bidi streaming.
Implementation
HttpClient createHttpClient({String credentials = "same-origin"}) {
return (creq) async {
final reqHeader = web.Headers();
for (final header in creq.header.entries) {
// Skip the default user-agent header.
if (header.name == 'user-agent' &&
header.value.startsWith('connect-dart/')) {
continue;
}
reqHeader.append(header.name, header.value);
}
Uint8List? body;
if (creq.body != null) {
await for (final chunk in creq.body!) {
body = Uint8List.fromList(body ?? Uint8List(0) + chunk);
}
}
final abortCtrl = web.AbortController();
ConnectException? abortErr;
creq.signal?.future.then(
(err) {
abortErr = err;
abortCtrl.abort();
},
);
try {
final res = await web.fetch(
creq.url,
web.RequestInit(
method: creq.method,
headers: reqHeader,
mode: "cors",
credentials: credentials,
redirect: "error",
signal: abortCtrl.signal,
body: body?.toJS,
),
);
final resHeader = Headers();
for (final (:key, :value) in res.headers.entries()) {
resHeader.add(key, value);
}
// Browsers and other fetch environments decompress the response,
// but retain the original content-encoding and content-length headers.
// This causes issues when we validate the response body length against
// the content-length header.
// We remove it here, and instead rely on parsing the response body to
// determine issues with with the response.
//
// https://github.com/wintercg/fetch/issues/23
resHeader.remove('content-encoding');
resHeader.remove('content-length');
return HttpResponse(
res.status,
resHeader,
res.body.toStream(creq.signal),
Headers(),
);
} catch (err) {
if (abortErr != null) {
throw abortErr!;
}
rethrow;
}
};
}