Skip to content

Commit

Permalink
fix: allow pre/post-2024.3 proxy settings (#242)
Browse files Browse the repository at this point in the history
Signed-off-by: Andre Dietisheim <[email protected]>
  • Loading branch information
adietish committed Nov 4, 2024
1 parent 71b135b commit 9649d87
Show file tree
Hide file tree
Showing 2 changed files with 388 additions and 49 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,355 @@
/*******************************************************************************
* Copyright (c) 2024 Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is made available under the terms of the
* Eclipse Public License v2.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
******************************************************************************/
package com.redhat.devtools.intellij.common.utils;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.Authenticator;
import java.net.InetAddress;
import java.net.PasswordAuthentication;
import java.net.Proxy;
import java.net.ProxySelector;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;

public class IdeProxyAdapter {

public static ProxySelector getProxySelector() {
ProxySelector selector = Pre243.getProxySelector();
if (selector != null) {
return selector;
} else {
return Post243.getProxySelector();
}
}

public static Authenticator getAuthenticator() {
Authenticator authenticator = Pre243.getAuthenticator();
if (authenticator != null) {
return authenticator;
} else {
return Post243.getAuthenticator();
}
}

/**
*
* Returns the proxies that exist for the given url.
*
* @param url the url to get proxies for
* @return the proxies for the given url
*
*/
public static List<Proxy> getProxies(String url) {
List<Proxy> proxies = Pre243.getProxies(url);
if (proxies != null
&& !proxies.isEmpty()) {
return proxies;
} else {
return Post243.getProxies(url);
}
}

public static PasswordAuthentication getPasswordAuthentication() {
PasswordAuthentication authentication = Pre243.getPasswordAuthentication();
if (authentication != null) {
return authentication;
} else {
return Post243.getPasswordAuthentication();
}
}

private static class Pre243 {

static ProxySelector getProxySelector() {
Object httpConfigurable = httpConfigurable_getInstance();
if (httpConfigurable == null) {
return null;
}
return (ProxySelector) ideaWideProxySelector_newInstance(httpConfigurable);
}

/**
* <code>
* new IdeaWideAuthenticator(HttpConfigurable)
* </code>
*/
static Authenticator getAuthenticator() {
Object httpConfigurable = httpConfigurable_getInstance();
if (httpConfigurable == null) {
return null;
}
return (Authenticator) ideaWideAuthenticator_newInstance(httpConfigurable);
}

static List<Proxy> getProxies(String url) {
List<Proxy> proxies = new ArrayList<>();
try {
Object httpConfigurable = httpConfigurable_getInstance();
if (httpConfigurable != null) {
Object ideaWideProxySelector = ideaWideProxySelector_newInstance(httpConfigurable);
if (ideaWideProxySelector != null) {
proxies = ideaWideProxySelector_select(ideaWideProxySelector, new URI(url));
}
}
} catch (URISyntaxException e) {
// swallow only
}
return proxies;
}

/**
* <code>
* new IdeaWideAuthenticator(HttpConfigurable.getInstance()).getPasswordAuthentication()
* </code>
*/
static private PasswordAuthentication getPasswordAuthentication() {
PasswordAuthentication authentication = null;
Object httpConfigurable = httpConfigurable_getInstance();
if (httpConfigurable != null) {
authentication = httpConfigurable_getPromptedAuthentication("*", httpConfigurable);
}
return authentication;
}

/**
* <code>
* IdeaWideProxySelector.select(URI)
* </code>
*/
@SuppressWarnings("unchecked")
private static List<Proxy> ideaWideProxySelector_select(Object ideaWideProxySelector, URI uri) {
try {
Method method = ideaWideProxySelector.getClass().getDeclaredMethod("select", URI.class);
return (List<Proxy>) method.invoke(ideaWideProxySelector, uri);
} catch (ReflectiveOperationException | IllegalArgumentException e) {
return null;
}
}

/**
* <code>
* new IdeaWideProxySelector()
* </code>
*/
@SuppressWarnings("JavaReflectionMemberAccess")
private static Object ideaWideProxySelector_newInstance(Object httpConfigurable) {
try {
Class<?> clazz = Class.forName("com.intellij.util.net.IdeaWideProxySelector");
Constructor<?> constructor = clazz.getConstructor(httpConfigurable.getClass());
return constructor.newInstance(httpConfigurable);
} catch (ReflectiveOperationException | IllegalArgumentException e) {
return null;
}
}

/**
* <code>
* new IdeaWideAuthenticator(HttpConfigurable)
* </code>
*/
@SuppressWarnings("JavaReflectionMemberAccess")
private static Object ideaWideAuthenticator_newInstance(Object httpConfigurable) {
try {
Class<?> clazz = Class.forName("com.intellij.util.net.IdeaWideAuthenticator");
Constructor<?> constructor = clazz.getConstructor(httpConfigurable.getClass());
return constructor.newInstance(httpConfigurable);
} catch (Exception e) {
return null;
}
}

/**
* <code>
* HttpConfigurable.getPromptedAuthentication(String host, String prompt)
* </code>
*/
private static PasswordAuthentication httpConfigurable_getPromptedAuthentication(String url, Object httpConfigurable) {
try {
Method method = httpConfigurable.getClass().getMethod("getPromptedAuthentication", String.class, String.class);
return (PasswordAuthentication) method.invoke(httpConfigurable, url, null);
} catch (Exception e) {
return null;
}
}

/**
* <code>
* HttpConfigurable.getInstance()
* </code>
*/
private static Object httpConfigurable_getInstance() {
try {
Class<?> clazz = Class.forName("com.intellij.util.net.HttpConfigurable");
Method getInstanceMethod = clazz.getDeclaredMethod("getInstance");
return getInstanceMethod.invoke(null);
} catch (ReflectiveOperationException e) {
return null;
}
}
}

private static class Post243 {

/**
* <code>
* JdkProxyProvider.getInstance().getProxySelector()
* </code>
*/
static ProxySelector getProxySelector() {
Object provider = jdkProxyProvider_getInstance();
if (provider == null) {
return null;
}
return (ProxySelector) jdkProxyProvider_getProxySelector(provider);
}

/**
* <code>
* JdkProxyProvider.getInstance().getAuthenticator()
* </code>
*/
public static Authenticator getAuthenticator() {
Object proxyAuthentication = jdkProxyProvider_getInstance();
if (proxyAuthentication == null) {
return null;
}
return (Authenticator) jdkProxyProvider_getAuthenticator(proxyAuthentication);
}

/**
* <code>
* JdkProxyProvider.getInstance().getProxySelector().select(URI.create(url))
* </code>
*/
static List<Proxy> getProxies(String url) {
List<Proxy> proxies = new ArrayList<>();
try {
ProxySelector selector = getProxySelector();
if (selector != null) {
proxies = proxySelector_select(selector, new URI(url));
}
} catch (Exception e) {
// swallow only
}
return proxies;
}

/**
* <code>
* JdkProxyProvider.getInstance().getAuthenticator().requestPasswordAuthentication(
* null,
* 0,
* null,
* null,
* null
* );
* </code>
*/
private static PasswordAuthentication getPasswordAuthentication() {
PasswordAuthentication authentication = null;
Object provider = jdkProxyProvider_getInstance();
if (provider != null) {
Object authenticator = jdkProxyProvider_getAuthenticator(provider);
if (authenticator != null) {
authentication = authenticator_requestPasswordAuthentication(authenticator);
}
}
return authentication;
}

/**
* <code>
* ProxySelector.select(URI)
* <code>
*/
@SuppressWarnings("unchecked")
private static List<Proxy> proxySelector_select(Object proxySelector, URI uri) {
try {
Method method = proxySelector.getClass().getDeclaredMethod("select", URI.class);
method.setAccessible(true);
return (List<Proxy>) method.invoke(proxySelector, uri);
} catch (Exception e) {
return null;
}
}

/**
* <code>
* Authenticator.requestPasswordAuthentication(InetAddress addr, int port, String protocol, String prompt, String scheme)
* </code>
*/
private static PasswordAuthentication authenticator_requestPasswordAuthentication(Object authenticator) {
try {
Method method = authenticator.getClass().getMethod("requestPasswordAuthentication",
InetAddress.class,
Integer.TYPE,
String.class,
String.class,
String.class);
return (PasswordAuthentication) method.invoke(authenticator,
null,
0,
null,
null,
null
);
} catch (Exception e) {
return null;
}
}

/**
* <code>
* JdkProxyProvider.getProxySelector()
* </code>
*/
private static Object jdkProxyProvider_getProxySelector(Object jdkProxyProvider) {
try {
Method getInstanceMethod = jdkProxyProvider.getClass().getDeclaredMethod("getProxySelector");
return getInstanceMethod.invoke(jdkProxyProvider);
} catch (Exception e) {
return null;
}
}

/**
* <code>
* JdkProxyProvider.getAuthenticator()
* </code>
*/
private static Object jdkProxyProvider_getAuthenticator(Object jdkProxyProvider) {
try {
Method getAuthenticatorMethod = jdkProxyProvider.getClass().getDeclaredMethod("getAuthenticator");
return getAuthenticatorMethod.invoke(jdkProxyProvider);
} catch (Exception e) {
return null;
}
}

/**
* <code>
* JdkProxyProvider.getInstance()
* </code>
*/
private static Object jdkProxyProvider_getInstance() {
try {
Class<?> clazz = Class.forName("com.intellij.util.net.JdkProxyProvider");
Method getInstanceMethod = clazz.getDeclaredMethod("getInstance");
return getInstanceMethod.invoke(null);
} catch (Exception e) {
return null;
}
}
}
}
Loading

0 comments on commit 9649d87

Please sign in to comment.