send method
Sends an HTTP request and asynchronously returns the response.
Implementers should call BaseRequest.finalize
to get the body of the
request as a ByteStream
. They shouldn't make any assumptions about the
state of the stream; it could have data written to it asynchronously at a
later point, or it could already be closed when it's returned. Any
internal HTTP errors should be wrapped as ClientException
s.
Implementation
@override
Future<StreamedResponse> send(http.BaseRequest request) async {
var rq = MockHttpRequest(request.method, request.url);
request.headers.forEach(rq.headers.add);
if (request.url.userInfo.isNotEmpty) {
// Attempt to send as Basic auth
var encoded = base64Url.encode(utf8.encode(request.url.userInfo));
rq.headers.add('authorization', 'Basic $encoded');
} else if (rq.headers.value('authorization')?.startsWith('Basic ') ==
true) {
var encoded = rq.headers.value('authorization')!.substring(6);
var decoded = utf8.decode(base64Url.decode(encoded));
var oldRq = rq;
var newRq = MockHttpRequest(rq.method, rq.uri.replace(userInfo: decoded));
oldRq.headers.forEach(newRq.headers.add);
rq = newRq;
}
if (authToken?.isNotEmpty == true) {
rq.headers.add('authorization', 'Bearer $authToken');
}
rq
..cookies.addAll(cookies)
..session.addAll(session);
await request.finalize().pipe(rq);
await _http.handleRequest(rq);
var rs = rq.response;
session
..clear()
..addAll(rq.session);
var extractedHeaders = <String, String>{};
rs.headers.forEach((k, v) {
extractedHeaders[k] = v.join(',');
});
Stream<List<int>> stream = rs;
if (autoDecodeGzip != false &&
rs.headers['content-encoding']?.contains('gzip') == true) {
stream = stream.transform(gzip.decoder);
}
// Calling persistentConnection causes LateInitialization Exception
//var keepAliveState = rq.headers?.persistentConnection;
//if (keepAliveState == null) {
// keepAliveState = false;
//}
return StreamedResponse(stream, rs.statusCode,
contentLength: rs.contentLength,
isRedirect: rs.headers['location'] != null,
headers: extractedHeaders,
persistentConnection:
rq.headers.value('connection')?.toLowerCase().trim() ==
'keep-alive',
//|| keepAliveState,
reasonPhrase: rs.reasonPhrase);
}