1 /*
2 * Copyright 2012 The Netty Project
3 *
4 * The Netty Project licenses this file to you under the Apache License,
5 * version 2.0 (the "License"); you may not use this file except in compliance
6 * with the License. You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations
14 * under the License.
15 */
16 package org.jboss.netty.handler.codec.http.websocketx;
17
18 import org.jboss.netty.channel.Channel;
19 import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
20 import org.jboss.netty.handler.codec.http.HttpHeaders.Names;
21 import org.jboss.netty.handler.codec.http.HttpRequest;
22 import org.jboss.netty.handler.codec.http.HttpResponse;
23 import org.jboss.netty.handler.codec.http.HttpResponseStatus;
24 import org.jboss.netty.handler.codec.http.HttpVersion;
25
26 /**
27 * Instances the appropriate handshake class to use for servers
28 */
29 public class WebSocketServerHandshakerFactory {
30
31 private final String webSocketURL;
32
33 private final String subprotocols;
34
35 private final boolean allowExtensions;
36
37 private final long maxFramePayloadLength;
38
39 /**
40 * Constructor
41
42 * @param subprotocols
43 * CSV of supported protocols. Null if sub protocols not supported.
44 * @param allowExtensions
45 * Allow extensions to be used in the reserved bits of the web socket frame
46 */
47 public WebSocketServerHandshakerFactory(String webSocketURL, String subprotocols, boolean allowExtensions) {
48 this(webSocketURL, subprotocols, allowExtensions, Long.MAX_VALUE);
49 }
50
51 /**
52 * Constructor
53 *
54 * @param webSocketURL
55 * URL for web socket communications. e.g "ws://myhost.com/mypath".
56 * Subsequent web socket frames will be sent to this URL.
57 * @param subprotocols
58 * CSV of supported protocols. Null if sub protocols not supported.
59 * @param allowExtensions
60 * Allow extensions to be used in the reserved bits of the web socket frame
61 * @param maxFramePayloadLength
62 * Maximum allowable frame payload length. Setting this value to your application's
63 * requirement may reduce denial of service attacks using long data frames.
64 */
65 public WebSocketServerHandshakerFactory(String webSocketURL, String subprotocols, boolean allowExtensions,
66 long maxFramePayloadLength) {
67 this.webSocketURL = webSocketURL;
68 this.subprotocols = subprotocols;
69 this.allowExtensions = allowExtensions;
70 this.maxFramePayloadLength = maxFramePayloadLength;
71 }
72
73 /**
74 * Instances a new handshaker
75 *
76 * @return A new WebSocketServerHandshaker for the requested web socket version. Null if web
77 * socket version is not supported.
78 */
79 public WebSocketServerHandshaker newHandshaker(HttpRequest req) {
80
81 String version = req.getHeader(Names.SEC_WEBSOCKET_VERSION);
82 if (version != null) {
83 if (version.equals(WebSocketVersion.V13.toHttpHeaderValue())) {
84 // Version 13 of the wire protocol - RFC 6455 (version 17 of the draft hybi specification).
85 return new WebSocketServerHandshaker13(
86 webSocketURL, subprotocols, allowExtensions, maxFramePayloadLength);
87 } else if (version.equals(WebSocketVersion.V08.toHttpHeaderValue())) {
88 // Version 8 of the wire protocol - version 10 of the draft hybi specification.
89 return new WebSocketServerHandshaker08(
90 webSocketURL, subprotocols, allowExtensions, maxFramePayloadLength);
91 } else {
92 return null;
93 }
94 } else {
95 // Assume version 00 where version header was not specified
96 return new WebSocketServerHandshaker00(
97 webSocketURL, subprotocols, maxFramePayloadLength);
98 }
99 }
100
101 /**
102 * Return that we need cannot not support the web socket version
103 *
104 * @param channel
105 * Channel
106 */
107 public void sendUnsupportedWebSocketVersionResponse(Channel channel) {
108 HttpResponse res = new DefaultHttpResponse(
109 HttpVersion.HTTP_1_1,
110 HttpResponseStatus.SWITCHING_PROTOCOLS);
111 res.setStatus(HttpResponseStatus.UPGRADE_REQUIRED);
112 res.setHeader(Names.SEC_WEBSOCKET_VERSION, WebSocketVersion.V13.toHttpHeaderValue());
113 channel.write(res);
114 }
115
116 }