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 ClientExceptions.
Implementation
@override
Future<http.StreamedResponse> send(http.BaseRequest request) async {
final start = DateTime.now();
final method = request.method;
final url = request.url.toString();
final reqHeaders = captureHeaders ? Map<String, String>.from(request.headers) : null;
final reqBody = captureRequestBody ? await _readRequestBody(request) : null;
try {
final response = await _inner.send(request);
// Buffer the response body so we can both record it and pass an
// intact stream back to the caller. Streaming responses lose this
// property — there's no way to tee a stream once consumed.
final bytes = await response.stream.toBytes();
final responseBody = captureResponseBody ? _safeDecode(bytes) : null;
_emit(
method: method,
url: url,
statusCode: response.statusCode,
start: start,
requestHeaders: reqHeaders,
responseHeaders:
captureHeaders ? Map<String, String>.from(response.headers) : null,
requestBodyRaw: reqBody,
responseBodyRaw: responseBody,
error: null,
);
return http.StreamedResponse(
Stream<List<int>>.value(bytes),
response.statusCode,
contentLength: response.contentLength,
request: response.request,
headers: response.headers,
isRedirect: response.isRedirect,
persistentConnection: response.persistentConnection,
reasonPhrase: response.reasonPhrase,
);
} catch (error) {
_emit(
method: method,
url: url,
statusCode: null,
start: start,
requestHeaders: reqHeaders,
responseHeaders: null,
requestBodyRaw: reqBody,
responseBodyRaw: null,
error: error.toString(),
);
rethrow;
}
}