package httpProxy;
import java.net.*;
import java.io.*;
public class ProcessThread extends Thread {
//父级服务线程,提供数据库日志
private MyProxy mp;
//客户端的输入流,提供头部信息的读取
private InputStream c_is;
//客户端的输出流
private OutputStream c_os;
//是否开启调试信息输出
private static boolean isDebug = true;
private Socket s;
public ProcessThread(Socket s, MyProxy mp) {
try {
this.c_is = s.getInputStream();
this.c_os = s.getOutputStream();
} catch (IOException e) {
if (isDebug)
e.printStackTrace();
}
this.s = s;
this.mp = mp;
}
public void run() {
// 新的转发逻辑,需要在从客户端收到信息的同时判断是否是请求头部
// 当没有s_os的情况下,将从c_is读取到的东西放入缓冲区,遇到"\r\n\r\n"时结束,并开始头部解析
StringBuffer buff = new StringBuffer();
StringBuffer sendBuff = new StringBuffer();
Socket s_s = null;
InputStream s_is=null;
OutputStream s_os=null;
try{
int bit = -1;
int ContentLength = 0;
boolean conttrans=false;//继续转发标志
//从客户端读取数据,退出则线程结束
outter:
while(true)
while((bit=c_is.read())>0){
if(conttrans){//继续转发标志
s_os.write(bit);
if(--ContentLength==0){
conttrans=false;
break;
}
}else{//否则载入缓冲区
buff.append((char)bit);
if(buff.indexOf("\r\n\r\n",buff.length()-4)>0){//判断信息头是否结束
//开始进行头部解析
String str = buff.toString();
if(isDebug)System.out.println("ReadHead:\n"+str);
String[] lines = str.split("\r\n");
String RemoteHost = "";
boolean needWriteHead=true;
int port = 80;
//for(String line:lines){//重新构造头部
for(int i=0;i<lines.length;i++){
String line=lines[i];
if(line.startsWith("GET ")){
String[] tmp = line.split(" ");
sendBuff.append(tmp[0]);
if(tmp[1].startsWith("http://")){
tmp[1] = tmp[1].substring(7);
tmp[1] = tmp[1].substring(tmp[1].indexOf('/'));
}
sendBuff.append(" "+tmp[1]+" "+tmp[2]+"\r\n");
}else if(line.startsWith("POST ")){
String[] tmp = line.split(" ");
sendBuff.append(tmp[0]);
if(tmp[1].startsWith("http://")){
tmp[1] = tmp[1].substring(7);
tmp[1] = tmp[1].substring(tmp[1].indexOf('/'));
}
sendBuff.append(" "+tmp[1]+" "+tmp[2]+"\r\n");
}else if(line.startsWith("Content-Length:")){
String[] tmp = line.split(" ");
sendBuff.append(line+"\r\n");
ContentLength=Integer.parseInt(tmp[1]);//设定继续发送的字节数
conttrans=true;//设置继续传送数据
}else if(line.startsWith("CONNECT")){
String tmp[] = line.split(" ");
RemoteHost = tmp[1];
if(RemoteHost.contains(":")){
tmp = RemoteHost.split(":");
RemoteHost = tmp[0];
port = Integer.parseInt(tmp[1]);
}
needWriteHead=false;//设定不需要写请求头
break;//不需要继续判断,直接启用新线程来互联
}else if(line.startsWith("Host: ")){
String tmp[] = line.split(" ");
RemoteHost = tmp[1];
if(RemoteHost.contains(":")){
tmp = RemoteHost.split(":");
RemoteHost = tmp[0];
port = Integer.parseInt(tmp[1]);
}
sendBuff.append(line+"\r\n");
}else if(line.startsWith("Proxy-")){
sendBuff.append(line.substring(6)+"\r\n");
}else{
sendBuff.append(line+"\r\n");
}
}
sendBuff.append("\r\n");
if(s_s!=null)s_s.close();
if(isDebug)System.out.println("Start to connect to "+RemoteHost +" Port:"+port);
mp.writeLog(s.getInetAddress().getHostAddress(), "CONNECT: " + RemoteHost);
s_s= new Socket(RemoteHost,port);
if(isDebug)System.out.println("Connect to "+RemoteHost +" OK");
s_is = s_s.getInputStream();
s_os = s_s.getOutputStream();
if(isDebug){
System.out.println("end of head conttrans :"+conttrans);
System.out.println("end of head needWriteHead :"+needWriteHead);
System.out.println("end of head ContentLength :"+ContentLength);
}
if(needWriteHead){
String sendstr=sendBuff.toString();
if(isDebug)System.out.println("WriteHead:\n"+sendstr);
s_os.write(sendstr.getBytes());
}
sendBuff.setLength(0);//清空缓冲
buff.setLength(0);
//启动传输线程,从s_is到c_os
DataTransThread srt = new DataTransThread(s_is,c_os);
srt.start();
if(!needWriteHead){
if(isDebug)System.out.println("Write response to client");
c_os.write("HTTP/1.1 200 OK \r\n\r\n".getBytes());
if(isDebug)System.out.println("Write response to client finish");
//启动传输线程 从c_is到s_os
DataTransThread sst = new DataTransThread(c_is,s_os);
sst.start();
break outter;
}
if(!conttrans)break;
}
}
}
}catch(IOException e){
if(isDebug)e.printStackTrace();
try{
c_os.write("HTTP/1.1 404 NOT FOUND \r\n\r\n".getBytes());
// TODO:工作不正常的话,这行需要移出
s.close();//关闭客户端的s会不会出错?
}catch (IOException e1){
e1.printStackTrace();
}
}
}
}
java写的目前最完美的http代理程序
4星 · 超过85%的资源 需积分: 43 136 浏览量
2009-02-18
17:04:28
上传
评论 3
收藏 16KB RAR 举报
sigarron
- 粉丝: 3
- 资源: 1
最新资源
- xyctf:从入门到精通的实用指南.zip
- mmqrcode1714153659780.png
- Screenshot_2024-04-27-06-08-58-486_com.baidu.xin.aiqicha.jpg
- 基于Javaweb+Tomcat+MySQL的大学生公寓管理系统+sql文件.zip
- 实训作业基于javaweb的订单管理系统源码+数据库+实训报告.zip
- 多机调度问题贪心算法基于最小堆和贪心算法求解多机调度问题.zip
- 基于同态加密技术的匿名电子投票系统源码.zip
- Pyqt5项目框架-PyQt项目开发实践
- 基于C通过MQTT的智能农业大棚管理系统(本科毕业设计)
- python+CNN的网络入侵检测算法源码.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
- 1
- 2
- 3
- 4
- 5
- 6
前往页