send method

  1. @override
Future<StreamedResponse> send(
  1. BaseRequest request
)

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 call = _target.startCall(
    client: 'http',
    method: request.method,
    uri: request.url,
    headers: request.headers,
    body: switch (request) {
      http.Request() => request.bodyBytes.isEmpty ? null : request.bodyBytes,
      http.StreamedRequest() => '<streamed request>',
      _ => null,
    },
    formData:
        request is http.MultipartRequest
            ? [
              for (final field in request.fields.entries)
                TracklyFormField(field.key, value: field.value),
              for (final file in request.files)
                TracklyFormField(
                  file.field,
                  fileName: file.filename ?? 'file',
                  fileSize: file.length,
                ),
            ]
            : null,
  );
  if (call == null) return _inner.send(request);

  final http.StreamedResponse response;
  try {
    response = await _inner.send(request);
  } catch (error) {
    _target.failCall(call, error);
    rethrow;
  }

  final contentType = response.headers['content-type'] ?? '';
  if (contentType.contains('text/event-stream')) {
    _target.completeCall(
      call,
      statusCode: response.statusCode,
      reasonPhrase: response.reasonPhrase,
      headers: response.headers,
      body: '<event stream>',
    );
    return response;
  }

  final List<int> bytes;
  try {
    bytes = await response.stream.toBytes();
  } catch (error) {
    _target.failCall(call, error);
    rethrow;
  }
  _target.completeCall(
    call,
    statusCode: response.statusCode,
    reasonPhrase: response.reasonPhrase,
    headers: response.headers,
    body: bytes,
  );

  return http.StreamedResponse(
    http.ByteStream.fromBytes(bytes),
    response.statusCode,
    contentLength: response.contentLength,
    request: response.request,
    headers: response.headers,
    isRedirect: response.isRedirect,
    persistentConnection: response.persistentConnection,
    reasonPhrase: response.reasonPhrase,
  );
}