mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-10-31 16:25:27 +08:00 
			
		
		
		
	everything working..now for the docs
This commit is contained in:
		
							
								
								
									
										100
									
								
								build.cake
									
									
									
									
									
								
							
							
						
						
									
										100
									
								
								build.cake
									
									
									
									
									
								
							| @@ -1,6 +1,7 @@ | ||||
| #tool "nuget:?package=GitVersion.CommandLine" | ||||
| #tool "nuget:?package=GitReleaseNotes" | ||||
| #addin "nuget:?package=Cake.Json" | ||||
| #addin nuget:?package=Cake.Json | ||||
| #addin nuget:?package=Newtonsoft.Json&version=9.0.1 | ||||
| #tool "nuget:?package=OpenCover" | ||||
| #tool "nuget:?package=ReportGenerator" | ||||
| #tool coveralls.net | ||||
| @@ -260,11 +261,19 @@ Task("ReleasePackagesToUnstableFeed") | ||||
| Task("EnsureStableReleaseRequirements") | ||||
|     .Does(() => | ||||
|     { | ||||
| 		Information("Check if stable release..."); | ||||
|  | ||||
|         if (!AppVeyor.IsRunningOnAppVeyor) | ||||
| 		{ | ||||
|            throw new Exception("Stable release should happen via appveyor"); | ||||
| 		} | ||||
|          | ||||
|  | ||||
| 		Information("Running on AppVeyor..."); | ||||
|  | ||||
| 		Information("IsTag = " + AppVeyor.Environment.Repository.Tag.IsTag); | ||||
|  | ||||
| 		Information("Name = " + AppVeyor.Environment.Repository.Tag.Name); | ||||
|  | ||||
| 		var isTag = | ||||
|            AppVeyor.Environment.Repository.Tag.IsTag && | ||||
|            !string.IsNullOrWhiteSpace(AppVeyor.Environment.Repository.Tag.Name); | ||||
| @@ -273,6 +282,8 @@ Task("EnsureStableReleaseRequirements") | ||||
| 		{ | ||||
|            throw new Exception("Stable release should happen from a published GitHub release"); | ||||
| 		} | ||||
|  | ||||
| 		Information("Release is stable..."); | ||||
|     }); | ||||
|  | ||||
| Task("UpdateVersionInfo") | ||||
| @@ -287,19 +298,48 @@ Task("DownloadGitHubReleaseArtifacts") | ||||
|     .IsDependentOn("UpdateVersionInfo") | ||||
|     .Does(() => | ||||
|     { | ||||
|         EnsureDirectoryExists(packagesDir); | ||||
| 		try | ||||
| 		{ | ||||
| 			Information("DownloadGitHubReleaseArtifacts"); | ||||
|  | ||||
| 		var releaseUrl = tagsUrl + releaseTag; | ||||
|         var assets_url = ParseJson(GetResource(releaseUrl)) | ||||
|             .GetValue("assets_url") | ||||
| 			.Value<string>(); | ||||
| 			EnsureDirectoryExists(packagesDir); | ||||
|  | ||||
|         foreach(var asset in DeserializeJson<JArray>(GetResource(assets_url))) | ||||
|         { | ||||
| 			var file = packagesDir + File(asset.Value<string>("name")); | ||||
| 			Information("Downloading " + file); | ||||
|             DownloadFile(asset.Value<string>("browser_download_url"), file); | ||||
|         } | ||||
| 			Information("Directory exists..."); | ||||
|  | ||||
| 			var releaseUrl = tagsUrl + releaseTag; | ||||
|  | ||||
| 			Information("Release url " + releaseUrl); | ||||
|  | ||||
| 			//var releaseJson = Newtonsoft.Json.Linq.JObject.Parse(GetResource(releaseUrl));             | ||||
|  | ||||
|         	var assets_url = Newtonsoft.Json.Linq.JObject.Parse(GetResource(releaseUrl)) | ||||
| 				.GetValue("assets_url") | ||||
| 				.Value<string>(); | ||||
|  | ||||
| 			Information("Assets url " + assets_url); | ||||
|  | ||||
| 			var assets = GetResource(assets_url); | ||||
|  | ||||
| 			Information("Assets " + assets_url); | ||||
|  | ||||
| 			foreach(var asset in Newtonsoft.Json.JsonConvert.DeserializeObject<JArray>(assets)) | ||||
| 			{ | ||||
| 				Information("In the loop.."); | ||||
|  | ||||
| 				var file = packagesDir + File(asset.Value<string>("name")); | ||||
|  | ||||
| 				Information("Downloading " + file); | ||||
| 				 | ||||
| 				DownloadFile(asset.Value<string>("browser_download_url"), file); | ||||
| 			} | ||||
|  | ||||
| 			Information("Out of the loop..."); | ||||
| 		} | ||||
| 		catch(Exception exception) | ||||
| 		{ | ||||
| 			Information("There was an exception " + exception); | ||||
| 			throw; | ||||
| 		} | ||||
|     }); | ||||
|  | ||||
| Task("ReleasePackagesToStableFeed") | ||||
| @@ -394,19 +434,31 @@ private void PublishPackages(ConvertableDirectoryPath packagesDir, ConvertableFi | ||||
| /// gets the resource from the specified url | ||||
| private string GetResource(string url) | ||||
| { | ||||
| 	Information("Getting resource from " + url); | ||||
| 	try | ||||
| 	{ | ||||
| 		Information("Getting resource from " + url); | ||||
|  | ||||
|     var assetsRequest = System.Net.WebRequest.CreateHttp(url); | ||||
|     assetsRequest.Method = "GET"; | ||||
|     assetsRequest.Accept = "application/vnd.github.v3+json"; | ||||
|     assetsRequest.UserAgent = "BuildScript"; | ||||
| 		var assetsRequest = System.Net.WebRequest.CreateHttp(url); | ||||
| 		assetsRequest.Method = "GET"; | ||||
| 		assetsRequest.Accept = "application/vnd.github.v3+json"; | ||||
| 		assetsRequest.UserAgent = "BuildScript"; | ||||
|  | ||||
|     using (var assetsResponse = assetsRequest.GetResponse()) | ||||
|     { | ||||
|         var assetsStream = assetsResponse.GetResponseStream(); | ||||
|         var assetsReader = new StreamReader(assetsStream); | ||||
|         return assetsReader.ReadToEnd(); | ||||
|     } | ||||
| 		using (var assetsResponse = assetsRequest.GetResponse()) | ||||
| 		{ | ||||
| 			var assetsStream = assetsResponse.GetResponseStream(); | ||||
| 			var assetsReader = new StreamReader(assetsStream); | ||||
| 			var response =  assetsReader.ReadToEnd(); | ||||
|  | ||||
| 			Information("Response is " + response); | ||||
| 			 | ||||
| 			return response; | ||||
| 		} | ||||
| 	} | ||||
| 	catch(Exception exception) | ||||
| 	{ | ||||
| 		Information("There was an exception " + exception); | ||||
| 		throw; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| private bool ShouldPublishToUnstableFeed(string filter, string branchName) | ||||
|   | ||||
							
								
								
									
										121
									
								
								build.ps1
									
									
									
									
									
								
							
							
						
						
									
										121
									
								
								build.ps1
									
									
									
									
									
								
							| @@ -21,34 +21,35 @@ The build script target to run. | ||||
| The build configuration to use. | ||||
| .PARAMETER Verbosity | ||||
| Specifies the amount of information to be displayed. | ||||
| .PARAMETER ShowDescription | ||||
| Shows description about tasks. | ||||
| .PARAMETER DryRun | ||||
| Performs a dry run. | ||||
| .PARAMETER Experimental | ||||
| Tells Cake to use the latest Roslyn release. | ||||
| .PARAMETER WhatIf | ||||
| Performs a dry run of the build script. | ||||
| No tasks will be executed. | ||||
| Uses the nightly builds of the Roslyn script engine. | ||||
| .PARAMETER Mono | ||||
| Tells Cake to use the Mono scripting engine. | ||||
| Uses the Mono Compiler rather than the Roslyn script engine. | ||||
| .PARAMETER SkipToolPackageRestore | ||||
| Skips restoring of packages. | ||||
| .PARAMETER ScriptArgs | ||||
| Remaining arguments are added here. | ||||
|  | ||||
| .LINK | ||||
| http://cakebuild.net | ||||
| https://cakebuild.net | ||||
|  | ||||
| #> | ||||
|  | ||||
| [CmdletBinding()] | ||||
| Param( | ||||
|     [string]$Script = "build.cake", | ||||
|     [string]$Target = "Default", | ||||
|     [ValidateSet("Release", "Debug")] | ||||
|     [string]$Configuration = "Release", | ||||
|     [string]$Target, | ||||
|     [string]$Configuration, | ||||
|     [ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")] | ||||
|     [string]$Verbosity = "Verbose", | ||||
|     [string]$Verbosity, | ||||
|     [switch]$ShowDescription, | ||||
|     [Alias("WhatIf", "Noop")] | ||||
|     [switch]$DryRun, | ||||
|     [switch]$Experimental, | ||||
|     [Alias("DryRun","Noop")] | ||||
|     [switch]$WhatIf, | ||||
|     [switch]$Mono, | ||||
|     [switch]$SkipToolPackageRestore, | ||||
|     [Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)] | ||||
| @@ -80,6 +81,15 @@ function MD5HashFile([string] $filePath) | ||||
|     } | ||||
| } | ||||
|  | ||||
| function GetProxyEnabledWebClient | ||||
| { | ||||
|     $wc = New-Object System.Net.WebClient | ||||
|     $proxy = [System.Net.WebRequest]::GetSystemWebProxy() | ||||
|     $proxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials         | ||||
|     $wc.Proxy = $proxy | ||||
|     return $wc | ||||
| } | ||||
|  | ||||
| Write-Host "Preparing to run build script..." | ||||
|  | ||||
| if(!$PSScriptRoot){ | ||||
| @@ -87,31 +97,15 @@ if(!$PSScriptRoot){ | ||||
| } | ||||
|  | ||||
| $TOOLS_DIR = Join-Path $PSScriptRoot "tools" | ||||
| $ADDINS_DIR = Join-Path $TOOLS_DIR "Addins" | ||||
| $MODULES_DIR = Join-Path $TOOLS_DIR "Modules" | ||||
| $NUGET_EXE = Join-Path $TOOLS_DIR "nuget.exe" | ||||
| $CAKE_EXE = Join-Path $TOOLS_DIR "Cake/Cake.exe" | ||||
| $NUGET_URL = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" | ||||
| $PACKAGES_CONFIG = Join-Path $TOOLS_DIR "packages.config" | ||||
| $PACKAGES_CONFIG_MD5 = Join-Path $TOOLS_DIR "packages.config.md5sum" | ||||
|  | ||||
| # Should we use mono? | ||||
| $UseMono = ""; | ||||
| if($Mono.IsPresent) { | ||||
|     Write-Verbose -Message "Using the Mono based scripting engine." | ||||
|     $UseMono = "-mono" | ||||
| } | ||||
|  | ||||
| # Should we use the new Roslyn? | ||||
| $UseExperimental = ""; | ||||
| if($Experimental.IsPresent -and !($Mono.IsPresent)) { | ||||
|     Write-Verbose -Message "Using experimental version of Roslyn." | ||||
|     $UseExperimental = "-experimental" | ||||
| } | ||||
|  | ||||
| # Is this a dry run? | ||||
| $UseDryRun = ""; | ||||
| if($WhatIf.IsPresent) { | ||||
|     $UseDryRun = "-dryrun" | ||||
| } | ||||
| $ADDINS_PACKAGES_CONFIG = Join-Path $ADDINS_DIR "packages.config" | ||||
| $MODULES_PACKAGES_CONFIG = Join-Path $MODULES_DIR "packages.config" | ||||
|  | ||||
| # Make sure tools folder exists | ||||
| if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) { | ||||
| @@ -121,8 +115,10 @@ if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) { | ||||
|  | ||||
| # Make sure that packages.config exist. | ||||
| if (!(Test-Path $PACKAGES_CONFIG)) { | ||||
|     Write-Verbose -Message "Downloading packages.config..." | ||||
|     try { (New-Object System.Net.WebClient).DownloadFile("http://cakebuild.net/download/bootstrapper/packages", $PACKAGES_CONFIG) } catch { | ||||
|     Write-Verbose -Message "Downloading packages.config..."     | ||||
|     try {         | ||||
|         $wc = GetProxyEnabledWebClient | ||||
|         $wc.DownloadFile("https://cakebuild.net/download/bootstrapper/packages", $PACKAGES_CONFIG) } catch { | ||||
|         Throw "Could not download packages.config." | ||||
|     } | ||||
| } | ||||
| @@ -130,7 +126,7 @@ if (!(Test-Path $PACKAGES_CONFIG)) { | ||||
| # Try find NuGet.exe in path if not exists | ||||
| if (!(Test-Path $NUGET_EXE)) { | ||||
|     Write-Verbose -Message "Trying to find nuget.exe in PATH..." | ||||
|     $existingPaths = $Env:Path -Split ';' | Where-Object { (![string]::IsNullOrEmpty($_)) -and (Test-Path $_) } | ||||
|     $existingPaths = $Env:Path -Split ';' | Where-Object { (![string]::IsNullOrEmpty($_)) -and (Test-Path $_ -PathType Container) } | ||||
|     $NUGET_EXE_IN_PATH = Get-ChildItem -Path $existingPaths -Filter "nuget.exe" | Select -First 1 | ||||
|     if ($NUGET_EXE_IN_PATH -ne $null -and (Test-Path $NUGET_EXE_IN_PATH.FullName)) { | ||||
|         Write-Verbose -Message "Found in PATH at $($NUGET_EXE_IN_PATH.FullName)." | ||||
| @@ -142,7 +138,8 @@ if (!(Test-Path $NUGET_EXE)) { | ||||
| if (!(Test-Path $NUGET_EXE)) { | ||||
|     Write-Verbose -Message "Downloading NuGet.exe..." | ||||
|     try { | ||||
|         (New-Object System.Net.WebClient).DownloadFile($NUGET_URL, $NUGET_EXE) | ||||
|         $wc = GetProxyEnabledWebClient | ||||
|         $wc.DownloadFile($NUGET_URL, $NUGET_EXE) | ||||
|     } catch { | ||||
|         Throw "Could not download NuGet.exe." | ||||
|     } | ||||
| @@ -175,6 +172,41 @@ if(-Not $SkipToolPackageRestore.IsPresent) { | ||||
|         $md5Hash | Out-File $PACKAGES_CONFIG_MD5 -Encoding "ASCII" | ||||
|     } | ||||
|     Write-Verbose -Message ($NuGetOutput | out-string) | ||||
|  | ||||
|     Pop-Location | ||||
| } | ||||
|  | ||||
| # Restore addins from NuGet | ||||
| if (Test-Path $ADDINS_PACKAGES_CONFIG) { | ||||
|     Push-Location | ||||
|     Set-Location $ADDINS_DIR | ||||
|  | ||||
|     Write-Verbose -Message "Restoring addins from NuGet..." | ||||
|     $NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$ADDINS_DIR`"" | ||||
|  | ||||
|     if ($LASTEXITCODE -ne 0) { | ||||
|         Throw "An error occured while restoring NuGet addins." | ||||
|     } | ||||
|  | ||||
|     Write-Verbose -Message ($NuGetOutput | out-string) | ||||
|  | ||||
|     Pop-Location | ||||
| } | ||||
|  | ||||
| # Restore modules from NuGet | ||||
| if (Test-Path $MODULES_PACKAGES_CONFIG) { | ||||
|     Push-Location | ||||
|     Set-Location $MODULES_DIR | ||||
|  | ||||
|     Write-Verbose -Message "Restoring modules from NuGet..." | ||||
|     $NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$MODULES_DIR`"" | ||||
|  | ||||
|     if ($LASTEXITCODE -ne 0) { | ||||
|         Throw "An error occured while restoring NuGet modules." | ||||
|     } | ||||
|  | ||||
|     Write-Verbose -Message ($NuGetOutput | out-string) | ||||
|  | ||||
|     Pop-Location | ||||
| } | ||||
|  | ||||
| @@ -183,7 +215,20 @@ if (!(Test-Path $CAKE_EXE)) { | ||||
|     Throw "Could not find Cake.exe at $CAKE_EXE" | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| # Build Cake arguments | ||||
| $cakeArguments = @("$Script"); | ||||
| if ($Target) { $cakeArguments += "-target=$Target" } | ||||
| if ($Configuration) { $cakeArguments += "-configuration=$Configuration" } | ||||
| if ($Verbosity) { $cakeArguments += "-verbosity=$Verbosity" } | ||||
| if ($ShowDescription) { $cakeArguments += "-showdescription" } | ||||
| if ($DryRun) { $cakeArguments += "-dryrun" } | ||||
| if ($Experimental) { $cakeArguments += "-experimental" } | ||||
| if ($Mono) { $cakeArguments += "-mono" } | ||||
| $cakeArguments += $ScriptArgs | ||||
|  | ||||
| # Start Cake | ||||
| Write-Host "Running build script..." | ||||
| Invoke-Expression "& `"$CAKE_EXE`" `"$Script`" -target=`"$Target`" -configuration=`"$Configuration`" -verbosity=`"$Verbosity`" $UseMono $UseDryRun $UseExperimental $ScriptArgs" | ||||
| exit $LASTEXITCODE | ||||
| &$CAKE_EXE $cakeArguments | ||||
| exit $LASTEXITCODE | ||||
|   | ||||
| @@ -36,7 +36,7 @@ namespace Ocelot.Authentication.Middleware | ||||
|             { | ||||
|                 _logger.LogDebug($"{context.Request.Path} is an authenticated route. {MiddlewareName} checking if client is authenticated"); | ||||
|                  | ||||
|                 var result = await context.AuthenticateAsync(DownstreamRoute.ReRoute.AuthenticationProviderKey); | ||||
|                 var result = await context.AuthenticateAsync(DownstreamRoute.ReRoute.AuthenticationOptions.AuthenticationProviderKey); | ||||
|                  | ||||
|                 context.User = result.Principal; | ||||
|  | ||||
|   | ||||
| @@ -4,11 +4,13 @@ namespace Ocelot.Configuration | ||||
| { | ||||
|     public class AuthenticationOptions | ||||
|     { | ||||
|         public AuthenticationOptions(List<string> allowedScopes) | ||||
|         public AuthenticationOptions(List<string> allowedScopes, string authenticationProviderKey) | ||||
|         { | ||||
|             AllowedScopes = allowedScopes; | ||||
|             AuthenticationProviderKey = authenticationProviderKey; | ||||
|         } | ||||
|  | ||||
|         public List<string> AllowedScopes { get; private set; } | ||||
|         public string AuthenticationProviderKey { get; private set; } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -5,6 +5,7 @@ namespace Ocelot.Configuration.Builder | ||||
|     public class AuthenticationOptionsBuilder | ||||
|     { | ||||
|         private List<string> _allowedScopes = new List<string>(); | ||||
|         private string _authenticationProviderKey; | ||||
|  | ||||
|         public AuthenticationOptionsBuilder WithAllowedScopes(List<string> allowedScopes) | ||||
|         { | ||||
| @@ -12,9 +13,15 @@ namespace Ocelot.Configuration.Builder | ||||
|             return this; | ||||
|         } | ||||
|  | ||||
|         public AuthenticationOptionsBuilder WithAuthenticationProviderKey(string authenticationProviderKey) | ||||
|         { | ||||
|             _authenticationProviderKey = authenticationProviderKey; | ||||
|             return this; | ||||
|         } | ||||
|  | ||||
|         public AuthenticationOptions Build() | ||||
|         { | ||||
|             return new AuthenticationOptions(_allowedScopes); | ||||
|             return new AuthenticationOptions(_allowedScopes, _authenticationProviderKey); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -29,6 +29,7 @@ namespace Ocelot.Configuration.Builder | ||||
|         private ServiceProviderConfiguration _serviceProviderConfiguraion; | ||||
|         private bool _useQos; | ||||
|         private QoSOptions _qosOptions; | ||||
|         private HttpHandlerOptions _httpHandlerOptions; | ||||
|         public bool _enableRateLimiting; | ||||
|         public RateLimitOptions _rateLimitOptions; | ||||
|         private string _authenticationProviderKey; | ||||
| @@ -183,6 +184,11 @@ namespace Ocelot.Configuration.Builder | ||||
|             return this; | ||||
|         } | ||||
|  | ||||
|         public ReRouteBuilder WithHttpHandlerOptions(HttpHandlerOptions input) | ||||
|         { | ||||
|             _httpHandlerOptions = input; | ||||
|             return this; | ||||
|         } | ||||
|  | ||||
|         public ReRoute Build() | ||||
|         { | ||||
| @@ -211,7 +217,7 @@ namespace Ocelot.Configuration.Builder | ||||
|                 _qosOptions, | ||||
|                 _enableRateLimiting, | ||||
|                 _rateLimitOptions, | ||||
|                 _authenticationProviderKey); | ||||
|                 _httpHandlerOptions); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -6,7 +6,7 @@ namespace Ocelot.Configuration.Creator | ||||
|     { | ||||
|         public AuthenticationOptions Create(FileReRoute reRoute) | ||||
|         { | ||||
|             return new AuthenticationOptions(reRoute.AuthenticationOptions.AllowedScopes); | ||||
|             return new AuthenticationOptions(reRoute.AuthenticationOptions.AllowedScopes, reRoute.AuthenticationOptions.AuthenticationProviderKey); | ||||
|         }  | ||||
|     } | ||||
| } | ||||
| @@ -38,6 +38,7 @@ namespace Ocelot.Configuration.Creator | ||||
|         private readonly IReRouteOptionsCreator _fileReRouteOptionsCreator; | ||||
|         private readonly IRateLimitOptionsCreator _rateLimitOptionsCreator; | ||||
|         private readonly IRegionCreator _regionCreator; | ||||
|         private readonly IHttpHandlerOptionsCreator _httpHandlerOptionsCreator; | ||||
|  | ||||
|         public FileOcelotConfigurationCreator( | ||||
|             IOptions<FileConfiguration> options,  | ||||
| @@ -55,7 +56,8 @@ namespace Ocelot.Configuration.Creator | ||||
|             IQoSOptionsCreator qosOptionsCreator, | ||||
|             IReRouteOptionsCreator fileReRouteOptionsCreator, | ||||
|             IRateLimitOptionsCreator rateLimitOptionsCreator, | ||||
|             IRegionCreator regionCreator | ||||
|             IRegionCreator regionCreator, | ||||
|             IHttpHandlerOptionsCreator httpHandlerOptionsCreator | ||||
|             ) | ||||
|         { | ||||
|             _regionCreator = regionCreator; | ||||
| @@ -74,6 +76,7 @@ namespace Ocelot.Configuration.Creator | ||||
|             _serviceProviderConfigCreator = serviceProviderConfigCreator; | ||||
|             _qosOptionsCreator = qosOptionsCreator; | ||||
|             _fileReRouteOptionsCreator = fileReRouteOptionsCreator; | ||||
|             _httpHandlerOptionsCreator = httpHandlerOptionsCreator; | ||||
|         } | ||||
|  | ||||
|         public async Task<Response<IOcelotConfiguration>> Create() | ||||
| @@ -143,6 +146,8 @@ namespace Ocelot.Configuration.Creator | ||||
|  | ||||
|             var region = _regionCreator.Create(fileReRoute); | ||||
|  | ||||
|             var httpHandlerOptions = _httpHandlerOptionsCreator.Create(fileReRoute); | ||||
|  | ||||
|             var reRoute = new ReRouteBuilder() | ||||
|                 .WithDownstreamPathTemplate(fileReRoute.DownstreamPathTemplate) | ||||
|                 .WithUpstreamPathTemplate(fileReRoute.UpstreamPathTemplate) | ||||
| @@ -168,7 +173,7 @@ namespace Ocelot.Configuration.Creator | ||||
|                 .WithQosOptions(qosOptions) | ||||
|                 .WithEnableRateLimiting(fileReRouteOptions.EnableRateLimiting) | ||||
|                 .WithRateLimitOptions(rateLimitOption) | ||||
|                 .WithAuthenticationProviderKey(fileReRoute.AuthenticationOptions.AuthenticationProviderKey) | ||||
|                 .WithHttpHandlerOptions(httpHandlerOptions) | ||||
|                 .Build(); | ||||
|  | ||||
|             await SetupLoadBalancer(reRoute); | ||||
|   | ||||
| @@ -0,0 +1,13 @@ | ||||
| using Ocelot.Configuration.File; | ||||
|  | ||||
| namespace Ocelot.Configuration.Creator | ||||
| { | ||||
|     public class HttpHandlerOptionsCreator : IHttpHandlerOptionsCreator | ||||
|     { | ||||
|         public HttpHandlerOptions Create(FileReRoute fileReRoute) | ||||
|         { | ||||
|             return new HttpHandlerOptions(fileReRoute.HttpHandlerOptions.AllowAutoRedirect, | ||||
|                 fileReRoute.HttpHandlerOptions.UseCookieContainer); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,12 @@ | ||||
| using Ocelot.Configuration.File; | ||||
|  | ||||
| namespace Ocelot.Configuration.Creator | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Describes creation of HttpHandlerOptions | ||||
|     /// </summary> | ||||
|     public interface IHttpHandlerOptionsCreator | ||||
|     { | ||||
|         HttpHandlerOptions Create(FileReRoute fileReRoute); | ||||
|     } | ||||
| } | ||||
| @@ -41,8 +41,8 @@ namespace Ocelot.Configuration.Creator | ||||
|             } | ||||
|  | ||||
|             var route = reRoute.ReRouteIsCaseSensitive  | ||||
|                 ? $"{upstreamTemplate}{RegExMatchEndString}"  | ||||
|                 : $"{RegExIgnoreCase}{upstreamTemplate}{RegExMatchEndString}"; | ||||
|                 ? $"^{upstreamTemplate}{RegExMatchEndString}"  | ||||
|                 : $"^{RegExIgnoreCase}{upstreamTemplate}{RegExMatchEndString}"; | ||||
|  | ||||
|             return route; | ||||
|         } | ||||
|   | ||||
							
								
								
									
										15
									
								
								src/Ocelot/Configuration/File/FileHttpHandlerOptions.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/Ocelot/Configuration/File/FileHttpHandlerOptions.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| namespace Ocelot.Configuration.File | ||||
| { | ||||
|     public class FileHttpHandlerOptions | ||||
|     { | ||||
|         public FileHttpHandlerOptions() | ||||
|         { | ||||
|             AllowAutoRedirect = true; | ||||
|             UseCookieContainer = true; | ||||
|         } | ||||
|  | ||||
|         public bool AllowAutoRedirect { get; set; } | ||||
|  | ||||
|         public bool UseCookieContainer { get; set; } | ||||
|     } | ||||
| } | ||||
| @@ -15,6 +15,7 @@ namespace Ocelot.Configuration.File | ||||
|             QoSOptions = new FileQoSOptions(); | ||||
|             RateLimitOptions = new FileRateLimitRule(); | ||||
|             AuthenticationOptions = new FileAuthenticationOptions(); | ||||
|             HttpHandlerOptions = new FileHttpHandlerOptions(); | ||||
|         } | ||||
|  | ||||
|         public string DownstreamPathTemplate { get; set; } | ||||
| @@ -35,5 +36,6 @@ namespace Ocelot.Configuration.File | ||||
|         public string LoadBalancer {get;set;} | ||||
|         public FileRateLimitRule RateLimitOptions { get; set; } | ||||
|         public FileAuthenticationOptions AuthenticationOptions { get; set; } | ||||
|         public FileHttpHandlerOptions HttpHandlerOptions { get; set; } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										25
									
								
								src/Ocelot/Configuration/HttpHandlerOptions.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/Ocelot/Configuration/HttpHandlerOptions.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| namespace Ocelot.Configuration | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Describes configuration parameters for http handler,  | ||||
|     /// that is created to handle a request to service | ||||
|     /// </summary> | ||||
|     public class HttpHandlerOptions | ||||
|     { | ||||
|         public HttpHandlerOptions(bool allowAutoRedirect, bool useCookieContainer) | ||||
|         { | ||||
|             AllowAutoRedirect = allowAutoRedirect; | ||||
|             UseCookieContainer = useCookieContainer; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Specify if auto redirect is enabled | ||||
|         /// </summary> | ||||
|         public bool AllowAutoRedirect { get; private set; } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Specify is handler has to use a cookie container | ||||
|         /// </summary> | ||||
|         public bool UseCookieContainer { get; private set; } | ||||
|     } | ||||
| } | ||||
| @@ -30,7 +30,7 @@ namespace Ocelot.Configuration | ||||
|             QoSOptions qosOptions, | ||||
|             bool enableEndpointRateLimiting, | ||||
|             RateLimitOptions ratelimitOptions, | ||||
|             string authenticationProviderKey) | ||||
|             HttpHandlerOptions httpHandlerOptions) | ||||
|         { | ||||
|             ReRouteKey = reRouteKey; | ||||
|             ServiceProviderConfiguraion = serviceProviderConfiguraion; | ||||
| @@ -59,7 +59,7 @@ namespace Ocelot.Configuration | ||||
|             QosOptionsOptions = qosOptions; | ||||
|             EnableEndpointEndpointRateLimiting = enableEndpointRateLimiting; | ||||
|             RateLimitOptions = ratelimitOptions; | ||||
|             AuthenticationProviderKey = authenticationProviderKey; | ||||
|             HttpHandlerOptions = httpHandlerOptions; | ||||
|         } | ||||
|  | ||||
|         public string ReRouteKey {get;private set;} | ||||
| @@ -86,6 +86,6 @@ namespace Ocelot.Configuration | ||||
|         public ServiceProviderConfiguration ServiceProviderConfiguraion { get; private set; } | ||||
|         public bool EnableEndpointEndpointRateLimiting { get; private set; } | ||||
|         public RateLimitOptions RateLimitOptions { get; private set; } | ||||
|         public string AuthenticationProviderKey { get; private set; } | ||||
|         public HttpHandlerOptions HttpHandlerOptions { get; private set; } | ||||
|     } | ||||
| } | ||||
| @@ -124,6 +124,7 @@ namespace Ocelot.DependencyInjection | ||||
|             services.TryAddSingleton<IRateLimitCounterHandler, MemoryCacheRateLimitCounterHandler>(); | ||||
|             services.TryAddSingleton<IHttpClientCache, MemoryHttpClientCache>(); | ||||
|             services.TryAddSingleton<IRequestMapper, RequestMapper>(); | ||||
|             services.TryAddSingleton<IHttpHandlerOptionsCreator, HttpHandlerOptionsCreator>(); | ||||
|  | ||||
|             // see this for why we register this as singleton http://stackoverflow.com/questions/37371264/invalidoperationexception-unable-to-resolve-service-for-type-microsoft-aspnetc | ||||
|             // could maybe use a scoped data repository | ||||
|   | ||||
| @@ -10,9 +10,11 @@ namespace Ocelot.Request.Builder | ||||
|         public async Task<Response<Request>> Build( | ||||
|             HttpRequestMessage httpRequestMessage, | ||||
|             bool isQos, | ||||
|             IQoSProvider qosProvider) | ||||
|             IQoSProvider qosProvider, | ||||
|             bool useCookieContainer, | ||||
|             bool allowAutoRedirect) | ||||
|         { | ||||
|             return new OkResponse<Request>(new Request(httpRequestMessage, isQos, qosProvider)); | ||||
|             return new OkResponse<Request>(new Request(httpRequestMessage, isQos, qosProvider, useCookieContainer, allowAutoRedirect)); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -11,6 +11,8 @@ | ||||
|         Task<Response<Request>> Build( | ||||
|             HttpRequestMessage httpRequestMessage, | ||||
|             bool isQos, | ||||
|             IQoSProvider qosProvider); | ||||
|             IQoSProvider qosProvider, | ||||
|             bool useCookieContainer, | ||||
|             bool allowAutoRedirect); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -46,7 +46,9 @@ namespace Ocelot.Request.Middleware | ||||
|             var buildResult = await _requestCreator.Build( | ||||
|                     DownstreamRequest, | ||||
|                     DownstreamRoute.ReRoute.IsQos, | ||||
|                     qosProvider.Data); | ||||
|                     qosProvider.Data, | ||||
|                     DownstreamRoute.ReRoute.HttpHandlerOptions.UseCookieContainer, | ||||
|                     DownstreamRoute.ReRoute.HttpHandlerOptions.AllowAutoRedirect); | ||||
|  | ||||
|             if (buildResult.IsError) | ||||
|             { | ||||
|   | ||||
| @@ -8,15 +8,21 @@ namespace Ocelot.Request | ||||
|         public Request( | ||||
|             HttpRequestMessage httpRequestMessage,  | ||||
|             bool isQos, | ||||
|             IQoSProvider qosProvider) | ||||
|             IQoSProvider qosProvider,  | ||||
|             bool allowAutoRedirect, | ||||
|             bool useCookieContainer) | ||||
|         { | ||||
|             HttpRequestMessage = httpRequestMessage; | ||||
|             IsQos = isQos; | ||||
|             QosProvider = qosProvider; | ||||
|             AllowAutoRedirect = allowAutoRedirect; | ||||
|             UseCookieContainer = useCookieContainer; | ||||
|         } | ||||
|  | ||||
|         public HttpRequestMessage HttpRequestMessage { get; private set; } | ||||
|         public bool IsQos { get; private set; } | ||||
|         public IQoSProvider QosProvider { get; private set; } | ||||
|         public bool AllowAutoRedirect { get; private set; } | ||||
|         public bool UseCookieContainer { get; private set; } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -20,9 +20,9 @@ namespace Ocelot.Requester | ||||
|             return this; | ||||
|         }   | ||||
|  | ||||
|         public IHttpClient Create() | ||||
|         public IHttpClient Create(bool useCookies, bool allowAutoRedirect) | ||||
|         { | ||||
|             var httpclientHandler = new HttpClientHandler(); | ||||
|             var httpclientHandler = new HttpClientHandler { AllowAutoRedirect = allowAutoRedirect, UseCookies = useCookies}; | ||||
|              | ||||
|             var client = new HttpClient(CreateHttpMessageHandler(httpclientHandler));                 | ||||
|              | ||||
|   | ||||
| @@ -2,6 +2,7 @@ | ||||
| using System.Collections.Concurrent; | ||||
| using System.Net.Http; | ||||
| using System.Threading.Tasks; | ||||
| using Ocelot.Configuration; | ||||
| using Ocelot.Logging; | ||||
| using Ocelot.Responses; | ||||
| using Polly.CircuitBreaker; | ||||
| @@ -14,7 +15,8 @@ namespace Ocelot.Requester | ||||
|         private readonly IHttpClientCache _cacheHandlers; | ||||
|         private readonly IOcelotLogger _logger; | ||||
|  | ||||
|         public HttpClientHttpRequester(IOcelotLoggerFactory loggerFactory, IHttpClientCache cacheHandlers) | ||||
|         public HttpClientHttpRequester(IOcelotLoggerFactory loggerFactory,  | ||||
|             IHttpClientCache cacheHandlers) | ||||
|         { | ||||
|             _logger = loggerFactory.CreateLogger<HttpClientHttpRequester>(); | ||||
|             _cacheHandlers = cacheHandlers; | ||||
| @@ -25,8 +27,8 @@ namespace Ocelot.Requester | ||||
|             var builder = new HttpClientBuilder(); | ||||
|  | ||||
|             var cacheKey = GetCacheKey(request, builder); | ||||
|  | ||||
|             var httpClient = GetHttpClient(cacheKey, builder); | ||||
|              | ||||
|             var httpClient = GetHttpClient(cacheKey, builder, request.UseCookieContainer, request.AllowAutoRedirect); | ||||
|  | ||||
|             try | ||||
|             { | ||||
| @@ -54,13 +56,13 @@ namespace Ocelot.Requester | ||||
|  | ||||
|         } | ||||
|  | ||||
|         private IHttpClient GetHttpClient(string cacheKey, IHttpClientBuilder builder) | ||||
|         private IHttpClient GetHttpClient(string cacheKey, IHttpClientBuilder builder, bool useCookieContainer, bool allowAutoRedirect) | ||||
|         { | ||||
|             var httpClient = _cacheHandlers.Get(cacheKey); | ||||
|  | ||||
|             if (httpClient == null) | ||||
|             { | ||||
|                 httpClient = builder.Create(); | ||||
|                 httpClient = builder.Create(useCookieContainer, allowAutoRedirect); | ||||
|             } | ||||
|             return httpClient; | ||||
|         } | ||||
|   | ||||
| @@ -15,11 +15,13 @@ namespace Ocelot.Requester | ||||
|         /// <summary> | ||||
|         /// Sets a PollyCircuitBreakingDelegatingHandler . | ||||
|         /// </summary> | ||||
|         IHttpClientBuilder WithQos(IQoSProvider qosProvider, IOcelotLogger logger);             | ||||
|  | ||||
|         /// <summary> | ||||
|         IHttpClientBuilder WithQos(IQoSProvider qosProvider, IOcelotLogger logger); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Creates the <see cref="HttpClient"/> | ||||
|         /// </summary> | ||||
|         IHttpClient Create(); | ||||
|         /// </summary> | ||||
|         /// <param name="useCookies">Defines if http client should use cookie container</param> | ||||
|         /// <param name="allowAutoRedirect">Defines if http client should allow auto redirect</param> | ||||
|         IHttpClient Create(bool useCookies, bool allowAutoRedirect); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -98,7 +98,7 @@ namespace Ocelot.AcceptanceTests | ||||
|                         DownstreamScheme = "http", | ||||
|                         DownstreamHost = "localhost", | ||||
|                         DownstreamPort = 51880, | ||||
|                         UpstreamPathTemplate = "working", | ||||
|                         UpstreamPathTemplate = "/working", | ||||
|                         UpstreamHttpMethod = new List<string> { "Get" }, | ||||
|                     } | ||||
|                 } | ||||
|   | ||||
| @@ -61,6 +61,47 @@ namespace Ocelot.AcceptanceTests | ||||
|                 .BDDfy(); | ||||
|         } | ||||
|  | ||||
|         [Fact] | ||||
|         public void bug() | ||||
|         { | ||||
|             var configuration = new FileConfiguration | ||||
|             { | ||||
|                 ReRoutes = new List<FileReRoute> | ||||
|                 { | ||||
|                     new FileReRoute | ||||
|                     { | ||||
|                         DownstreamPathTemplate = "/api/v1/vacancy", | ||||
|                         DownstreamScheme = "http", | ||||
|                         DownstreamHost = "localhost", | ||||
|                         DownstreamPort = 51879, | ||||
|                         UpstreamPathTemplate = "/vacancy/", | ||||
|                         UpstreamHttpMethod = new List<string> { "Options",  "Put", "Get", "Post", "Delete" }, | ||||
|                         ServiceName = "botCore", | ||||
|                         LoadBalancer = "LeastConnection" | ||||
|                     }, | ||||
|                     new FileReRoute | ||||
|                     { | ||||
|                         DownstreamPathTemplate = "/api/v1/vacancy/{vacancyId}", | ||||
|                         DownstreamScheme = "http", | ||||
|                         DownstreamHost = "localhost", | ||||
|                         DownstreamPort = 51879, | ||||
|                         UpstreamPathTemplate = "/vacancy/{vacancyId}", | ||||
|                         UpstreamHttpMethod = new List<string> { "Options",  "Put", "Get", "Post", "Delete" }, | ||||
|                         ServiceName = "botCore", | ||||
|                         LoadBalancer = "LeastConnection" | ||||
|                     } | ||||
|                 } | ||||
|             }; | ||||
|  | ||||
|             this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/v1/vacancy/1", 200, "Hello from Laura")) | ||||
|                 .And(x => _steps.GivenThereIsAConfiguration(configuration)) | ||||
|                 .And(x => _steps.GivenOcelotIsRunning()) | ||||
|                 .When(x => _steps.WhenIGetUrlOnTheApiGateway("/vacancy/1")) | ||||
|                 .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK)) | ||||
|                 .And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura")) | ||||
|                 .BDDfy(); | ||||
|         } | ||||
|  | ||||
|         [Fact] | ||||
|         public void should_return_response_200_when_path_missing_forward_slash_as_first_char() | ||||
|         { | ||||
| @@ -402,6 +443,46 @@ namespace Ocelot.AcceptanceTests | ||||
|                 .BDDfy(); | ||||
|         } | ||||
|  | ||||
|         [Fact] | ||||
|         public void should_return_404_when_calling_upstream_route_with_no_matching_downstream_re_route_github_issue_134() | ||||
|         { | ||||
|             var configuration = new FileConfiguration | ||||
|             { | ||||
|                 ReRoutes = new List<FileReRoute> | ||||
|                 { | ||||
|                     new FileReRoute | ||||
|                     { | ||||
|                         DownstreamPathTemplate = "/api/v1/vacancy", | ||||
|                         DownstreamScheme = "http", | ||||
|                         DownstreamHost = "localhost", | ||||
|                         DownstreamPort = 51879, | ||||
|                         UpstreamPathTemplate = "/vacancy/", | ||||
|                         UpstreamHttpMethod = new List<string> { "Options",  "Put", "Get", "Post", "Delete" }, | ||||
|                         ServiceName = "botCore", | ||||
|                         LoadBalancer = "LeastConnection" | ||||
|                     }, | ||||
|                     new FileReRoute | ||||
|                     { | ||||
|                         DownstreamPathTemplate = "/api/v1/vacancy/{vacancyId}", | ||||
|                         DownstreamScheme = "http", | ||||
|                         DownstreamHost = "localhost", | ||||
|                         DownstreamPort = 51879, | ||||
|                         UpstreamPathTemplate = "/vacancy/{vacancyId}", | ||||
|                         UpstreamHttpMethod = new List<string> { "Options",  "Put", "Get", "Post", "Delete" }, | ||||
|                         ServiceName = "botCore", | ||||
|                         LoadBalancer = "LeastConnection" | ||||
|                     } | ||||
|                 } | ||||
|             }; | ||||
|  | ||||
|             this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/v1/vacancy/1", 200, "Hello from Laura")) | ||||
|                 .And(x => _steps.GivenThereIsAConfiguration(configuration)) | ||||
|                 .And(x => _steps.GivenOcelotIsRunning()) | ||||
|                 .When(x => _steps.WhenIGetUrlOnTheApiGateway("api/vacancy/1")) | ||||
|                 .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.NotFound)) | ||||
|                 .BDDfy(); | ||||
|         } | ||||
|  | ||||
|         private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode, string responseBody) | ||||
|         { | ||||
|             _builder = new WebHostBuilder() | ||||
| @@ -413,7 +494,7 @@ namespace Ocelot.AcceptanceTests | ||||
|                 { | ||||
|                     app.UsePathBase(basePath); | ||||
|                     app.Run(async context => | ||||
|                     { | ||||
|                     {    | ||||
|                         _downstreamPath = context.Request.PathBase.Value; | ||||
|                         context.Response.StatusCode = statusCode; | ||||
|                         await context.Response.WriteAsync(responseBody); | ||||
|   | ||||
| @@ -14,8 +14,8 @@ namespace Ocelot.ManualTest | ||||
|             }); | ||||
|             builder.UseKestrel() | ||||
|                 .UseContentRoot(Directory.GetCurrentDirectory()) | ||||
|                 .UseStartup<Startup>(); | ||||
|  | ||||
|                 .UseIISIntegration() | ||||
|                 .UseStartup<Startup>();                 | ||||
|             var host = builder.Build(); | ||||
|             host.Run(); | ||||
|         } | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -0,0 +1,71 @@ | ||||
| using Ocelot.Configuration; | ||||
| using Ocelot.Configuration.Creator; | ||||
| using Ocelot.Configuration.File; | ||||
| using Shouldly; | ||||
| using TestStack.BDDfy; | ||||
| using Xunit; | ||||
|  | ||||
| namespace Ocelot.UnitTests.Configuration | ||||
| { | ||||
|  | ||||
|     public class HttpHandlerOptionsCreatorTests | ||||
|     { | ||||
|         private readonly IHttpHandlerOptionsCreator _httpHandlerOptionsCreator; | ||||
|         private FileReRoute _fileReRoute; | ||||
|         private HttpHandlerOptions _httpHandlerOptions; | ||||
|  | ||||
|         public HttpHandlerOptionsCreatorTests() | ||||
|         { | ||||
|             _httpHandlerOptionsCreator = new HttpHandlerOptionsCreator(); | ||||
|         } | ||||
|  | ||||
|         [Fact] | ||||
|         public void should_create_options_with_useCookie_and_allowAutoRedirect_true_as_default() | ||||
|         { | ||||
|             var fileReRoute = new FileReRoute(); | ||||
|             var expectedOptions = new HttpHandlerOptions(true, true); | ||||
|  | ||||
|             this.Given(x => GivenTheFollowing(fileReRoute)) | ||||
|                 .When(x => WhenICreateHttpHandlerOptions()) | ||||
|                 .Then(x => ThenTheFollowingOptionsReturned(expectedOptions)) | ||||
|                 .BDDfy(); | ||||
|         } | ||||
|  | ||||
|         [Fact] | ||||
|         public void should_create_options_with_specified_useCookie_and_allowAutoRedirect() | ||||
|         { | ||||
|             var fileReRoute = new FileReRoute | ||||
|             { | ||||
|                 HttpHandlerOptions = new FileHttpHandlerOptions | ||||
|                 { | ||||
|                     AllowAutoRedirect = false, | ||||
|                     UseCookieContainer = false | ||||
|                 } | ||||
|             }; | ||||
|  | ||||
|             var expectedOptions = new HttpHandlerOptions(false, false); | ||||
|  | ||||
|             this.Given(x => GivenTheFollowing(fileReRoute)) | ||||
|                 .When(x => WhenICreateHttpHandlerOptions()) | ||||
|                 .Then(x => ThenTheFollowingOptionsReturned(expectedOptions)) | ||||
|                 .BDDfy(); | ||||
|         } | ||||
|  | ||||
|         private void GivenTheFollowing(FileReRoute fileReRoute) | ||||
|         { | ||||
|             _fileReRoute = fileReRoute; | ||||
|         } | ||||
|  | ||||
|         private void WhenICreateHttpHandlerOptions() | ||||
|         { | ||||
|             _httpHandlerOptions = _httpHandlerOptionsCreator.Create(_fileReRoute); | ||||
|         } | ||||
|  | ||||
|         private void ThenTheFollowingOptionsReturned(HttpHandlerOptions options) | ||||
|         { | ||||
|             _httpHandlerOptions.ShouldNotBeNull(); | ||||
|             _httpHandlerOptions.AllowAutoRedirect.ShouldBe(options.AllowAutoRedirect); | ||||
|             _httpHandlerOptions.UseCookieContainer.ShouldBe(options.UseCookieContainer); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -28,7 +28,7 @@ namespace Ocelot.UnitTests.Configuration | ||||
|  | ||||
|             this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute)) | ||||
|                 .When(x => x.WhenICreateTheTemplatePattern()) | ||||
|                 .Then(x => x.ThenTheFollowingIsReturned("(?i)/PRODUCTS/.*/$")) | ||||
|                 .Then(x => x.ThenTheFollowingIsReturned("^(?i)/PRODUCTS/.*/$")) | ||||
|                 .BDDfy(); | ||||
|         } | ||||
|  | ||||
| @@ -42,7 +42,7 @@ namespace Ocelot.UnitTests.Configuration | ||||
|                 }; | ||||
|             this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute)) | ||||
|                 .When(x => x.WhenICreateTheTemplatePattern()) | ||||
|                 .Then(x => x.ThenTheFollowingIsReturned("/PRODUCTS/.*/$")) | ||||
|                 .Then(x => x.ThenTheFollowingIsReturned("^/PRODUCTS/.*/$")) | ||||
|                 .BDDfy(); | ||||
|         } | ||||
|  | ||||
| @@ -57,7 +57,7 @@ namespace Ocelot.UnitTests.Configuration | ||||
|  | ||||
|             this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute)) | ||||
|                 .When(x => x.WhenICreateTheTemplatePattern()) | ||||
|                 .Then(x => x.ThenTheFollowingIsReturned("/api/products/.*/$")) | ||||
|                 .Then(x => x.ThenTheFollowingIsReturned("^/api/products/.*/$")) | ||||
|                 .BDDfy(); | ||||
|         } | ||||
|  | ||||
| @@ -72,7 +72,7 @@ namespace Ocelot.UnitTests.Configuration | ||||
|  | ||||
|             this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute)) | ||||
|                 .When(x => x.WhenICreateTheTemplatePattern()) | ||||
|                 .Then(x => x.ThenTheFollowingIsReturned("/api/products/.*/variants/.*/$")) | ||||
|                 .Then(x => x.ThenTheFollowingIsReturned("^/api/products/.*/variants/.*/$")) | ||||
|                 .BDDfy(); | ||||
|         } | ||||
|         [Fact] | ||||
| @@ -86,7 +86,7 @@ namespace Ocelot.UnitTests.Configuration | ||||
|  | ||||
|             this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute)) | ||||
|                 .When(x => x.WhenICreateTheTemplatePattern()) | ||||
|                 .Then(x => x.ThenTheFollowingIsReturned("/api/products/.*/variants/.*/$")) | ||||
|                 .Then(x => x.ThenTheFollowingIsReturned("^/api/products/.*/variants/.*/$")) | ||||
|                 .BDDfy(); | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -28,6 +28,16 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher | ||||
|               .BDDfy(); | ||||
|         } | ||||
|  | ||||
|         [Fact] | ||||
|         public void should_not_match_issue_134() | ||||
|         { | ||||
|             this.Given(x => x.GivenIHaveAUpstreamPath("/api/vacancy/1/")) | ||||
|               .And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^(?i)/vacancy/.*/$")) | ||||
|               .When(x => x.WhenIMatchThePaths()) | ||||
|               .And(x => x.ThenTheResultIsFalse()) | ||||
|               .BDDfy(); | ||||
|         } | ||||
|  | ||||
|         [Fact] | ||||
|         public void should_match_forward_slash_only_regex() | ||||
|         { | ||||
| @@ -42,7 +52,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher | ||||
|         public void should_find_match_when_template_smaller_than_valid_path() | ||||
|         { | ||||
|             this.Given(x => x.GivenIHaveAUpstreamPath("/api/products/2354325435624623464235")) | ||||
|                 .And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("/api/products/.*$")) | ||||
|                 .And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^/api/products/.*$")) | ||||
|                 .When(x => x.WhenIMatchThePaths()) | ||||
|                 .And(x => x.ThenTheResultIsTrue()) | ||||
|                 .BDDfy(); | ||||
| @@ -52,7 +62,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher | ||||
|         public void should_not_find_match() | ||||
|         { | ||||
|             this.Given(x => x.GivenIHaveAUpstreamPath("/api/values")) | ||||
|                 .And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("/$")) | ||||
|                 .And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^/$")) | ||||
|                 .When(x => x.WhenIMatchThePaths()) | ||||
|                 .And(x => x.ThenTheResultIsFalse()) | ||||
|                 .BDDfy(); | ||||
| @@ -62,7 +72,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher | ||||
|         public void can_match_down_stream_url() | ||||
|         { | ||||
|             this.Given(x => x.GivenIHaveAUpstreamPath("")) | ||||
|                 .And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("$")) | ||||
|                 .And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^$")) | ||||
|                 .When(x => x.WhenIMatchThePaths()) | ||||
|                 .And(x => x.ThenTheResultIsTrue()) | ||||
|                 .BDDfy(); | ||||
| @@ -72,7 +82,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher | ||||
|         public void can_match_down_stream_url_with_no_slash() | ||||
|         { | ||||
|             this.Given(x => x.GivenIHaveAUpstreamPath("api")) | ||||
|                  .Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("api$")) | ||||
|                  .Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api$")) | ||||
|                  .When(x => x.WhenIMatchThePaths()) | ||||
|                  .Then(x => x.ThenTheResultIsTrue()) | ||||
|                  .BDDfy(); | ||||
| @@ -82,7 +92,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher | ||||
|         public void can_match_down_stream_url_with_one_slash() | ||||
|         { | ||||
|             this.Given(x => x.GivenIHaveAUpstreamPath("api/")) | ||||
|                  .Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("api/$")) | ||||
|                  .Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/$")) | ||||
|                  .When(x => x.WhenIMatchThePaths()) | ||||
|                  .Then(x => x.ThenTheResultIsTrue()) | ||||
|                  .BDDfy(); | ||||
| @@ -92,7 +102,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher | ||||
|         public void can_match_down_stream_url_with_downstream_template() | ||||
|         { | ||||
|             this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/")) | ||||
|               .Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("api/product/products/$")) | ||||
|               .Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/$")) | ||||
|               .When(x => x.WhenIMatchThePaths()) | ||||
|               .Then(x => x.ThenTheResultIsTrue()) | ||||
|               .BDDfy(); | ||||
| @@ -102,7 +112,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher | ||||
|         public void can_match_down_stream_url_with_downstream_template_with_one_place_holder() | ||||
|         { | ||||
|             this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1")) | ||||
|                .Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("api/product/products/.*$")) | ||||
|                .Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.*$")) | ||||
|                .When(x => x.WhenIMatchThePaths()) | ||||
|                .Then(x => x.ThenTheResultIsTrue()) | ||||
|                .BDDfy(); | ||||
| @@ -112,7 +122,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher | ||||
|         public void can_match_down_stream_url_with_downstream_template_with_two_place_holders() | ||||
|         { | ||||
|             this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/2")) | ||||
|                  .Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("api/product/products/.*/.*$")) | ||||
|                  .Given(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.*/.*$")) | ||||
|                  .When(x => x.WhenIMatchThePaths()) | ||||
|                  .Then(x => x.ThenTheResultIsTrue()) | ||||
|                  .BDDfy(); | ||||
| @@ -122,7 +132,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher | ||||
|         public void can_match_down_stream_url_with_downstream_template_with_two_place_holders_seperated_by_something() | ||||
|         { | ||||
|             this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/categories/2")) | ||||
|                 .And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("api/product/products/.*/categories/.*$")) | ||||
|                 .And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.*/categories/.*$")) | ||||
|                 .When(x => x.WhenIMatchThePaths()) | ||||
|                 .Then(x => x.ThenTheResultIsTrue()) | ||||
|                 .BDDfy(); | ||||
| @@ -132,7 +142,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher | ||||
|         public void can_match_down_stream_url_with_downstream_template_with_three_place_holders_seperated_by_something() | ||||
|         { | ||||
|             this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/categories/2/variant/123")) | ||||
|                 .And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("api/product/products/.*/categories/.*/variant/.*$")) | ||||
|                 .And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.*/categories/.*/variant/.*$")) | ||||
|                 .When(x => x.WhenIMatchThePaths()) | ||||
|                 .Then(x => x.ThenTheResultIsTrue()) | ||||
|                 .BDDfy(); | ||||
| @@ -142,7 +152,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher | ||||
|         public void can_match_down_stream_url_with_downstream_template_with_three_place_holders() | ||||
|         { | ||||
|             this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/categories/2/variant/")) | ||||
|                  .And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("api/product/products/.*/categories/.*/variant/$")) | ||||
|                  .And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.*/categories/.*/variant/$")) | ||||
|                  .When(x => x.WhenIMatchThePaths()) | ||||
|                  .Then(x => x.ThenTheResultIsTrue()) | ||||
|                  .BDDfy(); | ||||
| @@ -152,7 +162,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher | ||||
|         public void should_ignore_case_sensitivity() | ||||
|         { | ||||
|             this.Given(x => x.GivenIHaveAUpstreamPath("API/product/products/1/categories/2/variant/")) | ||||
|                .And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("(?i)api/product/products/.*/categories/.*/variant/$")) | ||||
|                .And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^(?i)api/product/products/.*/categories/.*/variant/$")) | ||||
|                .When(x => x.WhenIMatchThePaths()) | ||||
|                .Then(x => x.ThenTheResultIsTrue()) | ||||
|                .BDDfy(); | ||||
| @@ -162,7 +172,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher | ||||
|         public void should_respect_case_sensitivity() | ||||
|         { | ||||
|             this.Given(x => x.GivenIHaveAUpstreamPath("API/product/products/1/categories/2/variant/")) | ||||
|               .And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("api/product/products/.*/categories/.*/variant/$")) | ||||
|               .And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern("^api/product/products/.*/categories/.*/variant/$")) | ||||
|               .When(x => x.WhenIMatchThePaths()) | ||||
|               .Then(x => x.ThenTheResultIsFalse()) | ||||
|               .BDDfy(); | ||||
|   | ||||
| @@ -15,8 +15,9 @@ | ||||
|     using TestStack.BDDfy; | ||||
|     using Xunit; | ||||
|     using Ocelot.Requester.QoS; | ||||
|     using Microsoft.AspNetCore.Builder; | ||||
|  | ||||
|     using Ocelot.Configuration; | ||||
|     using Microsoft.AspNetCore.Builder; | ||||
|  | ||||
|     public class HttpRequestBuilderMiddlewareTests : ServerHostedMiddlewareTest | ||||
|     { | ||||
|         private readonly Mock<IRequestCreator> _requestBuilder; | ||||
| @@ -50,12 +51,13 @@ | ||||
|                 new ReRouteBuilder() | ||||
|                     .WithRequestIdKey("LSRequestId") | ||||
|                     .WithUpstreamHttpMethod(new List<string> { "Get" }) | ||||
|                     .WithHttpHandlerOptions(new HttpHandlerOptions(true, true)) | ||||
|                     .Build()); | ||||
|  | ||||
|             this.Given(x => x.GivenTheDownStreamUrlIs("any old string")) | ||||
|                 .And(x => x.GivenTheQosProviderHouseReturns(new OkResponse<IQoSProvider>(new NoQoSProvider()))) | ||||
|                 .And(x => x.GivenTheDownStreamRouteIs(downstreamRoute)) | ||||
|                 .And(x => x.GivenTheRequestBuilderReturns(new Ocelot.Request.Request(new HttpRequestMessage(), true, new NoQoSProvider()))) | ||||
|                 .And(x => x.GivenTheRequestBuilderReturns(new Ocelot.Request.Request(new HttpRequestMessage(), true, new NoQoSProvider(), false, false))) | ||||
|                 .When(x => x.WhenICallTheMiddleware()) | ||||
|                 .Then(x => x.ThenTheScopedDataRepositoryIsCalledCorrectly()) | ||||
|                 .BDDfy(); | ||||
| @@ -103,7 +105,11 @@ | ||||
|             _request = new OkResponse<Ocelot.Request.Request>(request); | ||||
|  | ||||
|             _requestBuilder | ||||
|                 .Setup(x => x.Build(It.IsAny<HttpRequestMessage>(), It.IsAny<bool>(), It.IsAny<IQoSProvider>())) | ||||
|                 .Setup(x => x.Build(It.IsAny<HttpRequestMessage>(), | ||||
|                                     It.IsAny<bool>(), | ||||
|                                     It.IsAny<IQoSProvider>(), | ||||
|                                     It.IsAny<bool>(), | ||||
|                                     It.IsAny<bool>())) | ||||
|                 .ReturnsAsync(_request); | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -15,6 +15,9 @@ | ||||
|         private readonly bool _isQos; | ||||
|         private readonly IQoSProvider _qoSProvider; | ||||
|         private readonly HttpRequestMessage _requestMessage; | ||||
|         private readonly bool _useCookieContainer; | ||||
|         private readonly bool _allowAutoRedirect; | ||||
|  | ||||
|         private Response<Ocelot.Request.Request> _response; | ||||
|  | ||||
|         public HttpRequestCreatorTests() | ||||
| @@ -22,6 +25,9 @@ | ||||
|             _requestCreator = new HttpRequestCreator(); | ||||
|             _isQos = true; | ||||
|             _qoSProvider = new NoQoSProvider(); | ||||
|             _useCookieContainer = false; | ||||
|             _allowAutoRedirect = false; | ||||
|  | ||||
|             _requestMessage = new HttpRequestMessage(); | ||||
|         } | ||||
|  | ||||
| @@ -30,12 +36,19 @@ | ||||
|         { | ||||
|             this.When(x => x.WhenIBuildARequest()) | ||||
|                 .Then(x => x.ThenTheRequestContainsTheRequestMessage()) | ||||
|                 .Then(x => x.ThenTheRequestContainsTheIsQos()) | ||||
|                 .Then(x => x.ThenTheRequestContainsTheQosProvider()) | ||||
|                 .Then(x => x.ThenTheRequestContainsUseCookieContainer()) | ||||
|                 .Then(x => x.ThenTheRequestContainsAllowAutoRedirect()) | ||||
|                 .BDDfy(); | ||||
|         } | ||||
|  | ||||
|         private void WhenIBuildARequest() | ||||
|         { | ||||
|             _response = _requestCreator.Build(_requestMessage, _isQos, _qoSProvider).GetAwaiter().GetResult(); | ||||
|             _response = _requestCreator.Build(_requestMessage, | ||||
|                     _isQos, _qoSProvider, _useCookieContainer, _allowAutoRedirect) | ||||
|                 .GetAwaiter() | ||||
|                 .GetResult(); | ||||
|         } | ||||
|  | ||||
|         private void ThenTheRequestContainsTheRequestMessage() | ||||
| @@ -52,5 +65,15 @@ | ||||
|         { | ||||
|             _response.Data.QosProvider.ShouldBe(_qoSProvider); | ||||
|         } | ||||
|  | ||||
|         private void ThenTheRequestContainsUseCookieContainer() | ||||
|         { | ||||
|             _response.Data.UseCookieContainer.ShouldBe(_useCookieContainer); | ||||
|         } | ||||
|  | ||||
|         private void ThenTheRequestContainsAllowAutoRedirect() | ||||
|         { | ||||
|             _response.Data.AllowAutoRedirect.ShouldBe(_allowAutoRedirect); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -28,7 +28,7 @@ | ||||
|         [Fact] | ||||
|         public void should_call_scoped_data_repository_correctly() | ||||
|         { | ||||
|             this.Given(x => x.GivenTheRequestIs(new Ocelot.Request.Request(new HttpRequestMessage(),true, new NoQoSProvider()))) | ||||
|             this.Given(x => x.GivenTheRequestIs(new Ocelot.Request.Request(new HttpRequestMessage(),true, new NoQoSProvider(), false, false))) | ||||
|                 .And(x => x.GivenTheRequesterReturns(new HttpResponseMessage())) | ||||
|                 .And(x => x.GivenTheScopedRepoReturns()) | ||||
|                 .When(x => x.WhenICallTheMiddleware()) | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <packages> | ||||
|     <package id="Cake" version="0.17.0" /> | ||||
|     <package id="Cake" version="0.23.0" /> | ||||
| </packages> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Tom Pallister
					Tom Pallister