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 java.net.URI;
19  import java.util.Map;
20  
21  import org.jboss.netty.channel.Channel;
22  import org.jboss.netty.channel.ChannelFuture;
23  import org.jboss.netty.handler.codec.http.HttpResponse;
24  
25  /**
26   * Base class for web socket client handshake implementations
27   */
28  public abstract class WebSocketClientHandshaker {
29  
30      private final URI webSocketUrl;
31  
32      private final WebSocketVersion version;
33  
34      private boolean handshakeComplete;
35  
36      private final String expectedSubprotocol;
37  
38      private String actualSubprotocol;
39  
40      protected final Map<String, String> customHeaders;
41  
42      private final long maxFramePayloadLength;
43  
44      /**
45       * Base constructor with default values
46       *
47       * @param webSocketUrl
48       *            URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be
49       *            sent to this URL.
50       * @param version
51       *            Version of web socket specification to use to connect to the server
52       * @param subprotocol
53       *            Sub protocol request sent to the server.
54       * @param customHeaders
55       *            Map of custom headers to add to the client request
56       */
57      protected WebSocketClientHandshaker(URI webSocketUrl, WebSocketVersion version, String subprotocol,
58                                          Map<String, String> customHeaders) {
59          this(webSocketUrl, version, subprotocol, customHeaders, Long.MAX_VALUE);
60      }
61  
62      /**
63       * Base constructor
64       *
65       * @param webSocketUrl
66       *            URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be
67       *            sent to this URL.
68       * @param version
69       *            Version of web socket specification to use to connect to the server
70       * @param subprotocol
71       *            CSV of requested subprotocol(s) sent to the server.
72       * @param customHeaders
73       *            Map of custom headers to add to the client request
74       * @param maxFramePayloadLength
75       *            Maximum length of a frame's payload
76       */
77      protected WebSocketClientHandshaker(URI webSocketUrl, WebSocketVersion version, String subprotocol,
78                                          Map<String, String> customHeaders, long maxFramePayloadLength) {
79          this.webSocketUrl = webSocketUrl;
80          this.version = version;
81          expectedSubprotocol = subprotocol;
82          this.customHeaders = customHeaders;
83          this.maxFramePayloadLength = maxFramePayloadLength;
84      }
85  
86      /**
87       * Returns the URI to the web socket. e.g. "ws://myhost.com/path"
88       */
89      public URI getWebSocketUrl() {
90          return webSocketUrl;
91      }
92  
93      /**
94       * Version of the web socket specification that is being used
95       */
96      public WebSocketVersion getVersion() {
97          return version;
98      }
99  
100     /**
101      * Returns the max length for any frame's payload
102      */
103     public long getMaxFramePayloadLength() {
104         return maxFramePayloadLength;
105     }
106 
107     /**
108      * Flag to indicate if the opening handshake is complete
109      */
110     public boolean isHandshakeComplete() {
111         return handshakeComplete;
112     }
113 
114     protected void setHandshakeComplete() {
115         handshakeComplete = true;
116     }
117 
118     /**
119      * Returns the CSV of requested subprotocol(s) sent to the server as specified in the constructor
120      */
121     public String getExpectedSubprotocol() {
122         return expectedSubprotocol;
123     }
124 
125     /**
126      * Returns the subprotocol response sent by the server. Only available after end of handshake.
127      * Null if no subprotocol was requested or confirmed by the server.
128      */
129     public String getActualSubprotocol() {
130         return actualSubprotocol;
131     }
132 
133     protected void setActualSubprotocol(String actualSubprotocol) {
134         this.actualSubprotocol = actualSubprotocol;
135     }
136 
137     /**
138      * Begins the opening handshake
139      *
140      * @param channel
141      *            Channel
142      */
143     public abstract ChannelFuture handshake(Channel channel) throws Exception;
144 
145     /**
146      * Validates and finishes the opening handshake initiated by {@link #handshake}}.
147      *
148      * @param channel
149      *            Channel
150      * @param response
151      *            HTTP response containing the closing handshake details
152      */
153     public abstract void finishHandshake(Channel channel, HttpResponse response);
154 }