From e4071b9c6a5a4e5494f195942a9ad71b01f4ae99 Mon Sep 17 00:00:00 2001 From: Stef Heyenrath Date: Tue, 2 Feb 2021 22:21:30 +0100 Subject: [PATCH] Net5 issue (#579) * 472 * . * . * p * buffers * 3 * Fix date * fix --- WireMock.Net Solution.sln | 19 +- .../WireMock.Net.Console.NET5.csproj | 1 + .../MainApp.cs | 2 +- .../App.config | 54 +++ .../Properties/AssemblyInfo.cs | 36 ++ ...WireMock.Net.Console.Net472.Classic.csproj | 326 ++++++++++++++++ .../packages.config | 82 ++++ src/WireMock.Net/Http/HttpKnownHeaderNames.cs | 2 +- .../Owin/Mappers/OwinResponseMapper.cs | 357 +++++++++--------- .../Owin/Mappers/OwinResponseMapperTests.cs | 19 +- 10 files changed, 699 insertions(+), 199 deletions(-) create mode 100644 examples/WireMock.Net.Console.Net472.Classic/App.config create mode 100644 examples/WireMock.Net.Console.Net472.Classic/Properties/AssemblyInfo.cs create mode 100644 examples/WireMock.Net.Console.Net472.Classic/WireMock.Net.Console.Net472.Classic.csproj create mode 100644 examples/WireMock.Net.Console.Net472.Classic/packages.config diff --git a/WireMock.Net Solution.sln b/WireMock.Net Solution.sln index 0d20008cb..5e5ab3859 100644 --- a/WireMock.Net Solution.sln +++ b/WireMock.Net Solution.sln @@ -78,7 +78,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-WireMock", "src\dotn EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Console.NET5", "examples\WireMock.Net.Console.NET5\WireMock.Net.Console.NET5.csproj", "{3F8CF0AE-5F24-4A54-89E7-A3EE829DB5F8}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Matchers.CSharpCode", "src\WireMock.Net.Matchers.CSharpCode\WireMock.Net.Matchers.CSharpCode.csproj", "{6437CE56-8AB9-4D6D-90F1-70CC5BBE1572}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Matchers.CSharpCode", "src\WireMock.Net.Matchers.CSharpCode\WireMock.Net.Matchers.CSharpCode.csproj", "{B6269AAC-170A-4346-8B9A-444DED3D9A44}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Console.Net472.Classic", "examples\WireMock.Net.Console.Net472.Classic\WireMock.Net.Console.Net472.Classic.csproj", "{6580580B-1EFD-4922-B0EC-FF290DB279EE}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -194,10 +196,14 @@ Global {3F8CF0AE-5F24-4A54-89E7-A3EE829DB5F8}.Debug|Any CPU.Build.0 = Debug|Any CPU {3F8CF0AE-5F24-4A54-89E7-A3EE829DB5F8}.Release|Any CPU.ActiveCfg = Release|Any CPU {3F8CF0AE-5F24-4A54-89E7-A3EE829DB5F8}.Release|Any CPU.Build.0 = Release|Any CPU - {6437CE56-8AB9-4D6D-90F1-70CC5BBE1572}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6437CE56-8AB9-4D6D-90F1-70CC5BBE1572}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6437CE56-8AB9-4D6D-90F1-70CC5BBE1572}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6437CE56-8AB9-4D6D-90F1-70CC5BBE1572}.Release|Any CPU.Build.0 = Release|Any CPU + {B6269AAC-170A-4346-8B9A-444DED3D9A44}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B6269AAC-170A-4346-8B9A-444DED3D9A44}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B6269AAC-170A-4346-8B9A-444DED3D9A44}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B6269AAC-170A-4346-8B9A-444DED3D9A44}.Release|Any CPU.Build.0 = Release|Any CPU + {6580580B-1EFD-4922-B0EC-FF290DB279EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6580580B-1EFD-4922-B0EC-FF290DB279EE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6580580B-1EFD-4922-B0EC-FF290DB279EE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6580580B-1EFD-4922-B0EC-FF290DB279EE}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -230,7 +236,8 @@ Global {925E421A-1B3F-4202-B48F-734743573A4B} = {985E0ADB-D4B4-473A-AA40-567E279B7946} {40BF24B5-12E6-4610-9489-138798632E28} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2} {3F8CF0AE-5F24-4A54-89E7-A3EE829DB5F8} = {985E0ADB-D4B4-473A-AA40-567E279B7946} - {6437CE56-8AB9-4D6D-90F1-70CC5BBE1572} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2} + {B6269AAC-170A-4346-8B9A-444DED3D9A44} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2} + {6580580B-1EFD-4922-B0EC-FF290DB279EE} = {985E0ADB-D4B4-473A-AA40-567E279B7946} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {DC539027-9852-430C-B19F-FD035D018458} diff --git a/examples/WireMock.Net.Console.NET5/WireMock.Net.Console.NET5.csproj b/examples/WireMock.Net.Console.NET5/WireMock.Net.Console.NET5.csproj index 0e238f852..7c8899699 100644 --- a/examples/WireMock.Net.Console.NET5/WireMock.Net.Console.NET5.csproj +++ b/examples/WireMock.Net.Console.NET5/WireMock.Net.Console.NET5.csproj @@ -30,6 +30,7 @@ + diff --git a/examples/WireMock.Net.Console.Net452.Classic/MainApp.cs b/examples/WireMock.Net.Console.Net452.Classic/MainApp.cs index 9d8d3d2ee..8a9342ef3 100644 --- a/examples/WireMock.Net.Console.Net452.Classic/MainApp.cs +++ b/examples/WireMock.Net.Console.Net452.Classic/MainApp.cs @@ -280,7 +280,7 @@ public static void Run() .WithBody("hi")); server - .Given(Request.Create().WithPath("/data").UsingPost().WithBody(b => b.Contains("e"))) + .Given(Request.Create().WithPath("/data").UsingPost().WithBody(b => b != null && b.Contains("e"))) .AtPriority(999) .RespondWith(Response.Create() .WithStatusCode(201) diff --git a/examples/WireMock.Net.Console.Net472.Classic/App.config b/examples/WireMock.Net.Console.Net472.Classic/App.config new file mode 100644 index 000000000..773045f8d --- /dev/null +++ b/examples/WireMock.Net.Console.Net472.Classic/App.config @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/WireMock.Net.Console.Net472.Classic/Properties/AssemblyInfo.cs b/examples/WireMock.Net.Console.Net472.Classic/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..a10ce6d38 --- /dev/null +++ b/examples/WireMock.Net.Console.Net472.Classic/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("WireMock.Net.Console.Net461.Classic")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("WireMock.Net.Console.Net461.Classic")] +[assembly: AssemblyCopyright("Copyright © Stef Heyenrath 2018")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("1261bb9b-a7d4-456c-8985-3ce560361b8e")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/examples/WireMock.Net.Console.Net472.Classic/WireMock.Net.Console.Net472.Classic.csproj b/examples/WireMock.Net.Console.Net472.Classic/WireMock.Net.Console.Net472.Classic.csproj new file mode 100644 index 000000000..6b236af8a --- /dev/null +++ b/examples/WireMock.Net.Console.Net472.Classic/WireMock.Net.Console.Net472.Classic.csproj @@ -0,0 +1,326 @@ + + + + + + Debug + AnyCPU + {6580580B-1EFD-4922-B0EC-FF290DB279EE} + Exe + WireMock.Net.Console.Net461.Classic + WireMock.Net.Console.Net461.Classic + v4.7.2 + 512 + true + + + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + WireMock.Net.ConsoleApplication.Program + + + + ..\..\packages\Fare.2.1.1\lib\net35\Fare.dll + + + ..\..\packages\Handlebars.Net.1.9.5\lib\net452\Handlebars.dll + + + ..\..\packages\Handlebars.Net.Helpers.1.1.0\lib\net452\Handlebars.Net.Helpers.dll + + + ..\..\packages\JmesPath.Net.1.0.125\lib\net45\JmesPath.Net.dll + + + ..\..\packages\log4net.2.0.12\lib\net45\log4net.dll + + + ..\..\packages\Microsoft.AspNetCore.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.dll + + + ..\..\packages\Microsoft.AspNetCore.Authentication.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Authentication.Abstractions.dll + + + ..\..\packages\Microsoft.AspNetCore.Authentication.Core.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Authentication.Core.dll + + + ..\..\packages\Microsoft.AspNetCore.Connections.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Connections.Abstractions.dll + + + ..\..\packages\Microsoft.AspNetCore.Diagnostics.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Diagnostics.dll + + + ..\..\packages\Microsoft.AspNetCore.Diagnostics.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Diagnostics.Abstractions.dll + + + ..\..\packages\Microsoft.AspNetCore.HostFiltering.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.HostFiltering.dll + + + ..\..\packages\Microsoft.AspNetCore.Hosting.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Hosting.dll + + + ..\..\packages\Microsoft.AspNetCore.Hosting.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Hosting.Abstractions.dll + + + ..\..\packages\Microsoft.AspNetCore.Hosting.Server.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Hosting.Server.Abstractions.dll + + + ..\..\packages\Microsoft.AspNetCore.Http.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Http.dll + + + ..\..\packages\Microsoft.AspNetCore.Http.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Http.Abstractions.dll + + + ..\..\packages\Microsoft.AspNetCore.Http.Extensions.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Http.Extensions.dll + + + ..\..\packages\Microsoft.AspNetCore.Http.Features.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Http.Features.dll + + + ..\..\packages\Microsoft.AspNetCore.HttpOverrides.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.HttpOverrides.dll + + + ..\..\packages\Microsoft.AspNetCore.Routing.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Routing.dll + + + ..\..\packages\Microsoft.AspNetCore.Routing.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Routing.Abstractions.dll + + + ..\..\packages\Microsoft.AspNetCore.Server.IIS.2.2.6\lib\netstandard2.0\Microsoft.AspNetCore.Server.IIS.dll + + + ..\..\packages\Microsoft.AspNetCore.Server.IISIntegration.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Server.IISIntegration.dll + + + ..\..\packages\Microsoft.AspNetCore.Server.Kestrel.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Server.Kestrel.dll + + + ..\..\packages\Microsoft.AspNetCore.Server.Kestrel.Core.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Server.Kestrel.Core.dll + + + ..\..\packages\Microsoft.AspNetCore.Server.Kestrel.Https.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Server.Kestrel.Https.dll + + + ..\..\packages\Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.dll + + + ..\..\packages\Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.dll + + + ..\..\packages\Microsoft.AspNetCore.WebUtilities.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.WebUtilities.dll + + + ..\..\packages\Microsoft.Extensions.Configuration.5.0.0\lib\net461\Microsoft.Extensions.Configuration.dll + + + ..\..\packages\Microsoft.Extensions.Configuration.Abstractions.5.0.0\lib\net461\Microsoft.Extensions.Configuration.Abstractions.dll + + + ..\..\packages\Microsoft.Extensions.Configuration.Binder.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Configuration.Binder.dll + + + ..\..\packages\Microsoft.Extensions.Configuration.CommandLine.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Configuration.CommandLine.dll + + + ..\..\packages\Microsoft.Extensions.Configuration.EnvironmentVariables.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Configuration.EnvironmentVariables.dll + + + ..\..\packages\Microsoft.Extensions.Configuration.FileExtensions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Configuration.FileExtensions.dll + + + ..\..\packages\Microsoft.Extensions.Configuration.Json.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Configuration.Json.dll + + + ..\..\packages\Microsoft.Extensions.Configuration.UserSecrets.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Configuration.UserSecrets.dll + + + ..\..\packages\Microsoft.Extensions.DependencyInjection.2.2.0\lib\net461\Microsoft.Extensions.DependencyInjection.dll + + + ..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll + + + ..\..\packages\Microsoft.Extensions.FileProviders.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.FileProviders.Abstractions.dll + + + ..\..\packages\Microsoft.Extensions.FileProviders.Physical.2.2.0\lib\netstandard2.0\Microsoft.Extensions.FileProviders.Physical.dll + + + ..\..\packages\Microsoft.Extensions.FileSystemGlobbing.2.2.0\lib\netstandard2.0\Microsoft.Extensions.FileSystemGlobbing.dll + + + ..\..\packages\Microsoft.Extensions.Hosting.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Hosting.Abstractions.dll + + + ..\..\packages\Microsoft.Extensions.Logging.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Logging.dll + + + ..\..\packages\Microsoft.Extensions.Logging.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll + + + ..\..\packages\Microsoft.Extensions.Logging.Configuration.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Logging.Configuration.dll + + + ..\..\packages\Microsoft.Extensions.Logging.Console.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Logging.Console.dll + + + ..\..\packages\Microsoft.Extensions.Logging.Debug.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Logging.Debug.dll + + + ..\..\packages\Microsoft.Extensions.Logging.EventSource.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Logging.EventSource.dll + + + ..\..\packages\Microsoft.Extensions.ObjectPool.2.2.0\lib\netstandard2.0\Microsoft.Extensions.ObjectPool.dll + + + ..\..\packages\Microsoft.Extensions.Options.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Options.dll + + + ..\..\packages\Microsoft.Extensions.Options.ConfigurationExtensions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.Options.ConfigurationExtensions.dll + + + ..\..\packages\Microsoft.Extensions.Primitives.5.0.0\lib\net461\Microsoft.Extensions.Primitives.dll + + + ..\..\packages\Microsoft.Net.Http.Headers.2.2.0\lib\netstandard2.0\Microsoft.Net.Http.Headers.dll + + + ..\..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll + + + ..\..\packages\RandomDataGenerator.Net.1.0.12\lib\net45\RandomDataGenerator.dll + + + ..\..\packages\Scriban.Signed.2.1.4\lib\net45\Scriban.Signed.dll + + + ..\..\packages\SimMetrics.Net.1.0.5\lib\net45\SimMetrics.Net.dll + + + + ..\..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + ..\..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll + + + ..\..\packages\System.ComponentModel.Annotations.4.5.0\lib\net461\System.ComponentModel.Annotations.dll + + + + + + ..\..\packages\System.Diagnostics.DiagnosticSource.4.5.0\lib\net46\System.Diagnostics.DiagnosticSource.dll + + + ..\..\packages\System.IO.Pipelines.4.5.3\lib\netstandard2.0\System.IO.Pipelines.dll + + + ..\..\packages\System.Linq.Dynamic.Core.1.0.12\lib\net46\System.Linq.Dynamic.Core.dll + + + ..\..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll + + + + + ..\..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\..\packages\System.Reflection.Metadata.1.6.0\lib\netstandard2.0\System.Reflection.Metadata.dll + + + ..\..\packages\System.Runtime.CompilerServices.Unsafe.5.0.0\lib\net45\System.Runtime.CompilerServices.Unsafe.dll + + + ..\..\packages\System.Security.Cryptography.Cng.4.5.0\lib\net47\System.Security.Cryptography.Cng.dll + + + ..\..\packages\System.Security.Principal.Windows.4.5.0\lib\net461\System.Security.Principal.Windows.dll + + + ..\..\packages\System.Text.Encodings.Web.4.5.0\lib\netstandard2.0\System.Text.Encodings.Web.dll + + + ..\..\packages\System.Threading.Tasks.Extensions.4.5.1\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll + + + ..\..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll + + + + + + + + + + ..\..\packages\XPath2.1.1.0\lib\net40\XPath2.dll + + + ..\..\packages\XPath2.Extensions.1.1.0\lib\net40\XPath2.Extensions.dll + + + + + CustomFileSystemFileHandler.cs + + + MainApp.cs + + + Program.cs + + + + + + log4net.config + + + + + + + {b6269aac-170a-4346-8b9a-579ded3d9a94} + WireMock.Net.Abstractions + + + {d3804228-91f4-4502-9595-39584e5a01ad} + WireMock.Net + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + \ No newline at end of file diff --git a/examples/WireMock.Net.Console.Net472.Classic/packages.config b/examples/WireMock.Net.Console.Net472.Classic/packages.config new file mode 100644 index 000000000..c57d5f8b4 --- /dev/null +++ b/examples/WireMock.Net.Console.Net472.Classic/packages.config @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/WireMock.Net/Http/HttpKnownHeaderNames.cs b/src/WireMock.Net/Http/HttpKnownHeaderNames.cs index 857e1e7eb..07c2975bb 100644 --- a/src/WireMock.Net/Http/HttpKnownHeaderNames.cs +++ b/src/WireMock.Net/Http/HttpKnownHeaderNames.cs @@ -19,7 +19,7 @@ internal static class HttpKnownHeaderNames Connection, ContentLength, ContentType, - Date, + Date, // RFC1123Pattern Expect, Host, IfModifiedSince, diff --git a/src/WireMock.Net/Owin/Mappers/OwinResponseMapper.cs b/src/WireMock.Net/Owin/Mappers/OwinResponseMapper.cs index a70cd51ee..168647019 100644 --- a/src/WireMock.Net/Owin/Mappers/OwinResponseMapper.cs +++ b/src/WireMock.Net/Owin/Mappers/OwinResponseMapper.cs @@ -1,177 +1,188 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Net; using System.Reflection; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; -using RandomDataGenerator.FieldOptions; -using RandomDataGenerator.Randomizers; -using WireMock.Http; -using WireMock.ResponseBuilders; -using WireMock.Types; -using WireMock.Validation; -#if !USE_ASPNETCORE -using IResponse = Microsoft.Owin.IOwinResponse; -#else -using Microsoft.AspNetCore.Http; -using IResponse = Microsoft.AspNetCore.Http.HttpResponse; -#endif - -namespace WireMock.Owin.Mappers -{ - /// - /// OwinResponseMapper - /// - internal class OwinResponseMapper : IOwinResponseMapper - { - private readonly IRandomizerNumber _randomizerDouble = RandomizerFactory.GetRandomizer(new FieldOptionsDouble { Min = 0, Max = 1 }); - private readonly IRandomizerBytes _randomizerBytes = RandomizerFactory.GetRandomizer(new FieldOptionsBytes { Min = 100, Max = 200 }); - private readonly IWireMockMiddlewareOptions _options; - private readonly Encoding _utf8NoBom = new UTF8Encoding(false); - - // https://msdn.microsoft.com/en-us/library/78h415ay(v=vs.110).aspx -#if !USE_ASPNETCORE - private static readonly IDictionary>> ResponseHeadersToFix = new Dictionary>>(StringComparer.OrdinalIgnoreCase) { -#else - private static readonly IDictionary>> ResponseHeadersToFix = new Dictionary>>(StringComparer.OrdinalIgnoreCase) { -#endif - { HttpKnownHeaderNames.ContentType, (r, v) => r.ContentType = v.FirstOrDefault() } - }; - - /// - /// Constructor - /// - /// The IWireMockMiddlewareOptions. - public OwinResponseMapper(IWireMockMiddlewareOptions options) - { - Check.NotNull(options, nameof(options)); - - _options = options; - } - - /// - public async Task MapAsync(ResponseMessage responseMessage, IResponse response) - { - if (responseMessage == null) - { - return; - } - - byte[] bytes; - switch (responseMessage.FaultType) - { - case FaultType.EMPTY_RESPONSE: - bytes = IsFault(responseMessage) ? new byte[0] : GetNormalBody(responseMessage); - break; - - case FaultType.MALFORMED_RESPONSE_CHUNK: - bytes = GetNormalBody(responseMessage) ?? new byte[0]; - if (IsFault(responseMessage)) - { - bytes = bytes.Take(bytes.Length / 2).Union(_randomizerBytes.Generate()).ToArray(); - } - - break; - - default: - bytes = GetNormalBody(responseMessage); - break; - } - - var statusCodeType = responseMessage.StatusCode?.GetType(); - - switch (statusCodeType) - { - case Type typeAsIntOrEnum when typeAsIntOrEnum == typeof(int) || typeAsIntOrEnum == typeof(int?) || typeAsIntOrEnum.GetTypeInfo().IsEnum: - response.StatusCode = MapStatusCode((int)responseMessage.StatusCode); +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json; +using RandomDataGenerator.FieldOptions; +using RandomDataGenerator.Randomizers; +using WireMock.Http; +using WireMock.ResponseBuilders; +using WireMock.Types; +using WireMock.Validation; +#if !USE_ASPNETCORE +using IResponse = Microsoft.Owin.IOwinResponse; +#else +using Microsoft.AspNetCore.Http; +using IResponse = Microsoft.AspNetCore.Http.HttpResponse; +#endif + +namespace WireMock.Owin.Mappers +{ + /// + /// OwinResponseMapper + /// + internal class OwinResponseMapper : IOwinResponseMapper + { + private readonly IRandomizerNumber _randomizerDouble = RandomizerFactory.GetRandomizer(new FieldOptionsDouble { Min = 0, Max = 1 }); + private readonly IRandomizerBytes _randomizerBytes = RandomizerFactory.GetRandomizer(new FieldOptionsBytes { Min = 100, Max = 200 }); + private readonly IWireMockMiddlewareOptions _options; + private readonly Encoding _utf8NoBom = new UTF8Encoding(false); + + // https://msdn.microsoft.com/en-us/library/78h415ay(v=vs.110).aspx +#if !USE_ASPNETCORE + private static readonly IDictionary>> ResponseHeadersToFix = new Dictionary>>(StringComparer.OrdinalIgnoreCase) { +#else + private static readonly IDictionary>> ResponseHeadersToFix = new Dictionary>>(StringComparer.OrdinalIgnoreCase) { +#endif + { HttpKnownHeaderNames.ContentType, (r, v) => r.ContentType = v.FirstOrDefault() } + }; + + /// + /// Constructor + /// + /// The IWireMockMiddlewareOptions. + public OwinResponseMapper(IWireMockMiddlewareOptions options) + { + Check.NotNull(options, nameof(options)); + + _options = options; + } + + /// + public async Task MapAsync(ResponseMessage responseMessage, IResponse response) + { + if (responseMessage == null) + { + return; + } + + byte[] bytes; + switch (responseMessage.FaultType) + { + case FaultType.EMPTY_RESPONSE: + bytes = IsFault(responseMessage) ? new byte[0] : GetNormalBody(responseMessage); + break; + + case FaultType.MALFORMED_RESPONSE_CHUNK: + bytes = GetNormalBody(responseMessage) ?? new byte[0]; + if (IsFault(responseMessage)) + { + bytes = bytes.Take(bytes.Length / 2).Union(_randomizerBytes.Generate()).ToArray(); + } + + break; + + default: + bytes = GetNormalBody(responseMessage); + break; + } + + var statusCodeType = responseMessage.StatusCode?.GetType(); + + switch (statusCodeType) + { + case Type typeAsIntOrEnum when typeAsIntOrEnum == typeof(int) || typeAsIntOrEnum == typeof(int?) || typeAsIntOrEnum.GetTypeInfo().IsEnum: + response.StatusCode = MapStatusCode((int)responseMessage.StatusCode); + break; + + case Type typeAsString when typeAsString == typeof(string): + // Note: this case will also match on null + int.TryParse(responseMessage.StatusCode as string, out int result); + response.StatusCode = MapStatusCode(result); + break; + + default: break; + } + + SetResponseHeaders(responseMessage, response); + + if (bytes != null) + { + await response.Body.WriteAsync(bytes, 0, bytes.Length); + } + } + + private int MapStatusCode(int code) + { + if (_options.AllowOnlyDefinedHttpStatusCodeInResponse == true && !Enum.IsDefined(typeof(HttpStatusCode), code)) + { + return (int)HttpStatusCode.OK; + } + + return code; + } + + private bool IsFault(ResponseMessage responseMessage) + { + return responseMessage.FaultPercentage == null || _randomizerDouble.Generate() <= responseMessage.FaultPercentage; + } + + private byte[] GetNormalBody(ResponseMessage responseMessage) + { + byte[] bytes = null; + switch (responseMessage.BodyData?.DetectedBodyType) + { + case BodyType.String: + bytes = (responseMessage.BodyData.Encoding ?? _utf8NoBom).GetBytes(responseMessage.BodyData.BodyAsString); + break; + + case BodyType.Json: + Formatting formatting = responseMessage.BodyData.BodyAsJsonIndented == true + ? Formatting.Indented + : Formatting.None; + string jsonBody = JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson, new JsonSerializerSettings { Formatting = formatting, NullValueHandling = NullValueHandling.Ignore }); + bytes = (responseMessage.BodyData.Encoding ?? _utf8NoBom).GetBytes(jsonBody); + break; + + case BodyType.Bytes: + bytes = responseMessage.BodyData.BodyAsBytes; + break; + + case BodyType.File: + bytes = _options.FileSystemHandler.ReadResponseBodyAsFile(responseMessage.BodyData.BodyAsFile); + break; + } + + return bytes; + } + + private static void SetResponseHeaders(ResponseMessage responseMessage, IResponse response) + { + // Force setting the Date header (#577) + AppendResponseHeader(response, HttpKnownHeaderNames.Date, new[] { string.Format(CultureInfo.InvariantCulture.DateTimeFormat.RFC1123Pattern, CultureInfo.InvariantCulture.DateTimeFormat.RFC1123Pattern, DateTime.Now) }); + + // Set other headers + foreach (var item in responseMessage.Headers) + { + var headerName = item.Key; + var value = item.Value; + if (ResponseHeadersToFix.ContainsKey(headerName)) + { + ResponseHeadersToFix[headerName]?.Invoke(response, value); + } + else + { + // Check if this response header can be added (#148 and #227) + if (!HttpKnownHeaderNames.IsRestrictedResponseHeader(headerName)) + { + AppendResponseHeader(response, headerName, value.ToArray()); + } + } + } + } - case Type typeAsString when typeAsString == typeof(string): - // Note: this case will also match on null - int.TryParse(responseMessage.StatusCode as string, out int result); - response.StatusCode = MapStatusCode(result); - break; - - default: - break; - } - - SetResponseHeaders(responseMessage, response); - - if (bytes != null) - { - await response.Body.WriteAsync(bytes, 0, bytes.Length); - } - } - - private int MapStatusCode(int code) - { - if (_options.AllowOnlyDefinedHttpStatusCodeInResponse == true && !Enum.IsDefined(typeof(HttpStatusCode), code)) - { - return (int)HttpStatusCode.OK; - } - - return code; - } - - private bool IsFault(ResponseMessage responseMessage) - { - return responseMessage.FaultPercentage == null || _randomizerDouble.Generate() <= responseMessage.FaultPercentage; - } - - private byte[] GetNormalBody(ResponseMessage responseMessage) - { - byte[] bytes = null; - switch (responseMessage.BodyData?.DetectedBodyType) - { - case BodyType.String: - bytes = (responseMessage.BodyData.Encoding ?? _utf8NoBom).GetBytes(responseMessage.BodyData.BodyAsString); - break; - - case BodyType.Json: - Formatting formatting = responseMessage.BodyData.BodyAsJsonIndented == true - ? Formatting.Indented - : Formatting.None; - string jsonBody = JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson, new JsonSerializerSettings { Formatting = formatting, NullValueHandling = NullValueHandling.Ignore }); - bytes = (responseMessage.BodyData.Encoding ?? _utf8NoBom).GetBytes(jsonBody); - break; - - case BodyType.Bytes: - bytes = responseMessage.BodyData.BodyAsBytes; - break; - - case BodyType.File: - bytes = _options.FileSystemHandler.ReadResponseBodyAsFile(responseMessage.BodyData.BodyAsFile); - break; - } - - return bytes; - } - - private void SetResponseHeaders(ResponseMessage responseMessage, IResponse response) - { - // Set headers - foreach (var pair in responseMessage.Headers) - { - if (ResponseHeadersToFix.ContainsKey(pair.Key)) - { - ResponseHeadersToFix[pair.Key]?.Invoke(response, pair.Value); - } - else - { - // Check if this response header can be added (#148 and #227) - if (!HttpKnownHeaderNames.IsRestrictedResponseHeader(pair.Key)) - { -#if !USE_ASPNETCORE - response.Headers.AppendValues(pair.Key, pair.Value.ToArray()); -#else - response.Headers.Append(pair.Key, pair.Value.ToArray()); -#endif - } - } - } - } - } + private static void AppendResponseHeader(IResponse response, string headerName, string[] values) + { +#if !USE_ASPNETCORE + response.Headers.AppendValues(headerName, values); +#else + response.Headers.Append(headerName, values); +#endif + } + } } \ No newline at end of file diff --git a/test/WireMock.Net.Tests/Owin/Mappers/OwinResponseMapperTests.cs b/test/WireMock.Net.Tests/Owin/Mappers/OwinResponseMapperTests.cs index caf662c96..b0c4b187a 100644 --- a/test/WireMock.Net.Tests/Owin/Mappers/OwinResponseMapperTests.cs +++ b/test/WireMock.Net.Tests/Owin/Mappers/OwinResponseMapperTests.cs @@ -108,23 +108,6 @@ public async Task OwinResponseMapper_MapAsync_Invalid_StatusCode_When_AllowOnlyD _responseMock.VerifySet(r => r.StatusCode = expected, Times.Once); } - [Fact] - public async Task OwinResponseMapper_MapAsync_Null_StatusCode_When_AllowOnlyDefinedHttpStatusCodeInResponseSet_Is_True() - { - // Arrange - _optionsMock.SetupGet(o => o.AllowOnlyDefinedHttpStatusCodeInResponse).Returns(true); - var responseMessage = new ResponseMessage - { - StatusCode = null - }; - - // Act - await _sut.MapAsync(responseMessage, _responseMock.Object); - - // Assert - _responseMock.VerifyNoOtherCalls(); - } - [Fact] public async Task OwinResponseMapper_MapAsync_StatusCode_Is_Null() { @@ -138,7 +121,7 @@ public async Task OwinResponseMapper_MapAsync_StatusCode_Is_Null() await _sut.MapAsync(responseMessage, _responseMock.Object); // Assert - _responseMock.VerifyNoOtherCalls(); + _responseMock.VerifySet(r => r.StatusCode = It.IsAny(), Times.Never); } [Theory]