send method
Issues an HTTP request to the specified URL, returning a Future that resolves with an SignalRHttpResponse representing the result.
request: An HttpRequest describing the request to send. Returns a Future that resolves with an SignalRHttpResponse describing the response, or rejects with an Error indicating a failure.
Implementation
Future<SignalRHttpResponse> send(SignalRHttpRequest request) {
// Check that abort was not signaled before calling send
if ((request.abortSignal != null) && request.abortSignal!.aborted!) {
return Future.error(AbortError());
}
if ((request.method == null) || (request.method!.length == 0)) {
return Future.error(new ArgumentError("No method defined."));
}
if ((request.url == null) || (request.url!.length == 0)) {
return Future.error(new ArgumentError("No url defined."));
}
return Future<SignalRHttpResponse>(() async {
final uri = Uri.parse(request.url!);
final httpClient = Client();
if (_httpClientCreateCallback != null) {
_httpClientCreateCallback!(httpClient);
}
final abortFuture = Future<void>(() {
final completer = Completer<void>();
if (request.abortSignal != null) {
request.abortSignal!.onabort = () {
if (!completer.isCompleted) completer.completeError(AbortError());
};
}
return completer.future;
});
final isJson = request.content != null &&
request.content is String &&
(request.content as String).startsWith('{');
var headers = MessageHeaders();
headers.setHeaderValue('X-Requested-With', 'FlutterHttpClient');
headers.setHeaderValue(
'content-type',
isJson
? 'application/json;charset=UTF-8'
: 'text/plain;charset=UTF-8');
headers.addMessageHeaders(request.headers);
_logger?.finest(
"HTTP send: url '${request.url}', method: '${request.method}' content: '${request.content}' content length = '${(request.content as String).length}' headers: '$headers'");
try {
final httpRespFuture = await Future.any(
[_sendHttpRequest(httpClient, request, uri, headers), abortFuture]);
final httpResp = httpRespFuture as Response;
if (request.abortSignal != null) {
request.abortSignal!.onabort = null;
}
if ((httpResp.statusCode >= 200) && (httpResp.statusCode < 300)) {
Object content;
final contentTypeHeader = httpResp.headers['content-type'];
final isJsonContent = contentTypeHeader == null ||
contentTypeHeader.startsWith('application/json');
if (isJsonContent) {
content = httpResp.body;
} else {
content = httpResp.body;
// When using SSE and the uri has an 'id' query parameter the response is not evaluated, otherwise it is an error.
if (isStringEmpty(uri.queryParameters['id'])) {
throw ArgumentError(
"Response Content-Type not supported: $contentTypeHeader");
}
}
return SignalRHttpResponse(httpResp.statusCode,
statusText: httpResp.reasonPhrase, content: content);
} else {
throw HttpError(httpResp.reasonPhrase, httpResp.statusCode);
}
} catch (e) {
return Future.error(e);
}
});
}