in agent/src/main/java/jetbrains/buildServer/torrent/TorrentTransportFactory.java [178:268]
public String downloadUrlTo(@NotNull String url, @NotNull File target, @NotNull final FileProgress fileDownloadProgress) throws IOException {
if (url.endsWith(TEAMCITY_IVY)) {
// downloading teamcity-ivy.xml and parsing it:
return parseArtifactsList(url, target);
}
final String decodedUrl = URLDecoder.decode(url, "UTF-8");
ParsedArtifactPath parsedArtifactUrl = new ParsedArtifactPath(decodedUrl);
long start = System.currentTimeMillis();
TorrentMetadata torrent = downloadTorrent(parsedArtifactUrl);
if (torrent == null) {
return null;
}
long maxTimeForDownloadTorrentMs = 1000;
final long downloadTime = System.currentTimeMillis() - start;
if (downloadTime > maxTimeForDownloadTorrentMs) {
LOG.info("torrent " + parsedArtifactUrl + " was downloaded in " + downloadTime + " ms");
}
File torrentFile = myTorrentFilesFactory.getTorrentFile();
TorrentUtil.saveTorrentToFile(torrent, torrentFile);
String hexInfoHash = torrent.getHexInfoHash();
String name = torrent.getDirectoryName();
List<String> fileNames = TorrentUtils.getTorrentFileNames(torrent);
long size = 0;
for (TorrentFile file : torrent.getFiles()) {
size += file.size;
}
fileDownloadProgress.setExpectedLength(size);
torrent = null;
try {
LOG.info(String.format("trying to download %s via bittorrent", url));
final String message = "Downloading " + target.getName() + " via BitTorrent protocol.";
myBuildLogger.logMessage(DefaultMessagesInfo.createProgressMessage(message));
final int minSeedersForDownload = myLeechSettings.getMinSeedersForDownload();
final int timeoutForConnectToPeersMs = 5000;
final AtomicReference<Exception> exceptionHolder = new AtomicReference<Exception>();
Loggers.AGENT.debug("start download file " + target.getName());
Thread th = myClient.downloadAndShareOrFailAsync(
torrentFile,
fileNames,
hexInfoHash,
target,
target.getParentFile(),
fileDownloadProgress,
myLeechSettings.getMaxPieceDownloadTime() * 1000,
minSeedersForDownload,
timeoutForConnectToPeersMs,
exceptionHolder);
myCurrentDownload.set(Thread.currentThread());
th.join();
myCurrentDownload.set(null);
if (exceptionHolder.get() != null) {
myTorrentsDownloadStatistic.fileDownloadFailed();
Loggers.AGENT.warnAndDebugDetails("unable to download file " + name + " "
+ exceptionHolder.get().getMessage(), exceptionHolder.get());
throw exceptionHolder.get();
}
if (size != target.length()) {
myTorrentsDownloadStatistic.fileDownloadFailed();
log2Build(String.format("Failed to download file completely via BitTorrent protocol. Expected file size: %s, actual file size: %s", String.valueOf(size), String.valueOf(target.length())));
return null;
}
} catch (InterruptedException e) {
throw new IOException("Torrent download has been interrupted " + url, e);
} catch (RuntimeException ex) {
log2Build(String.format("Unable to download artifact %s: %s", url, ex.getMessage()));
throw ex;
} catch (Exception ex) {
log2Build(String.format("Unable to download artifact %s: %s", url, ex.getMessage()));
throw new IOException(ex);
}
// return standard digest
String digest;
try {
digest = getDigest(url);
} catch (IOException e) {
Loggers.AGENT.warnAndDebugDetails("Unable to execute digest request by URL " + url, e);
throw e;
}
myTorrentsDownloadStatistic.fileDownloaded();
return digest;
}