You've already forked linux-packaging-mono
acceptance-tests
data
debian
docs
external
Newtonsoft.Json
api-doc-tools
api-snapshot
aspnetwebstack
packages
src
test
Microsoft.TestCommon
Microsoft.Web.Helpers.Test
Microsoft.Web.Http.Data.Test
Microsoft.Web.Mvc.Test
Microsoft.Web.WebPages.OAuth.Test
SPA.Test
System.Json.Test.Integration
System.Json.Test.Unit
System.Net.Http.Formatting.Test.Integration
System.Net.Http.Formatting.Test.Unit
System.Web.Helpers.Test
System.Web.Http.Integration.Test
System.Web.Http.SelfHost.Test
Properties
DeeplyNestedTypeTests.cs
HttpSelfHostConfigurationTest.cs
HttpSelfHostServerTest.cs
MaxHttpCollectionKeyTests.cs
System.Web.Http.SelfHost.Test.csproj
packages.config
System.Web.Http.Test
System.Web.Http.WebHost.Test
System.Web.Mvc.Test
System.Web.Razor.Test
System.Web.WebPages.Administration.Test
System.Web.WebPages.Deployment.Test
System.Web.WebPages.Razor.Test
System.Web.WebPages.Test
WebMatrix.Data.Test
WebMatrix.WebData.Test
Settings.StyleCop
tools
.gitattributes
.gitignore
License.txt
README.md
Runtime.msbuild
Runtime.sln
Runtime.xunit
Settings.StyleCop
build.cmd
bdwgc
binary-reference-assemblies
bockbuild
boringssl
cecil
cecil-legacy
corefx
corert
helix-binaries
ikdasm
ikvm
illinker-test-assets
linker
llvm-project
nuget-buildtasks
nunit-lite
roslyn-binaries
rx
xunit-binaries
how-to-bump-roslyn-binaries.md
ikvm-native
llvm
m4
man
mcs
mono
msvc
netcore
po
runtime
samples
scripts
support
tools
COPYING.LIB
LICENSE
Makefile.am
Makefile.in
NEWS
README.md
acinclude.m4
aclocal.m4
autogen.sh
code_of_conduct.md
compile
config.guess
config.h.in
config.rpath
config.sub
configure.REMOVED.git-id
configure.ac.REMOVED.git-id
depcomp
install-sh
ltmain.sh.REMOVED.git-id
missing
mkinstalldirs
mono-uninstalled.pc.in
test-driver
winconfig.h
378 lines
15 KiB
C#
378 lines
15 KiB
C#
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
|
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Net.Http;
|
|
using System.Net.Http.Formatting;
|
|
using System.ServiceModel;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Xunit.Extensions;
|
|
using Assert = Microsoft.TestCommon.AssertEx;
|
|
|
|
namespace System.Web.Http.SelfHost
|
|
{
|
|
public class HttpSelfHostServerTest : IDisposable
|
|
{
|
|
private string machineName = Environment.MachineName;
|
|
private HttpSelfHostServer _bufferServer;
|
|
private HttpSelfHostServer _streamServer;
|
|
|
|
public HttpSelfHostServerTest()
|
|
{
|
|
SetupHosts();
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
CleanupHosts();
|
|
}
|
|
|
|
private void SetupHosts()
|
|
{
|
|
try
|
|
{
|
|
HttpSelfHostConfiguration config = new HttpSelfHostConfiguration(BaseUri(TransferMode.Buffered));
|
|
config.Routes.MapHttpRoute("Default", "{controller}/{action}");
|
|
_bufferServer = new HttpSelfHostServer(config);
|
|
SafeOpen(_bufferServer);
|
|
|
|
config = new HttpSelfHostConfiguration(BaseUri(TransferMode.Streamed));
|
|
config.Routes.MapHttpRoute("Default", "{controller}/{action}");
|
|
config.TransferMode = TransferMode.Streamed;
|
|
_streamServer = new HttpSelfHostServer(config);
|
|
SafeOpen(_streamServer);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
System.Diagnostics.Debug.WriteLine("HttpSelfHostServerTests.SetupHosts failed: " + ex.GetBaseException());
|
|
throw;
|
|
}
|
|
}
|
|
|
|
private void CleanupHosts()
|
|
{
|
|
SafeClose(_bufferServer);
|
|
SafeClose(_streamServer);
|
|
}
|
|
|
|
// HttpSelfHostServer has a small latency between CloseAsync.Wait
|
|
// completing and other async tasks still running. Theory driven
|
|
// tests run quickly enough they sometimes attempt to open when the
|
|
// prior test is still finishing those async tasks.
|
|
private static void SafeOpen(HttpSelfHostServer server)
|
|
{
|
|
for (int i = 0; i < 10; i++)
|
|
{
|
|
try
|
|
{
|
|
server.OpenAsync().Wait();
|
|
return;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
if (i == 9)
|
|
{
|
|
System.Diagnostics.Debug.WriteLine("HttpSelfHostServerTests.SafeOpen failed to open server at " + server.Configuration.VirtualPathRoot);
|
|
throw;
|
|
}
|
|
|
|
Thread.Sleep(200);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void SafeClose(HttpSelfHostServer server)
|
|
{
|
|
try
|
|
{
|
|
server.CloseAsync().Wait();
|
|
}
|
|
catch
|
|
{
|
|
System.Diagnostics.Debug.WriteLine("HttpSelfHostServerTests.SafeOpen failed to close server at " + server.Configuration.VirtualPathRoot);
|
|
}
|
|
}
|
|
|
|
private string BaseUri(TransferMode transferMode)
|
|
{
|
|
return transferMode == TransferMode.Streamed
|
|
? String.Format("http://{0}:8081/stream", machineName)
|
|
: String.Format("http://{0}:8081", machineName);
|
|
}
|
|
|
|
private HttpSelfHostServer GetServer(TransferMode transferMode)
|
|
{
|
|
return transferMode == TransferMode.Streamed
|
|
? _streamServer
|
|
: _bufferServer;
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("/SelfHostServerTest/EchoString", TransferMode.Buffered)]
|
|
[InlineData("/SelfHostServerTest/EchoString", TransferMode.Streamed)]
|
|
public void SendAsync_Direct_Returns_OK_For_Successful_ObjectContent_Write(string uri, TransferMode transferMode)
|
|
{
|
|
// Arrange & Act
|
|
HttpResponseMessage response = new HttpClient().GetAsync(BaseUri(transferMode) + uri).Result;
|
|
string responseString = response.Content.ReadAsStringAsync().Result;
|
|
|
|
// Assert
|
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
|
Assert.Equal("\"echoString\"", responseString);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("/SelfHostServerTest/EchoString", TransferMode.Buffered)]
|
|
[InlineData("/SelfHostServerTest/EchoString", TransferMode.Streamed)]
|
|
public void SendAsync_ServiceModel_Returns_OK_For_Successful_ObjectContent_Write(string uri, TransferMode transferMode)
|
|
{
|
|
// Arrange
|
|
bool shouldChunk = transferMode == TransferMode.Streamed;
|
|
|
|
// Act
|
|
HttpResponseMessage response = new HttpClient().GetAsync(BaseUri(transferMode) + uri).Result;
|
|
string responseString = response.Content.ReadAsStringAsync().Result;
|
|
IEnumerable<string> headerValues = null;
|
|
bool isChunked = response.Headers.TryGetValues("Transfer-Encoding", out headerValues) && headerValues != null &&
|
|
headerValues.Any((v) => String.Equals(v, "chunked", StringComparison.OrdinalIgnoreCase));
|
|
|
|
// Assert
|
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
|
Assert.Equal("\"echoString\"", responseString);
|
|
Assert.Equal(shouldChunk, isChunked);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("/SelfHostServerTest/EchoStream", TransferMode.Buffered)]
|
|
[InlineData("/SelfHostServerTest/EchoStream", TransferMode.Streamed)]
|
|
public void SendAsync_Direct_Returns_OK_For_Successful_Stream_Write(string uri, TransferMode transferMode)
|
|
{
|
|
// Arrange & Act
|
|
HttpResponseMessage response = new HttpClient(GetServer(transferMode)).GetAsync(BaseUri(transferMode) + uri).Result;
|
|
string responseString = response.Content.ReadAsStringAsync().Result;
|
|
IEnumerable<string> headerValues = null;
|
|
bool isChunked = response.Headers.TryGetValues("Transfer-Encoding", out headerValues) && headerValues != null &&
|
|
headerValues.Any((v) => String.Equals(v, "chunked", StringComparison.OrdinalIgnoreCase));
|
|
|
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
|
Assert.Equal("echoStream", responseString);
|
|
Assert.False(isChunked); // stream never chunk, buffered or streamed
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("/SelfHostServerTest/EchoStream", TransferMode.Buffered)]
|
|
[InlineData("/SelfHostServerTest/EchoStream", TransferMode.Streamed)]
|
|
public void SendAsync_ServiceModel_Returns_OK_For_Successful_Stream_Write(string uri, TransferMode transferMode)
|
|
{
|
|
// Arrange & Act
|
|
HttpResponseMessage response = new HttpClient().GetAsync(BaseUri(transferMode) + uri).Result;
|
|
string responseString = response.Content.ReadAsStringAsync().Result;
|
|
|
|
// Assert
|
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
|
Assert.Equal("echoStream", responseString);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("/SelfHostServerTest/ThrowBeforeTask", TransferMode.Buffered)]
|
|
[InlineData("/SelfHostServerTest/ThrowBeforeTask", TransferMode.Streamed)]
|
|
[InlineData("/SelfHostServerTest/ThrowBeforeWrite", TransferMode.Buffered)]
|
|
[InlineData("/SelfHostServerTest/ThrowBeforeWrite", TransferMode.Streamed)]
|
|
[InlineData("/SelfHostServerTest/ThrowAfterWrite", TransferMode.Buffered)]
|
|
[InlineData("/SelfHostServerTest/ThrowAfterWrite", TransferMode.Streamed)]
|
|
public void SendAsync_Direct_Throws_When_ObjectContent_CopyToAsync_Throws(string uri, TransferMode transferMode)
|
|
{
|
|
// Arrange & Act & Assert
|
|
Assert.Throws<InvalidOperationException>(
|
|
() => new HttpClient(GetServer(transferMode)).GetAsync(BaseUri(transferMode) + uri).Wait());
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("/SelfHostServerTest/ThrowBeforeTask", TransferMode.Buffered)]
|
|
[InlineData("/SelfHostServerTest/ThrowBeforeTask", TransferMode.Streamed)]
|
|
[InlineData("/SelfHostServerTest/ThrowBeforeWrite", TransferMode.Buffered)]
|
|
[InlineData("/SelfHostServerTest/ThrowBeforeWrite", TransferMode.Streamed)]
|
|
[InlineData("/SelfHostServerTest/ThrowAfterWrite", TransferMode.Buffered)]
|
|
[InlineData("/SelfHostServerTest/ThrowAfterWrite", TransferMode.Streamed)]
|
|
public void SendAsync_ServiceModel_Closes_Connection_When_ObjectContent_CopyToAsync_Throws(string uri, TransferMode transferMode)
|
|
{
|
|
// Arrange
|
|
Task<HttpResponseMessage> task = new HttpClient().GetAsync(BaseUri(transferMode) + uri);
|
|
|
|
// Act & Assert
|
|
Assert.Throws<HttpRequestException>(() => task.Wait());
|
|
}
|
|
|
|
[Theory(Skip = "This currently fails on CI machine only")]
|
|
[InlineData("/SelfHostServerTest/ThrowBeforeWriteStream", TransferMode.Buffered)]
|
|
[InlineData("/SelfHostServerTest/ThrowBeforeWriteStream", TransferMode.Streamed)]
|
|
[InlineData("/SelfHostServerTest/ThrowAfterWriteStream", TransferMode.Buffered)]
|
|
[InlineData("/SelfHostServerTest/ThrowAfterWriteStream", TransferMode.Streamed)]
|
|
public void SendAsync_Direct_Throws_When_StreamContent_Throws(string uri, TransferMode transferMode)
|
|
{
|
|
// Arrange & Act & Assert
|
|
Assert.Throws<InvalidOperationException>(
|
|
() => new HttpClient(GetServer(transferMode)).GetAsync(BaseUri(transferMode) + uri).Wait());
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("/SelfHostServerTest/ThrowBeforeWriteStream", TransferMode.Buffered)]
|
|
[InlineData("/SelfHostServerTest/ThrowBeforeWriteStream", TransferMode.Streamed)]
|
|
[InlineData("/SelfHostServerTest/ThrowAfterWriteStream", TransferMode.Buffered)]
|
|
[InlineData("/SelfHostServerTest/ThrowAfterWriteStream", TransferMode.Streamed)]
|
|
public void SendAsync_ServiceModel_Throws_When_StreamContent_Throws(string uri, TransferMode transferMode)
|
|
{
|
|
// Arrange
|
|
Task task = new HttpClient().GetAsync(BaseUri(transferMode) + uri);
|
|
|
|
// Act & Assert
|
|
Assert.Throws<HttpRequestException>(() => task.Wait());
|
|
}
|
|
|
|
internal class ThrowsBeforeTaskObjectContent : ObjectContent
|
|
{
|
|
public ThrowsBeforeTaskObjectContent() : base(typeof(string), "testContent", new JsonMediaTypeFormatter())
|
|
{
|
|
}
|
|
|
|
protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
|
|
{
|
|
throw new InvalidOperationException("ThrowBeforeTask");
|
|
}
|
|
}
|
|
|
|
internal class ThrowBeforeWriteObjectContent : ObjectContent
|
|
{
|
|
public ThrowBeforeWriteObjectContent()
|
|
: base(typeof(string), "testContent", new JsonMediaTypeFormatter())
|
|
{
|
|
}
|
|
|
|
protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
|
|
{
|
|
return Task.Factory.StartNew(() =>
|
|
{
|
|
throw new InvalidOperationException("ThrowBeforeWrite");
|
|
});
|
|
|
|
}
|
|
}
|
|
|
|
internal class ThrowAfterWriteObjectContent : ObjectContent
|
|
{
|
|
public ThrowAfterWriteObjectContent()
|
|
: base(typeof(string), "testContent", new JsonMediaTypeFormatter())
|
|
{
|
|
}
|
|
|
|
protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
|
|
{
|
|
return Task.Factory.StartNew(() =>
|
|
{
|
|
byte[] buffer =
|
|
Encoding.UTF8.GetBytes("ThrowAfterWrite");
|
|
stream.Write(buffer, 0, buffer.Length);
|
|
throw new InvalidOperationException("ThrowAfterWrite");
|
|
});
|
|
}
|
|
}
|
|
|
|
internal class ThrowBeforeWriteStream : StreamContent
|
|
{
|
|
public ThrowBeforeWriteStream() : base(new MemoryStream(Encoding.UTF8.GetBytes("ThrowBeforeWriteStream")))
|
|
{
|
|
}
|
|
|
|
protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
|
|
{
|
|
throw new InvalidOperationException("ThrowBeforeWriteStream");
|
|
}
|
|
}
|
|
|
|
internal class ThrowAfterWriteStream : StreamContent
|
|
{
|
|
public ThrowAfterWriteStream() : base(new MemoryStream(Encoding.UTF8.GetBytes("ThrowAfterWriteStream")))
|
|
{
|
|
}
|
|
|
|
protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
|
|
{
|
|
base.SerializeToStreamAsync(stream, context).Wait();
|
|
throw new InvalidOperationException("ThrowAfterWriteStream");
|
|
}
|
|
}
|
|
}
|
|
|
|
public class SelfHostServerTestController : ApiController
|
|
{
|
|
[HttpGet]
|
|
public string EchoString()
|
|
{
|
|
return "echoString";
|
|
}
|
|
|
|
[HttpGet]
|
|
public HttpResponseMessage EchoStream()
|
|
{
|
|
return new HttpResponseMessage(HttpStatusCode.OK)
|
|
{
|
|
Content = new StreamContent(new MemoryStream(Encoding.UTF8.GetBytes("echoStream")))
|
|
};
|
|
}
|
|
|
|
[HttpGet]
|
|
public HttpResponseMessage ThrowBeforeTask()
|
|
{
|
|
return new HttpResponseMessage(HttpStatusCode.OK)
|
|
{
|
|
RequestMessage = Request,
|
|
Content = new HttpSelfHostServerTest.ThrowsBeforeTaskObjectContent()
|
|
};
|
|
}
|
|
|
|
[HttpGet]
|
|
public HttpResponseMessage ThrowBeforeWrite()
|
|
{
|
|
return new HttpResponseMessage(HttpStatusCode.OK)
|
|
{
|
|
RequestMessage = Request,
|
|
Content = new HttpSelfHostServerTest.ThrowBeforeWriteObjectContent()
|
|
};
|
|
}
|
|
|
|
[HttpGet]
|
|
public HttpResponseMessage ThrowAfterWrite()
|
|
{
|
|
return new HttpResponseMessage(HttpStatusCode.OK)
|
|
{
|
|
RequestMessage = Request,
|
|
Content = new HttpSelfHostServerTest.ThrowAfterWriteObjectContent()
|
|
};
|
|
}
|
|
|
|
[HttpGet]
|
|
public HttpResponseMessage ThrowBeforeWriteStream()
|
|
{
|
|
return new HttpResponseMessage(HttpStatusCode.OK)
|
|
{
|
|
RequestMessage = Request,
|
|
Content = new HttpSelfHostServerTest.ThrowBeforeWriteStream()
|
|
};
|
|
}
|
|
|
|
[HttpGet]
|
|
public HttpResponseMessage ThrowAfterWriteStream()
|
|
{
|
|
return new HttpResponseMessage(HttpStatusCode.OK)
|
|
{
|
|
RequestMessage = Request,
|
|
Content = new HttpSelfHostServerTest.ThrowAfterWriteStream()
|
|
};
|
|
}
|
|
}
|
|
}
|