Skip to content

Commit d74f699

Browse files
committed
-fix error on receiving a close frame( any control frame after the opening handshake )
-fix ignoring content of a received handshake -better handling for multiple frames at once
1 parent dcc3db9 commit d74f699

File tree

3 files changed

+34
-21
lines changed

3 files changed

+34
-21
lines changed

src/net/tootallnate/websocket/Draft.java

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public static Handshakedata translateHandshake( byte[] buffer, int readcount ){
7777
byte[] lines = message.array ();
7878
int previndex = 0;
7979
int index = findNewLine ( lines , previndex );
80-
if ( index == -1 )
80+
if ( index == lines.length )
8181
return null;
8282
String line = new String ( lines , previndex , index - previndex );
8383
//TODO Care about resources here like: GET /chat HTTP/1.1
@@ -86,9 +86,9 @@ public static Handshakedata translateHandshake( byte[] buffer, int readcount ){
8686

8787
previndex = index + 2;
8888
index = findNewLine ( lines , previndex );
89-
90-
while ( index != -1 ) {
91-
int length = index - previndex;
89+
int length = index - previndex;
90+
while ( length != 0 ) {
91+
9292
line = new String ( lines , previndex , length );
9393
if ( index != previndex ) {
9494
String[] pair = line.split ( ":" , 2 );
@@ -98,15 +98,18 @@ public static Handshakedata translateHandshake( byte[] buffer, int readcount ){
9898
}
9999
previndex = index + 2;
100100
index = findNewLine ( lines , previndex );
101+
length = index - previndex;
101102
}
102103
return draft;
103104
}
104-
105+
106+
/**will return the index of the first \r\n or the index off the last element in arr*/
105107
public static int findNewLine( byte[] arr , int offset ) {
106108
int len = arr.length - 1;
107-
for ( int i = offset ; i < len ; i++ )
109+
int i = offset;
110+
for ( ; i < len ; i++ )
108111
if( arr[i] == (byte)'\r' && arr[ i + 1 ] == (byte)'\n' )
109112
return i;
110-
return -1;
113+
return i;//the end of input will be handled like newline
111114
}
112115
}

src/net/tootallnate/websocket/WebSocket.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ else if( role == Role.CLIENT){
205205
}
206206
}
207207
catch (InvalidHandshakeException e) {
208-
abort( "draft "+draft.getClass ().getSimpleName ()+" refuses handshake: " + e.getMessage ());
208+
abort( "draft "+draft+" refuses handshake: " + e.getMessage ());
209209
}
210210
}
211211
else{
@@ -217,12 +217,15 @@ else if( role == Role.CLIENT){
217217
else if( curop == Opcode.CLOSING){
218218
sendFrame ( new FramedataImpl1 ( Opcode.CLOSING ) );
219219
close();
220+
continue;
220221
}
221222
else if( curop == Opcode.PING){
222223
sendFrame ( new FramedataImpl1 ( Opcode.PONG ) );
224+
continue;
223225
}
224226
else if( curop == Opcode.PONG){
225227
wsl.onPong ();
228+
continue;
226229
}
227230
if( currentframe == null){
228231
if( f.isFin () ){

src/net/tootallnate/websocket/drafts/Draft_10.java

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -137,31 +137,38 @@ else if( payloadlength == 126 ){
137137

138138
return frame;
139139
}
140+
140141
@Override
141142
public ByteBuffer createBinaryFrame( Framedata framedata ) {
142143
byte[] mes = framedata.getPayloadData ();
143144
boolean mask = framedata.getTransfereMasked();
144-
int sizebytes = mes.length <= 125 ? 1 : mes.length <= 65535 ? 2 : 4;//4 bytes length currently not useable
145-
ByteBuffer buf = ByteBuffer.allocate ( 1 + ( sizebytes != 1 ? sizebytes + 1 : sizebytes ) +( mask ? 4 : 0 ) + mes.length );
145+
int sizebytes = mes.length==0?0:mes.length <= 125 ? 1 : mes.length <= 65535 ? 2 : 4;//4 bytes length currently not useable
146+
ByteBuffer buf = ByteBuffer.allocate ( 1 + ( sizebytes > 1 ? sizebytes + 1 : sizebytes ) +( mask ? 4 : 0 ) + mes.length );
146147
byte optcode = fromOpcode ( framedata.getOpcode () );
147148
byte one = ( byte ) ( framedata.isFin () ? -128 : 0 );
148149
one |= optcode;
149150
buf.put ( one );
150151
byte[] payloadlengthbytes = toByteArray ( mes.length , sizebytes );
151152
assert( payloadlengthbytes.length == sizebytes );
152-
if( sizebytes == 1){
153+
if( sizebytes == 0){
154+
//controllframe
155+
}
156+
else if( sizebytes == 1){
153157
buf.put ( (byte)( (byte)payloadlengthbytes[0] | ( mask ? (byte)-128 : 0 ) ) );
154158
}
155-
else{
156-
if( sizebytes == 2 ){
157-
buf.put ( (byte)( (byte)126 | ( mask ? (byte)-128 : 0 ) ) );
158-
}
159-
else if( sizebytes == 8 ){
160-
buf.put ( (byte)( (byte)127 | ( mask ? (byte)-128 : 0 ) ) );
161-
}
162-
else throw new RuntimeException ( "Size representation not supported/specified" );
159+
else if( sizebytes == 2 ){
160+
buf.put ( (byte)( (byte)126 | ( mask ? (byte)-128 : 0 ) ) );
163161
buf.put ( payloadlengthbytes );
164162
}
163+
else if( sizebytes == 8 ){
164+
buf.put ( (byte)( (byte)127 | ( mask ? (byte)-128 : 0 ) ) );
165+
buf.put ( payloadlengthbytes );
166+
}
167+
else
168+
throw new RuntimeException ( "Size representation not supported/specified" );
169+
170+
171+
165172

166173
if( mask ){
167174
ByteBuffer maskkey = ByteBuffer.allocate ( 4 );
@@ -198,12 +205,12 @@ public List<Framedata> createFrames( byte[] binary , boolean mask ) {
198205
public boolean acceptHandshakeAsServer( Handshakedata handshakedata ) throws InvalidHandshakeException {
199206
//TODO Do a more detailed formal handshake test
200207
String vers = handshakedata.getFieldValue ( "Sec-WebSocket-Version" );
201-
if( vers != null ){
208+
if( !vers.isEmpty () ){
202209
int v;
203210
try {
204211
v = new Integer ( vers.trim () );
205212
} catch ( NumberFormatException e ) {
206-
throw new InvalidHandshakeException( e);
213+
return false;
207214
}
208215
if( v == 7 || v == 8 )//g
209216
return true;

0 commit comments

Comments
 (0)