diff --git a/src/Ocelot/Configuration/Creator/VersionCreator.cs b/src/Ocelot/Configuration/Creator/HttpVersionCreator.cs similarity index 86% rename from src/Ocelot/Configuration/Creator/VersionCreator.cs rename to src/Ocelot/Configuration/Creator/HttpVersionCreator.cs index b6fb3ad1..f80f98ff 100644 --- a/src/Ocelot/Configuration/Creator/VersionCreator.cs +++ b/src/Ocelot/Configuration/Creator/HttpVersionCreator.cs @@ -2,7 +2,7 @@ { using System; - public class VersionCreator : IVersionCreator + public class HttpVersionCreator : IVersionCreator { public Version Create(string downstreamHttpVersion) { diff --git a/src/Ocelot/DependencyInjection/OcelotBuilder.cs b/src/Ocelot/DependencyInjection/OcelotBuilder.cs index 2f1444f6..0336f691 100644 --- a/src/Ocelot/DependencyInjection/OcelotBuilder.cs +++ b/src/Ocelot/DependencyInjection/OcelotBuilder.cs @@ -136,7 +136,7 @@ namespace Ocelot.DependencyInjection Services.TryAddSingleton(); Services.TryAddSingleton(); Services.TryAddSingleton(); - Services.TryAddSingleton(); + Services.TryAddSingleton(); //add security this.AddSecurity(); diff --git a/test/Ocelot.AcceptanceTests/HttpTests.cs b/test/Ocelot.AcceptanceTests/HttpTests.cs new file mode 100644 index 00000000..89ab12f4 --- /dev/null +++ b/test/Ocelot.AcceptanceTests/HttpTests.cs @@ -0,0 +1,205 @@ +namespace Ocelot.AcceptanceTests +{ + using Microsoft.AspNetCore.Http; + using Ocelot.Configuration.File; + using System; + using System.Collections.Generic; + using System.IO; + using System.Net; + using System.Net.Http; + using Microsoft.AspNetCore.Server.Kestrel.Core; + using TestStack.BDDfy; + using Xunit; + + public class HttpTests : IDisposable + { + private readonly Steps _steps; + private readonly ServiceHandler _serviceHandler; + + public HttpTests() + { + _serviceHandler = new ServiceHandler(); + _steps = new Steps(); + } + + [Fact] + public void should_return_response_200_when_using_http_one_point_one() + { + const int port = 53279; + + var configuration = new FileConfiguration + { + ReRoutes = new List + { + new FileReRoute + { + DownstreamPathTemplate = "/{url}", + DownstreamScheme = "https", + UpstreamPathTemplate = "/{url}", + UpstreamHttpMethod = new List { "Get" }, + DownstreamHostAndPorts = new List + { + new FileHostAndPort + { + Host = "localhost", + Port = port, + }, + }, + DownstreamHttpMethod = "POST", + DownstreamHttpVersion = "1.1", + DangerousAcceptAnyServerCertificateValidator = true + }, + }, + }; + + this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}/", "/", port, HttpProtocols.Http1)) + .And(x => _steps.GivenThereIsAConfiguration(configuration)) + .And(x => _steps.GivenOcelotIsRunning()) + .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) + .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK)) + .BDDfy(); + } + + [Fact] + public void should_return_response_200_when_using_http_two_point_zero() + { + const int port = 53675; + + var configuration = new FileConfiguration + { + ReRoutes = new List + { + new FileReRoute + { + DownstreamPathTemplate = "/{url}", + DownstreamScheme = "https", + UpstreamPathTemplate = "/{url}", + UpstreamHttpMethod = new List { "Get" }, + DownstreamHostAndPorts = new List + { + new FileHostAndPort + { + Host = "localhost", + Port = port, + }, + }, + DownstreamHttpMethod = "POST", + DownstreamHttpVersion = "2.0", + DangerousAcceptAnyServerCertificateValidator = true + }, + }, + }; + + const string expected = "here is some content"; + var httpContent = new StringContent(expected); + + this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}/", "/", port, HttpProtocols.Http2)) + .And(x => _steps.GivenThereIsAConfiguration(configuration)) + .And(x => _steps.GivenOcelotIsRunning()) + .When(x => _steps.WhenIGetUrlOnTheApiGateway("/", httpContent)) + .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK)) + .And(_ => _steps.ThenTheResponseBodyShouldBe(expected)) + .BDDfy(); + } + + [Fact] + public void should_return_response_500_when_using_http_one_to_talk_to_server_running_http_two() + { + const int port = 53677; + + var configuration = new FileConfiguration + { + ReRoutes = new List + { + new FileReRoute + { + DownstreamPathTemplate = "/{url}", + DownstreamScheme = "https", + UpstreamPathTemplate = "/{url}", + UpstreamHttpMethod = new List { "Get" }, + DownstreamHostAndPorts = new List + { + new FileHostAndPort + { + Host = "localhost", + Port = port, + }, + }, + DownstreamHttpMethod = "POST", + DownstreamHttpVersion = "1.1", + DangerousAcceptAnyServerCertificateValidator = true + }, + }, + }; + + const string expected = "here is some content"; + var httpContent = new StringContent(expected); + + this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}/", "/", port, HttpProtocols.Http2)) + .And(x => _steps.GivenThereIsAConfiguration(configuration)) + .And(x => _steps.GivenOcelotIsRunning()) + .When(x => _steps.WhenIGetUrlOnTheApiGateway("/", httpContent)) + .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.InternalServerError)) + .BDDfy(); + } + + [Fact] + public void should_return_response_200_when_using_http_two_to_talk_to_server_running_http_one_point_one() + { + const int port = 53679; + + var configuration = new FileConfiguration + { + ReRoutes = new List + { + new FileReRoute + { + DownstreamPathTemplate = "/{url}", + DownstreamScheme = "https", + UpstreamPathTemplate = "/{url}", + UpstreamHttpMethod = new List { "Get" }, + DownstreamHostAndPorts = new List + { + new FileHostAndPort + { + Host = "localhost", + Port = port, + }, + }, + DownstreamHttpMethod = "POST", + DownstreamHttpVersion = "2.0", + DangerousAcceptAnyServerCertificateValidator = true + }, + }, + }; + + const string expected = "here is some content"; + var httpContent = new StringContent(expected); + + this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}/", "/", port, HttpProtocols.Http1)) + .And(x => _steps.GivenThereIsAConfiguration(configuration)) + .And(x => _steps.GivenOcelotIsRunning()) + .When(x => _steps.WhenIGetUrlOnTheApiGateway("/", httpContent)) + .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK)) + .And(_ => _steps.ThenTheResponseBodyShouldBe(expected)) + .BDDfy(); + } + + private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int port, HttpProtocols protocols) + { + _serviceHandler.GivenThereIsAServiceRunningOn(baseUrl, basePath, async context => + { + context.Response.StatusCode = 200; + var reader = new StreamReader(context.Request.Body); + var body = await reader.ReadToEndAsync(); + await context.Response.WriteAsync(body); + }, port, protocols); + } + + public void Dispose() + { + _serviceHandler.Dispose(); + _steps.Dispose(); + } + } +} diff --git a/test/Ocelot.AcceptanceTests/ServiceHandler.cs b/test/Ocelot.AcceptanceTests/ServiceHandler.cs index c10c122b..9fc8b0f5 100644 --- a/test/Ocelot.AcceptanceTests/ServiceHandler.cs +++ b/test/Ocelot.AcceptanceTests/ServiceHandler.cs @@ -6,9 +6,11 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using System; + using System.ComponentModel; using System.IO; using System.Net; using System.Threading.Tasks; + using Microsoft.AspNetCore.Server.Kestrel.Core; public class ServiceHandler : IDisposable { @@ -47,6 +49,31 @@ _builder.Start(); } + public void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, RequestDelegate del, int port, HttpProtocols protocols) + { + _builder = new WebHostBuilder() + .UseUrls(baseUrl) + .UseKestrel() + .ConfigureKestrel(serverOptions => + { + serverOptions.Listen(IPAddress.Loopback, port, listenOptions => + { + listenOptions.UseHttps("idsrv3test.pfx", "idsrv3test"); + listenOptions.Protocols = protocols; + }); + }) + .UseContentRoot(Directory.GetCurrentDirectory()) + .UseIISIntegration() + .Configure(app => + { + app.UsePathBase(basePath); + app.Run(del); + }) + .Build(); + + _builder.Start(); + } + public void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, string fileName, string password, int port, RequestDelegate del) { _builder = new WebHostBuilder() diff --git a/test/Ocelot.UnitTests/Configuration/VersionCreatorTests.cs b/test/Ocelot.UnitTests/Configuration/VersionCreatorTests.cs index f5119ec8..bb440c5c 100644 --- a/test/Ocelot.UnitTests/Configuration/VersionCreatorTests.cs +++ b/test/Ocelot.UnitTests/Configuration/VersionCreatorTests.cs @@ -8,13 +8,13 @@ public class VersionCreatorTests { - private readonly VersionCreator _creator; + private readonly HttpVersionCreator _creator; private string _input; private Version _result; public VersionCreatorTests() { - _creator = new VersionCreator(); + _creator = new HttpVersionCreator(); } [Fact]