UrlConnectionTransformer.kt 2.2 KB
Newer Older
J
jackjintai 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
package com.didichuxing.doraemonkit.plugin.transform

import com.didichuxing.doraemonkit.plugin.DoKitExtUtil
import com.didiglobal.booster.annotations.Priority
import com.didiglobal.booster.kotlinx.asIterable
import com.didiglobal.booster.kotlinx.file
import com.didiglobal.booster.kotlinx.touch
import com.didiglobal.booster.transform.TransformContext
import com.didiglobal.booster.transform.asm.ClassTransformer
import com.didiglobal.booster.transform.asm.className
import com.google.auto.service.AutoService
import org.objectweb.asm.Opcodes.INVOKESTATIC
import org.objectweb.asm.Opcodes.INVOKEVIRTUAL
import org.objectweb.asm.tree.ClassNode
import org.objectweb.asm.tree.MethodInsnNode
import org.objectweb.asm.tree.MethodNode
import java.io.PrintWriter

/**
 * ================================================
 * 作    者:jint(金台)
 * 版    本:1.0
 * 创建日期:2020/5/14-18:07
 * 描    述:wiki:https://juejin.im/post/5e8d87c4f265da47ad218e6b
 * 修订历史:
 * ================================================
 */
@Priority(1)
@AutoService(ClassTransformer::class)
class UrlConnectionTransformer : ClassTransformer {


    override fun transform(context: TransformContext, klass: ClassNode): ClassNode {
        if (!DoKitExtUtil.dokitPluginSwitchOpen()) {
            return klass
        }

        if (DoKitExtUtil.ignorePackageNames(klass.className)) {
            return klass
        }


        if (DoKitExtUtil.commExt.networkSwitch) {
            klass.methods.forEach { method ->
                method.instructions?.iterator()?.asIterable()?.filterIsInstance(MethodInsnNode::class.java)?.filter {
                    it.opcode == INVOKEVIRTUAL &&
                            it.owner == "java/net/URL" &&
                            it.name == "openConnection" &&
                            it.desc == "()Ljava/net/URLConnection;"
                }?.forEach {
                    method.instructions.insert(it, MethodInsnNode(INVOKESTATIC, SHADOW_URL, "proxy", "(Ljava/net/URLConnection;)Ljava/net/URLConnection;", false))
                }
            }
        }
        return klass
    }
}

private const val SHADOW_URL = "com/didichuxing/doraemonkit/aop/urlconnection/HttpUrlConnectionProxyUtil"