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.buffer.ChannelBuffer;
19 import org.jboss.netty.buffer.ChannelBuffers;
20 import org.jboss.netty.channel.Channel;
21 import org.jboss.netty.channel.ChannelFuture;
22 import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
23 import org.jboss.netty.handler.codec.http.HttpHeaders.Names;
24 import org.jboss.netty.handler.codec.http.HttpHeaders.Values;
25 import org.jboss.netty.handler.codec.http.HttpRequest;
26 import org.jboss.netty.handler.codec.http.HttpResponse;
27 import org.jboss.netty.handler.codec.http.HttpResponseStatus;
28 import org.jboss.netty.logging.InternalLogger;
29 import org.jboss.netty.logging.InternalLoggerFactory;
30
31 import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.*;
32 import static org.jboss.netty.handler.codec.http.HttpHeaders.Values.*;
33 import static org.jboss.netty.handler.codec.http.HttpVersion.*;
34
35
36
37
38
39
40
41
42
43
44
45 public class WebSocketServerHandshaker00 extends WebSocketServerHandshaker {
46
47 private static final InternalLogger logger = InternalLoggerFactory.getInstance(WebSocketServerHandshaker00.class);
48
49
50
51
52
53
54
55
56
57
58 public WebSocketServerHandshaker00(String webSocketURL, String subprotocols) {
59 this(webSocketURL, subprotocols, Long.MAX_VALUE);
60 }
61
62
63
64
65
66
67
68
69
70
71
72
73
74 public WebSocketServerHandshaker00(String webSocketURL, String subprotocols, long maxFramePayloadLength) {
75 super(WebSocketVersion.V00, webSocketURL, subprotocols, maxFramePayloadLength);
76 }
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123 @Override
124 public ChannelFuture handshake(Channel channel, HttpRequest req) {
125
126 if (logger.isDebugEnabled()) {
127 logger.debug(String.format("Channel %s WS Version 00 server handshake", channel.getId()));
128 }
129
130
131 if (!Values.UPGRADE.equalsIgnoreCase(req.headers().get(CONNECTION))
132 || !WEBSOCKET.equalsIgnoreCase(req.headers().get(Names.UPGRADE))) {
133 throw new WebSocketHandshakeException("not a WebSocket handshake request: missing upgrade");
134 }
135
136
137 boolean isHixie76 = req.headers().contains(SEC_WEBSOCKET_KEY1) && req.headers().contains(SEC_WEBSOCKET_KEY2);
138
139
140 HttpResponse res = new DefaultHttpResponse(HTTP_1_1, new HttpResponseStatus(101,
141 isHixie76 ? "WebSocket Protocol Handshake" : "Web Socket Protocol Handshake"));
142 res.headers().add(Names.UPGRADE, WEBSOCKET);
143 res.headers().add(CONNECTION, Values.UPGRADE);
144
145
146 if (isHixie76) {
147
148 res.headers().add(SEC_WEBSOCKET_ORIGIN, req.headers().get(ORIGIN));
149 res.headers().add(SEC_WEBSOCKET_LOCATION, getWebSocketUrl());
150 String subprotocols = req.headers().get(SEC_WEBSOCKET_PROTOCOL);
151 if (subprotocols != null) {
152 String selectedSubprotocol = selectSubprotocol(subprotocols);
153 if (selectedSubprotocol == null) {
154 throw new WebSocketHandshakeException("Requested subprotocol(s) not supported: " + subprotocols);
155 } else {
156 res.headers().add(SEC_WEBSOCKET_PROTOCOL, selectedSubprotocol);
157 setSelectedSubprotocol(selectedSubprotocol);
158 }
159 }
160
161
162 String key1 = req.headers().get(SEC_WEBSOCKET_KEY1);
163 String key2 = req.headers().get(SEC_WEBSOCKET_KEY2);
164 int a = (int) (Long.parseLong(key1.replaceAll("[^0-9]", "")) / key1.replaceAll("[^ ]", "").length());
165 int b = (int) (Long.parseLong(key2.replaceAll("[^0-9]", "")) / key2.replaceAll("[^ ]", "").length());
166 long c = req.getContent().readLong();
167 ChannelBuffer input = ChannelBuffers.buffer(16);
168 input.writeInt(a);
169 input.writeInt(b);
170 input.writeLong(c);
171 res.setContent(WebSocketUtil.md5(input));
172 } else {
173
174 res.headers().add(WEBSOCKET_ORIGIN, req.headers().get(ORIGIN));
175 res.headers().add(WEBSOCKET_LOCATION, getWebSocketUrl());
176 String protocol = req.headers().get(WEBSOCKET_PROTOCOL);
177 if (protocol != null) {
178 res.headers().add(WEBSOCKET_PROTOCOL, selectSubprotocol(protocol));
179 }
180 }
181
182 return writeHandshakeResponse(
183 channel, res, new WebSocket00FrameEncoder(), new WebSocket00FrameDecoder(getMaxFramePayloadLength()));
184 }
185
186
187
188
189
190
191
192
193
194 @Override
195 public ChannelFuture close(Channel channel, CloseWebSocketFrame frame) {
196 return channel.write(frame);
197 }
198 }