Fix for the per message compression
This commit is contained in:
parent
b33b5e63ba
commit
a1345386fd
Binary file not shown.
@ -116,6 +116,7 @@ namespace Example
|
|||||||
//ws.SetCookie(new Cookie("nobita", "\"idiot, gunfighter\""));
|
//ws.SetCookie(new Cookie("nobita", "\"idiot, gunfighter\""));
|
||||||
//ws.SetCookie(new Cookie("dora", "tanuki"));
|
//ws.SetCookie(new Cookie("dora", "tanuki"));
|
||||||
ws.Connect();
|
ws.Connect();
|
||||||
|
//Console.WriteLine("Compression: {0}", ws.Compression);
|
||||||
|
|
||||||
Thread.Sleep(500);
|
Thread.Sleep(500);
|
||||||
Console.WriteLine("\nType \"exit\" to exit.\n");
|
Console.WriteLine("\nType \"exit\" to exit.\n");
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -42,6 +42,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.IO.Compression;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@ -63,6 +64,83 @@ namespace WebSocketSharp {
|
|||||||
|
|
||||||
#region Private Methods
|
#region Private Methods
|
||||||
|
|
||||||
|
private static byte[] compress(this byte[] value)
|
||||||
|
{
|
||||||
|
if (value.LongLength == 0)
|
||||||
|
//return new Byte[] { 0x00, 0x00, 0x00, 0xff, 0xff };
|
||||||
|
return value;
|
||||||
|
|
||||||
|
using (var input = new MemoryStream(value))
|
||||||
|
using (var output = input.compress())
|
||||||
|
{
|
||||||
|
output.Close();
|
||||||
|
return output.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MemoryStream compress(this Stream stream)
|
||||||
|
{
|
||||||
|
var output = new MemoryStream();
|
||||||
|
if (stream.Length == 0)
|
||||||
|
return output;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
ds.Close(); // "BFINAL" set to 1.
|
||||||
|
output.Position = 0;
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MemoryStream decompress(this Stream stream)
|
||||||
|
{
|
||||||
|
var output = new MemoryStream();
|
||||||
|
if (stream.Length == 0)
|
||||||
|
return output;
|
||||||
|
|
||||||
|
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;
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void times(this ulong n, Action act)
|
private static void times(this ulong n, Action act)
|
||||||
{
|
{
|
||||||
for (ulong i = 0; i < n; i++)
|
for (ulong i = 0; i < n; i++)
|
||||||
@ -73,6 +151,34 @@ namespace WebSocketSharp {
|
|||||||
|
|
||||||
#region Internal Methods
|
#region Internal Methods
|
||||||
|
|
||||||
|
internal static byte[] Compress(this byte[] value, CompressionMethod method)
|
||||||
|
{
|
||||||
|
return method == CompressionMethod.DEFLATE
|
||||||
|
? value.compress()
|
||||||
|
: value;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static Stream Compress(this Stream stream, CompressionMethod method)
|
||||||
|
{
|
||||||
|
return method == CompressionMethod.DEFLATE
|
||||||
|
? stream.compress()
|
||||||
|
: stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static byte[] Decompress(this byte[] value, CompressionMethod method)
|
||||||
|
{
|
||||||
|
return method == CompressionMethod.DEFLATE
|
||||||
|
? value.decompress()
|
||||||
|
: value;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static Stream Decompress(this Stream stream, CompressionMethod method)
|
||||||
|
{
|
||||||
|
return method == CompressionMethod.DEFLATE
|
||||||
|
? stream.decompress()
|
||||||
|
: stream;
|
||||||
|
}
|
||||||
|
|
||||||
internal static string GetNameInternal(this string nameAndValue, string separator)
|
internal static string GetNameInternal(this string nameAndValue, string separator)
|
||||||
{
|
{
|
||||||
int i = nameAndValue.IndexOf(separator);
|
int i = nameAndValue.IndexOf(separator);
|
||||||
|
@ -128,48 +128,6 @@ namespace WebSocketSharp {
|
|||||||
|
|
||||||
#region Private Methods
|
#region Private Methods
|
||||||
|
|
||||||
private static byte[] compress(byte[] value)
|
|
||||||
{
|
|
||||||
if (value.LongLength == 0)
|
|
||||||
//return new Byte[] { 0x00, 0x00, 0x00, 0xff, 0xff };
|
|
||||||
return value;
|
|
||||||
|
|
||||||
using (var comp = new MemoryStream())
|
|
||||||
using (var ds = new DeflateStream(comp, CompressionMode.Compress, true))
|
|
||||||
{
|
|
||||||
ds.Write(value, 0, value.Length);
|
|
||||||
ds.Close(); // "BFINAL" set to 1.
|
|
||||||
comp.Close();
|
|
||||||
|
|
||||||
return comp.ToArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static byte[] decompress(byte[] value)
|
|
||||||
{
|
|
||||||
if (value.LongLength == 0)
|
|
||||||
return value;
|
|
||||||
|
|
||||||
using (var decomp = new MemoryStream())
|
|
||||||
using (var comp = new MemoryStream(value))
|
|
||||||
using (var ds = new DeflateStream(comp, CompressionMode.Decompress, true))
|
|
||||||
{
|
|
||||||
int readLen = 0;
|
|
||||||
var buffer = new byte[256];
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
readLen = ds.Read(buffer, 0, buffer.Length);
|
|
||||||
if (readLen == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
decomp.Write(buffer, 0, readLen);
|
|
||||||
}
|
|
||||||
|
|
||||||
decomp.Close();
|
|
||||||
return decomp.ToArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void mask(byte[] src, byte[] key)
|
private static void mask(byte[] src, byte[] key)
|
||||||
{
|
{
|
||||||
for (long i = 0; i < src.LongLength; i++)
|
for (long i = 0; i < src.LongLength; i++)
|
||||||
@ -184,14 +142,13 @@ namespace WebSocketSharp {
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if (method == CompressionMethod.NONE)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (ExtensionData.LongLength > 0)
|
if (ExtensionData.LongLength > 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (method == CompressionMethod.DEFLATE)
|
ApplicationData = ApplicationData.Compress(method);
|
||||||
ApplicationData = compress(ApplicationData);
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
@ -204,14 +161,12 @@ namespace WebSocketSharp {
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (ApplicationData.LongLength == 0)
|
if (method == CompressionMethod.NONE)
|
||||||
return true;
|
|
||||||
|
|
||||||
if (method == CompressionMethod.DEFLATE)
|
|
||||||
ApplicationData = decompress(ApplicationData);
|
|
||||||
else
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (ApplicationData.LongLength > 0)
|
||||||
|
ApplicationData = ApplicationData.Decompress(method);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
|
@ -36,6 +36,7 @@ using System.Collections.Generic;
|
|||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.IO.Compression;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
@ -63,12 +64,6 @@ namespace WebSocketSharp {
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Private Static Fields
|
|
||||||
|
|
||||||
private static NameValueCollection _extensionsReg;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Private Fields
|
#region Private Fields
|
||||||
|
|
||||||
private string _base64key;
|
private string _base64key;
|
||||||
@ -82,6 +77,7 @@ namespace WebSocketSharp {
|
|||||||
private Object _forClose;
|
private Object _forClose;
|
||||||
private Object _forSend;
|
private Object _forSend;
|
||||||
private string _origin;
|
private string _origin;
|
||||||
|
private bool _perFrameCompress;
|
||||||
private string _protocol;
|
private string _protocol;
|
||||||
private string _protocols;
|
private string _protocols;
|
||||||
private volatile WsState _readyState;
|
private volatile WsState _readyState;
|
||||||
@ -93,18 +89,6 @@ namespace WebSocketSharp {
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Static Constructor
|
|
||||||
|
|
||||||
static WebSocket()
|
|
||||||
{
|
|
||||||
_extensionsReg = new NameValueCollection();
|
|
||||||
_extensionsReg.Add("deflate", "deflate-frame");
|
|
||||||
_extensionsReg.Add("deflate", "perframe-compress; method=deflate");
|
|
||||||
_extensionsReg.Add("deflate", "permessage-compress; method=deflate");
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Private Constructors
|
#region Private Constructors
|
||||||
|
|
||||||
private WebSocket()
|
private WebSocket()
|
||||||
@ -115,6 +99,7 @@ namespace WebSocketSharp {
|
|||||||
_forClose = new Object();
|
_forClose = new Object();
|
||||||
_forSend = new Object();
|
_forSend = new Object();
|
||||||
_origin = String.Empty;
|
_origin = String.Empty;
|
||||||
|
_perFrameCompress = false;
|
||||||
_protocol = String.Empty;
|
_protocol = String.Empty;
|
||||||
_readyState = WsState.CONNECTING;
|
_readyState = WsState.CONNECTING;
|
||||||
}
|
}
|
||||||
@ -512,7 +497,7 @@ namespace WebSocketSharp {
|
|||||||
private void closeHandshake(PayloadData data)
|
private void closeHandshake(PayloadData data)
|
||||||
{
|
{
|
||||||
var args = new CloseEventArgs(data);
|
var args = new CloseEventArgs(data);
|
||||||
var frame = createControlFrame(Opcode.CLOSE, data);
|
var frame = createControlFrame(Opcode.CLOSE, data, _client);
|
||||||
if (send(frame))
|
if (send(frame))
|
||||||
args.WasClean = true;
|
args.WasClean = true;
|
||||||
|
|
||||||
@ -574,7 +559,7 @@ namespace WebSocketSharp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// As client
|
// As client
|
||||||
private string createBase64Key()
|
private static string createBase64Key()
|
||||||
{
|
{
|
||||||
var src = new byte[16];
|
var src = new byte[16];
|
||||||
var rand = new Random();
|
var rand = new Random();
|
||||||
@ -583,37 +568,38 @@ namespace WebSocketSharp {
|
|||||||
return Convert.ToBase64String(src);
|
return Convert.ToBase64String(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
// As client
|
private static string createCompressExtension(CompressionMethod method)
|
||||||
private string createCompressionExtension()
|
|
||||||
{
|
{
|
||||||
return _compression != CompressionMethod.NONE
|
return method != CompressionMethod.NONE
|
||||||
//? "deflate-frame"
|
? String.Format("permessage-compress; method={0}", method.ToString().ToLower())
|
||||||
//? String.Format("perframe-compress; method={0}", _compression.ToString().ToLower())
|
|
||||||
? String.Format("permessage-compress; method={0}", _compression.ToString().ToLower())
|
|
||||||
: String.Empty;
|
: String.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
private WsFrame createControlFrame(Opcode opcode, PayloadData payloadData)
|
private static WsFrame createControlFrame(Opcode opcode, PayloadData payloadData, bool client)
|
||||||
{
|
{
|
||||||
return _client
|
var mask = client ? Mask.MASK : Mask.UNMASK;
|
||||||
? new WsFrame(opcode, Mask.MASK, payloadData)
|
return new WsFrame(opcode, mask, payloadData);
|
||||||
: new WsFrame(opcode, Mask.UNMASK, payloadData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private WsFrame createDataFrame(Fin fin, Opcode opcode, PayloadData payloadData)
|
private static WsFrame createDataFrame(
|
||||||
|
Fin fin, Opcode opcode, PayloadData payloadData, CompressionMethod method, bool compressed, bool client)
|
||||||
{
|
{
|
||||||
return _client
|
var mask = client ? Mask.MASK : Mask.UNMASK;
|
||||||
? new WsFrame(fin, opcode, Mask.MASK, payloadData, _compression)
|
var compress = compressed ? CompressionMethod.NONE : method;
|
||||||
: new WsFrame(fin, opcode, Mask.UNMASK, payloadData, _compression);
|
var frame = new WsFrame(fin, opcode, mask, payloadData, compress);
|
||||||
|
if (compressed)
|
||||||
|
frame.PerMessageCompressed = true;
|
||||||
|
|
||||||
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
// As client
|
// As client
|
||||||
private string createRequestExtensions()
|
private string createRequestExtensions()
|
||||||
{
|
{
|
||||||
var extensions = new StringBuilder(64);
|
var extensions = new StringBuilder(64);
|
||||||
var compression = createCompressionExtension();
|
var compress = createCompressExtension(_compression);
|
||||||
if (!compression.IsEmpty())
|
if (!compress.IsEmpty())
|
||||||
extensions.Append(compression);
|
extensions.Append(compress);
|
||||||
|
|
||||||
return extensions.Length > 0
|
return extensions.Length > 0
|
||||||
? extensions.ToString()
|
? extensions.ToString()
|
||||||
@ -712,28 +698,14 @@ namespace WebSocketSharp {
|
|||||||
_client = false;
|
_client = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// As client
|
private static bool isCompressExtension(string value, CompressionMethod method)
|
||||||
private bool isCompressionExtension(string value)
|
|
||||||
{
|
{
|
||||||
var expected = createCompressionExtension();
|
var expected = createCompressExtension(method);
|
||||||
return !expected.IsEmpty()
|
return !expected.IsEmpty()
|
||||||
? value.Equals(expected)
|
? value.Equals(expected)
|
||||||
: false;
|
: false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// As server
|
|
||||||
private bool isDeflateExtension(string value)
|
|
||||||
{
|
|
||||||
if (value.StartsWith("x-webkit-"))
|
|
||||||
value = value.Substring(9);
|
|
||||||
|
|
||||||
foreach (var deflate in _extensionsReg.GetValues("deflate"))
|
|
||||||
if (value.Equals(deflate))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool isOpened(bool errorIfOpened)
|
private bool isOpened(bool errorIfOpened)
|
||||||
{
|
{
|
||||||
if (_readyState != WsState.OPEN && _readyState != WsState.CLOSING)
|
if (_readyState != WsState.OPEN && _readyState != WsState.CLOSING)
|
||||||
@ -745,6 +717,18 @@ namespace WebSocketSharp {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// As server
|
||||||
|
private static bool isPerFrameCompressExtension(string value)
|
||||||
|
{
|
||||||
|
if (value.Equals("deflate-frame"))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (value.Equals("perframe-compress; method=deflate"))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// As server
|
// As server
|
||||||
private bool isValidHostHeader()
|
private bool isValidHostHeader()
|
||||||
{
|
{
|
||||||
@ -831,7 +815,7 @@ namespace WebSocketSharp {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var frame = createControlFrame(Opcode.PING, new PayloadData(buffer));
|
var frame = createControlFrame(Opcode.PING, new PayloadData(buffer), _client);
|
||||||
if (!send(frame))
|
if (!send(frame))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -840,7 +824,7 @@ namespace WebSocketSharp {
|
|||||||
|
|
||||||
private void pong(PayloadData data)
|
private void pong(PayloadData data)
|
||||||
{
|
{
|
||||||
var frame = createControlFrame(Opcode.PONG, data);
|
var frame = createControlFrame(Opcode.PONG, data, _client);
|
||||||
send(frame);
|
send(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -914,7 +898,7 @@ namespace WebSocketSharp {
|
|||||||
private void processFragments(WsFrame first)
|
private void processFragments(WsFrame first)
|
||||||
{
|
{
|
||||||
bool compressed = first.IsCompressed;
|
bool compressed = first.IsCompressed;
|
||||||
if (compressed)
|
if (compressed && _perFrameCompress)
|
||||||
first.Decompress(_compression);
|
first.Decompress(_compression);
|
||||||
|
|
||||||
var buffer = new List<byte>(first.PayloadData.ToByteArray());
|
var buffer = new List<byte>(first.PayloadData.ToByteArray());
|
||||||
@ -923,7 +907,7 @@ namespace WebSocketSharp {
|
|||||||
if (!contFrame.IsContinuation)
|
if (!contFrame.IsContinuation)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (compressed)
|
if (contFrame.IsCompressed)
|
||||||
contFrame.Decompress(_compression);
|
contFrame.Decompress(_compression);
|
||||||
|
|
||||||
buffer.AddRange(contFrame.PayloadData.ToByteArray());
|
buffer.AddRange(contFrame.PayloadData.ToByteArray());
|
||||||
@ -966,7 +950,11 @@ namespace WebSocketSharp {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
onMessage(new MessageEventArgs(first.Opcode, new PayloadData(buffer.ToArray())));
|
var data = compressed && !_perFrameCompress
|
||||||
|
? buffer.ToArray().Decompress(_compression)
|
||||||
|
: buffer.ToArray();
|
||||||
|
|
||||||
|
onMessage(new MessageEventArgs(first.Opcode, new PayloadData(data)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processFrame(WsFrame frame)
|
private void processFrame(WsFrame frame)
|
||||||
@ -1022,23 +1010,40 @@ namespace WebSocketSharp {
|
|||||||
if (extensions.IsNullOrEmpty())
|
if (extensions.IsNullOrEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool deflate = false;
|
var compress = false;
|
||||||
var buffer = new StringBuilder(64);
|
var buffer = new List<string>();
|
||||||
foreach (var extension in extensions.SplitHeaderValue(','))
|
foreach (var extension in extensions.SplitHeaderValue(','))
|
||||||
{
|
{
|
||||||
var tmp = extension.Trim();
|
var e = extension.Trim();
|
||||||
if (!deflate && isDeflateExtension(tmp))
|
var tmp = e.StartsWith("x-webkit-")
|
||||||
|
? e.Substring(9)
|
||||||
|
: e;
|
||||||
|
|
||||||
|
if (!compress)
|
||||||
{
|
{
|
||||||
buffer.Append(tmp);
|
if (isPerFrameCompressExtension(tmp))
|
||||||
deflate = true;
|
{
|
||||||
|
_perFrameCompress = true;
|
||||||
|
_compression = CompressionMethod.DEFLATE;
|
||||||
|
compress = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!compress && isCompressExtension(tmp, CompressionMethod.DEFLATE))
|
||||||
|
{
|
||||||
|
_compression = CompressionMethod.DEFLATE;
|
||||||
|
compress = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (compress)
|
||||||
|
{
|
||||||
|
buffer.Add(e);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deflate)
|
if (buffer.Count > 0)
|
||||||
_compression = CompressionMethod.DEFLATE;
|
_extensions = buffer.ToArray().ToString(",");
|
||||||
|
|
||||||
if (buffer.Length > 0)
|
|
||||||
_extensions = buffer.ToString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// As server
|
// As server
|
||||||
@ -1080,13 +1085,13 @@ namespace WebSocketSharp {
|
|||||||
// As client
|
// As client
|
||||||
private void processResponseExtensions(string extensions)
|
private void processResponseExtensions(string extensions)
|
||||||
{
|
{
|
||||||
bool compress = false;
|
var compress = false;
|
||||||
if (!extensions.IsNullOrEmpty())
|
if (!extensions.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
foreach (var extension in extensions.SplitHeaderValue(','))
|
foreach (var extension in extensions.SplitHeaderValue(','))
|
||||||
{
|
{
|
||||||
var tmp = extension.Trim();
|
var e = extension.Trim();
|
||||||
if (!compress && isCompressionExtension(tmp))
|
if (!compress && isCompressExtension(e, _compression))
|
||||||
compress = true;
|
compress = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1197,6 +1202,20 @@ namespace WebSocketSharp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void send(Opcode opcode, Stream stream)
|
private void send(Opcode opcode, Stream stream)
|
||||||
|
{
|
||||||
|
if (_compression == CompressionMethod.NONE || _perFrameCompress)
|
||||||
|
{
|
||||||
|
send(opcode, stream, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
using (var compressed = stream.Compress(_compression))
|
||||||
|
{
|
||||||
|
send(opcode, compressed, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void send(Opcode opcode, Stream stream, bool compressed)
|
||||||
{
|
{
|
||||||
lock (_forSend)
|
lock (_forSend)
|
||||||
{
|
{
|
||||||
@ -1210,9 +1229,9 @@ namespace WebSocketSharp {
|
|||||||
|
|
||||||
var length = stream.Length;
|
var length = stream.Length;
|
||||||
if (length <= _fragmentLen)
|
if (length <= _fragmentLen)
|
||||||
send(Fin.FINAL, opcode, stream.ReadBytes((int)length));
|
send(Fin.FINAL, opcode, stream.ReadBytes((int)length), compressed);
|
||||||
else
|
else
|
||||||
sendFragmented(opcode, stream);
|
sendFragmented(opcode, stream, compressed);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -1221,9 +1240,10 @@ namespace WebSocketSharp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool send(Fin fin, Opcode opcode, byte[] data)
|
private bool send(Fin fin, Opcode opcode, byte[] data, bool compressed)
|
||||||
{
|
{
|
||||||
var frame = createDataFrame(fin, opcode, new PayloadData(data));
|
var frame = createDataFrame(
|
||||||
|
fin, opcode, new PayloadData(data), _compression, compressed, _client);
|
||||||
return send(frame);
|
return send(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1257,7 +1277,7 @@ namespace WebSocketSharp {
|
|||||||
action.BeginInvoke(opcode, stream, callback, null);
|
action.BeginInvoke(opcode, stream, callback, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private long sendFragmented(Opcode opcode, Stream stream)
|
private long sendFragmented(Opcode opcode, Stream stream, bool compressed)
|
||||||
{
|
{
|
||||||
var length = stream.Length;
|
var length = stream.Length;
|
||||||
var quo = length / _fragmentLen;
|
var quo = length / _fragmentLen;
|
||||||
@ -1270,7 +1290,7 @@ namespace WebSocketSharp {
|
|||||||
|
|
||||||
// First
|
// First
|
||||||
tmpLen = stream.Read(buffer, 0, _fragmentLen);
|
tmpLen = stream.Read(buffer, 0, _fragmentLen);
|
||||||
if (send(Fin.MORE, opcode, buffer))
|
if (send(Fin.MORE, opcode, buffer, compressed))
|
||||||
readLen += tmpLen;
|
readLen += tmpLen;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
@ -1279,7 +1299,7 @@ namespace WebSocketSharp {
|
|||||||
for (long i = 0; i < count; i++)
|
for (long i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
tmpLen = stream.Read(buffer, 0, _fragmentLen);
|
tmpLen = stream.Read(buffer, 0, _fragmentLen);
|
||||||
if (send(Fin.MORE, Opcode.CONT, buffer))
|
if (send(Fin.MORE, Opcode.CONT, buffer, compressed))
|
||||||
readLen += tmpLen;
|
readLen += tmpLen;
|
||||||
else
|
else
|
||||||
return readLen;
|
return readLen;
|
||||||
@ -1289,7 +1309,7 @@ namespace WebSocketSharp {
|
|||||||
if (rem != 0)
|
if (rem != 0)
|
||||||
buffer = new byte[rem];
|
buffer = new byte[rem];
|
||||||
tmpLen = stream.Read(buffer, 0, buffer.Length);
|
tmpLen = stream.Read(buffer, 0, buffer.Length);
|
||||||
if (send(Fin.FINAL, Opcode.CONT, buffer))
|
if (send(Fin.FINAL, Opcode.CONT, buffer, compressed))
|
||||||
readLen += tmpLen;
|
readLen += tmpLen;
|
||||||
|
|
||||||
return readLen;
|
return readLen;
|
||||||
|
@ -178,6 +178,19 @@ namespace WebSocketSharp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal bool PerMessageCompressed {
|
||||||
|
get {
|
||||||
|
return IsData && IsCompressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
set {
|
||||||
|
if (value && !IsData)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Rsv1 = value ? Rsv.ON : Rsv.OFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Public Properties
|
#region Public Properties
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,6 +1,6 @@
|
|||||||
<Type Name="WebSocket" FullName="WebSocketSharp.WebSocket">
|
<Type Name="WebSocket" FullName="WebSocketSharp.WebSocket">
|
||||||
<TypeSignature Language="C#" Value="public class WebSocket : IDisposable" />
|
<TypeSignature Language="C#" Value="public class WebSocket : IDisposable" />
|
||||||
<TypeSignature Language="ILAsm" Value=".class public auto ansi WebSocket extends System.Object implements class System.IDisposable" />
|
<TypeSignature Language="ILAsm" Value=".class public auto ansi beforefieldinit WebSocket extends System.Object implements class System.IDisposable" />
|
||||||
<AssemblyInfo>
|
<AssemblyInfo>
|
||||||
<AssemblyName>websocket-sharp</AssemblyName>
|
<AssemblyName>websocket-sharp</AssemblyName>
|
||||||
</AssemblyInfo>
|
</AssemblyInfo>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<Overview>
|
<Overview>
|
||||||
<Assemblies>
|
<Assemblies>
|
||||||
<Assembly Name="websocket-sharp" Version="1.0.2.32570">
|
<Assembly Name="websocket-sharp" Version="1.0.2.4444">
|
||||||
<AssemblyPublicKey>[00 24 00 00 04 80 00 00 94 00 00 00 06 02 00 00 00 24 00 00 52 53 41 31 00 04 00 00 11 00 00 00 29 17 fb 89 fe c3 91 f7 2b cb 8b e2 61 d2 3f 05 93 6d 65 a8 9e 63 72 a6 f5 d5 2c f2 9d 20 fa 0b c0 70 6a f6 88 7e 8b 90 3f 39 f5 76 c8 48 e0 bb 7b b2 7b ed d3 10 a7 1a 0f 70 98 0f 7f f4 4b 53 09 d2 a5 ef 36 c3 56 b4 aa f0 91 72 63 25 07 89 e0 93 3e 3f 2e f2 b9 73 0e 12 15 5d 43 56 c3 f4 70 a5 89 fe f7 f6 ac 3e 77 c2 d8 d0 84 91 f4 0c d1 f3 8e dc c3 c3 b8 38 3d 0c bf 17 de 20 78 c1 ]</AssemblyPublicKey>
|
<AssemblyPublicKey>[00 24 00 00 04 80 00 00 94 00 00 00 06 02 00 00 00 24 00 00 52 53 41 31 00 04 00 00 11 00 00 00 29 17 fb 89 fe c3 91 f7 2b cb 8b e2 61 d2 3f 05 93 6d 65 a8 9e 63 72 a6 f5 d5 2c f2 9d 20 fa 0b c0 70 6a f6 88 7e 8b 90 3f 39 f5 76 c8 48 e0 bb 7b b2 7b ed d3 10 a7 1a 0f 70 98 0f 7f f4 4b 53 09 d2 a5 ef 36 c3 56 b4 aa f0 91 72 63 25 07 89 e0 93 3e 3f 2e f2 b9 73 0e 12 15 5d 43 56 c3 f4 70 a5 89 fe f7 f6 ac 3e 77 c2 d8 d0 84 91 f4 0c d1 f3 8e dc c3 c3 b8 38 3d 0c bf 17 de 20 78 c1 ]</AssemblyPublicKey>
|
||||||
<Attributes>
|
<Attributes>
|
||||||
<Attribute>
|
<Attribute>
|
||||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user