diff --git a/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/internal/FileFactory.kt b/pluto-plugins/base/lib/src/main/java/com/pluto/plugin/libinterface/FilesInterface.kt similarity index 55% rename from pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/internal/FileFactory.kt rename to pluto-plugins/base/lib/src/main/java/com/pluto/plugin/libinterface/FilesInterface.kt index 61dc1786a..c13e2e180 100644 --- a/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/internal/FileFactory.kt +++ b/pluto-plugins/base/lib/src/main/java/com/pluto/plugin/libinterface/FilesInterface.kt @@ -1,20 +1,16 @@ -/** - * Source: chucker - https://github.com/ChuckerTeam/chucker.git - * License: https://github.com/ChuckerTeam/chucker/blob/develop/LICENSE.txt - */ -package com.pluto.plugins.network.internal +package com.pluto.plugin.libinterface +import android.app.Application import java.io.File import java.io.IOException import java.util.concurrent.atomic.AtomicLong -internal object FileFactory { +class FilesInterface(application: Application) { private val uniqueIdGenerator = AtomicLong() + private val directory: File = application.applicationContext.filesDir - fun create(directory: File) = create(directory, fileName = "pluto-${uniqueIdGenerator.getAndIncrement()}") - - private fun create(directory: File, fileName: String): File? = try { - File(directory, fileName).apply { + fun createFile(filename: String = "pluto-${uniqueIdGenerator.getAndIncrement()}"): File? = try { + File(directory, filename).apply { if (exists() && !delete()) { throw IOException("Failed to delete file $this") } diff --git a/pluto-plugins/base/lib/src/main/java/com/pluto/plugin/libinterface/PlutoInterface.kt b/pluto-plugins/base/lib/src/main/java/com/pluto/plugin/libinterface/PlutoInterface.kt index d3d231227..126aa30ea 100644 --- a/pluto-plugins/base/lib/src/main/java/com/pluto/plugin/libinterface/PlutoInterface.kt +++ b/pluto-plugins/base/lib/src/main/java/com/pluto/plugin/libinterface/PlutoInterface.kt @@ -27,6 +27,9 @@ class PlutoInterface private constructor( val libInfo: LibraryInfoInterface get() = LibraryInfoInterface(get.pluginActivityClass, get.selectorActivityClass) + val files: FilesInterface + get() = FilesInterface(get.application) + fun create( application: Application, pluginActivityClass: Class, diff --git a/pluto-plugins/plugins/network/core/lib-no-op/src/main/java/com/pluto/plugins/network/DataModel.kt b/pluto-plugins/plugins/network/core/lib-no-op/src/main/java/com/pluto/plugins/network/DataModel.kt deleted file mode 100644 index f2050b18a..000000000 --- a/pluto-plugins/plugins/network/core/lib-no-op/src/main/java/com/pluto/plugins/network/DataModel.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.pluto.plugins.network - -data class RequestData( - val url: String, - val method: String, - val body: ProcessedBody?, - val headers: Map, - val sentTimestamp: Long -) - -data class ResponseData( - val statusCode: Int, - val body: ProcessedBody?, - val headers: Map, - val sentTimestamp: Long, - val receiveTimestamp: Long, - val protocol: String = "", - val fromDiskCache: Boolean = false -) - -data class ProcessedBody( - val body: CharSequence, - val contentType: String -) diff --git a/pluto-plugins/plugins/network/core/lib-no-op/src/main/java/com/pluto/plugins/network/NetworkRecorder.kt b/pluto-plugins/plugins/network/core/lib-no-op/src/main/java/com/pluto/plugins/network/NetworkRecorder.kt deleted file mode 100644 index de92f24d5..000000000 --- a/pluto-plugins/plugins/network/core/lib-no-op/src/main/java/com/pluto/plugins/network/NetworkRecorder.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.pluto.plugins.network - -import java.io.IOException - -@SuppressWarnings("EmptyFunctionBlock", "UnusedPrivateMember") -class NetworkRecorder(private val request: RequestData) { - - fun onError(e: IOException) { - } - - fun onResponse(response: ResponseData) { - } -} diff --git a/pluto-plugins/plugins/network/core/lib-no-op/src/main/java/com/pluto/plugins/network/PlutoNetwork.kt b/pluto-plugins/plugins/network/core/lib-no-op/src/main/java/com/pluto/plugins/network/PlutoNetwork.kt deleted file mode 100644 index 0236e0151..000000000 --- a/pluto-plugins/plugins/network/core/lib-no-op/src/main/java/com/pluto/plugins/network/PlutoNetwork.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.pluto.plugins.network - -import android.content.Context - -@SuppressWarnings("UnusedPrivateMember", "EmptyFunctionBlock") -object PlutoNetwork { - - internal fun initialize(context: Context) { - } -} diff --git a/pluto-plugins/plugins/network/core/lib-no-op/src/main/java/com/pluto/plugins/network/intercept/NetworkData.kt b/pluto-plugins/plugins/network/core/lib-no-op/src/main/java/com/pluto/plugins/network/intercept/NetworkData.kt new file mode 100644 index 000000000..be3bb14ab --- /dev/null +++ b/pluto-plugins/plugins/network/core/lib-no-op/src/main/java/com/pluto/plugins/network/intercept/NetworkData.kt @@ -0,0 +1,32 @@ +package com.pluto.plugins.network.intercept + +class NetworkData { + + data class Request( + val url: String, + val method: String, + val body: Body?, + val headers: Map, + val sentTimestamp: Long + ) + + data class Response( + val statusCode: Int, + val body: Body?, + val headers: Map, + val sentTimestamp: Long, + val receiveTimestamp: Long, + val protocol: String = "", + val fromDiskCache: Boolean = false + ) { + val isSuccessful: Boolean + get() = statusCode in 200..299 + } + + data class Body( + val body: CharSequence, + val contentType: String + ) { + val sizeInBytes: Long = body.length.toLong() + } +} diff --git a/pluto-plugins/plugins/network/core/lib-no-op/src/main/java/com/pluto/plugins/network/intercept/NetworkInterceptor.kt b/pluto-plugins/plugins/network/core/lib-no-op/src/main/java/com/pluto/plugins/network/intercept/NetworkInterceptor.kt new file mode 100644 index 000000000..8d1cdcd51 --- /dev/null +++ b/pluto-plugins/plugins/network/core/lib-no-op/src/main/java/com/pluto/plugins/network/intercept/NetworkInterceptor.kt @@ -0,0 +1,26 @@ +package com.pluto.plugins.network.intercept + +import java.io.IOException + +@SuppressWarnings("EmptyFunctionBlock", "UnusedPrivateMember") +class NetworkInterceptor private constructor(private val request: NetworkData.Request, option: Option) { + + companion object { + + @JvmOverloads + fun intercept(request: NetworkData.Request, option: Option = Option()): NetworkInterceptor { + return NetworkInterceptor(request, option) + } + } + + fun onError(e: IOException) { + } + + fun onResponse(response: NetworkData.Response) { + } + + data class Option( + val name: String = "Custom", + val metadata: HashMap? = null + ) +} diff --git a/pluto-plugins/plugins/network/core/lib/src/main/java/com/pluto/plugins/network/PlutoNetwork.kt b/pluto-plugins/plugins/network/core/lib/src/main/java/com/pluto/plugins/network/PlutoNetwork.kt deleted file mode 100644 index 1d1373d2e..000000000 --- a/pluto-plugins/plugins/network/core/lib/src/main/java/com/pluto/plugins/network/PlutoNetwork.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.pluto.plugins.network - -import android.content.Context - -object PlutoNetwork { - - var applicationContext: Context? = null - private set - - internal fun initialize(context: Context) { - applicationContext = context.applicationContext - } -} diff --git a/pluto-plugins/plugins/network/core/lib/src/main/java/com/pluto/plugins/network/PlutoNetworkPlugin.kt b/pluto-plugins/plugins/network/core/lib/src/main/java/com/pluto/plugins/network/PlutoNetworkPlugin.kt index 15eb0eb1c..256bb0be5 100644 --- a/pluto-plugins/plugins/network/core/lib/src/main/java/com/pluto/plugins/network/PlutoNetworkPlugin.kt +++ b/pluto-plugins/plugins/network/core/lib/src/main/java/com/pluto/plugins/network/PlutoNetworkPlugin.kt @@ -36,7 +36,6 @@ class PlutoNetworkPlugin() : Plugin(ID) { } override fun onPluginInstalled() { - PlutoNetwork.initialize(context) MockSettingsRepo.init(context) } diff --git a/pluto-plugins/plugins/network/core/lib/src/main/java/com/pluto/plugins/network/intercept/NetworkData.kt b/pluto-plugins/plugins/network/core/lib/src/main/java/com/pluto/plugins/network/intercept/NetworkData.kt index 0faf96c4e..4bb5bccbb 100644 --- a/pluto-plugins/plugins/network/core/lib/src/main/java/com/pluto/plugins/network/intercept/NetworkData.kt +++ b/pluto-plugins/plugins/network/core/lib/src/main/java/com/pluto/plugins/network/intercept/NetworkData.kt @@ -4,7 +4,7 @@ import com.pluto.plugins.network.internal.Status import com.pluto.plugins.network.internal.interceptor.logic.mapCode2Message import io.ktor.http.ContentType -object NetworkData { +class NetworkData { data class Request( val url: String, @@ -46,5 +46,7 @@ object NetworkData { internal val mediaTypeFull: String = "$mediaType/$mediaSubtype" } - internal val BINARY_MEDIA_TYPES = listOf("audio", "video", "image", "font") + companion object { + internal val BINARY_MEDIA_TYPES = listOf("audio", "video", "image", "font") + } } diff --git a/pluto-plugins/plugins/network/core/lib/src/main/java/com/pluto/plugins/network/intercept/NetworkInterceptor.kt b/pluto-plugins/plugins/network/core/lib/src/main/java/com/pluto/plugins/network/intercept/NetworkInterceptor.kt index e352ec742..12934c23d 100644 --- a/pluto-plugins/plugins/network/core/lib/src/main/java/com/pluto/plugins/network/intercept/NetworkInterceptor.kt +++ b/pluto-plugins/plugins/network/core/lib/src/main/java/com/pluto/plugins/network/intercept/NetworkInterceptor.kt @@ -9,10 +9,18 @@ import com.pluto.utilities.DebugLog import java.io.IOException import java.util.UUID -class NetworkInterceptor private constructor(private val request: NetworkData.Request, val option: Option) { +class NetworkInterceptor private constructor(private val request: NetworkData.Request, option: Option) { private val getRequestId: String = UUID.nameUUIDFromBytes("${System.currentTimeMillis()}::${request.url}".toByteArray()).toString() private val apiCallData = ApiCallData(id = getRequestId, interceptorOption = option, request = request) - val requestUrlWithMockInfo: String = MockSettingsRepo.get(request.url, request.method)?.let { + + /** + * Returns updated request url + * + * if Mock setting is configured, returns mock url + * + * else returns actual request url + */ + val actualOrMockRequestUrl: String = MockSettingsRepo.get(request.url, request.method)?.let { apiCallData.mock = MockConfig(it) NetworkCallsRepo.set(apiCallData) it @@ -21,6 +29,8 @@ class NetworkInterceptor private constructor(private val request: NetworkData.Re } companion object { + + @JvmOverloads fun intercept(request: NetworkData.Request, option: Option = Option()): NetworkInterceptor { return NetworkInterceptor(request, option) } diff --git a/pluto-plugins/plugins/network/interceptor-ktor/lib-no-op/build.gradle b/pluto-plugins/plugins/network/interceptor-ktor/lib-no-op/build.gradle index c293e6ad8..28e087908 100644 --- a/pluto-plugins/plugins/network/interceptor-ktor/lib-no-op/build.gradle +++ b/pluto-plugins/plugins/network/interceptor-ktor/lib-no-op/build.gradle @@ -12,7 +12,7 @@ def verCode, verName, verBuild, verNameShort, verPublish ext { PUBLISH_GROUP_ID = "com.plutolib.plugins" PUBLISH_VERSION = verPublish - PUBLISH_ARTIFACT_ID = 'network-ktor-no-op' + PUBLISH_ARTIFACT_ID = 'network-interceptor-ktor-no-op' } android { diff --git a/pluto-plugins/plugins/network/interceptor-ktor/lib-no-op/src/main/java/com/pluto/plugins/network/PlutoKtorInterceptor.kt b/pluto-plugins/plugins/network/interceptor-ktor/lib-no-op/src/main/java/com/pluto/plugins/network/ktor/PlutoKtorInterceptor.kt similarity index 74% rename from pluto-plugins/plugins/network/interceptor-ktor/lib-no-op/src/main/java/com/pluto/plugins/network/PlutoKtorInterceptor.kt rename to pluto-plugins/plugins/network/interceptor-ktor/lib-no-op/src/main/java/com/pluto/plugins/network/ktor/PlutoKtorInterceptor.kt index bb883bb9d..3c906e8e8 100644 --- a/pluto-plugins/plugins/network/interceptor-ktor/lib-no-op/src/main/java/com/pluto/plugins/network/PlutoKtorInterceptor.kt +++ b/pluto-plugins/plugins/network/interceptor-ktor/lib-no-op/src/main/java/com/pluto/plugins/network/ktor/PlutoKtorInterceptor.kt @@ -1,4 +1,4 @@ -package com.pluto.plugins.network +package com.pluto.plugins.network.ktor import io.ktor.client.HttpClient diff --git a/pluto-plugins/plugins/network/interceptor-ktor/lib/build.gradle b/pluto-plugins/plugins/network/interceptor-ktor/lib/build.gradle index 9c172d8a5..9cddd4045 100644 --- a/pluto-plugins/plugins/network/interceptor-ktor/lib/build.gradle +++ b/pluto-plugins/plugins/network/interceptor-ktor/lib/build.gradle @@ -14,7 +14,7 @@ def verCode, verName, verBuild, verNameShort, verPublish ext { PUBLISH_GROUP_ID = "com.plutolib.plugins" PUBLISH_VERSION = verPublish - PUBLISH_ARTIFACT_ID = "network-ktor" + PUBLISH_ARTIFACT_ID = "network-interceptor-ktor" } android { diff --git a/pluto-plugins/plugins/network/interceptor-ktor/lib/src/main/kotlin/com/pluto/plugins/network/PlutoKtorInterceptor.kt b/pluto-plugins/plugins/network/interceptor-ktor/lib/src/main/kotlin/com/pluto/plugins/network/ktor/PlutoKtorHelper.kt similarity index 68% rename from pluto-plugins/plugins/network/interceptor-ktor/lib/src/main/kotlin/com/pluto/plugins/network/PlutoKtorInterceptor.kt rename to pluto-plugins/plugins/network/interceptor-ktor/lib/src/main/kotlin/com/pluto/plugins/network/ktor/PlutoKtorHelper.kt index f537e84ce..348c7b67b 100644 --- a/pluto-plugins/plugins/network/interceptor-ktor/lib/src/main/kotlin/com/pluto/plugins/network/PlutoKtorInterceptor.kt +++ b/pluto-plugins/plugins/network/interceptor-ktor/lib/src/main/kotlin/com/pluto/plugins/network/ktor/PlutoKtorHelper.kt @@ -1,20 +1,21 @@ -package com.pluto.plugins.network +package com.pluto.plugins.network.ktor import com.pluto.plugins.network.intercept.NetworkInterceptor -import com.pluto.plugins.network.internal.KtorRequestConverter.convert -import com.pluto.plugins.network.internal.KtorResponseConverter.convert +import com.pluto.plugins.network.ktor.internal.KtorRequestConverter.convert +import com.pluto.plugins.network.ktor.internal.KtorResponseConverter.convert import io.ktor.client.HttpClient import io.ktor.client.plugins.HttpSend import io.ktor.client.plugins.plugin import io.ktor.client.request.url import io.ktor.utils.io.errors.IOException -fun HttpClient.addPlutoKtorPlugin() { +fun HttpClient.addPlutoKtorInterceptor() { + // todo add ktor settings block here plugin(HttpSend).intercept { requestUnBuilt -> val request = requestUnBuilt.build() val networkInterceptor = NetworkInterceptor.intercept(request.convert(), NetworkInterceptor.Option(NAME)) val callResult = try { - requestUnBuilt.url(networkInterceptor.requestUrlWithMockInfo) + requestUnBuilt.url(networkInterceptor.actualOrMockRequestUrl) execute(requestUnBuilt) } catch (e: IOException) { networkInterceptor.onError(e) diff --git a/pluto-plugins/plugins/network/interceptor-ktor/lib/src/main/kotlin/com/pluto/plugins/network/internal/KtorRequestConverter.kt b/pluto-plugins/plugins/network/interceptor-ktor/lib/src/main/kotlin/com/pluto/plugins/network/ktor/internal/KtorRequestConverter.kt similarity index 97% rename from pluto-plugins/plugins/network/interceptor-ktor/lib/src/main/kotlin/com/pluto/plugins/network/internal/KtorRequestConverter.kt rename to pluto-plugins/plugins/network/interceptor-ktor/lib/src/main/kotlin/com/pluto/plugins/network/ktor/internal/KtorRequestConverter.kt index 6374fcec3..ffa6fab18 100644 --- a/pluto-plugins/plugins/network/interceptor-ktor/lib/src/main/kotlin/com/pluto/plugins/network/internal/KtorRequestConverter.kt +++ b/pluto-plugins/plugins/network/interceptor-ktor/lib/src/main/kotlin/com/pluto/plugins/network/ktor/internal/KtorRequestConverter.kt @@ -1,4 +1,4 @@ -package com.pluto.plugins.network.internal +package com.pluto.plugins.network.ktor.internal import com.pluto.plugins.network.intercept.NetworkData.Body import com.pluto.plugins.network.intercept.NetworkData.Request diff --git a/pluto-plugins/plugins/network/interceptor-ktor/lib/src/main/kotlin/com/pluto/plugins/network/internal/KtorResponseConverter.kt b/pluto-plugins/plugins/network/interceptor-ktor/lib/src/main/kotlin/com/pluto/plugins/network/ktor/internal/KtorResponseConverter.kt similarity index 97% rename from pluto-plugins/plugins/network/interceptor-ktor/lib/src/main/kotlin/com/pluto/plugins/network/internal/KtorResponseConverter.kt rename to pluto-plugins/plugins/network/interceptor-ktor/lib/src/main/kotlin/com/pluto/plugins/network/ktor/internal/KtorResponseConverter.kt index 015527294..8b6555d1e 100644 --- a/pluto-plugins/plugins/network/interceptor-ktor/lib/src/main/kotlin/com/pluto/plugins/network/internal/KtorResponseConverter.kt +++ b/pluto-plugins/plugins/network/interceptor-ktor/lib/src/main/kotlin/com/pluto/plugins/network/ktor/internal/KtorResponseConverter.kt @@ -1,4 +1,4 @@ -package com.pluto.plugins.network.internal +package com.pluto.plugins.network.ktor.internal import com.pluto.plugins.network.intercept.NetworkData.Body import com.pluto.plugins.network.intercept.NetworkData.Response diff --git a/pluto-plugins/plugins/network/interceptor-ktor/lib/src/main/kotlin/com/pluto/plugins/network/internal/RequestConverter.kt b/pluto-plugins/plugins/network/interceptor-ktor/lib/src/main/kotlin/com/pluto/plugins/network/ktor/internal/RequestConverter.kt similarity index 74% rename from pluto-plugins/plugins/network/interceptor-ktor/lib/src/main/kotlin/com/pluto/plugins/network/internal/RequestConverter.kt rename to pluto-plugins/plugins/network/interceptor-ktor/lib/src/main/kotlin/com/pluto/plugins/network/ktor/internal/RequestConverter.kt index 3c7e916e9..d69d7db4c 100644 --- a/pluto-plugins/plugins/network/interceptor-ktor/lib/src/main/kotlin/com/pluto/plugins/network/internal/RequestConverter.kt +++ b/pluto-plugins/plugins/network/interceptor-ktor/lib/src/main/kotlin/com/pluto/plugins/network/ktor/internal/RequestConverter.kt @@ -1,4 +1,4 @@ -package com.pluto.plugins.network.internal +package com.pluto.plugins.network.ktor.internal import com.pluto.plugins.network.intercept.NetworkData.Request diff --git a/pluto-plugins/plugins/network/interceptor-ktor/lib/src/main/kotlin/com/pluto/plugins/network/internal/ResponseConverter.kt b/pluto-plugins/plugins/network/interceptor-ktor/lib/src/main/kotlin/com/pluto/plugins/network/ktor/internal/ResponseConverter.kt similarity index 75% rename from pluto-plugins/plugins/network/interceptor-ktor/lib/src/main/kotlin/com/pluto/plugins/network/internal/ResponseConverter.kt rename to pluto-plugins/plugins/network/interceptor-ktor/lib/src/main/kotlin/com/pluto/plugins/network/ktor/internal/ResponseConverter.kt index 38da97719..a6ec250dc 100644 --- a/pluto-plugins/plugins/network/interceptor-ktor/lib/src/main/kotlin/com/pluto/plugins/network/internal/ResponseConverter.kt +++ b/pluto-plugins/plugins/network/interceptor-ktor/lib/src/main/kotlin/com/pluto/plugins/network/ktor/internal/ResponseConverter.kt @@ -1,4 +1,4 @@ -package com.pluto.plugins.network.internal +package com.pluto.plugins.network.ktor.internal import com.pluto.plugins.network.intercept.NetworkData.Response diff --git a/pluto-plugins/plugins/network/interceptor-okhttp/lib-no-op/build.gradle b/pluto-plugins/plugins/network/interceptor-okhttp/lib-no-op/build.gradle index d96cb4093..3793ffa03 100644 --- a/pluto-plugins/plugins/network/interceptor-okhttp/lib-no-op/build.gradle +++ b/pluto-plugins/plugins/network/interceptor-okhttp/lib-no-op/build.gradle @@ -12,7 +12,7 @@ def verCode, verName, verBuild, verNameShort, verPublish ext { PUBLISH_GROUP_ID = "com.plutolib.plugins" PUBLISH_VERSION = verPublish - PUBLISH_ARTIFACT_ID = 'network-okhttp-no-op' + PUBLISH_ARTIFACT_ID = 'network-interceptor-okhttp-no-op' } android { diff --git a/pluto-plugins/plugins/network/interceptor-okhttp/lib-no-op/src/main/java/com/pluto/plugins/network/PlutoInterceptor.kt b/pluto-plugins/plugins/network/interceptor-okhttp/lib-no-op/src/main/java/com/pluto/plugins/network/okhttp/PlutoInterceptor.kt similarity index 87% rename from pluto-plugins/plugins/network/interceptor-okhttp/lib-no-op/src/main/java/com/pluto/plugins/network/PlutoInterceptor.kt rename to pluto-plugins/plugins/network/interceptor-okhttp/lib-no-op/src/main/java/com/pluto/plugins/network/okhttp/PlutoInterceptor.kt index d782d4990..91fb06d18 100644 --- a/pluto-plugins/plugins/network/interceptor-okhttp/lib-no-op/src/main/java/com/pluto/plugins/network/PlutoInterceptor.kt +++ b/pluto-plugins/plugins/network/interceptor-okhttp/lib-no-op/src/main/java/com/pluto/plugins/network/okhttp/PlutoInterceptor.kt @@ -1,4 +1,4 @@ -package com.pluto.plugins.network +package com.pluto.plugins.network.okhttp import androidx.annotation.Keep import okhttp3.Interceptor diff --git a/pluto-plugins/plugins/network/interceptor-okhttp/lib/build.gradle b/pluto-plugins/plugins/network/interceptor-okhttp/lib/build.gradle index 55331c080..31ddfe8c4 100644 --- a/pluto-plugins/plugins/network/interceptor-okhttp/lib/build.gradle +++ b/pluto-plugins/plugins/network/interceptor-okhttp/lib/build.gradle @@ -14,7 +14,7 @@ def verCode, verName, verBuild, verNameShort, verPublish ext { PUBLISH_GROUP_ID = "com.plutolib.plugins" PUBLISH_VERSION = verPublish - PUBLISH_ARTIFACT_ID = "network-okhttp" + PUBLISH_ARTIFACT_ID = "network-interceptor-okhttp" } android { diff --git a/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/PlutoOkhttpInterceptor.kt b/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/PlutoOkhttpInterceptor.kt deleted file mode 100644 index 99f11c3f4..000000000 --- a/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/PlutoOkhttpInterceptor.kt +++ /dev/null @@ -1,51 +0,0 @@ -package com.pluto.plugins.network - -import android.util.Log -import androidx.annotation.Keep -import com.pluto.plugins.network.intercept.NetworkInterceptor -import com.pluto.plugins.network.internal.CacheDirectoryProvider -import com.pluto.plugins.network.internal.ResponseBodyProcessor -import com.pluto.plugins.network.internal.convert -import okhttp3.Interceptor -import okhttp3.Response -import java.io.IOException - -@Keep -class PlutoOkhttpInterceptor : Interceptor { - - private var cacheDirectoryProvider: CacheDirectoryProvider? = null - - override fun intercept(chain: Interceptor.Chain): Response { - val request = chain.request() - getCacheProvider()?.let { provider -> - val networkInterceptor = NetworkInterceptor.intercept(request.convert(), NetworkInterceptor.Option(NAME)) - val response: Response = try { - val builder = request.newBuilder().url(networkInterceptor.requestUrlWithMockInfo) - chain.proceed(builder.build()) - } catch (e: IOException) { - networkInterceptor.onError(e) - throw e - } - return ResponseBodyProcessor.processBody(provider, response) { responseData -> - networkInterceptor.onResponse(responseData) - } - } - Log.e("pluto", "API call not intercepted as Pluto Network is not installed.") - return chain.proceed(request) - } - - private fun getCacheProvider(): CacheDirectoryProvider? { - return PlutoNetwork.applicationContext?.let { context -> - if (cacheDirectoryProvider == null) { - cacheDirectoryProvider = CacheDirectoryProvider { context.filesDir } - } - cacheDirectoryProvider - } ?: run { - null - } - } - - companion object { - private const val NAME = "Okhttp" - } -} diff --git a/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/internal/CacheDirectoryProvider.kt b/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/internal/CacheDirectoryProvider.kt deleted file mode 100644 index 2de8cf8a2..000000000 --- a/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/internal/CacheDirectoryProvider.kt +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Source: chucker - https://github.com/ChuckerTeam/chucker.git - * License: https://github.com/ChuckerTeam/chucker/blob/develop/LICENSE.txt - */ -package com.pluto.plugins.network.internal - -import java.io.File - -/** - * An interface that returns a reference to a cache directory where temporary files can be - * saved. - */ -internal fun interface CacheDirectoryProvider { - fun provide(): File? -} diff --git a/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/internal/DataConvertor.kt b/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/internal/DataConvertor.kt deleted file mode 100644 index 2a35faee9..000000000 --- a/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/internal/DataConvertor.kt +++ /dev/null @@ -1,140 +0,0 @@ -package com.pluto.plugins.network.internal - -import com.pluto.plugins.network.intercept.NetworkData -import com.pluto.utilities.DebugLog -import okhttp3.Request -import okhttp3.Response -import okio.IOException -import java.io.ByteArrayInputStream -import java.io.ByteArrayOutputStream -import java.io.InputStream -import java.io.OutputStream -import java.nio.charset.Charset -import java.util.zip.GZIPInputStream - -internal fun Request.convert(): NetworkData.Request { - val body = this.body?.processBody(this.isGzipped) - return NetworkData.Request( - url = this.url.toString(), - method = this.method, - body = body, - headers = this.headerMap(body?.sizeInBytes ?: 0L), - sentTimestamp = System.currentTimeMillis() - ) -} - -internal fun Request.headerMap(contentLength: Long): Map { - val headerNames = arrayListOf() - headerNames.addAll(headers.names()) - headerNames.add("content-type") - headerNames.add("content-length") - headerNames.sortBy { it } - - val map = mutableMapOf() - headerNames.forEach { - val key = it.lowercase().trim() - when (it) { - "content-type" -> body?.contentType()?.toString()?.let { value -> - map[key] = value.trim() - } - "content-length" -> map[key] = headers[it]?.trim() ?: run { contentLength.toString() } - else -> map[key] = headers[it]?.trim() - } - } - return map -} - -internal fun Response.convert(body: NetworkData.Body?): NetworkData.Response { - return NetworkData.Response( - statusCode = code, - body = body, - protocol = protocol.name, - fromDiskCache = false, - headers = headersMap(), - sentTimestamp = sentRequestAtMillis, - receiveTimestamp = receivedResponseAtMillis - ) -} - -private fun Response.headersMap(): Map { - val headerNames = arrayListOf() - headerNames.addAll(headers.names()) - headerNames.sortBy { it } - - val map = mutableMapOf() - headerNames.forEach { - map[it.lowercase().trim()] = headers[it]?.trim() - } - - return map -} - -@Suppress("TooGenericExceptionCaught") -internal fun doUnZipToString(gzippedMessage: ByteArray?): String { - var unzippedMessage: String? = null - try { - val gzippped = doUnZip(gzippedMessage) - unzippedMessage = String(gzippped!!, Charset.defaultCharset()) - } catch (e: Throwable) { - DebugLog.e(LOGTAG, "doUnZipToString 1", e) - } - return unzippedMessage ?: "" -} - -private fun doUnZip(stream: InputStream?): ByteArray? { - if (stream !is ByteArrayInputStream) { - return try { - doUnZip(stream?.readBytes()) - } catch (e: IOException) { - DebugLog.e(LOGTAG, "doUnZip 1", e) - null -// throw SystemFailedException(e.getMessage(), e) - } - } - var bos: ByteArrayOutputStream? = null - var gzipStream: InputStream? = null - var bytes: ByteArray? = null - try { - bos = ByteArrayOutputStream() - gzipStream = GZIPInputStream(stream) - copy(gzipStream, bos) - bytes = bos.toByteArray() - } catch (e: IOException) { - DebugLog.e(LOGTAG, "error while unzip", e) - } finally { - try { - gzipStream?.close() - bos?.close() - } catch (e: IOException) { - DebugLog.e(LOGTAG, "error while closing stream", e) - } - } - return bytes -} - -private fun doUnZip(zippedMessage: ByteArray?): ByteArray? { - var stream: ByteArrayInputStream? = null - return try { - stream = ByteArrayInputStream(zippedMessage) - doUnZip(stream) - } finally { - try { - stream?.close() - } catch (e: IOException) { - DebugLog.e(LOGTAG, "error while closing zippedMessage stream", e) - } - } -} - -private const val BUFFER_SIZE = 1024 - -@Throws(IOException::class) -private fun copy(stream: InputStream, out: OutputStream) { - val buf = ByteArray(BUFFER_SIZE) - var len: Int - while (stream.read(buf, 0, buf.size).also { len = it } != -1) { - out.write(buf, 0, len) - } -} - -private const val LOGTAG = "data-convertor" diff --git a/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/internal/OkHttpKtx.kt b/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/internal/OkHttpKtx.kt deleted file mode 100644 index dbe58dc88..000000000 --- a/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/internal/OkHttpKtx.kt +++ /dev/null @@ -1,61 +0,0 @@ -package com.pluto.plugins.network.internal - -import java.net.HttpURLConnection -import okhttp3.Headers -import okhttp3.Request -import okhttp3.Response - -private const val HTTP_CONTINUE = 100 - -/** Returns true if the response must have a (possibly 0-length) body. See RFC 7231. */ -internal fun Response.hasBody(): Boolean { - // HEAD requests never yield a body regardless of the response headers. - if (request.method == "HEAD") { - return false - } - - val responseCode = code - val isSuccessResponse = responseCode < HTTP_CONTINUE || responseCode >= HttpURLConnection.HTTP_OK - if (isSuccessResponse && - responseCode != HttpURLConnection.HTTP_NO_CONTENT && - responseCode != HttpURLConnection.HTTP_NOT_MODIFIED - ) { - return true - } - - // If the Content-Length or Transfer-Encoding headers disagree with the response code, the - // response is malformed. For best compatibility, we honor the headers. - return contentLength > 0 || isChunked -} - -internal val Response.contentLength: Long - get() { - return this.header("Content-Length")?.toLongOrNull() ?: -1L - } - -internal val Response.isChunked: Boolean - get() { - return this.header("Transfer-Encoding").equals("chunked", ignoreCase = true) - } - -internal val Response.contentType: String? - get() { - return this.header("Content-Type") - } - -/** Checks if the OkHttp response uses gzip encoding. */ -internal val Response.isGzipped: Boolean - get() { - return this.headers.containsGzip - } - -/** Checks if the OkHttp request uses gzip encoding. */ -internal val Request.isGzipped: Boolean - get() { - return this.headers.containsGzip - } - -private val Headers.containsGzip: Boolean - get() { - return this["Content-Encoding"].equals("gzip", ignoreCase = true) - } diff --git a/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/internal/ResponseBodyProcessor.kt b/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/internal/ResponseBodyProcessor.kt deleted file mode 100644 index d6be6aa10..000000000 --- a/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/internal/ResponseBodyProcessor.kt +++ /dev/null @@ -1,93 +0,0 @@ -package com.pluto.plugins.network.internal - -import com.pluto.plugins.network.intercept.NetworkData -import okhttp3.MediaType -import okhttp3.Response -import okhttp3.ResponseBody -import okio.Buffer -import okio.BufferedSource -import okio.GzipSource -import okio.Source -import okio.buffer -import okio.source -import java.io.File -import java.io.IOException - -internal object ResponseBodyProcessor { - private const val MAX_CONTENT_LENGTH = 300_000L - private const val maxContentLength = MAX_CONTENT_LENGTH - - fun processBody(cacheDirectoryProvider: CacheDirectoryProvider, response: Response, onComplete: (NetworkData.Response) -> Unit): Response { - onComplete.invoke(response.convert(null)) - val responseBody = response.body - if (!response.hasBody() || responseBody == null) { - return response - } - - val contentType = responseBody.contentType() - val contentLength = responseBody.contentLength() - - val sideStream = ReportingSink( - createTempTransactionFile(cacheDirectoryProvider), - ApiCallReportingSinkCallback(response, onComplete), - maxContentLength - ) - var upstream: Source = TeeSource(responseBody.source(), sideStream) - upstream = DepletingSource(upstream) - - return response.newBuilder() - .body(upstream.buffer().asResponseBody(contentType, contentLength)) - .build() - } - - private fun createTempTransactionFile(cacheDirectoryProvider: CacheDirectoryProvider): File? { - val cache = cacheDirectoryProvider.provide() - return if (cache == null) { - IOException("Failed to obtain a valid cache directory for Pluto transaction file").printStackTrace() - null - } else { - FileFactory.create(cache) - } - } - - private class ApiCallReportingSinkCallback( - private val response: Response, - private val onComplete: (NetworkData.Response) -> Unit - ) : ReportingSink.Callback { - - override fun onSuccess(file: File?, sourceByteCount: Long) { - file?.let { f -> - readResponseBuffer(f, response.isGzipped)?.let { - val responseBody = response.body ?: return - val body = responseBody.processBody(it) - onComplete.invoke(response.convert(body)) - } - f.delete() - } - } - - override fun onFailure(file: File?, exception: IOException) = exception.printStackTrace() - - private fun readResponseBuffer(responseBody: File, isGzipped: Boolean) = try { - val bufferedSource = responseBody.source().buffer() - val source = if (isGzipped) { - GzipSource(bufferedSource) - } else { - bufferedSource - } - Buffer().apply { source.use { writeAll(it) } } - } catch (e: IOException) { - IOException("Response payload couldn't be processed by Pluto", e).printStackTrace() - null - } - } -} - -/** Returns a new response body that transmits this source. */ -private fun BufferedSource.asResponseBody(contentType: MediaType? = null, contentLength: Long = -1L) = object : ResponseBody() { - override fun contentType() = contentType - - override fun contentLength() = contentLength - - override fun source() = this@asResponseBody -} diff --git a/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/okhttp/PlutoInterceptor.kt b/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/okhttp/PlutoInterceptor.kt new file mode 100644 index 000000000..3905b1916 --- /dev/null +++ b/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/okhttp/PlutoInterceptor.kt @@ -0,0 +1,65 @@ +package com.pluto.plugins.network.okhttp + +import androidx.annotation.Keep +import com.pluto.plugin.libinterface.PlutoInterface +import com.pluto.plugins.network.intercept.NetworkData +import com.pluto.plugins.network.intercept.NetworkInterceptor +import com.pluto.plugins.network.okhttp.internal.ResponseReportingSinkCallback +import com.pluto.plugins.network.okhttp.internal.convert +import com.pluto.plugins.network.okhttp.internal.hasBody +import com.pluto.plugins.network.okhttp.internal.utilities.DepletingSource +import com.pluto.plugins.network.okhttp.internal.utilities.ReportingSink +import com.pluto.plugins.network.okhttp.internal.utilities.TeeSource +import okhttp3.Interceptor +import okhttp3.Response +import okhttp3.ResponseBody +import okio.BufferedSource +import okio.buffer +import java.io.IOException + +@Keep +internal class PlutoInterceptor : Interceptor { + + override fun intercept(chain: Interceptor.Chain): Response { + val request = chain.request() + val networkInterceptor = NetworkInterceptor.intercept(request.convert(), NetworkInterceptor.Option(NAME)) + val response: Response = try { + val builder = request.newBuilder().url(networkInterceptor.actualOrMockRequestUrl) + chain.proceed(builder.build()) + } catch (e: IOException) { + networkInterceptor.onError(e) + throw e + } + return response.processBody { networkInterceptor.onResponse(it) } + } + + companion object { + private const val NAME = "Okhttp" + } +} + +private fun Response.processBody(onComplete: (NetworkData.Response) -> Unit): Response { + if (!hasBody()) { + onComplete.invoke(convert(null)) + return this + } + val responseBody: ResponseBody = body as ResponseBody + val sideStream = ReportingSink(PlutoInterface.files.createFile(), ResponseReportingSinkCallback(this, onComplete)) + val processedResponseBody: ResponseBody = DepletingSource(TeeSource(responseBody.source(), sideStream)) + .buffer() + .asResponseBody(responseBody) + + return newBuilder() + .body(processedResponseBody) + .build() +} + +/** Returns a new response body that transmits this source. */ +private fun BufferedSource.asResponseBody(referenceBody: ResponseBody) = object : ResponseBody() { + override fun contentType() = referenceBody.contentType() + + override fun contentLength() = referenceBody.contentLength() + + override fun source() = this@asResponseBody +} + diff --git a/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/okhttp/PlutoOkhttpHelper.kt b/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/okhttp/PlutoOkhttpHelper.kt new file mode 100644 index 000000000..4824a2543 --- /dev/null +++ b/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/okhttp/PlutoOkhttpHelper.kt @@ -0,0 +1,10 @@ +package com.pluto.plugins.network.okhttp + +import okhttp3.OkHttpClient +import javax.net.SocketFactory + +fun OkHttpClient.Builder.addPlutoOkhttpInterceptor() { + // todo add okhttp settings block here + socketFactory(SocketFactory.getDefault()) + addInterceptor(PlutoInterceptor()) +} diff --git a/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/internal/ContentProcessor.kt b/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/okhttp/internal/ContentProcessor.kt similarity index 81% rename from pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/internal/ContentProcessor.kt rename to pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/okhttp/internal/ContentProcessor.kt index 9a41009fe..416fbce7c 100644 --- a/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/internal/ContentProcessor.kt +++ b/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/okhttp/internal/ContentProcessor.kt @@ -1,4 +1,4 @@ -package com.pluto.plugins.network.internal +package com.pluto.plugins.network.okhttp.internal import com.pluto.plugins.network.intercept.NetworkData.Body import com.pluto.plugins.network.internal.interceptor.logic.UTF8 @@ -12,7 +12,7 @@ import okio.IOException internal fun RequestBody.processBody(gzipped: Boolean): Body? { return contentType()?.let { - DebugLog.e(LOGTAG, "request : ${it.type}, ${it.subtype}, ${it.charset()}") + DebugLog.e(LOG_TAG, "request : ${it.type}, ${it.subtype}, ${it.charset()}") Body( body = if (it.isText()) extractBody(gzipped) else BINARY_BODY, contentType = it.toString() @@ -22,7 +22,7 @@ internal fun RequestBody.processBody(gzipped: Boolean): Body? { internal fun ResponseBody?.processBody(buffer: Buffer): Body? { return this?.contentType()?.let { - DebugLog.e(LOGTAG, "response : ${it.type}, ${it.subtype}, ${it.charset()}") + DebugLog.e(LOG_TAG, "response : ${it.type}, ${it.subtype}, ${it.charset()}") Body( body = if (it.isText()) buffer.readString(it.charset(UTF8) ?: UTF8) else BINARY_BODY, contentType = it.toString() @@ -35,12 +35,12 @@ private fun RequestBody.extractBody(gzipped: Boolean): CharSequence { val buffer = Buffer() writeTo(buffer) if (gzipped) { - doUnZipToString(buffer.readByteArray()) + buffer.readByteArray().unzipToString() } else { buffer.readUtf8() } } catch (e: IOException) { - DebugLog.e(LOGTAG, "request body parsing failed", e) + DebugLog.e(LOG_TAG, "request body parsing failed", e) "" } } @@ -59,4 +59,4 @@ internal const val BODY_INDENTATION = 2 private const val BINARY_BODY = "~ Binary Data" private const val HTTP_PORT = 80 private const val HTTPS_PORT = 443 -private const val LOGTAG = "content-processor" \ No newline at end of file +private const val LOG_TAG = "content-processor" \ No newline at end of file diff --git a/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/okhttp/internal/DataConvertor.kt b/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/okhttp/internal/DataConvertor.kt new file mode 100644 index 000000000..da21cafca --- /dev/null +++ b/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/okhttp/internal/DataConvertor.kt @@ -0,0 +1,62 @@ +package com.pluto.plugins.network.okhttp.internal + +import com.pluto.plugins.network.intercept.NetworkData +import okhttp3.Request +import okhttp3.Response + +internal fun Request.convert(): NetworkData.Request { + val body = this.body?.processBody(this.isGzipped) + return NetworkData.Request( + url = this.url.toString(), + method = this.method, + body = body, + headers = this.headerMap(body?.sizeInBytes ?: 0L), + sentTimestamp = System.currentTimeMillis() + ) +} + +internal fun Request.headerMap(contentLength: Long): Map { + val headerNames = arrayListOf() + headerNames.addAll(headers.names()) + headerNames.add("content-type") + headerNames.add("content-length") + headerNames.sortBy { it } + + val map = mutableMapOf() + headerNames.forEach { + val key = it.lowercase().trim() + when (it) { + "content-type" -> body?.contentType()?.toString()?.let { value -> + map[key] = value.trim() + } + "content-length" -> map[key] = headers[it]?.trim() ?: run { contentLength.toString() } + else -> map[key] = headers[it]?.trim() + } + } + return map +} + +internal fun Response.convert(body: NetworkData.Body?): NetworkData.Response { + return NetworkData.Response( + statusCode = code, + body = body, + protocol = protocol.name, + fromDiskCache = false, + headers = headersMap(), + sentTimestamp = sentRequestAtMillis, + receiveTimestamp = receivedResponseAtMillis + ) +} + +private fun Response.headersMap(): Map { + val headerNames = arrayListOf() + headerNames.addAll(headers.names()) + headerNames.sortBy { it } + + val map = mutableMapOf() + headerNames.forEach { + map[it.lowercase().trim()] = headers[it]?.trim() + } + + return map +} diff --git a/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/okhttp/internal/OkHttpKtx.kt b/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/okhttp/internal/OkHttpKtx.kt new file mode 100644 index 000000000..435aac8f2 --- /dev/null +++ b/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/okhttp/internal/OkHttpKtx.kt @@ -0,0 +1,52 @@ +package com.pluto.plugins.network.okhttp.internal + +import java.net.HttpURLConnection +import okhttp3.Request +import okhttp3.Response + +private const val HTTP_CONTINUE = 100 + +internal fun Response.hasBody(): Boolean { + if (request.method == "HEAD") { + return false + } + body?.let { + val responseCode = code + val isSuccessResponse = responseCode < HTTP_CONTINUE || responseCode >= HttpURLConnection.HTTP_OK + if (isSuccessResponse && + responseCode != HttpURLConnection.HTTP_NO_CONTENT && + responseCode != HttpURLConnection.HTTP_NOT_MODIFIED + ) { + return true + } + + return contentLength > 0 || isChunked + } + return false +} + +internal val Response.contentLength: Long + get() { + return this.header("Content-Length")?.toLongOrNull() ?: 0 + } + +internal val Response.isChunked: Boolean + get() { + return this.header("Transfer-Encoding").equals("chunked", ignoreCase = true) + } + +internal val Response.contentType: String? + get() { + return this.header("Content-Type") + } + +internal val Response.isGzipped: Boolean + get() { + return this.header("Content-Encoding").equals("gzip", ignoreCase = true) + } + +internal val Request.isGzipped: Boolean + get() { + return this.header("Content-Encoding").equals("gzip", ignoreCase = true) + } + diff --git a/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/okhttp/internal/ResponseReportingSinkCallback.kt b/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/okhttp/internal/ResponseReportingSinkCallback.kt new file mode 100644 index 000000000..e94648bad --- /dev/null +++ b/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/okhttp/internal/ResponseReportingSinkCallback.kt @@ -0,0 +1,43 @@ +package com.pluto.plugins.network.okhttp.internal + +import com.pluto.plugins.network.intercept.NetworkData +import com.pluto.plugins.network.okhttp.internal.utilities.ReportingSink +import okhttp3.Response +import okio.Buffer +import okio.GzipSource +import okio.buffer +import okio.source +import java.io.File +import java.io.IOException + +class ResponseReportingSinkCallback( + private val response: Response, + private val onComplete: (NetworkData.Response) -> Unit +) : ReportingSink.Callback { + + override fun onSuccess(file: File?, sourceByteCount: Long) { + file?.let { f -> + readResponseBuffer(f, response.isGzipped)?.let { + val responseBody = response.body ?: return + val body = responseBody.processBody(it) + onComplete.invoke(response.convert(body)) + } + f.delete() + } + } + + override fun onFailure(file: File?, exception: IOException) = exception.printStackTrace() + + private fun readResponseBuffer(responseBody: File, isGzipped: Boolean) = try { + val bufferedSource = responseBody.source().buffer() + val source = if (isGzipped) { + GzipSource(bufferedSource) + } else { + bufferedSource + } + Buffer().apply { source.use { writeAll(it) } } + } catch (e: IOException) { + IOException("Response payload couldn't be processed by Pluto", e).printStackTrace() + null + } +} \ No newline at end of file diff --git a/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/okhttp/internal/StreamKtx.kt b/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/okhttp/internal/StreamKtx.kt new file mode 100644 index 000000000..b39bb0e87 --- /dev/null +++ b/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/okhttp/internal/StreamKtx.kt @@ -0,0 +1,65 @@ +package com.pluto.plugins.network.okhttp.internal + +import com.pluto.utilities.DebugLog +import okio.IOException +import java.io.ByteArrayInputStream +import java.io.ByteArrayOutputStream +import java.io.InputStream +import java.nio.charset.Charset +import java.util.zip.GZIPInputStream + +@Suppress("TooGenericExceptionCaught") +internal fun ByteArray.unzipToString(): String { + return try { + String(this.unzip()!!, Charset.defaultCharset()) + } catch (e: Throwable) { + DebugLog.e(LOG_TAG, "ByteArray.unzipToString", e) + "" + } +} + +private fun InputStream?.unzip(): ByteArray? { + if (this !is ByteArrayInputStream) { + return try { + this?.readBytes().unzip() + } catch (e: IOException) { + DebugLog.e(LOG_TAG, "doUnZip 1", e) + null + } + } + var bos: ByteArrayOutputStream? = null + var gzipStream: InputStream? = null + var bytes: ByteArray? = null + try { + bos = ByteArrayOutputStream() + gzipStream = GZIPInputStream(this) + gzipStream.copyTo(bos) + bytes = bos.toByteArray() + } catch (e: IOException) { + DebugLog.e(LOG_TAG, "error while unzip", e) + } finally { + try { + gzipStream?.close() + bos?.close() + } catch (e: IOException) { + DebugLog.e(LOG_TAG, "error while closing stream", e) + } + } + return bytes +} + +private fun ByteArray?.unzip(): ByteArray? { + var stream: ByteArrayInputStream? = null + return try { + stream = ByteArrayInputStream(this) + stream.unzip() + } finally { + try { + stream?.close() + } catch (e: IOException) { + DebugLog.e(LOG_TAG, "error while closing zippedMessage stream", e) + } + } +} + +private const val LOG_TAG = "stream" diff --git a/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/internal/DepletingSource.kt b/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/okhttp/internal/utilities/DepletingSource.kt similarity index 94% rename from pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/internal/DepletingSource.kt rename to pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/okhttp/internal/utilities/DepletingSource.kt index e08c2b6fd..9a22e50aa 100644 --- a/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/internal/DepletingSource.kt +++ b/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/okhttp/internal/utilities/DepletingSource.kt @@ -2,7 +2,7 @@ * Source: chucker - https://github.com/ChuckerTeam/chucker.git * License: https://github.com/ChuckerTeam/chucker/blob/develop/LICENSE.txt */ -package com.pluto.plugins.network.internal +package com.pluto.plugins.network.okhttp.internal.utilities import java.io.IOException import okio.Buffer diff --git a/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/internal/ReportingSink.kt b/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/okhttp/internal/utilities/ReportingSink.kt similarity index 96% rename from pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/internal/ReportingSink.kt rename to pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/okhttp/internal/utilities/ReportingSink.kt index 23dda742c..2455bb2f6 100644 --- a/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/internal/ReportingSink.kt +++ b/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/okhttp/internal/utilities/ReportingSink.kt @@ -2,7 +2,7 @@ * Source: chucker - https://github.com/ChuckerTeam/chucker.git * License: https://github.com/ChuckerTeam/chucker/blob/develop/LICENSE.txt */ -package com.pluto.plugins.network.internal +package com.pluto.plugins.network.okhttp.internal.utilities import java.io.File import java.io.IOException @@ -22,7 +22,7 @@ import okio.sink internal class ReportingSink( private val downstreamFile: File?, private val callback: Callback, - private val writeByteLimit: Long = Long.MAX_VALUE + private val writeByteLimit: Long = 300_000L ) : Sink { private var totalByteCount = 0L private var isFailure = false diff --git a/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/internal/TeeSource.kt b/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/okhttp/internal/utilities/TeeSource.kt similarity index 96% rename from pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/internal/TeeSource.kt rename to pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/okhttp/internal/utilities/TeeSource.kt index bf16f5123..f77acf1c9 100644 --- a/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/internal/TeeSource.kt +++ b/pluto-plugins/plugins/network/interceptor-okhttp/lib/src/main/kotlin/com/pluto/plugins/network/okhttp/internal/utilities/TeeSource.kt @@ -2,7 +2,7 @@ * Source: chucker - https://github.com/ChuckerTeam/chucker.git * License: https://github.com/ChuckerTeam/chucker/blob/develop/LICENSE.txt */ -package com.pluto.plugins.network.internal +package com.pluto.plugins.network.okhttp.internal.utilities import java.io.IOException import okio.Buffer diff --git a/sample/src/main/java/com/sampleapp/functions/network/internal/ktor/KtorNetwork.kt b/sample/src/main/java/com/sampleapp/functions/network/internal/ktor/KtorNetwork.kt index 1ba970846..f7859136a 100644 --- a/sample/src/main/java/com/sampleapp/functions/network/internal/ktor/KtorNetwork.kt +++ b/sample/src/main/java/com/sampleapp/functions/network/internal/ktor/KtorNetwork.kt @@ -1,6 +1,6 @@ package com.sampleapp.functions.network.internal.ktor -import com.pluto.plugins.network.addPlutoKtorPlugin +import com.pluto.plugins.network.ktor.addPlutoKtorInterceptor import io.ktor.client.HttpClient import io.ktor.client.plugins.contentnegotiation.ContentNegotiation import io.ktor.client.plugins.defaultRequest @@ -18,5 +18,5 @@ val Client = HttpClient { json() } }.apply { - addPlutoKtorPlugin() + addPlutoKtorInterceptor() } diff --git a/sample/src/main/java/com/sampleapp/functions/network/internal/okhttp/Network.kt b/sample/src/main/java/com/sampleapp/functions/network/internal/okhttp/Network.kt index d65f686ea..836afe97d 100644 --- a/sample/src/main/java/com/sampleapp/functions/network/internal/okhttp/Network.kt +++ b/sample/src/main/java/com/sampleapp/functions/network/internal/okhttp/Network.kt @@ -1,6 +1,6 @@ package com.sampleapp.functions.network.internal.okhttp -import com.pluto.plugins.network.PlutoOkhttpInterceptor +import com.pluto.plugins.network.okhttp.addPlutoOkhttpInterceptor import java.util.concurrent.TimeUnit import okhttp3.OkHttpClient import okhttp3.logging.HttpLoggingInterceptor @@ -38,6 +38,6 @@ object Network { private fun OkHttpClient.Builder.addInterceptors(): OkHttpClient.Builder { // addInterceptor(GzipRequestInterceptor()) addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)) - addInterceptor(PlutoOkhttpInterceptor()) + addPlutoOkhttpInterceptor() return this }