Skip to content

Commit 23e7488

Browse files
committed
Handling IOError on send().
Firing onclose instead of onerror on errors except for connection error. Not sure this is correct, but it seems this is what Chrome does. Adding check of RSV field.
1 parent d3f2b90 commit 23e7488

File tree

4 files changed

+30
-13
lines changed

4 files changed

+30
-13
lines changed

WebSocketMain.swf

769 Bytes
Binary file not shown.

WebSocketMainInsecure.zip

3.02 KB
Binary file not shown.

flash-src/src/net/gimite/websocket/WebSocket.as

+29-13
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import com.hurlant.crypto.tls.TLSSecurityParameters;
1313
import com.hurlant.crypto.tls.TLSSocket;
1414

1515
import flash.display.*;
16+
import flash.errors.*;
1617
import flash.events.*;
1718
import flash.external.*;
1819
import flash.net.*;
@@ -139,6 +140,7 @@ public class WebSocket extends EventDispatcher {
139140
}
140141

141142
public function send(encData:String):int {
143+
logger.log("send: " + data);
142144
var data:String;
143145
try {
144146
data = decodeURIComponent(encData);
@@ -153,9 +155,11 @@ public class WebSocket extends EventDispatcher {
153155
var frame:WebSocketFrame = new WebSocketFrame();
154156
frame.opcode = OPCODE_TEXT;
155157
frame.payload = dataBytes;
156-
sendFrame(frame);
157-
logger.log("send: " + data);
158-
return -1;
158+
if (sendFrame(frame)) {
159+
return -1;
160+
} else {
161+
return dataBytes.length;
162+
}
159163
} else if (readyState == CLOSING || readyState == CLOSED) {
160164
return dataBytes.length;
161165
} else {
@@ -191,7 +195,7 @@ public class WebSocket extends EventDispatcher {
191195
logger.log("closed");
192196
readyState = CLOSED;
193197
var eventName:String =
194-
(readyState != CONNECTING && isError) ? "error" : "close";
198+
(readyState != CONNECTING && isConnectionError) ? "error" : "close";
195199
this.dispatchEvent(new WebSocketEvent(eventName));
196200
} else {
197201
logger.log("closing");
@@ -303,7 +307,9 @@ public class WebSocket extends EventDispatcher {
303307
if (frame) {
304308
removeBufferBefore(frame.length);
305309
pos = -1;
306-
if (frame.opcode >= 0x08 && frame.opcode <= 0x0f && frame.payload.length >= 126) {
310+
if (frame.rsv != 0) {
311+
close(1002, "RSV must be 0.");
312+
} else if (frame.opcode >= 0x08 && frame.opcode <= 0x0f && frame.payload.length >= 126) {
307313
close(1004, "Payload of control frame must be less than 126 bytes.");
308314
} else {
309315
switch (frame.opcode) {
@@ -391,14 +397,14 @@ public class WebSocket extends EventDispatcher {
391397
return true;
392398
}
393399

394-
private function sendPong(payload:ByteArray):void {
400+
private function sendPong(payload:ByteArray):Boolean {
395401
var frame:WebSocketFrame = new WebSocketFrame();
396402
frame.opcode = OPCODE_PONG;
397403
frame.payload = payload;
398-
sendFrame(frame);
404+
return sendFrame(frame);
399405
}
400406

401-
private function sendFrame(frame:WebSocketFrame):void {
407+
private function sendFrame(frame:WebSocketFrame):Boolean {
402408

403409
var plength:uint = frame.payload.length;
404410

@@ -409,7 +415,8 @@ public class WebSocket extends EventDispatcher {
409415
}
410416

411417
var header:ByteArray = new ByteArray();
412-
header.writeByte((frame.fin ? 0x80 : 0x00) | frame.opcode); // FIN + opcode
418+
// FIN + RSV + opcode
419+
header.writeByte((frame.fin ? 0x80 : 0x00) | (frame.rsv << 4) | frame.opcode);
413420
if (plength <= 125) {
414421
header.writeByte(0x80 | plength); // Masked + length
415422
} else if (plength > 125 && plength < 65536) {
@@ -430,9 +437,17 @@ public class WebSocket extends EventDispatcher {
430437
maskedPayload[i] = mask[i % 4] ^ frame.payload[i];
431438
}
432439

433-
socket.writeBytes(header);
434-
socket.writeBytes(maskedPayload);
435-
socket.flush();
440+
try {
441+
socket.writeBytes(header);
442+
socket.writeBytes(maskedPayload);
443+
socket.flush();
444+
} catch (ex:IOError) {
445+
logger.error("IOError while sending frame");
446+
// TODO Fire close event if it hasn't
447+
readyState = CLOSED;
448+
return false;
449+
}
450+
return true;
436451

437452
}
438453

@@ -447,8 +462,9 @@ public class WebSocket extends EventDispatcher {
447462
return null;
448463
}
449464

465+
frame.fin = (buffer[0] & 0x80) != 0;
466+
frame.rsv = (buffer[0] & 0x70) >> 4;
450467
frame.opcode = buffer[0] & 0x0f;
451-
frame.fin = (buffer[0] & 0x80) != 0;
452468
plength = buffer[1] & 0x7f;
453469

454470
if (plength == 126) {

flash-src/src/net/gimite/websocket/WebSocketFrame.as

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import flash.utils.ByteArray;
77

88
public class WebSocketFrame {
99
public var fin:Boolean = true;
10+
public var rsv:int = 0;
1011
public var opcode:int = -1;
1112
public var payload:ByteArray;
1213
// Not used when used as a parameter of sendFrame().

0 commit comments

Comments
 (0)