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 {
var stopwatch = Stopwatch()..start();
String generateHex(int length) {
const chars = '0123456789abcdef';
final random = Random.secure();
return List.generate(length, (_) => chars[random.nextInt(16)]).join();
}
final traceId = generateHex(32); // 16 bytes
final spanId = generateHex(16); // 8 bytes
// Get options from global storage
final options = CxFlutterPlugin.globalOptions;
final shouldAddTraceParent = options != null && Utils.shouldAddTraceParent(request.url.toString(), options);
if (shouldAddTraceParent) {
var traceparent = generateTraceParent(traceId, spanId);
request.headers['traceparent'] = traceparent;
}
final response = await _inner.send(request);
stopwatch.stop();
var duration = stopwatch.elapsed;
final responseBody = await response.stream.bytesToString();
Map<String, dynamic> networkRequestContext = {
'url': request.url.toString(),
'host': request.url.host,
'method': request.method,
'status_code': response.statusCode,
'duration': duration.inMilliseconds,
'http_response_body_size': responseBody.length,
'fragments': request.url.fragment,
'schema': request.url.scheme,
};
if (shouldAddTraceParent) {
networkRequestContext['traceId'] = traceId;
networkRequestContext['spanId'] = spanId;
}
await CxFlutterPlugin.setNetworkRequestContext(networkRequestContext);
// Return the response with a new stream
return http.StreamedResponse(
Stream.fromIterable([utf8.encode(responseBody)]),
response.statusCode,
contentLength: response.contentLength,
request: response.request,
headers: response.headers,
isRedirect: response.isRedirect,
persistentConnection: response.persistentConnection,
reasonPhrase: response.reasonPhrase,
);
}