fetchMetadataValue function
Retrieves a value from the GCE metadata server without caching the result.
If client is provided, it is used to make the request to the metadata
server.
If the metadata server cannot be contacted or returns a non-200 status code, a MetadataServerException is thrown.
The request should complete almost immediately if the metadata server is
available. If the metadata server is not available, the request will timeout
after timeout.
timeout defaults to 1 second, which we set to a very low value to avoid
waiting too long.
Implementation
Future<String> fetchMetadataValue(
String path, {
http.Client? client,
Duration timeout = const Duration(seconds: 3),
}) async {
final url = gceMetadataUrl(path);
try {
final abortTrigger = Completer<void>();
final request = http.AbortableRequest(
'GET',
url,
abortTrigger: abortTrigger.future,
)..headers.addAll(metadataFlavorHeaders);
final actualClient = client ?? http.Client();
http.Response response;
Timer? timeoutTimer;
try {
timeoutTimer = Timer(timeout, () {
if (!abortTrigger.isCompleted) {
abortTrigger.complete();
}
});
final responseStream = await actualClient.send(request);
response = await http.Response.fromStream(responseStream);
timeoutTimer.cancel();
} catch (e) {
timeoutTimer?.cancel();
if (abortTrigger.isCompleted) {
throw TimeoutException('Metadata server check timed out');
}
rethrow;
} finally {
if (client == null) {
actualClient.close();
}
}
if (response.statusCode != 200) {
throw MetadataServerException._(
'${response.body} (${response.statusCode})',
);
}
return response.body.trim();
} on TimeoutException catch (e, stackTrace) {
throw MetadataServerException._(
'Metadata server check timed out.',
innerException: e,
innerStackTrace: stackTrace,
);
} on SocketException catch (e, stackTrace) {
throw MetadataServerException._(
'Could not connect to $gceMetadataHost.',
innerException: e,
innerStackTrace: stackTrace,
);
} on http.ClientException catch (e, stackTrace) {
throw MetadataServerException._(
'HTTP Client Exception when connecting to $gceMetadataHost.',
innerException: e,
innerStackTrace: stackTrace,
);
}
}