diff options
author | Simon Ogorodnik <Simon.Ogorodnik@jetbrains.com> | 2017-10-27 03:18:28 +0300 |
---|---|---|
committer | Simon Ogorodnik <Simon.Ogorodnik@jetbrains.com> | 2017-11-02 17:59:50 +0300 |
commit | d6d320eb13a24fb8e70df0ba11effabe429f0fd4 (patch) | |
tree | 6948a7fbd8d1fc6a29f5c9b4ed4f0251f4698129 | |
parent | d92518ab71a2b10cb50758cc6f6a20c55253ffea (diff) | |
download | dokka-d6d320eb13a24fb8e70df0ba11effabe429f0fd4.tar.gz dokka-d6d320eb13a24fb8e70df0ba11effabe429f0fd4.tar.bz2 dokka-d6d320eb13a24fb8e70df0ba11effabe429f0fd4.zip |
Correctly handle redirects in ExternalDocumentationLinkResolver
-rw-r--r-- | core/src/main/kotlin/Kotlin/ExternalDocumentationLinkResolver.kt | 41 |
1 files changed, 37 insertions, 4 deletions
diff --git a/core/src/main/kotlin/Kotlin/ExternalDocumentationLinkResolver.kt b/core/src/main/kotlin/Kotlin/ExternalDocumentationLinkResolver.kt index 84d83c73..f28fcc16 100644 --- a/core/src/main/kotlin/Kotlin/ExternalDocumentationLinkResolver.kt +++ b/core/src/main/kotlin/Kotlin/ExternalDocumentationLinkResolver.kt @@ -15,7 +15,9 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.parents import java.io.ByteArrayOutputStream import java.io.PrintWriter +import java.net.HttpURLConnection import java.net.URL +import java.net.URLConnection import java.nio.file.Path import java.security.MessageDigest @@ -30,12 +32,43 @@ class ExternalDocumentationLinkResolver @Inject constructor( val packageFqNameToLocation = mutableMapOf<FqName, ExternalDocumentationRoot>() val formats = mutableMapOf<String, InboundExternalLinkResolutionService>() - class ExternalDocumentationRoot(val rootUrl: URL, val resolver: InboundExternalLinkResolutionService, val locations: Map<String, String>) + class ExternalDocumentationRoot(val rootUrl: URL, val resolver: InboundExternalLinkResolutionService, val locations: Map<String, String>) { + override fun toString(): String = rootUrl.toString() + } val cacheDir: Path? = options.cacheRoot?.resolve("packageListCache")?.apply { createDirectories() } val cachedProtocols = setOf("http", "https", "ftp") + fun URL.doOpenConnectionToReadContent(timeout: Int = 10000, redirectsAllowed: Int = 16): URLConnection { + val connection = this.openConnection() + connection.connectTimeout = timeout + + when (connection) { + is HttpURLConnection -> { + return when (connection.responseCode) { + in 200..299 -> { + connection + } + HttpURLConnection.HTTP_MOVED_PERM, + HttpURLConnection.HTTP_MOVED_TEMP, + HttpURLConnection.HTTP_SEE_OTHER -> { + if (redirectsAllowed > 0) { + val newUrl = connection.getHeaderField("Location") + URL(newUrl).doOpenConnectionToReadContent(timeout, redirectsAllowed - 1) + } else { + throw RuntimeException("Too many redirects") + } + } + else -> { + throw RuntimeException("Unhandled http code: ${connection.responseCode}") + } + } + } + else -> return connection + } + } + fun loadPackageList(link: DokkaConfiguration.ExternalDocumentationLink) { val packageListUrl = link.packageListUrl @@ -50,7 +83,7 @@ class ExternalDocumentationLinkResolver @Inject constructor( if (cacheEntry.exists()) { try { - val connection = packageListUrl.openConnection() + val connection = packageListUrl.doOpenConnectionToReadContent() val originModifiedDate = connection.date val cacheDate = cacheEntry.lastModified().toMillis() if (originModifiedDate > cacheDate || originModifiedDate == 0L) { @@ -60,7 +93,7 @@ class ExternalDocumentationLinkResolver @Inject constructor( logger.info("Renewing package-list from $packageListUrl") connection.getInputStream().copyTo(cacheEntry.outputStream()) } - } catch(e: Exception) { + } catch (e: Exception) { logger.error("Failed to update package-list cache for $link") val baos = ByteArrayOutputStream() PrintWriter(baos).use { @@ -75,7 +108,7 @@ class ExternalDocumentationLinkResolver @Inject constructor( } cacheEntry.inputStream() } else { - packageListUrl.openStream() + packageListUrl.doOpenConnectionToReadContent().getInputStream() } val (params, packages) = |