Browse Source

refactor: peekString rename to peekBytes, remove logString

drake 2 years ago
parent
commit
fc78aca04d

+ 0 - 8
docs/interceptor.md

@@ -48,14 +48,6 @@ class RefreshTokenInterceptor : Interceptor {
 }
 ```
 
-
-在拦截器中可以使用以下函数复制请求/响应体
-
-| 函数 | 描述 |
-|-|-|
-| peekString | 可以截取复制`RequestBody/ResponseBody`, 并返回String |
-| logString | 等同`peekString`, 但仅支持content-type为xml/html/json/plain类型的数据 |
-
 ## 请求拦截器
 
 RequestInterceptor属于轻量级的请求拦截器, 在每次请求的时候该拦截器都会被触发(无法修改响应信息), 方便添加全局请求头/参数

+ 12 - 18
net/src/main/java/com/drake/net/body/BodyExtension.kt

@@ -4,8 +4,8 @@ import com.drake.net.interfaces.ProgressListener
 import okhttp3.MultipartBody
 import okhttp3.RequestBody
 import okhttp3.ResponseBody
-import okhttp3.ResponseBody.Companion.asResponseBody
 import okio.Buffer
+import okio.ByteString
 import java.util.concurrent.ConcurrentLinkedQueue
 
 fun RequestBody.toNetRequestBody(listeners: ConcurrentLinkedQueue<ProgressListener>? = null) = run {
@@ -19,38 +19,32 @@ fun ResponseBody.toNetResponseBody(
 
 /**
  * 复制一段指定长度的字符串内容
- * @param byteCount 复制的字节长度. 如果-1则返回完整的字符串内容
+ * @param byteCount 复制的字节长度, 允许超过实际长度, 如果-1则返回完整的字符串内容
  */
-@JvmName("peekString")
-fun RequestBody.peekString(byteCount: Long = 1024 * 1024, discard: Boolean = false): String {
+fun RequestBody.peekBytes(byteCount: Long = 1024 * 1024): ByteString {
     return when (this) {
-        is NetRequestBody -> peekString(byteCount, discard)
+        is NetRequestBody -> peekBytes(byteCount)
         else -> {
             val buffer = Buffer()
             writeTo(buffer)
-            if (discard && buffer.size > byteCount) return ""
-            val byteCountFinal = if (byteCount < 0) buffer.size else minOf(buffer.size, byteCount)
-            buffer.readUtf8(byteCountFinal)
+            val maxSize = if (byteCount < 0) buffer.size else minOf(buffer.size, byteCount)
+            buffer.readByteString(maxSize)
         }
     }
 }
 
 /**
  * 复制一段指定长度的字符串内容
- * @param byteCount 复制的字节长度. 如果-1则返回完整的字符串内容
+ * @param byteCount 复制的字节长度, 允许超过实际长度, 如果-1则返回完整的字符串内容
  */
-fun ResponseBody.peekString(byteCount: Long = 1024 * 1024 * 4, discard: Boolean = false): String {
+fun ResponseBody.peekBytes(byteCount: Long = 1024 * 1024 * 4): ByteString {
     return when (this) {
-        is NetResponseBody -> peekString(byteCount, discard)
+        is NetResponseBody -> peekBytes(byteCount)
         else -> {
             val peeked = source().peek()
-            val buffer = Buffer()
             peeked.request(byteCount)
-            val byteCountFinal =
-                if (byteCount < 0) peeked.buffer.size else minOf(byteCount, peeked.buffer.size)
-            buffer.write(peeked, byteCountFinal)
-            if (discard && buffer.size > byteCount) return ""
-            buffer.asResponseBody(contentType(), byteCountFinal).string()
+            val maxSize = if (byteCount < 0) peeked.buffer.size else minOf(byteCount, peeked.buffer.size)
+            peeked.readByteString(maxSize)
         }
     }
 }
@@ -78,5 +72,5 @@ fun MultipartBody.Part.name(): String? {
 fun MultipartBody.Part.value(): String? {
     val contentDisposition = headers?.get("Content-Disposition") ?: return null
     return ";\\s${"filename"}=\"(.+?)\"".toRegex().find(contentDisposition)?.groupValues?.getOrNull(1)
-        ?: body.peekString()
+        ?: body.peekBytes().utf8()
 }

+ 10 - 12
net/src/main/java/com/drake/net/body/NetRequestBody.kt

@@ -25,15 +25,15 @@ import java.io.IOException
 import java.util.concurrent.ConcurrentLinkedQueue
 
 class NetRequestBody(
-    private val requestBody: RequestBody,
+    private val body: RequestBody,
     private val progressListeners: ConcurrentLinkedQueue<ProgressListener>? = null
 ) : RequestBody() {
 
     private val progress = Progress()
-    val contentLength by lazy { requestBody.contentLength() }
+    val contentLength by lazy { body.contentLength() }
 
     override fun contentType(): MediaType? {
-        return requestBody.contentType()
+        return body.contentType()
     }
 
     @Throws(IOException::class)
@@ -45,25 +45,23 @@ class NetRequestBody(
     override fun writeTo(sink: BufferedSink) {
         if (sink is Buffer ||
             sink.toString().contains("com.android.tools.profiler.support.network.HttpTracker\$OutputStreamTracker")) {
-            requestBody.writeTo(sink)
+            body.writeTo(sink)
         } else {
             val bufferedSink: BufferedSink = sink.toProgress().buffer()
-            requestBody.writeTo(bufferedSink)
+            body.writeTo(bufferedSink)
             bufferedSink.close()
         }
     }
 
     /**
      * 复制一段指定长度的字符串内容
-     * @param byteCount 复制的字节长度. 如果-1则返回完整的字符串内容
-     * @param discard 如果实际长度大于指定长度则直接返回null. 可以保证数据完整性
+     * @param byteCount 复制的字节长度, 允许超过实际长度, 如果-1则返回完整的字符串内容
      */
-    fun peekString(byteCount: Long = 1024 * 1024, discard: Boolean = false): String {
+    fun peekBytes(byteCount: Long = 1024 * 1024): ByteString {
         val buffer = Buffer()
-        requestBody.writeTo(buffer)
-        if (discard && buffer.size > byteCount) return ""
-        val byteCountFinal = if (byteCount < 0) buffer.size else minOf(buffer.size, byteCount)
-        return buffer.readUtf8(byteCountFinal)
+        body.writeTo(buffer)
+        val maxSize = if (byteCount < 0) buffer.size else minOf(buffer.size, byteCount)
+        return buffer.readByteString(maxSize)
     }
 
     private fun Sink.toProgress() = object : ForwardingSink(this) {

+ 9 - 14
net/src/main/java/com/drake/net/body/NetResponseBody.kt

@@ -25,17 +25,17 @@ import java.io.IOException
 import java.util.concurrent.ConcurrentLinkedQueue
 
 class NetResponseBody(
-    private val responseBody: ResponseBody,
+    private val body: ResponseBody,
     private val progressListeners: ConcurrentLinkedQueue<ProgressListener>? = null,
     private val complete: (() -> Unit)? = null
 ) : ResponseBody() {
 
     private val progress = Progress()
-    private val bufferedSource by lazy { responseBody.source().toProgress().buffer() }
-    private val contentLength by lazy { responseBody.contentLength() }
+    private val bufferedSource by lazy { body.source().toProgress().buffer() }
+    private val contentLength by lazy { body.contentLength() }
 
     override fun contentType(): MediaType? {
-        return responseBody.contentType()
+        return body.contentType()
     }
 
     override fun contentLength(): Long {
@@ -48,18 +48,13 @@ class NetResponseBody(
 
     /**
      * 复制一段指定长度的字符串内容
-     * @param byteCount 复制的字节长度. 如果-1则返回完整的字符串内容
-     * @param discard 如果实际长度大于指定长度则直接返回null. 可以保证数据完整性
+     * @param byteCount 复制的字节长度, 允许超过实际长度, 如果-1则返回完整的字符串内容
      */
-    fun peekString(byteCount: Long = 1024 * 1024 * 4, discard: Boolean = false): String {
-        val peeked = responseBody.source().peek()
-        val buffer = Buffer()
+    fun peekBytes(byteCount: Long = 1024 * 1024 * 4): ByteString {
+        val peeked = body.source().peek()
         peeked.request(byteCount)
-        if (discard && buffer.size > byteCount) return ""
-        val byteCountFinal =
-            if (byteCount < 0) peeked.buffer.size else minOf(byteCount, peeked.buffer.size)
-        buffer.write(peeked, byteCountFinal)
-        return buffer.readUtf8(byteCountFinal)
+        val maxSize = if (byteCount < 0) peeked.buffer.size else minOf(byteCount, peeked.buffer.size)
+        return peeked.readByteString(maxSize)
     }
 
     private fun Source.toProgress() = object : ForwardingSource(this) {

+ 24 - 23
net/src/main/java/com/drake/net/interceptor/LogRecordInterceptor.kt

@@ -1,17 +1,14 @@
 package com.drake.net.interceptor
 
+import com.drake.net.body.name
+import com.drake.net.body.peekBytes
+import com.drake.net.body.value
 import com.drake.net.log.LogRecorder
-import com.drake.net.request.logString
-import com.drake.net.response.logString
-import okhttp3.Interceptor
-import okhttp3.Request
-import okhttp3.Response
+import okhttp3.*
 
 /**
  * 网络日志记录器
  * 可以参考此拦截器为项目中其他网络请求库配置. 本拦截器属于标准的OkHttp拦截器适用于所有OkHttp拦截器内核的网络请求库
- * 如果项目中的日志需要特殊情况, 例如请求体加密, 响应体解密, 请继承本拦截器进行自定义
- * 使用Request/Response的peekString函数可以复制请求和响应字符串
  *
  * 在正式环境下请禁用此日志记录器. 因为他会消耗少量网络速度
  *
@@ -25,10 +22,6 @@ open class LogRecordInterceptor(
     var responseByteCount: Long = 1024 * 1024 * 4
 ) : Interceptor {
 
-    init {
-        LogRecorder.enabled = enabled
-    }
-
     override fun intercept(chain: Interceptor.Chain): Response {
         val request = chain.request()
         if (!enabled) {
@@ -37,20 +30,12 @@ open class LogRecordInterceptor(
 
         val generateId = LogRecorder.generateId()
         LogRecorder.recordRequest(
-            generateId,
-            request.url.toString(),
-            request.method,
-            request.headers.toMultimap(),
-            requestString(request)
+            generateId, request.url.toString(), request.method, request.headers.toMultimap(), requestString(request)
         )
         try {
             val response = chain.proceed(request)
             LogRecorder.recordResponse(
-                generateId,
-                System.currentTimeMillis(),
-                response.code,
-                response.headers.toMultimap(),
-                responseString(response)
+                generateId, System.currentTimeMillis(), response.code, response.headers.toMultimap(), responseString(response)
             )
             return response
         } catch (e: Exception) {
@@ -64,13 +49,29 @@ open class LogRecordInterceptor(
      * 请求字符串
      */
     protected open fun requestString(request: Request): String? {
-        return request.logString(requestByteCount)
+        val body = request.body ?: return null
+        val mediaType = body.contentType()
+        return when {
+            body is MultipartBody -> body.parts.joinToString("&") {
+                "${it.name()}=${it.value()}"
+            }
+            body is FormBody -> body.peekBytes(requestByteCount).utf8()
+            arrayOf("plain", "json", "xml", "html").contains(mediaType?.subtype) -> body.peekBytes(requestByteCount).utf8()
+            else -> "$mediaType does not support output logs"
+        }
     }
 
     /**
      * 响应字符串
      */
     protected open fun responseString(response: Response): String? {
-        return response.logString(responseByteCount)
+        val body = response.body ?: return null
+        val mediaType = body.contentType()
+        val isPrintType = arrayOf("plain", "json", "xml", "html").contains(mediaType?.subtype)
+        return if (isPrintType) {
+            body.peekBytes(responseByteCount).utf8()
+        } else {
+            "$mediaType does not support output logs"
+        }
     }
 }

+ 0 - 37
net/src/main/java/com/drake/net/request/RequestExtension.kt

@@ -17,17 +17,11 @@
 package com.drake.net.request
 
 import com.drake.net.NetConfig
-import com.drake.net.body.name
-import com.drake.net.body.peekString
-import com.drake.net.body.value
 import com.drake.net.convert.NetConverter
 import com.drake.net.interfaces.ProgressListener
 import com.drake.net.tag.NetTag
-import okhttp3.FormBody
-import okhttp3.MultipartBody
 import okhttp3.OkHttpUtils
 import okhttp3.Request
-import java.net.URLDecoder
 import java.util.concurrent.ConcurrentLinkedQueue
 import kotlin.reflect.KType
 
@@ -187,35 +181,4 @@ fun Request.downloadTempFile(): Boolean {
  */
 fun Request.converter(): NetConverter {
     return tagOf<NetConverter>() ?: NetConfig.converter
-}
-
-/**
- * 请求日志信息
- * 只会输出 application/x-www-form-urlencoded, application/json, text/`*` 的请求体类型日志
- * @param urlDecode 是否进行 UTF-8 URLDecode
- */
-fun Request.logString(byteCount: Long = 1024 * 1024, urlDecode: Boolean = true): String? {
-    val requestBody = body ?: return null
-    val mediaType = requestBody.contentType()
-    val supportSubtype = arrayOf("plain", "json", "xml", "html").contains(mediaType?.subtype)
-    val bodyString = when {
-        requestBody is MultipartBody -> {
-            val params = mutableListOf<String>()
-            requestBody.parts.forEach {
-                params.add("${it.name()}=${it.value()}")
-            }
-            params.joinToString("&")
-        }
-        requestBody is FormBody || supportSubtype -> requestBody.peekString(byteCount)
-        else -> "$mediaType does not support output logs"
-    }
-    return if (urlDecode) {
-        try {
-            URLDecoder.decode(bodyString, "UTF-8")
-        } catch (e: Exception) {
-            bodyString
-        }
-    } else {
-        bodyString
-    }
 }

+ 0 - 16
net/src/main/java/com/drake/net/response/ResponseExtension.kt

@@ -16,7 +16,6 @@
 
 package com.drake.net.response
 
-import com.drake.net.body.peekString
 import com.drake.net.component.Progress
 import com.drake.net.convert.NetConverter
 import com.drake.net.exception.ConvertException
@@ -147,21 +146,6 @@ fun Response.file(): File? {
     }
 }
 
-/**
- * 响应日志信息
- * 只会输出 application/json, text/`*` 响应体类型日志
- */
-fun Response.logString(byteCount: Long = 1024 * 1024 * 4): String? {
-    val requestBody = body ?: return null
-    val mediaType = requestBody.contentType()
-    val supportSubtype = arrayOf("plain", "json", "xml", "html").contains(mediaType?.subtype)
-    return if (supportSubtype) {
-        requestBody.peekString(byteCount)
-    } else {
-        "$mediaType does not support output logs"
-    }
-}
-
 /**
  * 响应体使用转换器处理数据
  */