Modified WebSocket.cs

This commit is contained in:
sta
2013-05-01 14:27:24 +09:00
parent 2a816ef0c8
commit 585686f401
22 changed files with 120 additions and 79 deletions

View File

@@ -548,6 +548,56 @@ namespace WebSocketSharp {
}
}
private bool concatenateFragments(Stream dest)
{
Func<WsFrame, bool> processContinuation = contFrame =>
{
if (!contFrame.IsContinuation)
return false;
dest.WriteBytes(contFrame.PayloadData.ApplicationData);
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 bool connect()
{
return _client
@@ -565,11 +615,9 @@ namespace WebSocketSharp {
return Convert.ToBase64String(src);
}
private static string createCompressExtension(CompressionMethod method)
private static string createCompressionExtension(CompressionMethod method)
{
return method != CompressionMethod.NONE
? String.Format("permessage-compress; method={0}", method.ToString().ToLower())
: String.Empty;
return createCurrentCompressionExtension(method);
}
private static WsFrame createControlFrame(Opcode opcode, PayloadData payloadData, bool client)
@@ -577,6 +625,20 @@ namespace WebSocketSharp {
return createFrame(Fin.FINAL, opcode, payloadData, false, client);
}
private static string createCurrentCompressionExtension(CompressionMethod method)
{
return method != CompressionMethod.NONE
? String.Format("permessage-{0}", method.ToString().ToLower())
: String.Empty;
}
private static string createDeprecatedCompressionExtension(CompressionMethod method)
{
return method != CompressionMethod.NONE
? String.Format("permessage-compress; method={0}", method.ToString().ToLower())
: String.Empty;
}
private static WsFrame createFrame(
Fin fin, Opcode opcode, PayloadData payloadData, bool compressed, bool client)
{
@@ -590,9 +652,9 @@ namespace WebSocketSharp {
private string createRequestExtensions()
{
var extensions = new StringBuilder(64);
var compress = createCompressExtension(_compression);
if (!compress.IsEmpty())
extensions.Append(compress);
var comp = createCompressionExtension(_compression);
if (!comp.IsEmpty())
extensions.Append(comp);
return extensions.Length > 0
? extensions.ToString()
@@ -671,6 +733,19 @@ namespace WebSocketSharp {
return processResponseHandshake();
}
private static CompressionMethod getCompressionMethod(string value)
{
var deprecated = createDeprecatedCompressionExtension(CompressionMethod.DEFLATE);
if (value.Equals(deprecated))
return CompressionMethod.DEFLATE;
foreach (CompressionMethod method in Enum.GetValues(typeof(CompressionMethod)))
if (isCompressionExtension(value, method))
return method;
return CompressionMethod.NONE;
}
// As client
private void init()
{
@@ -691,9 +766,14 @@ namespace WebSocketSharp {
_client = false;
}
private static bool isCompressExtension(string value, CompressionMethod method)
private static bool isCompressionExtension(string value)
{
var expected = createCompressExtension(method);
return value.StartsWith("permessage-");
}
private static bool isCompressionExtension(string value, CompressionMethod method)
{
var expected = createCompressionExtension(method);
return !expected.IsEmpty()
? value.Equals(expected)
: false;
@@ -751,56 +831,6 @@ namespace WebSocketSharp {
response.HeaderExists("Sec-WebSocket-Version", _version);
}
private bool mergeFragments(Stream dest)
{
Func<WsFrame, bool> processContinuation = contFrame =>
{
if (!contFrame.IsContinuation)
return false;
dest.WriteBytes(contFrame.PayloadData.ApplicationData);
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)
@@ -931,21 +961,21 @@ namespace WebSocketSharp {
private void processFragments(WsFrame first)
{
using (var merge = new MemoryStream())
using (var concatenated = new MemoryStream())
{
merge.WriteBytes(first.PayloadData.ApplicationData);
if (!mergeFragments(merge))
concatenated.WriteBytes(first.PayloadData.ApplicationData);
if (!concatenateFragments(concatenated))
return;
byte[] data;
if (_compression != CompressionMethod.NONE)
{
data = merge.DecompressToArray(_compression);
data = concatenated.DecompressToArray(_compression);
}
else
{
merge.Close();
data = merge.ToArray();
concatenated.Close();
data = concatenated.ToArray();
}
onMessage(new MessageEventArgs(first.Opcode, data));
@@ -1005,17 +1035,21 @@ namespace WebSocketSharp {
if (extensions.IsNullOrEmpty())
return;
var compress = false;
var comp = false;
var buffer = new List<string>();
foreach (var extension in extensions.SplitHeaderValue(','))
{
var e = extension.Trim();
var tmp = e.RemovePrefix("x-webkit-");
if (!compress && isCompressExtension(tmp, CompressionMethod.DEFLATE))
if (!comp && isCompressionExtension(tmp))
{
_compression = CompressionMethod.DEFLATE;
compress = true;
buffer.Add(e);
var method = getCompressionMethod(tmp);
if (method != CompressionMethod.NONE)
{
_compression = method;
comp = true;
buffer.Add(e);
}
}
}
@@ -1062,20 +1096,26 @@ namespace WebSocketSharp {
// As client
private void processResponseExtensions(string extensions)
{
var compress = false;
var checkComp = _compression != CompressionMethod.NONE
? true
: false;
var comp = false;
if (!extensions.IsNullOrEmpty())
{
foreach (var extension in extensions.SplitHeaderValue(','))
{
var e = extension.Trim();
if (!compress && isCompressExtension(e, _compression))
compress = true;
if (checkComp &&
!comp &&
isCompressionExtension(e, _compression))
comp = true;
}
_extensions = extensions;
}
if (!compress)
if (checkComp && !comp)
_compression = CompressionMethod.NONE;
}

Binary file not shown.