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 + -
显示快捷键?