HttpUtil.java
net.minecraft.util.HttpUtil
信息
- 全限定名:net.minecraft.util.HttpUtil
- 类型:public class
- 包:net.minecraft.util
- 源码路径:src/main/java/net/minecraft/util/HttpUtil.java
- 起始行号:L29
- 职责:
TODO
字段/常量
LOGGER- 类型:
Logger - 修饰符:
private static final - 源码定位:
L30 - 说明:
TODO
- 类型:
内部类/嵌套类型
net.minecraft.util.HttpUtil.DownloadProgressListener- 类型:
interface - 修饰符:
public - 源码定位:
L235 - 说明:
TODO
- 类型:
构造器
private HttpUtil() @ L32
- 构造器名:HttpUtil
- 源码定位:L32
- 修饰符:private
参数:
- 无
说明:
TODO
方法
下面的方法块按源码顺序生成。
public static Path downloadFile(Path targetDir, URL url, Map<String,String> headers, HashFunction hashFunction, HashCode requestedHash, int maxSize, Proxy proxy, HttpUtil.DownloadProgressListener listener) @ L35
- 方法名:downloadFile
- 源码定位:L35
- 返回类型:Path
- 修饰符:public static
参数:
- targetDir: Path
- url: URL
- headers: Map<String,String>
- hashFunction: HashFunction
- requestedHash: HashCode
- maxSize: int
- proxy: Proxy
- listener: HttpUtil.DownloadProgressListener
说明:
TODO
private static void updateModificationTime(Path targetFile) @ L135
- 方法名:updateModificationTime
- 源码定位:L135
- 返回类型:void
- 修饰符:private static
参数:
- targetFile: Path
说明:
TODO
private static HashCode hashFile(Path file, HashFunction hashFunction) @ L143
- 方法名:hashFile
- 源码定位:L143
- 返回类型:HashCode
- 修饰符:private static
参数:
- file: Path
- hashFunction: HashFunction
说明:
TODO
private static boolean checkExistingFile(Path file, HashFunction hashFunction, HashCode expectedHash) @ L156
- 方法名:checkExistingFile
- 源码定位:L156
- 返回类型:boolean
- 修饰符:private static
参数:
- file: Path
- hashFunction: HashFunction
- expectedHash: HashCode
说明:
TODO
private static Path cachedFilePath(Path targetDir, HashCode requestedHash) @ L169
- 方法名:cachedFilePath
- 源码定位:L169
- 返回类型:Path
- 修饰符:private static
参数:
- targetDir: Path
- requestedHash: HashCode
说明:
TODO
private static HashCode downloadAndHash(HashFunction hashFunction, int maxSize, HttpUtil.DownloadProgressListener listener, InputStream input, Path downloadFile) @ L173
- 方法名:downloadAndHash
- 源码定位:L173
- 返回类型:HashCode
- 修饰符:private static
参数:
- hashFunction: HashFunction
- maxSize: int
- listener: HttpUtil.DownloadProgressListener
- input: InputStream
- downloadFile: Path
说明:
TODO
public static int getAvailablePort() @ L205
- 方法名:getAvailablePort
- 源码定位:L205
- 返回类型:int
- 修饰符:public static
参数:
- 无
说明:
TODO
public static boolean isPortAvailable(int port) @ L218
- 方法名:isPortAvailable
- 源码定位:L218
- 返回类型:boolean
- 修饰符:public static
参数:
- port: int
说明:
TODO
代码
public class HttpUtil {
private static final Logger LOGGER = LogUtils.getLogger();
private HttpUtil() {
}
public static Path downloadFile(
Path targetDir,
URL url,
Map<String, String> headers,
HashFunction hashFunction,
@Nullable HashCode requestedHash,
int maxSize,
Proxy proxy,
HttpUtil.DownloadProgressListener listener
) {
HttpURLConnection connection = null;
InputStream input = null;
listener.requestStart();
Path targetFile;
if (requestedHash != null) {
targetFile = cachedFilePath(targetDir, requestedHash);
try {
if (checkExistingFile(targetFile, hashFunction, requestedHash)) {
LOGGER.info("Returning cached file since actual hash matches requested");
listener.requestFinished(true);
updateModificationTime(targetFile);
return targetFile;
}
} catch (IOException var35) {
LOGGER.warn("Failed to check cached file {}", targetFile, var35);
}
try {
LOGGER.warn("Existing file {} not found or had mismatched hash", targetFile);
Files.deleteIfExists(targetFile);
} catch (IOException var34) {
listener.requestFinished(false);
throw new UncheckedIOException("Failed to remove existing file " + targetFile, var34);
}
} else {
targetFile = null;
}
Path actualHash;
try {
connection = (HttpURLConnection)url.openConnection(proxy);
connection.setInstanceFollowRedirects(true);
headers.forEach(connection::setRequestProperty);
input = connection.getInputStream();
long contentLength = connection.getContentLengthLong();
OptionalLong size = contentLength != -1L ? OptionalLong.of(contentLength) : OptionalLong.empty();
FileUtil.createDirectoriesSafe(targetDir);
listener.downloadStart(size);
if (size.isPresent() && size.getAsLong() > maxSize) {
throw new IOException("Filesize is bigger than maximum allowed (file is " + size + ", limit is " + maxSize + ")");
}
if (targetFile == null) {
Path tmpPath = Files.createTempFile(targetDir, "download", ".tmp");
try {
HashCode actualHashx = downloadAndHash(hashFunction, maxSize, listener, input, tmpPath);
Path actualPath = cachedFilePath(targetDir, actualHashx);
if (!checkExistingFile(actualPath, hashFunction, actualHashx)) {
Files.move(tmpPath, actualPath, StandardCopyOption.REPLACE_EXISTING);
} else {
updateModificationTime(actualPath);
}
listener.requestFinished(true);
return actualPath;
} finally {
Files.deleteIfExists(tmpPath);
}
}
HashCode actualHashx = downloadAndHash(hashFunction, maxSize, listener, input, targetFile);
if (!actualHashx.equals(requestedHash)) {
throw new IOException("Hash of downloaded file (" + actualHashx + ") did not match requested (" + requestedHash + ")");
}
listener.requestFinished(true);
actualHash = targetFile;
} catch (Throwable var36) {
if (connection != null) {
InputStream error = connection.getErrorStream();
if (error != null) {
try {
LOGGER.error("HTTP response error: {}", IOUtils.toString(error, StandardCharsets.UTF_8));
} catch (Exception var32) {
LOGGER.error("Failed to read response from server");
}
}
}
listener.requestFinished(false);
throw new IllegalStateException("Failed to download file " + url, var36);
} finally {
IOUtils.closeQuietly(input);
}
return actualHash;
}
private static void updateModificationTime(Path targetFile) {
try {
Files.setLastModifiedTime(targetFile, FileTime.from(Instant.now()));
} catch (IOException var2) {
LOGGER.warn("Failed to update modification time of {}", targetFile, var2);
}
}
private static HashCode hashFile(Path file, HashFunction hashFunction) throws IOException {
Hasher hasher = hashFunction.newHasher();
try (
OutputStream outputStream = Funnels.asOutputStream(hasher);
InputStream fileInput = Files.newInputStream(file);
) {
fileInput.transferTo(outputStream);
}
return hasher.hash();
}
private static boolean checkExistingFile(Path file, HashFunction hashFunction, HashCode expectedHash) throws IOException {
if (Files.exists(file)) {
HashCode actualHash = hashFile(file, hashFunction);
if (actualHash.equals(expectedHash)) {
return true;
}
LOGGER.warn("Mismatched hash of file {}, expected {} but found {}", file, expectedHash, actualHash);
}
return false;
}
private static Path cachedFilePath(Path targetDir, HashCode requestedHash) {
return targetDir.resolve(requestedHash.toString());
}
private static HashCode downloadAndHash(
HashFunction hashFunction, int maxSize, HttpUtil.DownloadProgressListener listener, InputStream input, Path downloadFile
) throws IOException {
HashCode var11;
try (OutputStream output = Files.newOutputStream(downloadFile, StandardOpenOption.CREATE)) {
Hasher hasher = hashFunction.newHasher();
byte[] buffer = new byte[8196];
long readSoFar = 0L;
int read;
while ((read = input.read(buffer)) >= 0) {
readSoFar += read;
listener.downloadedBytes(readSoFar);
if (readSoFar > maxSize) {
throw new IOException("Filesize was bigger than maximum allowed (got >= " + readSoFar + ", limit was " + maxSize + ")");
}
if (Thread.interrupted()) {
LOGGER.error("INTERRUPTED");
throw new IOException("Download interrupted");
}
output.write(buffer, 0, read);
hasher.putBytes(buffer, 0, read);
}
var11 = hasher.hash();
}
return var11;
}
public static int getAvailablePort() {
try {
int var1;
try (ServerSocket server = new ServerSocket(0)) {
var1 = server.getLocalPort();
}
return var1;
} catch (IOException var5) {
return 25564;
}
}
public static boolean isPortAvailable(int port) {
if (port >= 0 && port <= 65535) {
try {
boolean var2;
try (ServerSocket server = new ServerSocket(port)) {
var2 = server.getLocalPort() == port;
}
return var2;
} catch (IOException var6) {
return false;
}
} else {
return false;
}
}
public interface DownloadProgressListener {
void requestStart();
void downloadStart(OptionalLong sizeBytes);
void downloadedBytes(long bytesSoFar);
void requestFinished(boolean success);
}
}引用的其他类
- FileUtil
- 引用位置:
方法调用 - 关联成员:
FileUtil.createDirectoriesSafe()
- 引用位置: