diff --git a/launcher/src/main/java/com/threerings/getdown/launcher/Getdown.java b/launcher/src/main/java/com/threerings/getdown/launcher/Getdown.java index 503134e..35a6388 100644 --- a/launcher/src/main/java/com/threerings/getdown/launcher/Getdown.java +++ b/launcher/src/main/java/com/threerings/getdown/launcher/Getdown.java @@ -38,6 +38,7 @@ import javax.swing.AbstractAction; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLayeredPane; +import javax.swing.JOptionPane; import com.samskivert.swing.util.SwingUtil; import com.threerings.getdown.data.Application; @@ -202,11 +203,17 @@ public abstract class Getdown _dead = false; // if we fail to detect a proxy, but we're allowed to run offline, then go ahead and // run the app anyway because we're prepared to cope with not being able to update - if (detectProxy() || _app.allowOffline()) getdown(); - else requestProxyInfo(false); + try { + if (detectProxy() || _app.allowOffline()) getdown(); + else requestProxyInfo(false); + } catch (IOException ioe) { + log.info("Failed to detect if proxy is needed", "error", ioe); + log.info("We may need a proxy, or maybe their network is down."); + showConnectionFailedDialog(); + } } - protected boolean detectProxy () { + protected boolean detectProxy () throws IOException { // first we have to initialize our application to get the appbase URL, etc. log.info("Checking whether we need to use a proxy..."); try { @@ -223,6 +230,7 @@ public abstract class Getdown // see if we actually need a proxy updateStatus("m.detecting_proxy"); URL configURL = _app.getConfigResource().getRemote(); + // if this detection fails to connect, we'll let the IOException propagate out if (!ProxyUtil.canLoadWithoutProxy(configURL, tryNoProxy ? 2 : 5)) { // if we didn't auto-detect proxy first thing, do auto-detect now return tryNoProxy ? ProxyUtil.autoDetectProxy(_app) : false; @@ -262,6 +270,33 @@ public abstract class Getdown showContainer(); } + /** + * Shows a dialog informing the user that we could not connect to the download servers, + * with buttons to try again or configure a proxy. + */ + protected void showConnectionFailedDialog () { + if (_silent) { + log.warning("Unable to connect to download servers. Exiting."); + return; + } + + String message = _msgs.getString("m.proxy_connect_failed"); + String tryAgain = _msgs.getString("m.try_again"); + String configureProxy = _msgs.getString("m.configure_proxy_button"); + Object[] options = { tryAgain, configureProxy }; + int choice = JOptionPane.showOptionDialog( + null, message, "", + JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, + null, options, options[0]); + if (choice == JOptionPane.YES_OPTION) { + // "Try again" — re-run the update/launch sequence + run(); + } else if (choice == JOptionPane.NO_OPTION) { + // "Configure proxy" — show the proxy configuration panel + requestProxyInfo(false); + } + } + /** * Downloads and installs (without verifying) any resources that are marked with a * {@code PRELOAD} attribute. diff --git a/launcher/src/main/java/com/threerings/getdown/launcher/ProxyUtil.java b/launcher/src/main/java/com/threerings/getdown/launcher/ProxyUtil.java index 7b69cba..d9849f7 100644 --- a/launcher/src/main/java/com/threerings/getdown/launcher/ProxyUtil.java +++ b/launcher/src/main/java/com/threerings/getdown/launcher/ProxyUtil.java @@ -124,35 +124,31 @@ public final class ProxyUtil { } public static boolean canLoadWithoutProxy (URL rurl, int timeoutSeconds) + throws IOException { log.info("Attempting to fetch without proxy: " + rurl); + URLConnection conn = Connector.DEFAULT.open(rurl, timeoutSeconds, timeoutSeconds); + // if the appbase is not an HTTP/S URL (like file:), then we don't need a proxy + if (!(conn instanceof HttpURLConnection)) { + return true; + } + // otherwise, try to make a HEAD request for this URL + HttpURLConnection hcon = (HttpURLConnection)conn; try { - URLConnection conn = Connector.DEFAULT.open(rurl, timeoutSeconds, timeoutSeconds); - // if the appbase is not an HTTP/S URL (like file:), then we don't need a proxy - if (!(conn instanceof HttpURLConnection)) { + hcon.setRequestMethod("HEAD"); + hcon.connect(); + // make sure we got a satisfactory response code + int rcode = hcon.getResponseCode(); + if (rcode == HttpURLConnection.HTTP_PROXY_AUTH || + rcode == HttpURLConnection.HTTP_FORBIDDEN) { + log.warning("Got an 'HTTP credentials needed' response", "code", rcode); + return false; + } else { return true; } - // otherwise, try to make a HEAD request for this URL - HttpURLConnection hcon = (HttpURLConnection)conn; - try { - hcon.setRequestMethod("HEAD"); - hcon.connect(); - // make sure we got a satisfactory response code - int rcode = hcon.getResponseCode(); - if (rcode == HttpURLConnection.HTTP_PROXY_AUTH || - rcode == HttpURLConnection.HTTP_FORBIDDEN) { - log.warning("Got an 'HTTP credentials needed' response", "code", rcode); - } else { - return true; - } - } finally { - hcon.disconnect(); - } - } catch (IOException ioe) { - log.info("Failed to HEAD " + rurl + ": " + ioe); - log.info("We probably need a proxy, but auto-detection failed."); + } finally { + hcon.disconnect(); } - return false; } public static void configProxy (Application app, String host, String port, diff --git a/launcher/src/main/resources/com/threerings/getdown/messages.properties b/launcher/src/main/resources/com/threerings/getdown/messages.properties index 7a33ca0..1b6387a 100644 --- a/launcher/src/main/resources/com/threerings/getdown/messages.properties +++ b/launcher/src/main/resources/com/threerings/getdown/messages.properties @@ -11,6 +11,10 @@ m.abort_cancel = Continue installation m.detecting_proxy = Trying to auto-detect proxy settings +m.proxy_connect_failed = We were unable to connect to the download servers. Please check your Internet connection. +m.try_again = Try again +m.configure_proxy_button = Configure proxy + m.configure_proxy = We were unable to connect to the application server to download data. \

Please make sure that no virus scanner or firewall is blocking network communication with \ the server. \