diff --git a/src/http.cpp b/src/http.cpp index 930eea1951920069be8033621cac42e2b150fe5d..cea8b7517234dad9784bf630de6feae0e0fc9e25 100644 --- a/src/http.cpp +++ b/src/http.cpp @@ -818,10 +818,21 @@ Resolver::add_callback(ResolverCb cb, sa_family_t family) } void -Resolver::resolve(const std::string& host, const std::string& service) +Resolver::resolve(const std::string& host, const std::string& serviceName) { - asio::ip::tcp::resolver::query query_(host, service); - resolver_.async_resolve(query_, [this, host, service, destroyed = destroyed_] + auto service = serviceName; + // The async_resolve function used below typically relies on the contents of the + // /etc/services (Linux/POSIX) or c:\windows\system32\drivers\etc\services (Windows) + // file in order to resolve a descriptive service name into a port number. A + // resolution attempt that would otherwise succeed can therefore fail if the file + // is inaccessible or corrupted (which is rare but can happen in practice). We + // hardcode the port numbers for http and https to prevent this failure mode. + if (service == "http") { + service = "80"; + } else if (service == "https") { + service = "443"; + } + resolver_.async_resolve(host, service, [this, host, service, destroyed = destroyed_] (const asio::error_code& ec, asio::ip::tcp::resolver::results_type endpoints) { if (ec == asio::error::operation_aborted or *destroyed)