diff --git a/app/build.gradle b/app/build.gradle index 191cd641c..4896f54be 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -17,7 +17,7 @@ android { minSdkVersion 21 targetSdkVersion 29 versionCode gitCommits - versionName '0.3.1' + versionName '0.3.2' buildConfigField 'String', 'GIT_BRANCH', "\"${gitBranch}\"" diff --git a/app/src/main/java/org/koitharu/kotatsu/core/model/MangaSource.kt b/app/src/main/java/org/koitharu/kotatsu/core/model/MangaSource.kt index 0c4b815ff..b4715830a 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/model/MangaSource.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/model/MangaSource.kt @@ -22,6 +22,6 @@ enum class MangaSource( HENCHAN("Хентай-тян", "ru", HenChanRepository::class.java), YAOICHAN("Яой-тян", "ru", YaoiChanRepository::class.java), MANGATOWN("MangaTown", "en", MangaTownRepository::class.java), - MANGALIB("MangaLib", "ru", MangaLibRepository::class.java), - HENTAILIB("HentaiLib", "ru", HentaiLibRepository::class.java) + MANGALIB("MangaLib", "ru", MangaLibRepository::class.java) + // HENTAILIB("HentaiLib", "ru", HentaiLibRepository::class.java) } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/RemoteMangaRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/RemoteMangaRepository.kt index 6234cf5ac..428527e9f 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/RemoteMangaRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/RemoteMangaRepository.kt @@ -1,18 +1,15 @@ package org.koitharu.kotatsu.core.parser -import org.koin.core.KoinComponent -import org.koin.core.inject import org.koitharu.kotatsu.core.model.MangaPage import org.koitharu.kotatsu.core.model.MangaSource import org.koitharu.kotatsu.core.model.MangaTag import org.koitharu.kotatsu.core.model.SortOrder import org.koitharu.kotatsu.domain.MangaLoaderContext -abstract class RemoteMangaRepository : MangaRepository, KoinComponent { +abstract class RemoteMangaRepository(protected val loaderContext: MangaLoaderContext) : MangaRepository { protected abstract val source: MangaSource - protected val loaderContext by inject() protected val conf by lazy(LazyThreadSafetyMode.NONE) { loaderContext.getSettings(source) } diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/ChanRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/ChanRepository.kt index 199e02504..f4e8d3c21 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/ChanRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/ChanRepository.kt @@ -4,9 +4,12 @@ import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.exceptions.ParseException import org.koitharu.kotatsu.core.model.* import org.koitharu.kotatsu.core.parser.RemoteMangaRepository +import org.koitharu.kotatsu.domain.MangaLoaderContext import org.koitharu.kotatsu.utils.ext.* -abstract class ChanRepository : RemoteMangaRepository() { +abstract class ChanRepository(loaderContext: MangaLoaderContext) : RemoteMangaRepository( + loaderContext +) { protected abstract val defaultDomain: String diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/DesuMeRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/DesuMeRepository.kt index e8532f437..2c6056ce2 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/DesuMeRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/DesuMeRepository.kt @@ -4,9 +4,13 @@ import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.exceptions.ParseException import org.koitharu.kotatsu.core.model.* import org.koitharu.kotatsu.core.parser.RemoteMangaRepository -import org.koitharu.kotatsu.utils.ext.* +import org.koitharu.kotatsu.domain.MangaLoaderContext +import org.koitharu.kotatsu.utils.ext.map +import org.koitharu.kotatsu.utils.ext.mapIndexed +import org.koitharu.kotatsu.utils.ext.parseHtml +import org.koitharu.kotatsu.utils.ext.parseJson -class DesuMeRepository : RemoteMangaRepository() { +class DesuMeRepository(loaderContext: MangaLoaderContext) : RemoteMangaRepository(loaderContext) { override val source = MangaSource.DESUME diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/GroupleRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/GroupleRepository.kt index b70289e17..ae9f4c7d7 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/GroupleRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/GroupleRepository.kt @@ -4,9 +4,11 @@ import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.exceptions.ParseException import org.koitharu.kotatsu.core.model.* import org.koitharu.kotatsu.core.parser.RemoteMangaRepository +import org.koitharu.kotatsu.domain.MangaLoaderContext import org.koitharu.kotatsu.utils.ext.* -abstract class GroupleRepository : RemoteMangaRepository() { +abstract class GroupleRepository(loaderContext: MangaLoaderContext) : + RemoteMangaRepository(loaderContext) { protected abstract val defaultDomain: String @@ -28,8 +30,11 @@ abstract class GroupleRepository : RemoteMangaRepository() { "https://$domain/search", mapOf("q" to query, "offset" to offset.toString()) ) - tag == null -> loaderContext.httpGet("https://$domain/list?sortType=${getSortKey( - sortOrder)}&offset=$offset") + tag == null -> loaderContext.httpGet( + "https://$domain/list?sortType=${getSortKey( + sortOrder + )}&offset=$offset" + ) else -> loaderContext.httpGet( "https://$domain/list/genre/${tag.key}?sortType=${getSortKey( sortOrder diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/HenChanRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/HenChanRepository.kt index 212ed5611..2f2d4787a 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/HenChanRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/HenChanRepository.kt @@ -5,11 +5,12 @@ import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.core.model.MangaChapter import org.koitharu.kotatsu.core.model.MangaSource import org.koitharu.kotatsu.core.model.MangaTag +import org.koitharu.kotatsu.domain.MangaLoaderContext import org.koitharu.kotatsu.utils.ext.longHashCode import org.koitharu.kotatsu.utils.ext.parseHtml import org.koitharu.kotatsu.utils.ext.withDomain -class HenChanRepository : ChanRepository() { +class HenChanRepository(loaderContext: MangaLoaderContext) : ChanRepository(loaderContext) { override val defaultDomain = "h-chan.me" override val source = MangaSource.HENCHAN diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/HentaiLibRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/HentaiLibRepository.kt index 0b3a5c083..b53fc098b 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/HentaiLibRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/HentaiLibRepository.kt @@ -1,11 +1,10 @@ package org.koitharu.kotatsu.core.parser.site -import org.koitharu.kotatsu.core.model.MangaSource - -class HentaiLibRepository : MangaLibRepository() { +/* +class HentaiLibRepository(loaderContext: MangaLoaderContext) : MangaLibRepository(loaderContext) { protected override val defaultDomain = "hentailib.me" override val source = MangaSource.HENTAILIB -} \ No newline at end of file +}*/ diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaChanRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaChanRepository.kt index 9091fe922..0d6247169 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaChanRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaChanRepository.kt @@ -1,8 +1,9 @@ package org.koitharu.kotatsu.core.parser.site import org.koitharu.kotatsu.core.model.MangaSource +import org.koitharu.kotatsu.domain.MangaLoaderContext -class MangaChanRepository : ChanRepository() { +class MangaChanRepository(loaderContext: MangaLoaderContext) : ChanRepository(loaderContext) { override val defaultDomain = "manga-chan.me" override val source = MangaSource.MANGACHAN diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaLibRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaLibRepository.kt index 0b0b34c6a..ae63ab89b 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaLibRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaLibRepository.kt @@ -6,9 +6,11 @@ import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.exceptions.ParseException import org.koitharu.kotatsu.core.model.* import org.koitharu.kotatsu.core.parser.RemoteMangaRepository +import org.koitharu.kotatsu.domain.MangaLoaderContext import org.koitharu.kotatsu.utils.ext.* -open class MangaLibRepository : RemoteMangaRepository() { +open class MangaLibRepository(loaderContext: MangaLoaderContext) : + RemoteMangaRepository(loaderContext) { protected open val defaultDomain = "mangalib.me" @@ -28,6 +30,9 @@ open class MangaLibRepository : RemoteMangaRepository() { sortOrder: SortOrder?, tag: MangaTag? ): List { + if (!query.isNullOrEmpty()) { + return search(query) + } val domain = conf.getDomain(defaultDomain) val page = (offset / 60f).toIntUp() val url = buildString { @@ -107,6 +112,7 @@ open class MangaLibRepository : RemoteMangaRepository() { ) ) } + chapters.reverse() break@scripts } } @@ -193,4 +199,25 @@ open class MangaLibRepository : RemoteMangaRepository() { SortOrder.NEWEST -> "desc&sort=created_at" else -> "desc&sort=last_chapter_at" } + + private suspend fun search(query: String): List { + val domain = conf.getDomain(defaultDomain) + val json = loaderContext.httpGet("https://$domain/search?query=${query.urlEncoded()}") + .parseJsonArray() + return json.map { jo -> + val url = "https://$domain/${jo.getString("slug")}" + Manga( + id = url.longHashCode(), + url = url, + title = jo.getString("rus_name"), + altTitle = jo.getString("name"), + author = null, + tags = emptySet(), + rating = Manga.NO_RATING, + state = null, + source = source, + coverUrl = "https://$domain/uploads/cover/${jo.getString("slug")}/${jo.getString("cover")}/cover_thumb.jpg" + ) + } + } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaTownRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaTownRepository.kt index cee43c3d6..c9f1e0c2e 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaTownRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaTownRepository.kt @@ -5,10 +5,11 @@ import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.exceptions.ParseException import org.koitharu.kotatsu.core.model.* import org.koitharu.kotatsu.core.parser.RemoteMangaRepository +import org.koitharu.kotatsu.domain.MangaLoaderContext import org.koitharu.kotatsu.utils.ext.* import java.util.* -class MangaTownRepository : RemoteMangaRepository() { +class MangaTownRepository(loaderContext: MangaLoaderContext) : RemoteMangaRepository(loaderContext) { override val source = MangaSource.MANGATOWN diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MintMangaRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MintMangaRepository.kt index afd708856..e0383adea 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MintMangaRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MintMangaRepository.kt @@ -1,8 +1,9 @@ package org.koitharu.kotatsu.core.parser.site import org.koitharu.kotatsu.core.model.MangaSource +import org.koitharu.kotatsu.domain.MangaLoaderContext -class MintMangaRepository : GroupleRepository() { +class MintMangaRepository(loaderContext: MangaLoaderContext) : GroupleRepository(loaderContext) { override val source = MangaSource.MINTMANGA override val defaultDomain: String = "mintmanga.live" diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/ReadmangaRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/ReadmangaRepository.kt index bca9851ef..930c0b002 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/ReadmangaRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/ReadmangaRepository.kt @@ -1,8 +1,9 @@ package org.koitharu.kotatsu.core.parser.site import org.koitharu.kotatsu.core.model.MangaSource +import org.koitharu.kotatsu.domain.MangaLoaderContext -class ReadmangaRepository : GroupleRepository() { +class ReadmangaRepository(loaderContext: MangaLoaderContext) : GroupleRepository(loaderContext) { override val defaultDomain = "readmanga.me" override val source = MangaSource.READMANGA_RU diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/SelfMangaRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/SelfMangaRepository.kt index d02131966..952c29578 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/SelfMangaRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/SelfMangaRepository.kt @@ -1,8 +1,9 @@ package org.koitharu.kotatsu.core.parser.site import org.koitharu.kotatsu.core.model.MangaSource +import org.koitharu.kotatsu.domain.MangaLoaderContext -class SelfMangaRepository : GroupleRepository() { +class SelfMangaRepository(loaderContext: MangaLoaderContext) : GroupleRepository(loaderContext) { override val defaultDomain = "selfmanga.ru" override val source = MangaSource.SELFMANGA diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/YaoiChanRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/YaoiChanRepository.kt index abc4c60c0..e40a054b8 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/YaoiChanRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/YaoiChanRepository.kt @@ -4,11 +4,12 @@ import org.koitharu.kotatsu.core.exceptions.ParseException import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.core.model.MangaChapter import org.koitharu.kotatsu.core.model.MangaSource +import org.koitharu.kotatsu.domain.MangaLoaderContext import org.koitharu.kotatsu.utils.ext.longHashCode import org.koitharu.kotatsu.utils.ext.parseHtml import org.koitharu.kotatsu.utils.ext.withDomain -class YaoiChanRepository : ChanRepository() { +class YaoiChanRepository(loaderContext: MangaLoaderContext) : ChanRepository(loaderContext) { override val source = MangaSource.YAOICHAN override val defaultDomain = "yaoi-chan.me" diff --git a/app/src/main/java/org/koitharu/kotatsu/domain/MangaProviderFactory.kt b/app/src/main/java/org/koitharu/kotatsu/domain/MangaProviderFactory.kt index 3c36c00a9..d2dc795ab 100644 --- a/app/src/main/java/org/koitharu/kotatsu/domain/MangaProviderFactory.kt +++ b/app/src/main/java/org/koitharu/kotatsu/domain/MangaProviderFactory.kt @@ -2,13 +2,19 @@ package org.koitharu.kotatsu.domain import org.koin.core.KoinComponent import org.koin.core.get +import org.koin.core.inject import org.koitharu.kotatsu.core.model.MangaSource import org.koitharu.kotatsu.core.parser.LocalMangaRepository import org.koitharu.kotatsu.core.parser.MangaRepository import org.koitharu.kotatsu.core.prefs.AppSettings +import java.lang.ref.WeakReference +import java.util.* object MangaProviderFactory : KoinComponent { + private val loaderContext by inject() + private val cache = EnumMap>(MangaSource::class.java) + fun getSources(includeHidden: Boolean): List { val settings = get() val list = MangaSource.values().toList() - MangaSource.LOCAL @@ -18,7 +24,7 @@ object MangaProviderFactory : KoinComponent { val e = order.indexOf(x.ordinal) if (e == -1) order.size + x.ordinal else e } - return if(includeHidden) { + return if (includeHidden) { sorted } else { sorted.filterNot { x -> @@ -27,9 +33,24 @@ object MangaProviderFactory : KoinComponent { } } - fun createLocal() = LocalMangaRepository() + fun createLocal(): LocalMangaRepository = + (cache[MangaSource.LOCAL]?.get() as? LocalMangaRepository) + ?: LocalMangaRepository().also { + cache[MangaSource.LOCAL] = WeakReference(it) + } + @Throws(Throwable::class) fun create(source: MangaSource): MangaRepository { - return source.cls.newInstance() + cache[source]?.get()?.let { + return it + } + val instance = try { + source.cls.getDeclaredConstructor(MangaLoaderContext::class.java) + .newInstance(loaderContext) + } catch (e: NoSuchMethodException) { + source.cls.newInstance() + } + cache[source] = WeakReference(instance) + return instance } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/PageLoader.kt b/app/src/main/java/org/koitharu/kotatsu/ui/reader/PageLoader.kt index 39be815a7..663ab050e 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/PageLoader.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/reader/PageLoader.kt @@ -51,13 +51,12 @@ class PageLoader : KoinComponent, CoroutineScope, DisposableHandle { .cacheControl(CacheUtils.CONTROL_DISABLED) .build() okHttp.newCall(request).await().use { response -> - val body = response.body!! - val type = body.contentType() - check(type?.type == "image") { - "Unexpected content type ${type?.type}/${type?.subtype}" + val body = response.body + checkNotNull(body) { + "Null response" } cache.put(url) { out -> - response.body!!.byteStream().copyTo(out) + body.byteStream().copyTo(out) } } } diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/CacheUtils.kt b/app/src/main/java/org/koitharu/kotatsu/utils/CacheUtils.kt index d4f21c2ea..3f80f7cb5 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/CacheUtils.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/CacheUtils.kt @@ -12,7 +12,6 @@ object CacheUtils { @JvmStatic val CONTROL_DISABLED = CacheControl.Builder() - .noCache() .noStore() .build() diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/ext/ParseExt.kt b/app/src/main/java/org/koitharu/kotatsu/utils/ext/ParseExt.kt index 048525a0e..944286f59 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/ext/ParseExt.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/ext/ParseExt.kt @@ -2,6 +2,7 @@ package org.koitharu.kotatsu.utils.ext import okhttp3.Response import okhttp3.internal.closeQuietly +import org.json.JSONArray import org.json.JSONObject import org.jsoup.Jsoup import org.jsoup.nodes.Document @@ -30,6 +31,15 @@ fun Response.parseJson(): JSONObject { } } +fun Response.parseJsonArray(): JSONArray { + try { + val string = body?.string() ?: throw NullPointerException("Response body is null") + return JSONArray(string) + } finally { + closeQuietly() + } +} + inline fun Elements.findOwnText(predicate: (String) -> Boolean): String? { for (x in this) { val ownText = x.ownText() diff --git a/app/src/test/java/org/koitharu/kotatsu/parsers/RemoteRepositoryTest.kt b/app/src/test/java/org/koitharu/kotatsu/parsers/RemoteRepositoryTest.kt index 02320a3de..e41122c42 100644 --- a/app/src/test/java/org/koitharu/kotatsu/parsers/RemoteRepositoryTest.kt +++ b/app/src/test/java/org/koitharu/kotatsu/parsers/RemoteRepositoryTest.kt @@ -10,6 +10,7 @@ import org.junit.runners.Parameterized import org.koin.core.context.startKoin import org.koin.dsl.module import org.koitharu.kotatsu.core.model.MangaSource +import org.koitharu.kotatsu.core.parser.UserAgentInterceptor import org.koitharu.kotatsu.core.prefs.SourceConfig import org.koitharu.kotatsu.domain.MangaLoaderContext import org.koitharu.kotatsu.domain.MangaProviderFactory @@ -88,6 +89,8 @@ class RemoteRepositoryTest(source: MangaSource) { module { factory { OkHttpClient.Builder() + .cookieJar(TemporaryCookieJar()) + .addInterceptor(UserAgentInterceptor) .connectTimeout(20, TimeUnit.SECONDS) .readTimeout(60, TimeUnit.SECONDS) .writeTimeout(20, TimeUnit.SECONDS) diff --git a/app/src/test/java/org/koitharu/kotatsu/parsers/TemporaryCookieJar.kt b/app/src/test/java/org/koitharu/kotatsu/parsers/TemporaryCookieJar.kt new file mode 100644 index 000000000..0095f4745 --- /dev/null +++ b/app/src/test/java/org/koitharu/kotatsu/parsers/TemporaryCookieJar.kt @@ -0,0 +1,19 @@ +package org.koitharu.kotatsu.parsers + +import okhttp3.Cookie +import okhttp3.CookieJar +import okhttp3.HttpUrl +import org.koitharu.kotatsu.core.local.cookies.cache.SetCookieCache + +class TemporaryCookieJar : CookieJar { + + private val cache = SetCookieCache() + + override fun loadForRequest(url: HttpUrl): List { + return cache.toList() + } + + override fun saveFromResponse(url: HttpUrl, cookies: List) { + cache.addAll(cookies) + } +} \ No newline at end of file diff --git a/app/src/test/java/org/koitharu/kotatsu/utils/AssertX.kt b/app/src/test/java/org/koitharu/kotatsu/utils/AssertX.kt index 30ec1aeef..0b7584a75 100644 --- a/app/src/test/java/org/koitharu/kotatsu/utils/AssertX.kt +++ b/app/src/test/java/org/koitharu/kotatsu/utils/AssertX.kt @@ -1,26 +1,33 @@ package org.koitharu.kotatsu.utils +import okhttp3.OkHttpClient +import okhttp3.Request import org.junit.Assert +import org.koin.core.KoinComponent +import org.koin.core.inject import java.net.HttpURLConnection -import java.net.URL -object AssertX { +object AssertX : KoinComponent { + + private val okHttp by inject() fun assertContentType(url: String, vararg types: String) { Assert.assertFalse("URL is empty", url.isEmpty()) - val cn = URL(url).openConnection() as HttpURLConnection - cn.requestMethod = "HEAD" - cn.connect() - when (val code = cn.responseCode) { - HttpURLConnection.HTTP_MOVED_PERM, + val request = Request.Builder() + .url(url) + .head() + .build() + val response = okHttp.newCall(request).execute() + when (val code = response.code) { + /*HttpURLConnection.HTTP_MOVED_PERM, HttpURLConnection.HTTP_MOVED_TEMP -> { assertContentType(cn.getHeaderField("Location"), *types) - } + }*/ HttpURLConnection.HTTP_OK -> { - val ct = cn.contentType.substringBeforeLast(';').split("/") + val type = response.body!!.contentType() Assert.assertTrue(types.any { val x = it.split('/') - x[0] == ct[0] && (x[1] == "*" || x[1] == ct[1]) + type?.type == x[0] && (x[1] == "*" || type.subtype == x[1]) }) } else -> Assert.fail("Invalid response code $code at $url")