SocketChannel clientSocket;
SocketChannel remoteSocket;
Selector selector;
SelectionKey clientkey;
SelectionKey remotekey;
Charset charset;
CharsetEncoder encoder;
CharsetDecoder decoder;
ByteBuffer buffer;
int bytesread = 0;
String header = "";
int protocolStatus = 0;
public static final int START = 0;
public static final int CONNECT_HEADER_RECEIVING = 1;
public static final int REDIRECTING_TRAFFIC = 2;
public static final int CLOSED = 3;
public Acceptor(SocketChannel clientSocket) {
super("Client[" + clientSocket.socket().getLocalPort() + "]");
try {
charset = Charset.forName("UTF-8");
encoder = charset.newEncoder();
decoder = charset.newDecoder();
buffer = ByteBuffer.allocate(1024);
selector = Selector.open();
this.clientSocket = clientSocket;
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void run() {
try {
clientkey = clientSocket.register(selector, SelectionKey.OP_READ);
remotekey = null;
protocolStatus = START;
protocolStatus = CONNECT_HEADER_RECEIVING;
for (;;) {
selector.select();
Set<SelectionKey> keys = selector.selectedKeys();
for (Iterator<SelectionKey> i = keys.iterator(); i.hasNext();) {
SelectionKey key = (SelectionKey) i.next();
i.remove();
if (protocolStatus == CLOSED) { return; }
if (key == clientkey) {
if (!key.isReadable()) {
continue;
}
try {
bytesread = clientSocket.read(buffer);
} catch (IOException e) {
close();
continue;
}
if (bytesread == -1) {
close();
continue;
}
buffer.flip();
try {
clientDataRead();
} catch (Exception e) {
e.printStackTrace();
}
buffer.clear();
}
if (key == remotekey) {
if (!key.isReadable()) {
continue;
}
try {
bytesread = remoteSocket.read(buffer);
} catch (IOException e) {
close();
continue;
}
if (bytesread == -1) {
close();
continue;
}
buffer.flip();
try {
remoteDataRead();
} catch (Exception e) {
e.printStackTrace();
}
buffer.clear();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void close() throws IOException {
if (remoteSocket != null) {
remoteSocket.close();
}
if (remotekey != null) {
remotekey.cancel();
}
clientkey.cancel();
clientkey = null;
remotekey = null;
protocolStatus = CLOSED;
}
public void clientDataRead() throws Exception {
if (protocolStatus == CONNECT_HEADER_RECEIVING) {
handleRequest(decoder.decode(buffer).toString());
} else if (protocolStatus == REDIRECTING_TRAFFIC) {
if (remotekey != null) {
if (!remoteSocket.socket().isClosed()) {
remoteSocket.write(buffer);
}
}
}
}
public void handleRequest(String request) throws IOException {
if (request.indexOf(";") < 0) {
header += request;
} else {
String data = request.substring(request.indexOf(";") + 1);
header += request.substring(0, request.indexOf(";"));
header.replace("&&", "&");
header.replace("&s", ";");
handleHeader();
if (data.length() > 0) {
try {
} catch (Exception e) {
}
clientSocket.write(encoder.encode(CharBuffer.wrap(data)));
}
}
}
public void handleHeader() throws IOException {
if (header.startsWith("CONNECT")) {
String[] parts = header.split(" ");
String host = parts[1].trim();
int port = 0;
if (host.indexOf(":") >= 0) {
port = Integer.parseInt(host.substring(host.indexOf(":") + 1));
host = host.substring(0, host.indexOf(":"));
}
remoteSocket = SocketChannel.open(new InetSocketAddress(host, port));
remoteSocket.configureBlocking(false);
remotekey = remoteSocket.register(selector, SelectionKey.OP_READ);
String command = "200 Connection established;";
try {
} catch (Exception e) {
}
clientSocket.write(encoder.encode(CharBuffer.wrap(command)));
protocolStatus = REDIRECTING_TRAFFIC;
} else if (header.startsWith("PING")) {
String command = "100 Proxy Service available;\n";
try {
} catch (Exception e) {
}
clientSocket.write(encoder.encode(CharBuffer.wrap(command)));
protocolStatus = CLOSED;
close();
}
}
public void remoteDataRead() throws IOException {
if (!clientSocket.socket().isClosed()) {
try {
} catch (Exception e) {
}
clientSocket.write(buffer);
} else {
close();
}
}