JAVA实现网络请求代理之HTTP篇 (一)
JAVA实现网络请求代理之Socket篇(二)
Java代理服务器之截取,篡改HTTP请求(应用篇)
说到篡改请求,其实就是篡改底层的一些数据包,就是替换数据包里面的一些数据而已。
前面我们开发了一个HTTP代理服务器,在里面我们是通过转发的方式来实现的,说白了,就是所有的数据都经过了这个代理服务器进行转发,既然数据都了我们的手上了,那么截取,发到别的地方,或者篡改,还不是手到擒来的事。
下面我就实现一个简单的篡改功能,希望大家举一反三。对大家的学习有帮助。
看过HTTP请求代理服务器博文的同学继续往下面看,没看过的同学请先看那片博文。
首先我们需要一个Map<String,String> ,这个里面保存的就是我们需要替换的字符串,其中Key代表原本的字符串,value代表需要替换的字符串。
这个私有对象是保存在 HTTPServerThread 类里面的
private static Map<String, String> filter = new HashMap<String, String>();
还有就是添加一个替换的方法,和一个设置上面map 的方法
/** * 替换数据 - 篡改数据 * @param buf */ private byte[] replease(byte[] buf) { String tmp = new String(buf); for (String key : filter.keySet()) { if(tmp.contains(key)) { tmp=tmp.replace(key,filter.get(key)); } } return tmp.getBytes(); } public static void put(String str, String rep) { filter.put(str, rep); }
然后就是改造我们的doGet方法,将我们的replease方法加进去
/** * 处理GET请求 * @param buf 缓冲区 * @param creadlen 客户端读取buf的长度 * @param sin 服务端输入流 * @param cout 客户端输出流 * @param sout 服务端输出流 * @return * @throws IOException */ private int doGet(byte[] buf, int creadlen, DataInputStream sin, DataOutputStream cout, DataOutputStream sout) throws IOException { int sreadlen;// 如读到 GET 请求,向外网发出 GET 请求 System.out.println("[get] >> " + new String(buf)); write(buf, creadlen, sout); while ((sreadlen = sin.read(buf, 0, 10000))!=-1) { // 循环 try { if (sreadlen > 0) { //替换内容 byte [] tmp = replease(buf); write(tmp, tmp.length, cout); } } catch (Exception e) { break; } // 异常则退出 } return sreadlen; }
接下来替换post方法
/** * 处理POST 请求 * @param buf 数据缓存区 * @param creadlen 客户端读取的buf的长度 * @param sreadlen 服务端读取的buf的长度 * @param cin 客户端输入流 * @param sin 服务端输入流 * @param cout 客户端输出流 * @param sout 服务端输出流 * @throws IOException */ private void doPost(byte[] buf, int creadlen, int sreadlen, DataInputStream cin, DataInputStream sin, DataOutputStream cout, DataOutputStream sout) throws IOException { write(buf, creadlen, sout); // 建立线程 , 用于从外网读数据 , 并返回给内网客户端 HTTPChannel thread1 = new HTTPChannel(sin, cout); while ((sreadlen = cin.read(buf, 0, 10000))!=-1) { // 循环 try { System.out.println("post>>"+new String(buf)); if (sreadlen > 0) { // 读到数据 , 则发送给外网 write(replease(buf), sreadlen, sout); } } catch (Exception e1) { break; } } }
到现在为止,我们就可以替换请求数据包里面的数据了
需要替换什么直接put到Map里面就可以了。
至于截取数据包转发到其地址,就是在发送数据的时候,顺带发一份到其他的地址,还是很简单的,就留给你们自己实现咯。