send method

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

Sends an HTTP request and asynchronously returns the response.

Implementation

@override
Future<IOStreamedResponse> send(BaseRequest request) async {
  if (_inner == null) {
    throw ClientException(
        'HTTP request failed. Client is already closed.', request.url);
  }

  var stream = request.finalize();

  try {
    final tracker = request.controller?.track(request, isStreaming: true);

    // Open a connection to the server.
    // If the connection times out, this will simply throw a
    // CancelledException and we needn't do anything else as there's no
    // resulting HttpClientRequest to close.
    var ioRequest = (await maybeTrack(
      _inner!.openUrl(request.method, request.url),
      tracker: tracker,
      state: RequestLifecycleState.connecting,
    ))
      ..followRedirects = request.followRedirects
      ..maxRedirects = request.maxRedirects
      ..contentLength = (request.contentLength ?? -1)
      ..persistentConnection = request.persistentConnection;

    // Pass-thru all request headers from the BaseRequest.
    request.headers.forEach((name, value) {
      ioRequest.headers.set(name, value);
    });

    // Pipe the byte stream of request body data into the HttpClientRequest.
    // This will send the request to the server and call .done() on the
    // HttpClientRequest when the stream is done. At which point, the future
    // will complete once the response is available.
    //
    // If the step or the request times out or is cancelled, this will abort
    // with the corresponding error.
    var response = await maybeTrack(
      stream.pipe(ioRequest),
      tracker: tracker,
      state: RequestLifecycleState.sending,
      onCancel: (error) => ioRequest.abort(error),
    ) as HttpClientResponse;

    // Read all the response headers into a map, comma-concatenating any
    // duplicate values for a single header name.
    var headers = <String, String>{};
    response.headers.forEach((key, values) {
      // TODO: Remove trimRight() when
      // https://github.com/dart-lang/sdk/issues/53005 is resolved and the
      // package:http SDK constraint requires that version or later.
      headers[key] = values.map((value) => value.trimRight()).join(',');
    });

    return IOStreamedResponse(
        response.handleError((Object error) {
          final httpException = error as HttpException;
          throw ClientException(httpException.message, httpException.uri);
        }, test: (error) => error is HttpException),
        response.statusCode,
        contentLength:
            response.contentLength == -1 ? null : response.contentLength,
        request: request,
        headers: headers,
        isRedirect: response.isRedirect,
        persistentConnection: response.persistentConnection,
        reasonPhrase: response.reasonPhrase,
        inner: response);
  } on SocketException catch (error) {
    throw _ClientSocketException(error, request.url);
  } on HttpException catch (error) {
    throw ClientException(error.message, error.uri);
  }
}