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.channel.ChannelFuture;
20 import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
21 import org.jboss.netty.handler.codec.http.HttpHeaders.Names;
22 import org.jboss.netty.handler.codec.http.HttpRequest;
23 import org.jboss.netty.handler.codec.http.HttpResponse;
24 import org.jboss.netty.handler.codec.http.HttpResponseStatus;
25 import org.jboss.netty.handler.codec.http.HttpVersion;
26
27 /**
28 * Instances the appropriate handshake class to use for servers
29 */
30 public class WebSocketServerHandshakerFactory {
31
32 private final String webSocketURL;
33
34 private final String subprotocols;
35
36 private final boolean allowExtensions;
37
38 private final long maxFramePayloadLength;
39
40 /**
41 * Constructor
42
43 * @param subprotocols
44 * CSV of supported protocols. Null if sub protocols not supported.
45 * @param allowExtensions
46 * Allow extensions to be used in the reserved bits of the web socket frame
47 */
48 public WebSocketServerHandshakerFactory(String webSocketURL, String subprotocols, boolean allowExtensions) {
49 this(webSocketURL, subprotocols, allowExtensions, Long.MAX_VALUE);
50 }
51
52 /**
53 * Constructor
54 *
55 * @param webSocketURL
56 * URL for web socket communications. e.g "ws://myhost.com/mypath".
57 * Subsequent web socket frames will be sent to this URL.
58 * @param subprotocols
59 * CSV of supported protocols. Null if sub protocols not supported.
60 * @param allowExtensions
61 * Allow extensions to be used in the reserved bits of the web socket frame
62 * @param maxFramePayloadLength
63 * Maximum allowable frame payload length. Setting this value to your application's
64 * requirement may reduce denial of service attacks using long data frames.
65 */
66 public WebSocketServerHandshakerFactory(String webSocketURL, String subprotocols, boolean allowExtensions,
67 long maxFramePayloadLength) {
68 this.webSocketURL = webSocketURL;
69 this.subprotocols = subprotocols;
70 this.allowExtensions = allowExtensions;
71 this.maxFramePayloadLength = maxFramePayloadLength;
72 }
73
74 /**
75 * Instances a new handshaker
76 *
77 * @return A new WebSocketServerHandshaker for the requested web socket version. Null if web
78 * socket version is not supported.
79 */
80 public WebSocketServerHandshaker newHandshaker(HttpRequest req) {
81
82 String version = req.getHeader(Names.SEC_WEBSOCKET_VERSION);
83
84 if (version != null) {
85 if (version.equals(WebSocketVersion.V13.toHttpHeaderValue())) {
86 // Version 13 of the wire protocol - RFC 6455 (version 17 of the draft hybi specification).
87 return new WebSocketServerHandshaker13(
88 webSocketURL, subprotocols, allowExtensions, maxFramePayloadLength);
89 } else if (version.equals(WebSocketVersion.V08.toHttpHeaderValue())) {
90 // Version 8 of the wire protocol - version 10 of the draft hybi specification.
91 return new WebSocketServerHandshaker08(
92 webSocketURL, subprotocols, allowExtensions, maxFramePayloadLength);
93 } else if (version.equals(WebSocketVersion.V07.toHttpHeaderValue())) {
94 // Version 8 of the wire protocol - version 07 of the draft hybi specification.
95 return new WebSocketServerHandshaker07(
96 webSocketURL, subprotocols, allowExtensions, maxFramePayloadLength);
97 } else {
98 return null;
99 }
100 } else {
101 // Assume version 00 where version header was not specified
102 return new WebSocketServerHandshaker00(
103 webSocketURL, subprotocols, maxFramePayloadLength);
104 }
105 }
106
107 /**
108 * Return that we need cannot not support the web socket version
109 *
110 * @param channel
111 * Channel
112 */
113 public ChannelFuture sendUnsupportedWebSocketVersionResponse(Channel channel) {
114 HttpResponse res = new DefaultHttpResponse(
115 HttpVersion.HTTP_1_1,
116 HttpResponseStatus.SWITCHING_PROTOCOLS);
117 res.setStatus(HttpResponseStatus.UPGRADE_REQUIRED);
118 res.setHeader(Names.SEC_WEBSOCKET_VERSION, WebSocketVersion.V13.toHttpHeaderValue());
119 return channel.write(res);
120 }
121
122 }