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 }