1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.jboss.netty.handler.codec.http.websocketx;
17
18 import org.jboss.netty.channel.Channel;
19 import org.jboss.netty.channel.ChannelFuture;
20 import org.jboss.netty.channel.ChannelFutureListener;
21 import org.jboss.netty.channel.ChannelHandler;
22 import org.jboss.netty.channel.ChannelHandlerContext;
23 import org.jboss.netty.channel.ChannelPipeline;
24 import org.jboss.netty.channel.Channels;
25 import org.jboss.netty.handler.codec.http.HttpChunkAggregator;
26 import org.jboss.netty.handler.codec.http.HttpRequest;
27 import org.jboss.netty.handler.codec.http.HttpRequestDecoder;
28 import org.jboss.netty.handler.codec.http.HttpResponse;
29 import org.jboss.netty.handler.codec.http.HttpResponseEncoder;
30 import org.jboss.netty.util.internal.StringUtil;
31
32 import java.util.Collections;
33 import java.util.LinkedHashSet;
34 import java.util.Set;
35
36
37
38
39 public abstract class WebSocketServerHandshaker {
40
41
42
43
44 public static final String SUB_PROTOCOL_WILDCARD = "*";
45
46 private final String webSocketUrl;
47
48 private final String[] subprotocols;
49
50 private final WebSocketVersion version;
51
52 private final long maxFramePayloadLength;
53
54 private String selectedSubprotocol;
55
56
57
58
59
60
61 public static final ChannelFutureListener HANDSHAKE_LISTENER = new ChannelFutureListener() {
62 public void operationComplete(ChannelFuture future) throws Exception {
63 if (!future.isSuccess()) {
64 Channels.fireExceptionCaught(future.getChannel(), future.getCause());
65 }
66 }
67 };
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82 protected WebSocketServerHandshaker(WebSocketVersion version, String webSocketUrl, String subprotocols) {
83 this(version, webSocketUrl, subprotocols, Long.MAX_VALUE);
84 }
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101 protected WebSocketServerHandshaker(WebSocketVersion version, String webSocketUrl, String subprotocols,
102 long maxFramePayloadLength) {
103 this.version = version;
104 this.webSocketUrl = webSocketUrl;
105 if (subprotocols != null) {
106 String[] subprotocolArray = StringUtil.split(subprotocols, ',');
107 for (int i = 0; i < subprotocolArray.length; i++) {
108 subprotocolArray[i] = subprotocolArray[i].trim();
109 }
110 this.subprotocols = subprotocolArray;
111 } else {
112 this.subprotocols = new String[0];
113 }
114 this.maxFramePayloadLength = maxFramePayloadLength;
115 }
116
117
118
119
120 public String getWebSocketUrl() {
121 return webSocketUrl;
122 }
123
124
125
126
127 public Set<String> getSubprotocols() {
128 Set<String> ret = new LinkedHashSet<String>();
129 Collections.addAll(ret, subprotocols);
130 return ret;
131 }
132
133
134
135
136 public WebSocketVersion getVersion() {
137 return version;
138 }
139
140
141
142
143 public long getMaxFramePayloadLength() {
144 return maxFramePayloadLength;
145 }
146
147
148
149
150
151
152
153
154
155 public abstract ChannelFuture handshake(Channel channel, HttpRequest req);
156
157
158
159
160 protected ChannelFuture writeHandshakeResponse(
161 Channel channel, HttpResponse res, ChannelHandler encoder, ChannelHandler decoder) {
162 final ChannelPipeline p = channel.getPipeline();
163 if (p.get(HttpChunkAggregator.class) != null) {
164 p.remove(HttpChunkAggregator.class);
165 }
166
167 final String httpEncoderName = p.getContext(HttpResponseEncoder.class).getName();
168 p.addAfter(httpEncoderName, "wsencoder", encoder);
169 p.get(HttpRequestDecoder.class).replace("wsdecoder", decoder);
170
171 final ChannelFuture future = channel.write(res);
172 future.addListener(new ChannelFutureListener() {
173 public void operationComplete(ChannelFuture future) {
174 p.remove(httpEncoderName);
175 }
176 });
177
178 return future;
179 }
180
181
182
183
184
185
186
187
188
189 public abstract ChannelFuture close(Channel channel, CloseWebSocketFrame frame);
190
191
192
193
194
195
196
197
198 protected String selectSubprotocol(String requestedSubprotocols) {
199 if (requestedSubprotocols == null || subprotocols.length == 0) {
200 return null;
201 }
202
203 String[] requestedSubprotocolArray = StringUtil.split(requestedSubprotocols, ',');
204 for (String p : requestedSubprotocolArray) {
205 String requestedSubprotocol = p.trim();
206
207 for (String supportedSubprotocol : subprotocols) {
208 if (SUB_PROTOCOL_WILDCARD.equals(supportedSubprotocol) ||
209 requestedSubprotocol.equals(supportedSubprotocol)) {
210 return requestedSubprotocol;
211 }
212 }
213 }
214
215
216 return null;
217 }
218
219
220
221
222
223
224
225 public String getSelectedSubprotocol() {
226 return selectedSubprotocol;
227 }
228
229 protected void setSelectedSubprotocol(String value) {
230 selectedSubprotocol = value;
231 }
232
233 }