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
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
124
125
126
127
128
129
130
131 @Override
132 protected FullHttpResponse newHandshakeResponse(FullHttpRequest req, HttpHeaders headers) {
133 HttpMethod method = req.method();
134 if (!GET.equals(method)) {
135 throw new WebSocketServerHandshakeException("Invalid WebSocket handshake method: " + method, req);
136 }
137 HttpHeaders reqHeaders = req.headers();
138 if (!reqHeaders.containsValue(HttpHeaderNames.CONNECTION, HttpHeaderValues.UPGRADE, true)) {
139 throw new WebSocketServerHandshakeException(
140 "not a WebSocket request: a |Connection| header must include a token 'Upgrade'", req);
141 }
142 if (!reqHeaders.contains(HttpHeaderNames.UPGRADE, HttpHeaderValues.WEBSOCKET, true)) {
143 throw new WebSocketServerHandshakeException(
144 "not a WebSocket request: an |Upgrade| header must containing the value 'websocket'", req);
145 }
146 CharSequence key = reqHeaders.get(HttpHeaderNames.SEC_WEBSOCKET_KEY);
147 if (key == null) {
148 throw new WebSocketServerHandshakeException("not a WebSocket request: missing key", req);
149 }
150
151 FullHttpResponse res =
152 new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.SWITCHING_PROTOCOLS,
153 req.content().alloc().buffer(0));
154
155 if (headers != null) {
156 res.headers().add(headers);
157 }
158
159 String acceptSeed = key + WEBSOCKET_07_ACCEPT_GUID;
160 byte[] sha1 = WebSocketUtil.sha1(acceptSeed.getBytes(CharsetUtil.US_ASCII));
161 String accept = WebSocketUtil.base64(sha1);
162
163 if (logger.isDebugEnabled()) {
164 logger.debug("WebSocket version 07 server handshake key: {}, response: {}.", key, accept);
165 }
166
167 res.headers().set(HttpHeaderNames.UPGRADE, HttpHeaderValues.WEBSOCKET)
168 .set(HttpHeaderNames.CONNECTION, HttpHeaderValues.UPGRADE)
169 .set(HttpHeaderNames.SEC_WEBSOCKET_ACCEPT, accept);
170
171 String subprotocols = req.headers().get(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL);
172 if (subprotocols != null) {
173 String selectedSubprotocol = selectSubprotocol(subprotocols);
174 if (selectedSubprotocol == null) {
175 if (logger.isDebugEnabled()) {
176 logger.debug("Requested subprotocol(s) not supported: {}", subprotocols);
177 }
178 } else {
179 res.headers().set(HttpHeaderNames.SEC_WEBSOCKET_PROTOCOL, selectedSubprotocol);
180 }
181 }
182 return res;
183 }
184
185 @Override
186 protected WebSocketFrameDecoder newWebsocketDecoder() {
187 return new WebSocket07FrameDecoder(decoderConfig());
188 }
189
190 @Override
191 protected WebSocketFrameEncoder newWebSocketEncoder() {
192 return new WebSocket07FrameEncoder(false);
193 }
194 }