Rework MockHostResolver to better fit the new HTTPS record world

Changes:
* Rewrote the core of MockHostResolverBase with a new RuleResolver to
  handle rule matching. MockHostResolver is now completely divorced
  from RuleBasedHostResolverProc that still exists for rule matching by
  TestHostResolver (for browser tests) and is not compatible with
  scheme matching because it is based around mocking the system
  resolver that does not even see schemes. Ideally, we'd also rework
  RuleBasedHostResolverProc to itself be based on the new RuleResolver
  to avoid unnecessary logic duplication, but I'm leaving it alone for
  now since we haven't yet figured out all the plans for browser tests
  in the HTTPS record world.
* Pipe the scheme through to the RuleResolver to allow it to match on
  those schemes.  Also, similarly pipe the scheme through to the
  underlying HostCache, so it can do scheme-specific caching, like in
  the real HostResolver.
* Create new rule setting for RuleResolver to a simple
  `AddRule(key, result);` with string overloads for the simple
  key-is-hostname and result-is-single-ip cases. The key allows more
  matching specifying than before, especially allowing requiring
  specific schemes, but in the default case, is even more allowing,
  matching on only hostname, to simplify the 99% case where the test
  doesn't care that other specific parameters match. Also added some
  legacy Add*() methods with same name as old RuleBasedHostResolverProc
  methods to reduce the already-crazy code churn from this CL.
* Make the default to DCHECK on queries without any matching rules, as
  I believe that is more commonly the sane behavior for a unittest mock
  like this.  But also add a `default_result` parameter to the
  constructor to allow different behavior.  Set that new parameter in
  test utilities where MockHostResolvers get widely used by tests that
  likely don't even know what a HostResolver is, as that seems
  reasonable for those cases.  Also set it in a few cases of mocks used
  in large test files where I didn't want to take the churn of setting
  expectations for all the tests, even if those were generally cases
  where, in an ideal world, we would have explicit expectations.  But
  going forward, the new expectation for new tests is that if you are
  directly messing with a MockHostResolver, you should be setting the
  expectations rather than relying on default behavior.
* Add automatic synchronous resolution of "localhost" and similar, more
  closely matching the real HostResolver behavior for such names.
  Related to the default result change, as some tests were relying on
  the previous default behavior in order to allow resolving these
  names.  (And them some tests were just randomly using "localhost" for
  no apparent reason and became slightly broken if the expected it to
  be mappable through rules or made asynchronous, etc, even though the
  real HostResolver absolutely would never behave that way.)
* A subtle change that MockHostResolver will now only overwrite the
  port in results with the request port when the rule-matched response
  port is zero. This matches the actual behavior of HostResolver when
  request port is only used when lower layers return a port of zero.
  Allows matching to rules with a specific overriding port to match the
  HostResolver behavior that will soon be more common with HTTPS record
  support.

Change-Id: I6e57c4b6cdd2dac2a1aca6bfaf15fbde6671d4cb
Bug: 1206799
Fixed: 1182263
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3166033
Commit-Queue: Eric Orth <[email protected]>
Reviewed-by: David Benjamin <[email protected]>
Reviewed-by: Dan McArdle <[email protected]>
Cr-Commit-Position: refs/heads/main@{#936136}
diff --git a/net/websockets/websocket_end_to_end_test.cc b/net/websockets/websocket_end_to_end_test.cc
index 6e513836..13af758 100644
--- a/net/websockets/websocket_end_to_end_test.cc
+++ b/net/websockets/websocket_end_to_end_test.cc
@@ -65,6 +65,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 #include "url/origin.h"
+#include "url/url_constants.h"
 
 namespace net {
 
@@ -648,12 +649,16 @@
   replacements.SetSchemeStr(url::kWsScheme);
   GURL ws_url = wss_url.ReplaceComponents(replacements);
 
-  // Build a mocked resolver that returns ERR_DNS_NAME_HTTPS_ONLY for the
-  // first lookup, regardless of the request scheme. Real resolvers should
-  // only return this error when the scheme is "http" or "ws".
+  // Note that due to socket pool behavior, HostResolver will see the ws/wss
+  // requests as http/https.
   MockHostResolver host_resolver;
-  host_resolver.rules()->AddSimulatedHTTPSServiceFormRecord("a.test");
-  host_resolver.rules()->AddRule("*", "127.0.0.1");
+  MockHostResolverBase::RuleResolver::RuleKey unencrypted_resolve_key;
+  unencrypted_resolve_key.scheme = url::kHttpScheme;
+  host_resolver.rules()->AddRule(std::move(unencrypted_resolve_key),
+                                 ERR_DNS_NAME_HTTPS_ONLY);
+  MockHostResolverBase::RuleResolver::RuleKey encrypted_resolve_key;
+  encrypted_resolve_key.scheme = url::kHttpsScheme;
+  host_resolver.rules()->AddRule(std::move(encrypted_resolve_key), "127.0.0.1");
   context_.set_host_resolver(&host_resolver);
 
   EXPECT_TRUE(ConnectAndWait(ws_url));