/*************************************
* 一个基础的代理服务器类
*************************************
*/
import java.net.*;
import java.io.*;
public class httpproxy extends thread {
static public int connect_retries=5;
static public int connect_pause=5;
static public int timeout=50;
static public int bufsiz=1024;
static public boolean logging = false;
static public outputstream log=null;
// 传入数据用的socket
protected socket socket;
// 上级代理服务器,可选
static private string parent=null;
static private int parentport=-1;
static public void setparentproxy(string name, int pport) {
parent=name;
parentport=pport;
}
// 在给定socket上创建一个代理线程。
public httpproxy(socket s) { socket=s; start(); }
public void writelog(int c, boolean browser) throws ioexception {
log.write(c);
}
public void writelog(byte[] bytes,int offset, int len, boolean browser) throws ioexception {
for (int i=0;i<len;i++) writelog((int)bytes[offset+i],browser);
}
// 默认情况下,日志信息输出到
// 标准输出设备
// 派生类可以覆盖它
public string processhostname(string url, string host, int port, socket sock) {
java.text.dateformat cal=java.text.dateformat.getdatetimeinstance();
system.out.println(cal.format(new java.util.date()) + " - " + url + " "
+ sock.getinetaddress()+"/n");
return host;
}
// 执行操作的线程
public void run() {
string line;
string host;
int port=80;
socket outbound=null;
try {
socket.setsotimeout(timeout);
inputstream is=socket.getinputstream();
outputstream os=null;
try {
// 获取请求行的内容
line="";
host="";
int state=0;
boolean space;
while (true) {
int c=is.read();
if (c==-1) break;
if (logging) writelog(c,true);
space=character.iswhitespace((char)c);
switch (state) {
case 0:
if (space) continue;
state=1;
case 1:
if (space) {
state=2;
continue;
}
line=line+(char)c;
break;
case 2:
if (space) continue; // 跳过多个空白字符
state=3;
case 3:
if (space) {
state=4;
// 只取出主机名称部分
string host0=host;
int n;
n=host.indexof("//");
if (n!=-1) host=host.substring(n+2);
n=host.indexof('/');
if (n!=-1) host=host.substring(0,n);
// 分析可能存在的端口号
n=host.indexof(":");
if (n!=-1) {
port=integer.parseint(host.substring(n+1));
host=host.substring(0,n);
}
host=processhostname(host0,host,port,socket);
if (parent!=null) {
host=parent;
port=parentport;
}
int retry=connect_retries;
while (retry--!=0) {
try {
outbound=new socket(host,port);
break;
} catch (exception e) { }
// 等待
thread.sleep(connect_pause);
}
if (outbound==null) break;
outbound.setsotimeout(timeout);
os=outbound.getoutputstream();
os.write(line.getbytes());
os.write(' ');
os.write(host0.getbytes());
os.write(' ');
pipe(is,outbound.getinputstream(),os,socket.getoutputstream());
break;
}
host=host+(char)c;
break;
}
}
}
catch (ioexception e) { }
} catch (exception e) { }
finally {
try { socket.close();} catch (exception e1) {}
try { outbound.close();} catch (exception e2) {}
}
}
void pipe(inputstream is0, inputstream is1,
outputstream os0, outputstream os1) throws ioexception {
try {
int ir;
byte bytes[]=new byte[bufsiz];
while (true) {
try {
if ((ir=is0.read(bytes))>0) {
os0.write(bytes,0,ir);
if (logging) writelog(bytes,0,ir,true);
}
else if (ir<0)
break;
} catch (interruptedioexception e) { }
try {
if ((ir=is1.read(bytes))>0) {
os1.write(bytes,0,ir);
if (logging) writelog(bytes,0,ir,false);
}
else if (ir<0)
break;
} catch (interruptedioexception e) { }
}
} catch (exception e0) {
system.out.println("pipe异常: " + e0);
}
}
static public void startproxy(int port,class clobj) {
serversocket ssock;
socket sock;
try {
ssock=new serversocket(port);
while (true) {
class [] sarg = new class[1];
object [] arg= new object[1];
sarg[0]=socket.class;
try {
java.lang.reflect.constructor cons = clobj.getdeclaredconstructor(sarg);
arg[0]=ssock.accept();
cons.newinstance(arg); // 创建httpproxy或其派生类的实例
} catch (exception e) {
socket esock = (socket)arg[0];
try { esock.close(); } catch (exception ec) {}
}
}
} catch (ioexception e) {
}
}
// 测试用的简单main方法
static public void main(string args[]) {
system.out.println("在端口8080启动代理服务器/n");
httpproxy.log=system.out;
httpproxy.logging=false;
httpproxy.startproxy(8080,httpproxy.class);
}
}
闽公网安备 35060202000074号