getdown.txt
* configuration file from the supplied application directory.
@@ -1208,7 +1214,7 @@ public class Application
}
if (_latest != null) {
- try (InputStream in = ConnectionUtil.open(_latest, 0, 0).getInputStream();
+ try (InputStream in = ConnectionUtil.open(proxy, _latest, 0, 0).getInputStream();
InputStreamReader reader = new InputStreamReader(in, UTF_8);
BufferedReader bin = new BufferedReader(reader)) {
for (String[] pair : Config.parsePairs(bin, Config.createOpts(false))) {
@@ -1592,7 +1598,7 @@ public class Application
log.info("Attempting to refetch '" + path + "' from '" + targetURL + "'.");
// stream the URL into our temporary file
- URLConnection uconn = ConnectionUtil.open(targetURL, 0, 0);
+ URLConnection uconn = ConnectionUtil.open(proxy, targetURL, 0, 0);
// we have to tell Java not to use caches here, otherwise it will cache any request for
// same URL for the lifetime of this JVM (based on the URL string, not the URL object);
// if the getdown.txt file, for example, changes in the meanwhile, we would never hear
diff --git a/core/src/main/java/com/threerings/getdown/net/HTTPDownloader.java b/core/src/main/java/com/threerings/getdown/net/HTTPDownloader.java
index f141366..a7a3287 100644
--- a/core/src/main/java/com/threerings/getdown/net/HTTPDownloader.java
+++ b/core/src/main/java/com/threerings/getdown/net/HTTPDownloader.java
@@ -10,6 +10,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
+import java.net.Proxy;
import java.net.URL;
import java.net.URLConnection;
import java.nio.channels.Channels;
@@ -25,9 +26,14 @@ import static com.threerings.getdown.Log.log;
*/
public class HTTPDownloader extends Downloader
{
+ public HTTPDownloader (Proxy proxy)
+ {
+ _proxy = proxy;
+ }
+
@Override protected long checkSize (Resource rsrc) throws IOException
{
- URLConnection conn = ConnectionUtil.open(rsrc.getRemote(), 0, 0);
+ URLConnection conn = ConnectionUtil.open(_proxy, rsrc.getRemote(), 0, 0);
try {
// if we're accessing our data via HTTP, we only need a HEAD request
if (conn instanceof HttpURLConnection) {
@@ -54,7 +60,7 @@ public class HTTPDownloader extends Downloader
// system property
if (true) {
// download the resource from the specified URL
- URLConnection conn = ConnectionUtil.open(rsrc.getRemote(), 0, 0);
+ URLConnection conn = ConnectionUtil.open(_proxy, rsrc.getRemote(), 0, 0);
conn.connect();
// make sure we got a satisfactory response code
@@ -65,7 +71,6 @@ public class HTTPDownloader extends Downloader
hcon.getResponseCode());
}
}
-
long actualSize = conn.getContentLength();
log.info("Downloading resource", "url", rsrc.getRemote(), "size", actualSize);
long currentSize = 0L;
@@ -105,4 +110,6 @@ public class HTTPDownloader extends Downloader
}
}
}
+
+ protected final Proxy _proxy;
}
diff --git a/core/src/main/java/com/threerings/getdown/spi/ProxyAuth.java b/core/src/main/java/com/threerings/getdown/spi/ProxyAuth.java
new file mode 100644
index 0000000..22446ec
--- /dev/null
+++ b/core/src/main/java/com/threerings/getdown/spi/ProxyAuth.java
@@ -0,0 +1,32 @@
+//
+// Getdown - application installer, patcher and launcher
+// Copyright (C) 2004-2018 Getdown authors
+// https://github.com/threerings/getdown/blob/master/LICENSE
+
+package com.threerings.getdown.spi;
+
+/**
+ * A service provider interface that handles the storage of proxy credentials.
+ */
+public interface ProxyAuth
+{
+ /** Credentials for a proxy server. */
+ public static class Credentials {
+ public final String username;
+ public final String password;
+ public Credentials (String username, String password) {
+ this.username = username;
+ this.password = password;
+ }
+ }
+
+ /**
+ * Loads the credentials for the app installed in {@code appDir}.
+ */
+ public Credentials loadCredentials (String appDir);
+
+ /**
+ * Encrypts and saves the credentials for the app installed in {@code appDir}.
+ */
+ public void saveCredentials (String appDir, String username, String password);
+}
diff --git a/core/src/main/java/com/threerings/getdown/util/ConnectionUtil.java b/core/src/main/java/com/threerings/getdown/util/ConnectionUtil.java
index 7f5a6aa..21b0569 100644
--- a/core/src/main/java/com/threerings/getdown/util/ConnectionUtil.java
+++ b/core/src/main/java/com/threerings/getdown/util/ConnectionUtil.java
@@ -7,11 +7,12 @@ package com.threerings.getdown.util;
import java.io.IOException;
import java.net.HttpURLConnection;
+import java.net.Proxy;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
+
import com.threerings.getdown.data.SysProps;
-import com.threerings.getdown.util.Base64;
import static java.nio.charset.StandardCharsets.UTF_8;
@@ -19,6 +20,7 @@ public class ConnectionUtil
{
/**
* Opens a connection to a URL, setting the authentication header if user info is present.
+ * @param proxy the proxy via which to perform HTTP connections.
* @param url the URL to which to open a connection.
* @param connectTimeout if {@code > 0} then a timeout, in seconds, to use when opening the
* connection. If {@code 0} is supplied, the connection timeout specified via system properties
@@ -27,10 +29,10 @@ public class ConnectionUtil
* the connection. If {@code 0} is supplied, the read timeout specified via system properties
* will be used instead.
*/
- public static URLConnection open (URL url, int connectTimeout, int readTimeout)
+ public static URLConnection open (Proxy proxy, URL url, int connectTimeout, int readTimeout)
throws IOException
{
- URLConnection conn = url.openConnection();
+ URLConnection conn = url.openConnection(proxy);
// configure a connect timeout, if requested
int ctimeout = connectTimeout > 0 ? connectTimeout : SysProps.connectTimeout();
@@ -63,9 +65,9 @@ public class ConnectionUtil
* present. Throws a class cast exception if the connection returned is not the right type. See
* {@link #open} for parameter documentation.
*/
- public static HttpURLConnection openHttp (URL url, int connectTimeout, int readTimeout)
- throws IOException
+ public static HttpURLConnection openHttp (
+ Proxy proxy, URL url, int connectTimeout, int readTimeout) throws IOException
{
- return (HttpURLConnection)open(url, connectTimeout, readTimeout);
+ return (HttpURLConnection)open(proxy, url, connectTimeout, readTimeout);
}
}
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 20ad0b0..377e5cd 100644
--- a/launcher/src/main/java/com/threerings/getdown/launcher/Getdown.java
+++ b/launcher/src/main/java/com/threerings/getdown/launcher/Getdown.java
@@ -13,6 +13,16 @@ import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.*;
import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
@@ -20,29 +30,9 @@ import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.PrintStream;
-
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.net.URLConnection;
-
-import java.util.*;
-
-import ca.beq.util.win32.registry.RegistryKey;
-import ca.beq.util.win32.registry.RegistryValue;
-import ca.beq.util.win32.registry.RootKey;
-
import com.samskivert.swing.util.SwingUtil;
-
-import com.threerings.getdown.data.Application.UpdateInterface.Step;
import com.threerings.getdown.data.*;
+import com.threerings.getdown.data.Application.UpdateInterface.Step;
import com.threerings.getdown.net.Downloader;
import com.threerings.getdown.net.HTTPDownloader;
import com.threerings.getdown.tools.Patcher;
@@ -186,24 +176,12 @@ public abstract class Getdown extends Thread
/**
* Configures our proxy settings (called by {@link ProxyPanel}) and fires up the launcher.
*/
- public void configureProxy (String host, String port)
+ public void configProxy (String host, String port, String username, String password)
{
log.info("User configured proxy", "host", host, "port", port);
- // if we're provided with valid values, create a proxy.txt file
if (!StringUtil.isBlank(host)) {
- File pfile = _app.getLocalPath("proxy.txt");
- try (PrintStream pout = new PrintStream(new FileOutputStream(pfile))) {
- pout.println("host = " + host);
- if (!StringUtil.isBlank(port)) {
- pout.println("port = " + port);
- }
- } catch (IOException ioe) {
- log.warning("Error creating proxy file '" + pfile + "': " + ioe);
- }
-
- // also configure them in the JVM
- setProxyProperties(host, port);
+ ProxyUtil.configProxy(_app, host, port, username, password);
}
// clear out our UI
@@ -214,67 +192,11 @@ public abstract class Getdown extends Thread
new Thread(this).start();
}
- /**
- * Reads and/or autodetects our proxy settings.
- *
- * @return true if we should proceed with running the launcher, false if we need to wait for
- * the user to enter proxy settings.
- */
- protected boolean detectProxy ()
- {
- // we may already have a proxy configured
- if (System.getProperty("http.proxyHost") != null ||
- System.getProperty("https.proxyHost") != null) {
+ protected boolean detectProxy () {
+ if (ProxyUtil.autoDetectProxy(_app)) {
return true;
}
- // look in the Vinders registry
- if (LaunchUtil.isWindows()) {
- try {
- String host = null, port = null;
- boolean enabled = false;
- RegistryKey.initialize();
- RegistryKey r = new RegistryKey(RootKey.HKEY_CURRENT_USER, PROXY_REGISTRY);
- for (Iterator> iter = r.values(); iter.hasNext(); ) {
- RegistryValue value = (RegistryValue)iter.next();
- if (value.getName().equals("ProxyEnable")) {
- enabled = value.getStringValue().equals("1");
- }
- if (value.getName().equals("ProxyServer")) {
- String strval = value.getStringValue();
- int cidx = strval.indexOf(":");
- if (cidx != -1) {
- port = strval.substring(cidx+1);
- strval = strval.substring(0, cidx);
- }
- host = strval;
- }
- }
-
- if (enabled) {
- setProxyProperties(host, port);
- return true;
- } else {
- log.info("Detected no proxy settings in the registry.");
- }
-
- } catch (Throwable t) {
- log.info("Failed to find proxy settings in Windows registry", "error", t);
- }
- }
-
- // otherwise look for and read our proxy.txt file
- File pfile = _app.getLocalPath("proxy.txt");
- if (pfile.exists()) {
- try {
- Config pconf = Config.parseConfig(pfile, Config.createOpts(false));
- setProxyProperties(pconf.getString("host"), pconf.getString("port"));
- return true;
- } catch (IOException ioe) {
- log.warning("Failed to read '" + pfile + "': " + ioe);
- }
- }
-
// otherwise see if we actually need a proxy; first we have to initialize our application
// to get some sort of interface configuration and the appbase URL
log.info("Checking whether we need to use a proxy...");
@@ -284,59 +206,15 @@ public abstract class Getdown extends Thread
// no worries
}
updateStatus("m.detecting_proxy");
-
- URL rurl = _app.getConfigResource().getRemote();
- try {
- // try to make a HEAD request for this URL (use short connect and read timeouts)
- URLConnection conn = ConnectionUtil.open(rurl, 5, 5);
- if (conn instanceof HttpURLConnection) {
- HttpURLConnection hcon = (HttpURLConnection)conn;
- try {
- hcon.setRequestMethod("HEAD");
- hcon.connect();
- // make sure we got a satisfactory response code
- if (hcon.getResponseCode() != HttpURLConnection.HTTP_OK) {
- log.warning("Got a non-200 response but assuming we're OK because we got " +
- "something...", "url", rurl, "rsp", hcon.getResponseCode());
- }
- } finally {
- hcon.disconnect();
- }
- }
-
- // we got through, so we appear not to require a proxy; make a blank proxy config and
- // get on gettin' down
- log.info("No proxy appears to be needed.");
- try {
- pfile.createNewFile();
- } catch (IOException ioe) {
- log.warning("Failed to create blank proxy file '" + pfile + "': " + ioe);
- }
- return true;
-
- } catch (IOException ioe) {
- log.info("Failed to HEAD " + rurl + ": " + ioe);
- log.info("We probably need a proxy, but auto-detection failed.");
+ if (!ProxyUtil.canLoadWithoutProxy(_app.getConfigResource().getRemote())) {
+ return false;
}
- // let the caller know that we need a proxy but can't detect it
- return false;
- }
-
- /**
- * Configures the JVM proxy system properties.
- */
- protected void setProxyProperties (String host, String port)
- {
- if (!StringUtil.isBlank(host)) {
- System.setProperty("http.proxyHost", host);
- System.setProperty("https.proxyHost", host);
- if (!StringUtil.isBlank(port)) {
- System.setProperty("http.proxyPort", port);
- System.setProperty("https.proxyPort", port);
- }
- log.info("Using proxy", "host", host, "port", port);
- }
+ // we got through, so we appear not to require a proxy; make a blank proxy config so that
+ // we don't go through this whole detection process again next time
+ log.info("No proxy appears to be needed.");
+ ProxyUtil.saveProxy(_app, null, null);
+ return true;
}
protected void readConfig (boolean preloads) throws IOException {
@@ -374,10 +252,6 @@ public abstract class Getdown extends Thread
*/
protected void getdown ()
{
- log.info("---------------- Proxy Info -----------------");
- log.info("-- Proxy Host: " + System.getProperty("http.proxyHost"));
- log.info("-- Proxy Port: " + System.getProperty("http.proxyPort"));
- log.info("---------------------------------------------");
try {
// first parses our application deployment file
@@ -723,7 +597,7 @@ public abstract class Getdown extends Thread
// create our user interface
createInterfaceAsync(false);
- Downloader dl = new HTTPDownloader() {
+ Downloader dl = new HTTPDownloader(_app.proxy) {
@Override protected void resolvingDownloads () {
updateStatus("m.resolving");
}
@@ -1113,7 +987,7 @@ public abstract class Getdown extends Thread
@Override
public void run () {
try {
- HttpURLConnection ucon = ConnectionUtil.openHttp(_url, 0, 0);
+ HttpURLConnection ucon = ConnectionUtil.openHttp(_app.proxy, _url, 0, 0);
// if we have a tracking cookie configured, configure the request with it
if (_app.getTrackingCookieName() != null &&
@@ -1182,6 +1056,4 @@ public abstract class Getdown extends Thread
protected static final int MAX_LOOPS = 5;
protected static final long FALLBACK_CHECK_TIME = 1000L;
- protected static final String PROXY_REGISTRY =
- "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings";
}
diff --git a/launcher/src/main/java/com/threerings/getdown/launcher/ProxyPanel.java b/launcher/src/main/java/com/threerings/getdown/launcher/ProxyPanel.java
index 939b243..5a620dd 100644
--- a/launcher/src/main/java/com/threerings/getdown/launcher/ProxyPanel.java
+++ b/launcher/src/main/java/com/threerings/getdown/launcher/ProxyPanel.java
@@ -7,22 +7,25 @@ package com.threerings.getdown.launcher;
import java.awt.BorderLayout;
import java.awt.Dimension;
+import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import javax.swing.BorderFactory;
import javax.swing.JButton;
+import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
+import javax.swing.JPasswordField;
import javax.swing.JTextField;
import com.samskivert.swing.GroupLayout;
import com.samskivert.swing.Spacer;
import com.samskivert.swing.VGroupLayout;
-
import com.threerings.getdown.util.MessageUtil;
import static com.threerings.getdown.Log.log;
@@ -30,8 +33,7 @@ import static com.threerings.getdown.Log.log;
* Displays an interface with which the user can configure their proxy
* settings.
*/
-public final class ProxyPanel extends JPanel
- implements ActionListener
+public final class ProxyPanel extends JPanel implements ActionListener
{
public ProxyPanel (Getdown getdown, ResourceBundle msgs)
{
@@ -40,21 +42,50 @@ public final class ProxyPanel extends JPanel
setLayout(new VGroupLayout());
setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
- add(new JLabel(get("m.configure_proxy")));
+ add(new SaneLabelField(get("m.configure_proxy")));
add(new Spacer(5, 5));
- JPanel row = new JPanel(new BorderLayout(5, 5));
- row.add(new JLabel(get("m.proxy_host")), BorderLayout.WEST);
+ JPanel row = new JPanel(new GridLayout());
+ row.add(new SaneLabelField(get("m.proxy_host")), BorderLayout.WEST);
row.add(_host = new SaneTextField());
add(row);
- row = new JPanel(new BorderLayout(5, 5));
- row.add(new JLabel(get("m.proxy_port")), BorderLayout.WEST);
+ row = new JPanel(new GridLayout());
+ row.add(new SaneLabelField(get("m.proxy_port")), BorderLayout.WEST);
row.add(_port = new SaneTextField());
add(row);
add(new Spacer(5, 5));
- add(new JLabel(get("m.proxy_extra")));
+
+ row = new JPanel(new GridLayout());
+ row.add(new SaneLabelField(get("m.proxy_auth_required")), BorderLayout.WEST);
+ _useAuth = new JCheckBox();
+ row.add(_useAuth);
+ add(row);
+
+ row = new JPanel(new GridLayout());
+ row.add(new SaneLabelField(get("m.proxy_username")), BorderLayout.WEST);
+ _username = new SaneTextField();
+ _username.setEnabled(false);
+ row.add(_username);
+ add(row);
+
+ row = new JPanel(new GridLayout());
+ row.add(new SaneLabelField(get("m.proxy_password")), BorderLayout.WEST);
+ _password = new SanePasswordField();
+ _password.setEnabled(false);
+ row.add(_password);
+ add(row);
+
+ _useAuth.addItemListener(new ItemListener() {
+ @Override public void itemStateChanged (ItemEvent event) {
+ boolean selected = (event.getStateChange() == ItemEvent.SELECTED);
+ _username.setEnabled(selected);
+ _password.setEnabled(selected);
+ }
+ });
+
+ add(new Spacer(5, 5));
row = GroupLayout.makeButtonBox(GroupLayout.CENTER);
JButton button;
@@ -79,7 +110,7 @@ public final class ProxyPanel extends JPanel
// documentation inherited
@Override
- public void addNotify ()
+ public void addNotify ()
{
super.addNotify();
_host.requestFocusInWindow();
@@ -93,17 +124,23 @@ public final class ProxyPanel extends JPanel
// or the JLabel will claim a bogus height thinking it can lay its
// text out all on one line which will booch the whole UI's
// preferred size
- return new Dimension(500, 350);
+ return new Dimension(500, 320);
}
// documentation inherited from interface
+ @Override
public void actionPerformed (ActionEvent e)
{
String cmd = e.getActionCommand();
if (cmd.equals("ok")) {
- // communicate this info back to getdown
- _getdown.configureProxy(_host.getText(), _port.getText());
-
+ String user = null, pass = null;
+ if (_useAuth.isSelected()) {
+ user = _username.getText();
+ // we have to keep the proxy password around for every HTTP request, so having it
+ // in a char[] that gets zeroed out after use is not viable for this use case
+ pass = new String(_password.getPassword());
+ }
+ _getdown.configProxy(_host.getText(), _port.getText(), user, pass);
} else {
// they canceled, we're outta here
System.exit(0);
@@ -126,19 +163,34 @@ public final class ProxyPanel extends JPanel
}
}
- protected static class SaneTextField extends JTextField
- {
- @Override
- public Dimension getPreferredSize () {
- Dimension d = super.getPreferredSize();
- d.width = Math.max(d.width, 150);
- return d;
+ protected static class SaneLabelField extends JLabel {
+ public SaneLabelField(String message) { super(message); }
+ @Override public Dimension getPreferredSize () {
+ return clampWidth(super.getPreferredSize(), 200);
}
}
+ protected static class SaneTextField extends JTextField {
+ @Override public Dimension getPreferredSize () {
+ return clampWidth(super.getPreferredSize(), 150);
+ }
+ }
+ protected static class SanePasswordField extends JPasswordField {
+ @Override public Dimension getPreferredSize () {
+ return clampWidth(super.getPreferredSize(), 150);
+ }
+ }
+
+ protected static Dimension clampWidth (Dimension dim, int minWidth) {
+ dim.width = Math.max(dim.width, minWidth);
+ return dim;
+ }
protected Getdown _getdown;
protected ResourceBundle _msgs;
protected JTextField _host;
protected JTextField _port;
+ protected JCheckBox _useAuth;
+ protected JTextField _username;
+ protected JPasswordField _password;
}
diff --git a/launcher/src/main/java/com/threerings/getdown/launcher/ProxyUtil.java b/launcher/src/main/java/com/threerings/getdown/launcher/ProxyUtil.java
new file mode 100644
index 0000000..a36b5fa
--- /dev/null
+++ b/launcher/src/main/java/com/threerings/getdown/launcher/ProxyUtil.java
@@ -0,0 +1,210 @@
+//
+// Getdown - application installer, patcher and launcher
+// Copyright (C) 2004-2018 Getdown authors
+// https://github.com/threerings/getdown/blob/master/LICENSE
+
+package com.threerings.getdown.launcher;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.net.Authenticator;
+import java.net.HttpURLConnection;
+import java.net.InetSocketAddress;
+import java.net.PasswordAuthentication;
+import java.net.Proxy;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Iterator;
+import java.util.ServiceLoader;
+
+import ca.beq.util.win32.registry.RegistryKey;
+import ca.beq.util.win32.registry.RegistryValue;
+import ca.beq.util.win32.registry.RootKey;
+
+import com.threerings.getdown.data.Application;
+import com.threerings.getdown.spi.ProxyAuth;
+import com.threerings.getdown.util.Config;
+import com.threerings.getdown.util.ConnectionUtil;
+import com.threerings.getdown.util.LaunchUtil;
+import com.threerings.getdown.util.StringUtil;
+
+import static com.threerings.getdown.Log.log;
+
+public class ProxyUtil {
+
+ public static boolean autoDetectProxy (Application app)
+ {
+ String host = null, port = null;
+
+ // check for a proxy configured via system properties
+ if (System.getProperty("https.proxyHost") != null) {
+ host = System.getProperty("https.proxyHost");
+ port = System.getProperty("https.proxyPort");
+ }
+ if (StringUtil.isBlank(host) && System.getProperty("http.proxyHost") != null) {
+ host = System.getProperty("http.proxyHost");
+ port = System.getProperty("http.proxyPort");
+ }
+
+ // check the Windows registry
+ if (StringUtil.isBlank(host) && LaunchUtil.isWindows()) {
+ try {
+ String rhost = null, rport = null;
+ boolean enabled = false;
+ RegistryKey.initialize();
+ RegistryKey r = new RegistryKey(RootKey.HKEY_CURRENT_USER, PROXY_REGISTRY);
+ for (Iterator> iter = r.values(); iter.hasNext(); ) {
+ RegistryValue value = (RegistryValue)iter.next();
+ if (value.getName().equals("ProxyEnable")) {
+ enabled = value.getStringValue().equals("1");
+ }
+ if (value.getName().equals("ProxyServer")) {
+ String strval = value.getStringValue();
+ int cidx = strval.indexOf(":");
+ if (cidx != -1) {
+ rport = strval.substring(cidx+1);
+ strval = strval.substring(0, cidx);
+ }
+ rhost = strval;
+ }
+ }
+ if (enabled) {
+ host = rhost;
+ port = rport;
+ } else {
+ log.info("Detected no proxy settings in the registry.");
+ }
+ } catch (Throwable t) {
+ log.info("Failed to find proxy settings in Windows registry", "error", t);
+ }
+ }
+
+ // look for a proxy.txt file
+ if (StringUtil.isBlank(host)) {
+ String[] hostPort = loadProxy(app);
+ host = hostPort[0];
+ port = hostPort[1];
+ }
+
+ if (StringUtil.isBlank(host)) {
+ return false;
+ }
+
+ // yay, we found a proxy configuration, configure it in the app
+ initProxy(app, host, port, null, null);
+ return true;
+ }
+
+ public static boolean canLoadWithoutProxy (URL rurl)
+ {
+ log.info("Testing whether proxy is needed, via: " + rurl);
+ try {
+ // try to make a HEAD request for this URL (use short connect and read timeouts)
+ URLConnection conn = ConnectionUtil.open(Proxy.NO_PROXY, rurl, 5, 5);
+ if (conn instanceof HttpURLConnection) {
+ 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();
+ }
+ } else {
+ // if the appbase is not an HTTP/S URL (like file:), then we don't need a proxy
+ return true;
+ }
+ } catch (IOException ioe) {
+ log.info("Failed to HEAD " + rurl + ": " + ioe);
+ log.info("We probably need a proxy, but auto-detection failed.");
+ }
+ return false;
+ }
+
+ public static void configProxy (Application app, String host, String port,
+ String username, String password) {
+ // save our proxy host and port in a local file
+ saveProxy(app, host, port);
+
+ // save our credentials via the SPI
+ if (!StringUtil.isBlank(username) && !StringUtil.isBlank(password)) {
+ ServiceLoaderjavaw.exe we cannot download the data. You will need \
- to allow javaw.exe to access the internet. You can try \
- running the app again, but you may need to clear javaw.exe from your \
- firewall configuration ( Start -> Control Panel -> Windows Firewall ).Your computer may access the Internet through a proxy and we were \ - unable to automatically detect your proxy settings. If you know your \ - proxy settings, you can enter them below. +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 communicaton with \ + the server. \ +
Your computer may access the Internet through a proxy and we were unable to automatically \ + detect your proxy settings. If you know your proxy settings, you can enter them below. m.proxy_extra = If you are sure that you don't use a proxy then \ perhaps there is a temporary Internet outage that is preventing us from \ @@ -28,6 +24,9 @@ m.proxy_extra = If you are sure that you don't use a proxy then \ m.proxy_host = Proxy IP m.proxy_port = Proxy port +m.proxy_username = Username +m.proxy_password = Password +m.proxy_auth_required = Authentication required m.proxy_ok = OK m.proxy_cancel = Cancel diff --git a/launcher/src/main/resources/com/threerings/getdown/messages_de.properties b/launcher/src/main/resources/com/threerings/getdown/messages_de.properties index 72c8626..8e36835 100644 --- a/launcher/src/main/resources/com/threerings/getdown/messages_de.properties +++ b/launcher/src/main/resources/com/threerings/getdown/messages_de.properties @@ -13,27 +13,21 @@ m.abort_cancel = Installation fortsetzen m.detecting_proxy = Versuche Proxy-Einstellungen automatisch zu ermitteln -m.configure_proxy = Es war nicht m\u00f6glich, eine Verbindung zu unserem \ -Server herzustellen, um die Anwendungsdaten herunterzuladen. \ -
javaw.exe zu blockieren, kann die Anwendung nicht \
-heruntergeladen werden. Du musst javaw.exe erlauben, \
-Verbindung zum Internet herzustellen. Du kannst nochmals versuchen, die \
-Anwendung zu starten, aber eventuell musst du javaw.exe aus der \
-Firewall-Konfiguration entfernen (Start -> Systemsteuerung -> Windows \
-Firewall). Eventuell ist der Computer durch einen Proxy mit dem Internet \ -verbunden. Es war uns nicht m\u00f6glich, die Proxy-Einstellungen automatisch \ -zu ermitteln. Falls bekannt, k\u00f6nnen diese unten eingetragen \ -werden. +m.configure_proxy = Es konnte keine Verbindung zum Applikations-Server aufgebaut werden. \ +
Bitte kontrollieren Sie die Proxyeinstellungen und stellen Sie sicher, dass keine lokal oder \
+ im Netzwerk betriebene Sicherheitsanwendung (Virenscanner, Firewall, etc.) die Kommunikation \
+ mit dem Server blockiert.
\
+ Wenn kein Proxy verwendet werden soll, l\u00f6schen Sie bitte alle Eintr\u00e4ge in den unten \
+ stehenden Feldern und klicken sie auf OK.
-m.proxy_extra = Falls kein Proxy verwendet wird, liegt \
-m\u00f6glicherweise eine St\u00f6rung in der Internetverbindung zu unserem Server \
-vor. In diesem Fall bitte abbrechen und sp\u00e4ter noch einmal \
-versuchen.
+m.proxy_extra = Sollten Sie keine Proxyeinstellungen gesetzt haben wenden Sie sich bitte \
+ an Ihren Administrator.
-m.proxy_host = Proxy IP
-m.proxy_port = Proxy port
+m.proxy_host = Proxy-Adresse
+m.proxy_port = Proxy-Port
+m.proxy_username = Benutzername
+m.proxy_password = Passwort
+m.proxy_auth_required = Authentisierung erforderlich
m.proxy_ok = OK
m.proxy_cancel = Abbrechen
diff --git a/launcher/src/main/resources/com/threerings/getdown/messages_es.properties b/launcher/src/main/resources/com/threerings/getdown/messages_es.properties
index 7ad2777..609b025 100644
--- a/launcher/src/main/resources/com/threerings/getdown/messages_es.properties
+++ b/launcher/src/main/resources/com/threerings/getdown/messages_es.properties
@@ -29,6 +29,9 @@ m.proxy_extra = Si est\u00e1s seguro de que no tienes un proxy entonces \
m.proxy_host = IP proxy
m.proxy_port = Puerto proxy
+m.proxy_username = Nombre de usuario
+m.proxy_password = Contrase\u00f1a
+m.proxy_auth_required = Autenticacion requerida
m.proxy_ok = OK
m.proxy_cancel = Cancelar
diff --git a/launcher/src/main/resources/com/threerings/getdown/messages_fr.properties b/launcher/src/main/resources/com/threerings/getdown/messages_fr.properties
index dd31f3e..3666204 100644
--- a/launcher/src/main/resources/com/threerings/getdown/messages_fr.properties
+++ b/launcher/src/main/resources/com/threerings/getdown/messages_fr.properties
@@ -27,6 +27,9 @@ m.proxy_extra =Si vous \u00eates certain de ne pas utiliser de proxy, il e
m.proxy_host = Proxy IP
m.proxy_port = Proxy port
+m.proxy_username = Nom d'utilisateur
+m.proxy_password = Mot de passe
+m.proxy_auth_required = Identification requise
m.proxy_ok = OK
m.proxy_cancel = Annuler
diff --git a/launcher/src/main/resources/com/threerings/getdown/messages_it.properties b/launcher/src/main/resources/com/threerings/getdown/messages_it.properties
index 4592d86..33b3260 100644
--- a/launcher/src/main/resources/com/threerings/getdown/messages_it.properties
+++ b/launcher/src/main/resources/com/threerings/getdown/messages_it.properties
@@ -28,6 +28,9 @@ m.proxy_extra = Se sei sicuro di non usare proxy \
m.proxy_host = IP Proxy
m.proxy_port = Porta Proxy
+m.proxy_username = Nome utente
+m.proxy_password = Parola d'ordine
+m.proxy_auth_required = Autenticazione richiesta
m.proxy_ok = OK
m.proxy_cancel = Annulla
diff --git a/launcher/src/main/resources/com/threerings/getdown/messages_ja.properties b/launcher/src/main/resources/com/threerings/getdown/messages_ja.properties
index 4b98391..c344c16 100644
--- a/launcher/src/main/resources/com/threerings/getdown/messages_ja.properties
+++ b/launcher/src/main/resources/com/threerings/getdown/messages_ja.properties
@@ -28,7 +28,10 @@ m.proxy_extra = \u30d7\u30ed\u30ad\u30b7\u3092\u4f7f\u7528\u3057\u3066\u30
\u5f8c\u307b\u3069\u6539\u3081\u3066\u5b9f\u884c\u3057\u3066\u304f\u3060\u3055\u3044\u3002
m.proxy_host = \u30d7\u30ed\u30ad\u30b7IP
-m.proxy_port = \u30d7\u30ed\u30ad\u30b7\u30dd\u30fc\u30c8
+m.proxy_port = \u30d7\u30ed\u30ad\u30b7\u30dd\u30fc\u30c8
+m.proxy_username = Username
+m.proxy_password = Password
+m.proxy_auth_required = Authentication required
m.proxy_ok = OK
m.proxy_cancel = \u30ad\u30e3\u30f3\u30bb\u30eb
diff --git a/launcher/src/main/resources/com/threerings/getdown/messages_ko.properties b/launcher/src/main/resources/com/threerings/getdown/messages_ko.properties
index 000538f..3f8a47f 100644
--- a/launcher/src/main/resources/com/threerings/getdown/messages_ko.properties
+++ b/launcher/src/main/resources/com/threerings/getdown/messages_ko.properties
@@ -24,6 +24,9 @@ m.proxy_extra = \uC790\uB3D9 \uD504\uB85D\uC2DC\uB97C \uC124\uC815\uC744 \uC2DC\
m.proxy_host = \uD504\uB85D\uC2DC IP
m.proxy_port = \uD504\uB85D\uC2DC \uD3EC\uD2B8
+m.proxy_username = Username
+m.proxy_password = Password
+m.proxy_auth_required = Authentication required
m.proxy_ok = OK
m.proxy_cancel = \uCDE8\uC18C
diff --git a/launcher/src/main/resources/com/threerings/getdown/messages_pt.properties b/launcher/src/main/resources/com/threerings/getdown/messages_pt.properties
index 87cc1a4..47db91c 100644
--- a/launcher/src/main/resources/com/threerings/getdown/messages_pt.properties
+++ b/launcher/src/main/resources/com/threerings/getdown/messages_pt.properties
@@ -31,6 +31,9 @@ m.proxy_extra = Se voc\u00EA tem certeza que n\u00E3o usa um proxy, ent\u0
m.proxy_host = IP do Proxy
m.proxy_port = Porta do Proxy
+m.proxy_username = Nome de usu\u00e1rio
+m.proxy_password = Senha
+m.proxy_auth_required = Autentifica\u00e7\u00e3o requerida
m.proxy_ok = OK
m.proxy_cancel = Cancelar
diff --git a/launcher/src/main/resources/com/threerings/getdown/messages_zh.properties b/launcher/src/main/resources/com/threerings/getdown/messages_zh.properties
index 986ebb2..2c27543 100644
--- a/launcher/src/main/resources/com/threerings/getdown/messages_zh.properties
+++ b/launcher/src/main/resources/com/threerings/getdown/messages_zh.properties
@@ -16,6 +16,9 @@ m.proxy_extra = \u5982\u679c\u60a8\u786e\u5b9a\u60a8\u6ca1\u6709\u4f7f\u75
m.proxy_host = \u4ee3\u7406\u670d\u52a1\u5668\u7684IP\u5730\u5740
m.proxy_port = \u4ee3\u7406\u670d\u52a1\u5668\u7684\u7aef\u53e3\u53f7
+m.proxy_username = Username
+m.proxy_password = Password
+m.proxy_auth_required = Authentication required
m.proxy_ok = \u786e\u5b9a
m.proxy_cancel = \u53d6\u6d88