大家都知道大名鼎鼎的BurpSuite代理神器,对于抓取HTTP请求非常好用,偶然,一朋友问我Java应该如何去编写代理服务器(因为他想做某些东西),有没有相关的API 去实现,我想说,差不多你能想到的,JAVA都可以做到,没有任何一门成熟的语言是垃圾的。
图1-1 Java代理示意图
那么Java就处于中间这层代理服务器,代理服务器所作的事情如下:
1、接收客户端请求,进行处理,然后发送给服务端
2、接收服务端响应,进行处理,然后发送给客户端
这样,就更清晰了,Java给我们提供了代理的API为,java.net.Proxy类。此类表示代理设置,通常为类型(http、socks)和套接字地址。Proxy 是不可变对象。
也就是说Java可以制作高级协议的代理,如 HTTP 或 FTP。也可以制作SOCKS(V4 或 V5)代理。
在基本的概念说完之后,来实际操作一把,分为两个步骤,第一部分,让JAVA程序使用代理服务器,第二步部分,让我们的Java程序像BurpSuite一样,来做一个HTTP的代理服务器吧。
首先,使用到了URL类,HttpURLConnection类及其我们的代理类Proxy类。他们都位于java.net包中。
第一步:生成代理,指定端口为8888:
第二步:使用URLConnection类进行连接www.moonsos.com
图1-2 java使用代理服务器
完整代码示例如下:
图1-3 配置代理服务器
OK,配置完毕,进行访问http://www.moonsos.com,可以发现我们写的小程序已经能够进行抓取到HTTP协议信息,如图1-4所示。
图1-4 抓取浏览器 HTTP 请求信息
当获取HTTP请求之后,我想后面的东西就不用说了吧。无非就是对HTTP请求进行分析,封装。然后在时候Socket发送。获取到信息之后,在使用当前的Socket以打印流的方式输出到浏览器。
![\](http://www.moonsos.com/uploadfile/2013/1230/20131230092751511.jpg)
图1-1 Java代理示意图
那么Java就处于中间这层代理服务器,代理服务器所作的事情如下:
1、接收客户端请求,进行处理,然后发送给服务端
2、接收服务端响应,进行处理,然后发送给客户端
这样,就更清晰了,Java给我们提供了代理的API为,java.net.Proxy类。此类表示代理设置,通常为类型(http、socks)和套接字地址。Proxy 是不可变对象。
也就是说Java可以制作高级协议的代理,如 HTTP 或 FTP。也可以制作SOCKS(V4 或 V5)代理。
在基本的概念说完之后,来实际操作一把,分为两个步骤,第一部分,让JAVA程序使用代理服务器,第二步部分,让我们的Java程序像BurpSuite一样,来做一个HTTP的代理服务器吧。
首先,使用到了URL类,HttpURLConnection类及其我们的代理类Proxy类。他们都位于java.net包中。
第一步:生成代理,指定端口为8888:
1 | Proxy proxy = null ; |
2 | proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress( "127.0.0.1" , 8888 )); // 实例化本地代理对象,端口为8888 |
第二步:使用URLConnection类进行连接www.moonsos.com
1 | URL url = new URL( "http://www.moonsos.com" ); //实例化米安网URL类 |
2 | HttpURLConnection action = (HttpURLConnection)url.openConnection(proxy); //使用代理打开网页 |
第三步:打开URL,并且读取HTML源码
01 | HttpURLConnection action = (HttpURLConnection)url.openConnection(proxy); //使用代理打开网页 |
02 | InputStream in = action.getInputStream(); |
03 | BufferedReader br = new BufferedReader( new InputStreamReader(in, "UTF-8" )); |
04 | StringBuilder sb = new StringBuilder(); |
05 | String lin = System.getProperty( "line.separator" ) ; |
06 | for (String temp = br.readLine() ; temp!= null ;temp = br.readLine() ){ |
07 | sb.append(temp+lin); |
08 | } |
09 | br.close(); |
10 | in.close(); |
11 | System.out.println(sb); |
效果执行图,如图1-2所示。
![\](http://www.moonsos.com/uploadfile/2013/1230/20131230093053556.jpg)
图1-2 java使用代理服务器
完整代码示例如下:
01 | import java.net.* ; |
02 | import java.io.* ; |
03 | public class ProxyTest{ |
04 | public static void main(String args[]) throws Exception{ |
05 | Proxy proxy = null ; |
06 |
07 | proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress( "127.0.0.1" , 8888 )); // 实例化本地代理对象,端口为8888 |
08 | |
09 | URL url = new URL( "http://www.moonsos.com" ); |
10 | HttpURLConnection action = (HttpURLConnection)url.openConnection(proxy); //使用代理打开网页 |
11 | |
12 | InputStream in = action.getInputStream(); |
13 | |
14 | BufferedReader br = new BufferedReader( new InputStreamReader(in, "UTF-8" )); |
15 | StringBuilder sb = new StringBuilder(); |
16 | String lin = System.getProperty( "line.separator" ) ; |
17 | for (String temp = br.readLine() ; temp!= null ;temp = br.readLine() ){ |
18 | |
19 | sb.append(temp+lin); |
20 | |
21 | } |
22 |
23 | br.close(); |
24 | in.close(); |
25 | System.out.println(sb); |
26 | } |
27 | } |
第一部分我们学会了Java如何使用代理程序,那么第二部分就看Java制作代理服务器。
第一步,生成Socket类,作为代理服务器
1 | ServerSocket server = new ServerSocket( 8888 ); //建立本地代理服务器,端口为8888 |
第二步,等待连接,也就是等待使用代理程序的用户进入,如果没有用户进入那么,将会一直在此等待。
1 | Socket socket =server. accept(); //等待客户端连接 |
第三步,当用户进来后,查看用户数据发送的请求,这里新做了一个ActionScoket类,多线程,专门用来处理Scoket输入流,代码如下所所示。
01 | ServerSocket server = new ServerSocket( 8888 ); |
02 | while ( true ){ |
03 | Socket socket = server.accept(); |
04 | ActionSocket ap = new ActionSocket(socket); |
05 | ap.start(); |
06 | } |
07 | ActionSocket代码如下: |
08 | class ActionSocket extends Thread{ |
09 | private Socket socket = null ; |
10 | public ActionSocket(Socket s){ |
11 | this .socket = s ; |
12 | } |
13 | public void run(){ |
14 | try { |
15 | this .action() ; |
16 | } catch (Exception e){ |
17 | e.printStackTrace(); |
18 | } |
19 | } |
20 |
21 | public void action() throws Exception { |
22 | |
23 | if ( this .socket == null ){ |
24 | return ; |
25 | } |
26 | |
27 | BufferedReader br = new BufferedReader( new InputStreamReader( this .socket.getInputStream())); |
28 | for (String temp = br.readLine() ; temp!= null ;temp = br.readLine() ){ |
29 | |
30 | System.out.println(temp); |
31 | } |
32 |
33 | br.close(); |
34 | } |
35 | } |
完整代码如下:
01 | import java.net.* ; |
02 | import java.io.* ; |
03 |
04 | class ActionSocket extends Thread{ |
05 | private Socket socket = null ; |
06 | public ActionSocket(Socket s){ |
07 | this .socket = s ; |
08 | } |
09 | public void run(){ |
10 | try { |
11 | this .action() ; |
12 | } catch (Exception e){ |
13 | e.printStackTrace(); |
14 | } |
15 | } |
16 | public void action() throws Exception { |
17 | |
18 | if ( this .socket == null ){ |
19 | return ; |
20 | } |
21 | |
22 | BufferedReader br = new BufferedReader( new InputStreamReader( this .socket.getInputStream())); |
23 | for (String temp = br.readLine() ; temp!= null ;temp = br.readLine() ){ |
24 | |
25 | System.out.println(temp); |
26 | } |
27 |
28 | br.close(); |
29 | } |
30 | } |
31 |
32 |
33 |
34 | public class ServerPrxoy{ |
35 | public static void main(String args[]) throws Exception{ |
36 | ServerSocket server = new ServerSocket( 8888 ); |
37 | while ( true ){ |
38 | Socket socket = server.accept(); |
39 | ActionSocket ap = new ActionSocket(socket); |
40 | ap.start(); |
41 | } |
42 | } |
43 | } |
给火狐,搜狗等浏览器配置代理,如图1-3所示:
![\](http://www.moonsos.com/uploadfile/2013/1230/20131230093407255.jpg)
图1-3 配置代理服务器
OK,配置完毕,进行访问http://www.moonsos.com,可以发现我们写的小程序已经能够进行抓取到HTTP协议信息,如图1-4所示。
![\](http://www.moonsos.com/uploadfile/2013/1230/20131230093506152.jpg)
图1-4 抓取浏览器 HTTP 请求信息
当获取HTTP请求之后,我想后面的东西就不用说了吧。无非就是对HTTP请求进行分析,封装。然后在时候Socket发送。获取到信息之后,在使用当前的Socket以打印流的方式输出到浏览器。