Merge branch 'javafx' of https://github.com/huanghongxun/HMCL into javafx

This commit is contained in:
huanghongxun
2018-10-11 14:05:35 +08:00
8 changed files with 98 additions and 11 deletions

View File

@@ -35,9 +35,12 @@ public class LibraryDownloadTask extends Task {
protected final Library library;
protected final String url;
protected boolean xz;
private final Library originalLibrary;
private boolean cached = false;
public LibraryDownloadTask(AbstractDependencyManager dependencyManager, File file, Library library) {
this.originalLibrary = library;
setSignificance(TaskSignificance.MODERATE);
if (library.is("net.minecraftforge", "forge"))
@@ -86,7 +89,7 @@ public class LibraryDownloadTask extends Task {
@Override
public void preExecute() throws Exception {
Optional<Path> libPath = cacheRepository.getLibrary(library.setClassifier(null));
Optional<Path> libPath = cacheRepository.getLibrary(originalLibrary);
if (libPath.isPresent()) {
try {
FileUtils.copyFile(libPath.get().toFile(), jar);

View File

@@ -27,10 +27,12 @@ import org.jackhuang.hmcl.util.io.FileUtils;
import org.jackhuang.hmcl.util.io.NetworkUtils;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
@@ -103,6 +105,7 @@ public final class CurseCompletionTask extends Task {
AtomicBoolean flag = new AtomicBoolean(true);
AtomicInteger finished = new AtomicInteger(0);
AtomicBoolean notFound = new AtomicBoolean(false);
// Because in China, Curse is too difficult to visit,
// if failed, ignore it and retry next time.
@@ -113,6 +116,9 @@ public final class CurseCompletionTask extends Task {
if (StringUtils.isBlank(file.getFileName())) {
try {
return file.withFileName(NetworkUtils.detectFileName(file.getUrl()));
} catch (FileNotFoundException e) {
notFound.set(true);
return file;
} catch (IOException ioe) {
Logging.LOG.log(Level.WARNING, "Unable to fetch the file name of URL: " + file.getUrl(), ioe);
flag.set(false);
@@ -132,9 +138,13 @@ public final class CurseCompletionTask extends Task {
}
// Let this task fail if the curse manifest has not been completed.
if (!flag.get())
// But continue other downloads.
if (!flag.get() || notFound.get())
dependencies.add(Task.of(() -> {
throw new CurseCompletionException();
if (notFound.get())
throw new CurseCompletionException(new FileNotFoundException());
else
throw new CurseCompletionException();
}));
}

View File

@@ -218,9 +218,9 @@ public class FileDownloadTask extends Task {
HttpURLConnection con = NetworkUtils.createConnection(url);
if (checkETag) repository.injectConnection(con);
con.connect();
con = NetworkUtils.resolveConnection(con);
if (con.getResponseCode() == 304) {
if (con.getResponseCode() == HttpURLConnection.HTTP_NOT_MODIFIED) {
// Handle cache
Path cache = repository.getCachedRemoteFile(con);
FileUtils.copyFile(cache.toFile(), file);

View File

@@ -19,6 +19,8 @@ package org.jackhuang.hmcl.util.io;
import java.io.*;
import java.net.*;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -57,13 +59,76 @@ public final class NetworkUtils {
public static HttpURLConnection createConnection(URL url) throws IOException {
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setUseCaches(false);
connection.setConnectTimeout(15000);
connection.setReadTimeout(15000);
return connection;
}
/**
* @see <a href="https://github.com/curl/curl/blob/3f7b1bb89f92c13e69ee51b710ac54f775aab320/lib/transfer.c#L1427-L1461">Curl</a>
* @param location
* @return
*/
public static String encodeLocation(String location) {
StringBuilder sb = new StringBuilder();
boolean left = true;
for (char ch : location.toCharArray()) {
switch (ch) {
case ' ':
if (left) sb.append("%20");
else sb.append('+');
break;
case '?':
left = false;
default:
if (ch >= 0x80)
sb.append(encodeURL(Character.toString(ch)));
else
sb.append(ch);
break;
}
}
return sb.toString();
}
/**
* This method aims to solve problem when "Location" in stupid server's response is not encoded.
* @see <a href="https://github.com/curl/curl/issues/473">Issue with libcurl</a>
* @param conn
* @return
* @throws IOException
*/
public static HttpURLConnection resolveConnection(HttpURLConnection conn) throws IOException {
int redirect = 0;
while (true) {
conn.setUseCaches(false);
conn.setConnectTimeout(15000);
conn.setReadTimeout(15000);
conn.setInstanceFollowRedirects(false);
Map<String, List<String>> properties = conn.getRequestProperties();
int code = conn.getResponseCode();
if (code >= 300 && code <= 307 && code != 306 && code != 304) {
String newURL = conn.getHeaderField("Location");
conn.disconnect();
if (redirect > 20) {
throw new IOException("Too much redirects");
}
HttpURLConnection redirected = (HttpURLConnection) new URL(conn.getURL(), encodeLocation(newURL)).openConnection();
properties.forEach((key, value) -> value.forEach(element -> redirected.addRequestProperty(key, element)));
conn = redirected;
++redirect;
} else {
break;
}
}
return conn;
}
public static String doGet(URL url) throws IOException {
return IOUtils.readFullyAsString(createConnection(url).getInputStream());
}
@@ -110,10 +175,12 @@ public final class NetworkUtils {
}
public static String detectFileName(URL url) throws IOException {
HttpURLConnection conn = createConnection(url);
conn.connect();
if (conn.getResponseCode() / 100 != 2)
throw new IOException("Response code " + conn.getResponseCode());
HttpURLConnection conn = resolveConnection(createConnection(url));
int code = conn.getResponseCode();
if (code == 404)
throw new FileNotFoundException();
if (code / 100 != 2)
throw new IOException(url + ": response code " + conn.getResponseCode());
return detectFileName(conn);
}