diff --git a/Example/Example.pidb b/Example/Example.pidb index 27af9f9f..62976b35 100644 Binary files a/Example/Example.pidb and b/Example/Example.pidb differ diff --git a/Example/bin/Debug/example.exe b/Example/bin/Debug/example.exe index c637b265..4f5e6111 100755 Binary files a/Example/bin/Debug/example.exe and b/Example/bin/Debug/example.exe differ diff --git a/Example/bin/Debug/example.exe.mdb b/Example/bin/Debug/example.exe.mdb index 96fc8011..3ffadea6 100644 Binary files a/Example/bin/Debug/example.exe.mdb and b/Example/bin/Debug/example.exe.mdb differ diff --git a/Example/bin/Debug/websocket-sharp.dll b/Example/bin/Debug/websocket-sharp.dll index 682adfab..88f7fba0 100755 Binary files a/Example/bin/Debug/websocket-sharp.dll and b/Example/bin/Debug/websocket-sharp.dll differ diff --git a/Example/bin/Debug/websocket-sharp.dll.mdb b/Example/bin/Debug/websocket-sharp.dll.mdb index 43a868d1..e270cce5 100644 Binary files a/Example/bin/Debug/websocket-sharp.dll.mdb and b/Example/bin/Debug/websocket-sharp.dll.mdb differ diff --git a/Example/bin/Debug_Ubuntu/example.exe b/Example/bin/Debug_Ubuntu/example.exe index de793734..bfe82989 100755 Binary files a/Example/bin/Debug_Ubuntu/example.exe and b/Example/bin/Debug_Ubuntu/example.exe differ diff --git a/Example/bin/Debug_Ubuntu/example.exe.mdb b/Example/bin/Debug_Ubuntu/example.exe.mdb index 73202efa..93ae86b2 100644 Binary files a/Example/bin/Debug_Ubuntu/example.exe.mdb and b/Example/bin/Debug_Ubuntu/example.exe.mdb differ diff --git a/Example/bin/Debug_Ubuntu/websocket-sharp.dll b/Example/bin/Debug_Ubuntu/websocket-sharp.dll index 5b28603b..7ed31d1b 100755 Binary files a/Example/bin/Debug_Ubuntu/websocket-sharp.dll and b/Example/bin/Debug_Ubuntu/websocket-sharp.dll differ diff --git a/Example/bin/Debug_Ubuntu/websocket-sharp.dll.mdb b/Example/bin/Debug_Ubuntu/websocket-sharp.dll.mdb index 81092b7c..0efa287d 100644 Binary files a/Example/bin/Debug_Ubuntu/websocket-sharp.dll.mdb and b/Example/bin/Debug_Ubuntu/websocket-sharp.dll.mdb differ diff --git a/Example/bin/Release/example.exe b/Example/bin/Release/example.exe index 9f34ec86..301372fa 100755 Binary files a/Example/bin/Release/example.exe and b/Example/bin/Release/example.exe differ diff --git a/Example/bin/Release/websocket-sharp.dll b/Example/bin/Release/websocket-sharp.dll index ac47adbd..6b8b7f95 100755 Binary files a/Example/bin/Release/websocket-sharp.dll and b/Example/bin/Release/websocket-sharp.dll differ diff --git a/Example/bin/Release_Ubuntu/example.exe b/Example/bin/Release_Ubuntu/example.exe index e4250124..9a14c68a 100755 Binary files a/Example/bin/Release_Ubuntu/example.exe and b/Example/bin/Release_Ubuntu/example.exe differ diff --git a/Example/bin/Release_Ubuntu/websocket-sharp.dll b/Example/bin/Release_Ubuntu/websocket-sharp.dll index 038f0657..198c3156 100755 Binary files a/Example/bin/Release_Ubuntu/websocket-sharp.dll and b/Example/bin/Release_Ubuntu/websocket-sharp.dll differ diff --git a/Example1/bin/Debug/example1.exe b/Example1/bin/Debug/example1.exe index b25a2121..a9d8d99e 100755 Binary files a/Example1/bin/Debug/example1.exe and b/Example1/bin/Debug/example1.exe differ diff --git a/Example1/bin/Debug/example1.exe.mdb b/Example1/bin/Debug/example1.exe.mdb index f5eeb4c1..e64a19d5 100644 Binary files a/Example1/bin/Debug/example1.exe.mdb and b/Example1/bin/Debug/example1.exe.mdb differ diff --git a/Example1/bin/Debug/websocket-sharp.dll b/Example1/bin/Debug/websocket-sharp.dll index 682adfab..88f7fba0 100755 Binary files a/Example1/bin/Debug/websocket-sharp.dll and b/Example1/bin/Debug/websocket-sharp.dll differ diff --git a/Example1/bin/Debug/websocket-sharp.dll.mdb b/Example1/bin/Debug/websocket-sharp.dll.mdb index 43a868d1..e270cce5 100644 Binary files a/Example1/bin/Debug/websocket-sharp.dll.mdb and b/Example1/bin/Debug/websocket-sharp.dll.mdb differ diff --git a/Example1/bin/Debug_Ubuntu/example1.exe b/Example1/bin/Debug_Ubuntu/example1.exe index 87d50dc1..3ff6ed44 100755 Binary files a/Example1/bin/Debug_Ubuntu/example1.exe and b/Example1/bin/Debug_Ubuntu/example1.exe differ diff --git a/Example1/bin/Debug_Ubuntu/example1.exe.mdb b/Example1/bin/Debug_Ubuntu/example1.exe.mdb index ce473bc6..344060af 100644 Binary files a/Example1/bin/Debug_Ubuntu/example1.exe.mdb and b/Example1/bin/Debug_Ubuntu/example1.exe.mdb differ diff --git a/Example1/bin/Debug_Ubuntu/websocket-sharp.dll b/Example1/bin/Debug_Ubuntu/websocket-sharp.dll index 5b28603b..7ed31d1b 100755 Binary files a/Example1/bin/Debug_Ubuntu/websocket-sharp.dll and b/Example1/bin/Debug_Ubuntu/websocket-sharp.dll differ diff --git a/Example1/bin/Debug_Ubuntu/websocket-sharp.dll.mdb b/Example1/bin/Debug_Ubuntu/websocket-sharp.dll.mdb index 81092b7c..0efa287d 100644 Binary files a/Example1/bin/Debug_Ubuntu/websocket-sharp.dll.mdb and b/Example1/bin/Debug_Ubuntu/websocket-sharp.dll.mdb differ diff --git a/Example1/bin/Release/example1.exe b/Example1/bin/Release/example1.exe index 67ff2922..ba927585 100755 Binary files a/Example1/bin/Release/example1.exe and b/Example1/bin/Release/example1.exe differ diff --git a/Example1/bin/Release/websocket-sharp.dll b/Example1/bin/Release/websocket-sharp.dll index ac47adbd..6b8b7f95 100755 Binary files a/Example1/bin/Release/websocket-sharp.dll and b/Example1/bin/Release/websocket-sharp.dll differ diff --git a/Example1/bin/Release_Ubuntu/example1.exe b/Example1/bin/Release_Ubuntu/example1.exe index 3daabb66..cf6ec23a 100755 Binary files a/Example1/bin/Release_Ubuntu/example1.exe and b/Example1/bin/Release_Ubuntu/example1.exe differ diff --git a/Example1/bin/Release_Ubuntu/websocket-sharp.dll b/Example1/bin/Release_Ubuntu/websocket-sharp.dll index 038f0657..198c3156 100755 Binary files a/Example1/bin/Release_Ubuntu/websocket-sharp.dll and b/Example1/bin/Release_Ubuntu/websocket-sharp.dll differ diff --git a/Example2/Example2.pidb b/Example2/Example2.pidb index f04e2b7b..5c4f5f39 100644 Binary files a/Example2/Example2.pidb and b/Example2/Example2.pidb differ diff --git a/Example2/bin/Debug/example2.exe b/Example2/bin/Debug/example2.exe index 1c990636..de8a7827 100755 Binary files a/Example2/bin/Debug/example2.exe and b/Example2/bin/Debug/example2.exe differ diff --git a/Example2/bin/Debug/example2.exe.mdb b/Example2/bin/Debug/example2.exe.mdb index a7d513b6..1b2c9af3 100644 Binary files a/Example2/bin/Debug/example2.exe.mdb and b/Example2/bin/Debug/example2.exe.mdb differ diff --git a/Example2/bin/Debug/websocket-sharp.dll b/Example2/bin/Debug/websocket-sharp.dll index 682adfab..88f7fba0 100755 Binary files a/Example2/bin/Debug/websocket-sharp.dll and b/Example2/bin/Debug/websocket-sharp.dll differ diff --git a/Example2/bin/Debug/websocket-sharp.dll.mdb b/Example2/bin/Debug/websocket-sharp.dll.mdb index 43a868d1..e270cce5 100644 Binary files a/Example2/bin/Debug/websocket-sharp.dll.mdb and b/Example2/bin/Debug/websocket-sharp.dll.mdb differ diff --git a/Example2/bin/Debug_Ubuntu/example2.exe b/Example2/bin/Debug_Ubuntu/example2.exe index 2fb2e3c1..3f7c6b9d 100755 Binary files a/Example2/bin/Debug_Ubuntu/example2.exe and b/Example2/bin/Debug_Ubuntu/example2.exe differ diff --git a/Example2/bin/Debug_Ubuntu/example2.exe.mdb b/Example2/bin/Debug_Ubuntu/example2.exe.mdb index 65250898..c3d8d2f5 100644 Binary files a/Example2/bin/Debug_Ubuntu/example2.exe.mdb and b/Example2/bin/Debug_Ubuntu/example2.exe.mdb differ diff --git a/Example2/bin/Debug_Ubuntu/websocket-sharp.dll b/Example2/bin/Debug_Ubuntu/websocket-sharp.dll index 5b28603b..7ed31d1b 100755 Binary files a/Example2/bin/Debug_Ubuntu/websocket-sharp.dll and b/Example2/bin/Debug_Ubuntu/websocket-sharp.dll differ diff --git a/Example2/bin/Debug_Ubuntu/websocket-sharp.dll.mdb b/Example2/bin/Debug_Ubuntu/websocket-sharp.dll.mdb index 81092b7c..0efa287d 100644 Binary files a/Example2/bin/Debug_Ubuntu/websocket-sharp.dll.mdb and b/Example2/bin/Debug_Ubuntu/websocket-sharp.dll.mdb differ diff --git a/Example2/bin/Release/example2.exe b/Example2/bin/Release/example2.exe index cf15fe20..9fdd9adf 100755 Binary files a/Example2/bin/Release/example2.exe and b/Example2/bin/Release/example2.exe differ diff --git a/Example2/bin/Release/websocket-sharp.dll b/Example2/bin/Release/websocket-sharp.dll index ac47adbd..6b8b7f95 100755 Binary files a/Example2/bin/Release/websocket-sharp.dll and b/Example2/bin/Release/websocket-sharp.dll differ diff --git a/Example2/bin/Release_Ubuntu/example2.exe b/Example2/bin/Release_Ubuntu/example2.exe index 08a3124d..097e96c6 100755 Binary files a/Example2/bin/Release_Ubuntu/example2.exe and b/Example2/bin/Release_Ubuntu/example2.exe differ diff --git a/Example2/bin/Release_Ubuntu/websocket-sharp.dll b/Example2/bin/Release_Ubuntu/websocket-sharp.dll index 038f0657..198c3156 100755 Binary files a/Example2/bin/Release_Ubuntu/websocket-sharp.dll and b/Example2/bin/Release_Ubuntu/websocket-sharp.dll differ diff --git a/Example3/bin/Debug/Example3.exe b/Example3/bin/Debug/Example3.exe index 3aecf3a1..8386bf1e 100755 Binary files a/Example3/bin/Debug/Example3.exe and b/Example3/bin/Debug/Example3.exe differ diff --git a/Example3/bin/Debug/Example3.exe.mdb b/Example3/bin/Debug/Example3.exe.mdb index 2d552ecc..0a75cdbc 100644 Binary files a/Example3/bin/Debug/Example3.exe.mdb and b/Example3/bin/Debug/Example3.exe.mdb differ diff --git a/Example3/bin/Debug/websocket-sharp.dll b/Example3/bin/Debug/websocket-sharp.dll index 682adfab..88f7fba0 100755 Binary files a/Example3/bin/Debug/websocket-sharp.dll and b/Example3/bin/Debug/websocket-sharp.dll differ diff --git a/Example3/bin/Debug/websocket-sharp.dll.mdb b/Example3/bin/Debug/websocket-sharp.dll.mdb index 43a868d1..e270cce5 100644 Binary files a/Example3/bin/Debug/websocket-sharp.dll.mdb and b/Example3/bin/Debug/websocket-sharp.dll.mdb differ diff --git a/Example3/bin/Debug_Ubuntu/Example3.exe b/Example3/bin/Debug_Ubuntu/Example3.exe index c044676d..c55cab96 100755 Binary files a/Example3/bin/Debug_Ubuntu/Example3.exe and b/Example3/bin/Debug_Ubuntu/Example3.exe differ diff --git a/Example3/bin/Debug_Ubuntu/Example3.exe.mdb b/Example3/bin/Debug_Ubuntu/Example3.exe.mdb index 1aac917b..1e4e303b 100644 Binary files a/Example3/bin/Debug_Ubuntu/Example3.exe.mdb and b/Example3/bin/Debug_Ubuntu/Example3.exe.mdb differ diff --git a/Example3/bin/Debug_Ubuntu/websocket-sharp.dll b/Example3/bin/Debug_Ubuntu/websocket-sharp.dll index 5b28603b..7ed31d1b 100755 Binary files a/Example3/bin/Debug_Ubuntu/websocket-sharp.dll and b/Example3/bin/Debug_Ubuntu/websocket-sharp.dll differ diff --git a/Example3/bin/Debug_Ubuntu/websocket-sharp.dll.mdb b/Example3/bin/Debug_Ubuntu/websocket-sharp.dll.mdb index 81092b7c..0efa287d 100644 Binary files a/Example3/bin/Debug_Ubuntu/websocket-sharp.dll.mdb and b/Example3/bin/Debug_Ubuntu/websocket-sharp.dll.mdb differ diff --git a/Example3/bin/Release/Example3.exe b/Example3/bin/Release/Example3.exe index 02a40cd0..4c8ec767 100755 Binary files a/Example3/bin/Release/Example3.exe and b/Example3/bin/Release/Example3.exe differ diff --git a/Example3/bin/Release/websocket-sharp.dll b/Example3/bin/Release/websocket-sharp.dll index ac47adbd..6b8b7f95 100755 Binary files a/Example3/bin/Release/websocket-sharp.dll and b/Example3/bin/Release/websocket-sharp.dll differ diff --git a/Example3/bin/Release_Ubuntu/Example3.exe b/Example3/bin/Release_Ubuntu/Example3.exe index 4108f6ab..e04e65a7 100755 Binary files a/Example3/bin/Release_Ubuntu/Example3.exe and b/Example3/bin/Release_Ubuntu/Example3.exe differ diff --git a/Example3/bin/Release_Ubuntu/websocket-sharp.dll b/Example3/bin/Release_Ubuntu/websocket-sharp.dll index 038f0657..198c3156 100755 Binary files a/Example3/bin/Release_Ubuntu/websocket-sharp.dll and b/Example3/bin/Release_Ubuntu/websocket-sharp.dll differ diff --git a/websocket-sharp/Ext.cs b/websocket-sharp/Ext.cs index 276d7481..502b369b 100644 --- a/websocket-sharp/Ext.cs +++ b/websocket-sharp/Ext.cs @@ -302,35 +302,45 @@ namespace WebSocketSharp { if (length <= 0) return new byte[]{}; - var buffer = new byte[length]; - stream.Read(buffer, 0, length); - return buffer; + var buffer = new byte[length]; + var readLen = stream.Read(buffer, 0, length); + + return readLen == length ? buffer : null; } public static byte[] ReadBytes(this Stream stream, long length, int bufferLength) { - var count = length / bufferLength; - var rem = length % bufferLength; - var readData = new List(); - var readLen = 0; - var buffer = new byte[bufferLength]; + var count = length / bufferLength; + var rem = length % bufferLength; + var readData = new List(); + var readBuffer = new byte[bufferLength]; + long readLen = 0; + var tmpLen = 0; + + Action read = (buffer) => + { + tmpLen = stream.Read(buffer, 0, buffer.Length); + if (tmpLen > 0) + { + readLen += tmpLen; + readData.AddRange(buffer.SubArray(0, tmpLen)); + } + }; count.Times(() => { - readLen = stream.Read(buffer, 0, bufferLength); - if (readLen > 0) - readData.AddRange(buffer.SubArray(0, readLen)); + read(readBuffer); }); if (rem > 0) { - buffer = new byte[rem]; - readLen = stream.Read(buffer, 0, (int)rem); - if (readLen > 0) - readData.AddRange(buffer.SubArray(0, readLen)); + readBuffer = new byte[rem]; + read(readBuffer); } - return readData.ToArray(); + return readLen == length + ? readData.ToArray() + : null; } public static T[] SubArray(this T[] array, int startIndex, int length) diff --git a/websocket-sharp/Frame/WsFrame.cs b/websocket-sharp/Frame/WsFrame.cs index 96826736..076aa57e 100644 --- a/websocket-sharp/Frame/WsFrame.cs +++ b/websocket-sharp/Frame/WsFrame.cs @@ -28,6 +28,7 @@ using System; using System.IO; +using System.Collections; using System.Collections.Generic; using System.Text; @@ -35,7 +36,7 @@ namespace WebSocketSharp.Frame { public class WsFrame : IEnumerable { - #region Private Static Fields + #region Field private static readonly int _readBufferLen; @@ -81,7 +82,7 @@ namespace WebSocketSharp.Frame #endregion - #region Private Constructors + #region Private Constructor private WsFrame() { @@ -109,223 +110,148 @@ namespace WebSocketSharp.Frame public WsFrame(Fin fin, Opcode opcode, Mask mask, PayloadData payloadData) : this() { - Fin = fin; - Opcode = opcode; - - ulong dataLength = payloadData.Length; - - if (dataLength == 0) - { - Masked = Mask.UNMASK; - } - else - { - Masked = mask; - } - - if (dataLength < 126) - { - PayloadLen = (byte)dataLength; - } - else if (dataLength < 0x010000) - { - PayloadLen = (byte)126; - ExtPayloadLen = ((ushort)dataLength).ToBytes(ByteOrder.BIG); - } - else - { - PayloadLen = (byte)127; - ExtPayloadLen = dataLength.ToBytes(ByteOrder.BIG); - } - + Fin = fin; + Opcode = opcode; + Masked = payloadData.Length != 0 ? mask : Mask.UNMASK; PayloadData = payloadData; - if (Masked == Mask.MASK) - { - MaskingKey = new byte[4]; - var rand = new Random(); - rand.NextBytes(MaskingKey); - PayloadData.Mask(MaskingKey); - } + init(); } #endregion - #region Public Static Methods + #region Private Methods - public static WsFrame Parse(byte[] src) + IEnumerator IEnumerable.GetEnumerator() { - return Parse(src, true); + return GetEnumerator(); } - public static WsFrame Parse(byte[] src, bool unmask) + private void init() { - using (MemoryStream ms = new MemoryStream(src)) - { - return Parse(ms, unmask); - } + setPayloadLen(PayloadLength); + if (Masked == Mask.MASK) + maskPayloadData(); } - public static WsFrame Parse(TStream stream) - where TStream : System.IO.Stream + private void maskPayloadData() { - return Parse(stream, true); + var key = new byte[4]; + var rand = new Random(); + rand.NextBytes(key); + + MaskingKey = key; + PayloadData.Mask(key); } - public static WsFrame Parse(TStream stream, bool unmask) - where TStream : System.IO.Stream + private static void readExtPayloadLen(Stream stream, WsFrame frame) { - Fin fin; - Rsv rsv1, rsv2, rsv3; - Opcode opcode; - Mask masked; - byte payloadLen; - byte[] extPayloadLen = new byte[]{}; - byte[] maskingKey = new byte[]{}; - PayloadData payloadData; - - byte[] buffer1, buffer2, buffer3; - int buffer1Len = 2; - int buffer2Len = 0; - ulong buffer3Len = 0; - int maskingKeyLen = 4; - int readLen = 0; + var length = frame.PayloadLen <= 125 + ? 0 + : frame.PayloadLen == 126 ? 2 : 8; - buffer1 = new byte[buffer1Len]; - readLen = stream.Read(buffer1, 0, buffer1Len); - if (readLen < buffer1Len) + if (length > 0) { - return null; + var extLength = stream.ReadBytes(length); + if (extLength == null) + throw new IOException(); + frame.ExtPayloadLen = extLength; } + } + + private static WsFrame readHeader(Stream stream) + { + var header = stream.ReadBytes(2); + if (header == null) + return null; // FIN - fin = (buffer1[0] & 0x80) == 0x80 - ? Fin.FINAL - : Fin.MORE; + Fin fin = (header[0] & 0x80) == 0x80 ? Fin.FINAL : Fin.MORE; // RSV1 - rsv1 = (buffer1[0] & 0x40) == 0x40 - ? Rsv.ON - : Rsv.OFF; + Rsv rsv1 = (header[0] & 0x40) == 0x40 ? Rsv.ON : Rsv.OFF; // RSV2 - rsv2 = (buffer1[0] & 0x20) == 0x20 - ? Rsv.ON - : Rsv.OFF; + Rsv rsv2 = (header[0] & 0x20) == 0x20 ? Rsv.ON : Rsv.OFF; // RSV3 - rsv3 = (buffer1[0] & 0x10) == 0x10 - ? Rsv.ON - : Rsv.OFF; - // opcode - opcode = (Opcode)(buffer1[0] & 0x0f); + Rsv rsv3 = (header[0] & 0x10) == 0x10 ? Rsv.ON : Rsv.OFF; + // Opcode + Opcode opcode = (Opcode)(header[0] & 0x0f); // MASK - masked = (buffer1[1] & 0x80) == 0x80 - ? Mask.MASK - : Mask.UNMASK; + Mask masked = (header[1] & 0x80) == 0x80 ? Mask.MASK : Mask.UNMASK; // Payload len - payloadLen = (byte)(buffer1[1] & 0x7f); - // Extended payload length - if (payloadLen <= 125) - { - buffer3Len = payloadLen; - } - else if (payloadLen == 126) - { - buffer2Len = 2; - } - else + byte payloadLen = (byte)(header[1] & 0x7f); + + return new WsFrame { + Fin = fin, + Rsv1 = rsv1, + Rsv2 = rsv2, + Rsv3 = rsv3, + Opcode = opcode, + Masked = masked, + PayloadLen = payloadLen}; + } + + private static void readMaskingKey(Stream stream, WsFrame frame) + { + if (frame.Masked == Mask.MASK) { - buffer2Len = 8; + var maskingKey = stream.ReadBytes(4); + if (maskingKey == null) + throw new IOException(); + frame.MaskingKey = maskingKey; } + } - if (buffer2Len > 0) - { - buffer2 = new byte[buffer2Len]; - readLen = stream.Read(buffer2, 0, buffer2Len); + private static void readPayloadData(Stream stream, WsFrame frame, bool unmask) + { + ulong length = frame.PayloadLen <= 125 + ? frame.PayloadLen + : frame.PayloadLen == 126 + ? frame.ExtPayloadLen.To(ByteOrder.BIG) + : frame.ExtPayloadLen.To(ByteOrder.BIG); - if (readLen < buffer2Len) - { - return null; - } + var buffer = length <= (ulong)_readBufferLen + ? stream.ReadBytes((int)length) + : stream.ReadBytes((long)length, _readBufferLen); - extPayloadLen = buffer2; - switch (buffer2Len) - { - case 2: - buffer3Len = extPayloadLen.To(ByteOrder.BIG); - break; - case 8: - buffer3Len = extPayloadLen.To(ByteOrder.BIG); - break; - } - } + if (buffer == null) + throw new IOException(); - if (buffer3Len > PayloadData.MaxLength) - { - throw new WsReceivedTooBigMessageException(); - } - // Masking-key - if (masked == Mask.MASK) - { - maskingKey = new byte[maskingKeyLen]; - readLen = stream.Read(maskingKey, 0, maskingKeyLen); - - if (readLen < maskingKeyLen) - { - return null; - } - } - // Payload Data - if (buffer3Len == 0) - { - buffer3 = new byte[]{}; - } - else if (buffer3Len <= (ulong)_readBufferLen) + PayloadData payloadData; + if (frame.Masked == Mask.MASK) { - buffer3 = new byte[buffer3Len]; - readLen = stream.Read(buffer3, 0, (int)buffer3Len); - - if (readLen < (int)buffer3Len) + payloadData = new PayloadData(buffer, true); + if (unmask == true) { - return null; + payloadData.Mask(frame.MaskingKey); + frame.Masked = Mask.UNMASK; + frame.MaskingKey = new byte[]{}; } } else { - buffer3 = stream.ReadBytes((long)buffer3Len, _readBufferLen); - - if ((ulong)buffer3.LongLength < buffer3Len) - { - return null; - } + payloadData = new PayloadData(buffer); } - if (masked == Mask.MASK) + frame.PayloadData = payloadData; + } + + private void setPayloadLen(ulong length) + { + if (length < 126) { - payloadData = new PayloadData(buffer3, true); - if (unmask == true) - { - payloadData.Mask(maskingKey); - masked = Mask.UNMASK; - maskingKey = new byte[]{}; - } + PayloadLen = (byte)length; + return; } - else + + if (length < 0x010000) { - payloadData = new PayloadData(buffer3); + PayloadLen = (byte)126; + ExtPayloadLen = ((ushort)length).ToBytes(ByteOrder.BIG); + return; } - return new WsFrame - { - Fin = fin, - Rsv1 = rsv1, - Rsv2 = rsv2, - Rsv3 = rsv3, - Opcode = opcode, - Masked = masked, - PayloadLen = payloadLen, - ExtPayloadLen = extPayloadLen, - MaskingKey = maskingKey, - PayloadData = payloadData - }; + PayloadLen = (byte)127; + ExtPayloadLen = length.ToBytes(ByteOrder.BIG); } #endregion @@ -335,14 +261,38 @@ namespace WebSocketSharp.Frame public IEnumerator GetEnumerator() { foreach (byte b in ToBytes()) - { yield return b; + } + + public static WsFrame Parse(byte[] src) + { + return Parse(src, true); + } + + public static WsFrame Parse(byte[] src, bool unmask) + { + using (MemoryStream ms = new MemoryStream(src)) + { + return Parse(ms, unmask); } } - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + public static WsFrame Parse(Stream stream) { - return GetEnumerator(); + return Parse(stream, true); + } + + public static WsFrame Parse(Stream stream, bool unmask) + { + var frame = readHeader(stream); + if (frame == null) + return null; + + readExtPayloadLen(stream, frame); + readMaskingKey(stream, frame); + readPayloadData(stream, frame, unmask); + + return frame; } public void Print() @@ -462,33 +412,27 @@ namespace WebSocketSharp.Frame public byte[] ToBytes() { - var bytes = new List(); + var buffer = new List(); - int first16 = (int)Fin; - first16 = (first16 << 1) + (int)Rsv1; - first16 = (first16 << 1) + (int)Rsv2; - first16 = (first16 << 1) + (int)Rsv3; - first16 = (first16 << 4) + (int)Opcode; - first16 = (first16 << 1) + (int)Masked; - first16 = (first16 << 7) + (int)PayloadLen; - bytes.AddRange(((ushort)first16).ToBytes(ByteOrder.BIG)); + int header = (int)Fin; + header = (header << 1) + (int)Rsv1; + header = (header << 1) + (int)Rsv2; + header = (header << 1) + (int)Rsv3; + header = (header << 4) + (int)Opcode; + header = (header << 1) + (int)Masked; + header = (header << 7) + (int)PayloadLen; + buffer.AddRange(((ushort)header).ToBytes(ByteOrder.BIG)); if (PayloadLen >= 126) - { - bytes.AddRange(ExtPayloadLen); - } + buffer.AddRange(ExtPayloadLen); if (Masked == Mask.MASK) - { - bytes.AddRange(MaskingKey); - } + buffer.AddRange(MaskingKey); if (PayloadLen > 0) - { - bytes.AddRange(PayloadData.ToBytes()); - } + buffer.AddRange(PayloadData.ToBytes()); - return bytes.ToArray(); + return buffer.ToArray(); } public override string ToString() diff --git a/websocket-sharp/Net/HttpConnection.cs b/websocket-sharp/Net/HttpConnection.cs index c31aeab9..2d0b8d67 100644 --- a/websocket-sharp/Net/HttpConnection.cs +++ b/websocket-sharp/Net/HttpConnection.cs @@ -31,13 +31,13 @@ using System; using System.IO; using System.Net; -using System.Net.Security; using System.Net.Sockets; using System.Reflection; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading; +using WebSocketSharp.Net.Security; namespace WebSocketSharp.Net { @@ -122,7 +122,7 @@ namespace WebSocketSharp.Net { if (!secure) { stream = net_stream; } else { - var ssl_stream = new SslStream(net_stream); + var ssl_stream = new SslStream(net_stream, false); ssl_stream.AuthenticateAsServer(cert); stream = ssl_stream; } diff --git a/websocket-sharp/Net/Security/SslStream.cs b/websocket-sharp/Net/Security/SslStream.cs new file mode 100644 index 00000000..fcb3635c --- /dev/null +++ b/websocket-sharp/Net/Security/SslStream.cs @@ -0,0 +1,83 @@ +#region MIT License +/** + * SslStream.cs + * + * The MIT License + * + * Copyright (c) 2012 sta.blockhead + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#endregion + +using System; +using System.Net.Security; +using System.Net.Sockets; + +namespace WebSocketSharp.Net.Security { + + public class SslStream : System.Net.Security.SslStream + { + #region Constructors + + public SslStream(NetworkStream innerStream) + : base(innerStream) + { + } + + public SslStream(NetworkStream innerStream, bool leaveInnerStreamOpen) + : base(innerStream, leaveInnerStreamOpen) + { + } + + public SslStream( + NetworkStream innerStream, + bool leaveInnerStreamOpen, + RemoteCertificateValidationCallback userCertificateValidationCallback + ) : base(innerStream, leaveInnerStreamOpen, userCertificateValidationCallback) + { + } + + public SslStream( + NetworkStream innerStream, + bool leaveInnerStreamOpen, + RemoteCertificateValidationCallback userCertificateValidationCallback, + LocalCertificateSelectionCallback userCertificateSelectionCallback + ) : base( + innerStream, + leaveInnerStreamOpen, + userCertificateValidationCallback, + userCertificateSelectionCallback + ) + { + } + + #endregion + + #region Property + + public bool DataAvailable { + get { + return ((NetworkStream)InnerStream).DataAvailable; + } + } + + #endregion + } +} diff --git a/websocket-sharp/WebSocket.cs b/websocket-sharp/WebSocket.cs index c824dd94..58211a10 100644 --- a/websocket-sharp/WebSocket.cs +++ b/websocket-sharp/WebSocket.cs @@ -643,6 +643,19 @@ namespace WebSocketSharp { return frame; } + private WsFrame readFrameWithTimeout() + { + if (!_wsStream.DataAvailable) + { + var timeout = 1 * 100; + Thread.Sleep(timeout); + if (!_wsStream.DataAvailable) + return null; + } + + return readFrame(); + } + private string[] readHandshake() { return _wsStream.ReadHandshake(); @@ -650,7 +663,7 @@ namespace WebSocketSharp { private MessageEventArgs receive() { - var frame = readFrame(); + var frame = _isClient ? readFrame() : readFrameWithTimeout(); if (frame == null) return null; diff --git a/websocket-sharp/WsStream.cs b/websocket-sharp/WsStream.cs index edba2e14..703d633d 100644 --- a/websocket-sharp/WsStream.cs +++ b/websocket-sharp/WsStream.cs @@ -31,11 +31,11 @@ using System.Collections.Generic; using System.Configuration; using System.IO; using System.Net; -using System.Net.Security; using System.Net.Sockets; using System.Security.Cryptography.X509Certificates; using System.Text; using WebSocketSharp.Frame; +using WebSocketSharp.Net.Security; namespace WebSocketSharp { @@ -51,7 +51,7 @@ namespace WebSocketSharp #endregion - #region Constructor + #region Constructors public WsStream(NetworkStream innerStream) { @@ -65,7 +65,16 @@ namespace WebSocketSharp #endregion - #region Public Property + #region Properties + + public bool DataAvailable { + get { + if (_innerStreamType == typeof(SslStream)) + return ((SslStream)_innerStream).DataAvailable; + + return ((NetworkStream)_innerStream).DataAvailable; + } + } public bool IsSecure { get { return _isSecure; } @@ -73,7 +82,7 @@ namespace WebSocketSharp #endregion - #region Private Methods + #region Private Method private void init(Stream innerStream) { @@ -98,7 +107,7 @@ namespace WebSocketSharp if (port == 443) { - RemoteCertificateValidationCallback validationCb = (sender, certificate, chain, sslPolicyErrors) => + System.Net.Security.RemoteCertificateValidationCallback validationCb = (sender, certificate, chain, sslPolicyErrors) => { // FIXME: Always returns true return true; @@ -120,7 +129,7 @@ namespace WebSocketSharp var port = ((IPEndPoint)client.Client.LocalEndPoint).Port; if (port == 443) { - var sslStream = new SslStream(netStream); + var sslStream = new SslStream(netStream, false); var certPath = ConfigurationManager.AppSettings["ServerCertPath"]; sslStream.AuthenticateAsServer(new X509Certificate2(certPath)); diff --git a/websocket-sharp/bin/Debug/websocket-sharp.dll b/websocket-sharp/bin/Debug/websocket-sharp.dll index 682adfab..88f7fba0 100755 Binary files a/websocket-sharp/bin/Debug/websocket-sharp.dll and b/websocket-sharp/bin/Debug/websocket-sharp.dll differ diff --git a/websocket-sharp/bin/Debug/websocket-sharp.dll.mdb b/websocket-sharp/bin/Debug/websocket-sharp.dll.mdb index 43a868d1..e270cce5 100644 Binary files a/websocket-sharp/bin/Debug/websocket-sharp.dll.mdb and b/websocket-sharp/bin/Debug/websocket-sharp.dll.mdb differ diff --git a/websocket-sharp/bin/Debug_Ubuntu/websocket-sharp.dll b/websocket-sharp/bin/Debug_Ubuntu/websocket-sharp.dll index 5b28603b..7ed31d1b 100755 Binary files a/websocket-sharp/bin/Debug_Ubuntu/websocket-sharp.dll and b/websocket-sharp/bin/Debug_Ubuntu/websocket-sharp.dll differ diff --git a/websocket-sharp/bin/Debug_Ubuntu/websocket-sharp.dll.mdb b/websocket-sharp/bin/Debug_Ubuntu/websocket-sharp.dll.mdb index 81092b7c..0efa287d 100644 Binary files a/websocket-sharp/bin/Debug_Ubuntu/websocket-sharp.dll.mdb and b/websocket-sharp/bin/Debug_Ubuntu/websocket-sharp.dll.mdb differ diff --git a/websocket-sharp/bin/Release/websocket-sharp.dll b/websocket-sharp/bin/Release/websocket-sharp.dll index ac47adbd..6b8b7f95 100755 Binary files a/websocket-sharp/bin/Release/websocket-sharp.dll and b/websocket-sharp/bin/Release/websocket-sharp.dll differ diff --git a/websocket-sharp/bin/Release_Ubuntu/websocket-sharp.dll b/websocket-sharp/bin/Release_Ubuntu/websocket-sharp.dll index 038f0657..198c3156 100755 Binary files a/websocket-sharp/bin/Release_Ubuntu/websocket-sharp.dll and b/websocket-sharp/bin/Release_Ubuntu/websocket-sharp.dll differ diff --git a/websocket-sharp/websocket-sharp.csproj b/websocket-sharp/websocket-sharp.csproj index 24f92169..d48a4d08 100644 --- a/websocket-sharp/websocket-sharp.csproj +++ b/websocket-sharp/websocket-sharp.csproj @@ -110,6 +110,7 @@ + @@ -117,5 +118,6 @@ + \ No newline at end of file diff --git a/websocket-sharp/websocket-sharp.pidb b/websocket-sharp/websocket-sharp.pidb index 08f1d181..4b3e8274 100644 Binary files a/websocket-sharp/websocket-sharp.pidb and b/websocket-sharp/websocket-sharp.pidb differ