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