aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Ogorodnik <Simon.Ogorodnik@jetbrains.com>2017-10-27 03:18:28 +0300
committerSimon Ogorodnik <Simon.Ogorodnik@jetbrains.com>2017-11-02 17:59:50 +0300
commitd6d320eb13a24fb8e70df0ba11effabe429f0fd4 (patch)
tree6948a7fbd8d1fc6a29f5c9b4ed4f0251f4698129
parentd92518ab71a2b10cb50758cc6f6a20c55253ffea (diff)
downloaddokka-d6d320eb13a24fb8e70df0ba11effabe429f0fd4.tar.gz
dokka-d6d320eb13a24fb8e70df0ba11effabe429f0fd4.tar.bz2
dokka-d6d320eb13a24fb8e70df0ba11effabe429f0fd4.zip
Correctly handle redirects in ExternalDocumentationLinkResolver
-rw-r--r--core/src/main/kotlin/Kotlin/ExternalDocumentationLinkResolver.kt41
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) =