1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.jboss.netty.example.securechat;
17
18 import java.net.InetAddress;
19 import java.util.logging.Level;
20 import java.util.logging.Logger;
21
22 import org.jboss.netty.channel.Channel;
23 import org.jboss.netty.channel.ChannelEvent;
24 import org.jboss.netty.channel.ChannelFuture;
25 import org.jboss.netty.channel.ChannelFutureListener;
26 import org.jboss.netty.channel.ChannelHandlerContext;
27 import org.jboss.netty.channel.ChannelStateEvent;
28 import org.jboss.netty.channel.ExceptionEvent;
29 import org.jboss.netty.channel.MessageEvent;
30 import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
31 import org.jboss.netty.channel.group.ChannelGroup;
32 import org.jboss.netty.channel.group.DefaultChannelGroup;
33 import org.jboss.netty.handler.ssl.SslHandler;
34
35
36
37
38
39
40
41
42
43 public class SecureChatServerHandler extends SimpleChannelUpstreamHandler {
44
45 private static final Logger logger = Logger.getLogger(
46 SecureChatServerHandler.class.getName());
47
48 static final ChannelGroup channels = new DefaultChannelGroup();
49
50 @Override
51 public void handleUpstream(
52 ChannelHandlerContext ctx, ChannelEvent e) throws Exception {
53 if (e instanceof ChannelStateEvent) {
54 logger.info(e.toString());
55 }
56 super.handleUpstream(ctx, e);
57 }
58
59 @Override
60 public void channelConnected(
61 ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
62
63
64
65 final SslHandler sslHandler = ctx.getPipeline().get(SslHandler.class);
66
67
68 ChannelFuture handshakeFuture = sslHandler.handshake();
69 handshakeFuture.addListener(new Greeter(sslHandler));
70 }
71
72 @Override
73 public void channelDisconnected(
74 ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
75
76
77 channels.remove(e.getChannel());
78 }
79
80 @Override
81 public void messageReceived(
82 ChannelHandlerContext ctx, MessageEvent e) {
83
84
85 String request = (String) e.getMessage();
86
87
88 for (Channel c: channels) {
89 if (c != e.getChannel()) {
90 c.write("[" + e.getChannel().getRemoteAddress() + "] " +
91 request + '\n');
92 } else {
93 c.write("[you] " + request + '\n');
94 }
95 }
96
97
98 if (request.toLowerCase().equals("bye")) {
99 e.getChannel().close();
100 }
101 }
102
103 @Override
104 public void exceptionCaught(
105 ChannelHandlerContext ctx, ExceptionEvent e) {
106 logger.log(
107 Level.WARNING,
108 "Unexpected exception from downstream.",
109 e.getCause());
110 e.getChannel().close();
111 }
112
113
114
115
116
117
118 private static final class Greeter implements ChannelFutureListener {
119
120 private final SslHandler sslHandler;
121
122 Greeter(SslHandler sslHandler) {
123 this.sslHandler = sslHandler;
124 }
125
126 public void operationComplete(ChannelFuture future) throws Exception {
127 if (future.isSuccess()) {
128
129 future.getChannel().write(
130 "Welcome to " + InetAddress.getLocalHost().getHostName() +
131 " secure chat service!\n");
132 future.getChannel().write(
133 "Your session is protected by " +
134 sslHandler.getEngine().getSession().getCipherSuite() +
135 " cipher suite.\n");
136
137
138
139 channels.add(future.getChannel());
140 } else {
141 future.getChannel().close();
142 }
143 }
144 }
145 }