// 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(); /// 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 Function() body, { HttpClient Function(SecurityContext?)? createHttpClient, String Function(Uri uri, Map? environment)? findProxyFromEnvironment, }) { HttpOverrides overrides = _HttpOverridesScope( createHttpClient, findProxyFromEnvironment, ); return dart_async.runZoned( 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 Function() body, HttpOverrides overrides) { return dart_async.runZoned( 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? 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? 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? 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); } }