From 3db33720a943aca1c5f6e3bdd8ca5d63eb3d6041 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 24 Jul 2017 05:16:42 -0400 Subject: [PATCH] Use IvyAuthenticator and JavaNetAuthenticator Fixes sbt/sbt#3331 The siatuation is a bit complicated. Currently the credentials are stored in Ivy's credential store. This needs to be translated into `java.net.Authenticator` by installing `IvyAuthenticator` and `ErrorMessageAuthenticator` in succession. This, then, needs to be translated into OkHttp Authenticator using `okhttp3.JavaNetAuthenticator`. --- .../scala/sbt/librarymanagement/Http.scala | 6 -- .../ivyint/GigahorseUrlHandler.scala | 55 +++++++++++++++++-- 2 files changed, 49 insertions(+), 12 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/Http.scala b/core/src/main/scala/sbt/librarymanagement/Http.scala index 3fee33b82..9870d9b0f 100644 --- a/core/src/main/scala/sbt/librarymanagement/Http.scala +++ b/core/src/main/scala/sbt/librarymanagement/Http.scala @@ -1,13 +1,7 @@ package sbt.librarymanagement import gigahorse._, support.okhttp.Gigahorse -import okhttp3.{ OkUrlFactory, OkHttpClient } -import java.net.{ URL, HttpURLConnection } object Http { lazy val http: HttpClient = Gigahorse.http(Gigahorse.config) - - private[sbt] lazy val urlFactory = new OkUrlFactory(http.underlying[OkHttpClient]) - private[sbt] def open(url: URL): HttpURLConnection = - urlFactory.open(url) } 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 6603919b5..69ab22cf7 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala @@ -4,9 +4,8 @@ package ivyint import java.net.{ URL, UnknownHostException, HttpURLConnection } import java.io.{ File, IOException, InputStream, ByteArrayOutputStream, ByteArrayInputStream } import org.apache.ivy.util.{ CopyProgressListener, Message, FileUtil } -import org.apache.ivy.util.url.{ URLHandler, AbstractURLHandler, BasicURLHandler } +import org.apache.ivy.util.url.{ URLHandler, AbstractURLHandler, BasicURLHandler, IvyAuthenticator } import org.apache.ivy.util.url.URLHandler._ -import sbt.librarymanagement.Http import sbt.io.{ IO, Using } // Copied from Ivy's BasicURLHandler. @@ -24,8 +23,14 @@ class GigahorseUrlHandler extends AbstractURLHandler { * if the url is not reachable. */ def getURLInfo(url0: URL, timeout: Int): URLInfo = { + // Install the ErrorMessageAuthenticator + if ("http" == url0.getProtocol() || "https" == url0.getProtocol()) { + IvyAuthenticator.install() + ErrorMessageAuthenticator.install() + } + val url = normalizeToURL(url0) - val con = Http.open(url) + val con = GigahorseUrlHandler.open(url) val infoOption = try { con match { case httpCon: HttpURLConnection => @@ -65,8 +70,14 @@ class GigahorseUrlHandler extends AbstractURLHandler { } def openStream(url0: URL): InputStream = { + // Install the ErrorMessageAuthenticator + if ("http" == url0.getProtocol() || "https" == url0.getProtocol()) { + IvyAuthenticator.install() + ErrorMessageAuthenticator.install() + } + val url = normalizeToURL(url0) - val conn = Http.open(url) + val conn = GigahorseUrlHandler.open(url) conn.setRequestProperty("Accept-Encoding", "gzip,deflate") conn match { case httpCon: HttpURLConnection => @@ -91,8 +102,14 @@ class GigahorseUrlHandler extends AbstractURLHandler { } def download(src0: URL, dest: File, l: CopyProgressListener): Unit = { + // Install the ErrorMessageAuthenticator + if ("http" == src0.getProtocol() || "https" == src0.getProtocol()) { + IvyAuthenticator.install() + ErrorMessageAuthenticator.install() + } + val src = normalizeToURL(src0) - val srcConn = Http.open(src) + val srcConn = GigahorseUrlHandler.open(src) srcConn.setRequestProperty("Accept-Encoding", "gzip,deflate") srcConn match { case httpCon: HttpURLConnection => @@ -126,8 +143,16 @@ class GigahorseUrlHandler extends AbstractURLHandler { } def upload(source: File, dest0: URL, l: CopyProgressListener): Unit = { + if( ("http" != dest0.getProtocol()) && ("https" != dest0.getProtocol())) { + throw new UnsupportedOperationException( + "URL repository only support HTTP PUT at the moment") + } + + IvyAuthenticator.install() + ErrorMessageAuthenticator.install() + val dest = normalizeToURL(dest0) - val conn = Http.open(dest) match { + val conn = GigahorseUrlHandler.open(dest) match { case c: HttpURLConnection => c } conn.setDoOutput(true) @@ -169,3 +194,21 @@ class GigahorseUrlHandler extends AbstractURLHandler { } } } + +object GigahorseUrlHandler { + import gigahorse._, support.okhttp.Gigahorse + import okhttp3.{ OkUrlFactory, OkHttpClient, JavaNetAuthenticator } + + lazy val http: HttpClient = Gigahorse.http(Gigahorse.config) + + private[sbt] def urlFactory = { + val client0 = http.underlying[OkHttpClient] + val client = client0.newBuilder() + .authenticator(new JavaNetAuthenticator) + .build + new OkUrlFactory(client) + } + + private[sbt] def open(url: URL): HttpURLConnection = + urlFactory.open(url) +}