From 315fbec370a8648d2b1d649f5f635cdca30f7947 Mon Sep 17 00:00:00 2001 From: Steve Waldman Date: Sat, 29 Jun 2019 12:41:26 -0700 Subject: [PATCH] Add more neurotic resource management, close()ing of streams. --- .../ivyint/GigahorseUrlHandler.scala | 59 +++++++++++++------ 1 file changed, 42 insertions(+), 17 deletions(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala index 1941de252..87ed352b1 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala @@ -204,25 +204,50 @@ class GigahorseUrlHandler(http: OkHttpClient) extends AbstractURLHandler { private val ErrorBodyTruncateLen = 512 // in case some bad service returns files rather than messages in error bodies private val DefaultErrorCharset = java.nio.charset.StandardCharsets.UTF_8 - // this is perhaps overly cautious, but oh well - private def readTruncated(is: InputStream): Option[(Array[Byte], Boolean)] = { - val os = new ByteArrayOutputStream(ErrorBodyTruncateLen) - var count = 0 - var b = is.read() - var truncated = false - while (!truncated && b >= 0) { - if (count >= ErrorBodyTruncateLen) { - truncated = true - } else { - os.write(b) - count += 1 - b = is.read() + // neurotic resource managemement... + // we could use this elsewhere in the class too + private def borrow[S <: AutoCloseable, T](rsrc: => S)(op: S => T): T = { + val r = rsrc + val out = { + try { + op(r) + } catch { + case NonFatal(t) => { + try { + r.close() + } catch { + case NonFatal(ct) => t.addSuppressed(ct) + } + throw t + } } } - if (count > 0) { - Some((os.toByteArray, truncated)) - } else { - None + r.close() + out + } + + // this is perhaps overly cautious, but oh well + private def readTruncated(byteStream: InputStream): Option[(Array[Byte], Boolean)] = { + borrow(byteStream) { is => + borrow(new ByteArrayOutputStream(ErrorBodyTruncateLen)) { os => + var count = 0 + var b = is.read() + var truncated = false + while (!truncated && b >= 0) { + if (count >= ErrorBodyTruncateLen) { + truncated = true + } else { + os.write(b) + count += 1 + b = is.read() + } + } + if (count > 0) { + Some((os.toByteArray, truncated)) + } else { + None + } + } } }