diff --git a/launcher-bootstrap/src/main/java/com/skcraft/launcher/bootstrap/HttpRequest.java b/launcher-bootstrap/src/main/java/com/skcraft/launcher/bootstrap/HttpRequest.java index 09b84e4..b07e874 100644 --- a/launcher-bootstrap/src/main/java/com/skcraft/launcher/bootstrap/HttpRequest.java +++ b/launcher-bootstrap/src/main/java/com/skcraft/launcher/bootstrap/HttpRequest.java @@ -33,13 +33,14 @@ public class HttpRequest implements Closeable, ProgressObservable { private static final int READ_BUFFER_SIZE = 1024 * 8; private final Map headers = new HashMap(); - private final String method; + private String method; @Getter private final URL url; private String contentType; private byte[] body; private HttpURLConnection conn; private InputStream inputStream; + private int redirectCount; private long contentLength = -1; private long readBytes = 0; @@ -95,31 +96,7 @@ public class HttpRequest implements Closeable, ProgressObservable { throw new IllegalArgumentException("Connection already executed"); } - conn = (HttpURLConnection) reformat(url).openConnection(); - - if (body != null) { - conn.setRequestProperty("Content-Type", contentType); - conn.setRequestProperty("Content-Length", Integer.toString(body.length)); - conn.setDoInput(true); - } - - for (Map.Entry entry : headers.entrySet()) { - conn.setRequestProperty(entry.getKey(), entry.getValue()); - } - - conn.setRequestMethod(method); - conn.setUseCaches(false); - conn.setDoOutput(true); - conn.setReadTimeout(READ_TIMEOUT); - - conn.connect(); - - if (body != null) { - DataOutputStream out = new DataOutputStream(conn.getOutputStream()); - out.write(body); - out.flush(); - out.close(); - } + conn = this.runRequest(url); inputStream = conn.getResponseCode() == HttpURLConnection.HTTP_OK ? conn.getInputStream() : conn.getErrorStream(); @@ -134,6 +111,60 @@ public class HttpRequest implements Closeable, ProgressObservable { return this; } + private HttpURLConnection runRequest(URL url) throws IOException { + if (redirectCount > 20) { + throw new IOException("Too many redirects!"); + } + + HttpURLConnection conn = (HttpURLConnection) reformat(url).openConnection(); + conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Java) SKMCLauncher"); + conn.setInstanceFollowRedirects(false); + + if (body != null) { + conn.setRequestProperty("Content-Type", contentType); + conn.setRequestProperty("Content-Length", Integer.toString(body.length)); + conn.setDoInput(true); + } + + for (Map.Entry entry : headers.entrySet()) { + conn.setRequestProperty(entry.getKey(), entry.getValue()); + } + + conn.setRequestMethod(method); + conn.setUseCaches(false); + conn.setDoOutput(true); + conn.setReadTimeout(READ_TIMEOUT); + + conn.connect(); + + if (body != null) { + DataOutputStream out = new DataOutputStream(conn.getOutputStream()); + out.write(body); + out.flush(); + out.close(); + } + + switch (conn.getResponseCode()) { + case HttpURLConnection.HTTP_SEE_OTHER: + method = "GET"; + body = null; + case HttpURLConnection.HTTP_MOVED_PERM: + case HttpURLConnection.HTTP_MOVED_TEMP: + case HttpURLConnection.HTTP_ACCEPTED: + case 307: + case 308: + String location = conn.getHeaderField("Location"); + location = URLDecoder.decode(location, "UTF-8"); + redirectCount++; + + return runRequest(new URL(this.url, location)); + default: + break; + } + + return conn; + } + /** * Require that the response code is one of the given response codes. * diff --git a/launcher/src/main/java/com/skcraft/launcher/util/HttpRequest.java b/launcher/src/main/java/com/skcraft/launcher/util/HttpRequest.java index 29a1704..37ebda4 100644 --- a/launcher/src/main/java/com/skcraft/launcher/util/HttpRequest.java +++ b/launcher/src/main/java/com/skcraft/launcher/util/HttpRequest.java @@ -17,7 +17,10 @@ import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; import java.io.*; import java.net.*; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import static com.skcraft.launcher.LauncherUtils.checkInterrupted; import static org.apache.commons.io.IOUtils.closeQuietly; @@ -34,13 +37,14 @@ public class HttpRequest implements Closeable, ProgressObservable { private final ObjectMapper mapper = new ObjectMapper(); private final Map headers = new HashMap(); - private final String method; + private String method; @Getter private final URL url; private String contentType; private byte[] body; private HttpURLConnection conn; private InputStream inputStream; + private int redirectCount; private long contentLength = -1; private long readBytes = 0; @@ -109,32 +113,7 @@ public class HttpRequest implements Closeable, ProgressObservable { throw new IllegalArgumentException("Connection already executed"); } - conn = (HttpURLConnection) reformat(url).openConnection(); - conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Java) SKMCLauncher"); - - if (body != null) { - conn.setRequestProperty("Content-Type", contentType); - conn.setRequestProperty("Content-Length", Integer.toString(body.length)); - conn.setDoInput(true); - } - - for (Map.Entry entry : headers.entrySet()) { - conn.setRequestProperty(entry.getKey(), entry.getValue()); - } - - conn.setRequestMethod(method); - conn.setUseCaches(false); - conn.setDoOutput(true); - conn.setReadTimeout(READ_TIMEOUT); - - conn.connect(); - - if (body != null) { - DataOutputStream out = new DataOutputStream(conn.getOutputStream()); - out.write(body); - out.flush(); - out.close(); - } + conn = this.runRequest(url); inputStream = conn.getResponseCode() == HttpURLConnection.HTTP_OK ? conn.getInputStream() : conn.getErrorStream(); @@ -149,6 +128,60 @@ public class HttpRequest implements Closeable, ProgressObservable { return this; } + private HttpURLConnection runRequest(URL url) throws IOException { + if (redirectCount > 20) { + throw new IOException("Too many redirects!"); + } + + HttpURLConnection conn = (HttpURLConnection) reformat(url).openConnection(); + conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Java) SKMCLauncher"); + conn.setInstanceFollowRedirects(false); + + if (body != null) { + conn.setRequestProperty("Content-Type", contentType); + conn.setRequestProperty("Content-Length", Integer.toString(body.length)); + conn.setDoInput(true); + } + + for (Map.Entry entry : headers.entrySet()) { + conn.setRequestProperty(entry.getKey(), entry.getValue()); + } + + conn.setRequestMethod(method); + conn.setUseCaches(false); + conn.setDoOutput(true); + conn.setReadTimeout(READ_TIMEOUT); + + conn.connect(); + + if (body != null) { + DataOutputStream out = new DataOutputStream(conn.getOutputStream()); + out.write(body); + out.flush(); + out.close(); + } + + switch (conn.getResponseCode()) { + case HttpURLConnection.HTTP_SEE_OTHER: + method = "GET"; + body = null; + case HttpURLConnection.HTTP_MOVED_PERM: + case HttpURLConnection.HTTP_MOVED_TEMP: + case HttpURLConnection.HTTP_ACCEPTED: + case 307: + case 308: + String location = conn.getHeaderField("Location"); + location = URLDecoder.decode(location, "UTF-8"); + redirectCount++; + + return runRequest(new URL(this.url, location)); + default: + break; + } + + return conn; + } + /** * Require that the response code is one of the given response codes. *