public void Should_correctly_receive_a_non_ascii_header_from_server() { if (!RuntimeDetector.IsDotNet50AndNewer) { return; } var responseBuilder = new StringBuilder(); responseBuilder.AppendLine("HTTP/1.1 200 OK"); responseBuilder.AppendLine("Connection: close"); responseBuilder.AppendLine("Content-Length: 0"); responseBuilder.AppendLine("Custom-Header: кириллица"); responseBuilder.AppendLine("Content-Disposition: ещё кириллица"); responseBuilder.AppendLine(); using (var server = SocketTestServer.StartNew(responseBuilder.ToString())) { var response = Send(Request.Post(server.Url)); response.Headers["Custom-Header"].Should().Be("кириллица"); response.Headers["Content-Disposition"].Should().Be("ещё кириллица"); } }
public async Task Connection_Pipe_ReadWrite_Integration(int totalLines) { using SocketsConnectionFactory factory = new SocketsConnectionFactory(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); using SocketTestServer echoServer = SocketTestServer.SocketTestServerFactory(SocketImplementationType.Async, IPAddress.Loopback); Socket serverSocket = null; echoServer.Accepted += s => serverSocket = s; using Connection connection = await factory.ConnectAsync(echoServer.EndPoint); IDuplexPipe pipe = connection.Pipe; ConcurrentQueue <string> linesSent = new ConcurrentQueue <string>(); Task writerTask = Task.Factory.StartNew(async() => { byte[] endl = Encoding.ASCII.GetBytes("\n"); StringBuilder expectedLine = new StringBuilder(); for (int i = 0; i < totalLines; i++) { int words = i % 10 + 1; for (int j = 0; j < words; j++) { string word = Guid.NewGuid() + " "; Encoding.ASCII.GetBytes(word, pipe.Output); expectedLine.Append(word); } linesSent.Enqueue(expectedLine.ToString()); await pipe.Output.WriteAsync(endl); expectedLine.Clear(); } await pipe.Output.FlushAsync(); // This will also trigger completion on the reader. TODO: Fix // await pipe.Output.CompleteAsync(); }, TaskCreationOptions.LongRunning); // The test server should echo the data sent to it PipeReader reader = pipe.Input; int lineIndex = 0; void ProcessLine(ReadOnlySequence <byte> lineBuffer) { string line = Encoding.ASCII.GetString(lineBuffer); Assert.True(linesSent.TryDequeue(out string expectedLine)); Assert.Equal(expectedLine, line); lineIndex++; // Received everything, shut down the server, so next read will complete: if (lineIndex == totalLines) { serverSocket.Shutdown(SocketShutdown.Both); } } while (true) { try { ReadResult result = await reader.ReadAsync(); ReadOnlySequence <byte> buffer = result.Buffer; SequencePosition? position = null; // Stop reading if there's no more data coming if (result.IsCompleted) { break; } do { // Look for a EOL in the buffer position = buffer.PositionOf((byte)'\n'); if (position != null) { // Process the line ProcessLine(buffer.Slice(0, position.Value)); // Skip the line + the \n character (basically position) buffer = buffer.Slice(buffer.GetPosition(1, position.Value)); } }while (position != null); // Tell the PipeReader how much of the buffer we have consumed reader.AdvanceTo(buffer.Start, buffer.End); } catch (SocketException) { // terminate } } // Mark the PipeReader as complete await reader.CompleteAsync(); await writerTask; // TODO: If this is done in the end of writerTask the socket stops working Assert.Equal(totalLines, lineIndex); }