3131import org .java_websocket .extensions .*;
3232import org .java_websocket .framing .*;
3333import org .java_websocket .handshake .*;
34+ import org .java_websocket .protocols .IProtocol ;
35+ import org .java_websocket .protocols .Protocol ;
3436import org .java_websocket .util .*;
3537import org .java_websocket .util .Base64 ;
3638
@@ -57,6 +59,16 @@ public class Draft_6455 extends Draft {
5759 */
5860 private List <IExtension > knownExtensions ;
5961
62+ /**
63+ * Attribute for the used protocol in this draft
64+ */
65+ private IProtocol protocol ;
66+
67+ /**
68+ * Attribute for all available protocols in this draft
69+ */
70+ private List <IProtocol > knownProtocols ;
71+
6072 /**
6173 * Attribute for the current continuous frame
6274 */
@@ -99,7 +111,21 @@ public Draft_6455( IExtension inputExtension ) {
99111 * @param inputExtensions the extensions which should be used for this draft
100112 */
101113 public Draft_6455 ( List <IExtension > inputExtensions ) {
102- knownExtensions = new ArrayList <IExtension >();
114+ this ( inputExtensions , Collections .<IProtocol >singletonList ( new Protocol ( "" ) ));
115+ }
116+
117+ /**
118+ * Constructor for the websocket protocol specified by RFC 6455 with custom extensions and protocols
119+ *
120+ * @param inputExtensions the extensions which should be used for this draft
121+ * @param inputProtocols the protocols which should be used for this draft
122+ */
123+ public Draft_6455 ( List <IExtension > inputExtensions , List <IProtocol > inputProtocols ) {
124+ if (inputExtensions == null || inputProtocols == null ) {
125+ throw new IllegalArgumentException ();
126+ }
127+ knownExtensions = new ArrayList <IExtension >( inputExtensions .size ());
128+ knownProtocols = new ArrayList <IProtocol >( inputProtocols .size ());
103129 boolean hasDefault = false ;
104130 byteBufferList = new ArrayList <ByteBuffer >();
105131 for ( IExtension inputExtension : inputExtensions ) {
@@ -112,24 +138,38 @@ public Draft_6455( List<IExtension> inputExtensions ) {
112138 if ( !hasDefault ) {
113139 knownExtensions .add ( this .knownExtensions .size (), extension );
114140 }
141+ knownProtocols .addAll ( inputProtocols );
115142 }
116143
117144 @ Override
118145 public HandshakeState acceptHandshakeAsServer ( ClientHandshake handshakedata ) throws InvalidHandshakeException {
119146 int v = readVersion ( handshakedata );
120147 if ( v != 13 )
121148 return HandshakeState .NOT_MATCHED ;
149+ HandshakeState extensionState = HandshakeState .NOT_MATCHED ;
122150 String requestedExtension = handshakedata .getFieldValue ( "Sec-WebSocket-Extensions" );
123151 for ( IExtension knownExtension : knownExtensions ) {
124152 if ( knownExtension .acceptProvidedExtensionAsServer ( requestedExtension ) ) {
125153 extension = knownExtension ;
126- return HandshakeState .MATCHED ;
154+ extensionState = HandshakeState .MATCHED ;
155+ break ;
156+ }
157+ }
158+ HandshakeState protocolState = HandshakeState .NOT_MATCHED ;
159+ String requestedProtocol = handshakedata .getFieldValue ( "Sec-WebSocket-Protocol" );
160+ for ( IProtocol knownProtocol : knownProtocols ) {
161+ if ( knownProtocol .acceptProvidedProtocol ( requestedProtocol ) ) {
162+ protocol = knownProtocol ;
163+ protocolState = HandshakeState .MATCHED ;
164+ break ;
127165 }
128166 }
167+ if (protocolState == HandshakeState .MATCHED && extensionState == HandshakeState .MATCHED ) {
168+ return HandshakeState .MATCHED ;
169+ }
129170 return HandshakeState .NOT_MATCHED ;
130171 }
131172
132-
133173 @ Override
134174 public HandshakeState acceptHandshakeAsClient ( ClientHandshake request , ServerHandshake response ) throws InvalidHandshakeException {
135175 if (! basicAccept ( response )) {
@@ -145,13 +185,27 @@ public HandshakeState acceptHandshakeAsClient( ClientHandshake request, ServerHa
145185 if ( !seckey_challenge .equals ( seckey_answere ) )
146186 return HandshakeState .NOT_MATCHED ;
147187
188+ HandshakeState extensionState = HandshakeState .NOT_MATCHED ;
148189 String requestedExtension = response .getFieldValue ( "Sec-WebSocket-Extensions" );
149190 for ( IExtension knownExtension : knownExtensions ) {
150191 if ( knownExtension .acceptProvidedExtensionAsClient ( requestedExtension ) ) {
151192 extension = knownExtension ;
152- return HandshakeState .MATCHED ;
193+ extensionState = HandshakeState .MATCHED ;
194+ break ;
195+ }
196+ }
197+ HandshakeState protocolState = HandshakeState .NOT_MATCHED ;
198+ String requestedProtocol = response .getFieldValue ( "Sec-WebSocket-Protocol" );
199+ for ( IProtocol knownProtocol : knownProtocols ) {
200+ if ( knownProtocol .acceptProvidedProtocol ( requestedProtocol ) ) {
201+ protocol = knownProtocol ;
202+ protocolState = HandshakeState .MATCHED ;
203+ break ;
153204 }
154205 }
206+ if (protocolState == HandshakeState .MATCHED && extensionState == HandshakeState .MATCHED ) {
207+ return HandshakeState .MATCHED ;
208+ }
155209 return HandshakeState .NOT_MATCHED ;
156210 }
157211
@@ -172,6 +226,23 @@ public List<IExtension> getKnownExtensions() {
172226 return knownExtensions ;
173227 }
174228
229+ /**
230+ * Getter for the protocol which is used by this draft
231+ *
232+ * @return the protocol which is used or null, if handshake is not yet done or no valid protocols
233+ */
234+ public IProtocol getProtocol () {
235+ return protocol ;
236+ }
237+
238+ /**
239+ * Getter for all available protocols for this draft
240+ * @return the protocols which are enabled for this draft
241+ */
242+ public List <IProtocol > getKnownProtocols () {
243+ return knownProtocols ;
244+ }
245+
175246 @ Override
176247 public ClientHandshakeBuilder postProcessHandshakeRequestAsClient ( ClientHandshakeBuilder request ) {
177248 request .put ( "Upgrade" , "websocket" );
@@ -183,12 +254,27 @@ public ClientHandshakeBuilder postProcessHandshakeRequestAsClient( ClientHandsha
183254 StringBuilder requestedExtensions = new StringBuilder ();
184255 for ( IExtension knownExtension : knownExtensions ) {
185256 if ( knownExtension .getProvidedExtensionAsClient () != null && knownExtension .getProvidedExtensionAsClient ().length () != 0 ) {
186- requestedExtensions .append ( knownExtension .getProvidedExtensionAsClient () ).append ( "; " );
257+ if (requestedExtensions .length () > 0 ) {
258+ requestedExtensions .append ( ", " );
259+ }
260+ requestedExtensions .append ( knownExtension .getProvidedExtensionAsClient () );
187261 }
188262 }
189263 if ( requestedExtensions .length () != 0 ) {
190264 request .put ( "Sec-WebSocket-Extensions" , requestedExtensions .toString () );
191265 }
266+ StringBuilder requestedProtocols = new StringBuilder ();
267+ for ( IProtocol knownProtocol : knownProtocols ) {
268+ if ( knownProtocol .getProvidedProtocol ().length () != 0 ) {
269+ if (requestedProtocols .length () > 0 ) {
270+ requestedProtocols .append ( ", " );
271+ }
272+ requestedProtocols .append ( knownProtocol .getProvidedProtocol () );
273+ }
274+ }
275+ if ( requestedProtocols .length () != 0 ) {
276+ request .put ( "Sec-WebSocket-Protocol" , requestedProtocols .toString () );
277+ }
192278 return request ;
193279 }
194280
@@ -203,6 +289,9 @@ public HandshakeBuilder postProcessHandshakeResponseAsServer( ClientHandshake re
203289 if ( getExtension ().getProvidedExtensionAsServer ().length () != 0 ) {
204290 response .put ( "Sec-WebSocket-Extensions" , getExtension ().getProvidedExtensionAsServer () );
205291 }
292+ if ( getProtocol () != null && getProtocol ().getProvidedProtocol ().length () != 0 ) {
293+ response .put ( "Sec-WebSocket-Protocol" , getProtocol ().getProvidedProtocol () );
294+ }
206295 response .setHttpStatusMessage ( "Web Socket Protocol Handshake" );
207296 response .put ( "Server" , "TooTallNate Java-WebSocket" );
208297 response .put ( "Date" , getServerTime () );
@@ -215,7 +304,11 @@ public Draft copyInstance() {
215304 for ( IExtension extension : getKnownExtensions () ) {
216305 newExtensions .add ( extension .copyInstance () );
217306 }
218- return new Draft_6455 ( newExtensions );
307+ ArrayList <IProtocol > newProtocols = new ArrayList <IProtocol >();
308+ for ( IProtocol protocol : getKnownProtocols () ) {
309+ newProtocols .add ( protocol .copyInstance () );
310+ }
311+ return new Draft_6455 ( newExtensions , newProtocols );
219312 }
220313
221314 @ Override
@@ -440,6 +533,7 @@ public void reset() {
440533 extension .reset ();
441534 }
442535 extension = new DefaultExtension ();
536+ protocol = null ;
443537 }
444538
445539 /**
@@ -617,6 +711,8 @@ public String toString() {
617711 String result = super .toString ();
618712 if ( getExtension () != null )
619713 result += " extension: " + getExtension ().toString ();
714+ if ( getProtocol () != null )
715+ result += " protocol: " + getProtocol ().toString ();
620716 return result ;
621717 }
622718
@@ -627,12 +723,15 @@ public boolean equals( Object o ) {
627723
628724 Draft_6455 that = ( Draft_6455 ) o ;
629725
630- return extension != null ? extension .equals ( that .extension ) : that .extension == null ;
726+ if ( extension != null ? !extension .equals ( that .extension ) : that .extension != null ) return false ;
727+ return protocol != null ? protocol .equals ( that .protocol ) : that .protocol == null ;
631728 }
632729
633730 @ Override
634731 public int hashCode () {
635- return extension != null ? extension .hashCode () : 0 ;
732+ int result = extension != null ? extension .hashCode () : 0 ;
733+ result = 31 * result + ( protocol != null ? protocol .hashCode () : 0 );
734+ return result ;
636735 }
637736
638737 /**
0 commit comments