diff --git a/app/src/main/java/com/nova/brain/glass/repository/HeaderInterceptor.kt b/app/src/main/java/com/nova/brain/glass/repository/HeaderInterceptor.kt index d8c6dd8..affa054 100644 --- a/app/src/main/java/com/nova/brain/glass/repository/HeaderInterceptor.kt +++ b/app/src/main/java/com/nova/brain/glass/repository/HeaderInterceptor.kt @@ -5,8 +5,8 @@ import com.xuqm.base.common.SHARE_UESR_TOKEN import com.xuqm.base.extensions.getStringForPreferences import com.xuqm.base.extensions.log import com.xuqm.base.extensions.loge -import okhttp3.Headers import okhttp3.Interceptor +import okhttp3.MultipartBody import okhttp3.RequestBody import okhttp3.Response import okio.Buffer @@ -81,21 +81,53 @@ class HeaderInterceptor(val context: Context) : Interceptor { } private fun logRequest(request: okhttp3.Request) { - val requestBodyText = request.body?.let { bodyToString(it) }.orEmpty() - buildString { + buildRequestLog(request).loge() + } + + private fun buildRequestLog(request: okhttp3.Request): String { + return buildString { append("request: ") append(request.method) append(" ") append(request.url) - append('\n') - append("headers: ") - append(request.headers) - if (requestBodyText.isNotBlank()) { + val params = buildRequestParamsLog(request) + if (params.isNotBlank()) { append('\n') append("body: ") - append(requestBodyText) + append(params) } - }.loge() + } + } + + private fun buildRequestParamsLog(request: okhttp3.Request): String { + if (request.method == "GET") { + return urlQueryToJson(request.url) + } + val body = request.body ?: return "" + if (request.method != "POST") { + return bodyToString(body) + } + return when (body) { + is MultipartBody -> multipartBodyToString(body) + else -> bodyToString(body) + } + } + + private fun urlQueryToJson(url: okhttp3.HttpUrl): String { + if (url.querySize == 0) return "" + return buildString { + append("{") + repeat(url.querySize) { index -> + if (index > 0) append(",") + append("\"") + append(escapeJson(url.queryParameterName(index))) + append("\":") + append("\"") + append(escapeJson(url.queryParameterValue(index).orEmpty())) + append("\"") + } + append("}") + } } private fun bodyToString(requestBody: RequestBody): String { @@ -108,7 +140,38 @@ class HeaderInterceptor(val context: Context) : Interceptor { } } - private fun bodyHasUnknownEncoding(headers: Headers): Boolean { + private fun multipartBodyToString(body: MultipartBody): String { + val formFields = linkedMapOf() + body.parts.forEach { part -> + val disposition = part.headers?.get("Content-Disposition").orEmpty() + val name = disposition.substringAfter("name=\"", "").substringBefore('"') + if (name.isBlank()) return@forEach + if ("filename=\"" in disposition) { + return@forEach + } + val value = bodyToString(part.body).trim() + formFields[name] = value + } + return mapToJson(formFields) + } + + private fun mapToJson(fields: Map): String { + if (fields.isEmpty()) return "{}" + return fields.entries.joinToString(prefix = "{", postfix = "}") { + "\"${escapeJson(it.key)}\":\"${escapeJson(it.value)}\"" + } + } + + private fun escapeJson(value: String): String { + return value + .replace("\\", "\\\\") + .replace("\"", "\\\"") + .replace("\n", "\\n") + .replace("\r", "\\r") + .replace("\t", "\\t") + } + + private fun bodyHasUnknownEncoding(headers: okhttp3.Headers): Boolean { val contentEncoding = headers["Content-Encoding"] return (contentEncoding != null && !contentEncoding.equals("identity", ignoreCase = true) && !contentEncoding.equals("gzip", ignoreCase = true))