blob: 0fd2cba447fcd60877a71613424096b48222f6b1 [file] [log] [blame]
// Copyright (c) 2020, 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.
// @dart = 2.9
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:http/io_client.dart';
import 'package:logging/logging.dart';
import 'package:shelf/shelf.dart';
import 'package:shelf_proxy/shelf_proxy.dart';
import 'asset_reader.dart';
/// A reader for resources provided by a proxy server.
class ProxyServerAssetReader implements AssetReader {
final _logger = Logger('ProxyServerAssetReader');
Handler _handler;
http.Client _client;
ProxyServerAssetReader(int assetServerPort,
{String root, String host, bool isHttps}) {
host ??= 'localhost';
root ??= '';
isHttps ??= false;
var scheme = isHttps ? 'https://' : 'http://';
var inner = HttpClient()
..maxConnectionsPerHost = 200
..idleTimeout = const Duration(seconds: 30)
..connectionTimeout = const Duration(seconds: 30);
_client = isHttps
? IOClient(inner..badCertificateCallback = (cert, host, port) => true)
: IOClient(inner);
var url = '$scheme$host:$assetServerPort/';
if (root?.isNotEmpty ?? false) url += '$root/';
_handler = proxyHandler(url, client: _client);
}
@override
Future<String> dartSourceContents(String serverPath) =>
_readResource(serverPath);
@override
Future<String> sourceMapContents(String serverPath) =>
_readResource(serverPath);
Future<String> _readResource(String path) async {
// Handlers expect a fully formed HTML URI. The actual hostname and port
// does not matter.
var response =
await _handler(Request('GET', Uri.parse('http://foo:0000/$path')));
if (response.statusCode != HttpStatus.ok) {
_logger.warning('''
Failed to load asset at path: $path.
Status code: ${response.statusCode}
Headers:
${const JsonEncoder.withIndent(' ').convert(response.headers)}
''');
return null;
} else {
return await response.readAsString();
}
}
@override
Future<String> metadataContents(String serverPath) =>
_readResource(serverPath);
@override
Future<void> close() async => _client.close();
}