blob: 59664943056b4cd364209bb3b43fe18084279bec [file] [log] [blame]
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
import 'dart:io' as io;
import 'package:front_end/src/api_unstable/vm.dart';
class HttpAwareFileSystem implements FileSystem {
FileSystem original;
HttpAwareFileSystem(this.original);
@override
FileSystemEntity entityForUri(Uri uri) {
if (uri.isScheme('http') || uri.isScheme('https')) {
return new HttpFileSystemEntity(this, uri);
} else {
return original.entityForUri(uri);
}
}
}
class HttpFileSystemEntity implements FileSystemEntity {
HttpAwareFileSystem fileSystem;
Uri uri;
HttpFileSystemEntity(this.fileSystem, this.uri);
@override
Future<bool> exists() async {
return connectAndRun((io.HttpClient httpClient) async {
io.HttpClientRequest request = await httpClient.headUrl(uri);
io.HttpClientResponse response = await request.close();
await response.drain();
return response.statusCode == io.HttpStatus.ok;
});
}
@override
Future<bool> existsAsyncIfPossible() => exists();
@override
Future<List<int>> readAsBytes() async {
return connectAndRun((io.HttpClient httpClient) async {
io.HttpClientRequest request = await httpClient.getUrl(uri);
io.HttpClientResponse response = await request.close();
if (response.statusCode != io.HttpStatus.ok) {
await response.drain();
throw new FileSystemException(uri, response.toString());
}
List<List<int>> list = await response.toList();
return list.expand((list) => list).toList();
});
}
@override
Future<List<int>> readAsBytesAsyncIfPossible() => readAsBytes();
@override
Future<String> readAsString() async {
return String.fromCharCodes(await readAsBytes());
}
Future<T> connectAndRun<T>(Future<T> body(io.HttpClient httpClient)) async {
io.HttpClient? httpClient;
try {
httpClient = new io.HttpClient();
// Set timeout to be shorter than anticipated OS default
httpClient.connectionTimeout = const Duration(seconds: 5);
return await body(httpClient);
} on Exception catch (e) {
throw new FileSystemException(uri, e.toString());
} finally {
httpClient?.close(force: true);
}
}
}