描述
-
支持按照域名设置对应的header信息
-
支持移除不需要的header信息
-
去除之前全局白名单处理
相关类说明
-
HeaderUtils
提供通用的header信息辅助类 -
RequestHeaderProvider
总的对外暴露提供请求Header信息的类 -
HeaderDataResponder
基础的Header数据提供响应者,使得提供header信息能够像插件一样。 -
GeneralHeaderDataResponder
通用的header信息响应者,用来处理改进之前的提供header信息。
如何添加指定域名的Header信息
在已有的HeaderDataResponder增加对应的host
比如某个HeaderDataResponder满足需要提供的header数据,可以直接在其中增加host即可。
如下以添加droidyue.com
为例。
package com.secoo.commonsdk.http.headers.responder
import com.secoo.commonsdk.core.Constants.*
import com.secoo.commonsdk.http.headers.HeaderDataResponder
import com.secoo.commonsdk.http.headers.HeaderUtils
/**
* 之前全局处理的header信息,支持响应多个域名
*/
object GeneralHeaderDataResponder : HeaderDataResponder() {
override fun provideDomainsToRespond(): List<String> {
return listOf(HOST_LAS, HOST_LR, HOST_MSHOPPING, HOST_ANDROID,
HOST_MMY, HOST_PAY, HOST_USER, HOST_CONTENT,
HOST_CRM,HOST_CUSTOMER).mapNotNull { HeaderUtils.getHostOfUrl(it) }
.plus("droidyue.com")//对应的代码
}
override fun provideDynamicHeaders(): Map<String, String> {
return HeaderUtils.createHeaders()
}
}
建立对应的HeaderDataResponder类
以添加datacollect.secoo.com
域名header信息为例
package com.secoo.commonsdk.http.headers.responder
import com.secoo.commonsdk.base.SecooApplication
import com.secoo.commonsdk.count.distinctId
import com.secoo.commonsdk.count.networkType
import com.secoo.commonsdk.http.headers.HeaderDataResponder
import com.secoo.commonsdk.http.headers.HeaderUtils
import com.secoo.commonsdk.ktx.*
import com.secoo.commonsdk.utils.DeviceUtils
object DataCollectHeaderDataResponder : HeaderDataResponder() {
private const val HEADER_DISTINCT_ID = "distinct_id"
private const val HEADER_APP_VERSION = "app_version"
private const val HEADER_DEVICE_MANUFACTURER = "manufacturer"
private const val HEADER_DEVICE_MODEL = "model"
private const val HEADER_DEVICE_OS_NAME = "os"
private const val HEADER_DEVICE_OS_VERSION = "os_version"
private const val HEADER_DEVICE_SCREEN_HEIGHT = "screen_height"
private const val HEADER_DEVICE_SCREEN_WIDTH = "screen_width"
private const val HEADER_DEVICE_MOBILE_CARRIER = "carrier"
private const val HEADER_NETWORK_TYPE = "network_type"
private const val HEADER_DEVICE_ID = "device_id"
//提供静态不变的header信息
override fun createStaticHeaders(): Map<String, String> {
return mapOf(
HEADER_APP_VERSION to appVersionName,
HEADER_DEVICE_MANUFACTURER to deviceManufacturer,
HEADER_DEVICE_MODEL to deviceModel,
HEADER_DEVICE_OS_NAME to "android",
HEADER_DEVICE_OS_VERSION to systemVersion.toString(),
HEADER_DEVICE_SCREEN_HEIGHT to screenHeight.toString(),
HEADER_DEVICE_SCREEN_WIDTH to screenWidth.toString(),
HEADER_DEVICE_MOBILE_CARRIER to mobileCarrier,
HEADER_DEVICE_ID to (DeviceUtils.getUUID(SecooApplication.getInstance()) ?:"")
)
}
//提供动态易变的header信息
override fun provideDynamicHeaders(): Map<String, String> {
return mutableMapOf(
HEADER_DISTINCT_ID to distinctId,
HEADER_NETWORK_TYPE to networkType
).plus(HeaderUtils.createHeaders())
}
//添加想要处理的host信息
override fun provideDomainsToRespond(): List<String> {
return listOf("datacollect.secoo.com")
}
}
添加到响应者队列
object RequestHeaderProvider {
/**
* 根据host遍历,提供header数据的响应者列表
*/
private val headerDataResponders = mutableListOf<HeaderDataResponder>()
init {
headerDataResponders.add(GeneralHeaderDataResponder)
//添加上面创建的DataCollectHeaderDataResponder
headerDataResponders.add(DataCollectHeaderDataResponder)
}
//.......
}
调试日志
adb logcat |grep --color=always -E "HeaderDataResponder|RequestHeaderProvider"
Header 过滤非法名称和值
-
目前我们使用的OkHttp 对于header的name和value有做非法数据校验
-
我们参考了OkHttp的实现,实现了一个简单的过滤非法字符的方法,即
filterValidHeaders
(HeaderExt.kt) -
上述方法
filterValidHeaders
在运行时如果发现有非法内容,会抛出异常,便于尽早发现问题。 -
尽量将
filterValidHeaders
调用处理在合适的时机。
注意
-
header信息中包含敏感内容,一定要慎重添加。
-
pic*.secooimg.com
由于会指向cdn,严禁增加敏感的header信息