feat: add app.configureHostResolver (#30576)
This commit is contained in:
		
					parent
					
						
							
								3b2db5f168
							
						
					
				
			
			
				commit
				
					
						dd7aeda6fb
					
				
			
		
					 6 changed files with 292 additions and 7 deletions
				
			
		| 
						 | 
				
			
			@ -1061,6 +1061,61 @@ Imports the certificate in pkcs12 format into the platform certificate store.
 | 
			
		|||
`callback` is called with the `result` of import operation, a value of `0`
 | 
			
		||||
indicates success while any other value indicates failure according to Chromium [net_error_list](https://source.chromium.org/chromium/chromium/src/+/master:net/base/net_error_list.h).
 | 
			
		||||
 | 
			
		||||
### `app.configureHostResolver(options)`
 | 
			
		||||
 | 
			
		||||
* `options` Object
 | 
			
		||||
  * `enableBuiltInResolver` Boolean (optional) - Whether the built-in host
 | 
			
		||||
    resolver is used in preference to getaddrinfo. When enabled, the built-in
 | 
			
		||||
    resolver will attempt to use the system's DNS settings to do DNS lookups
 | 
			
		||||
    itself. Enabled by default on macOS, disabled by default on Windows and
 | 
			
		||||
    Linux.
 | 
			
		||||
  * `secureDnsMode` String (optional) - Can be "off", "automatic" or "secure".
 | 
			
		||||
    Configures the DNS-over-HTTP mode. When "off", no DoH lookups will be
 | 
			
		||||
    performed. When "automatic", DoH lookups will be peformed first if DoH is
 | 
			
		||||
    available, and insecure DNS lookups will be performed as a fallback. When
 | 
			
		||||
    "secure", only DoH lookups will be performed. Defaults to "automatic".
 | 
			
		||||
  * `secureDnsServers` String[] (optional) - A list of DNS-over-HTTP
 | 
			
		||||
    server templates. See [RFC8484 § 3][] for details on the template format.
 | 
			
		||||
    Most servers support the POST method; the template for such servers is
 | 
			
		||||
    simply a URI. Note that for [some DNS providers][doh-providers], the
 | 
			
		||||
    resolver will automatically upgrade to DoH unless DoH is explicitly
 | 
			
		||||
    disabled, even if there are no DoH servers provided in this list.
 | 
			
		||||
  * `enableAdditionalDnsQueryTypes` Boolean (optional) - Controls whether additional DNS
 | 
			
		||||
    query types, e.g. HTTPS (DNS type 65) will be allowed besides the
 | 
			
		||||
    traditional A and AAAA queries when a request is being made via insecure
 | 
			
		||||
    DNS. Has no effect on Secure DNS which always allows additional types.
 | 
			
		||||
    Defaults to true.
 | 
			
		||||
 | 
			
		||||
Configures host resolution (DNS and DNS-over-HTTPS). By default, the following
 | 
			
		||||
resolvers will be used, in order:
 | 
			
		||||
 | 
			
		||||
1. DNS-over-HTTPS, if the [DNS provider supports it][doh-providers], then
 | 
			
		||||
2. the built-in resolver (enabled on macOS only by default), then
 | 
			
		||||
3. the system's resolver (e.g. `getaddrinfo`).
 | 
			
		||||
 | 
			
		||||
This can be configured to either restrict usage of non-encrypted DNS
 | 
			
		||||
(`secureDnsMode: "secure"`), or disable DNS-over-HTTPS (`secureDnsMode:
 | 
			
		||||
"off"`). It is also possible to enable or disable the built-in resolver.
 | 
			
		||||
 | 
			
		||||
To disable insecure DNS, you can specify a `secureDnsMode` of `"secure"`. If you do
 | 
			
		||||
so, you should make sure to provide a list of DNS-over-HTTPS servers to use, in
 | 
			
		||||
case the user's DNS configuration does not include a provider that supports
 | 
			
		||||
DoH.
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
app.configureHostResolver({
 | 
			
		||||
  secureDnsMode: 'secure',
 | 
			
		||||
  secureDnsServers: [
 | 
			
		||||
    'https://cloudflare-dns.com/dns-query'
 | 
			
		||||
  ]
 | 
			
		||||
})
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This API must be called after the `ready` event is emitted.
 | 
			
		||||
 | 
			
		||||
[doh-providers]: https://source.chromium.org/chromium/chromium/src/+/main:net/dns/public/doh_provider_entry.cc;l=31?q=%22DohProviderEntry::GetList()%22&ss=chromium%2Fchromium%2Fsrc
 | 
			
		||||
[RFC8484 § 3]: https://datatracker.ietf.org/doc/html/rfc8484#section-3
 | 
			
		||||
 | 
			
		||||
### `app.disableHardwareAcceleration()`
 | 
			
		||||
 | 
			
		||||
Disables hardware acceleration for current app.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,7 @@
 | 
			
		|||
  "repository": "https://github.com/electron/electron",
 | 
			
		||||
  "description": "Build cross platform desktop apps with JavaScript, HTML, and CSS",
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@electron/docs-parser": "^0.12.1",
 | 
			
		||||
    "@electron/docs-parser": "^0.12.2",
 | 
			
		||||
    "@electron/typescript-definitions": "^8.9.5",
 | 
			
		||||
    "@octokit/auth-app": "^2.10.0",
 | 
			
		||||
    "@octokit/rest": "^18.0.3",
 | 
			
		||||
| 
						 | 
				
			
			@ -141,4 +141,4 @@
 | 
			
		|||
      "node script/gen-hunspell-filenames.js"
 | 
			
		||||
    ]
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,6 +19,7 @@
 | 
			
		|||
#include "base/system/sys_info.h"
 | 
			
		||||
#include "chrome/browser/browser_process.h"
 | 
			
		||||
#include "chrome/browser/icon_manager.h"
 | 
			
		||||
#include "chrome/common/chrome_features.h"
 | 
			
		||||
#include "chrome/common/chrome_paths.h"
 | 
			
		||||
#include "content/browser/gpu/compositor_util.h"        // nogncheck
 | 
			
		||||
#include "content/browser/gpu/gpu_data_manager_impl.h"  // nogncheck
 | 
			
		||||
| 
						 | 
				
			
			@ -27,13 +28,16 @@
 | 
			
		|||
#include "content/public/browser/child_process_data.h"
 | 
			
		||||
#include "content/public/browser/client_certificate_delegate.h"
 | 
			
		||||
#include "content/public/browser/gpu_data_manager.h"
 | 
			
		||||
#include "content/public/browser/network_service_instance.h"
 | 
			
		||||
#include "content/public/browser/render_frame_host.h"
 | 
			
		||||
#include "content/public/common/content_switches.h"
 | 
			
		||||
#include "media/audio/audio_manager.h"
 | 
			
		||||
#include "net/dns/public/util.h"
 | 
			
		||||
#include "net/ssl/client_cert_identity.h"
 | 
			
		||||
#include "net/ssl/ssl_cert_request_info.h"
 | 
			
		||||
#include "net/ssl/ssl_private_key.h"
 | 
			
		||||
#include "sandbox/policy/switches.h"
 | 
			
		||||
#include "services/network/network_service.h"
 | 
			
		||||
#include "shell/browser/api/electron_api_menu.h"
 | 
			
		||||
#include "shell/browser/api/electron_api_session.h"
 | 
			
		||||
#include "shell/browser/api/electron_api_web_contents.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -419,6 +423,27 @@ struct Converter<content::CertificateRequestResultType> {
 | 
			
		|||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct Converter<net::SecureDnsMode> {
 | 
			
		||||
  static bool FromV8(v8::Isolate* isolate,
 | 
			
		||||
                     v8::Local<v8::Value> val,
 | 
			
		||||
                     net::SecureDnsMode* out) {
 | 
			
		||||
    std::string s;
 | 
			
		||||
    if (!ConvertFromV8(isolate, val, &s))
 | 
			
		||||
      return false;
 | 
			
		||||
    if (s == "off") {
 | 
			
		||||
      *out = net::SecureDnsMode::kOff;
 | 
			
		||||
      return true;
 | 
			
		||||
    } else if (s == "automatic") {
 | 
			
		||||
      *out = net::SecureDnsMode::kAutomatic;
 | 
			
		||||
      return true;
 | 
			
		||||
    } else if (s == "secure") {
 | 
			
		||||
      *out = net::SecureDnsMode::kSecure;
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
}  // namespace gin
 | 
			
		||||
 | 
			
		||||
namespace electron {
 | 
			
		||||
| 
						 | 
				
			
			@ -1525,6 +1550,108 @@ v8::Local<v8::Value> App::GetDockAPI(v8::Isolate* isolate) {
 | 
			
		|||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void ConfigureHostResolver(v8::Isolate* isolate,
 | 
			
		||||
                           const gin_helper::Dictionary& opts) {
 | 
			
		||||
  gin_helper::ErrorThrower thrower(isolate);
 | 
			
		||||
  net::SecureDnsMode secure_dns_mode = net::SecureDnsMode::kOff;
 | 
			
		||||
  std::string default_doh_templates;
 | 
			
		||||
  if (base::FeatureList::IsEnabled(features::kDnsOverHttps)) {
 | 
			
		||||
    if (features::kDnsOverHttpsFallbackParam.Get()) {
 | 
			
		||||
      secure_dns_mode = net::SecureDnsMode::kAutomatic;
 | 
			
		||||
    } else {
 | 
			
		||||
      secure_dns_mode = net::SecureDnsMode::kSecure;
 | 
			
		||||
    }
 | 
			
		||||
    default_doh_templates = features::kDnsOverHttpsTemplatesParam.Get();
 | 
			
		||||
  }
 | 
			
		||||
  std::string server_method;
 | 
			
		||||
  std::vector<net::DnsOverHttpsServerConfig> dns_over_https_servers;
 | 
			
		||||
  absl::optional<std::vector<network::mojom::DnsOverHttpsServerPtr>>
 | 
			
		||||
      servers_mojo;
 | 
			
		||||
  if (!default_doh_templates.empty() &&
 | 
			
		||||
      secure_dns_mode != net::SecureDnsMode::kOff) {
 | 
			
		||||
    for (base::StringPiece server_template :
 | 
			
		||||
         SplitStringPiece(default_doh_templates, " ", base::TRIM_WHITESPACE,
 | 
			
		||||
                          base::SPLIT_WANT_NONEMPTY)) {
 | 
			
		||||
      if (!net::dns_util::IsValidDohTemplate(server_template, &server_method)) {
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      bool use_post = server_method == "POST";
 | 
			
		||||
      dns_over_https_servers.emplace_back(std::string(server_template),
 | 
			
		||||
                                          use_post);
 | 
			
		||||
 | 
			
		||||
      if (!servers_mojo.has_value()) {
 | 
			
		||||
        servers_mojo = absl::make_optional<
 | 
			
		||||
            std::vector<network::mojom::DnsOverHttpsServerPtr>>();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      network::mojom::DnsOverHttpsServerPtr server_mojo =
 | 
			
		||||
          network::mojom::DnsOverHttpsServer::New();
 | 
			
		||||
      server_mojo->server_template = std::string(server_template);
 | 
			
		||||
      server_mojo->use_post = use_post;
 | 
			
		||||
      servers_mojo->emplace_back(std::move(server_mojo));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool enable_built_in_resolver =
 | 
			
		||||
      base::FeatureList::IsEnabled(features::kAsyncDns);
 | 
			
		||||
  bool additional_dns_query_types_enabled = true;
 | 
			
		||||
 | 
			
		||||
  if (opts.Has("enableBuiltInResolver") &&
 | 
			
		||||
      !opts.Get("enableBuiltInResolver", &enable_built_in_resolver)) {
 | 
			
		||||
    thrower.ThrowTypeError("enableBuiltInResolver must be a boolean");
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (opts.Has("secureDnsMode") &&
 | 
			
		||||
      !opts.Get("secureDnsMode", &secure_dns_mode)) {
 | 
			
		||||
    thrower.ThrowTypeError(
 | 
			
		||||
        "secureDnsMode must be one of: off, automatic, secure");
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  std::vector<std::string> secure_dns_server_strings;
 | 
			
		||||
  if (opts.Has("secureDnsServers")) {
 | 
			
		||||
    if (!opts.Get("secureDnsServers", &secure_dns_server_strings)) {
 | 
			
		||||
      thrower.ThrowTypeError("secureDnsServers must be an array of strings");
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    servers_mojo = absl::nullopt;
 | 
			
		||||
    for (const std::string& server_template : secure_dns_server_strings) {
 | 
			
		||||
      std::string server_method;
 | 
			
		||||
      if (!net::dns_util::IsValidDohTemplate(server_template, &server_method)) {
 | 
			
		||||
        thrower.ThrowTypeError(std::string("not a valid DoH template: ") +
 | 
			
		||||
                               server_template);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      bool use_post = server_method == "POST";
 | 
			
		||||
      if (!servers_mojo.has_value()) {
 | 
			
		||||
        servers_mojo = absl::make_optional<
 | 
			
		||||
            std::vector<network::mojom::DnsOverHttpsServerPtr>>();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      network::mojom::DnsOverHttpsServerPtr server_mojo =
 | 
			
		||||
          network::mojom::DnsOverHttpsServer::New();
 | 
			
		||||
      server_mojo->server_template = std::string(server_template);
 | 
			
		||||
      server_mojo->use_post = use_post;
 | 
			
		||||
      servers_mojo->emplace_back(std::move(server_mojo));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (opts.Has("enableAdditionalDnsQueryTypes") &&
 | 
			
		||||
      !opts.Get("enableAdditionalDnsQueryTypes",
 | 
			
		||||
                &additional_dns_query_types_enabled)) {
 | 
			
		||||
    thrower.ThrowTypeError("enableAdditionalDnsQueryTypes must be a boolean");
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Configure the stub resolver. This must be done after the system
 | 
			
		||||
  // NetworkContext is created, but before anything has the chance to use it.
 | 
			
		||||
  content::GetNetworkService()->ConfigureStubHostResolver(
 | 
			
		||||
      enable_built_in_resolver, secure_dns_mode, std::move(servers_mojo),
 | 
			
		||||
      additional_dns_query_types_enabled);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// static
 | 
			
		||||
App* App::Get() {
 | 
			
		||||
  static base::NoDestructor<App> app;
 | 
			
		||||
| 
						 | 
				
			
			@ -1671,6 +1798,7 @@ gin::ObjectTemplateBuilder App::GetObjectTemplateBuilder(v8::Isolate* isolate) {
 | 
			
		|||
#endif
 | 
			
		||||
      .SetProperty("userAgentFallback", &App::GetUserAgentFallback,
 | 
			
		||||
                   &App::SetUserAgentFallback)
 | 
			
		||||
      .SetMethod("configureHostResolver", &ConfigureHostResolver)
 | 
			
		||||
      .SetMethod("enableSandbox", &App::EnableSandbox);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,11 +7,14 @@
 | 
			
		|||
#include <memory>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <utility>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include "base/command_line.h"
 | 
			
		||||
#include "base/path_service.h"
 | 
			
		||||
#include "base/strings/string_split.h"
 | 
			
		||||
#include "chrome/browser/browser_process.h"
 | 
			
		||||
#include "chrome/browser/net/chrome_mojo_proxy_resolver_factory.h"
 | 
			
		||||
#include "chrome/common/chrome_features.h"
 | 
			
		||||
#include "chrome/common/chrome_paths.h"
 | 
			
		||||
#include "chrome/common/chrome_switches.h"
 | 
			
		||||
#include "components/os_crypt/os_crypt.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -21,6 +24,7 @@
 | 
			
		|||
#include "content/public/common/network_service_util.h"
 | 
			
		||||
#include "electron/fuses.h"
 | 
			
		||||
#include "mojo/public/cpp/bindings/pending_receiver.h"
 | 
			
		||||
#include "net/dns/public/util.h"
 | 
			
		||||
#include "net/net_buildflags.h"
 | 
			
		||||
#include "services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom.h"
 | 
			
		||||
#include "services/network/network_service.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -234,6 +238,52 @@ void SystemNetworkContextManager::OnNetworkServiceCreated(
 | 
			
		|||
      network_context_.BindNewPipeAndPassReceiver(),
 | 
			
		||||
      CreateNetworkContextParams());
 | 
			
		||||
 | 
			
		||||
  net::SecureDnsMode default_secure_dns_mode = net::SecureDnsMode::kOff;
 | 
			
		||||
  std::string default_doh_templates;
 | 
			
		||||
  if (base::FeatureList::IsEnabled(features::kDnsOverHttps)) {
 | 
			
		||||
    if (features::kDnsOverHttpsFallbackParam.Get()) {
 | 
			
		||||
      default_secure_dns_mode = net::SecureDnsMode::kAutomatic;
 | 
			
		||||
    } else {
 | 
			
		||||
      default_secure_dns_mode = net::SecureDnsMode::kSecure;
 | 
			
		||||
    }
 | 
			
		||||
    default_doh_templates = features::kDnsOverHttpsTemplatesParam.Get();
 | 
			
		||||
  }
 | 
			
		||||
  std::string server_method;
 | 
			
		||||
  absl::optional<std::vector<network::mojom::DnsOverHttpsServerPtr>>
 | 
			
		||||
      servers_mojo;
 | 
			
		||||
  if (!default_doh_templates.empty() &&
 | 
			
		||||
      default_secure_dns_mode != net::SecureDnsMode::kOff) {
 | 
			
		||||
    for (base::StringPiece server_template :
 | 
			
		||||
         SplitStringPiece(default_doh_templates, " ", base::TRIM_WHITESPACE,
 | 
			
		||||
                          base::SPLIT_WANT_NONEMPTY)) {
 | 
			
		||||
      if (!net::dns_util::IsValidDohTemplate(server_template, &server_method)) {
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      bool use_post = server_method == "POST";
 | 
			
		||||
 | 
			
		||||
      if (!servers_mojo.has_value()) {
 | 
			
		||||
        servers_mojo = absl::make_optional<
 | 
			
		||||
            std::vector<network::mojom::DnsOverHttpsServerPtr>>();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      network::mojom::DnsOverHttpsServerPtr server_mojo =
 | 
			
		||||
          network::mojom::DnsOverHttpsServer::New();
 | 
			
		||||
      server_mojo->server_template = std::string(server_template);
 | 
			
		||||
      server_mojo->use_post = use_post;
 | 
			
		||||
      servers_mojo->emplace_back(std::move(server_mojo));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool additional_dns_query_types_enabled = true;
 | 
			
		||||
 | 
			
		||||
  // Configure the stub resolver. This must be done after the system
 | 
			
		||||
  // NetworkContext is created, but before anything has the chance to use it.
 | 
			
		||||
  content::GetNetworkService()->ConfigureStubHostResolver(
 | 
			
		||||
      base::FeatureList::IsEnabled(features::kAsyncDns),
 | 
			
		||||
      default_secure_dns_mode, std::move(servers_mojo),
 | 
			
		||||
      additional_dns_query_types_enabled);
 | 
			
		||||
 | 
			
		||||
  std::string app_name = electron::Browser::Get()->GetName();
 | 
			
		||||
#if defined(OS_MAC)
 | 
			
		||||
  KeychainPassword::GetServiceName() = app_name + " Safe Storage";
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,7 @@ import * as net from 'net';
 | 
			
		|||
import * as fs from 'fs';
 | 
			
		||||
import * as path from 'path';
 | 
			
		||||
import { promisify } from 'util';
 | 
			
		||||
import { app, BrowserWindow, Menu, session } from 'electron/main';
 | 
			
		||||
import { app, BrowserWindow, Menu, session, net as electronNet } from 'electron/main';
 | 
			
		||||
import { emittedOnce } from './events-helpers';
 | 
			
		||||
import { closeWindow, closeAllWindows } from './window-helpers';
 | 
			
		||||
import { ifdescribe, ifit } from './spec-helpers';
 | 
			
		||||
| 
						 | 
				
			
			@ -1631,6 +1631,58 @@ describe('app module', () => {
 | 
			
		|||
      expect(app.isSecureKeyboardEntryEnabled()).to.equal(false);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('configureHostResolver', () => {
 | 
			
		||||
    after(() => {
 | 
			
		||||
      // Returns to the default configuration.
 | 
			
		||||
      app.configureHostResolver({});
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('fails on bad arguments', () => {
 | 
			
		||||
      expect(() => {
 | 
			
		||||
        (app.configureHostResolver as any)();
 | 
			
		||||
      }).to.throw();
 | 
			
		||||
      expect(() => {
 | 
			
		||||
        app.configureHostResolver({
 | 
			
		||||
          secureDnsMode: 'notAValidValue' as any
 | 
			
		||||
        });
 | 
			
		||||
      }).to.throw();
 | 
			
		||||
      expect(() => {
 | 
			
		||||
        app.configureHostResolver({
 | 
			
		||||
          secureDnsServers: [123 as any]
 | 
			
		||||
        });
 | 
			
		||||
      }).to.throw();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('affects dns lookup behavior', async () => {
 | 
			
		||||
      // 1. resolve a domain name to check that things are working
 | 
			
		||||
      await expect(new Promise((resolve, reject) => {
 | 
			
		||||
        electronNet.request({
 | 
			
		||||
          method: 'HEAD',
 | 
			
		||||
          url: 'https://www.electronjs.org'
 | 
			
		||||
        }).on('response', resolve)
 | 
			
		||||
          .on('error', reject)
 | 
			
		||||
          .end();
 | 
			
		||||
      })).to.eventually.be.fulfilled();
 | 
			
		||||
      // 2. change the host resolver configuration to something that will
 | 
			
		||||
      // always fail
 | 
			
		||||
      app.configureHostResolver({
 | 
			
		||||
        secureDnsMode: 'secure',
 | 
			
		||||
        secureDnsServers: ['https://127.0.0.1:1234']
 | 
			
		||||
      });
 | 
			
		||||
      // 3. check that resolving domain names now fails
 | 
			
		||||
      await expect(new Promise((resolve, reject) => {
 | 
			
		||||
        electronNet.request({
 | 
			
		||||
          method: 'HEAD',
 | 
			
		||||
          // Needs to be a slightly different domain to above, otherwise the
 | 
			
		||||
          // response will come from the cache.
 | 
			
		||||
          url: 'https://electronjs.org'
 | 
			
		||||
        }).on('response', resolve)
 | 
			
		||||
          .on('error', reject)
 | 
			
		||||
          .end();
 | 
			
		||||
      })).to.eventually.be.rejectedWith(/ERR_NAME_NOT_RESOLVED/);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
describe('default behavior', () => {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,10 +18,10 @@
 | 
			
		|||
    esutils "^2.0.2"
 | 
			
		||||
    js-tokens "^4.0.0"
 | 
			
		||||
 | 
			
		||||
"@electron/docs-parser@^0.12.1":
 | 
			
		||||
  version "0.12.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@electron/docs-parser/-/docs-parser-0.12.1.tgz#254c324b5953c67cdcce0a8902736778a1788742"
 | 
			
		||||
  integrity sha512-E9/GjNVlFzBM2MNOoLjiKSE0xAMM3KsxvzMKmMeORY7aDbalObFm23XCh8DC8Jn/hfh6BzgVPF3OZO9hKvs5nw==
 | 
			
		||||
"@electron/docs-parser@^0.12.2":
 | 
			
		||||
  version "0.12.2"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/@electron/docs-parser/-/docs-parser-0.12.2.tgz#42ac92404058411be4155b25320b96192da85ba5"
 | 
			
		||||
  integrity sha512-81l/jlz21VvTOZ21NyY1gd63ZPT/Ny0vY/nu9iYb2FkaGThMvy2xKNHifPcOTDkT+94jK0D8f7eUMDh75FIqCw==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    "@types/markdown-it" "^10.0.0"
 | 
			
		||||
    chai "^4.2.0"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue