diff options
Diffstat (limited to 'platform/platform-api/src/com/intellij/util/net')
11 files changed, 656 insertions, 601 deletions
diff --git a/platform/platform-api/src/com/intellij/util/net/AuthenticationDialog.java b/platform/platform-api/src/com/intellij/util/net/AuthenticationDialog.java index 246f1e449d5d..83cca8a039df 100644 --- a/platform/platform-api/src/com/intellij/util/net/AuthenticationDialog.java +++ b/platform/platform-api/src/com/intellij/util/net/AuthenticationDialog.java @@ -23,13 +23,6 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; -/** - * Created by IntelliJ IDEA. - * User: stathik - * Date: Oct 7, 2003 - * Time: 3:56:25 PM - * To change this template use Options | File Templates. - */ public class AuthenticationDialog extends DialogWrapper { private final AuthenticationPanel panel; @@ -42,7 +35,7 @@ public class AuthenticationDialog extends DialogWrapper { final Window window = getWindow(); if (window instanceof JDialog) { - ((JDialog) window).setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); + ((JDialog) window).setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); } init(); @@ -57,7 +50,7 @@ public class AuthenticationDialog extends DialogWrapper { final Window window = getWindow(); if (window instanceof JDialog) { - ((JDialog) window).setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); + ((JDialog) window).setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); } init(); @@ -69,6 +62,7 @@ public class AuthenticationDialog extends DialogWrapper { return panel.getPreferredFocusedComponent(); } + @Override @Nullable protected JComponent createCenterPanel() { return panel; diff --git a/platform/platform-api/src/com/intellij/util/net/HTTPProxySettingsDialog.java b/platform/platform-api/src/com/intellij/util/net/HTTPProxySettingsDialog.java index 52dfa7e7e5ab..5d7d807095f1 100644 --- a/platform/platform-api/src/com/intellij/util/net/HTTPProxySettingsDialog.java +++ b/platform/platform-api/src/com/intellij/util/net/HTTPProxySettingsDialog.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,43 +22,48 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.event.ActionEvent; +@Deprecated +@SuppressWarnings("UnusedDeclaration") /** - * Created by IntelliJ IDEA. - * User: stathik - * Date: Oct 21, 2003 - * Time: 4:35:44 PM - * To change this template use Options | File Templates. + * @deprecated Use {@link com.intellij.util.net.HttpConfigurable#editConfigurable(javax.swing.JComponent)} + * to remove in IDEA 15 */ public class HTTPProxySettingsDialog extends DialogWrapper { - private final HTTPProxySettingsPanel panel; + private final HttpProxySettingsUi panel; private final Action okAction; private final Action cancelAction; public HTTPProxySettingsDialog() { super(false); + setTitle(CommonBundle.message("title.http.proxy.settings")); - panel = new HTTPProxySettingsPanel(HttpConfigurable.getInstance()); - panel.reset(); + final HttpConfigurable settings = HttpConfigurable.getInstance(); + panel = new HttpProxySettingsUi(settings); + panel.reset(settings); okAction = new AbstractAction(CommonBundle.getOkButtonText()) { - public void actionPerformed(ActionEvent e) { - panel.apply(); + @Override + public void actionPerformed(@NotNull ActionEvent e) { + panel.apply(settings); close(OK_EXIT_CODE); } }; okAction.putValue(DEFAULT_ACTION, Boolean.TRUE.toString()); cancelAction = new AbstractAction(CommonBundle.getCancelButtonText()) { - public void actionPerformed(ActionEvent e) { + @Override + public void actionPerformed(@NotNull ActionEvent e) { close(CANCEL_EXIT_CODE); } }; init(); } + @Override protected JComponent createCenterPanel() { - return panel.createComponent(); + return panel.getComponent(); } + @Override @NotNull protected Action[] createActions() { return new Action[]{okAction, cancelAction}; diff --git a/platform/platform-api/src/com/intellij/util/net/HTTPProxySettingsPanel.java b/platform/platform-api/src/com/intellij/util/net/HTTPProxySettingsPanel.java index 46ea422a3f69..f53c88f372e5 100644 --- a/platform/platform-api/src/com/intellij/util/net/HTTPProxySettingsPanel.java +++ b/platform/platform-api/src/com/intellij/util/net/HTTPProxySettingsPanel.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,389 +15,18 @@ */ package com.intellij.util.net; -import com.intellij.openapi.application.Application; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.options.Configurable; -import com.intellij.openapi.options.SearchableConfigurable; -import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.ui.MultiLineLabelUI; -import com.intellij.openapi.util.Comparing; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.wm.IdeFocusManager; -import com.intellij.openapi.wm.IdeFrame; -import com.intellij.ui.components.JBLabel; -import com.intellij.ui.components.JBRadioButton; -import com.intellij.util.proxy.CommonProxy; -import com.intellij.util.proxy.JavaProxyProperty; -import com.intellij.util.ui.UIUtil; -import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; -import javax.swing.*; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.io.IOException; -import java.net.HttpURLConnection; -import java.util.concurrent.atomic.AtomicReference; - +@SuppressWarnings("UnusedDeclaration") +@Deprecated /** - * Created by IntelliJ IDEA. - * User: stathik - * Date: Aug 28, 2003 - * Time: 3:52:47 PM - * To change this template use Options | File Templates. + * @deprecated Use {@link HttpProxyConfigurable} + * to remove in IDEA 15 */ -public class HTTPProxySettingsPanel implements SearchableConfigurable, Configurable.NoScroll { +public class HTTPProxySettingsPanel extends HttpProxyConfigurable { public static final String NAME = "Proxy"; - private JPanel myMainPanel; - - private JTextField myProxyLoginTextField; - private JPasswordField myProxyPasswordTextField; - private JCheckBox myProxyAuthCheckBox; - private JTextField myProxyPortTextField; - private JTextField myProxyHostTextField; - private JCheckBox myRememberProxyPasswordCheckBox; - - private JLabel myProxyLoginLabel; - private JLabel myProxyPasswordLabel; - private JLabel myHostNameLabel; - private JLabel myPortNumberLabel; - private JBRadioButton myAutoDetectProxyRb; - private JBRadioButton myUseHTTPProxyRb; - private JBLabel mySystemProxyDefined; - private JBRadioButton myNoProxyRb; - private JBRadioButton myHTTP; - private JBRadioButton mySocks; - private JButton myClearPasswordsButton; - private JLabel myErrorLabel; - private JButton myCheckButton; - private JBLabel myOtherWarning; - private JLabel myProxyExceptionsLabel; - private JTextArea myProxyExceptions; - private JLabel myNoProxyForLabel; - private JCheckBox myPacUrlCheckBox; - private JTextField myPacUrlTextField; - private final HttpConfigurable myHttpConfigurable; - private volatile boolean myConnectionCheckInProgress; - - public boolean isModified() { - boolean isModified = false; - HttpConfigurable httpConfigurable = myHttpConfigurable; - if (! Comparing.equal(myProxyExceptions.getText().trim(), httpConfigurable.PROXY_EXCEPTIONS)) return true; - isModified |= httpConfigurable.USE_PROXY_PAC != myAutoDetectProxyRb.isSelected(); - isModified |= httpConfigurable.USE_PAC_URL != myPacUrlCheckBox.isSelected(); - isModified |= !Comparing.strEqual(httpConfigurable.PAC_URL, myPacUrlTextField.getText()); - isModified |= httpConfigurable.USE_HTTP_PROXY != myUseHTTPProxyRb.isSelected(); - isModified |= httpConfigurable.PROXY_AUTHENTICATION != myProxyAuthCheckBox.isSelected(); - isModified |= httpConfigurable.KEEP_PROXY_PASSWORD != myRememberProxyPasswordCheckBox.isSelected(); - isModified |= httpConfigurable.PROXY_TYPE_IS_SOCKS != mySocks.isSelected(); - - isModified |= !Comparing.strEqual(httpConfigurable.PROXY_LOGIN, myProxyLoginTextField.getText()); - isModified |= !Comparing.strEqual(httpConfigurable.getPlainProxyPassword(),new String (myProxyPasswordTextField.getPassword())); - - try { - isModified |= httpConfigurable.PROXY_PORT != Integer.valueOf(myProxyPortTextField.getText()).intValue(); - } catch (NumberFormatException e) { - isModified = true; - } - isModified |= !Comparing.strEqual(httpConfigurable.PROXY_HOST, myProxyHostTextField.getText()); - return isModified; - } - - public HTTPProxySettingsPanel(final HttpConfigurable httpConfigurable) { - final ButtonGroup group = new ButtonGroup(); - group.add(myUseHTTPProxyRb); - group.add(myAutoDetectProxyRb); - group.add(myNoProxyRb); - myNoProxyRb.setSelected(true); - - final ButtonGroup proxyTypeGroup = new ButtonGroup(); - proxyTypeGroup.add(myHTTP); - proxyTypeGroup.add(mySocks); - myHTTP.setSelected(true); - - myProxyExceptions.setBorder(UIUtil.getTextFieldBorder()); - - final Boolean property = Boolean.getBoolean(JavaProxyProperty.USE_SYSTEM_PROXY); - mySystemProxyDefined.setVisible(Boolean.TRUE.equals(property)); - if (Boolean.TRUE.equals(property)) { - mySystemProxyDefined.setIcon(Messages.getWarningIcon()); - mySystemProxyDefined.setFont(mySystemProxyDefined.getFont().deriveFont(Font.BOLD)); - mySystemProxyDefined.setUI(new MultiLineLabelUI()); - } - - myProxyAuthCheckBox.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - enableProxyAuthentication(myProxyAuthCheckBox.isSelected()); - } - }); - myPacUrlCheckBox.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - myPacUrlTextField.setEnabled(myPacUrlCheckBox.isSelected()); - } - }); - - final ActionListener listener = new ActionListener() { - public void actionPerformed(ActionEvent e) { - enableProxy(myUseHTTPProxyRb.isSelected()); - } - }; - myUseHTTPProxyRb.addActionListener(listener); - myAutoDetectProxyRb.addActionListener(listener); - myNoProxyRb.addActionListener(listener); - myHttpConfigurable = httpConfigurable; - - myClearPasswordsButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - myHttpConfigurable.clearGenericPasswords(); - Messages.showMessageDialog(myMainPanel, "Proxy passwords were cleared.", "Auto-detected proxy", Messages.getInformationIcon()); - } - }); - - if (HttpConfigurable.getInstance() != null) { - myCheckButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - final String title = "Check Proxy Settings"; - final String answer = Messages - .showInputDialog(myMainPanel, "Warning: your settings will be saved.\n\nEnter any URL to check connection to:", - title, Messages.getQuestionIcon(), "http://", null); - if (! StringUtil.isEmptyOrSpaces(answer)) { - apply(); - final HttpConfigurable instance = HttpConfigurable.getInstance(); - final AtomicReference<IOException> exc = new AtomicReference<IOException>(); - myCheckButton.setEnabled(false); - myCheckButton.setText("Check connection (in progress...)"); - myConnectionCheckInProgress = true; - final Application application = ApplicationManager.getApplication(); - application.executeOnPooledThread(new Runnable() { - @Override - public void run() { - HttpURLConnection connection = null; - try { - //already checked for null above - //noinspection ConstantConditions - connection = instance.openHttpConnection(answer); - connection.setReadTimeout(3 * 1000); - connection.setConnectTimeout(3 * 1000); - connection.connect(); - final int code = connection.getResponseCode(); - if (HttpURLConnection.HTTP_OK != code) { - exc.set(new IOException("Error code: " + code)); - } - } - catch (IOException e1) { - exc.set(e1); - } - finally { - if (connection != null) { - connection.disconnect(); - } - } - //noinspection SSBasedInspection - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - myConnectionCheckInProgress = false; - reset(); // since password might have been set - Component parent = null; - if (myMainPanel.isShowing()) { - parent = myMainPanel; - myCheckButton.setText("Check connection"); - myCheckButton.setEnabled(canEnableConnectionCheck()); - } else { - final IdeFrame frame = IdeFocusManager.findInstance().getLastFocusedFrame(); - if (frame == null) { - return; - } - parent = frame.getComponent(); - } - //noinspection ThrowableResultOfMethodCallIgnored - final IOException exception = exc.get(); - if (exception == null) { - Messages.showMessageDialog(parent, "Connection successful", title, Messages.getInformationIcon()); - } - else { - final String message = exception.getMessage(); - if (instance.USE_HTTP_PROXY) { - instance.LAST_ERROR = message; - } - Messages.showErrorDialog(parent, errorText(message)); - } - } - }); - } - }); - } - } - }); - } else { - myCheckButton.setVisible(false); - } - } - - private boolean canEnableConnectionCheck() { - return ! myNoProxyRb.isSelected() && ! myConnectionCheckInProgress; - } - - public void reset() { - myNoProxyRb.setSelected(true); // default - HttpConfigurable httpConfigurable = myHttpConfigurable; - myAutoDetectProxyRb.setSelected(httpConfigurable.USE_PROXY_PAC); - myPacUrlCheckBox.setSelected(httpConfigurable.USE_PAC_URL); - myPacUrlTextField.setText(httpConfigurable.PAC_URL); - myUseHTTPProxyRb.setSelected(httpConfigurable.USE_HTTP_PROXY); - myProxyAuthCheckBox.setSelected(httpConfigurable.PROXY_AUTHENTICATION); - - enableProxy(httpConfigurable.USE_HTTP_PROXY); - - myProxyLoginTextField.setText(httpConfigurable.PROXY_LOGIN); - myProxyPasswordTextField.setText(httpConfigurable.getPlainProxyPassword()); - - myProxyPortTextField.setText(Integer.toString(httpConfigurable.PROXY_PORT)); - myProxyHostTextField.setText(httpConfigurable.PROXY_HOST); - myProxyExceptions.setText(httpConfigurable.PROXY_EXCEPTIONS); - - myRememberProxyPasswordCheckBox.setSelected(httpConfigurable.KEEP_PROXY_PASSWORD); - mySocks.setSelected(httpConfigurable.PROXY_TYPE_IS_SOCKS); - myHTTP.setSelected(!httpConfigurable.PROXY_TYPE_IS_SOCKS); - - final boolean showError = !StringUtil.isEmptyOrSpaces(httpConfigurable.LAST_ERROR); - myErrorLabel.setVisible(showError); - myErrorLabel.setText(showError ? errorText(httpConfigurable.LAST_ERROR) : ""); - - final String oldStyleText = CommonProxy.getMessageFromProps(CommonProxy.getOldStyleProperties()); - myOtherWarning.setVisible(oldStyleText != null); - if (oldStyleText != null) { - myOtherWarning.setText(oldStyleText); - myOtherWarning.setUI(new MultiLineLabelUI()); - myOtherWarning.setIcon(Messages.getWarningIcon()); - } - } - - private String errorText(final String s) { - return "Problem with connection: " + s; - } - - public void apply () { - HttpConfigurable httpConfigurable = myHttpConfigurable; - if (isModified()){ - httpConfigurable.AUTHENTICATION_CANCELLED = false; - } - httpConfigurable.USE_PROXY_PAC = myAutoDetectProxyRb.isSelected(); - httpConfigurable.USE_PAC_URL = myPacUrlCheckBox.isSelected(); - httpConfigurable.PAC_URL = trimFieldText(myPacUrlTextField); - httpConfigurable.USE_HTTP_PROXY = myUseHTTPProxyRb.isSelected(); - httpConfigurable.PROXY_TYPE_IS_SOCKS = mySocks.isSelected(); - httpConfigurable.PROXY_AUTHENTICATION = myProxyAuthCheckBox.isSelected(); - httpConfigurable.KEEP_PROXY_PASSWORD = myRememberProxyPasswordCheckBox.isSelected(); - - httpConfigurable.PROXY_LOGIN = trimFieldText(myProxyLoginTextField); - httpConfigurable.setPlainProxyPassword(new String(myProxyPasswordTextField.getPassword())); - httpConfigurable.PROXY_EXCEPTIONS = myProxyExceptions.getText(); - - try { - httpConfigurable.PROXY_PORT = Integer.valueOf(trimFieldText(myProxyPortTextField)).intValue(); - } catch (NumberFormatException e) { - httpConfigurable.PROXY_PORT = 80; - } - httpConfigurable.PROXY_HOST = trimFieldText(myProxyHostTextField); - } - - private static String trimFieldText(JTextField field) { - String trimmed = field.getText().trim(); - field.setText(trimmed); - return trimmed; - } - - private void enableProxy (boolean enabled) { - myHostNameLabel.setEnabled(enabled); - myPortNumberLabel.setEnabled(enabled); - myProxyHostTextField.setEnabled(enabled); - myProxyPortTextField.setEnabled(enabled); - mySocks.setEnabled(enabled); - myHTTP.setEnabled(enabled); - myProxyExceptions.setEnabled(enabled); - myProxyExceptions.setBackground(myProxyPortTextField.getBackground()); - myProxyExceptionsLabel.setEnabled(enabled); - myNoProxyForLabel.setEnabled(enabled); - - myProxyAuthCheckBox.setEnabled(enabled); - enableProxyAuthentication(enabled && myProxyAuthCheckBox.isSelected()); - myCheckButton.setEnabled(canEnableConnectionCheck()); - - final boolean autoDetectProxy = myAutoDetectProxyRb.isSelected(); - myPacUrlCheckBox.setEnabled(autoDetectProxy); - myClearPasswordsButton.setEnabled(autoDetectProxy); - myPacUrlTextField.setEnabled(autoDetectProxy && myPacUrlCheckBox.isSelected()); - } - - private void enableProxyAuthentication (boolean enabled) { - myProxyPasswordLabel.setEnabled(enabled); - myProxyLoginLabel.setEnabled(enabled); - - myProxyLoginTextField.setEnabled(enabled); - myProxyPasswordTextField.setEnabled(enabled); - - myRememberProxyPasswordCheckBox.setEnabled(enabled); - } - - public JComponent getComponent() { - return myMainPanel; - } - - public JComponent createComponent() { - return myMainPanel; - } - - @NotNull - public String getId() { - return getHelpTopic(); - } - - public Runnable enableSearch(final String option) { - return null; - } - - @Nls - public String getDisplayName() { - return NAME; - } - - public String getHelpTopic() { - return "http.proxy"; - } - - public void addActionListener(final ActionListener actionListener) { - myProxyLoginTextField.addActionListener(actionListener); - DocumentListener docListener = new DocumentListener() { - public void insertUpdate(DocumentEvent e) { - actionListener.actionPerformed(null); - } - - public void removeUpdate(DocumentEvent e) { - actionListener.actionPerformed(null); - } - - public void changedUpdate(DocumentEvent e) { - actionListener.actionPerformed(null); - } - }; - myProxyPasswordTextField.getDocument().addDocumentListener(docListener); - myProxyAuthCheckBox.addActionListener(actionListener); - myProxyPortTextField.getDocument().addDocumentListener(docListener); - myProxyHostTextField.getDocument().addDocumentListener(docListener); - myUseHTTPProxyRb.addActionListener(actionListener); - myRememberProxyPasswordCheckBox.addActionListener(actionListener); - - } - @Override - public void disposeUIResources() { + public HTTPProxySettingsPanel(@NotNull HttpConfigurable settings) { + super(settings); } -} +}
\ No newline at end of file diff --git a/platform/platform-api/src/com/intellij/util/net/HttpConfigurable.java b/platform/platform-api/src/com/intellij/util/net/HttpConfigurable.java index d51891a8ffe4..0f9855001b63 100644 --- a/platform/platform-api/src/com/intellij/util/net/HttpConfigurable.java +++ b/platform/platform-api/src/com/intellij/util/net/HttpConfigurable.java @@ -21,22 +21,28 @@ import com.intellij.openapi.application.PathManager; import com.intellij.openapi.components.*; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.options.ShowSettingsUtil; +import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.popup.util.PopupUtil; import com.intellij.openapi.util.*; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.CharsetToolkit; import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.openapi.wm.IdeFrame; +import com.intellij.util.Base64; import com.intellij.util.SystemProperties; import com.intellij.util.WaitForProgressToShow; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.proxy.CommonProxy; import com.intellij.util.proxy.JavaProxyProperty; import com.intellij.util.xmlb.XmlSerializer; import com.intellij.util.xmlb.XmlSerializerUtil; import com.intellij.util.xmlb.annotations.Transient; -import org.apache.commons.codec.binary.Base64; +import gnu.trove.THashMap; +import gnu.trove.THashSet; +import gnu.trove.TObjectObjectProcedure; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -48,75 +54,74 @@ import java.lang.reflect.InvocationTargetException; import java.net.*; import java.util.*; -/** - * Created by IntelliJ IDEA. - * User: stathik - * Date: Oct 7, 2003 - * Time: 3:58:23 PM - * To change this template use Options | File Templates. - */ @State( name = "HttpConfigurable", storages = { - @Storage( file = StoragePathMacros.APP_CONFIG + "/other.xml" ), - @Storage( file = StoragePathMacros.APP_CONFIG + "/proxy.settings.xml" ) + // we use two storages due to backward compatibility, see http://crucible.labs.intellij.net/cru/CR-IC-5142 + @Storage(file = StoragePathMacros.APP_CONFIG + "/other.xml"), + @Storage(file = StoragePathMacros.APP_CONFIG + "/proxy.settings.xml") }, storageChooser = HttpConfigurable.StorageChooser.class ) -public class HttpConfigurable implements PersistentStateComponent<HttpConfigurable>, ApplicationComponent, - ExportableApplicationComponent { +public class HttpConfigurable implements PersistentStateComponent<HttpConfigurable>, ExportableApplicationComponent { public static final int CONNECTION_TIMEOUT = SystemProperties.getIntProperty("idea.connection.timeout", 10000); - private static final Logger LOG = Logger.getInstance("#com.intellij.util.net.HttpConfigurable"); - public boolean PROXY_TYPE_IS_SOCKS = false; - public boolean USE_HTTP_PROXY = false; - public boolean USE_PROXY_PAC = false; - public volatile transient boolean AUTHENTICATION_CANCELLED = false; - public String PROXY_HOST = ""; + private static final Logger LOG = Logger.getInstance(HttpConfigurable.class); + + public boolean PROXY_TYPE_IS_SOCKS; + public boolean USE_HTTP_PROXY; + public boolean USE_PROXY_PAC; + public volatile transient boolean AUTHENTICATION_CANCELLED; + public String PROXY_HOST; public int PROXY_PORT = 80; - public volatile boolean PROXY_AUTHENTICATION = false; - public volatile String PROXY_LOGIN = ""; - public volatile String PROXY_PASSWORD_CRYPT = ""; - public boolean KEEP_PROXY_PASSWORD = false; + public volatile boolean PROXY_AUTHENTICATION; + public volatile String PROXY_LOGIN; + public volatile String PROXY_PASSWORD_CRYPT; + public boolean KEEP_PROXY_PASSWORD; public transient String LAST_ERROR; - public Map<CommonProxy.HostInfo, ProxyInfo> myGenericPasswords = new HashMap<CommonProxy.HostInfo, ProxyInfo>(); - public Set<CommonProxy.HostInfo> myGenericCancelled = new HashSet<CommonProxy.HostInfo>(); + + private final THashMap<CommonProxy.HostInfo, ProxyInfo> myGenericPasswords = new THashMap<CommonProxy.HostInfo, ProxyInfo>(); + private final Set<CommonProxy.HostInfo> myGenericCancelled = new THashSet<CommonProxy.HostInfo>(); + + public String PROXY_EXCEPTIONS; + public boolean USE_PAC_URL; + public String PAC_URL; + + private transient IdeaWideProxySelector mySelector; + private transient final Object myLock = new Object(); - private IdeaWideProxySelector mySelector; - private IdeaWideAuthenticator myAuthenticator; + + @SuppressWarnings("UnusedDeclaration") public transient Getter<PasswordAuthentication> myTestAuthRunnable = new StaticGetter<PasswordAuthentication>(null); public transient Getter<PasswordAuthentication> myTestGenericAuthRunnable = new StaticGetter<PasswordAuthentication>(null); - public String PROXY_EXCEPTIONS = ""; - public boolean USE_PAC_URL = false; - public String PAC_URL = ""; public static HttpConfigurable getInstance() { return ServiceManager.getService(HttpConfigurable.class); } - public static boolean editConfigurable(final JComponent parent) { - return ShowSettingsUtil.getInstance().editConfigurable(parent, new HTTPProxySettingsPanel(getInstance())); + public static boolean editConfigurable(@Nullable JComponent parent) { + return ShowSettingsUtil.getInstance().editConfigurable(parent, new HttpProxyConfigurable()); } @Override public HttpConfigurable getState() { CommonProxy.isInstalledAssertion(); - final HttpConfigurable state = new HttpConfigurable(); + + HttpConfigurable state = new HttpConfigurable(); XmlSerializerUtil.copyBean(this, state); if (!KEEP_PROXY_PASSWORD) { - state.PROXY_PASSWORD_CRYPT = ""; + state.PROXY_PASSWORD_CRYPT = null; } - correctPasswords(this, state); + correctPasswords(state); return state; } @Override public void initComponent() { mySelector = new IdeaWideProxySelector(this); - myAuthenticator = new IdeaWideAuthenticator(this); - final String name = getClass().getName(); + String name = getClass().getName(); CommonProxy.getInstance().setCustom(name, mySelector); - CommonProxy.getInstance().setCustomAuth(name, myAuthenticator); + CommonProxy.getInstance().setCustomAuth(name, new IdeaWideAuthenticator(this)); } @NotNull @@ -137,62 +142,64 @@ public class HttpConfigurable implements PersistentStateComponent<HttpConfigurab return getClass().getName(); } - private void correctPasswords(HttpConfigurable from, HttpConfigurable to) { + private void correctPasswords(@NotNull HttpConfigurable to) { synchronized (myLock) { - to.myGenericPasswords = new HashMap<CommonProxy.HostInfo, ProxyInfo>(); - for (Map.Entry<CommonProxy.HostInfo, ProxyInfo> entry : from.myGenericPasswords.entrySet()) { - if (Boolean.TRUE.equals(entry.getValue().isStore())) { - to.myGenericPasswords.put(entry.getKey(), entry.getValue()); + to.myGenericPasswords.retainEntries(new TObjectObjectProcedure<CommonProxy.HostInfo, ProxyInfo>() { + @Override + public boolean execute(CommonProxy.HostInfo hostInfo, ProxyInfo proxyInfo) { + return proxyInfo.isStore(); } - } + }); } } @Override - public void loadState(HttpConfigurable state) { + public void loadState(@NotNull HttpConfigurable state) { XmlSerializerUtil.copyBean(state, this); if (!KEEP_PROXY_PASSWORD) { - PROXY_PASSWORD_CRYPT = ""; + PROXY_PASSWORD_CRYPT = null; } - correctPasswords(state, this); + correctPasswords(this); } - public boolean isGenericPasswordCanceled(final String host, final int port) { + public boolean isGenericPasswordCanceled(@NotNull String host, int port) { synchronized (myLock) { - return myGenericCancelled.contains(Pair.create(host, port)); + return myGenericCancelled.contains(new CommonProxy.HostInfo(null, host, port)); } } public void setGenericPasswordCanceled(final String host, final int port) { synchronized (myLock) { - myGenericCancelled.add(new CommonProxy.HostInfo("", host, port)); + myGenericCancelled.add(new CommonProxy.HostInfo(null, host, port)); } } - public PasswordAuthentication getGenericPassword(final String host, final int port) { + public PasswordAuthentication getGenericPassword(@NotNull String host, int port) { final ProxyInfo proxyInfo; synchronized (myLock) { - proxyInfo = myGenericPasswords.get(new CommonProxy.HostInfo("", host, port)); + proxyInfo = myGenericPasswords.get(new CommonProxy.HostInfo(null, host, port)); + } + if (proxyInfo == null) { + return null; } - if (proxyInfo == null) return null; return new PasswordAuthentication(proxyInfo.getUsername(), decode(String.valueOf(proxyInfo.getPasswordCrypt())).toCharArray()); } - public void putGenericPassword(final String host, final int port, final PasswordAuthentication authentication, final boolean remember) { - final PasswordAuthentication coded = new PasswordAuthentication(authentication.getUserName(), encode(String.valueOf(authentication.getPassword())).toCharArray()); + public void putGenericPassword(final String host, final int port, @NotNull PasswordAuthentication authentication, boolean remember) { + PasswordAuthentication coded = new PasswordAuthentication(authentication.getUserName(), encode(String.valueOf(authentication.getPassword())).toCharArray()); synchronized (myLock) { - myGenericPasswords.put(new CommonProxy.HostInfo("", host, port), new ProxyInfo(remember, coded.getUserName(), String.valueOf( - coded.getPassword()))); + myGenericPasswords.put(new CommonProxy.HostInfo(null, host, port), new ProxyInfo(remember, coded.getUserName(), String.valueOf(coded.getPassword()))); } } @Transient + @Nullable public String getPlainProxyPassword() { - return decode(PROXY_PASSWORD_CRYPT); + return PROXY_PASSWORD_CRYPT == null ? null : decode(PROXY_PASSWORD_CRYPT); } - private String decode(String value) { - return new String(new Base64().decode(value.getBytes())); + private static String decode(String value) { + return new String(Base64.decode(value)); } @Transient @@ -200,42 +207,50 @@ public class HttpConfigurable implements PersistentStateComponent<HttpConfigurab PROXY_PASSWORD_CRYPT = encode(password); } - private String encode(String password) { - return new String(new Base64().encode(password.getBytes())); + private static String encode(String password) { + return new String(Base64.encode(password.getBytes(CharsetToolkit.UTF8_CHARSET))); } public PasswordAuthentication getGenericPromptedAuthentication(final String prefix, final String host, final String prompt, final int port, final boolean remember) { if (ApplicationManager.getApplication().isUnitTestMode()) { return myTestGenericAuthRunnable.get(); } - final PasswordAuthentication[] value = new PasswordAuthentication[1]; - final Runnable runnable = new Runnable() { + + final Ref<PasswordAuthentication> value = Ref.create(); + runAboveAll(new Runnable() { + @Override public void run() { - if (isGenericPasswordCanceled(host, port)) return; - final PasswordAuthentication password = getGenericPassword(host, port); + if (isGenericPasswordCanceled(host, port)) { + return; + } + + PasswordAuthentication password = getGenericPassword(host, port); if (password != null) { - value[0] = password; + value.set(password); return; } - final AuthenticationDialog dlg = new AuthenticationDialog(PopupUtil.getActiveComponent(), prefix + host, - "Please enter credentials for: " + prompt, "", "", remember); - dlg.show(); - if (dlg.getExitCode() == DialogWrapper.OK_EXIT_CODE) { - final AuthenticationPanel panel = dlg.getPanel(); - final boolean remember1 = remember && panel.isRememberPassword(); - value[0] = new PasswordAuthentication(panel.getLogin(), panel.getPassword()); - putGenericPassword(host, port, value[0], remember1); - } else { + + AuthenticationDialog dialog = new AuthenticationDialog(PopupUtil.getActiveComponent(), prefix + host, + "Please enter credentials for: " + prompt, "", "", remember); + dialog.show(); + if (dialog.getExitCode() == DialogWrapper.OK_EXIT_CODE) { + AuthenticationPanel panel = dialog.getPanel(); + PasswordAuthentication passwordAuthentication = new PasswordAuthentication(panel.getLogin(), panel.getPassword()); + putGenericPassword(host, port, passwordAuthentication, remember && panel.isRememberPassword()); + value.set(passwordAuthentication); + } + else { setGenericPasswordCanceled(host, port); } } - }; - runAboveAll(runnable); - return value[0]; + }); + return value.get(); } public PasswordAuthentication getPromptedAuthentication(final String host, final String prompt) { - if (AUTHENTICATION_CANCELLED) return null; + if (AUTHENTICATION_CANCELLED) { + return null; + } final String password = getPlainProxyPassword(); if (PROXY_AUTHENTICATION && ! StringUtil.isEmptyOrSpaces(PROXY_LOGIN) && ! StringUtil.isEmptyOrSpaces(password)) { return new PasswordAuthentication(PROXY_LOGIN, password.toCharArray()); @@ -248,63 +263,63 @@ public class HttpConfigurable implements PersistentStateComponent<HttpConfigurab if (ApplicationManager.getApplication().isUnitTestMode()) { return myTestGenericAuthRunnable.get(); } - final String login = PROXY_LOGIN == null ? "" : PROXY_LOGIN; final PasswordAuthentication[] value = new PasswordAuthentication[1]; - final Runnable runnable = new Runnable() { + runAboveAll(new Runnable() { + @Override public void run() { - if (AUTHENTICATION_CANCELLED) return; + if (AUTHENTICATION_CANCELLED) { + return; + } + // password might have changed, and the check below is for that - final String password = getPlainProxyPassword(); + String password = getPlainProxyPassword(); if (PROXY_AUTHENTICATION && ! StringUtil.isEmptyOrSpaces(PROXY_LOGIN) && ! StringUtil.isEmptyOrSpaces(password)) { value[0] = new PasswordAuthentication(PROXY_LOGIN, password.toCharArray()); return; } - final AuthenticationDialog dlg = new AuthenticationDialog(PopupUtil.getActiveComponent(), "Proxy authentication: " + host, - "Please enter credentials for: " + prompt, login, "", KEEP_PROXY_PASSWORD); - dlg.show(); - if (dlg.getExitCode() == DialogWrapper.OK_EXIT_CODE) { + AuthenticationDialog dialog = new AuthenticationDialog(PopupUtil.getActiveComponent(), "Proxy authentication: " + host, + "Please enter credentials for: " + prompt, PROXY_LOGIN, "", KEEP_PROXY_PASSWORD); + dialog.show(); + if (dialog.getExitCode() == DialogWrapper.OK_EXIT_CODE) { PROXY_AUTHENTICATION = true; - final AuthenticationPanel panel = dlg.getPanel(); + AuthenticationPanel panel = dialog.getPanel(); KEEP_PROXY_PASSWORD = panel.isRememberPassword(); - PROXY_LOGIN = panel.getLogin(); + PROXY_LOGIN = StringUtil.nullize(panel.getLogin()); setPlainProxyPassword(String.valueOf(panel.getPassword())); value[0] = new PasswordAuthentication(panel.getLogin(), panel.getPassword()); } else { AUTHENTICATION_CANCELLED = true; } } - }; - runAboveAll(runnable); + }); return value[0]; } - @SuppressWarnings("MethodMayBeStatic") - private void runAboveAll(final Runnable runnable) { + private static void runAboveAll(@NotNull final Runnable runnable) { final Runnable throughSwing = new Runnable() { @Override public void run() { if (SwingUtilities.isEventDispatchThread()) { runnable.run(); - return; } - try { - SwingUtilities.invokeAndWait(runnable); - } - catch (InterruptedException e) { - LOG.info(e); - } - catch (InvocationTargetException e) { - LOG.info(e); + else { + try { + SwingUtilities.invokeAndWait(runnable); + } + catch (InterruptedException e) { + LOG.info(e); + } + catch (InvocationTargetException e) { + LOG.info(e); + } } } }; - if (ProgressManager.getInstance().getProgressIndicator() != null) { - if (ProgressManager.getInstance().getProgressIndicator().isModal()) { - WaitForProgressToShow.runOrInvokeAndWaitAboveProgress(runnable); - } else { - throughSwing.run(); - } - } else { + ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator(); + if (progressIndicator != null && progressIndicator.isModal()) { + WaitForProgressToShow.runOrInvokeAndWaitAboveProgress(runnable); + } + else { throughSwing.run(); } } @@ -312,22 +327,23 @@ public class HttpConfigurable implements PersistentStateComponent<HttpConfigurab //these methods are preserved for compatibility with com.intellij.openapi.project.impl.IdeaServerSettings @Deprecated public void readExternal(Element element) throws InvalidDataException { + //noinspection ConstantConditions loadState(XmlSerializer.deserialize(element, HttpConfigurable.class)); } @Deprecated public void writeExternal(Element element) throws WriteExternalException { XmlSerializer.serializeInto(getState(), element); - if (USE_PROXY_PAC && USE_HTTP_PROXY && ! ApplicationManager.getApplication().isDisposed()) { + if (USE_PROXY_PAC && USE_HTTP_PROXY && !ApplicationManager.getApplication().isDisposed()) { ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { - final IdeFrame frame = IdeFocusManager.findInstance().getLastFocusedFrame(); + IdeFrame frame = IdeFocusManager.findInstance().getLastFocusedFrame(); if (frame != null) { USE_PROXY_PAC = false; Messages.showMessageDialog(frame.getComponent(), "Proxy: both 'use proxy' and 'autodetect proxy' settings were set." + "\nOnly one of these options should be selected.\nPlease re-configure.", - "Proxy setup", Messages.getWarningIcon()); + "Proxy Setup", Messages.getWarningIcon()); editConfigurable(frame.getComponent()); } } @@ -344,51 +360,52 @@ public class HttpConfigurable implements PersistentStateComponent<HttpConfigurab * @param url URL for HTTP connection * @throws IOException */ - public void prepareURL (String url) throws IOException { - //setAuthenticator(); - CommonProxy.isInstalledAssertion(); - - final URLConnection connection = openConnection(url); + public void prepareURL(@NotNull String url) throws IOException { + URLConnection connection = openConnection(url); try { connection.connect(); connection.getInputStream(); } - catch (Throwable e) { - if (e instanceof IOException) { - throw (IOException)e; - } - } finally { + catch (IOException e) { + throw e; + } + catch (Throwable ignored) { + } + finally { if (connection instanceof HttpURLConnection) { ((HttpURLConnection)connection).disconnect(); } } } + @NotNull public URLConnection openConnection(@NotNull String location) throws IOException { CommonProxy.isInstalledAssertion(); final URL url = new URL(location); URLConnection urlConnection = null; final List<Proxy> proxies = CommonProxy.getInstance().select(url); - if (proxies == null || proxies.isEmpty()) { + if (ContainerUtil.isEmpty(proxies)) { urlConnection = url.openConnection(); - } else { - IOException ioe = null; + } + else { + IOException exception = null; for (Proxy proxy : proxies) { try { urlConnection = url.openConnection(proxy); - } catch (IOException e) { + } + catch (IOException e) { // continue iteration - ioe = e; + exception = e; } } - if (urlConnection == null && ioe != null) { - throw ioe; + if (urlConnection == null && exception != null) { + throw exception; } } - if (urlConnection != null) { - urlConnection.setReadTimeout(CONNECTION_TIMEOUT); - urlConnection.setConnectTimeout(CONNECTION_TIMEOUT); - } + + assert urlConnection != null; + urlConnection.setReadTimeout(CONNECTION_TIMEOUT); + urlConnection.setConnectTimeout(CONNECTION_TIMEOUT); return urlConnection; } @@ -461,12 +478,15 @@ public class HttpConfigurable implements PersistentStateComponent<HttpConfigurab return result; } - public static boolean isRealProxy(Proxy proxy) { - return ! Proxy.NO_PROXY.equals(proxy) && ! Proxy.Type.DIRECT.equals(proxy.type()); + public static boolean isRealProxy(@NotNull Proxy proxy) { + return !Proxy.NO_PROXY.equals(proxy) && !Proxy.Type.DIRECT.equals(proxy.type()); } + @NotNull public static List<String> convertArguments(@NotNull final List<KeyValue<String, String>> list) { - if (list.isEmpty()) return Collections.emptyList(); + if (list.isEmpty()) { + return Collections.emptyList(); + } final List<String> result = new ArrayList<String>(list.size()); for (KeyValue<String, String> value : list) { result.add("-D" + value.getKey() + "=" + value.getValue()); @@ -481,7 +501,7 @@ public class HttpConfigurable implements PersistentStateComponent<HttpConfigurab } } - public void removeGeneric(CommonProxy.HostInfo info) { + public void removeGeneric(@NotNull CommonProxy.HostInfo info) { synchronized (myLock) { myGenericPasswords.remove(info); } @@ -518,6 +538,7 @@ public class HttpConfigurable implements PersistentStateComponent<HttpConfigurab public String myUsername; public String myPasswordCrypt; + @SuppressWarnings("UnusedDeclaration") public ProxyInfo() { } @@ -547,6 +568,7 @@ public class HttpConfigurable implements PersistentStateComponent<HttpConfigurab return myPasswordCrypt; } + @SuppressWarnings("UnusedDeclaration") public void setPasswordCrypt(String passwordCrypt) { myPasswordCrypt = passwordCrypt; } diff --git a/platform/platform-api/src/com/intellij/util/net/HttpProxyConfigurable.java b/platform/platform-api/src/com/intellij/util/net/HttpProxyConfigurable.java new file mode 100644 index 000000000000..4778c811d63e --- /dev/null +++ b/platform/platform-api/src/com/intellij/util/net/HttpProxyConfigurable.java @@ -0,0 +1,44 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * 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 com.intellij.util.net; + +import com.intellij.openapi.options.ConfigurableBase; +import org.jetbrains.annotations.NotNull; + +public class HttpProxyConfigurable extends ConfigurableBase<HttpProxySettingsUi, HttpConfigurable> { + private final HttpConfigurable settings; + + public HttpProxyConfigurable() { + this(HttpConfigurable.getInstance()); + } + + public HttpProxyConfigurable(@NotNull HttpConfigurable settings) { + super("http.proxy", "HTTP Proxy", "http.proxy"); + + this.settings = settings; + } + + @NotNull + @Override + protected HttpConfigurable getSettings() { + return settings; + } + + @Override + protected HttpProxySettingsUi createUi() { + return new HttpProxySettingsUi(settings); + } +}
\ No newline at end of file diff --git a/platform/platform-api/src/com/intellij/util/net/HTTPProxySettings.form b/platform/platform-api/src/com/intellij/util/net/HttpProxySettingsUi.form index 5ffe378667d3..3d2ae0575e1f 100644 --- a/platform/platform-api/src/com/intellij/util/net/HTTPProxySettings.form +++ b/platform/platform-api/src/com/intellij/util/net/HttpProxySettingsUi.form @@ -1,14 +1,14 @@ <?xml version="1.0" encoding="UTF-8"?> -<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.util.net.HTTPProxySettingsPanel"> +<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.util.net.HttpProxySettingsUi"> <grid id="111c4" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="11" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> <margin top="0" left="0" bottom="0" right="0"/> <constraints> - <xy x="111" y="44" width="1040" height="521"/> + <xy x="111" y="44" width="1369" height="608"/> </constraints> <properties/> <border type="none"/> <children> - <grid id="fe3b6" layout-manager="GridLayoutManager" row-count="8" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> + <grid id="fe3b6" layout-manager="GridLayoutManager" row-count="8" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> <margin top="5" left="20" bottom="10" right="10"/> <constraints> <grid row="7" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="3" indent="0" use-parent-layout="false"/> @@ -34,19 +34,9 @@ <text resource-bundle="messages/CommonBundle" key="editbox.port.number"/> </properties> </component> - <component id="2008d" class="javax.swing.JTextField" binding="myProxyHostTextField"> - <constraints> - <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false"> - <preferred-size width="150" height="-1"/> - </grid> - </constraints> - <properties/> - </component> - <component id="7e62" class="javax.swing.JTextField" binding="myProxyPortTextField"> + <component id="7e62" class="com.intellij.ui.PortField" binding="myProxyPortTextField"> <constraints> - <grid row="1" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false"> - <preferred-size width="150" height="-1"/> - </grid> + <grid row="1" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> </constraints> <properties/> </component> @@ -105,11 +95,6 @@ <text resource-bundle="messages/CommonBundle" key="checkbox.remember.password"/> </properties> </component> - <hspacer id="92b79"> - <constraints> - <grid row="5" column="3" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/> - </constraints> - </hspacer> <component id="a16e5" class="javax.swing.JTextArea" binding="myProxyExceptions"> <constraints> <grid row="2" column="2" row-span="1" col-span="1" vsize-policy="6" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false"> @@ -137,6 +122,14 @@ <text resource-bundle="messages/CommonBundle" key="label.proxy.exceptions.text"/> </properties> </component> + <component id="2008d" class="javax.swing.JTextField" binding="myProxyHostTextField"> + <constraints> + <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false"> + <preferred-size width="150" height="-1"/> + </grid> + </constraints> + <properties/> + </component> </children> </grid> <vspacer id="53d33"> @@ -177,7 +170,7 @@ <text resource-bundle="messages/CommonBundle" key="http.noproxy"/> </properties> </component> - <grid id="1bb9b" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> + <grid id="1bb9b" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> <margin top="0" left="0" bottom="0" right="0"/> <constraints> <grid row="6" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/> @@ -193,11 +186,6 @@ <text resource-bundle="messages/CommonBundle" key="http.proxy.type"/> </properties> </component> - <hspacer id="14ffd"> - <constraints> - <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/> - </constraints> - </hspacer> <component id="2538c" class="com.intellij.ui.components.JBRadioButton" binding="mySocks"> <constraints> <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="2" use-parent-layout="false"/> @@ -230,7 +218,7 @@ </constraints> <properties/> </component> - <grid id="fee34" layout-manager="GridLayoutManager" row-count="2" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> + <grid id="fee34" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> <margin top="0" left="0" bottom="0" right="0"/> <constraints> <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="true"/> @@ -262,11 +250,6 @@ </constraints> <properties/> </component> - <hspacer id="21dc"> - <constraints> - <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/> - </constraints> - </hspacer> </children> </grid> </children> diff --git a/platform/platform-api/src/com/intellij/util/net/HttpProxySettingsUi.java b/platform/platform-api/src/com/intellij/util/net/HttpProxySettingsUi.java new file mode 100644 index 000000000000..e71d8e5af4ec --- /dev/null +++ b/platform/platform-api/src/com/intellij/util/net/HttpProxySettingsUi.java @@ -0,0 +1,386 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * 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 com.intellij.util.net; + +import com.google.common.net.HostAndPort; +import com.google.common.net.InetAddresses; +import com.google.common.net.InternetDomainName; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.options.ConfigurableUi; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.MultiLineLabelUI; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.wm.IdeFocusManager; +import com.intellij.openapi.wm.IdeFrame; +import com.intellij.ui.PortField; +import com.intellij.ui.components.JBLabel; +import com.intellij.ui.components.JBRadioButton; +import com.intellij.util.proxy.CommonProxy; +import com.intellij.util.proxy.JavaProxyProperty; +import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.IOException; +import java.net.HttpURLConnection; +import java.util.concurrent.atomic.AtomicReference; + +class HttpProxySettingsUi implements ConfigurableUi<HttpConfigurable> { + private JPanel myMainPanel; + + private JTextField myProxyLoginTextField; + private JPasswordField myProxyPasswordTextField; + private JCheckBox myProxyAuthCheckBox; + private PortField myProxyPortTextField; + private JTextField myProxyHostTextField; + private JCheckBox myRememberProxyPasswordCheckBox; + + private JLabel myProxyLoginLabel; + private JLabel myProxyPasswordLabel; + private JLabel myHostNameLabel; + private JLabel myPortNumberLabel; + private JBRadioButton myAutoDetectProxyRb; + private JBRadioButton myUseHTTPProxyRb; + private JBLabel mySystemProxyDefined; + private JBRadioButton myNoProxyRb; + private JBRadioButton myHTTP; + private JBRadioButton mySocks; + private JButton myClearPasswordsButton; + private JLabel myErrorLabel; + private JButton myCheckButton; + private JBLabel myOtherWarning; + private JLabel myProxyExceptionsLabel; + private JTextArea myProxyExceptions; + private JLabel myNoProxyForLabel; + private JCheckBox myPacUrlCheckBox; + private JTextField myPacUrlTextField; + private volatile boolean myConnectionCheckInProgress; + + @Override + public boolean isModified(@NotNull HttpConfigurable settings) { + if (!isValid()) { + return false; + } + + return !Comparing.strEqual(myProxyExceptions.getText().trim(), settings.PROXY_EXCEPTIONS) || + settings.USE_PROXY_PAC != myAutoDetectProxyRb.isSelected() || + settings.USE_PAC_URL != myPacUrlCheckBox.isSelected() || + !Comparing.strEqual(settings.PAC_URL, myPacUrlTextField.getText()) || + settings.USE_HTTP_PROXY != myUseHTTPProxyRb.isSelected() || + settings.PROXY_AUTHENTICATION != myProxyAuthCheckBox.isSelected() || + settings.KEEP_PROXY_PASSWORD != myRememberProxyPasswordCheckBox.isSelected() || + settings.PROXY_TYPE_IS_SOCKS != mySocks.isSelected() || + !Comparing.strEqual(settings.PROXY_LOGIN, myProxyLoginTextField.getText()) || + !Comparing.strEqual(settings.getPlainProxyPassword(), new String(myProxyPasswordTextField.getPassword())) || + settings.PROXY_PORT != myProxyPortTextField.getNumber() || + !Comparing.strEqual(settings.PROXY_HOST, myProxyHostTextField.getText()); + } + + public HttpProxySettingsUi(@NotNull final HttpConfigurable settings) { + ButtonGroup group = new ButtonGroup(); + group.add(myUseHTTPProxyRb); + group.add(myAutoDetectProxyRb); + group.add(myNoProxyRb); + myNoProxyRb.setSelected(true); + + ButtonGroup proxyTypeGroup = new ButtonGroup(); + proxyTypeGroup.add(myHTTP); + proxyTypeGroup.add(mySocks); + myHTTP.setSelected(true); + + myProxyExceptions.setBorder(UIUtil.getTextFieldBorder()); + + Boolean property = Boolean.getBoolean(JavaProxyProperty.USE_SYSTEM_PROXY); + mySystemProxyDefined.setVisible(Boolean.TRUE.equals(property)); + if (Boolean.TRUE.equals(property)) { + mySystemProxyDefined.setIcon(Messages.getWarningIcon()); + mySystemProxyDefined.setFont(mySystemProxyDefined.getFont().deriveFont(Font.BOLD)); + mySystemProxyDefined.setUI(new MultiLineLabelUI()); + } + + myProxyAuthCheckBox.addActionListener(new ActionListener() { + @Override + public void actionPerformed(@NotNull ActionEvent e) { + enableProxyAuthentication(myProxyAuthCheckBox.isSelected()); + } + }); + myPacUrlCheckBox.addActionListener(new ActionListener() { + @Override + public void actionPerformed(@NotNull ActionEvent e) { + myPacUrlTextField.setEnabled(myPacUrlCheckBox.isSelected()); + } + }); + + ActionListener listener = new ActionListener() { + @Override + public void actionPerformed(@NotNull ActionEvent e) { + enableProxy(myUseHTTPProxyRb.isSelected()); + } + }; + myUseHTTPProxyRb.addActionListener(listener); + myAutoDetectProxyRb.addActionListener(listener); + myNoProxyRb.addActionListener(listener); + + myClearPasswordsButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(@NotNull ActionEvent e) { + settings.clearGenericPasswords(); + //noinspection DialogTitleCapitalization + Messages.showMessageDialog(myMainPanel, "Proxy passwords were cleared.", "Auto-detected Proxy", Messages.getInformationIcon()); + } + }); + + configureCheckButton(); + } + + private void configureCheckButton() { + if (HttpConfigurable.getInstance() == null) { + myCheckButton.setVisible(false); + return; + } + + myCheckButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(@NotNull ActionEvent e) { + final String title = "Check Proxy Settings"; + final String answer = Messages.showInputDialog(myMainPanel, "Warning: your settings will be saved.\n\nEnter any URL to check connection to:", + title, Messages.getQuestionIcon(), "http://", null); + if (StringUtil.isEmptyOrSpaces(answer)) { + return; + } + + final HttpConfigurable settings = HttpConfigurable.getInstance(); + apply(settings); + final AtomicReference<IOException> exceptionReference = new AtomicReference<IOException>(); + myCheckButton.setEnabled(false); + myCheckButton.setText("Check connection (in progress...)"); + myConnectionCheckInProgress = true; + ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { + @Override + public void run() { + HttpURLConnection connection = null; + try { + //already checked for null above + //noinspection ConstantConditions + connection = settings.openHttpConnection(answer); + connection.setReadTimeout(3 * 1000); + connection.setConnectTimeout(3 * 1000); + connection.connect(); + final int code = connection.getResponseCode(); + if (HttpURLConnection.HTTP_OK != code) { + exceptionReference.set(new IOException("Error code: " + code)); + } + } + catch (IOException e) { + exceptionReference.set(e); + } + finally { + if (connection != null) { + connection.disconnect(); + } + } + //noinspection SSBasedInspection + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + myConnectionCheckInProgress = false; + reset(settings); // since password might have been set + Component parent; + if (myMainPanel.isShowing()) { + parent = myMainPanel; + myCheckButton.setText("Check connection"); + myCheckButton.setEnabled(canEnableConnectionCheck()); + } + else { + IdeFrame frame = IdeFocusManager.findInstance().getLastFocusedFrame(); + if (frame == null) { + return; + } + parent = frame.getComponent(); + } + //noinspection ThrowableResultOfMethodCallIgnored + final IOException exception = exceptionReference.get(); + if (exception == null) { + Messages.showMessageDialog(parent, "Connection successful", title, Messages.getInformationIcon()); + } + else { + final String message = exception.getMessage(); + if (settings.USE_HTTP_PROXY) { + settings.LAST_ERROR = message; + } + Messages.showErrorDialog(parent, errorText(message)); + } + } + }); + } + }); + } + }); + } + + private boolean canEnableConnectionCheck() { + return !myNoProxyRb.isSelected() && !myConnectionCheckInProgress; + } + + @Override + public void reset(@NotNull HttpConfigurable settings) { + myNoProxyRb.setSelected(true); // default + myAutoDetectProxyRb.setSelected(settings.USE_PROXY_PAC); + myPacUrlCheckBox.setSelected(settings.USE_PAC_URL); + myPacUrlTextField.setText(settings.PAC_URL); + myUseHTTPProxyRb.setSelected(settings.USE_HTTP_PROXY); + myProxyAuthCheckBox.setSelected(settings.PROXY_AUTHENTICATION); + + enableProxy(settings.USE_HTTP_PROXY); + + myProxyLoginTextField.setText(settings.PROXY_LOGIN); + myProxyPasswordTextField.setText(settings.getPlainProxyPassword()); + + myProxyPortTextField.setNumber(settings.PROXY_PORT); + myProxyHostTextField.setText(settings.PROXY_HOST); + myProxyExceptions.setText(StringUtil.notNullize(settings.PROXY_EXCEPTIONS)); + + myRememberProxyPasswordCheckBox.setSelected(settings.KEEP_PROXY_PASSWORD); + mySocks.setSelected(settings.PROXY_TYPE_IS_SOCKS); + myHTTP.setSelected(!settings.PROXY_TYPE_IS_SOCKS); + + boolean showError = !StringUtil.isEmptyOrSpaces(settings.LAST_ERROR); + myErrorLabel.setVisible(showError); + myErrorLabel.setText(showError ? errorText(settings.LAST_ERROR) : null); + + final String oldStyleText = CommonProxy.getMessageFromProps(CommonProxy.getOldStyleProperties()); + myOtherWarning.setVisible(oldStyleText != null); + if (oldStyleText != null) { + myOtherWarning.setText(oldStyleText); + myOtherWarning.setUI(new MultiLineLabelUI()); + myOtherWarning.setIcon(Messages.getWarningIcon()); + } + } + + @NotNull + private static String errorText(@NotNull String s) { + return "Problem with connection: " + s; + } + + private boolean isValid() { + if (myUseHTTPProxyRb.isSelected()) { + String host = getText(myProxyHostTextField); + if (host == null) { + return false; + } + + try { + HostAndPort parsedHost = HostAndPort.fromString(host); + if (parsedHost.hasPort()) { + return false; + } + host = parsedHost.getHostText(); + + try { + InetAddresses.forString(host); + return true; + } + catch (IllegalArgumentException e) { + // it is not an IPv4 or IPv6 literal + } + + InternetDomainName.from(host); + } + catch (IllegalArgumentException e) { + return false; + } + + if (myProxyAuthCheckBox.isSelected()) { + return !StringUtil.isEmptyOrSpaces(myProxyLoginTextField.getText()) && myProxyPasswordTextField.getPassword().length > 0; + } + } + return true; + } + + @Override + public void apply(@NotNull HttpConfigurable settings) { + if (!isValid()) { + return; + } + + if (isModified(settings)) { + settings.AUTHENTICATION_CANCELLED = false; + } + + settings.USE_PROXY_PAC = myAutoDetectProxyRb.isSelected(); + settings.USE_PAC_URL = myPacUrlCheckBox.isSelected(); + settings.PAC_URL = getText(myPacUrlTextField); + settings.USE_HTTP_PROXY = myUseHTTPProxyRb.isSelected(); + settings.PROXY_TYPE_IS_SOCKS = mySocks.isSelected(); + settings.PROXY_AUTHENTICATION = myProxyAuthCheckBox.isSelected(); + settings.KEEP_PROXY_PASSWORD = myRememberProxyPasswordCheckBox.isSelected(); + + settings.PROXY_LOGIN = getText(myProxyLoginTextField); + settings.setPlainProxyPassword(new String(myProxyPasswordTextField.getPassword())); + settings.PROXY_EXCEPTIONS = StringUtil.nullize(myProxyExceptions.getText(), true); + + settings.PROXY_PORT = myProxyPortTextField.getNumber(); + settings.PROXY_HOST = getText(myProxyHostTextField); + } + + @Nullable + private static String getText(@NotNull JTextField field) { + return StringUtil.nullize(field.getText(), true); + } + + private void enableProxy(boolean enabled) { + myHostNameLabel.setEnabled(enabled); + myPortNumberLabel.setEnabled(enabled); + myProxyHostTextField.setEnabled(enabled); + myProxyPortTextField.setEnabled(enabled); + mySocks.setEnabled(enabled); + myHTTP.setEnabled(enabled); + myProxyExceptions.setEnabled(enabled); + myProxyExceptions.setBackground(myProxyPortTextField.getBackground()); + myProxyExceptionsLabel.setEnabled(enabled); + myNoProxyForLabel.setEnabled(enabled); + + myProxyAuthCheckBox.setEnabled(enabled); + enableProxyAuthentication(enabled && myProxyAuthCheckBox.isSelected()); + myCheckButton.setEnabled(canEnableConnectionCheck()); + + final boolean autoDetectProxy = myAutoDetectProxyRb.isSelected(); + myPacUrlCheckBox.setEnabled(autoDetectProxy); + myClearPasswordsButton.setEnabled(autoDetectProxy); + myPacUrlTextField.setEnabled(autoDetectProxy && myPacUrlCheckBox.isSelected()); + } + + private void enableProxyAuthentication(boolean enabled) { + myProxyPasswordLabel.setEnabled(enabled); + myProxyLoginLabel.setEnabled(enabled); + + myProxyLoginTextField.setEnabled(enabled); + myProxyPasswordTextField.setEnabled(enabled); + + myRememberProxyPasswordCheckBox.setEnabled(enabled); + } + + @Override + @NotNull + public JComponent getComponent() { + return myMainPanel; + } +} diff --git a/platform/platform-api/src/com/intellij/util/net/IOExceptionDialog.java b/platform/platform-api/src/com/intellij/util/net/IOExceptionDialog.java index f49eb983c3af..642125b275fa 100644 --- a/platform/platform-api/src/com/intellij/util/net/IOExceptionDialog.java +++ b/platform/platform-api/src/com/intellij/util/net/IOExceptionDialog.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.util.Ref; import com.intellij.ui.GuiUtils; +import com.intellij.util.ObjectUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -28,16 +29,9 @@ import javax.swing.*; import java.awt.event.ActionEvent; import java.lang.reflect.InvocationTargetException; -/** - * Created by IntelliJ IDEA. - * User: stathik - * Date: Nov 19, 2003 - * Time: 10:04:14 PM - * To change this template use Options | File Templates. - */ public class IOExceptionDialog extends DialogWrapper { private static final Logger LOG = Logger.getInstance(IOExceptionDialog.class); - private JTextArea myErrorLabel; + private final JTextArea myErrorLabel; public IOExceptionDialog(String title, String errorText) { super((Project)null, true); @@ -65,8 +59,8 @@ public class IOExceptionDialog extends DialogWrapper { return new Action[] { new AbstractAction(CommonBundle.message("dialog.ioexception.proxy")) { @Override - public void actionPerformed(ActionEvent e) { - new HTTPProxySettingsDialog().show(); + public void actionPerformed(@NotNull ActionEvent e) { + HttpConfigurable.editConfigurable(ObjectUtils.tryCast(e.getSource(), JComponent.class)); } } }; @@ -79,14 +73,14 @@ public class IOExceptionDialog extends DialogWrapper { public static boolean showErrorDialog(final String title, final String text) { final Ref<Boolean> ok = Ref.create(false); try { - final Runnable doRun = new Runnable() { + GuiUtils.runOrInvokeAndWait(new Runnable() { + @Override public void run() { IOExceptionDialog dialog = new IOExceptionDialog(title, text); dialog.show(); ok.set(dialog.isOK()); } - }; - GuiUtils.runOrInvokeAndWait(doRun); + }); } catch (InterruptedException e) { LOG.info(e); diff --git a/platform/platform-api/src/com/intellij/util/net/IdeaWideAuthenticator.java b/platform/platform-api/src/com/intellij/util/net/IdeaWideAuthenticator.java index fedcb359b03d..b3a8fff57763 100644 --- a/platform/platform-api/src/com/intellij/util/net/IdeaWideAuthenticator.java +++ b/platform/platform-api/src/com/intellij/util/net/IdeaWideAuthenticator.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,7 @@ */ package com.intellij.util.net; +import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.util.proxy.CommonProxy; @@ -23,12 +24,6 @@ import com.intellij.util.proxy.NonStaticAuthenticator; import java.net.Authenticator; import java.net.PasswordAuthentication; -/** - * Created with IntelliJ IDEA. - * User: Irina.Chernushina - * Date: 1/30/13 - * Time: 5:58 PM - */ public class IdeaWideAuthenticator extends NonStaticAuthenticator { private final static Logger LOG = Logger.getInstance("#com.intellij.util.net.IdeaWideAuthenticator"); private final HttpConfigurable myHttpConfigurable; @@ -42,12 +37,14 @@ public class IdeaWideAuthenticator extends NonStaticAuthenticator { final String host = CommonProxy.getHostNameReliably(getRequestingHost(), getRequestingSite(), getRequestingURL()); final boolean isProxy = Authenticator.RequestorType.PROXY.equals(getRequestorType()); final String prefix = isProxy ? "Proxy authentication: " : "Server authentication: "; + Application application = ApplicationManager.getApplication(); if (isProxy) { // according to idea-wide settings if (myHttpConfigurable.USE_HTTP_PROXY) { LOG.debug("CommonAuthenticator.getPasswordAuthentication will return common defined proxy"); return myHttpConfigurable.getPromptedAuthentication(host + ":" + getRequestingPort(), getRequestingPrompt()); - } else if (myHttpConfigurable.USE_PROXY_PAC) { + } + else if (myHttpConfigurable.USE_PROXY_PAC) { LOG.debug("CommonAuthenticator.getPasswordAuthentication will return autodetected proxy"); if (myHttpConfigurable.isGenericPasswordCanceled(host, getRequestingPort())) return null; // same but without remembering the results.. @@ -56,16 +53,19 @@ public class IdeaWideAuthenticator extends NonStaticAuthenticator { return password; } // do not try to show any dialogs if application is exiting - if (ApplicationManager.getApplication() == null || ApplicationManager.getApplication().isDisposeInProgress() || - ApplicationManager.getApplication().isDisposed()) return null; + if (application == null || application.isDisposeInProgress() || + application.isDisposed()) { + return null; + } return myHttpConfigurable.getGenericPromptedAuthentication(prefix, host, getRequestingPrompt(), getRequestingPort(), true); } } // do not try to show any dialogs if application is exiting - if (ApplicationManager.getApplication() == null || ApplicationManager.getApplication().isDisposeInProgress() || - ApplicationManager.getApplication().isDisposed()) return null; + if (application == null || application.isDisposeInProgress() || application.isDisposed()) { + return null; + } LOG.debug("CommonAuthenticator.getPasswordAuthentication generic authentication will be asked"); //return myHttpConfigurable.getGenericPromptedAuthentication(prefix, host, getRequestingPrompt(), getRequestingPort(), false); diff --git a/platform/platform-api/src/com/intellij/util/net/IdeaWideProxySelector.java b/platform/platform-api/src/com/intellij/util/net/IdeaWideProxySelector.java index df986ea946c4..62199b335425 100644 --- a/platform/platform-api/src/com/intellij/util/net/IdeaWideProxySelector.java +++ b/platform/platform-api/src/com/intellij/util/net/IdeaWideProxySelector.java @@ -17,7 +17,6 @@ package com.intellij.util.net; import com.btr.proxy.search.ProxySearch; import com.btr.proxy.selector.pac.PacProxySelector; -import com.btr.proxy.selector.pac.PacScriptSource; import com.btr.proxy.selector.pac.UrlPacScriptSource; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Comparing; @@ -77,8 +76,7 @@ public class IdeaWideProxySelector extends ProxySelector { if (myHttpConfigurable.USE_PROXY_PAC) { ProxySelector pacProxySelector = myPacProxySelector.get(); if (myHttpConfigurable.USE_PAC_URL && !StringUtil.isEmpty(myHttpConfigurable.PAC_URL)) { - PacScriptSource pacSource = new UrlPacScriptSource(myHttpConfigurable.PAC_URL); - myPacProxySelector.set(new PacProxySelector(pacSource)); + myPacProxySelector.set(new PacProxySelector(new UrlPacScriptSource(myHttpConfigurable.PAC_URL))); } else if (pacProxySelector == null) { ProxySearch proxySearch = ProxySearch.getDefaultProxySearch(); diff --git a/platform/platform-api/src/com/intellij/util/net/NetUtils.java b/platform/platform-api/src/com/intellij/util/net/NetUtils.java index eb56e08e4d64..b01d4db1f1cb 100644 --- a/platform/platform-api/src/com/intellij/util/net/NetUtils.java +++ b/platform/platform-api/src/com/intellij/util/net/NetUtils.java @@ -66,7 +66,7 @@ public class NetUtils { } public static boolean isLocalhost(@NotNull String host) { - return host.equalsIgnoreCase("localhost") || host.equals("127.0.0.1"); + return host.equalsIgnoreCase("localhost") || host.equals("127.0.0.1") || host.equals("::1"); } private static boolean canBindToLocalSocket(String host, int port) { |