| // Copyright (c) 2017, 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. |
| |
| part of dart._http; |
| |
| final _httpOverridesToken = Object(); |
| |
| const _asyncRunZoned = runZoned; |
| |
| /// This class facilitates overriding [HttpClient] with a mock implementation. |
| /// It should be extended by another class in client code with overrides |
| /// that construct a mock implementation. The implementation in this base class |
| /// defaults to the actual [HttpClient] implementation. For example: |
| /// |
| /// ```dart import:io |
| /// // An implementation of the HttpClient interface |
| /// class MyHttpClient implements HttpClient { |
| /// MyHttpClient(SecurityContext? c); |
| /// |
| /// @override |
| /// noSuchMethod(Invocation invocation) { |
| /// // your implementation here |
| /// } |
| /// } |
| /// |
| /// void main() { |
| /// HttpOverrides.runZoned(() { |
| /// // Operations will use MyHttpClient instead of the real HttpClient |
| /// // implementation whenever HttpClient is used. |
| /// }, createHttpClient: (SecurityContext? c) => MyHttpClient(c)); |
| /// } |
| /// ``` |
| abstract class HttpOverrides { |
| static HttpOverrides? _global; |
| |
| static HttpOverrides? get current { |
| return Zone.current[_httpOverridesToken] ?? _global; |
| } |
| |
| /// The [HttpOverrides] to use in the root [Zone]. |
| /// |
| /// These are the [HttpOverrides] that will be used in the root Zone, and in |
| /// Zone's that do not set [HttpOverrides] and whose ancestors up to the root |
| /// Zone do not set [HttpOverrides]. |
| static set global(HttpOverrides? overrides) { |
| _global = overrides; |
| } |
| |
| /// Runs [body] in a fresh [Zone] using the provided overrides. |
| static R runZoned<R>(R Function() body, |
| {HttpClient Function(SecurityContext?)? createHttpClient, |
| String Function(Uri uri, Map<String, String>? environment)? |
| findProxyFromEnvironment}) { |
| HttpOverrides overrides = |
| _HttpOverridesScope(createHttpClient, findProxyFromEnvironment); |
| return _asyncRunZoned<R>(body, |
| zoneValues: {_httpOverridesToken: overrides}); |
| } |
| |
| /// Runs [body] in a fresh [Zone] using the overrides found in [overrides]. |
| /// |
| /// Note that [overrides] should be an instance of a class that extends |
| /// [HttpOverrides]. |
| static R runWithHttpOverrides<R>(R Function() body, HttpOverrides overrides) { |
| return _asyncRunZoned<R>(body, |
| zoneValues: {_httpOverridesToken: overrides}); |
| } |
| |
| /// Returns a new [HttpClient] using the given [context]. |
| /// |
| /// When this override is installed, this function overrides the behavior of |
| /// `new HttpClient`. |
| HttpClient createHttpClient(SecurityContext? context) { |
| return _HttpClient(context); |
| } |
| |
| /// Resolves the proxy server to be used for HTTP connections. |
| /// |
| /// When this override is installed, this function overrides the behavior of |
| /// `HttpClient.findProxyFromEnvironment`. |
| String findProxyFromEnvironment(Uri url, Map<String, String>? environment) { |
| return _HttpClient._findProxyFromEnvironment(url, environment); |
| } |
| } |
| |
| class _HttpOverridesScope extends HttpOverrides { |
| final HttpOverrides? _previous = HttpOverrides.current; |
| final HttpClient Function(SecurityContext?)? _createHttpClient; |
| final String Function(Uri uri, Map<String, String>? environment)? |
| _findProxyFromEnvironment; |
| |
| _HttpOverridesScope(this._createHttpClient, this._findProxyFromEnvironment); |
| |
| @override |
| HttpClient createHttpClient(SecurityContext? context) { |
| var createHttpClient = _createHttpClient; |
| if (createHttpClient != null) return createHttpClient(context); |
| var previous = _previous; |
| if (previous != null) return previous.createHttpClient(context); |
| return super.createHttpClient(context); |
| } |
| |
| @override |
| String findProxyFromEnvironment(Uri url, Map<String, String>? environment) { |
| var findProxyFromEnvironment = _findProxyFromEnvironment; |
| if (findProxyFromEnvironment != null) { |
| return findProxyFromEnvironment(url, environment); |
| } |
| var previous = _previous; |
| if (previous != null) { |
| return previous.findProxyFromEnvironment(url, environment); |
| } |
| return super.findProxyFromEnvironment(url, environment); |
| } |
| } |