Source Code Cross Referenced for Proxy.java in  » Net » JGroups-2.4.1-sp3 » org » jgroups » util » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Net » JGroups 2.4.1 sp3 » org.jgroups.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        // $Id: Proxy.java,v 1.2 2005/07/17 11:33:58 chrislott Exp $
002:
003:        package org.jgroups.util;
004:
005:        import EDU.oswego.cs.dl.util.concurrent.Executor;
006:        import EDU.oswego.cs.dl.util.concurrent.PooledExecutor;
007:
008:        import javax.net.ssl.SSLServerSocket;
009:        import javax.net.ssl.SSLServerSocketFactory;
010:        import javax.net.ssl.SSLSocket;
011:        import javax.net.ssl.SSLSocketFactory;
012:        import java.io.*;
013:        import java.net.*;
014:        import java.nio.ByteBuffer;
015:        import java.nio.channels.SelectionKey;
016:        import java.nio.channels.Selector;
017:        import java.nio.channels.ServerSocketChannel;
018:        import java.nio.channels.SocketChannel;
019:        import java.util.*;
020:
021:        /**
022:         * Redirects incoming TCP connections to other hosts/ports. All redirections are defined in a file as for example
023:         * <pre>
024:         * 127.0.0.1:8888=www.ibm.com:80
025:         * localhost:80=pop.mail.yahoo.com:110
026:         * </pre>
027:         * The first line forwards all requests to port 8888 on to www.ibm.com at port 80 (it also forwards the HTTP
028:         * response back to the sender. The second line essentially provides a POP-3 service on port 8110, using
029:         * Yahoo's POP service. This is neat when you're behind a firewall and one of the few services in the outside
030:         * world that are not blocked is port 80 (HHTP).<br/>
031:         * Note that JDK 1.4 is required for this class. Also, concurrent.jar has to be on the classpath. Note that
032:         * you also need to include jsse.jar/jce.jar (same location as rt.jar) if you want SSL sockets.<br>
033:         * To create SSLServerSockets you'll need to do the following:
034:         * Generate a certificate as follows:
035:         * <pre>
036:         * keytool -genkey -keystore /home/bela/.keystore -keyalg rsa -alias bela -storepass <passwd> -keypass <passwd>
037:         * </pre>
038:         *
039:         * Start the Proxy as follows:
040:         * <pre>
041:         * java -Djavax.net.ssl.keyStore=/home/bela/.keystore -Djavax.net.ssl.keyStorePassword=<passwd>
042:         *      -Djavax.net.ssl.trustStore=/home/bela/.keystore -Djavax.net.ssl.trustStorePassword=<passwd>
043:         *      org.jgroups.util.Proxy -file /home/bela/map.properties
044:         * </pre>
045:         * Start client as follows:
046:         * <pre>
047:         * java -Djavax.net.ssl.trustStore=/home/bela/.keystore -Djavax.net.ssl.trustStorePassword=<passwd> sslclient
048:         * </pre>
049:         * <br/>
050:         * To import a certificate into the keystore, use the following steps:
051:         * <pre>
052:         * openssl x509 -in server.crt -out server.crt.der -outform DER
053:         * keytool -import -trustcacerts -alias <your alias name> -file server.crt.der
054:         * </pre>
055:         * This will store the server's certificate in the ${user.home}/.keystore key store.
056:         * <br/>
057:         * Note that an SSL client or server can be debugged by starting it as follows:
058:         * <pre>-Djava.protocol.handler.pkgs=com.sun.net.ssl.internal.www.protocol -Djavax.net.debug=ssl</pre>
059:         * <br/>
060:         * If you run a web browser, simply enter https://<host>:<port> as URL to connect to an SSLServerSocket
061:         * <br/>Note that we cannot use JDK 1.4's selectors for SSL sockets, as
062:         * getChannel() on an SSL socket doesn't seem to work.
063:         * @todo Check whether SSLSocket.getChannel() or SSLServerSocket.getChannel() works.
064:         * @author Bela Ban
065:         */
066:        public class Proxy {
067:            InetAddress local = null, remote = null;
068:            int local_port = 0, remote_port = 0;
069:            static boolean verbose = false;
070:            static boolean debug = false;
071:            String mapping_file = null; // contains a list of src and dest host:port pairs
072:            final HashMap mappings = new HashMap(); // keys=MyInetSocketAddr (src), values=MyInetSocketAddr (dest)
073:            Executor executor; // maintains a thread pool
074:            static final int MAX_THREAD_POOL_SIZE = 64; // for processing requests
075:            static final int BUFSIZE = 1024; // size of data transfer buffer
076:
077:            public Proxy(InetAddress local, int local_port, InetAddress remote,
078:                    int remote_port, boolean verbose, boolean debug) {
079:                this .local = local;
080:                this .local_port = local_port;
081:                this .remote = remote;
082:                this .remote_port = remote_port;
083:                Proxy.verbose = verbose;
084:                Proxy.debug = debug;
085:            }
086:
087:            public Proxy(InetAddress local, int local_port, InetAddress remote,
088:                    int remote_port, boolean verbose, boolean debug,
089:                    String mapping_file) {
090:                this (local, local_port, remote, remote_port, verbose, debug);
091:                this .mapping_file = mapping_file;
092:            }
093:
094:            public void start() throws Exception {
095:                Map.Entry entry;
096:                Selector selector;
097:                ServerSocketChannel sock_channel;
098:                MyInetSocketAddress key, value;
099:
100:                if (remote != null && local != null)
101:                    mappings.put(new InetSocketAddress(local, local_port),
102:                            new InetSocketAddress(remote, remote_port));
103:
104:                if (mapping_file != null) {
105:                    try {
106:                        populateMappings(mapping_file);
107:                    } catch (Exception ex) {
108:                        log("Failed reading " + mapping_file);
109:                        throw ex;
110:                    }
111:                }
112:
113:                log("\nProxy started at " + new java.util.Date());
114:
115:                if (verbose) {
116:                    log("\nMappings:\n---------");
117:                    for (Iterator it = mappings.entrySet().iterator(); it
118:                            .hasNext();) {
119:                        entry = (Map.Entry) it.next();
120:                        log(toString((InetSocketAddress) entry.getKey())
121:                                + " <--> "
122:                                + toString((InetSocketAddress) entry.getValue()));
123:                    }
124:                    log("\n");
125:                }
126:
127:                // 1. Create a Selector
128:                selector = Selector.open();
129:
130:                // Create a thread pool (Executor)
131:                executor = new PooledExecutor(MAX_THREAD_POOL_SIZE);
132:
133:                for (Iterator it = mappings.keySet().iterator(); it.hasNext();) {
134:                    key = (MyInetSocketAddress) it.next();
135:                    value = (MyInetSocketAddress) mappings.get(key);
136:
137:                    // if either source or destination are SSL, we cannot use JDK 1.4
138:                    // NIO selectors, but have to fall back on separate threads per connection
139:
140:                    if (key.ssl() || value.ssl()) {
141:                        // if(2 == 2) {
142:                        SocketAcceptor acceptor = new SocketAcceptor(key, value);
143:                        executor.execute(acceptor);
144:                        continue;
145:                    }
146:
147:                    // 2. Create a ServerSocketChannel
148:                    sock_channel = ServerSocketChannel.open();
149:                    sock_channel.configureBlocking(false);
150:                    sock_channel.socket().bind(key);
151:
152:                    // 3. Register the selector with all server sockets. 'Key' is attachment, so we get it again on
153:                    //    select(). That way we can associate it with the mappings hashmap to find the corresponding
154:                    //    value
155:                    sock_channel
156:                            .register(selector, SelectionKey.OP_ACCEPT, key);
157:                }
158:
159:                // 4. Start main loop. won't return until CTRL-C'ed        
160:                loop(selector);
161:            }
162:
163:            /** We handle only non-SSL connections */
164:            void loop(Selector selector) {
165:                Set ready_keys;
166:                SelectionKey key;
167:                ServerSocketChannel srv_sock;
168:                SocketChannel in_sock, out_sock;
169:                InetSocketAddress src, dest;
170:
171:                while (true) {
172:                    if (verbose)
173:                        log("[Proxy] ready to accept connection");
174:
175:                    // 4. Call Selector.select()
176:                    try {
177:                        selector.select();
178:
179:                        // get set of ready objects
180:                        ready_keys = selector.selectedKeys();
181:                        for (Iterator it = ready_keys.iterator(); it.hasNext();) {
182:                            key = (SelectionKey) it.next();
183:                            it.remove();
184:
185:                            if (key.isAcceptable()) {
186:                                srv_sock = (ServerSocketChannel) key.channel();
187:                                // get server socket and attachment
188:                                src = (InetSocketAddress) key.attachment();
189:                                in_sock = srv_sock.accept(); // accept request
190:                                if (verbose)
191:                                    log("Proxy.loop()",
192:                                            "accepted connection from "
193:                                                    + toString(in_sock));
194:                                dest = (InetSocketAddress) mappings.get(src);
195:                                // find corresponding dest
196:                                if (dest == null) {
197:                                    in_sock.close();
198:                                    log("Proxy.loop()",
199:                                            "did not find a destination host for "
200:                                                    + src);
201:                                    continue;
202:                                } else {
203:                                    if (verbose)
204:                                        log("Proxy.loop()",
205:                                                "relaying traffic from "
206:                                                        + toString(src)
207:                                                        + " to "
208:                                                        + toString(dest));
209:                                }
210:
211:                                // establish connection to destination host
212:                                try {
213:                                    out_sock = SocketChannel.open(dest);
214:                                    // uses thread pool (Executor) to handle request, closes socks at end
215:                                    handleConnection(in_sock, out_sock);
216:                                } catch (Exception ex) {
217:                                    in_sock.close();
218:                                    throw ex;
219:                                }
220:                            }
221:                        }
222:                    } catch (Exception ex) {
223:                        log("Proxy.loop()", "exception: " + ex);
224:                    }
225:                }
226:            }
227:
228:            //    void handleConnection(Socket in_sock, Socket out_sock) {
229:            //        try {
230:            //            Relayer r=new Relayer(in_sock, out_sock);
231:            //            executor.execute(r);
232:            //            r=new Relayer(out_sock, in_sock);
233:            //            executor.execute(r);
234:            //        }
235:            //        catch (Exception ex) {
236:            //            log("Proxy.handleConnection()", "exception: " + ex);
237:            //        }
238:            //        finally {
239:            //            close(in_sock, out_sock);
240:            //        }
241:            //    }
242:
243:            void handleConnection(SocketChannel in, SocketChannel out) {
244:                try {
245:                    _handleConnection(in, out);
246:                } catch (Exception ex) {
247:                    log("Proxy.handleConnection()", "exception: " + ex);
248:                }
249:            }
250:
251:            void _handleConnection(final SocketChannel in_channel,
252:                    final SocketChannel out_channel) throws Exception {
253:                executor.execute(new Runnable() {
254:                    public void run() {
255:                        Selector sel = null;
256:                        SocketChannel tmp;
257:                        Set ready_keys;
258:                        SelectionKey key;
259:                        ByteBuffer transfer_buf = ByteBuffer.allocate(BUFSIZE);
260:
261:                        try {
262:                            sel = Selector.open();
263:                            in_channel.configureBlocking(false);
264:                            out_channel.configureBlocking(false);
265:                            in_channel.register(sel, SelectionKey.OP_READ);
266:                            out_channel.register(sel, SelectionKey.OP_READ);
267:
268:                            while (sel.select() > 0) {
269:                                ready_keys = sel.selectedKeys();
270:                                for (Iterator it = ready_keys.iterator(); it
271:                                        .hasNext();) {
272:                                    key = (SelectionKey) it.next();
273:                                    it.remove(); // remove current entry (why ?)
274:                                    tmp = (SocketChannel) key.channel();
275:                                    if (tmp == null) {
276:                                        log("Proxy._handleConnection()",
277:                                                "attachment is null, continuing");
278:                                        continue;
279:                                    }
280:                                    if (key.isReadable()) { // data is available to be read from tmp
281:                                        if (tmp == in_channel) {
282:                                            // read all data from in_channel and forward it to out_channel (request)
283:                                            if (relay(tmp, out_channel,
284:                                                    transfer_buf) == false)
285:                                                return;
286:                                        }
287:                                        if (tmp == out_channel) {
288:                                            // read all data from out_channel and forward it 
289:                                            // to in_channel (response)
290:                                            if (relay(tmp, in_channel,
291:                                                    transfer_buf) == false)
292:                                                return;
293:                                        }
294:                                    }
295:                                }
296:                            }
297:                        } catch (Exception ex) {
298:                            ex.printStackTrace();
299:                            return;
300:                        } finally {
301:                            close(sel, in_channel, out_channel);
302:                        }
303:                    }
304:                });
305:            }
306:
307:            void close(Selector sel, SocketChannel in_channel,
308:                    SocketChannel out_channel) {
309:                try {
310:                    if (sel != null)
311:                        sel.close();
312:                } catch (Exception ex) {
313:                }
314:                try {
315:                    if (in_channel != null)
316:                        in_channel.close();
317:                } catch (Exception ex) {
318:                }
319:                try {
320:                    if (out_channel != null)
321:                        out_channel.close();
322:                } catch (Exception ex) {
323:                }
324:            }
325:
326:            /**
327:             * Read all data from <code>from</code> and write it to <code>to</code>.
328:             * Returns false if channel was closed
329:             */
330:            boolean relay(SocketChannel from, SocketChannel to, ByteBuffer buf)
331:                    throws Exception {
332:                int num;
333:                StringBuffer sb;
334:
335:                buf.clear();
336:                while (true) {
337:                    num = from.read(buf);
338:                    if (num < 0)
339:                        return false;
340:                    else if (num == 0)
341:                        return true;
342:                    buf.flip();
343:                    if (verbose) {
344:                        log(printRelayedData(toString(from), toString(to), buf
345:                                .remaining()));
346:                    }
347:                    if (debug) {
348:                        sb = new StringBuffer();
349:                        sb.append(new String(buf.array()).trim());
350:                        sb.append('\n');
351:                        log(sb.toString());
352:                    }
353:                    to.write(buf);
354:                    buf.flip();
355:                }
356:            }
357:
358:            String toString(SocketChannel ch) {
359:                StringBuffer sb = new StringBuffer();
360:                Socket sock;
361:
362:                if (ch == null)
363:                    return null;
364:                if ((sock = ch.socket()) == null)
365:                    return null;
366:                sb.append(sock.getInetAddress().getHostName()).append(':')
367:                        .append(sock.getPort());
368:                return sb.toString();
369:            }
370:
371:            String toString(InetSocketAddress addr) {
372:                StringBuffer sb = new StringBuffer();
373:
374:                if (addr == null)
375:                    return null;
376:                sb.append(addr.getAddress().getHostName()).append(':').append(
377:                        addr.getPort());
378:                if (addr instanceof  MyInetSocketAddress)
379:                    sb.append(" [ssl=").append(
380:                            ((MyInetSocketAddress) addr).ssl()).append(']');
381:                return sb.toString();
382:            }
383:
384:            static String printRelayedData(String from, String to, int num_bytes) {
385:                StringBuffer sb = new StringBuffer();
386:                sb.append("\n[PROXY] ").append(from);
387:                sb.append(" to ").append(to);
388:                sb.append(" (").append(num_bytes).append(" bytes)");
389:                // log("Proxy.relay()", sb.toString());
390:                return sb.toString();
391:            }
392:
393:            /**
394:             * Populates <code>mappings</code> hashmap. An example of a definition file is:
395:             * <pre>
396:             * http://localhost:8888=http://www.yahoo.com:80
397:             * https://localhost:2200=https://cvs.sourceforge.net:22
398:             * http://localhost:8000=https://www.ibm.com:443
399:             * </pre>
400:             * Mappings can be http-https, https-http, http-http or https-https
401:             */
402:            void populateMappings(String filename) throws Exception {
403:                FileInputStream in = new FileInputStream(filename);
404:                BufferedReader reader;
405:                String line;
406:                URI key, value;
407:                int index;
408:                boolean ssl_key, ssl_value;
409:                final String HTTPS = "https";
410:
411:                reader = new BufferedReader(new InputStreamReader(in));
412:                while ((line = reader.readLine()) != null) {
413:                    line = line.trim();
414:                    if (line.startsWith("//") || line.startsWith("#")
415:                            || line.length() == 0)
416:                        continue;
417:                    index = line.indexOf('=');
418:                    if (index == -1)
419:                        throw new Exception(
420:                                "Proxy.populateMappings(): detected no '=' character in "
421:                                        + line);
422:                    key = new URI(line.substring(0, index));
423:                    ssl_key = key.getScheme().trim().equals(HTTPS);
424:
425:                    value = new URI(line.substring(index + 1));
426:                    ssl_value = value.getScheme().trim().equals(HTTPS);
427:
428:                    check(key);
429:                    check(value);
430:
431:                    log("key: " + key + ", value: " + value);
432:
433:                    mappings.put(new MyInetSocketAddress(key.getHost(), key
434:                            .getPort(), ssl_key), new MyInetSocketAddress(value
435:                            .getHost(), value.getPort(), ssl_value));
436:                }
437:                in.close();
438:            }
439:
440:            /** Checks whether a URI is http(s)://<host>:<port> */
441:            void check(URI u) throws Exception {
442:                if (u.getScheme() == null)
443:                    throw new Exception("scheme is null in " + u
444:                            + ", (valid URI is \"http(s)://<host>:<port>\")");
445:
446:                if (u.getHost() == null)
447:                    throw new Exception("host is null in " + u
448:                            + ", (valid URI is \"http(s)://<host>:<port>\")");
449:
450:                if (u.getPort() <= 0)
451:                    throw new Exception("port is <=0 in " + u
452:                            + ", (valid URI is \"http(s)://<host>:<port>\")");
453:
454:            }
455:
456:            /** Input is "host:port" */
457:            SocketAddress strToAddr(String input) throws Exception {
458:                StringTokenizer tok = new StringTokenizer(input, ":");
459:                String host, port;
460:
461:                host = tok.nextToken();
462:                port = tok.nextToken();
463:                return new InetSocketAddress(host, Integer.parseInt(port));
464:            }
465:
466:            String printSelectionOps(SelectionKey key) {
467:                StringBuffer sb = new StringBuffer();
468:                if ((key.readyOps() & SelectionKey.OP_ACCEPT) != 0)
469:                    sb.append("OP_ACCEPT ");
470:                if ((key.readyOps() & SelectionKey.OP_CONNECT) != 0)
471:                    sb.append("OP_CONNECT ");
472:                if ((key.readyOps() & SelectionKey.OP_READ) != 0)
473:                    sb.append("OP_READ ");
474:                if ((key.readyOps() & SelectionKey.OP_WRITE) != 0)
475:                    sb.append("OP_WRITE ");
476:                return sb.toString();
477:            }
478:
479:            public static void main(String[] args) {
480:                Proxy p;
481:                InetAddress local = null, remote = null;
482:                int local_port = 0, remote_port = 0;
483:                String tmp, tmp_addr, tmp_port;
484:                boolean verbose = false, debug = false;
485:                int index;
486:                String mapping_file = null;
487:
488:                try {
489:                    for (int i = 0; i < args.length; i++) {
490:                        tmp = args[i];
491:                        if ("-help".equals(tmp)) {
492:                            help();
493:                            return;
494:                        }
495:                        if ("-verbose".equals(tmp)) {
496:                            verbose = true;
497:                            continue;
498:                        }
499:                        if ("-local".equals(tmp)) {
500:                            tmp_addr = args[++i];
501:                            index = tmp_addr.indexOf(':');
502:                            if (index > -1) { // it is in the format address:port
503:                                tmp_port = tmp_addr.substring(index + 1);
504:                                local_port = Integer.parseInt(tmp_port);
505:                                tmp_addr = tmp_addr.substring(0, index);
506:                                local = InetAddress.getByName(tmp_addr);
507:                            } else
508:                                local = InetAddress.getByName(args[++i]);
509:                            continue;
510:                        }
511:                        if ("-local_port".equals(tmp)) {
512:                            local_port = Integer.parseInt(args[++i]);
513:                            continue;
514:                        }
515:                        if ("-remote".equals(tmp)) {
516:                            tmp_addr = args[++i];
517:                            index = tmp_addr.indexOf(':');
518:                            if (index > -1) { // it is in the format address:port
519:                                tmp_port = tmp_addr.substring(index + 1);
520:                                remote_port = Integer.parseInt(tmp_port);
521:                                tmp_addr = tmp_addr.substring(0, index);
522:                                remote = InetAddress.getByName(tmp_addr);
523:                            } else
524:                                remote = InetAddress.getByName(args[++i]);
525:                            continue;
526:                        }
527:                        if ("-remote_port".equals(tmp)) {
528:                            remote_port = Integer.parseInt(args[++i]);
529:                            continue;
530:                        }
531:                        if ("-file".equals(tmp)) {
532:                            mapping_file = args[++i];
533:                            continue;
534:                        }
535:                        if ("-debug".equals(tmp)) {
536:                            debug = true;
537:                            continue;
538:                        }
539:                        help();
540:                        return;
541:                    }
542:
543:                    if (local == null)
544:                        local = InetAddress.getLocalHost();
545:
546:                    p = new Proxy(local, local_port, remote, remote_port,
547:                            verbose, debug, mapping_file);
548:                    p.start();
549:                } catch (Throwable ex) {
550:                    ex.printStackTrace();
551:                }
552:            }
553:
554:            static void help() {
555:                System.out
556:                        .println("Proxy [-help] [-local <local address>] [-local_port <port>] "
557:                                + "[-remote <remote address>] [-remote_port <port>] [-verbose] "
558:                                + "[-file <mapping file>] [-debug]");
559:            }
560:
561:            static void log(String method_name, String msg) {
562:                System.out.println('[' + method_name + "]: " + msg);
563:            }
564:
565:            static void log(String msg) {
566:                System.out.println(msg);
567:            }
568:
569:            static void close(Socket in, Socket out) {
570:                if (in != null) {
571:                    try {
572:                        in.close();
573:                    } catch (Exception ex) {
574:                    }
575:                }
576:                if (out != null) {
577:                    try {
578:                        out.close();
579:                    } catch (Exception ex) {
580:                    }
581:                }
582:            }
583:
584:            static void close(Socket sock) {
585:                if (sock != null) {
586:                    try {
587:                        sock.close();
588:                    } catch (Exception ex) {
589:                    }
590:                }
591:            }
592:
593:            static class Relayer implements  Runnable {
594:                final Socket in_sock;
595:                final Socket out_sock;
596:                final InputStream in;
597:                final OutputStream out;
598:                Thread t = null;
599:                final java.util.List listeners = new ArrayList();
600:                String name = null;
601:
602:                interface Listener {
603:                    void connectionClosed();
604:                }
605:
606:                public Relayer(Socket in_sock, Socket out_sock, String name)
607:                        throws Exception {
608:                    this .in_sock = in_sock;
609:                    this .out_sock = out_sock;
610:                    this .name = name;
611:                    in = in_sock.getInputStream();
612:                    out = out_sock.getOutputStream();
613:                }
614:
615:                public void addListener(Listener l) {
616:                    if (l != null && !listeners.contains(l))
617:                        listeners.add(l);
618:                }
619:
620:                public void run() {
621:                    byte[] buf = new byte[1024];
622:                    int num;
623:                    StringBuffer sb;
624:
625:                    try {
626:                        while (t != null) {
627:                            if ((num = in.read(buf)) == -1)
628:                                break;
629:
630:                            if (verbose) {
631:
632:                                //sb=new StringBuffer();
633:
634:                                //sb.append("forwarding ").append(num).append(" bytes from ").append(toString(in_sock));
635:                                //sb.append(" to ").append(toString(out_sock));
636:                                // log("Proxy.Relayer.run()", sb.toString());
637:                                log(printRelayedData(toString(in_sock),
638:                                        toString(out_sock), num));
639:                            }
640:                            if (debug) {
641:                                sb = new StringBuffer();
642:                                sb.append(new String(buf, 0, num).trim());
643:                                log(sb.toString());
644:                            }
645:
646:                            out.write(buf, 0, num);
647:                            //if(debug)
648:                            //    System.out.println(new String(buf));
649:                        }
650:
651:                    } catch (Exception ex) {
652:                        log("Proxy.Relayer.run(): [" + name + "] exception="
653:                                + ex + ", in_sock=" + in_sock + ", out_sock="
654:                                + out_sock);
655:                    } finally {
656:                        stop();
657:                    }
658:                }
659:
660:                public void start() {
661:                    if (t == null) {
662:                        t = new Thread(this , "Proxy.Relayer");
663:                        t.setDaemon(true);
664:                        t.start();
665:                    }
666:                }
667:
668:                public void stop() {
669:                    t = null;
670:                    close(in_sock);
671:                    close(out_sock);
672:                }
673:
674:                String toString(Socket s) {
675:                    if (s == null)
676:                        return null;
677:                    return s.getInetAddress().getHostName() + ':' + s.getPort();
678:                }
679:
680:                void notifyListeners() {
681:                    for (Iterator it = listeners.iterator(); it.hasNext();) {
682:                        try {
683:                            ((Listener) it.next()).connectionClosed();
684:                        } catch (Throwable ex) {
685:                            ;
686:                        }
687:                    }
688:                }
689:            }
690:
691:            static class MyInetSocketAddress extends InetSocketAddress {
692:                boolean is_ssl = false;
693:
694:                public MyInetSocketAddress(InetAddress addr, int port) {
695:                    super (addr, port);
696:                }
697:
698:                public MyInetSocketAddress(InetAddress addr, int port,
699:                        boolean is_ssl) {
700:                    super (addr, port);
701:                    this .is_ssl = is_ssl;
702:                }
703:
704:                public MyInetSocketAddress(int port) {
705:                    super (port);
706:                }
707:
708:                public MyInetSocketAddress(int port, boolean is_ssl) {
709:                    super (port);
710:                    this .is_ssl = is_ssl;
711:                }
712:
713:                public MyInetSocketAddress(String hostname, int port) {
714:                    super (hostname, port);
715:                }
716:
717:                public MyInetSocketAddress(String hostname, int port,
718:                        boolean is_ssl) {
719:                    super (hostname, port);
720:                    this .is_ssl = is_ssl;
721:                }
722:
723:                public boolean ssl() {
724:                    return is_ssl;
725:                }
726:
727:                public String toString() {
728:                    return super .toString() + " [ssl: " + ssl() + ']';
729:                }
730:            }
731:
732:            /**
733:             * Handles accepts on an SSLServerSocket or ServerSocket. Creates a {@link
734:             * Connection} for each successful accept().
735:             * 
736:             * @author bela Dec 19, 2002
737:             */
738:            class SocketAcceptor implements  Runnable {
739:                ServerSocket srv_sock = null;
740:                MyInetSocketAddress dest = null;
741:
742:                /**
743:                 * Create an SSLServerSocket or ServerSocket and continuously call
744:                 * accept() on it.
745:                 * @param sock_addr
746:                 */
747:                public SocketAcceptor(MyInetSocketAddress sock_addr,
748:                        MyInetSocketAddress dest) throws Exception {
749:                    this .dest = dest;
750:                    if (sock_addr.ssl()) {
751:                        srv_sock = createSSLServerSocket(sock_addr);
752:                    } else {
753:                        srv_sock = createServerSocket(sock_addr);
754:                    }
755:                    executor.execute(this );
756:                }
757:
758:                public void run() {
759:                    Connection conn;
760:                    Socket s, dest_sock;
761:
762:                    while (srv_sock != null) {
763:                        try {
764:                            s = srv_sock.accept();
765:                            dest_sock = dest.ssl() ? createSSLSocket(dest)
766:                                    : createSocket(dest);
767:                            conn = new Connection(s, dest_sock);
768:                            conn.start();
769:                        } catch (Exception e) {
770:                            log("Proxy.SSLServerSocketAcceptor.run(): exception="
771:                                    + e);
772:                            break;
773:                        }
774:                    }
775:                }
776:
777:                Socket createSocket(InetSocketAddress addr) throws Exception {
778:                    return new Socket(addr.getAddress(), addr.getPort());
779:                }
780:
781:                Socket createSSLSocket(InetSocketAddress addr) throws Exception {
782:                    SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory
783:                            .getDefault();
784:                    SSLSocket sslsocket = (SSLSocket) sslsocketfactory
785:                            .createSocket(addr.getAddress(), addr.getPort());
786:                    return sslsocket;
787:                }
788:
789:                ServerSocket createServerSocket(InetSocketAddress addr)
790:                        throws Exception {
791:                    return new ServerSocket(addr.getPort(), 10, addr
792:                            .getAddress());
793:                }
794:
795:                ServerSocket createSSLServerSocket(InetSocketAddress addr)
796:                        throws Exception {
797:                    SSLServerSocketFactory sslserversocketfactory = (SSLServerSocketFactory) SSLServerSocketFactory
798:                            .getDefault();
799:                    SSLServerSocket sslserversocket = (SSLServerSocket) sslserversocketfactory
800:                            .createServerSocket(addr.getPort(), 10, addr
801:                                    .getAddress());
802:                    return sslserversocket;
803:                }
804:            }
805:
806:            /**
807:             * Handles an incoming SSLSocket or Socket. Looks up the destination in the
808:             * mapping hashmap, key is the incoming socket address. Creates an outgoing
809:             * socket (regular or SSL, depending on settings) and relays data between
810:             * incoming and outgoing sockets. Closes the connection when either incoming
811:             * or outgoing socket is closed, or when stop() is called.
812:             * 
813:             * @author bela Dec 19, 2002
814:             */
815:            static class Connection implements  Relayer.Listener {
816:                Relayer in_to_out = null;
817:                Relayer out_to_in = null;
818:
819:                /**
820:                 * Creates an outgoing (regular or SSL) socket according to the mapping
821:                 * table. Sets both input and output stream. Caller needs to call
822:                 * start() after the instance has been created.
823:                 * @param in The Socket we got as result of accept()
824:                 * @throws Exception Thrown if either the input or output streams cannot
825:                 * be created.
826:                 */
827:                public Connection(Socket in, Socket out) throws Exception {
828:                    in_to_out = new Relayer(in, out, "in-out");
829:                    in_to_out.addListener(this );
830:                    out_to_in = new Relayer(out, in, "out-in");
831:                    out_to_in.addListener(this );
832:                }
833:
834:                /** Starts relaying between incoming and outgoing sockets.
835:                 * Returns immediately (thread is started). 
836:                 * 
837:                 */
838:                public void start() {
839:                    in_to_out.start();
840:                    out_to_in.start();
841:                }
842:
843:                public void stop() {
844:                    if (in_to_out != null) {
845:                        in_to_out.stop();
846:                    }
847:                    if (out_to_in != null) {
848:                        out_to_in.stop();
849:                    }
850:                }
851:
852:                public void connectionClosed() {
853:                    stop();
854:                }
855:            }
856:
857:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.