summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHiroshi Ichikawa <gimite@gmail.com>2011-09-25 22:00:00 +0900
committerHiroshi Ichikawa <gimite@gmail.com>2011-09-25 22:00:00 +0900
commit23e748891097ef9286071f68e6cca1006c2a6e77 (patch)
treea5434b395bea5aede3538960ad0f247f67c0a742
parentd3f2b90b2cb3f0098c10bd55e7c32e62b89aaabd (diff)
downloadweb-socket-js-23e748891097ef9286071f68e6cca1006c2a6e77.tar.gz
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.
-rw-r--r--WebSocketMain.swfbin176009 -> 176778 bytes
-rw-r--r--WebSocketMainInsecure.zipbin166856 -> 169949 bytes
-rw-r--r--flash-src/src/net/gimite/websocket/WebSocket.as42
-rw-r--r--flash-src/src/net/gimite/websocket/WebSocketFrame.as1
4 files changed, 30 insertions, 13 deletions
diff --git a/WebSocketMain.swf b/WebSocketMain.swf
index 016c4d5..1a706a6 100644
--- a/WebSocketMain.swf
+++ b/WebSocketMain.swf
Binary files differ
diff --git a/WebSocketMainInsecure.zip b/WebSocketMainInsecure.zip
index 0d5e693..85f140d 100644
--- a/WebSocketMainInsecure.zip
+++ b/WebSocketMainInsecure.zip
Binary files differ
diff --git a/flash-src/src/net/gimite/websocket/WebSocket.as b/flash-src/src/net/gimite/websocket/WebSocket.as
index db2832c..301af21 100644
--- a/flash-src/src/net/gimite/websocket/WebSocket.as
+++ b/flash-src/src/net/gimite/websocket/WebSocket.as
@@ -13,6 +13,7 @@ import com.hurlant.crypto.tls.TLSSecurityParameters;
import com.hurlant.crypto.tls.TLSSocket;
import flash.display.*;
+import flash.errors.*;
import flash.events.*;
import flash.external.*;
import flash.net.*;
@@ -139,6 +140,7 @@ public class WebSocket extends EventDispatcher {
}
public function send(encData:String):int {
+ logger.log("send: " + data);
var data:String;
try {
data = decodeURIComponent(encData);
@@ -153,9 +155,11 @@ public class WebSocket extends EventDispatcher {
var frame:WebSocketFrame = new WebSocketFrame();
frame.opcode = OPCODE_TEXT;
frame.payload = dataBytes;
- sendFrame(frame);
- logger.log("send: " + data);
- return -1;
+ if (sendFrame(frame)) {
+ return -1;
+ } else {
+ return dataBytes.length;
+ }
} else if (readyState == CLOSING || readyState == CLOSED) {
return dataBytes.length;
} else {
@@ -191,7 +195,7 @@ public class WebSocket extends EventDispatcher {
logger.log("closed");
readyState = CLOSED;
var eventName:String =
- (readyState != CONNECTING && isError) ? "error" : "close";
+ (readyState != CONNECTING && isConnectionError) ? "error" : "close";
this.dispatchEvent(new WebSocketEvent(eventName));
} else {
logger.log("closing");
@@ -303,7 +307,9 @@ public class WebSocket extends EventDispatcher {
if (frame) {
removeBufferBefore(frame.length);
pos = -1;
- if (frame.opcode >= 0x08 && frame.opcode <= 0x0f && frame.payload.length >= 126) {
+ if (frame.rsv != 0) {
+ close(1002, "RSV must be 0.");
+ } else if (frame.opcode >= 0x08 && frame.opcode <= 0x0f && frame.payload.length >= 126) {
close(1004, "Payload of control frame must be less than 126 bytes.");
} else {
switch (frame.opcode) {
@@ -391,14 +397,14 @@ public class WebSocket extends EventDispatcher {
return true;
}
- private function sendPong(payload:ByteArray):void {
+ private function sendPong(payload:ByteArray):Boolean {
var frame:WebSocketFrame = new WebSocketFrame();
frame.opcode = OPCODE_PONG;
frame.payload = payload;
- sendFrame(frame);
+ return sendFrame(frame);
}
- private function sendFrame(frame:WebSocketFrame):void {
+ private function sendFrame(frame:WebSocketFrame):Boolean {
var plength:uint = frame.payload.length;
@@ -409,7 +415,8 @@ public class WebSocket extends EventDispatcher {
}
var header:ByteArray = new ByteArray();
- header.writeByte((frame.fin ? 0x80 : 0x00) | frame.opcode); // FIN + opcode
+ // FIN + RSV + opcode
+ header.writeByte((frame.fin ? 0x80 : 0x00) | (frame.rsv << 4) | frame.opcode);
if (plength <= 125) {
header.writeByte(0x80 | plength); // Masked + length
} else if (plength > 125 && plength < 65536) {
@@ -430,9 +437,17 @@ public class WebSocket extends EventDispatcher {
maskedPayload[i] = mask[i % 4] ^ frame.payload[i];
}
- socket.writeBytes(header);
- socket.writeBytes(maskedPayload);
- socket.flush();
+ try {
+ socket.writeBytes(header);
+ socket.writeBytes(maskedPayload);
+ socket.flush();
+ } catch (ex:IOError) {
+ logger.error("IOError while sending frame");
+ // TODO Fire close event if it hasn't
+ readyState = CLOSED;
+ return false;
+ }
+ return true;
}
@@ -447,8 +462,9 @@ public class WebSocket extends EventDispatcher {
return null;
}
+ frame.fin = (buffer[0] & 0x80) != 0;
+ frame.rsv = (buffer[0] & 0x70) >> 4;
frame.opcode = buffer[0] & 0x0f;
- frame.fin = (buffer[0] & 0x80) != 0;
plength = buffer[1] & 0x7f;
if (plength == 126) {
diff --git a/flash-src/src/net/gimite/websocket/WebSocketFrame.as b/flash-src/src/net/gimite/websocket/WebSocketFrame.as
index 119bcce..060e9aa 100644
--- a/flash-src/src/net/gimite/websocket/WebSocketFrame.as
+++ b/flash-src/src/net/gimite/websocket/WebSocketFrame.as
@@ -7,6 +7,7 @@ import flash.utils.ByteArray;
public class WebSocketFrame {
public var fin:Boolean = true;
+ public var rsv:int = 0;
public var opcode:int = -1;
public var payload:ByteArray;
// Not used when used as a parameter of sendFrame().