近来好多人亮相自已发出HTTP请求,我也正好也在做HTTP代理,还可以看看我写的一个文章也有关于HttpClient的内容
http://feixing2008.iteye.com/blog/569927
其中我没有使用HttpClient这个东西,我想更直接地透传数据。下边写了几个工具方法,引出内容。还有出遇到的一些问题。
public static byte[] getDataByInputStream(InputStream in)
throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] b = new byte[BUF_SIZE];
int len = 0;
while ((len = in.read(b, 0, BUF_SIZE)) != -1) {
baos.write(b, 0, len);
}
baos.flush();
byte[] bytes = baos.toByteArray();
return bytes;
}
上边的方法是从流中取出所有数据,放在数组中。BUF_SIZE常量自已设定,意义为缓冲区的大小。
在以上的基础上加增多一个方法
public static String getStrByInputStream(InputStream in, String outEncode) throws IOException{
byte[] btyStr = getDataByInputStream(in);
String str = new String(btyStr, outEncode);
return str;
}
这个方法主要是将响应的数据转成字符串。其中outEncode是字符器的编码。这里我要说一个问题
就是Content-Length这个头的主要含义是上边btye[]的长度,而不是String的length()的长度。
Content-Length反映了字节流的长度,这个受操作系统编码的影响。所以需要得到响应的编码形式。
继续再看看这个方法。
public static String getStrEveryLine(InputStream in, String encode)
throws IOException {
StringBuilder rs = new StringBuilder();
Scanner inScn = new Scanner(in);
String buf = "";
while(inScn.hasNextLine()){
buf = inScn.nextLine();
if(buf.length() < 1){
rs.append("\r\n");
break;
}
rs.append(buf);
rs.append("\r\n");
}
return rs.toString();
这个方法是是通过Scanner来处理流数据。本来使用getStrByInputStream这个方法好像已满足需求,其实非也,因为出现一个问题。
问题:
浏览器发出请求时,在完成请求头后关不会将socket关闭的,也就是说
in.read()是不会返回-1,只是线程会一直阻塞在那里。
再具体一点就是这样
GET / HTTP/1.0
Host: www.taobao.com
User-Agent: Mozilla/5.0 (X11; U; Linux i686; zh-CN; rv:1.9.0.11) Gecko/2009060308 Ubuntu/9.04 (jaunty) Firefox/3.0.11
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.5
Accept-Encoding: text/html
Accept-Charset: gb2312,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cookie: t=31d7b3ed1734e98759c7009c7cc5d492; cna=G2ZHBE1o0hUCATjEb3H2nl0g
<---------这里有个空行,读完这个空行再读的话会阻塞。所以读到这个空间就要跳出,不要再read
在请求头遇到这个情况还算好,因为可以通过一个空行可以发现头已经结束。
PS:不过这里还有个问题,如果是POST的话,在这个空行后边还是会有参数请求,这个时间就需要处理。然而我还没有实现。
在响应接收也是存在这个情况,这个问题更麻烦,因为是在响应数据流中读完一个字节流后阻塞,一般服务器是不会马上关闭Socket的,因为它不知你什么时间关闭,一般是等到10秒后才关闭。天吖,这个很影响我代理的性能。
其中一个解决方法是得到响应头的中Content-Length,再一次说明,这个头的值指的是字节流大小, 不是字符串大小。有了这个大小便可以根据大小读数据,知道何时数据已经完整,而不需要等服务器来关闭连接。
然而有时服务器是不会传Content-Length这个值。我也没有什么好方法,给合我代理的功能,我直接将流指向真实客服端的输出流当中。
BufferedInputStream bufIn = new BufferedInputStream(in);
ArrayList<Byte> bys = new ArrayList<Byte>();
BufferedOutputStream outBuf = new BufferedOutputStream(outToClient);
int c = 0;
int cCnt = 0;
while(( c = bufIn.read()) != -1){
++cCnt;
byte bc = (byte)c;
bys.add(bc);
outBuf.write(c);
if((cCnt % 256) == 0){
outBuf.flush();
}
}
outBuf.close();
这代码比较笨拙,其实不用细看,只是说明直接输到真实的客户端的输出流中。这个效率大大提升。
其中还有一个地方是线程池,这个是我需要改进的另一块,继续关注HTTP协议的相关开发。
分享到:
相关推荐
Java编写的HTTP代理,可以通过代理访问
局部,全局,代理,Sockts5,易语言源码,可以用易语言编译,局部代理和全局代理。
GoProxyPool是一款开源的基于Golang语言编写的代理池工具,可以自动化地获取、验证和维护可用的HTTP、HTTPS和SOCKS5代理,为应用程序提供高质量的代理服务。 GoProxyPool使用简单,可以通过配置文件或命令行参数来...
gost - Go语言编写多功能网络代理转发工具.zip
IE代理设置工具,VC编写,需要源码给我发邮件。
单击按钮获取工具获取WSDL,从WSDL生成.NET代理并显示可用方法列表。 用户可以选择任何方法并提供所需的输入参数。 在单击Invoke时,SOAP请求将发送到服务器,并解析响应以显示返回值。 此工具适用于Web服务实现者...
网络代理ip筛选工具, 使用的是swt进行代码的编写,进行数据ip的数据过滤
QT编写windowsIP切换工具代码,具有借鉴的价值,欢迎大家分享,谢谢!
文档与操作手册:为了方便他人理解和使用我的作品,我编写了详细的操作手册和使用说明,同时提供了一份Markdown格式的文档,概述了项目的主要功能和特点。 学习笔记:在项目开发过程中,我记录了大量的学习笔记和...
Stowaway是一个利用go语言编写,专为渗透测试工作者制作的多级代理工具 用户可使用此程序将外部流量通过多个代理至内网,突破内网访问限制,构造树状节点网络,并轻松实现管理功能 PS:谢谢大家的star,同时欢迎大家...
myprox.exe是由myprox.org编写的最新高速代理软件。本压缩包包含RUNmyprox.exe、myprox.exe、使用说明.txt、Microsoft.VC90.CRT。 這次更新了RUNmyprox.exe,修正了一點小BUG
Soxy-一种用于在Golang中检查开放式SOCKS代理的非常快速的工具,我一直在寻找一些开放式袜子代理,因此我需要对其进行测试-但速度非常快。 所以我在Go上写了! 安装如果您已经正确配置了GOPATH,并且$ GOPATH / bin...
【C语言HTTP代理服务器】是一个功能强大的工具,允许用户在网络中创建一个中介服务器,以便在客户端和目标服务器之间进行数据传输。本项目的源代码采用C语言编写,实现了HTTP代理服务器的核心功能,包括请求解析、...
Burp Suite不像其他的自动化测试工具,它需要你手工的去配置一些参数,触发一些自动化流程,然后它才会开始工作。 功能模块简介 Burp Target 组件主要包含站点地图、目标域、Target 工具三部分组成,他们帮助渗透...
OneForAll是一款由Python编写的子域名收集工具,它可以帮助安全测试人员和渗透测试人员自动化地获取目标网站相关的子域名信息。OneForAll在设计时兼顾了准确性和速度,可以通过多种方式进行子域名的发现,例如DNS...
PacketProxy是一种开放源代码代理工具,允许读取TCP / UDP通信。 它不仅限于HTTP。 它可以用于发展援助或风险评估。 屏幕截图 产品特点 功能齐全的本地代理工具 显示所有收到的数据包 通过关键字过滤/搜索数据包 ...
本文档的主要内容详细介绍的是ARM教程之ARM常用开发工具及相应开发环境配置资料说明包括了:ADS(ARM Developer Suite),IAR Embedded Workbench,KEIL FOR ARM 使用的配置都相对比较简单。 ...
python编写的工具,可以通过后台监控ip来定位发起访问的进程(包括父进程等)文件信息,可以用户终端偶发c&c通信杀毒找不到进程场景
基于图用go编写的分布式无代理配置和管理工具 这是我在 Go 中的第一个项目。 有一天gautomator应该是什么: 用于部署基础设施和/或分布式应用程序的二进制文件和配置的管道。 分布式配置和管理软件。 gautomator...