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