diff --git a/Example/Example.pidb b/Example/Example.pidb index 164e7d48..ff4acb4f 100644 Binary files a/Example/Example.pidb and b/Example/Example.pidb differ diff --git a/Example/bin/Debug_Ubuntu/example.exe b/Example/bin/Debug_Ubuntu/example.exe index c296e687..e55b1bf3 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 f6f92556..1e02a4aa 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 80717d64..a868c718 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 14200dab..97c87fac 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/Example1/bin/Debug_Ubuntu/example1.exe b/Example1/bin/Debug_Ubuntu/example1.exe index 716a56dd..18c0b310 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 d39186f1..c90326b1 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 80717d64..a868c718 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 14200dab..97c87fac 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/Example2/bin/Debug_Ubuntu/example2.exe b/Example2/bin/Debug_Ubuntu/example2.exe index d9b5941e..9b55ae32 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 9cf19757..5ca39f3a 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 80717d64..a868c718 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 14200dab..97c87fac 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/Example3/bin/Debug_Ubuntu/Example3.exe b/Example3/bin/Debug_Ubuntu/Example3.exe index ae4143bf..bdeb3237 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 412e92a7..6f89d880 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 80717d64..a868c718 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 14200dab..97c87fac 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/websocket-sharp/Ext.cs b/websocket-sharp/Ext.cs index a93c6bd2..56a6783f 100644 --- a/websocket-sharp/Ext.cs +++ b/websocket-sharp/Ext.cs @@ -71,10 +71,8 @@ namespace WebSocketSharp { return value; using (var input = new MemoryStream(value)) - using (var output = input.compress()) { - output.Close(); - return output.ToArray(); + return input.compressToArray(); } } @@ -84,19 +82,10 @@ namespace WebSocketSharp { if (stream.Length == 0) return output; + stream.Position = 0; using (var ds = new DeflateStream(output, CompressionMode.Compress, true)) { - int readLen = 0; - var buffer = new byte[256]; - while (true) - { - readLen = stream.Read(buffer, 0, buffer.Length); - if (readLen == 0) - break; - - ds.Write(buffer, 0, readLen); - } - + stream.CopyTo(ds); ds.Close(); // "BFINAL" set to 1. output.Position = 0; @@ -104,16 +93,23 @@ namespace WebSocketSharp { } } + private static byte[] compressToArray(this Stream stream) + { + using (var comp = stream.compress()) + { + comp.Close(); + return comp.ToArray(); + } + } + private static byte[] decompress(this byte[] value) { if (value.LongLength == 0) return value; using (var input = new MemoryStream(value)) - using (var output = input.decompress()) { - output.Close(); - return output.ToArray(); + return input.decompressToArray(); } } @@ -123,24 +119,23 @@ namespace WebSocketSharp { if (stream.Length == 0) return output; + stream.Position = 0; using (var ds = new DeflateStream(stream, CompressionMode.Decompress, true)) { - int readLen = 0; - var buffer = new byte[256]; - while (true) - { - readLen = ds.Read(buffer, 0, buffer.Length); - if (readLen == 0) - break; - - output.Write(buffer, 0, readLen); - } - - output.Position = 0; + ds.CopyTo(output, true); return output; } } + private static byte[] decompressToArray(this Stream stream) + { + using (var decomp = stream.decompress()) + { + decomp.Close(); + return decomp.ToArray(); + } + } + private static void times(this ulong n, Action act) { for (ulong i = 0; i < n; i++) @@ -165,6 +160,32 @@ namespace WebSocketSharp { : stream; } + internal static byte[] CompressToArray(this Stream stream, CompressionMethod method) + { + return method == CompressionMethod.DEFLATE + ? stream.compressToArray() + : stream.ToByteArray(); + } + + internal static void CopyTo(this Stream src, Stream dest) + { + src.CopyTo(dest, false); + } + + internal static void CopyTo(this Stream src, Stream dest, bool setDefaultPosition) + { + int readLen; + int bufferLen = 256; + var buffer = new byte[bufferLen]; + while ((readLen = src.Read(buffer, 0, bufferLen)) > 0) + { + dest.Write(buffer, 0, readLen); + } + + if (setDefaultPosition) + dest.Position = 0; + } + internal static byte[] Decompress(this byte[] value, CompressionMethod method) { return method == CompressionMethod.DEFLATE @@ -179,6 +200,13 @@ namespace WebSocketSharp { : stream; } + internal static byte[] DecompressToArray(this Stream stream, CompressionMethod method) + { + return method == CompressionMethod.DEFLATE + ? stream.decompressToArray() + : stream.ToByteArray(); + } + internal static string GetNameInternal(this string nameAndValue, string separator) { int i = nameAndValue.IndexOf(separator); @@ -234,6 +262,23 @@ namespace WebSocketSharp { : String.Format("\"{0}\"", value.Replace("\"", "\\\"")); } + internal static string RemovePrefix(this string value, params string[] prefixes) + { + int i = 0; + foreach (var prefix in prefixes) + { + if (value.StartsWith(prefix)) + { + i = prefix.Length; + break; + } + } + + return i > 0 + ? value.Substring(i) + : value; + } + internal static IEnumerable SplitHeaderValue(this string value, params char[] separator) { var separators = new string(separator); @@ -275,6 +320,26 @@ namespace WebSocketSharp { yield return buffer.ToString(); } + internal static byte[] ToByteArray(this Stream stream) + { + using (var output = new MemoryStream()) + { + stream.Position = 0; + stream.CopyTo(output); + output.Close(); + + return output.ToArray(); + } + } + + internal static void WriteBytes(this Stream stream, byte[] value) + { + using (var input = new MemoryStream(value)) + { + input.CopyTo(stream); + } + } + #endregion #region Public Methods diff --git a/websocket-sharp/WebSocket.cs b/websocket-sharp/WebSocket.cs index 9e2740db..d91cb1de 100644 --- a/websocket-sharp/WebSocket.cs +++ b/websocket-sharp/WebSocket.cs @@ -36,7 +36,6 @@ using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics; using System.IO; -using System.IO.Compression; using System.Linq; using System.Net.Sockets; using System.Security.Cryptography; @@ -770,6 +769,59 @@ namespace WebSocketSharp { response.HeaderExists("Sec-WebSocket-Version", _version); } + private bool mergeFragments(Stream dest) + { + Func processContinuation = contFrame => + { + if (!contFrame.IsContinuation) + return false; + + if (contFrame.IsCompressed) + contFrame.Decompress(_compression); + + dest.WriteBytes(contFrame.PayloadData.ToByteArray()); + return true; + }; + + while (true) + { + var frame = readFrame(); + if (processAbnormal(frame)) + return false; + + if (!frame.IsFinal) + { + // MORE & CONT + if (processContinuation(frame)) + continue; + } + else + { + // FINAL & CONT + if (processContinuation(frame)) + break; + + // FINAL & PING + if (processPing(frame)) + continue; + + // FINAL & PONG + if (processPong(frame)) + continue; + + // FINAL & CLOSE + if (processClose(frame)) + return false; + } + + // ? + processIncorrectFrame(); + return false; + } + + return true; + } + private void onClose(CloseEventArgs eventArgs) { if (!Thread.CurrentThread.IsBackground) @@ -897,64 +949,28 @@ namespace WebSocketSharp { private void processFragments(WsFrame first) { - bool compressed = first.IsCompressed; - if (compressed && _perFrameCompress) - first.Decompress(_compression); - - var buffer = new List(first.PayloadData.ToByteArray()); - Func processContinuation = contFrame => + using (var merge = new MemoryStream()) { - if (!contFrame.IsContinuation) - return false; - - if (contFrame.IsCompressed) - contFrame.Decompress(_compression); + if (first.IsCompressed && _perFrameCompress) + first.Decompress(_compression); - buffer.AddRange(contFrame.PayloadData.ToByteArray()); - return true; - }; - - while (true) - { - var frame = readFrame(); - if (processAbnormal(frame)) + merge.WriteBytes(first.PayloadData.ToByteArray()); + if (!mergeFragments(merge)) return; - if (!frame.IsFinal) + byte[] data; + if (_compression != CompressionMethod.NONE && !_perFrameCompress) { - // MORE & CONT - if (processContinuation(frame)) - continue; + data = merge.DecompressToArray(_compression); } else { - // FINAL & CONT - if (processContinuation(frame)) - break; - - // FINAL & PING - if (processPing(frame)) - continue; - - // FINAL & PONG - if (processPong(frame)) - continue; - - // FINAL & CLOSE - if (processClose(frame)) - return; + merge.Close(); + data = merge.ToArray(); } - // ? - processIncorrectFrame(); - return; + onMessage(new MessageEventArgs(first.Opcode, new PayloadData(data))); } - - var data = compressed && !_perFrameCompress - ? buffer.ToArray().Decompress(_compression) - : buffer.ToArray(); - - onMessage(new MessageEventArgs(first.Opcode, new PayloadData(data))); } private void processFrame(WsFrame frame) @@ -1015,10 +1031,7 @@ namespace WebSocketSharp { foreach (var extension in extensions.SplitHeaderValue(',')) { var e = extension.Trim(); - var tmp = e.StartsWith("x-webkit-") - ? e.Substring(9) - : e; - + var tmp = e.RemovePrefix("x-webkit-"); if (!compress) { if (isPerFrameCompressExtension(tmp)) diff --git a/websocket-sharp/bin/Debug_Ubuntu/websocket-sharp.dll b/websocket-sharp/bin/Debug_Ubuntu/websocket-sharp.dll index 80717d64..a868c718 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 14200dab..97c87fac 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/websocket-sharp.pidb b/websocket-sharp/websocket-sharp.pidb index c6fa4b00..0aea65fd 100644 Binary files a/websocket-sharp/websocket-sharp.pidb and b/websocket-sharp/websocket-sharp.pidb differ