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.handler.codec.http.DefaultFullHttpResponse;
19 import io.netty.handler.codec.http.FullHttpRequest;
20 import io.netty.handler.codec.http.FullHttpResponse;
21 import io.netty.handler.codec.http.HttpHeaderNames;
22 import io.netty.handler.codec.http.HttpHeaderValues;
23 import io.netty.handler.codec.http.HttpHeaders;
24 import io.netty.handler.codec.http.HttpMethod;
25 import io.netty.handler.codec.http.HttpResponseStatus;
26 import io.netty.util.CharsetUtil;
27
28 import static io.netty.handler.codec.http.HttpMethod.GET;
29 import static io.netty.handler.codec.http.HttpVersion.*;
30
31
32
33
34
35
36
37
38 public class WebSocketServerHandshaker08 extends WebSocketServerHandshaker {
39
40 public static final String WEBSOCKET_08_ACCEPT_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 public WebSocketServerHandshaker08(
57 String webSocketURL, String subprotocols, boolean allowExtensions, int maxFramePayloadLength) {
58 this(webSocketURL, subprotocols, allowExtensions, maxFramePayloadLength, false);
59 }
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78 public WebSocketServerHandshaker08(
79 String webSocketURL, String subprotocols, boolean allowExtensions, int maxFramePayloadLength,
80 boolean allowMaskMismatch) {
81 this(webSocketURL, subprotocols, WebSocketDecoderConfig.newBuilder()
82 .allowExtensions(allowExtensions)
83 .maxFramePayloadLength(maxFramePayloadLength)
84 .allowMaskMismatch(allowMaskMismatch)
85 .build());
86 }
87
88
89
90
91
92
93
94
95
96
97
98
99 public WebSocketServerHandshaker08(
100 String webSocketURL, String subprotocols, WebSocketDecoderConfig decoderConfig) {
101 super(WebSocketVersion.V08, webSocketURL, subprotocols, decoderConfig);
102 }
103
104 WebSocketServerHandshaker08(boolean isSecure, String host, String path,
105 String subprotocols, WebSocketDecoderConfig decoderConfig) {
106 super(WebSocketVersion.V08, isSecure, host, path, subprotocols, decoderConfig);
107 }
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143 @Override
144 protected FullHttpResponse newHandshakeResponse(FullHttpRequest req, HttpHeaders headers) {
145 HttpMethod method = req.method();
146 if (!GET.equals(method)) {
147 throw new WebSocketServerHandshakeException("Invalid WebSocket handshake method: " + method, req);
148 }
149
150 HttpHeaders reqHeaders = req.headers();
151 if (!reqHeaders.containsValue(HttpHeaderNames.CONNECTION, HttpHeaderValues.UPGRADE, true)) {
152 throw new WebSocketServerHandshakeException(
153 "not a WebSocket request: a |Connection| header must include a token 'Upgrade'", req);
154 }
155 if (!reqHeaders.contains(HttpHeaderNames.UPGRADE, HttpHeaderValues.WEBSOCKET, true)) {
156 throw new WebSocketServerHandshakeException(
157 "not a WebSocket request: an |Upgrade| header must containing the value 'websocket'", req);
158 }
159 CharSequence key = reqHeaders.get(HttpHeaderNames.SEC_WEBSOCKET_KEY);
160 if (key == null) {
161 throw new WebSocketServerHandshakeException("not a WebSocket request: missing key", req);
162 }
163
164 FullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.SWITCHING_PROTOCOLS,
165 req.content().alloc().buffer(0));
166
167 if (headers != null) {
168 res.headers().add(headers);
169 }
170
171 String acceptSeed = key + WEBSOCKET_08_ACCEPT_GUID;
172 byte[] sha1 = WebSocketUtil.sha1(acceptSeed.getBytes(CharsetUtil.US_ASCII));
173 String accept = WebSocketUtil.base64(sha1);
174
175 if (logger.isDebugEnabled()) {
176 logger.debug("WebSocket version 08 server handshake key: {}, response: {}", key, accept);
177 }
178
179 res.headers().set(HttpHeaderNames.UPGRADE, HttpHeaderValues.WEBSOCKET)
180 .set(HttpHeaderNames.CONNECTION, HttpHeaderValues.UPGRADE)
181 .set(HttpHeaderNames.SEC_WEBSOCKET_ACCEPT, accept);
182
183 String subprotocols = req.headers().get(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL);
184 if (subprotocols != null) {
185 String selectedSubprotocol = selectSubprotocol(subprotocols);
186 if (selectedSubprotocol == null) {
187 if (logger.isDebugEnabled()) {
188 logger.debug("Requested subprotocol(s) not supported: {}", subprotocols);
189 }
190 } else {
191 res.headers().set(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL, selectedSubprotocol);
192 }
193 }
194 return res;
195 }
196
197 @Override
198 protected WebSocketFrameDecoder newWebsocketDecoder() {
199 return new WebSocket08FrameDecoder(decoderConfig());
200 }
201
202 @Override
203 protected WebSocketFrameEncoder newWebSocketEncoder() {
204 return new WebSocket08FrameEncoder(false);
205 }
206 }