/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.trino.server;

import com.google.inject.Binder;
import io.airlift.configuration.AbstractConfigurationAwareModule;
import io.airlift.http.client.HttpClientConfig;
import io.airlift.http.server.HttpsConfig;

import static io.airlift.configuration.ConfigBinder.configBinder;
import static io.airlift.http.client.HttpClientBinder.httpClientBinder;

public class InternalCommunicationModule
        extends AbstractConfigurationAwareModule
{
    @Override
    protected void setup(Binder binder)
    {
        // Set defaults for all HttpClients in the same guice context
        // so in case of any additions or alternations here an update in:
        //   io.trino.server.security.jwt.JwtAuthenticatorSupportModule.JwkModule.configure
        // and
        //   io.trino.server.security.oauth2.OAuth2ServiceModule.setup
        // may also be required.
        InternalCommunicationConfig internalCommunicationConfig = buildConfigObject(InternalCommunicationConfig.class);
        if (internalCommunicationConfig.isHttpsRequired() && internalCommunicationConfig.getKeyStorePath() == null && internalCommunicationConfig.getTrustStorePath() == null) {
            String sharedSecret = internalCommunicationConfig.getSharedSecret()
                    .orElseThrow(() -> new IllegalArgumentException("Internal shared secret must be set when internal HTTPS is enabled"));
            configBinder(binder).bindConfigDefaults(HttpsConfig.class, config -> config.setAutomaticHttpsSharedSecret(sharedSecret));
            configBinder(binder).bindConfigGlobalDefaults(HttpClientConfig.class, config -> {
                config.setHttp2Enabled(internalCommunicationConfig.isHttp2Enabled());
                config.setAutomaticHttpsSharedSecret(sharedSecret);
            });
        }
        else {
            configBinder(binder).bindConfigGlobalDefaults(HttpClientConfig.class, config -> {
                config.setHttp2Enabled(internalCommunicationConfig.isHttp2Enabled());
                config.setKeyStorePath(internalCommunicationConfig.getKeyStorePath());
                config.setKeyStorePassword(internalCommunicationConfig.getKeyStorePassword());
                config.setTrustStorePath(internalCommunicationConfig.getTrustStorePath());
                config.setTrustStorePassword(internalCommunicationConfig.getTrustStorePassword());
                config.setAutomaticHttpsSharedSecret(null);
            });
        }

        binder.bind(InternalAuthenticationManager.class);
        httpClientBinder(binder).bindGlobalFilter(InternalAuthenticationManager.class);
    }
}

@@ -702,218 +702,782 @@
 ift.
-http.client.HttpClientConfig;%0Aimport io.airlift.http.server.HttpsConfig;%0A%0Aimport static io.airlift.configuration.ConfigBinder.configBinder;%0Aimport static io.airlift.http.client.HttpClientBinder.httpClientBinder
+discovery.client.ForDiscoveryClient;%0Aimport io.airlift.http.client.HttpClientConfig;%0Aimport io.airlift.http.client.HttpRequestFilter;%0Aimport io.airlift.http.client.Request;%0Aimport io.airlift.http.server.HttpsConfig;%0Aimport io.airlift.node.NodeConfig;%0A%0Aimport java.io.UncheckedIOException;%0Aimport java.net.InetAddress;%0Aimport java.net.URI;%0Aimport java.net.URISyntaxException;%0Aimport java.net.UnknownHostException;%0A%0Aimport static com.google.inject.multibindings.Multibinder.newSetBinder;%0Aimport static io.airlift.configuration.ConfigBinder.configBinder;%0Aimport static io.airlift.http.client.HttpClientBinder.httpClientBinder;%0Aimport static io.airlift.node.AddressToHostname.encodeAddressAsHostname;%0Aimport static io.airlift.node.NodeConfig.AddressSource.IP_ENCODED_AS_HOSTNAME
 ;%0A%0Ap
@@ -2888,32 +2888,551 @@
             %7D);%0A
+            configBinder(binder).bindConfigGlobalDefaults(NodeConfig.class, config -%3E config.setInternalAddressSource(IP_ENCODED_AS_HOSTNAME));%0A            // rewrite discovery client requests to use IP encoded as hostname%0A            newSetBinder(binder, HttpRequestFilter.class, ForDiscoveryClient.class).addBinding()%0A                    .toInstance(request -%3E Request.Builder.fromRequest(request)%0A                            .setUri(toIpEncodedAsHostnameUri(request.getUri()))%0A                            .build());%0A
         %7D%0A      
@@ -4230,11 +4230,710 @@
 );%0A    %7D
+%0A%0A    private static URI toIpEncodedAsHostnameUri(URI uri)%0A    %7B%0A        if (!uri.getScheme().equals(%22https%22)) %7B%0A            return uri;%0A        %7D%0A        try %7B%0A            String host = uri.getHost();%0A            InetAddress inetAddress = InetAddress.getByName(host);%0A            String addressAsHostname = encodeAddressAsHostname(inetAddress);%0A            return new URI(uri.getScheme(), uri.getUserInfo(), addressAsHostname, uri.getPort(), uri.getPath(), uri.getQuery(), uri.getFragment());%0A        %7D%0A        catch (UnknownHostException e) %7B%0A            throw new UncheckedIOException(e);%0A        %7D%0A        catch (URISyntaxException e) %7B%0A            throw new RuntimeException(e);%0A        %7D%0A    %7D
 %0A%7D%0A

Use IP_ENCODED_AS_HOSTNAME with automatic TLS