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
105
106
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 @Override
139 protected FullHttpResponse newHandshakeResponse(FullHttpRequest req, HttpHeaders headers) {
140 HttpMethod method = req.method();
141 if (!GET.equals(method)) {
142 throw new WebSocketServerHandshakeException("Invalid WebSocket handshake method: " + method, req);
143 }
144
145 CharSequence key = req.headers().get(HttpHeaderNames.SEC_WEBSOCKET_KEY);
146 if (key == null) {
147 throw new WebSocketServerHandshakeException("not a WebSocket request: missing key", req);
148 }
149
150 FullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.SWITCHING_PROTOCOLS,
151 req.content().alloc().buffer(0));
152
153 if (headers != null) {
154 res.headers().add(headers);
155 }
156
157 String acceptSeed = key + WEBSOCKET_08_ACCEPT_GUID;
158 byte[] sha1 = WebSocketUtil.sha1(acceptSeed.getBytes(CharsetUtil.US_ASCII));
159 String accept = WebSocketUtil.base64(sha1);
160
161 if (logger.isDebugEnabled()) {
162 logger.debug("WebSocket version 08 server handshake key: {}, response: {}", key, accept);
163 }
164
165 res.headers().set(HttpHeaderNames.UPGRADE, HttpHeaderValues.WEBSOCKET)
166 .set(HttpHeaderNames.CONNECTION, HttpHeaderValues.UPGRADE)
167 .set(HttpHeaderNames.SEC_WEBSOCKET_ACCEPT, accept);
168
169 String subprotocols = req.headers().get(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL);
170 if (subprotocols != null) {
171 String selectedSubprotocol = selectSubprotocol(subprotocols);
172 if (selectedSubprotocol == null) {
173 if (logger.isDebugEnabled()) {
174 logger.debug("Requested subprotocol(s) not supported: {}", subprotocols);
175 }
176 } else {
177 res.headers().set(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL, selectedSubprotocol);
178 }
179 }
180 return res;
181 }
182
183 @Override
184 protected WebSocketFrameDecoder newWebsocketDecoder() {
185 return new WebSocket08FrameDecoder(decoderConfig());
186 }
187
188 @Override
189 protected WebSocketFrameEncoder newWebSocketEncoder() {
190 return new WebSocket08FrameEncoder(false);
191 }
192 }