View Javadoc

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 }