io.github.gnuf0rce.github.GitHubClient.kt Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2021-2022 dsstudio Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/gnuf0rce/github-helper/blob/master/LICENSE
*/
package io.github.gnuf0rce.github
import io.github.gnuf0rce.github.entry.*
import io.github.gnuf0rce.github.exception.*
import io.ktor.client.*
import io.ktor.client.call.*
import io.ktor.client.engine.okhttp.*
import io.ktor.client.plugins.*
import io.ktor.client.plugins.auth.*
import io.ktor.client.plugins.auth.providers.*
import io.ktor.client.plugins.compression.*
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.client.request.*
import io.ktor.serialization.kotlinx.json.*
import kotlinx.coroutines.*
import java.io.*
import java.net.*
import kotlin.coroutines.*
public open class GitHubClient(public open val token: String?) : CoroutineScope, Closeable {
protected open val proxy: Proxy? = null
protected open val timeout: Long = 30 * 1000L
protected open val doh: String = ""
protected open val ipv6: Boolean = false
protected open val auth: Auth.() -> Unit = {
val tokens = token?.let { BearerTokens(accessToken = it, refreshToken = "") }
bearer {
loadTokens {
tokens
}
sendWithoutRequest { request ->
if (request.url.host == "api.github.com") {
request.accept(GitHubJsonContentType)
request.header("X-GitHub-Api-Version", System.getProperty(GITHUB_API_VERSION))
true
} else {
false
}
}
}
}
protected open val client: HttpClient = HttpClient(OkHttp) {
BrowserUserAgent()
ContentEncoding()
install(HttpTimeout) {
socketTimeoutMillis = timeout
connectTimeoutMillis = timeout
requestTimeoutMillis = null
}
install(ContentNegotiation) {
json(json = GitHubJson)
}
Auth(block = auth)
expectSuccess = true
HttpResponseValidator {
handleResponseExceptionWithRequest { cause, _ ->
if (cause is ClientRequestException && "documentation_url" in cause.message) {
throw GitHubApiException(
cause, try {
cause.response.call.save().response.body()
} catch (_: Exception) {
val json = cause.message.substringAfter("Text: \"").removeSuffix("\"")
GitHubJson.decodeFromString(ApiError.serializer(), json)
}
)
}
}
}
RateLimit {
notice = { _, _ ->
//
}
}
engine {
config {
proxy([email protected])
doh(urlString = [email protected], ipv6 = [email protected])
}
}
}
override val coroutineContext: CoroutineContext get() = client.coroutineContext
override fun close(): Unit = client.close()
protected open val ignore: (Throwable) -> Boolean = { it is IOException }
protected open val maxIgnoreCount: Int = 20
public suspend fun useHttpClient(block: suspend (HttpClient) -> T): T = supervisorScope {
var count = 0
var current: Throwable? = null
while (isActive) {
try {
return@supervisorScope block(client)
} catch (cause: Throwable) {
current = cause
if (isActive && ignore(cause)) {
if (++count > maxIgnoreCount) {
throw cause
}
} else {
throw cause
}
}
}
throw CancellationException(null, current)
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy