如何劫持Java應(yīng)用的HTTP請求
背景
全鏈路追蹤中,針對部分特殊的流量,希望將它引導(dǎo)到特定服務(wù)上(這個特定服務(wù)不在正常請求的鏈路上)——問題可以被抽象為解決進(jìn)程間通信過程中目標(biāo)進(jìn)程的選擇。
進(jìn)程間通信方式很多,本篇只關(guān)注 Java 進(jìn)程間套接字通信下 HTTP 形式的請求劫持,引導(dǎo)特定流量到特定進(jìn)程。
解決方案
可行的處理方案繁多。自頂向下從應(yīng)用、框架、JVM、Container Runtime、System Call、網(wǎng)絡(luò)協(xié)議棧等級別,均可著手解決。侵入性最強(qiáng)的操作就是要求所有業(yè)務(wù)應(yīng)用都主動實現(xiàn) HTTP 請求分流邏輯;次一級是提供二方庫供業(yè)務(wù)應(yīng)用主動集成;或者從系統(tǒng)層面進(jìn)行改造,基于改寫系統(tǒng)調(diào)用對請求進(jìn)行劫持。
回顧兩年前的所學(xué),JVM TI 為劫持 HTTP 請求提供了一個全新的解決思路。通過 Agent 改寫應(yīng)用啟動時加載的類的字節(jié)碼,劫持類的實例并完成目標(biāo)功能。
由于 Java 項目間調(diào)用大量的使用了 Apache 的 http-client 庫,改寫變得相當(dāng)簡單。識別流量,并對特定流量改寫請求的 Host 即可。
Demo
由于 http-client 對所有請求目標(biāo)都統(tǒng)一由 org.apache.http.HttpHost 維護(hù),控制變得極為簡單。只需在 HttpHost 實例化時,改寫類的構(gòu)造方法,即完成了對目標(biāo)的劫持工作(下例中強(qiáng)制將所有請求指向 163.com)
public class Agent implements ClassFileTransformer {
public static void premain(String args, Instrumentation instrumentation) {
instrumentation.addTransformer(new Agent());
}
@Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
if ("org/apache/http/HttpHost".equals(className)) {
ClassPool pool = ClassPool.getDefault();
try {
CtClass httpHost = pool.get("org.apache.http.HttpHost");
CtClass string = pool.get("java.lang.String");
CtConstructor constructor = httpHost.getDeclaredConstructor(new CtClass[]{string, CtClass.intType, string});
constructor.insertBefore("hostname = \"www.163.com\";");
byte[] bytes = httpHost.toBytecode();
FileOutputStream fos = new FileOutputStream("/Users/fangfeng/a.class");
fos.write(bytes);
return bytes;
} catch(NotFoundException | CannotCompileException | IOException e){
e.printStackTrace();
}
}
return classfileBuffer;
}
}
將整個項目打包為 agent.jar 的過程不做太多介紹,詳見 ffutop/http-client-plugin
針對需要劫持的項目,在啟動參數(shù)中增加 -javaagent:${PATH_TO}/http-client-plugin.jar
以上就是如何劫持Java應(yīng)用的HTTP請求的詳細(xì)內(nèi)容,更多關(guān)于劫持Java應(yīng)用的HTTP請求的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Mybatis配置之<typeAliases>別名配置元素解析
這篇文章主要介紹了Mybatis配置之<typeAliases>別名配置元素解析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07
Arthas排查Kubernetes中應(yīng)用頻繁掛掉重啟異常
這篇文章主要為大家介紹了Arthas排查Kubernetes中應(yīng)用頻繁掛掉重啟的異常分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助祝大家多多進(jìn)步2022-02-02
SpringMVC中controller接收json數(shù)據(jù)的方法
這篇文章主要為大家詳細(xì)介紹了SpringMVC中controller接收json數(shù)據(jù)的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-09-09
Java位集合之BitMap、BitSet和布隆過濾器示例解析
這篇文章主要介紹了Java中位集合的基本概念、實現(xiàn)方法以及應(yīng)用場景,包括Bit-Map、BitSet和BloomFilter,Bit-Map通過位操作高效地存儲和查詢元素狀態(tài),文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-12-12
詳解springboot?springsecuroty中的注銷和權(quán)限控制問題
這篇文章主要介紹了springboot-springsecuroty?注銷和權(quán)限控制,賬戶注銷需要在SecurityConfig中加入開啟注銷功能的代碼,權(quán)限控制要導(dǎo)入springsecurity和thymeleaf的整合依賴,本文通過實例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧2022-03-03
java如何實現(xiàn)基于opencv全景圖合成實例代碼
全景圖相信大家應(yīng)該都不陌生,下面這篇文章主要給大家介紹了關(guān)于java如何實現(xiàn)基于opencv全景圖合成的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-07-07

