java实现轻量型http代理服务器示例
package cn.liangjintang.httpproxy;
import java.io.bufferedreader;
import java.io.bytearrayinputstream;
import java.io.ioexception;
import java.io.inputstream;
import java.io.inputstreamreader;
import java.io.outputstream;
import java.net.serversocket;
import java.net.socket;
public class httpproxy {
static long threadcount = 0;
int mytcpport = 8080;
private serversocket myserversocket;
private thread mythread;
public httpproxy(int port) throws ioexception {
mytcpport = port;
myserversocket = new serversocket(mytcpport);
mythread = new thread(new runnable() {
public void run() {
try {
while (true)
new httpsession(myserversocket.accept());
} catch (ioexception ioe) {
}
}
});
mythread.setdaemon(true);
mythread.start();
}
/**
* stops the server.
*/
public void stop() {
try {
myserversocket.close();
mythread.join();
} catch (ioexception ioe) {
} catch (interruptedexception e) {
}
}
public class httpsession implements runnable {
private socket mysocket;
public httpsession(socket s) {
mysocket = s;
thread t = new thread(this);
t.setdaemon(true);
t.start();
}
@override
public void run() {
try {
++threadcount;
inputstream is = mysocket.getinputstream();
if (is == null)
return;
final int bufsize = 8192;
byte[] buf = new byte[bufsize];
int splitbyte = 0;
int rlen = 0;
{
int read = is.read(buf, 0, bufsize);
while (read > 0) {
rlen += read;
splitbyte = findheaderend(buf, rlen);
if (splitbyte > 0)
break;
read = is.read(buf, rlen, bufsize - rlen);
}
bytearrayinputstream hbis = new bytearrayinputstream(buf,
0, rlen);
bufferedreader hin = new bufferedreader(
new inputstreamreader(hbis));
host host = new host();
{
string string;
boolean flag = false;
while ((string = hin.readline()) != null) {
if (string.tolowercase().startswith("host:")) {
host.host = string;
flag = true;
}
system.out.println(string);
}
if (!flag) {
mysocket.getoutputstream().write(
"error!".getbytes());
mysocket.close();
return;
}
}
host.cal();
system.out.println("address:[" + host.address + "]port:"
+ host.port + "\n-------------------\n");
try {
pipe(buf, rlen, mysocket, mysocket.getinputstream(),
mysocket.getoutputstream(), host);
} catch (exception e) {
system.out.println("run exception!");
e.printstacktrace();
}
}
} catch (exception e) {
}
system.out.println("threadcount:" + --threadcount);
}
/**
* finad http header
**/
private int findheaderend(final byte[] buf, int rlen) {
int splitbyte = 0;
while (splitbyte + 3 < rlen) {
if (buf[splitbyte] == '\r' && buf[splitbyte + 1] == '\n'
&& buf[splitbyte + 2] == '\r'
&& buf[splitbyte + 3] == '\n')
return splitbyte + 4;
splitbyte++;
}
return 0;
}
void pipe(byte[] request, int requestlen, socket client,
inputstream clientis, outputstream clientos, host host)
throws exception {
byte bytes[] = new byte[1024 * 32];
socket socket = new socket(host.address, host.port);
socket.setsotimeout(3000);
outputstream os = socket.getoutputstream();
inputstream is = socket.getinputstream();
try {
do {
os.write(request, 0, requestlen);
int resultlen = 0;
try {
while ((resultlen = is.read(bytes)) != -1
&& !mysocket.isclosed() && !socket.isclosed()) {
clientos.write(bytes, 0, resultlen);
}
} catch (exception e) {
system.out.println("target socket exception:"
+ e.tostring());
}
system.out.println("proxy requset-connect broken,socket:"
+ socket.hashcode());
} while (!mysocket.isclosed()
&& (requestlen = clientis.read(request)) != -1);
} catch (exception e) {
system.out.println("client socket exception:" + e.tostring());
}
system.out.println("end,socket:" + socket.hashcode());
os.close();
is.close();
clientis.close();
clientos.close();
socket.close();
mysocket.close();
}
// target host info
final class host {
public string address;
public int port;
public string host;
public boolean cal() {
if (host == null)
return false;
int start = host.indexof(": ");
if (start == -1)
return false;
int next = host.indexof(':', start + 2);
if (next == -1) {
port = 80;
address = host.substring(start + 2);
} else {
address = host.substring(start + 2, next);
port = integer.valueof(host.substring(next + 1));
}
return true;
}
}
}
public static void main(string[] args) {
try {
new httpproxy(8580);
} catch (ioexception ioe) {
system.err.println("couldn't start server:\n" + ioe);
system.exit(-1);
}
system.out.println("start!");
try {
system.in.read();
} catch (throwable t) {
}
system.out.println("stop!");
}
}