import java.net.InetSocketAddress; import org.apache.mina.core.service.IoConnector; import org.apache.mina.transport.socket.nio.NioSocketAcceptor; import org.apache.mina.transport.socket.nio.NioSocketConnector; /** * (<b>Entry point</b>) Demonstrates how to write a very simple tunneling proxy * using MINA. The proxy only logs all data passing through it. This is only * suitable for text based protocols since received data will be converted into * strings before being logged. * <p> * Start a proxy like this:<br/> * <code>org.apache.mina.example.proxy.Main 12345 www.google.com 80</code><br/> * and open <a href="http://localhost:12345">http://localhost:12345</a> in a * browser window. * </p> * * @author The Apache MINA Project ([email protected]) * @version $Rev$, $Date$ */ public class Main { public static void main(String[] args) throws Exception { if (args.length != 3) { System.out.println(Main.class.getName() + " <proxy-port> <server-hostname> <server-port>"); return; } // Create TCP/IP acceptor. NioSocketAcceptor acceptor = new NioSocketAcceptor(); // Create TCP/IP connector. IoConnector connector = new NioSocketConnector(); // Set connect timeout. connector.setConnectTimeoutMillis(30*1000L); ClientToProxyIoHandler handler = new ClientToProxyIoHandler(connector, new InetSocketAddress(args[1], Integer.parseInt(args[2]))); // Start proxy. acceptor.setHandler(handler); acceptor.bind(new InetSocketAddress(Integer.parseInt(args[0]))); System.out.println("Listening on port " + Integer.parseInt(args[0])); } }
/** * Handles the server to proxy part of the proxied connection. * * @author The Apache MINA Project ([email protected]) * @version $Rev$, $Date$ * */ public class ServerToProxyIoHandler extends AbstractProxyIoHandler { }
import java.nio.charset.Charset; import org.apache.mina.core.buffer.IoBuffer; import org.apache.mina.core.service.IoHandlerAdapter; import org.apache.mina.core.session.IoSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Base class of {@link org.apache.mina.core.service.IoHandler} classes which handle * proxied connections. * * @author The Apache MINA Project ([email protected]) * @version $Rev$, $Date$ * */ public abstract class AbstractProxyIoHandler extends IoHandlerAdapter { private static final Charset CHARSET = Charset.forName("iso8859-1"); public static final String OTHER_IO_SESSION = AbstractProxyIoHandler.class.getName()+".OtherIoSession"; private final Logger logger = LoggerFactory.getLogger(getClass()); @Override public void sessionCreated(IoSession session) throws Exception { session.suspendRead(); session.suspendWrite(); } @Override public void sessionClosed(IoSession session) throws Exception { if (session.getAttribute( OTHER_IO_SESSION ) != null) { IoSession sess = (IoSession) session.getAttribute(OTHER_IO_SESSION); sess.setAttribute(OTHER_IO_SESSION, null); sess.close(false); session.setAttribute(OTHER_IO_SESSION, null); } } @Override public void messageReceived(IoSession session, Object message) throws Exception { IoBuffer rb = (IoBuffer) message; IoBuffer wb = IoBuffer.allocate(rb.remaining()); rb.mark(); wb.put(rb); wb.flip(); ((IoSession) session.getAttribute(OTHER_IO_SESSION)).write(wb); rb.reset(); logger.info(rb.getString(CHARSET.newDecoder())); } }
import java.net.SocketAddress; import org.apache.mina.core.RuntimeIoException; import org.apache.mina.core.future.ConnectFuture; import org.apache.mina.core.future.IoFutureListener; import org.apache.mina.core.service.IoConnector; import org.apache.mina.core.session.IoSession; /** * Handles the client to proxy part of the proxied connection. * * @author The Apache MINA Project ([email protected]) * @version $Rev$, $Date$ * */ public class ClientToProxyIoHandler extends AbstractProxyIoHandler { private final ServerToProxyIoHandler connectorHandler = new ServerToProxyIoHandler(); private final IoConnector connector; private final SocketAddress remoteAddress; public ClientToProxyIoHandler(IoConnector connector, SocketAddress remoteAddress) { this.connector = connector; this.remoteAddress = remoteAddress; connector.setHandler(connectorHandler); } @Override public void sessionOpened(final IoSession session) throws Exception { connector.connect(remoteAddress).addListener(new IoFutureListener<ConnectFuture>() { public void operationComplete(ConnectFuture future) { try { future.getSession().setAttribute(OTHER_IO_SESSION, session); session.setAttribute(OTHER_IO_SESSION, future.getSession()); IoSession session2 = future.getSession(); session2.resumeRead(); session2.resumeWrite(); } catch (RuntimeIoException e) { // Connect failed session.close(true); } finally { session.resumeRead(); session.resumeWrite(); } } }); } }