finish binary protocol formatter/parser (#203)
This commit is contained in:
parent
94dc265658
commit
70d97dd7b8
|
|
@ -0,0 +1,130 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Binary;
|
||||
using System.IO.Pipelines;
|
||||
|
||||
namespace Microsoft.AspNetCore.Sockets
|
||||
{
|
||||
internal static class BinaryMessageFormatter
|
||||
{
|
||||
private const byte TextTypeFlag = 0x00;
|
||||
private const byte BinaryTypeFlag = 0x01;
|
||||
private const byte ErrorTypeFlag = 0x02;
|
||||
private const byte CloseTypeFlag = 0x03;
|
||||
|
||||
internal static bool TryFormatMessage(Message message, Span<byte> buffer, out int bytesWritten)
|
||||
{
|
||||
// We can check the size needed right up front!
|
||||
var sizeNeeded = sizeof(long) + 1 + message.Payload.Buffer.Length;
|
||||
if (buffer.Length < sizeNeeded)
|
||||
{
|
||||
bytesWritten = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
buffer.WriteBigEndian((long)message.Payload.Buffer.Length);
|
||||
if (!TryFormatType(message.Type, buffer.Slice(sizeof(long), 1)))
|
||||
{
|
||||
bytesWritten = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
buffer = buffer.Slice(sizeof(long) + 1);
|
||||
|
||||
message.Payload.Buffer.CopyTo(buffer);
|
||||
bytesWritten = sizeNeeded;
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static bool TryParseMessage(ReadOnlySpan<byte> buffer, out Message message, out int bytesConsumed)
|
||||
{
|
||||
// Check if we have enough to read the size and type flag
|
||||
if (buffer.Length < sizeof(long) + 1)
|
||||
{
|
||||
message = default(Message);
|
||||
bytesConsumed = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// REVIEW: The spec calls for 64-bit length but I'm thinking that's a little ridiculous.
|
||||
// REVIEW: We don't really have a primitive for storing that much data. For now, I'm using it
|
||||
// REVIEW: but throwing if the size is over 2GB.
|
||||
var longLength = buffer.ReadBigEndian<long>();
|
||||
if (longLength > Int32.MaxValue)
|
||||
{
|
||||
throw new FormatException("Messages over 2GB in size are not supported");
|
||||
}
|
||||
var length = (int)longLength;
|
||||
|
||||
if (!TryParseType(buffer[sizeof(long)], out var messageType))
|
||||
{
|
||||
message = default(Message);
|
||||
bytesConsumed = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if we actually have the whole payload
|
||||
if (buffer.Length < sizeof(long) + 1 + length)
|
||||
{
|
||||
message = default(Message);
|
||||
bytesConsumed = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Copy the payload into the buffer
|
||||
// REVIEW: Copy! Noooooooooo! But how can we capture a segment of the span as an "Owned" reference?
|
||||
// REVIEW: If we do have to copy, we should at least use a pooled buffer
|
||||
var buf = new byte[length];
|
||||
buffer.Slice(sizeof(long) + 1, length).CopyTo(buf);
|
||||
|
||||
message = new Message(ReadableBuffer.Create(buf).Preserve(), messageType, endOfMessage: true);
|
||||
bytesConsumed = sizeof(long) + 1 + length;
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool TryParseType(byte type, out MessageType messageType)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case TextTypeFlag:
|
||||
messageType = MessageType.Text;
|
||||
return true;
|
||||
case BinaryTypeFlag:
|
||||
messageType = MessageType.Binary;
|
||||
return true;
|
||||
case CloseTypeFlag:
|
||||
messageType = MessageType.Close;
|
||||
return true;
|
||||
case ErrorTypeFlag:
|
||||
messageType = MessageType.Error;
|
||||
return true;
|
||||
default:
|
||||
messageType = default(MessageType);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool TryFormatType(MessageType type, Span<byte> buffer)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case MessageType.Text:
|
||||
buffer[0] = TextTypeFlag;
|
||||
return true;
|
||||
case MessageType.Binary:
|
||||
buffer[0] = BinaryTypeFlag;
|
||||
return true;
|
||||
case MessageType.Close:
|
||||
buffer[0] = CloseTypeFlag;
|
||||
return true;
|
||||
case MessageType.Error:
|
||||
buffer[0] = ErrorTypeFlag;
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -18,14 +18,14 @@ namespace Microsoft.AspNetCore.Sockets
|
|||
}
|
||||
return format == MessageFormat.Text ?
|
||||
TextMessageFormatter.TryFormatMessage(message, buffer, out bytesWritten) :
|
||||
throw new NotImplementedException();
|
||||
BinaryMessageFormatter.TryFormatMessage(message, buffer, out bytesWritten);
|
||||
}
|
||||
|
||||
public static bool TryParseMessage(ReadOnlySpan<byte> buffer, MessageFormat format, out Message message, out int bytesConsumed)
|
||||
{
|
||||
return format == MessageFormat.Text ?
|
||||
TextMessageFormatter.TryParseMessage(buffer, out message, out bytesConsumed) :
|
||||
throw new NotImplementedException();
|
||||
BinaryMessageFormatter.TryParseMessage(buffer, out message, out bytesConsumed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Sockets
|
|||
private const byte CloseTypeFlag = (byte)'C';
|
||||
private const byte ErrorTypeFlag = (byte)'E';
|
||||
|
||||
public static bool TryFormatMessage(Message message, Span<byte> buffer, out int bytesWritten)
|
||||
internal static bool TryFormatMessage(Message message, Span<byte> buffer, out int bytesWritten)
|
||||
{
|
||||
// Calculate the length, it's the number of characters for text messages, but number of base64 characters for binary
|
||||
var length = message.Payload.Buffer.Length;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,171 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO.Pipelines;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Sockets.Tests
|
||||
{
|
||||
public partial class BinaryMessageFormatterTests
|
||||
{
|
||||
[Fact]
|
||||
public void WriteMultipleMessages()
|
||||
{
|
||||
var expectedEncoding = new byte[]
|
||||
{
|
||||
/* length: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* type: */ 0x01, // Binary
|
||||
/* body: <empty> */
|
||||
/* length: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E,
|
||||
/* type: */ 0x00, // Text
|
||||
/* body: */ 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x2C, 0x0D, 0x0A, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21,
|
||||
/* length: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
/* type: */ 0x03, // Close
|
||||
/* body: */ 0x41,
|
||||
/* length: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C,
|
||||
/* type: */ 0x02, // Error
|
||||
/* body: */ 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x45, 0x72, 0x72, 0x6F, 0x72
|
||||
};
|
||||
|
||||
var messages = new[]
|
||||
{
|
||||
MessageTestUtils.CreateMessage(new byte[0]),
|
||||
MessageTestUtils.CreateMessage("Hello,\r\nWorld!",MessageType.Text),
|
||||
MessageTestUtils.CreateMessage("A", MessageType.Close),
|
||||
MessageTestUtils.CreateMessage("Server Error", MessageType.Error)
|
||||
};
|
||||
|
||||
var array = new byte[256];
|
||||
var buffer = array.Slice();
|
||||
var totalConsumed = 0;
|
||||
foreach (var message in messages)
|
||||
{
|
||||
Assert.True(MessageFormatter.TryFormatMessage(message, buffer, MessageFormat.Binary, out var consumed));
|
||||
buffer = buffer.Slice(consumed);
|
||||
totalConsumed += consumed;
|
||||
}
|
||||
|
||||
Assert.Equal(expectedEncoding, array.Slice(0, totalConsumed).ToArray());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, new byte[0])]
|
||||
[InlineData(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0xAB, 0xCD, 0xEF, 0x12 }, new byte[] { 0xAB, 0xCD, 0xEF, 0x12 })]
|
||||
public void WriteBinaryMessage(byte[] encoded, byte[] payload)
|
||||
{
|
||||
var message = MessageTestUtils.CreateMessage(payload);
|
||||
var buffer = new byte[256];
|
||||
|
||||
Assert.True(MessageFormatter.TryFormatMessage(message, buffer, MessageFormat.Binary, out var bytesWritten));
|
||||
|
||||
var encodedSpan = buffer.Slice(0, bytesWritten);
|
||||
Assert.Equal(encoded, encodedSpan.ToArray());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, MessageType.Text, "")]
|
||||
[InlineData(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x41, 0x42, 0x43 }, MessageType.Text, "ABC")]
|
||||
[InlineData(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x41, 0x0A, 0x52, 0x0D, 0x43, 0x0D, 0x0A, 0x3B, 0x44, 0x45, 0x46 }, MessageType.Text, "A\nR\rC\r\n;DEF")]
|
||||
[InlineData(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03 }, MessageType.Close, "")]
|
||||
[InlineData(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x03, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x43, 0x6C, 0x6F, 0x73, 0x65, 0x64 }, MessageType.Close, "Connection Closed")]
|
||||
[InlineData(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }, MessageType.Error, "")]
|
||||
[InlineData(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x02, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x45, 0x72, 0x72, 0x6F, 0x72 }, MessageType.Error, "Server Error")]
|
||||
public void WriteTextMessage(byte[] encoded, MessageType messageType, string payload)
|
||||
{
|
||||
var message = MessageTestUtils.CreateMessage(payload, messageType);
|
||||
var buffer = new byte[256];
|
||||
|
||||
Assert.True(MessageFormatter.TryFormatMessage(message, buffer, MessageFormat.Binary, out var bytesWritten));
|
||||
|
||||
var encodedSpan = buffer.Slice(0, bytesWritten);
|
||||
Assert.Equal(encoded, encodedSpan.ToArray());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteInvalidMessages()
|
||||
{
|
||||
var message = new Message(ReadableBuffer.Create(new byte[0]).Preserve(), MessageType.Binary, endOfMessage: false);
|
||||
var ex = Assert.Throws<InvalidOperationException>(() =>
|
||||
MessageFormatter.TryFormatMessage(message, Span<byte>.Empty, MessageFormat.Binary, out var written));
|
||||
Assert.Equal("Cannot format message where endOfMessage is false using this format", ex.Message);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, MessageType.Text, "")]
|
||||
[InlineData(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x41, 0x42, 0x43 }, MessageType.Text, "ABC")]
|
||||
[InlineData(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x41, 0x0A, 0x52, 0x0D, 0x43, 0x0D, 0x0A, 0x3B, 0x44, 0x45, 0x46 }, MessageType.Text, "A\nR\rC\r\n;DEF")]
|
||||
[InlineData(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03 }, MessageType.Close, "")]
|
||||
[InlineData(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x03, 0x43, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x43, 0x6C, 0x6F, 0x73, 0x65, 0x64 }, MessageType.Close, "Connection Closed")]
|
||||
[InlineData(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }, MessageType.Error, "")]
|
||||
[InlineData(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x02, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x45, 0x72, 0x72, 0x6F, 0x72 }, MessageType.Error, "Server Error")]
|
||||
public void ReadTextMessage(byte[] encoded, MessageType messageType, string payload)
|
||||
{
|
||||
Assert.True(MessageFormatter.TryParseMessage(encoded, MessageFormat.Binary, out var message, out var consumed));
|
||||
Assert.Equal(consumed, encoded.Length);
|
||||
|
||||
MessageTestUtils.AssertMessage(message, messageType, payload);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, new byte[0])]
|
||||
[InlineData(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0xAB, 0xCD, 0xEF, 0x12 }, new byte[] { 0xAB, 0xCD, 0xEF, 0x12 })]
|
||||
public void ReadBinaryMessage(byte[] encoded, byte[] payload)
|
||||
{
|
||||
Assert.True(MessageFormatter.TryParseMessage(encoded, MessageFormat.Binary, out var message, out var consumed));
|
||||
Assert.Equal(consumed, encoded.Length);
|
||||
|
||||
MessageTestUtils.AssertMessage(message, MessageType.Binary, payload);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReadMultipleMessages()
|
||||
{
|
||||
var encoded = new byte[]
|
||||
{
|
||||
/* length: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* type: */ 0x01, // Binary
|
||||
/* body: <empty> */
|
||||
/* length: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E,
|
||||
/* type: */ 0x00, // Text
|
||||
/* body: */ 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x2C, 0x0D, 0x0A, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21,
|
||||
/* length: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
/* type: */ 0x03, // Close
|
||||
/* body: */ 0x41,
|
||||
/* length: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C,
|
||||
/* type: */ 0x02, // Error
|
||||
/* body: */ 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x45, 0x72, 0x72, 0x6F, 0x72
|
||||
};
|
||||
var buffer = encoded.Slice();
|
||||
|
||||
var messages = new List<Message>();
|
||||
var consumedTotal = 0;
|
||||
while (MessageFormatter.TryParseMessage(buffer, MessageFormat.Binary, out var message, out var consumed))
|
||||
{
|
||||
messages.Add(message);
|
||||
consumedTotal += consumed;
|
||||
buffer = buffer.Slice(consumed);
|
||||
}
|
||||
|
||||
Assert.Equal(consumedTotal, encoded.Length);
|
||||
|
||||
Assert.Equal(4, messages.Count);
|
||||
MessageTestUtils.AssertMessage(messages[0], MessageType.Binary, new byte[0]);
|
||||
MessageTestUtils.AssertMessage(messages[1], MessageType.Text, "Hello,\r\nWorld!");
|
||||
MessageTestUtils.AssertMessage(messages[2], MessageType.Close, "A");
|
||||
MessageTestUtils.AssertMessage(messages[3], MessageType.Error, "Server Error");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(new byte[0])] // Empty
|
||||
[InlineData(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })] // Just length
|
||||
[InlineData(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00 })] // Not enough data for payload
|
||||
[InlineData(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04 })] // Invalid Type
|
||||
public void ReadInvalidMessages(byte[] encoded)
|
||||
{
|
||||
Assert.False(MessageFormatter.TryParseMessage(encoded, MessageFormat.Binary, out var message, out var consumed));
|
||||
Assert.Equal(0, consumed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
using System.IO.Pipelines;
|
||||
using System.Text;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Sockets.Tests
|
||||
{
|
||||
internal static class MessageTestUtils
|
||||
{
|
||||
public static void AssertMessage(Message message, MessageType messageType, byte[] payload)
|
||||
{
|
||||
Assert.True(message.EndOfMessage);
|
||||
Assert.Equal(messageType, message.Type);
|
||||
Assert.Equal(payload, message.Payload.Buffer.ToArray());
|
||||
}
|
||||
|
||||
public static void AssertMessage(Message message, MessageType messageType, string payload)
|
||||
{
|
||||
Assert.True(message.EndOfMessage);
|
||||
Assert.Equal(messageType, message.Type);
|
||||
Assert.Equal(payload, Encoding.UTF8.GetString(message.Payload.Buffer.ToArray()));
|
||||
}
|
||||
|
||||
public static Message CreateMessage(byte[] payload, MessageType type = MessageType.Binary)
|
||||
{
|
||||
return new Message(
|
||||
ReadableBuffer.Create(payload).Preserve(),
|
||||
type,
|
||||
endOfMessage: true);
|
||||
}
|
||||
|
||||
public static Message CreateMessage(string payload, MessageType type)
|
||||
{
|
||||
return new Message(
|
||||
ReadableBuffer.Create(Encoding.UTF8.GetBytes(payload)).Preserve(),
|
||||
type,
|
||||
endOfMessage: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
|
|
@ -9,7 +9,7 @@ using Xunit;
|
|||
|
||||
namespace Microsoft.AspNetCore.Sockets.Tests
|
||||
{
|
||||
public class MessageFormatterTests
|
||||
public class TextMessageFormatterTests
|
||||
{
|
||||
[Fact]
|
||||
public void WriteMultipleMessages()
|
||||
|
|
@ -17,10 +17,10 @@ namespace Microsoft.AspNetCore.Sockets.Tests
|
|||
const string expectedEncoding = "0:B:;14:T:Hello,\r\nWorld!;1:C:A;12:E:Server Error;";
|
||||
var messages = new[]
|
||||
{
|
||||
CreateMessage(new byte[0]),
|
||||
CreateMessage("Hello,\r\nWorld!",MessageType.Text),
|
||||
CreateMessage("A", MessageType.Close),
|
||||
CreateMessage("Server Error", MessageType.Error)
|
||||
MessageTestUtils.CreateMessage(new byte[0]),
|
||||
MessageTestUtils.CreateMessage("Hello,\r\nWorld!",MessageType.Text),
|
||||
MessageTestUtils.CreateMessage("A", MessageType.Close),
|
||||
MessageTestUtils.CreateMessage("Server Error", MessageType.Error)
|
||||
};
|
||||
|
||||
var array = new byte[256];
|
||||
|
|
@ -41,7 +41,7 @@ namespace Microsoft.AspNetCore.Sockets.Tests
|
|||
[InlineData("8:B:q83vEg==;", new byte[] { 0xAB, 0xCD, 0xEF, 0x12 })]
|
||||
public void WriteBinaryMessage(string encoded, byte[] payload)
|
||||
{
|
||||
var message = CreateMessage(payload);
|
||||
var message = MessageTestUtils.CreateMessage(payload);
|
||||
var buffer = new byte[256];
|
||||
|
||||
Assert.True(MessageFormatter.TryFormatMessage(message, buffer, MessageFormat.Text, out var bytesWritten));
|
||||
|
|
@ -60,7 +60,7 @@ namespace Microsoft.AspNetCore.Sockets.Tests
|
|||
[InlineData("12:E:Server Error;", MessageType.Error, "Server Error")]
|
||||
public void WriteTextMessage(string encoded, MessageType messageType, string payload)
|
||||
{
|
||||
var message = CreateMessage(payload, messageType);
|
||||
var message = MessageTestUtils.CreateMessage(payload, messageType);
|
||||
var buffer = new byte[256];
|
||||
|
||||
Assert.True(MessageFormatter.TryFormatMessage(message, buffer, MessageFormat.Text, out var bytesWritten));
|
||||
|
|
@ -93,7 +93,7 @@ namespace Microsoft.AspNetCore.Sockets.Tests
|
|||
Assert.True(MessageFormatter.TryParseMessage(buffer, MessageFormat.Text, out var message, out var consumed));
|
||||
Assert.Equal(consumed, buffer.Length);
|
||||
|
||||
AssertMessage(message, messageType, payload);
|
||||
MessageTestUtils.AssertMessage(message, messageType, payload);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
|
@ -106,7 +106,7 @@ namespace Microsoft.AspNetCore.Sockets.Tests
|
|||
Assert.True(MessageFormatter.TryParseMessage(buffer, MessageFormat.Text, out var message, out var consumed));
|
||||
Assert.Equal(consumed, buffer.Length);
|
||||
|
||||
AssertMessage(message, MessageType.Binary, payload);
|
||||
MessageTestUtils.AssertMessage(message, MessageType.Binary, payload);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -127,10 +127,10 @@ namespace Microsoft.AspNetCore.Sockets.Tests
|
|||
Assert.Equal(consumedTotal, Encoding.UTF8.GetByteCount(encoded));
|
||||
|
||||
Assert.Equal(4, messages.Count);
|
||||
AssertMessage(messages[0], MessageType.Binary, new byte[0]);
|
||||
AssertMessage(messages[1], MessageType.Text, "Hello,\r\nWorld!");
|
||||
AssertMessage(messages[2], MessageType.Close, "A");
|
||||
AssertMessage(messages[3], MessageType.Error, "Server Error");
|
||||
MessageTestUtils.AssertMessage(messages[0], MessageType.Binary, new byte[0]);
|
||||
MessageTestUtils.AssertMessage(messages[1], MessageType.Text, "Hello,\r\nWorld!");
|
||||
MessageTestUtils.AssertMessage(messages[2], MessageType.Close, "A");
|
||||
MessageTestUtils.AssertMessage(messages[3], MessageType.Error, "Server Error");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
|
@ -152,35 +152,5 @@ namespace Microsoft.AspNetCore.Sockets.Tests
|
|||
Assert.False(MessageFormatter.TryParseMessage(buffer, MessageFormat.Text, out var message, out var consumed));
|
||||
Assert.Equal(0, consumed);
|
||||
}
|
||||
|
||||
private static void AssertMessage(Message message, MessageType messageType, byte[] payload)
|
||||
{
|
||||
Assert.True(message.EndOfMessage);
|
||||
Assert.Equal(messageType, message.Type);
|
||||
Assert.Equal(payload, message.Payload.Buffer.ToArray());
|
||||
}
|
||||
|
||||
private static void AssertMessage(Message message, MessageType messageType, string payload)
|
||||
{
|
||||
Assert.True(message.EndOfMessage);
|
||||
Assert.Equal(messageType, message.Type);
|
||||
Assert.Equal(payload, Encoding.UTF8.GetString(message.Payload.Buffer.ToArray()));
|
||||
}
|
||||
|
||||
private static Message CreateMessage(byte[] payload, MessageType type = MessageType.Binary)
|
||||
{
|
||||
return new Message(
|
||||
ReadableBuffer.Create(payload).Preserve(),
|
||||
type,
|
||||
endOfMessage: true);
|
||||
}
|
||||
|
||||
private static Message CreateMessage(string payload, MessageType type)
|
||||
{
|
||||
return new Message(
|
||||
ReadableBuffer.Create(Encoding.UTF8.GetBytes(payload)).Preserve(),
|
||||
type,
|
||||
endOfMessage: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue