diff --git a/src/main/java/com/threerings/getdown/data/Application.java b/src/main/java/com/threerings/getdown/data/Application.java index 3abf647..75fd416 100644 --- a/src/main/java/com/threerings/getdown/data/Application.java +++ b/src/main/java/com/threerings/getdown/data/Application.java @@ -80,6 +80,7 @@ import com.samskivert.util.StringUtil; import com.threerings.getdown.launcher.RotatingBackgrounds; import com.threerings.getdown.util.ConfigUtil; +import com.threerings.getdown.util.ConnectionUtil; import com.threerings.getdown.util.FileUtil; import com.threerings.getdown.util.LaunchUtil; import com.threerings.getdown.util.MetaProgressObserver; @@ -1478,7 +1479,7 @@ public class Application InputStream fin = null; FileOutputStream fout = null; try { - URLConnection uconn = targetURL.openConnection(); + URLConnection uconn = ConnectionUtil.open(targetURL); // 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/src/main/java/com/threerings/getdown/launcher/Getdown.java b/src/main/java/com/threerings/getdown/launcher/Getdown.java index de1a9d4..671f6da 100644 --- a/src/main/java/com/threerings/getdown/launcher/Getdown.java +++ b/src/main/java/com/threerings/getdown/launcher/Getdown.java @@ -85,6 +85,7 @@ import com.threerings.getdown.net.Downloader; import com.threerings.getdown.net.HTTPDownloader; import com.threerings.getdown.tools.Patcher; import com.threerings.getdown.util.ConfigUtil; +import com.threerings.getdown.util.ConnectionUtil; import com.threerings.getdown.util.LaunchUtil; import com.threerings.getdown.util.MetaProgressObserver; import com.threerings.getdown.util.ProgressObserver; @@ -319,7 +320,7 @@ public abstract class Getdown extends Thread URL rurl = _app.getConfigResource().getRemote(); try { // try to make a HEAD request for this URL - URLConnection conn = rurl.openConnection(); + URLConnection conn = ConnectionUtil.open(rurl); if (conn instanceof HttpURLConnection) { HttpURLConnection hcon = (HttpURLConnection)conn; try { @@ -1178,7 +1179,7 @@ public abstract class Getdown extends Thread @Override public void run () { try { - HttpURLConnection ucon = (HttpURLConnection)_url.openConnection(); + HttpURLConnection ucon = ConnectionUtil.openHttp(_url); // if we have a tracking cookie configured, configure the request with it if (_app.getTrackingCookieName() != null && diff --git a/src/main/java/com/threerings/getdown/net/HTTPDownloader.java b/src/main/java/com/threerings/getdown/net/HTTPDownloader.java index 2f387a7..6f1c3a7 100644 --- a/src/main/java/com/threerings/getdown/net/HTTPDownloader.java +++ b/src/main/java/com/threerings/getdown/net/HTTPDownloader.java @@ -35,6 +35,7 @@ import java.util.List; import com.samskivert.io.StreamUtil; import com.threerings.getdown.data.Resource; +import com.threerings.getdown.util.ConnectionUtil; import static com.threerings.getdown.Log.log; @@ -52,7 +53,7 @@ public class HTTPDownloader extends Downloader protected long checkSize (Resource rsrc) throws IOException { - URLConnection conn = rsrc.getRemote().openConnection(); + URLConnection conn = ConnectionUtil.open(rsrc.getRemote()); try { // if we're accessing our data via HTTP, we only need a HEAD request if (conn instanceof HttpURLConnection) { @@ -78,7 +79,7 @@ public class HTTPDownloader extends Downloader throws IOException { // download the resource from the specified URL - URLConnection conn = rsrc.getRemote().openConnection(); + URLConnection conn = ConnectionUtil.open(rsrc.getRemote()); conn.connect(); // make sure we got a satisfactory response code diff --git a/src/main/java/com/threerings/getdown/util/ConnectionUtil.java b/src/main/java/com/threerings/getdown/util/ConnectionUtil.java new file mode 100644 index 0000000..1c789bc --- /dev/null +++ b/src/main/java/com/threerings/getdown/util/ConnectionUtil.java @@ -0,0 +1,65 @@ +// +// Getdown - application installer, patcher and launcher +// Copyright (C) 2004-2010 Three Rings Design, Inc. +// http://code.google.com/p/getdown/ +// +// Redistribution and use in source and binary forms, with or without modification, are permitted +// provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package com.threerings.getdown.util; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLDecoder; + +import org.apache.commons.codec.binary.Base64; + +public class ConnectionUtil +{ + /** + * Opens a connection to a URL, setting the authentication header if user info is present. + */ + public static URLConnection open (URL url) + throws IOException + { + URLConnection conn = url.openConnection(); + + // If URL has a username:password@ before hostname, use HTTP basic auth + String userInfo = url.getUserInfo(); + if (userInfo != null) { + // Remove any percent-encoding in the username/password + userInfo = URLDecoder.decode(userInfo, "UTF-8"); + conn.setRequestProperty("Authorization", "Basic " + + Base64.encodeBase64String(userInfo.getBytes("UTF-8")).replaceAll("\\n","")); + } + + return conn; + } + + /** + * Opens a connection to a http or https URL, setting the authentication header if user info + * is present. Throws a class cast exception if the connection returned is not the right type. + */ + public static HttpURLConnection openHttp (URL url) + throws IOException + { + return (HttpURLConnection)open(url); + } +}