proxy.java

来自「JGRoups源码」· Java 代码 · 共 852 行 · 第 1/2 页

JAVA
852
字号
            mappings.put(new MyInetSocketAddress(key.getHost(), key.getPort(), ssl_key),                         new MyInetSocketAddress(value.getHost(), value.getPort(), ssl_value));        }        in.close();    }    /** Checks whether a URI is http(s)://<host>:<port> */    void check(URI u) throws Exception {        if (u.getScheme() == null)            throw new Exception(                "scheme is null in " + u + ", (valid URI is \"http(s)://<host>:<port>\")");        if (u.getHost() == null)            throw new Exception(                "host is null in " + u + ", (valid URI is \"http(s)://<host>:<port>\")");        if (u.getPort() <=0)            throw new Exception(                "port is <=0 in " + u + ", (valid URI is \"http(s)://<host>:<port>\")");    }    /** Input is "host:port" */    SocketAddress strToAddr(String input) throws Exception {        StringTokenizer tok=new StringTokenizer(input, ":");        String host, port;        host=tok.nextToken();        port=tok.nextToken();        return new InetSocketAddress(host, Integer.parseInt(port));    }    String printSelectionOps(SelectionKey key) {        StringBuffer sb=new StringBuffer();        if ((key.readyOps() & SelectionKey.OP_ACCEPT) !=0)            sb.append("OP_ACCEPT ");        if ((key.readyOps() & SelectionKey.OP_CONNECT) !=0)            sb.append("OP_CONNECT ");        if ((key.readyOps() & SelectionKey.OP_READ) !=0)            sb.append("OP_READ ");        if ((key.readyOps() & SelectionKey.OP_WRITE) !=0)            sb.append("OP_WRITE ");        return sb.toString();    }    public static void main(String[] args) {        Proxy    p;        InetAddress local=null, remote=null;        int         local_port=0, remote_port=0;        String      tmp, tmp_addr, tmp_port;        boolean     verbose=false, debug=false;        int         index;        String      mapping_file=null;        try {            for (int i=0; i < args.length; i++) {                tmp=args[i];                if ("-help".equals(tmp)) {                    help();                    return;                }                if ("-verbose".equals(tmp)) {                    verbose=true;                    continue;                }                if ("-local".equals(tmp)) {                    tmp_addr=args[++i];                    index=tmp_addr.indexOf(':');                    if (index > -1) { // it is in the format address:port                        tmp_port=tmp_addr.substring(index + 1);                        local_port=Integer.parseInt(tmp_port);                        tmp_addr=tmp_addr.substring(0, index);                        local=InetAddress.getByName(tmp_addr);                    }                    else                        local=InetAddress.getByName(args[++i]);                    continue;                }                if ("-local_port".equals(tmp)) {                    local_port=Integer.parseInt(args[++i]);                    continue;                }                if ("-remote".equals(tmp)) {                    tmp_addr=args[++i];                    index=tmp_addr.indexOf(':');                    if (index > -1) { // it is in the format address:port                        tmp_port=tmp_addr.substring(index + 1);                        remote_port=Integer.parseInt(tmp_port);                        tmp_addr=tmp_addr.substring(0, index);                        remote=InetAddress.getByName(tmp_addr);                    }                    else                        remote=InetAddress.getByName(args[++i]);                    continue;                }                if ("-remote_port".equals(tmp)) {                    remote_port=Integer.parseInt(args[++i]);                    continue;                }                if ("-file".equals(tmp)) {                    mapping_file=args[++i];                    continue;                }                if ("-debug".equals(tmp)) {                    debug=true;                    continue;                }                help();                return;            }            if (local == null)                local=InetAddress.getLocalHost();            p=new Proxy(local, local_port, remote, remote_port, verbose, debug, mapping_file);            p.start();        }        catch (Throwable ex) {            ex.printStackTrace();        }    }    static void help() {        System.out.println("Proxy [-help] [-local <local address>] [-local_port <port>] "                           + "[-remote <remote address>] [-remote_port <port>] [-verbose] "                           + "[-file <mapping file>] [-debug]");    }    static void log(String method_name, String msg) {        System.out.println('[' + method_name + "]: " + msg);    }    static void log(String msg) {        System.out.println(msg);    }    static void close(Socket in, Socket out) {        if (in !=null) {            try {                in.close();            }            catch (Exception ex) {            }        }        if (out !=null) {            try {                out.close();            }            catch (Exception ex) {            }        }    }    static void close(Socket sock) {        if (sock !=null) {            try {                sock.close();            }            catch (Exception ex) {            }        }    }    static class Relayer implements Runnable {        final Socket         in_sock;        final Socket out_sock;        final InputStream    in;        final OutputStream   out;        Thread         t=null;        final java.util.List listeners=new ArrayList();        String         name=null;        interface Listener {            void connectionClosed();        }        public Relayer(Socket in_sock, Socket out_sock, String name) throws Exception {            this.in_sock=in_sock;            this.out_sock=out_sock;            this.name=name;            in=in_sock.getInputStream();            out=out_sock.getOutputStream();        }        public void addListener(Listener l) {            if(l != null && !listeners.contains(l))                listeners.add(l);        }        public void run() {            byte[]       buf=new byte[1024];            int          num;            StringBuffer sb;            try {                while(t != null) {                    if ((num=in.read(buf)) == -1)                        break;                    if (verbose) {                                                //sb=new StringBuffer();                        //sb.append("forwarding ").append(num).append(" bytes from ").append(toString(in_sock));                        //sb.append(" to ").append(toString(out_sock));                        // log("Proxy.Relayer.run()", sb.toString());                        log(printRelayedData(toString(in_sock), toString(out_sock), num));                    }                    if (debug) {                        sb=new StringBuffer();                        sb.append(new String(buf, 0, num).trim());                        log(sb.toString());                    }                    out.write(buf, 0, num);                    //if(debug)                    //    System.out.println(new String(buf));                }                            }                        catch (Exception ex) {                log("Proxy.Relayer.run(): [" + name + "] exception=" + ex + ", in_sock=" +                    in_sock + ", out_sock=" + out_sock);            }            finally {                stop();            }        }        public void start() {            if(t == null) {                t=new Thread(this, "Proxy.Relayer");                t.setDaemon(true);                t.start();            }        }        public void stop() {            t=null;            close(in_sock);            close(out_sock);        }        String toString(Socket s) {            if(s == null) return null;            return s.getInetAddress().getHostName() + ':' + s.getPort();        }                void notifyListeners() {            for(Iterator it=listeners.iterator(); it.hasNext();) {                try {                    ((Listener)it.next()).connectionClosed();                }                catch(Throwable ex) {                    ;                }            }        }    }    static class MyInetSocketAddress extends InetSocketAddress {        boolean is_ssl=false;        public MyInetSocketAddress(InetAddress addr, int port) {            super(addr, port);        }        public MyInetSocketAddress(InetAddress addr, int port, boolean is_ssl) {            super(addr, port);            this.is_ssl=is_ssl;        }        public MyInetSocketAddress(int port) {            super(port);        }        public MyInetSocketAddress(int port, boolean is_ssl) {            super(port);            this.is_ssl=is_ssl;        }        public MyInetSocketAddress(String hostname, int port) {            super(hostname, port);        }        public MyInetSocketAddress(String hostname, int port, boolean is_ssl) {            super(hostname, port);            this.is_ssl=is_ssl;        }        public boolean ssl() {            return is_ssl;        }        public String toString() {            return super.toString() + " [ssl: " + ssl() + ']';        }    }    /**     * Handles accepts on an SSLServerSocket or ServerSocket. Creates a {@link     * Connection} for each successful accept().     *      * @author bela Dec 19, 2002     */    class SocketAcceptor implements Runnable {        ServerSocket        srv_sock=null;        MyInetSocketAddress dest=null;                /**         * Create an SSLServerSocket or ServerSocket and continuously call         * accept() on it.         * @param sock_addr         */        public SocketAcceptor(MyInetSocketAddress sock_addr, MyInetSocketAddress dest) throws Exception {            this.dest=dest;            if(sock_addr.ssl()) {                srv_sock=createSSLServerSocket(sock_addr);            }            else {                srv_sock=createServerSocket(sock_addr);            }            executor.execute(this);        }        public void run() {            Connection conn;            Socket     s, dest_sock;            while (srv_sock !=null) {                try {                    s=srv_sock.accept();                    dest_sock=dest.ssl() ? createSSLSocket(dest) : createSocket(dest);                    conn=new Connection(s, dest_sock);                    conn.start();                }                catch (Exception e) {                    log("Proxy.SSLServerSocketAcceptor.run(): exception=" + e);                    break;                }            }        }                Socket createSocket(InetSocketAddress addr) throws Exception {            return new Socket(addr.getAddress(), addr.getPort());        }        Socket createSSLSocket(InetSocketAddress addr) throws Exception {            SSLSocketFactory sslsocketfactory = (SSLSocketFactory)SSLSocketFactory.getDefault();            SSLSocket        sslsocket = (SSLSocket)sslsocketfactory.createSocket(addr.getAddress(), addr.getPort());            return sslsocket;        }        ServerSocket createServerSocket(InetSocketAddress addr) throws Exception {            return new ServerSocket(addr.getPort(), 10, addr.getAddress());        }                ServerSocket createSSLServerSocket(InetSocketAddress addr) throws Exception {            SSLServerSocketFactory sslserversocketfactory =                (SSLServerSocketFactory)SSLServerSocketFactory.getDefault();            SSLServerSocket sslserversocket =                (SSLServerSocket)sslserversocketfactory.createServerSocket(addr.getPort(), 10, addr.getAddress());            return sslserversocket;        }    }    /**     * Handles an incoming SSLSocket or Socket. Looks up the destination in the     * mapping hashmap, key is the incoming socket address. Creates an outgoing     * socket (regular or SSL, depending on settings) and relays data between     * incoming and outgoing sockets. Closes the connection when either incoming     * or outgoing socket is closed, or when stop() is called.     *      * @author bela Dec 19, 2002     */    static class Connection implements Relayer.Listener {        Relayer in_to_out=null;        Relayer out_to_in=null;        /**         * Creates an outgoing (regular or SSL) socket according to the mapping         * table. Sets both input and output stream. Caller needs to call         * start() after the instance has been created.         * @param in The Socket we got as result of accept()         * @throws Exception Thrown if either the input or output streams cannot         * be created.         */        public Connection(Socket in, Socket out) throws Exception {            in_to_out=new Relayer(in, out, "in-out");            in_to_out.addListener(this);            out_to_in=new Relayer(out, in, "out-in");            out_to_in.addListener(this);        }        /** Starts relaying between incoming and outgoing sockets.         * Returns immediately (thread is started).          *          */        public void start() {            in_to_out.start();            out_to_in.start();        }        public void stop() {            if (in_to_out !=null) {                in_to_out.stop();            }            if (out_to_in !=null) {                out_to_in.stop();            }        }        public void connectionClosed() {            stop();        }    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?