Avoid intermediate strings in MCP transport serialization (#1274)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com> Co-authored-by: Stephen Toub <stoub@microsoft.com> Co-authored-by: halter73 <54385+halter73@users.noreply.github.com>
This commit is contained in:
parent
c3bb9c1955
commit
f3da4729f5
1 changed files with 136 additions and 63 deletions
|
|
@ -227,6 +227,54 @@ public class StdioServerTransportTests : LoggedTest
|
|||
Assert.Contains(traceLogMessages, x => x.Message.Contains("\"method\":\"test\"") && x.Message.Contains("\"id\":44"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SendMessageAsync_Should_Use_LF_Not_CRLF()
|
||||
{
|
||||
using var output = new MemoryStream();
|
||||
|
||||
await using var transport = new StreamServerTransport(
|
||||
new Pipe().Reader.AsStream(),
|
||||
output,
|
||||
loggerFactory: LoggerFactory);
|
||||
|
||||
var message = new JsonRpcRequest { Method = "test", Id = new RequestId(44) };
|
||||
|
||||
await transport.SendMessageAsync(message, TestContext.Current.CancellationToken);
|
||||
|
||||
byte[] bytes = output.ToArray();
|
||||
|
||||
// The output should end with exactly \n (0x0A), not \r\n (0x0D 0x0A).
|
||||
Assert.True(bytes.Length > 1, "Output should contain message data");
|
||||
Assert.Equal((byte)'\n', bytes[^1]);
|
||||
Assert.NotEqual((byte)'\r', bytes[^2]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReadMessagesAsync_Should_Accept_CRLF_Delimited_Messages()
|
||||
{
|
||||
var message = new JsonRpcRequest { Method = "test", Id = new RequestId(44) };
|
||||
var json = JsonSerializer.Serialize(message, McpJsonUtilities.DefaultOptions);
|
||||
|
||||
Pipe pipe = new();
|
||||
using var input = pipe.Reader.AsStream();
|
||||
|
||||
await using var transport = new StreamServerTransport(
|
||||
input,
|
||||
Stream.Null,
|
||||
loggerFactory: LoggerFactory);
|
||||
|
||||
// Write the message with \r\n line ending
|
||||
await pipe.Writer.WriteAsync(Encoding.UTF8.GetBytes($"{json}\r\n"), TestContext.Current.CancellationToken);
|
||||
|
||||
var canRead = await transport.MessageReader.WaitToReadAsync(TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.True(canRead, "Should be able to read a \\r\\n-delimited message");
|
||||
Assert.True(transport.MessageReader.TryPeek(out var readMessage));
|
||||
Assert.NotNull(readMessage);
|
||||
Assert.IsType<JsonRpcRequest>(readMessage);
|
||||
Assert.Equal("44", ((JsonRpcRequest)readMessage).Id.ToString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReadMessagesAsync_Should_Log_Received_At_Trace_Level()
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue