send method
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);
}
}