Allow more URLs in masque_client

Before this change, passing in the URL "127.0.0.1:10002" would fail to parse, and the code would incorrectly send an empty hostname on the wire. This change adds a second parsing step that handles such failures, and adds some checks to detect empty hostnames earlier.

PiperOrigin-RevId: 698411730
diff --git a/quiche/quic/masque/masque_client.cc b/quiche/quic/masque/masque_client.cc
index 874c20f..da6611e 100644
--- a/quiche/quic/masque/masque_client.cc
+++ b/quiche/quic/masque/masque_client.cc
@@ -26,6 +26,7 @@
 #include "quiche/quic/tools/quic_default_client.h"
 #include "quiche/quic/tools/quic_name_lookup.h"
 #include "quiche/quic/tools/quic_url.h"
+#include "quiche/common/platform/api/quiche_logging.h"
 
 namespace quic {
 
@@ -37,7 +38,9 @@
     : QuicDefaultClient(server_address, server_id, MasqueSupportedVersions(),
                         event_loop, std::move(proof_verifier)),
       masque_mode_(masque_mode),
-      uri_template_(uri_template) {}
+      uri_template_(uri_template) {
+  QUICHE_CHECK(!QuicUrl(uri_template_).host().empty());
+}
 
 MasqueClient::MasqueClient(
     QuicSocketAddress server_address, const QuicServerId& server_id,
@@ -49,7 +52,9 @@
                         config, event_loop, std::move(network_helper),
                         std::move(proof_verifier)),
       masque_mode_(masque_mode),
-      uri_template_(uri_template) {}
+      uri_template_(uri_template) {
+  QUICHE_CHECK(!QuicUrl(uri_template_).host().empty());
+}
 
 MasqueClient::MasqueClient(
     QuicSocketAddress server_address, const QuicServerId& server_id,
@@ -89,6 +94,11 @@
     QuicEventLoop* event_loop, std::unique_ptr<ProofVerifier> proof_verifier) {
   QuicUrl url(uri_template);
   std::string host = url.host();
+  if (host.empty()) {
+    QUIC_LOG(ERROR) << "Failed to parse URI template \"" << uri_template
+                    << "\"";
+    return nullptr;
+  }
   uint16_t port = url.port();
   // Build the masque_client, and try to connect.
   QuicSocketAddress addr = tools::LookupAddress(host, absl::StrCat(port));
diff --git a/quiche/quic/masque/masque_client_session.cc b/quiche/quic/masque/masque_client_session.cc
index 4ecf75d..b9efaf9 100644
--- a/quiche/quic/masque/masque_client_session.cc
+++ b/quiche/quic/masque/masque_client_session.cc
@@ -69,6 +69,7 @@
       masque_mode_(masque_mode),
       uri_template_(uri_template),
       owner_(owner) {
+  QUICHE_CHECK(!QuicUrl(uri_template_).host().empty());
   // We don't currently use `masque_mode_` but will in the future. To silence
   // clang's `-Wunused-private-field` warning for this when building QUICHE for
   // Chrome, add a use of it here.
@@ -112,6 +113,7 @@
   } else {
     target_host = target_server_address.host().ToString();
   }
+  QUICHE_CHECK(!target_host.empty());
 
   url::Parsed parsed_uri_template;
   url::ParseStandardURL(uri_template_.c_str(), uri_template_.length(),
@@ -704,6 +706,7 @@
 
 quiche::QuicheIpAddress MasqueClientSession::GetFakeAddress(
     absl::string_view hostname) {
+  QUICHE_CHECK(!hostname.empty());
   quiche::QuicheIpAddress address;
   uint8_t address_bytes[16] = {0xFD};
   quiche::QuicheRandom::GetInstance()->RandBytes(&address_bytes[1],
diff --git a/quiche/quic/masque/masque_client_tools.cc b/quiche/quic/masque/masque_client_tools.cc
index 1e71ada..74ec2ed 100644
--- a/quiche/quic/masque/masque_client_tools.cc
+++ b/quiche/quic/masque/masque_client_tools.cc
@@ -10,6 +10,7 @@
 #include <string>
 #include <utility>
 
+#include "absl/strings/match.h"
 #include "absl/strings/str_cat.h"
 #include "quiche/quic/core/crypto/proof_verifier.h"
 #include "quiche/quic/core/io/quic_event_loop.h"
@@ -68,7 +69,16 @@
     QUIC_LOG(ERROR) << "Refusing to use MASQUE without datagram support";
     return nullptr;
   }
-  const QuicUrl url(url_string, "https");
+
+  QuicUrl url(url_string, "https");
+  if (url.host().empty() && !absl::StrContains(url_string, "://")) {
+    url = QuicUrl(absl::StrCat("https://", url_string));
+  }
+  if (url.host().empty()) {
+    QUIC_LOG(ERROR) << "Failed to parse URL \"" << url_string << "\"";
+    return nullptr;
+  }
+
   std::unique_ptr<ProofVerifier> proof_verifier;
   if (disable_certificate_verification) {
     proof_verifier = std::make_unique<FakeProofVerifier>();