diff --git a/build.sbt b/build.sbt index 4965b0063..ea1fac52e 100644 --- a/build.sbt +++ b/build.sbt @@ -230,6 +230,8 @@ lazy val cache = project // New methdos in Cache.Logger ProblemFilters.exclude[MissingMethodProblem]("coursier.Cache#Logger.checkingUpdates"), ProblemFilters.exclude[MissingMethodProblem]("coursier.Cache#Logger.checkingUpdatesResult"), + // Better overload of Cache.Logger.downloadLength, deprecate previous one + ProblemFilters.exclude[MissingMethodProblem]("coursier.Cache#Logger.downloadLength"), // Changes to private class TermDisplay#Info ProblemFilters.exclude[MissingClassProblem]("coursier.TermDisplay$Info$"), ProblemFilters.exclude[AbstractClassProblem]("coursier.TermDisplay$Info"), diff --git a/cache/src/main/scala/coursier/Cache.scala b/cache/src/main/scala/coursier/Cache.scala index 1769701e5..b17577b7d 100644 --- a/cache/src/main/scala/coursier/Cache.scala +++ b/cache/src/main/scala/coursier/Cache.scala @@ -386,30 +386,30 @@ object Cache { val conn0 = urlConn(url) - if (is404(conn0)) + val (partialDownload, conn) = conn0 match { + case conn0: HttpURLConnection if alreadyDownloaded > 0L => + conn0.setRequestProperty("Range", s"bytes=$alreadyDownloaded-") + + if (conn0.getResponseCode == partialContentResponseCode) { + val ackRange = Option(conn0.getHeaderField("Content-Range")).getOrElse("") + + if (ackRange.startsWith(s"bytes $alreadyDownloaded-")) + (true, conn0) + else + // unrecognized Content-Range header -> start a new connection with no resume + (false, urlConn(url)) + } else + (false, conn0) + + case _ => (false, conn0) + } + + if (is404(conn)) FileError.NotFound(url, permanent = Some(true)).left else { - val (partialDownload, conn) = conn0 match { - case conn0: HttpURLConnection if alreadyDownloaded > 0L => - conn0.setRequestProperty("Range", s"bytes=$alreadyDownloaded-") - - if (conn0.getResponseCode == partialContentResponseCode) { - val ackRange = Option(conn0.getHeaderField("Content-Range")).getOrElse("") - - if (ackRange.startsWith(s"bytes $alreadyDownloaded-")) - (true, conn0) - else - // unrecognized Content-Range header -> start a new connection with no resume - (false, urlConn(url)) - } else - (false, conn0) - - case _ => (false, conn0) - } - for (len0 <- Option(conn.getContentLengthLong) if len0 >= 0L) { val len = len0 + (if (partialDownload) alreadyDownloaded else 0L) - logger.foreach(_.downloadLength(url, len)) + logger.foreach(_.downloadLength(url, len, alreadyDownloaded)) } val in = new BufferedInputStream(conn.getInputStream, bufferSize) @@ -747,9 +747,17 @@ object Cache { trait Logger { def foundLocally(url: String, f: File): Unit = {} + def downloadingArtifact(url: String, file: File): Unit = {} + + @deprecated("Use / override the variant with 3 arguments instead") def downloadLength(url: String, length: Long): Unit = {} + def downloadLength(url: String, totalLength: Long, alreadyDownloaded: Long): Unit = { + downloadLength(url, totalLength) + } + def downloadProgress(url: String, downloaded: Long): Unit = {} + def downloadedArtifact(url: String, success: Boolean): Unit = {} def checkingUpdates(url: String, currentTimeOpt: Option[Long]): Unit = {} def checkingUpdatesResult(url: String, currentTimeOpt: Option[Long], remoteTimeOpt: Option[Long]): Unit = {} diff --git a/cache/src/main/scala/coursier/TermDisplay.scala b/cache/src/main/scala/coursier/TermDisplay.scala index 757b5070c..65c2cc6a3 100644 --- a/cache/src/main/scala/coursier/TermDisplay.scala +++ b/cache/src/main/scala/coursier/TermDisplay.scala @@ -248,6 +248,7 @@ class TermDisplay( private case class DownloadInfo( downloaded: Long, + previouslyDownloaded: Long, length: Option[Long], startTime: Long, updateCheck: Boolean @@ -258,7 +259,7 @@ class TermDisplay( def rate(): Option[Double] = { val currentTime = System.currentTimeMillis() if (currentTime > startTime) - Some(downloaded.toDouble / (System.currentTimeMillis() - startTime) * 1000.0) + Some((downloaded - previouslyDownloaded).toDouble / (System.currentTimeMillis() - startTime) * 1000.0) else None } @@ -387,16 +388,16 @@ class TermDisplay( override def downloadingArtifact(url: String, file: File): Unit = newEntry( url, - DownloadInfo(0L, None, System.currentTimeMillis(), updateCheck = false), + DownloadInfo(0L, 0L, None, System.currentTimeMillis(), updateCheck = false), s"Downloading $url\n" ) - override def downloadLength(url: String, length: Long): Unit = { + override def downloadLength(url: String, totalLength: Long, alreadyDownloaded: Long): Unit = { val info = infos.get(url) assert(info != null) val newInfo = info match { case info0: DownloadInfo => - info0.copy(length = Some(length)) + info0.copy(length = Some(totalLength), previouslyDownloaded = alreadyDownloaded) case _ => throw new Exception(s"Incoherent display state for $url") }