fix: UnbindInterceptor 改用 peekBody 防止消费响应体

source.request() 在空body/非JSON响应时会导致后续Gson解析失败。
改用 peekBody(1024) 安全读取副本。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
dongliang
2026-04-27 20:47:53 +09:30
parent 2d0a4d94ae
commit aec33ee3e1

View File

@@ -14,6 +14,7 @@ import javax.inject.Singleton
/** /**
* 解绑拦截器 * 解绑拦截器
* 检测 API 返回 code=104 时,自动清除用户数据并发送解绑事件 * 检测 API 返回 code=104 时,自动清除用户数据并发送解绑事件
* 使用 peekBody 安全读取响应体,不影响后续解析
*/ */
@Singleton @Singleton
class UnbindInterceptor @Inject constructor( class UnbindInterceptor @Inject constructor(
@@ -25,23 +26,25 @@ class UnbindInterceptor @Inject constructor(
override fun intercept(chain: Interceptor.Chain): Response { override fun intercept(chain: Interceptor.Chain): Response {
val response = chain.proceed(chain.request()) val response = chain.proceed(chain.request())
// 只处理成功的 HTTP 响应
if (response.isSuccessful) { if (response.isSuccessful) {
try { try {
// 窥视响应体(不消耗) // peekBody 安全读取副本,不消耗原始 body
val source = response.body?.source() ?: return response val peekBody = response.peekBody(1024)
source.request(Long.MAX_VALUE) val json = peekBody.string()
val buffer = source.buffer.clone()
val json = buffer.readUtf8()
val apiResponse = gson.fromJson(json, ApiResponse::class.java) if (json.isNotEmpty()) {
if (apiResponse?.isUnbound == true) { val apiResponse = gson.fromJson(json, ApiResponse::class.java)
Timber.w("收到 code=104执行自动解绑") if (apiResponse?.isUnbound == true) {
userPrefs.clear() Timber.w("收到 code=104执行自动解绑")
runBlocking { userPrefs.clear()
eventBus.emit(AppEvent.DeviceUnbound) runBlocking {
eventBus.emit(AppEvent.DeviceUnbound)
}
} }
} }
} catch (e: Exception) { } catch (e: Exception) {
// 解析异常不影响正常请求
Timber.w(e, "解绑检测异常") Timber.w(e, "解绑检测异常")
} }
} }