bool GeneralHTTPCredentialsProvider::ShouldCreateGeneralHTTPProvider()

in src/aws-cpp-sdk-core/source/auth/GeneralHTTPCredentialsProvider.cpp [63:148]


bool GeneralHTTPCredentialsProvider::ShouldCreateGeneralHTTPProvider(const Aws::String& relativeUri, const Aws::String& absoluteUri, const Aws::String authToken)
{
    if (authToken.find("\r\n") != Aws::String::npos)
    {
        AWS_LOGSTREAM_WARN(GEN_HTTP_LOG_TAG, "Can't use General HTTP Provider: AWS_CONTAINER_AUTHORIZATION_TOKEN env value contains invalid characters (\\r\\n)");
        return false;
    }

    if (!relativeUri.empty())
    {
        // The provider MAY choose to assert syntactical validity of the resulting URI
        // perform very basic check here
        if (relativeUri[0] != '/') {
          AWS_LOGSTREAM_WARN(GEN_HTTP_LOG_TAG, "Can't use General HTTP Provider: AWS_CONTAINER_CREDENTIALS_RELATIVE_URI does not begin with /");
          return false;
        } else {
          // full URI is not used in case of a relative one present
          return true;
        }
    }

    if (!absoluteUri.empty())
    {
        // If the resolved URI’s scheme is HTTPS, its hostname may be used in the request
        if (Aws::Utils::StringUtils::ToLower(absoluteUri.c_str()).rfind(Aws::String("https://"), 0) == 0) // if starts_with
        {
            return true;
        }

        Aws::Http::URI absUri(absoluteUri);
        const Aws::String& authority = absUri.GetAuthority();

        // Otherwise, implementations MUST fail to resolve when the URI hostname does not satisfy any of the following conditions
        if (IsAllowedIp(authority))
        {
            return true;
        }

        Aws::Crt::Io::HostResolver* pHostResolver = Aws::Crt::ApiHandle::GetOrCreateStaticDefaultHostResolver();
        if (pHostResolver)
        {
          bool shouldAllow = false;
          bool hostResolved = false;
          std::mutex hostResolverMutex;
          std::condition_variable hostResolverCV;
          auto onHostResolved = [&shouldAllow, &hostResolved, &hostResolverCV, &hostResolverMutex](Aws::Crt::Io::HostResolver &resolver, const Aws::Crt::Vector<Aws::Crt::Io::HostAddress> &addresses, int errorCode)
            {
              AWS_UNREFERENCED_PARAM(resolver);
              if (AWS_ERROR_SUCCESS == errorCode)
              {
                for(const auto& address : addresses)
                {
                  if (!IsAllowedIp(Aws::String((const char*) address.address->bytes, address.address->len)))
                  {
                    return;
                  }
                }
                std::unique_lock<std::mutex> lock(hostResolverMutex);
                shouldAllow = !addresses.empty();
                hostResolved = true;
                hostResolverCV.notify_one();
              }
              else
              {
                std::unique_lock<std::mutex> lock(hostResolverMutex);
                hostResolverCV.notify_one();
              }
            };
          pHostResolver->ResolveHost(authority.c_str(), onHostResolved);
          std::unique_lock<std::mutex> lock(hostResolverMutex);
          if (!hostResolved) {
            hostResolverCV.wait_for(lock, std::chrono::milliseconds(1000));
          }
          if (shouldAllow)
          {
            return true;
          }
        }

        AWS_LOGSTREAM_WARN(GEN_HTTP_LOG_TAG, "Can't use General HTTP Provider: AWS_CONTAINER_CREDENTIALS_FULL_URI is not HTTPS and is not within loop back CIDR: " << authority);
        return false;
    }

    // both relativeUri and absoluteUri are empty
    return false;
}