-
Notifications
You must be signed in to change notification settings - Fork 4.9k
Add more Http response stream tests #6277
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
| // See the LICENSE file in the project root for more information. | ||
|
|
||
| using System; | ||
| using System.IO; | ||
| using System.Net; | ||
| using System.Net.Sockets; | ||
| using System.Text; | ||
| using System.Threading.Tasks; | ||
|
|
||
| namespace System.Net.Http.Functional.Tests | ||
| { | ||
| public class LoopbackServer | ||
| { | ||
| public enum TransferType | ||
| { | ||
| None = 0, | ||
| ContentLength, | ||
| Chunked | ||
| } | ||
|
|
||
| public enum TransferError | ||
| { | ||
| None = 0, | ||
| ContentLengthTooLarge, | ||
| ChunkSizeTooLarge, | ||
| MissingChunkTerminator | ||
| } | ||
|
|
||
| public static Task StartServer( | ||
| TransferType transferType, | ||
| TransferError transferError, | ||
| out IPEndPoint serverEndPoint) | ||
| { | ||
| var server = new TcpListener(IPAddress.Loopback, 0); | ||
| Task serverTask = ((Func<Task>)async delegate { | ||
| server.Start(); | ||
| using (var client = await server.AcceptSocketAsync()) | ||
| using (var stream = new NetworkStream(client)) | ||
| using (var reader = new StreamReader(stream, Encoding.ASCII)) | ||
| { | ||
| // Read past request headers. | ||
| string line; | ||
| while (!string.IsNullOrEmpty(line = reader.ReadLine())) ; | ||
|
|
||
| // Determine response transfer headers. | ||
| string transferHeader = null; | ||
| string content = "This is some response content."; | ||
| if (transferType == TransferType.ContentLength) | ||
| { | ||
| if (transferError == TransferError.ContentLengthTooLarge) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (if you change the enum as questioned, these comparisons will of course need to change, too) |
||
| { | ||
| transferHeader = $"Content-Length: {content.Length + 42}\r\n"; | ||
| } | ||
| else | ||
| { | ||
| transferHeader = $"Content-Length: {content.Length}\r\n"; | ||
| } | ||
| } | ||
| else if (transferType == TransferType.Chunked) | ||
| { | ||
| transferHeader = "Transfer-Encoding: chunked\r\n"; | ||
| } | ||
|
|
||
| // Write response. | ||
| using (var writer = new StreamWriter(stream, Encoding.ASCII)) | ||
| { | ||
| writer.Write("HTTP/1.1 200 OK\r\n"); | ||
| writer.Write($"Date: {DateTimeOffset.UtcNow:R}\r\n"); | ||
| writer.Write("Content-Type: text/plain\r\n"); | ||
|
|
||
| if (!string.IsNullOrEmpty(transferHeader)) | ||
| { | ||
| writer.Write(transferHeader); | ||
| } | ||
|
|
||
| writer.Write("\r\n"); | ||
| if (transferType == TransferType.Chunked) | ||
| { | ||
| string chunkSizeInHex = string.Format( | ||
| "{0:x}\r\n", | ||
| content.Length + (transferError == TransferError.ChunkSizeTooLarge ? 42 : 0)); | ||
| writer.Write(chunkSizeInHex); | ||
| writer.Write($"{content}\r\n"); | ||
| if (transferError != TransferError.MissingChunkTerminator) | ||
| { | ||
| writer.Write("0\r\n\r\n"); | ||
| } | ||
| } | ||
| else | ||
| { | ||
| writer.Write($"{content}\r\n"); | ||
| } | ||
| writer.Flush(); | ||
| } | ||
|
|
||
| client.Shutdown(SocketShutdown.Both); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know this is preexisting from my change, but it's there any chance anything above throws, and if so, what happens if this shutdown doesn't happen? Just wondering if this should be in a finally.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If something throws, then the StartServer task will fault. And the |
||
| } | ||
| })(); | ||
|
|
||
| serverEndPoint = (IPEndPoint)server.LocalEndpoint; | ||
| return serverTask; | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be a flags enum so that multiple failure conditions can be specified, or are they mutually exclusive?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only two that could be combined as flags would be
ChunkSizeTooLargeandMissingChunkTerminator, i.e. both of the invalid conditions could be present. But I currently don't test for that.ContentLengthTooLargeis basically mutually exclusive with the other two chunk related errors. I didn't think it was necessary to test every combination of the chunked failures.