如何劫持Java應用的HTTP請求
背景
全鏈路追蹤中,針對部分特殊的流量,希望將它引導到特定服務上(這個特定服務不在正常請求的鏈路上)——問題可以被抽象為解決進程間通信過程中目標進程的選擇。
進程間通信方式很多,本篇只關注 Java 進程間套接字通信下 HTTP 形式的請求劫持,引導特定流量到特定進程。
解決方案
可行的處理方案繁多。自頂向下從應用、框架、JVM、Container Runtime、System Call、網(wǎng)絡協(xié)議棧等級別,均可著手解決。侵入性最強的操作就是要求所有業(yè)務應用都主動實現(xiàn) HTTP 請求分流邏輯;次一級是提供二方庫供業(yè)務應用主動集成;或者從系統(tǒng)層面進行改造,基于改寫系統(tǒng)調用對請求進行劫持。
回顧兩年前的所學,JVM TI 為劫持 HTTP 請求提供了一個全新的解決思路。通過 Agent 改寫應用啟動時加載的類的字節(jié)碼,劫持類的實例并完成目標功能。
由于 Java 項目間調用大量的使用了 Apache 的 http-client 庫,改寫變得相當簡單。識別流量,并對特定流量改寫請求的 Host 即可。
Demo
由于 http-client 對所有請求目標都統(tǒng)一由 org.apache.http.HttpHost 維護,控制變得極為簡單。只需在 HttpHost 實例化時,改寫類的構造方法,即完成了對目標的劫持工作(下例中強制將所有請求指向 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應用的HTTP請求的詳細內容,更多關于劫持Java應用的HTTP請求的資料請關注腳本之家其它相關文章!
相關文章
SpringBoot如何通過自定義注解實現(xiàn)權限檢查詳解
這篇文章主要給大家介紹了關于SpringBoot如何通過自定義注解實現(xiàn)權限檢查的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-10-10
springboot3.2整合mybatis-plus詳細代碼示例
這篇文章主要給大家介紹了關于springboot3.2整合mybatis-plus的相關資料,Spring Boot是一個非常流行的Java Web框架,可以快速地搭建Web應用程序,需要的朋友可以參考下2023-12-12
springboot+Oauth2實現(xiàn)自定義AuthenticationManager和認證path
本篇文章主要介紹了springboot+Oauth2實現(xiàn)自定義AuthenticationManager和認證path,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-09-09
Java實現(xiàn)創(chuàng)建運行時類的對象操作示例
這篇文章主要介紹了Java實現(xiàn)創(chuàng)建運行時類的對象操作,結合實例形式分析了Java動態(tài)創(chuàng)建對象的原理與相關實現(xiàn)技巧,需要的朋友可以參考下2018-08-08
IDEA 項目創(chuàng)建Mapper的xml文件的方法
這篇文章主要介紹了IDEA 項目創(chuàng)建Mapper的xml文件的方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-11-11
SpringBoot中@PostConstruct 注解的實現(xiàn)
在Spring Boot框架中,?@PostConstruct是一個非常有用的注解,它用于在依賴注入完成后執(zhí)行初始化方法,本文將介紹?@PostConstruct的基本概念、使用場景以及提供詳細的代碼示例,感興趣的可以了解一下2024-09-09
Spring Boot中利用JavaMailSender發(fā)送郵件的方法示例(附源碼)
這篇文章主要介紹了Spring Boot中利用JavaMailSender發(fā)送郵件的方法示例, 相信使用過Spring的眾多開發(fā)者都知道Spring提供了非常好用的JavaMailSender接口實現(xiàn)郵件發(fā)送。在Spring Boot的Starter模塊中也為此提供了自動化配置。需要的朋友可以參考借鑒。2017-02-02

