1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.handler.codec.http.websocketx;
17
18 import io.netty.buffer.ByteBuf;
19 import io.netty.buffer.Unpooled;
20 import io.netty.channel.Channel;
21 import io.netty.channel.ChannelFuture;
22 import io.netty.channel.ChannelPromise;
23 import io.netty.handler.codec.http.DefaultFullHttpResponse;
24 import io.netty.handler.codec.http.FullHttpRequest;
25 import io.netty.handler.codec.http.FullHttpResponse;
26 import io.netty.handler.codec.http.HttpHeaders;
27 import io.netty.handler.codec.http.HttpHeaders.Names;
28 import io.netty.handler.codec.http.HttpHeaders.Values;
29 import io.netty.handler.codec.http.HttpResponseStatus;
30
31 import java.util.regex.Pattern;
32
33 import static io.netty.handler.codec.http.HttpHeaders.Names.*;
34 import static io.netty.handler.codec.http.HttpHeaders.Values.*;
35 import static io.netty.handler.codec.http.HttpVersion.*;
36
37
38
39
40
41
42
43
44
45
46
47 public class WebSocketServerHandshaker00 extends WebSocketServerHandshaker {
48
49 private static final Pattern BEGINNING_DIGIT = Pattern.compile("[^0-9]");
50 private static final Pattern BEGINNING_SPACE = Pattern.compile("[^ ]");
51
52
53
54
55
56
57
58
59
60
61
62
63
64 public WebSocketServerHandshaker00(String webSocketURL, String subprotocols, int maxFramePayloadLength) {
65 super(WebSocketVersion.V00, webSocketURL, subprotocols, maxFramePayloadLength);
66 }
67
68
69
70
71
72
73
74
75
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 @Override
109 protected FullHttpResponse newHandshakeResponse(FullHttpRequest req, HttpHeaders headers) {
110
111
112 if (!req.headers().containsValue(CONNECTION, Values.UPGRADE, true)
113 || !WEBSOCKET.equalsIgnoreCase(req.headers().get(Names.UPGRADE))) {
114 throw new WebSocketHandshakeException("not a WebSocket handshake request: missing upgrade");
115 }
116
117
118 boolean isHixie76 = req.headers().contains(SEC_WEBSOCKET_KEY1) && req.headers().contains(SEC_WEBSOCKET_KEY2);
119
120
121 FullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, new HttpResponseStatus(101,
122 isHixie76 ? "WebSocket Protocol Handshake" : "Web Socket Protocol Handshake"));
123 if (headers != null) {
124 res.headers().add(headers);
125 }
126
127 res.headers().add(Names.UPGRADE, WEBSOCKET);
128 res.headers().add(CONNECTION, Values.UPGRADE);
129
130
131 if (isHixie76) {
132
133 res.headers().add(SEC_WEBSOCKET_ORIGIN, req.headers().get(ORIGIN));
134 res.headers().add(SEC_WEBSOCKET_LOCATION, uri());
135 String subprotocols = req.headers().get(SEC_WEBSOCKET_PROTOCOL);
136 if (subprotocols != null) {
137 String selectedSubprotocol = selectSubprotocol(subprotocols);
138 if (selectedSubprotocol == null) {
139 if (logger.isDebugEnabled()) {
140 logger.debug("Requested subprotocol(s) not supported: {}", subprotocols);
141 }
142 } else {
143 res.headers().add(SEC_WEBSOCKET_PROTOCOL, selectedSubprotocol);
144 }
145 }
146
147
148 String key1 = req.headers().get(SEC_WEBSOCKET_KEY1);
149 String key2 = req.headers().get(SEC_WEBSOCKET_KEY2);
150 int a = (int) (Long.parseLong(BEGINNING_DIGIT.matcher(key1).replaceAll("")) /
151 BEGINNING_SPACE.matcher(key1).replaceAll("").length());
152 int b = (int) (Long.parseLong(BEGINNING_DIGIT.matcher(key2).replaceAll("")) /
153 BEGINNING_SPACE.matcher(key2).replaceAll("").length());
154 long c = req.content().readLong();
155 ByteBuf input = Unpooled.buffer(16);
156 input.writeInt(a);
157 input.writeInt(b);
158 input.writeLong(c);
159 res.content().writeBytes(WebSocketUtil.md5(input.array()));
160 } else {
161
162 res.headers().add(WEBSOCKET_ORIGIN, req.headers().get(ORIGIN));
163 res.headers().add(WEBSOCKET_LOCATION, uri());
164 String protocol = req.headers().get(WEBSOCKET_PROTOCOL);
165 if (protocol != null) {
166 res.headers().add(WEBSOCKET_PROTOCOL, selectSubprotocol(protocol));
167 }
168 }
169 return res;
170 }
171
172
173
174
175
176
177
178
179
180 @Override
181 public ChannelFuture close(Channel channel, CloseWebSocketFrame frame, ChannelPromise promise) {
182 return channel.writeAndFlush(frame, promise);
183 }
184
185 @Override
186 protected WebSocketFrameDecoder newWebsocketDecoder() {
187 return new WebSocket00FrameDecoder(maxFramePayloadLength());
188 }
189
190 @Override
191 protected WebSocketFrameEncoder newWebSocketEncoder() {
192 return new WebSocket00FrameEncoder();
193 }
194 }