1
2
3
4
5
6
7
8
9
10
11
12
13
14
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.channel.ChannelHandler;
21 import org.jboss.netty.channel.ChannelHandlerContext;
22 import org.jboss.netty.channel.ChannelPipeline;
23 import org.jboss.netty.handler.codec.http.HttpResponse;
24 import org.jboss.netty.handler.codec.http.HttpResponseDecoder;
25
26 import java.net.URI;
27 import java.util.Map;
28
29
30
31
32 public abstract class WebSocketClientHandshaker {
33
34 private final URI webSocketUrl;
35
36 private final WebSocketVersion version;
37
38 private volatile boolean handshakeComplete;
39
40 private final String expectedSubprotocol;
41
42 private volatile String actualSubprotocol;
43
44 protected final Map<String, String> customHeaders;
45
46 private final long maxFramePayloadLength;
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 protected WebSocketClientHandshaker(URI webSocketUrl, WebSocketVersion version, String subprotocol,
62 Map<String, String> customHeaders) {
63 this(webSocketUrl, version, subprotocol, customHeaders, Long.MAX_VALUE);
64 }
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81 protected WebSocketClientHandshaker(URI webSocketUrl, WebSocketVersion version, String subprotocol,
82 Map<String, String> customHeaders, long maxFramePayloadLength) {
83 this.webSocketUrl = webSocketUrl;
84 this.version = version;
85 expectedSubprotocol = subprotocol;
86 this.customHeaders = customHeaders;
87 this.maxFramePayloadLength = maxFramePayloadLength;
88 }
89
90
91
92
93 public URI getWebSocketUrl() {
94 return webSocketUrl;
95 }
96
97
98
99
100 public WebSocketVersion getVersion() {
101 return version;
102 }
103
104
105
106
107 public long getMaxFramePayloadLength() {
108 return maxFramePayloadLength;
109 }
110
111
112
113
114 public boolean isHandshakeComplete() {
115 return handshakeComplete;
116 }
117
118 protected void setHandshakeComplete() {
119 handshakeComplete = true;
120 }
121
122
123
124
125 public String getExpectedSubprotocol() {
126 return expectedSubprotocol;
127 }
128
129
130
131
132
133 public String getActualSubprotocol() {
134 return actualSubprotocol;
135 }
136
137 protected void setActualSubprotocol(String actualSubprotocol) {
138 this.actualSubprotocol = actualSubprotocol;
139 }
140
141
142
143
144
145
146
147 public abstract ChannelFuture handshake(Channel channel) throws Exception;
148
149
150
151
152
153
154
155
156
157 public abstract void finishHandshake(Channel channel, HttpResponse response);
158
159
160
161
162
163
164
165
166
167 static void replaceDecoder(Channel channel, ChannelHandler wsDecoder) {
168 ChannelPipeline p = channel.getPipeline();
169 ChannelHandlerContext httpDecoderCtx = p.getContext(HttpResponseDecoder.class);
170 if (httpDecoderCtx == null) {
171 throw new IllegalStateException("can't find an HTTP decoder from the pipeline");
172 }
173 p.addAfter(httpDecoderCtx.getName(), "ws-decoder", wsDecoder);
174 p.remove(httpDecoderCtx.getName());
175 }
176 }