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 WebSocketServerHandshaker07 extends WebSocketServerHandshaker {
39
40 public static final String WEBSOCKET_07_ACCEPT_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 public WebSocketServerHandshaker07(
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 WebSocketServerHandshaker07(
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 public WebSocketServerHandshaker07(String webSocketURL, String subprotocols, WebSocketDecoderConfig decoderConfig) {
95 super(WebSocketVersion.V07, webSocketURL, subprotocols, decoderConfig);
96 }
97
98 WebSocketServerHandshaker07(boolean isSecure, String host, String path,
99 String subprotocols, WebSocketDecoderConfig decoderConfig) {
100 super(WebSocketVersion.V07, isSecure, host, path, subprotocols, decoderConfig);
101 }
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 @Override
137 protected FullHttpResponse newHandshakeResponse(FullHttpRequest req, HttpHeaders headers) {
138 HttpMethod method = req.method();
139 if (!GET.equals(method)) {
140 throw new WebSocketServerHandshakeException("Invalid WebSocket handshake method: " + method, req);
141 }
142 HttpHeaders reqHeaders = req.headers();
143 if (!reqHeaders.containsValue(HttpHeaderNames.CONNECTION, HttpHeaderValues.UPGRADE, true)) {
144 throw new WebSocketServerHandshakeException(
145 "not a WebSocket request: a |Connection| header must include a token 'Upgrade'", req);
146 }
147 if (!reqHeaders.contains(HttpHeaderNames.UPGRADE, HttpHeaderValues.WEBSOCKET, true)) {
148 throw new WebSocketServerHandshakeException(
149 "not a WebSocket request: an |Upgrade| header must containing the value 'websocket'", req);
150 }
151 CharSequence key = reqHeaders.get(HttpHeaderNames.SEC_WEBSOCKET_KEY);
152 if (key == null) {
153 throw new WebSocketServerHandshakeException("not a WebSocket request: missing key", req);
154 }
155
156 FullHttpResponse res =
157 new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.SWITCHING_PROTOCOLS,
158 req.content().alloc().buffer(0));
159
160 if (headers != null) {
161 res.headers().add(headers);
162 }
163
164 String acceptSeed = key + WEBSOCKET_07_ACCEPT_GUID;
165 byte[] sha1 = WebSocketUtil.sha1(acceptSeed.getBytes(CharsetUtil.US_ASCII));
166 String accept = WebSocketUtil.base64(sha1);
167
168 if (logger.isDebugEnabled()) {
169 logger.debug("WebSocket version 07 server handshake key: {}, response: {}.", key, accept);
170 }
171
172 res.headers().set(HttpHeaderNames.UPGRADE, HttpHeaderValues.WEBSOCKET)
173 .set(HttpHeaderNames.CONNECTION, HttpHeaderValues.UPGRADE)
174 .set(HttpHeaderNames.SEC_WEBSOCKET_ACCEPT, accept);
175
176 String subprotocols = req.headers().get(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL);
177 if (subprotocols != null) {
178 String selectedSubprotocol = selectSubprotocol(subprotocols);
179 if (selectedSubprotocol == null) {
180 if (logger.isDebugEnabled()) {
181 logger.debug("Requested subprotocol(s) not supported: {}", subprotocols);
182 }
183 } else {
184 res.headers().set(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL, selectedSubprotocol);
185 }
186 }
187 return res;
188 }
189
190 @Override
191 protected WebSocketFrameDecoder newWebsocketDecoder() {
192 return new WebSocket07FrameDecoder(decoderConfig());
193 }
194
195 @Override
196 protected WebSocketFrameEncoder newWebSocketEncoder() {
197 return new WebSocket07FrameEncoder(false);
198 }
199 }