diff --git a/plugin/src/software/aws/toolkits/eclipse/amazonq/lsp/connection/QLspConnectionProvider.java b/plugin/src/software/aws/toolkits/eclipse/amazonq/lsp/connection/QLspConnectionProvider.java index 80ea5c2d..78a6556c 100644 --- a/plugin/src/software/aws/toolkits/eclipse/amazonq/lsp/connection/QLspConnectionProvider.java +++ b/plugin/src/software/aws/toolkits/eclipse/amazonq/lsp/connection/QLspConnectionProvider.java @@ -18,6 +18,7 @@ import software.aws.toolkits.eclipse.amazonq.providers.LspManagerProvider; import software.aws.toolkits.eclipse.amazonq.telemetry.LanguageServerTelemetryProvider; import software.aws.toolkits.eclipse.amazonq.telemetry.metadata.ExceptionMetadata; +import software.aws.toolkits.eclipse.amazonq.util.ProxyUtil; import software.aws.toolkits.telemetry.TelemetryDefinitions.Result; import software.aws.toolkits.eclipse.amazonq.plugin.Activator; import software.aws.toolkits.eclipse.amazonq.preferences.AmazonQPreferencePage; @@ -43,7 +44,7 @@ public QLspConnectionProvider() throws IOException { @Override protected final void addEnvironmentVariables(final Map env) { - String httpsProxyPreference = Activator.getDefault().getPreferenceStore().getString(AmazonQPreferencePage.HTTPS_PROXY); + String httpsProxyPreference = ProxyUtil.getHttpsProxyUrl(); String caCertPreference = Activator.getDefault().getPreferenceStore().getString(AmazonQPreferencePage.CA_CERT); if (!StringUtils.isEmpty(httpsProxyPreference)) { env.put("HTTPS_PROXY", httpsProxyPreference); diff --git a/plugin/src/software/aws/toolkits/eclipse/amazonq/preferences/AmazonQPreferencePage.java b/plugin/src/software/aws/toolkits/eclipse/amazonq/preferences/AmazonQPreferencePage.java index 0e1c962c..2beadb6e 100644 --- a/plugin/src/software/aws/toolkits/eclipse/amazonq/preferences/AmazonQPreferencePage.java +++ b/plugin/src/software/aws/toolkits/eclipse/amazonq/preferences/AmazonQPreferencePage.java @@ -193,6 +193,7 @@ private void createHttpsProxyField() { addField(httpsProxy); createLabel(""" Sets the address of the proxy to use for all HTTPS connections. \ + For example "http://localhost:8888". \ Leave blank if not using a proxy. Eclipse restart required to take effect. """, 20, getFieldEditorParent()); diff --git a/plugin/src/software/aws/toolkits/eclipse/amazonq/util/Constants.java b/plugin/src/software/aws/toolkits/eclipse/amazonq/util/Constants.java index f0a6b875..fa290cea 100644 --- a/plugin/src/software/aws/toolkits/eclipse/amazonq/util/Constants.java +++ b/plugin/src/software/aws/toolkits/eclipse/amazonq/util/Constants.java @@ -40,5 +40,7 @@ private Constants() { public static final String AUTHENTICATE_FAILURE_MESSAGE = "An error occurred while attempting to authenticate. Please try again."; public static final String IDE_SSL_HANDSHAKE_TITLE = "SSL Handshake Error"; public static final String IDE_SSL_HANDSHAKE_BODY = "The plugin encountered an SSL handshake error. If using a proxy, check the plugin preferences."; + public static final String INVALID_PROXY_CONFIGURATION_TITLE = "Proxy Configuration Error"; + public static final String INVALID_PROXY_CONFIGURATION_BODY = "The provided proxy URL is invalid. Please check your plugin configuration."; } diff --git a/plugin/src/software/aws/toolkits/eclipse/amazonq/util/ProxyUtil.java b/plugin/src/software/aws/toolkits/eclipse/amazonq/util/ProxyUtil.java index be52afd0..a9b41a7e 100644 --- a/plugin/src/software/aws/toolkits/eclipse/amazonq/util/ProxyUtil.java +++ b/plugin/src/software/aws/toolkits/eclipse/amazonq/util/ProxyUtil.java @@ -4,18 +4,25 @@ package software.aws.toolkits.eclipse.amazonq.util; import java.io.FileInputStream; +import java.net.URI; import java.security.KeyStore; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManagerFactory; + +import org.eclipse.mylyn.commons.ui.dialogs.AbstractNotificationPopup; +import org.eclipse.swt.widgets.Display; + import software.amazon.awssdk.utils.StringUtils; import software.aws.toolkits.eclipse.amazonq.plugin.Activator; import software.aws.toolkits.eclipse.amazonq.preferences.AmazonQPreferencePage; public final class ProxyUtil { + private static boolean hasSeenInvalidProxyNotification; + private ProxyUtil() { // Prevent initialization } @@ -30,6 +37,22 @@ protected static String getHttpsProxyUrl(final String envVarValue, final String if (!StringUtils.isEmpty(prefValue)) { httpsProxy = prefValue; } + try { + if (!StringUtils.isEmpty(httpsProxy)) { + URI.create(httpsProxy); + } + } catch (IllegalArgumentException e) { + if (!hasSeenInvalidProxyNotification) { + hasSeenInvalidProxyNotification = true; + Display.getDefault().asyncExec(() -> { + AbstractNotificationPopup notification = new ToolkitNotification(Display.getCurrent(), + Constants.INVALID_PROXY_CONFIGURATION_TITLE, + Constants.INVALID_PROXY_CONFIGURATION_BODY); + notification.open(); + }); + } + return null; + } return httpsProxy; } diff --git a/plugin/tst/software/aws/toolkits/eclipse/amazonq/util/ProxyUtilTest.java b/plugin/tst/software/aws/toolkits/eclipse/amazonq/util/ProxyUtilTest.java index d8ef582c..c9e5e983 100644 --- a/plugin/tst/software/aws/toolkits/eclipse/amazonq/util/ProxyUtilTest.java +++ b/plugin/tst/software/aws/toolkits/eclipse/amazonq/util/ProxyUtilTest.java @@ -4,7 +4,13 @@ package software.aws.toolkits.eclipse.amazonq.util; import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; + import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockStatic; + +import org.eclipse.swt.widgets.Display; class ProxyUtilTest { @@ -31,4 +37,24 @@ void testPreferenceProxyUrlPrecedence() { assertEquals(mockUrl, ProxyUtil.getHttpsProxyUrl("http://bar.com:8888", mockUrl)); } + @Test + void testEnvVarInvalidProxyUrl() { + try (MockedStatic displayMock = mockStatic(Display.class)) { + Display mockDisplay = mock(Display.class); + displayMock.when(Display::getDefault).thenReturn(mockDisplay); + String mockUrl = "127.0.0.1:8000"; + assertEquals(null, ProxyUtil.getHttpsProxyUrl(mockUrl, null)); + } + } + + @Test + void testPreferenceInvalidProxyUrl() { + try (MockedStatic displayMock = mockStatic(Display.class)) { + Display mockDisplay = mock(Display.class); + displayMock.when(Display::getDefault).thenReturn(mockDisplay); + String mockUrl = "127.0.0.1:8000"; + assertEquals(null, ProxyUtil.getHttpsProxyUrl(null, mockUrl)); + } + } + }