mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-11-04 20:10:50 +08:00 
			
		
		
		
	Merge branch 'develop' of https://github.com/geffzhang/Ocelot into develop
This commit is contained in:
		@@ -22,13 +22,13 @@
 | 
				
			|||||||
			"AuthenticationOptions": {
 | 
								"AuthenticationOptions": {
 | 
				
			||||||
				"Provider": "IdentityServer",
 | 
									"Provider": "IdentityServer",
 | 
				
			||||||
				"ProviderRootUrl": "http://localhost:52888",
 | 
									"ProviderRootUrl": "http://localhost:52888",
 | 
				
			||||||
				"ScopeName": "api",
 | 
									"ApiName": "api",
 | 
				
			||||||
				"AdditionalScopes": [
 | 
									"AllowedScopes": [
 | 
				
			||||||
					"openid",
 | 
										"openid",
 | 
				
			||||||
					"offline_access"
 | 
										"offline_access"
 | 
				
			||||||
				],
 | 
									],
 | 
				
			||||||
			# Required if using reference tokens
 | 
								# Required if using reference tokens
 | 
				
			||||||
				"ScopeSecret": "secret"
 | 
									"ApiSecret": "secret"
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			# WARNING - will overwrite any headers already in the request with these values.
 | 
								# WARNING - will overwrite any headers already in the request with these values.
 | 
				
			||||||
			# Ocelot will look in the user claims for the key in [] then return the value and save
 | 
								# Ocelot will look in the user claims for the key in [] then return the value and save
 | 
				
			||||||
 
 | 
				
			|||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@@ -19,11 +19,11 @@ namespace Ocelot.Authentication.Handler.Creator
 | 
				
			|||||||
            builder.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
 | 
					            builder.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                Authority = authOptions.ProviderRootUrl,
 | 
					                Authority = authOptions.ProviderRootUrl,
 | 
				
			||||||
                ApiName = authOptions.ScopeName,
 | 
					                ApiName = authOptions.ApiName,
 | 
				
			||||||
                RequireHttpsMetadata = authOptions.RequireHttps,
 | 
					                RequireHttpsMetadata = authOptions.RequireHttps,
 | 
				
			||||||
                AllowedScopes = authOptions.AdditionalScopes,
 | 
					                AllowedScopes = authOptions.AllowedScopes,
 | 
				
			||||||
                SupportedTokens = SupportedTokens.Both,
 | 
					                SupportedTokens = SupportedTokens.Both,
 | 
				
			||||||
                ApiSecret = authOptions.ScopeSecret
 | 
					                ApiSecret = authOptions.ApiSecret
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var authenticationNext = builder.Build();
 | 
					            var authenticationNext = builder.Build();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,22 +4,22 @@ namespace Ocelot.Configuration
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    public class AuthenticationOptions
 | 
					    public class AuthenticationOptions
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public AuthenticationOptions(string provider, string providerRootUrl, string scopeName, bool requireHttps, List<string> additionalScopes, string scopeSecret)
 | 
					        public AuthenticationOptions(string provider, string providerRootUrl, string apiName, bool requireHttps, List<string> allowedScopes, string apiSecret)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Provider = provider;
 | 
					            Provider = provider;
 | 
				
			||||||
            ProviderRootUrl = providerRootUrl;
 | 
					            ProviderRootUrl = providerRootUrl;
 | 
				
			||||||
            ScopeName = scopeName;
 | 
								ApiName = apiName;
 | 
				
			||||||
            RequireHttps = requireHttps;
 | 
					            RequireHttps = requireHttps;
 | 
				
			||||||
            AdditionalScopes = additionalScopes;
 | 
								AllowedScopes = allowedScopes;
 | 
				
			||||||
            ScopeSecret = scopeSecret;
 | 
					            ApiSecret = apiSecret;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public string Provider { get; private set; }
 | 
					        public string Provider { get; private set; }
 | 
				
			||||||
        public string ProviderRootUrl { get; private set; }
 | 
					        public string ProviderRootUrl { get; private set; }
 | 
				
			||||||
        public string ScopeName { get; private set; }
 | 
					        public string ApiName { get; private set; }
 | 
				
			||||||
        public string ScopeSecret { get; private set; }
 | 
					        public string ApiSecret { get; private set; }
 | 
				
			||||||
        public bool RequireHttps { get; private set; }
 | 
					        public bool RequireHttps { get; private set; }
 | 
				
			||||||
        public List<string> AdditionalScopes { get; private set; }
 | 
					        public List<string> AllowedScopes { get; private set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,10 +7,10 @@ namespace Ocelot.Configuration.Builder
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        private string _provider;
 | 
					        private string _provider;
 | 
				
			||||||
        private string _providerRootUrl;
 | 
					        private string _providerRootUrl;
 | 
				
			||||||
        private string _scopeName;
 | 
					        private string _apiName;
 | 
				
			||||||
        private string _scopeSecret;
 | 
					        private string _apiSecret;
 | 
				
			||||||
        private bool _requireHttps;
 | 
					        private bool _requireHttps;
 | 
				
			||||||
        private List<string> _additionalScopes;
 | 
					        private List<string> _allowedScopes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public AuthenticationOptionsBuilder WithProvider(string provider)
 | 
					        public AuthenticationOptionsBuilder WithProvider(string provider)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@@ -24,15 +24,15 @@ namespace Ocelot.Configuration.Builder
 | 
				
			|||||||
            return this;
 | 
					            return this;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public AuthenticationOptionsBuilder WithScopeName(string scopeName)
 | 
					        public AuthenticationOptionsBuilder WithApiName(string apiName)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _scopeName = scopeName;
 | 
					            _apiName = apiName;
 | 
				
			||||||
            return this;
 | 
					            return this;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public AuthenticationOptionsBuilder WithScopeSecret(string scopeSecret)
 | 
					        public AuthenticationOptionsBuilder WithApiSecret(string apiSecret)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _scopeSecret = scopeSecret;
 | 
					            _apiSecret = apiSecret;
 | 
				
			||||||
            return this;
 | 
					            return this;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -42,15 +42,15 @@ namespace Ocelot.Configuration.Builder
 | 
				
			|||||||
            return this;
 | 
					            return this;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public AuthenticationOptionsBuilder WithAdditionalScopes(List<string> additionalScopes)
 | 
					        public AuthenticationOptionsBuilder WithAllowedScopes(List<string> allowedScopes)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _additionalScopes = additionalScopes;
 | 
					            _allowedScopes = allowedScopes;
 | 
				
			||||||
            return this;
 | 
					            return this;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public AuthenticationOptions Build()
 | 
					        public AuthenticationOptions Build()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return new AuthenticationOptions(_provider, _providerRootUrl, _scopeName, _requireHttps, _additionalScopes, _scopeSecret);
 | 
					            return new AuthenticationOptions(_provider, _providerRootUrl, _apiName, _requireHttps, _allowedScopes, _apiSecret);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -10,10 +10,10 @@ namespace Ocelot.Configuration.Creator
 | 
				
			|||||||
            return new AuthenticationOptionsBuilder()
 | 
					            return new AuthenticationOptionsBuilder()
 | 
				
			||||||
                                        .WithProvider(fileReRoute.AuthenticationOptions?.Provider)
 | 
					                                        .WithProvider(fileReRoute.AuthenticationOptions?.Provider)
 | 
				
			||||||
                                        .WithProviderRootUrl(fileReRoute.AuthenticationOptions?.ProviderRootUrl)
 | 
					                                        .WithProviderRootUrl(fileReRoute.AuthenticationOptions?.ProviderRootUrl)
 | 
				
			||||||
                                        .WithScopeName(fileReRoute.AuthenticationOptions?.ScopeName)
 | 
					                                        .WithApiName(fileReRoute.AuthenticationOptions?.ApiName)
 | 
				
			||||||
                                        .WithRequireHttps(fileReRoute.AuthenticationOptions.RequireHttps)
 | 
					                                        .WithRequireHttps(fileReRoute.AuthenticationOptions.RequireHttps)
 | 
				
			||||||
                                        .WithAdditionalScopes(fileReRoute.AuthenticationOptions?.AdditionalScopes)
 | 
					                                        .WithAllowedScopes(fileReRoute.AuthenticationOptions?.AllowedScopes)
 | 
				
			||||||
                                        .WithScopeSecret(fileReRoute.AuthenticationOptions?.ScopeSecret)
 | 
					                                        .WithApiSecret(fileReRoute.AuthenticationOptions?.ApiSecret)
 | 
				
			||||||
                                        .Build();
 | 
					                                        .Build();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,14 +6,14 @@ namespace Ocelot.Configuration.File
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        public FileAuthenticationOptions()
 | 
					        public FileAuthenticationOptions()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            AdditionalScopes = new List<string>();
 | 
								AllowedScopes = new List<string>();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public string Provider { get; set; }
 | 
					        public string Provider { get; set; }
 | 
				
			||||||
        public string ProviderRootUrl { get; set; }
 | 
					        public string ProviderRootUrl { get; set; }
 | 
				
			||||||
        public string ScopeName { get; set; }
 | 
					        public string ApiName { get; set; }
 | 
				
			||||||
        public bool RequireHttps { get; set; }
 | 
					        public bool RequireHttps { get; set; }
 | 
				
			||||||
        public List<string> AdditionalScopes { get; set; }
 | 
					        public List<string> AllowedScopes { get; set; }
 | 
				
			||||||
        public string ScopeSecret { get; set; }
 | 
					        public string ApiSecret { get; set; }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,7 +25,7 @@ namespace Ocelot.DownstreamRouteFinder.Finder
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            var configuration = _configProvider.Get();
 | 
					            var configuration = _configProvider.Get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var applicableReRoutes = configuration.Data.ReRoutes.Where(r => string.Equals(r.UpstreamHttpMethod.Method, upstreamHttpMethod, StringComparison.CurrentCultureIgnoreCase));
 | 
					            var applicableReRoutes = configuration.Data.ReRoutes.Where(r => string.Equals(r.UpstreamHttpMethod.Method.ToLower(), upstreamHttpMethod.ToLower(), StringComparison.CurrentCultureIgnoreCase));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            foreach (var reRoute in applicableReRoutes)
 | 
					            foreach (var reRoute in applicableReRoutes)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,17 +1,16 @@
 | 
				
			|||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
using Ocelot.Errors;
 | 
					using Ocelot.Errors;
 | 
				
			||||||
using Ocelot.Responses;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Ocelot.Responder
 | 
					namespace Ocelot.Responder
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public class ErrorsToHttpStatusCodeMapper : IErrorsToHttpStatusCodeMapper
 | 
					    public class ErrorsToHttpStatusCodeMapper : IErrorsToHttpStatusCodeMapper
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public Response<int> Map(List<Error> errors)
 | 
					        public int Map(List<Error> errors)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (errors.Any(e => e.Code == OcelotErrorCode.UnauthenticatedError))
 | 
					            if (errors.Any(e => e.Code == OcelotErrorCode.UnauthenticatedError))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                return new OkResponse<int>(401);
 | 
					                return 401;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (errors.Any(e => e.Code == OcelotErrorCode.UnauthorizedError 
 | 
					            if (errors.Any(e => e.Code == OcelotErrorCode.UnauthorizedError 
 | 
				
			||||||
@@ -19,15 +18,15 @@ namespace Ocelot.Responder
 | 
				
			|||||||
                || e.Code == OcelotErrorCode.UserDoesNotHaveClaimError
 | 
					                || e.Code == OcelotErrorCode.UserDoesNotHaveClaimError
 | 
				
			||||||
                || e.Code == OcelotErrorCode.CannotFindClaimError))
 | 
					                || e.Code == OcelotErrorCode.CannotFindClaimError))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                return new OkResponse<int>(403);
 | 
					                return 403;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (errors.Any(e => e.Code == OcelotErrorCode.RequestTimedOutError))
 | 
					            if (errors.Any(e => e.Code == OcelotErrorCode.RequestTimedOutError))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                return new OkResponse<int>(503);
 | 
					                return 503;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return new OkResponse<int>(404);
 | 
					            return 404;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1,11 +1,13 @@
 | 
				
			|||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using Ocelot.Errors;
 | 
					using Ocelot.Errors;
 | 
				
			||||||
using Ocelot.Responses;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Ocelot.Responder
 | 
					namespace Ocelot.Responder
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Map a list OceoltErrors to a single appropriate HTTP status code
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
    public interface IErrorsToHttpStatusCodeMapper
 | 
					    public interface IErrorsToHttpStatusCodeMapper
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Response<int> Map(List<Error> errors);
 | 
					        int Map(List<Error> errors);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,12 +16,12 @@ namespace Ocelot.Responder.Middleware
 | 
				
			|||||||
        private readonly IErrorsToHttpStatusCodeMapper _codeMapper;
 | 
					        private readonly IErrorsToHttpStatusCodeMapper _codeMapper;
 | 
				
			||||||
        private readonly IOcelotLogger _logger;
 | 
					        private readonly IOcelotLogger _logger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public ResponderMiddleware(RequestDelegate next, 
 | 
					        public ResponderMiddleware(RequestDelegate next,
 | 
				
			||||||
            IHttpResponder responder,
 | 
					            IHttpResponder responder,
 | 
				
			||||||
            IOcelotLoggerFactory loggerFactory,
 | 
					            IOcelotLoggerFactory loggerFactory,
 | 
				
			||||||
            IRequestScopedDataRepository requestScopedDataRepository, 
 | 
					            IRequestScopedDataRepository requestScopedDataRepository,
 | 
				
			||||||
            IErrorsToHttpStatusCodeMapper codeMapper)
 | 
					            IErrorsToHttpStatusCodeMapper codeMapper)
 | 
				
			||||||
            :base(requestScopedDataRepository)
 | 
					            : base(requestScopedDataRepository)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _next = next;
 | 
					            _next = next;
 | 
				
			||||||
            _responder = responder;
 | 
					            _responder = responder;
 | 
				
			||||||
@@ -58,16 +58,9 @@ namespace Ocelot.Responder.Middleware
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        private void SetErrorResponse(HttpContext context, List<Error> errors)
 | 
					        private void SetErrorResponse(HttpContext context, List<Error> errors)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var statusCode = _codeMapper.Map(errors);
 | 
					            var statusCode = _codeMapper.Map(errors);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (!statusCode.IsError)
 | 
					            _responder.SetErrorResponseOnContext(context, statusCode);
 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                _responder.SetErrorResponseOnContext(context, statusCode.Data);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                _responder.SetErrorResponseOnContext(context, 500);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -51,12 +51,12 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                            UpstreamHttpMethod = "Post",
 | 
					                            UpstreamHttpMethod = "Post",
 | 
				
			||||||
                            AuthenticationOptions = new FileAuthenticationOptions
 | 
					                            AuthenticationOptions = new FileAuthenticationOptions
 | 
				
			||||||
                            {
 | 
					                            {
 | 
				
			||||||
                                AdditionalScopes =  new List<string>(),
 | 
													AllowedScopes =  new List<string>(),
 | 
				
			||||||
                                Provider = "IdentityServer",
 | 
					                                Provider = "IdentityServer",
 | 
				
			||||||
                                ProviderRootUrl = _identityServerRootUrl,
 | 
					                                ProviderRootUrl = _identityServerRootUrl,
 | 
				
			||||||
                                RequireHttps = false,
 | 
					                                RequireHttps = false,
 | 
				
			||||||
                                ScopeName = "api",
 | 
													ApiName = "api",
 | 
				
			||||||
                                ScopeSecret = "secret"
 | 
					                                ApiSecret = "secret"
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
@@ -89,12 +89,12 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                            UpstreamHttpMethod = "Post",
 | 
					                            UpstreamHttpMethod = "Post",
 | 
				
			||||||
                            AuthenticationOptions = new FileAuthenticationOptions
 | 
					                            AuthenticationOptions = new FileAuthenticationOptions
 | 
				
			||||||
                            {
 | 
					                            {
 | 
				
			||||||
                                AdditionalScopes =  new List<string>(),
 | 
													AllowedScopes =  new List<string>(),
 | 
				
			||||||
                                Provider = "IdentityServer",
 | 
					                                Provider = "IdentityServer",
 | 
				
			||||||
                                ProviderRootUrl = _identityServerRootUrl,
 | 
					                                ProviderRootUrl = _identityServerRootUrl,
 | 
				
			||||||
                                RequireHttps = false,
 | 
					                                RequireHttps = false,
 | 
				
			||||||
                                ScopeName = "api",
 | 
													ApiName = "api",
 | 
				
			||||||
                                ScopeSecret = "secret"
 | 
					                                ApiSecret = "secret"
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
@@ -127,12 +127,12 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                            UpstreamHttpMethod = "Get",
 | 
					                            UpstreamHttpMethod = "Get",
 | 
				
			||||||
                            AuthenticationOptions = new FileAuthenticationOptions
 | 
					                            AuthenticationOptions = new FileAuthenticationOptions
 | 
				
			||||||
                            {
 | 
					                            {
 | 
				
			||||||
                                AdditionalScopes =  new List<string>(),
 | 
													AllowedScopes =  new List<string>(),
 | 
				
			||||||
                                Provider = "IdentityServer",
 | 
					                                Provider = "IdentityServer",
 | 
				
			||||||
                                ProviderRootUrl = _identityServerRootUrl,
 | 
					                                ProviderRootUrl = _identityServerRootUrl,
 | 
				
			||||||
                                RequireHttps = false,
 | 
					                                RequireHttps = false,
 | 
				
			||||||
                                ScopeName = "api",
 | 
													ApiName = "api",
 | 
				
			||||||
                                ScopeSecret = "secret"
 | 
					                                ApiSecret = "secret"
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
@@ -168,12 +168,12 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                            
 | 
					                            
 | 
				
			||||||
                            AuthenticationOptions = new FileAuthenticationOptions
 | 
					                            AuthenticationOptions = new FileAuthenticationOptions
 | 
				
			||||||
                            {
 | 
					                            {
 | 
				
			||||||
                                AdditionalScopes =  new List<string>(),
 | 
													AllowedScopes =  new List<string>(),
 | 
				
			||||||
                                Provider = "IdentityServer",
 | 
					                                Provider = "IdentityServer",
 | 
				
			||||||
                                ProviderRootUrl = _identityServerRootUrl,
 | 
					                                ProviderRootUrl = _identityServerRootUrl,
 | 
				
			||||||
                                RequireHttps = false,
 | 
					                                RequireHttps = false,
 | 
				
			||||||
                                ScopeName = "api",
 | 
													ApiName = "api",
 | 
				
			||||||
                                ScopeSecret = "secret"
 | 
					                                ApiSecret = "secret"
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
@@ -208,12 +208,12 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                            UpstreamHttpMethod = "Post",
 | 
					                            UpstreamHttpMethod = "Post",
 | 
				
			||||||
                             AuthenticationOptions = new FileAuthenticationOptions
 | 
					                             AuthenticationOptions = new FileAuthenticationOptions
 | 
				
			||||||
                            {
 | 
					                            {
 | 
				
			||||||
                                AdditionalScopes = new List<string>(),
 | 
													AllowedScopes = new List<string>(),
 | 
				
			||||||
                                Provider = "IdentityServer",
 | 
					                                Provider = "IdentityServer",
 | 
				
			||||||
                                ProviderRootUrl = _identityServerRootUrl,
 | 
					                                ProviderRootUrl = _identityServerRootUrl,
 | 
				
			||||||
                                RequireHttps = false,
 | 
					                                RequireHttps = false,
 | 
				
			||||||
                                ScopeName = "api",
 | 
													ApiName = "api",
 | 
				
			||||||
                                ScopeSecret = "secret"
 | 
					                                ApiSecret = "secret"
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
@@ -252,7 +252,7 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
            _servicebuilder.Start();
 | 
					            _servicebuilder.Start();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void GivenThereIsAnIdentityServerOn(string url, string scopeName, AccessTokenType tokenType)
 | 
					        private void GivenThereIsAnIdentityServerOn(string url, string apiName, AccessTokenType tokenType)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _identityServerBuilder = new WebHostBuilder()
 | 
					            _identityServerBuilder = new WebHostBuilder()
 | 
				
			||||||
                .UseUrls(url)
 | 
					                .UseUrls(url)
 | 
				
			||||||
@@ -269,7 +269,7 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            new ApiResource
 | 
					                            new ApiResource
 | 
				
			||||||
                            {
 | 
					                            {
 | 
				
			||||||
                                Name = scopeName,
 | 
					                                Name = apiName,
 | 
				
			||||||
                                Description = "My API",
 | 
					                                Description = "My API",
 | 
				
			||||||
                                Enabled = true,
 | 
					                                Enabled = true,
 | 
				
			||||||
                                DisplayName = "test",
 | 
					                                DisplayName = "test",
 | 
				
			||||||
@@ -299,7 +299,7 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                                ClientId = "client",
 | 
					                                ClientId = "client",
 | 
				
			||||||
                                AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
 | 
					                                AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
 | 
				
			||||||
                                ClientSecrets = new List<Secret> {new Secret("secret".Sha256())},
 | 
					                                ClientSecrets = new List<Secret> {new Secret("secret".Sha256())},
 | 
				
			||||||
                                AllowedScopes = new List<string> { scopeName, "openid", "offline_access" },
 | 
					                                AllowedScopes = new List<string> { apiName, "openid", "offline_access" },
 | 
				
			||||||
                                AccessTokenType = tokenType,
 | 
					                                AccessTokenType = tokenType,
 | 
				
			||||||
                                Enabled = true,
 | 
					                                Enabled = true,
 | 
				
			||||||
                                RequireClientSecret = false
 | 
					                                RequireClientSecret = false
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -45,12 +45,12 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                            UpstreamHttpMethod = "Get",
 | 
					                            UpstreamHttpMethod = "Get",
 | 
				
			||||||
                            AuthenticationOptions = new FileAuthenticationOptions
 | 
					                            AuthenticationOptions = new FileAuthenticationOptions
 | 
				
			||||||
                            {
 | 
					                            {
 | 
				
			||||||
                                AdditionalScopes =  new List<string>(),
 | 
													AllowedScopes =  new List<string>(),
 | 
				
			||||||
                                Provider = "IdentityServer",
 | 
					                                Provider = "IdentityServer",
 | 
				
			||||||
                                ProviderRootUrl = "http://localhost:51888",
 | 
					                                ProviderRootUrl = "http://localhost:51888",
 | 
				
			||||||
                                RequireHttps = false,
 | 
					                                RequireHttps = false,
 | 
				
			||||||
                                ScopeName = "api",
 | 
													ApiName = "api",
 | 
				
			||||||
                                ScopeSecret = "secret"
 | 
					                                ApiSecret = "secret"
 | 
				
			||||||
                            },
 | 
					                            },
 | 
				
			||||||
                            AddHeadersToRequest =
 | 
					                            AddHeadersToRequest =
 | 
				
			||||||
                            {
 | 
					                            {
 | 
				
			||||||
@@ -102,12 +102,12 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                            UpstreamHttpMethod = "Get",
 | 
					                            UpstreamHttpMethod = "Get",
 | 
				
			||||||
                            AuthenticationOptions = new FileAuthenticationOptions
 | 
					                            AuthenticationOptions = new FileAuthenticationOptions
 | 
				
			||||||
                            {
 | 
					                            {
 | 
				
			||||||
                                AdditionalScopes =  new List<string>(),
 | 
													AllowedScopes =  new List<string>(),
 | 
				
			||||||
                                Provider = "IdentityServer",
 | 
					                                Provider = "IdentityServer",
 | 
				
			||||||
                                ProviderRootUrl = "http://localhost:51888",
 | 
					                                ProviderRootUrl = "http://localhost:51888",
 | 
				
			||||||
                                RequireHttps = false,
 | 
					                                RequireHttps = false,
 | 
				
			||||||
                                ScopeName = "api",
 | 
													ApiName = "api",
 | 
				
			||||||
                                ScopeSecret = "secret"
 | 
					                                ApiSecret = "secret"
 | 
				
			||||||
                            },
 | 
					                            },
 | 
				
			||||||
                            AddHeadersToRequest =
 | 
					                            AddHeadersToRequest =
 | 
				
			||||||
                            {
 | 
					                            {
 | 
				
			||||||
@@ -161,7 +161,7 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
            _servicebuilder.Start();
 | 
					            _servicebuilder.Start();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void GivenThereIsAnIdentityServerOn(string url, string scopeName, AccessTokenType tokenType)
 | 
					        private void GivenThereIsAnIdentityServerOn(string url, string apiName, AccessTokenType tokenType)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _identityServerBuilder = new WebHostBuilder()
 | 
					            _identityServerBuilder = new WebHostBuilder()
 | 
				
			||||||
                .UseUrls(url)
 | 
					                .UseUrls(url)
 | 
				
			||||||
@@ -178,7 +178,7 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            new ApiResource
 | 
					                            new ApiResource
 | 
				
			||||||
                            {
 | 
					                            {
 | 
				
			||||||
                                Name = scopeName,
 | 
					                                Name = apiName,
 | 
				
			||||||
                                Description = "My API",
 | 
					                                Description = "My API",
 | 
				
			||||||
                                Enabled = true,
 | 
					                                Enabled = true,
 | 
				
			||||||
                                DisplayName = "test",
 | 
					                                DisplayName = "test",
 | 
				
			||||||
@@ -209,7 +209,7 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                                ClientId = "client",
 | 
					                                ClientId = "client",
 | 
				
			||||||
                                AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
 | 
					                                AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
 | 
				
			||||||
                                ClientSecrets = new List<Secret> {new Secret("secret".Sha256())},
 | 
					                                ClientSecrets = new List<Secret> {new Secret("secret".Sha256())},
 | 
				
			||||||
                                AllowedScopes = new List<string> { scopeName, "openid", "offline_access" },
 | 
					                                AllowedScopes = new List<string> { apiName, "openid", "offline_access" },
 | 
				
			||||||
                                AccessTokenType = tokenType,
 | 
					                                AccessTokenType = tokenType,
 | 
				
			||||||
                                Enabled = true,
 | 
					                                Enabled = true,
 | 
				
			||||||
                                RequireClientSecret = false
 | 
					                                RequireClientSecret = false
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -59,15 +59,15 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                            UpstreamHttpMethod = "Get",
 | 
					                            UpstreamHttpMethod = "Get",
 | 
				
			||||||
                            AuthenticationOptions = new FileAuthenticationOptions
 | 
					                            AuthenticationOptions = new FileAuthenticationOptions
 | 
				
			||||||
                            {
 | 
					                            {
 | 
				
			||||||
                                AdditionalScopes = new List<string>
 | 
													AllowedScopes = new List<string>
 | 
				
			||||||
                                {
 | 
					                                {
 | 
				
			||||||
                                    "openid", "offline_access"
 | 
					                                    "openid", "offline_access"
 | 
				
			||||||
                                },
 | 
					                                },
 | 
				
			||||||
                                Provider = "IdentityServer",
 | 
					                                Provider = "IdentityServer",
 | 
				
			||||||
                                ProviderRootUrl = "http://localhost:52888",
 | 
					                                ProviderRootUrl = "http://localhost:52888",
 | 
				
			||||||
                                RequireHttps = false,
 | 
					                                RequireHttps = false,
 | 
				
			||||||
                                ScopeName = "api",
 | 
													ApiName = "api",
 | 
				
			||||||
                                ScopeSecret = "secret",
 | 
					                                ApiSecret = "secret",
 | 
				
			||||||
                            },
 | 
					                            },
 | 
				
			||||||
                            AddHeadersToRequest =
 | 
					                            AddHeadersToRequest =
 | 
				
			||||||
                            {
 | 
					                            {
 | 
				
			||||||
@@ -119,7 +119,7 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
            _servicebuilder.Start();
 | 
					            _servicebuilder.Start();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void GivenThereIsAnIdentityServerOn(string url, string scopeName, AccessTokenType tokenType, TestUser user)
 | 
					        private void GivenThereIsAnIdentityServerOn(string url, string apiName, AccessTokenType tokenType, TestUser user)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _identityServerBuilder = new WebHostBuilder()
 | 
					            _identityServerBuilder = new WebHostBuilder()
 | 
				
			||||||
                .UseUrls(url)
 | 
					                .UseUrls(url)
 | 
				
			||||||
@@ -136,7 +136,7 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            new ApiResource
 | 
					                            new ApiResource
 | 
				
			||||||
                            {
 | 
					                            {
 | 
				
			||||||
                                Name = scopeName,
 | 
					                                Name = apiName,
 | 
				
			||||||
                                Description = "My API",
 | 
					                                Description = "My API",
 | 
				
			||||||
                                Enabled = true,
 | 
					                                Enabled = true,
 | 
				
			||||||
                                DisplayName = "test",
 | 
					                                DisplayName = "test",
 | 
				
			||||||
@@ -166,7 +166,7 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                                ClientId = "client",
 | 
					                                ClientId = "client",
 | 
				
			||||||
                                AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
 | 
					                                AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
 | 
				
			||||||
                                ClientSecrets = new List<Secret> {new Secret("secret".Sha256())},
 | 
					                                ClientSecrets = new List<Secret> {new Secret("secret".Sha256())},
 | 
				
			||||||
                                AllowedScopes = new List<string> { scopeName, "openid", "offline_access" },
 | 
					                                AllowedScopes = new List<string> { apiName, "openid", "offline_access" },
 | 
				
			||||||
                                AccessTokenType = tokenType,
 | 
					                                AccessTokenType = tokenType,
 | 
				
			||||||
                                Enabled = true,
 | 
					                                Enabled = true,
 | 
				
			||||||
                                RequireClientSecret = false
 | 
					                                RequireClientSecret = false
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -59,15 +59,15 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                            UpstreamHttpMethod = "Get",
 | 
					                            UpstreamHttpMethod = "Get",
 | 
				
			||||||
                            AuthenticationOptions = new FileAuthenticationOptions
 | 
					                            AuthenticationOptions = new FileAuthenticationOptions
 | 
				
			||||||
                            {
 | 
					                            {
 | 
				
			||||||
                                AdditionalScopes = new List<string>
 | 
													AllowedScopes = new List<string>
 | 
				
			||||||
                                {
 | 
					                                {
 | 
				
			||||||
                                    "openid", "offline_access"
 | 
					                                    "openid", "offline_access"
 | 
				
			||||||
                                },
 | 
					                                },
 | 
				
			||||||
                                Provider = "IdentityServer",
 | 
					                                Provider = "IdentityServer",
 | 
				
			||||||
                                ProviderRootUrl = "http://localhost:57888",
 | 
					                                ProviderRootUrl = "http://localhost:57888",
 | 
				
			||||||
                                RequireHttps = false,
 | 
					                                RequireHttps = false,
 | 
				
			||||||
                                ScopeName = "api",
 | 
													ApiName = "api",
 | 
				
			||||||
                                ScopeSecret = "secret",
 | 
					                                ApiSecret = "secret",
 | 
				
			||||||
                            },
 | 
					                            },
 | 
				
			||||||
                            AddQueriesToRequest =
 | 
					                            AddQueriesToRequest =
 | 
				
			||||||
                            {
 | 
					                            {
 | 
				
			||||||
@@ -126,7 +126,7 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
            _servicebuilder.Start();
 | 
					            _servicebuilder.Start();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void GivenThereIsAnIdentityServerOn(string url, string scopeName, AccessTokenType tokenType, TestUser user)
 | 
					        private void GivenThereIsAnIdentityServerOn(string url, string apiName, AccessTokenType tokenType, TestUser user)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _identityServerBuilder = new WebHostBuilder()
 | 
					            _identityServerBuilder = new WebHostBuilder()
 | 
				
			||||||
                .UseUrls(url)
 | 
					                .UseUrls(url)
 | 
				
			||||||
@@ -143,7 +143,7 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            new ApiResource
 | 
					                            new ApiResource
 | 
				
			||||||
                            {
 | 
					                            {
 | 
				
			||||||
                              Name = scopeName,
 | 
													Name = apiName,
 | 
				
			||||||
                                Description = "My API",
 | 
					                                Description = "My API",
 | 
				
			||||||
                                Enabled = true,
 | 
					                                Enabled = true,
 | 
				
			||||||
                                DisplayName = "test",
 | 
					                                DisplayName = "test",
 | 
				
			||||||
@@ -173,7 +173,7 @@ namespace Ocelot.AcceptanceTests
 | 
				
			|||||||
                                ClientId = "client",
 | 
					                                ClientId = "client",
 | 
				
			||||||
                                AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
 | 
					                                AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
 | 
				
			||||||
                                ClientSecrets = new List<Secret> {new Secret("secret".Sha256())},
 | 
					                                ClientSecrets = new List<Secret> {new Secret("secret".Sha256())},
 | 
				
			||||||
                                AllowedScopes = new List<string> { scopeName, "openid", "offline_access" },
 | 
					                                AllowedScopes = new List<string> { apiName, "openid", "offline_access" },
 | 
				
			||||||
                                AccessTokenType = tokenType,
 | 
					                                AccessTokenType = tokenType,
 | 
				
			||||||
                                Enabled = true,
 | 
					                                Enabled = true,
 | 
				
			||||||
                                RequireClientSecret = false
 | 
					                                RequireClientSecret = false
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,7 @@
 | 
				
			|||||||
    <VersionPrefix>0.0.0-dev</VersionPrefix>
 | 
					    <VersionPrefix>0.0.0-dev</VersionPrefix>
 | 
				
			||||||
    <TargetFramework>netcoreapp1.1</TargetFramework>
 | 
					    <TargetFramework>netcoreapp1.1</TargetFramework>
 | 
				
			||||||
    <AssemblyName>Ocelot.AcceptanceTests</AssemblyName>
 | 
					    <AssemblyName>Ocelot.AcceptanceTests</AssemblyName>
 | 
				
			||||||
 | 
					    <OutputType>Exe</OutputType>
 | 
				
			||||||
    <PackageId>Ocelot.AcceptanceTests</PackageId>
 | 
					    <PackageId>Ocelot.AcceptanceTests</PackageId>
 | 
				
			||||||
    <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
 | 
					    <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
 | 
				
			||||||
    <RuntimeIdentifiers>osx.10.11-x64;osx.10.12-x64;win7-x64;win10-x64</RuntimeIdentifiers>
 | 
					    <RuntimeIdentifiers>osx.10.11-x64;osx.10.12-x64;win7-x64;win10-x64</RuntimeIdentifiers>
 | 
				
			||||||
@@ -24,6 +25,10 @@
 | 
				
			|||||||
    <ProjectReference Include="..\Ocelot.ManualTest\Ocelot.ManualTest.csproj" />
 | 
					    <ProjectReference Include="..\Ocelot.ManualTest\Ocelot.ManualTest.csproj" />
 | 
				
			||||||
  </ItemGroup>
 | 
					  </ItemGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <ItemGroup>
 | 
				
			||||||
 | 
					  <Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
 | 
				
			||||||
 | 
					</ItemGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <ItemGroup>
 | 
					  <ItemGroup>
 | 
				
			||||||
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0-preview-20170106-08" />
 | 
					    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0-preview-20170106-08" />
 | 
				
			||||||
    <PackageReference Include="xunit.runner.visualstudio" Version="2.2.0-beta5-build1225" />
 | 
					    <PackageReference Include="xunit.runner.visualstudio" Version="2.2.0-beta5-build1225" />
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1 +1 @@
 | 
				
			|||||||
{"ReRoutes":[{"DownstreamPathTemplate":"41879/","UpstreamPathTemplate":"/","UpstreamHttpMethod":"Get","AuthenticationOptions":{"Provider":null,"ProviderRootUrl":null,"ScopeName":null,"RequireHttps":false,"AdditionalScopes":[],"ScopeSecret":null},"AddHeadersToRequest":{},"AddClaimsToRequest":{},"RouteClaimsRequirement":{},"AddQueriesToRequest":{},"RequestIdKey":null,"FileCacheOptions":{"TtlSeconds":0},"ReRouteIsCaseSensitive":false,"ServiceName":null,"DownstreamScheme":"http","DownstreamHost":"localhost","DownstreamPort":41879,"QoSOptions":{"ExceptionsAllowedBeforeBreaking":0,"DurationOfBreak":0,"TimeoutValue":0},"LoadBalancer":null,"RateLimitOptions":{"ClientWhitelist":[],"EnableRateLimiting":false,"Period":null,"PeriodTimespan":0.0,"Limit":0}}],"GlobalConfiguration":{"RequestIdKey":null,"ServiceDiscoveryProvider":{"Provider":null,"Host":null,"Port":0},"AdministrationPath":null,"RateLimitOptions":{"ClientIdHeader":"ClientId","QuotaExceededMessage":null,"RateLimitCounterPrefix":"ocelot","DisableRateLimitHeaders":false,"HttpStatusCode":429}}}
 | 
					{"ReRoutes":[{"DownstreamPathTemplate":"41879/","UpstreamPathTemplate":"/","UpstreamHttpMethod":"Get","AuthenticationOptions":{"Provider":null,"ProviderRootUrl":null,"ApiName":null,"RequireHttps":false,"AllowedScopes":[],"ApiSecret":null},"AddHeadersToRequest":{},"AddClaimsToRequest":{},"RouteClaimsRequirement":{},"AddQueriesToRequest":{},"RequestIdKey":null,"FileCacheOptions":{"TtlSeconds":0},"ReRouteIsCaseSensitive":false,"ServiceName":null,"DownstreamScheme":"http","DownstreamHost":"localhost","DownstreamPort":41879,"QoSOptions":{"ExceptionsAllowedBeforeBreaking":0,"DurationOfBreak":0,"TimeoutValue":0},"LoadBalancer":null,"RateLimitOptions":{"ClientWhitelist":[],"EnableRateLimiting":false,"Period":null,"PeriodTimespan":0.0,"Limit":0}}],"GlobalConfiguration":{"RequestIdKey":null,"ServiceDiscoveryProvider":{"Provider":null,"Host":null,"Port":0},"AdministrationPath":null,"RateLimitOptions":{"ClientIdHeader":"ClientId","QuotaExceededMessage":null,"RateLimitCounterPrefix":"ocelot","DisableRateLimitHeaders":false,"HttpStatusCode":429}}}
 | 
				
			||||||
@@ -4,6 +4,7 @@
 | 
				
			|||||||
    <VersionPrefix>0.0.0-dev</VersionPrefix>
 | 
					    <VersionPrefix>0.0.0-dev</VersionPrefix>
 | 
				
			||||||
    <TargetFramework>netcoreapp1.1</TargetFramework>
 | 
					    <TargetFramework>netcoreapp1.1</TargetFramework>
 | 
				
			||||||
    <AssemblyName>Ocelot.IntegrationTests</AssemblyName>
 | 
					    <AssemblyName>Ocelot.IntegrationTests</AssemblyName>
 | 
				
			||||||
 | 
					    <OutputType>Exe</OutputType>
 | 
				
			||||||
    <PackageId>Ocelot.IntegrationTests</PackageId>
 | 
					    <PackageId>Ocelot.IntegrationTests</PackageId>
 | 
				
			||||||
    <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
 | 
					    <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
 | 
				
			||||||
    <RuntimeIdentifiers>win10-x64;osx.10.11-x64;osx.10.12-x64;win7-x64</RuntimeIdentifiers>
 | 
					    <RuntimeIdentifiers>win10-x64;osx.10.11-x64;osx.10.12-x64;win7-x64</RuntimeIdentifiers>
 | 
				
			||||||
@@ -19,6 +20,10 @@
 | 
				
			|||||||
    </None>
 | 
					    </None>
 | 
				
			||||||
  </ItemGroup>
 | 
					  </ItemGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <ItemGroup>
 | 
				
			||||||
 | 
					  <Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
 | 
				
			||||||
 | 
					  </ItemGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <ItemGroup>
 | 
					  <ItemGroup>
 | 
				
			||||||
    <ProjectReference Include="..\..\src\Ocelot\Ocelot.csproj" />
 | 
					    <ProjectReference Include="..\..\src\Ocelot\Ocelot.csproj" />
 | 
				
			||||||
    <ProjectReference Include="..\Ocelot.ManualTest\Ocelot.ManualTest.csproj" />
 | 
					    <ProjectReference Include="..\Ocelot.ManualTest\Ocelot.ManualTest.csproj" />
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1 +1 @@
 | 
				
			|||||||
{"ReRoutes":[{"DownstreamPathTemplate":"/","UpstreamPathTemplate":"/","UpstreamHttpMethod":"Get","AuthenticationOptions":{"Provider":null,"ProviderRootUrl":null,"ScopeName":null,"RequireHttps":false,"AdditionalScopes":[],"ScopeSecret":null},"AddHeadersToRequest":{},"AddClaimsToRequest":{},"RouteClaimsRequirement":{},"AddQueriesToRequest":{},"RequestIdKey":null,"FileCacheOptions":{"TtlSeconds":0},"ReRouteIsCaseSensitive":false,"ServiceName":null,"DownstreamScheme":"http","DownstreamHost":"localhost","DownstreamPort":51879,"QoSOptions":{"ExceptionsAllowedBeforeBreaking":0,"DurationOfBreak":0,"TimeoutValue":0},"LoadBalancer":null,"RateLimitOptions":{"ClientWhitelist":[],"EnableRateLimiting":false,"Period":null,"PeriodTimespan":0.0,"Limit":0}}],"GlobalConfiguration":{"RequestIdKey":null,"ServiceDiscoveryProvider":{"Provider":null,"Host":null,"Port":0},"AdministrationPath":null,"RateLimitOptions":{"ClientIdHeader":"ClientId","QuotaExceededMessage":null,"RateLimitCounterPrefix":"ocelot","DisableRateLimitHeaders":false,"HttpStatusCode":429}}}
 | 
					{"ReRoutes":[{"DownstreamPathTemplate":"/","UpstreamPathTemplate":"/","UpstreamHttpMethod":"Get","AuthenticationOptions":{"Provider":null,"ProviderRootUrl":null,"ApiName":null,"RequireHttps":false,"AllowedScopes":[],"ApiSecret":null},"AddHeadersToRequest":{},"AddClaimsToRequest":{},"RouteClaimsRequirement":{},"AddQueriesToRequest":{},"RequestIdKey":null,"FileCacheOptions":{"TtlSeconds":0},"ReRouteIsCaseSensitive":false,"ServiceName":null,"DownstreamScheme":"http","DownstreamHost":"localhost","DownstreamPort":51879,"QoSOptions":{"ExceptionsAllowedBeforeBreaking":0,"DurationOfBreak":0,"TimeoutValue":0},"LoadBalancer":null,"RateLimitOptions":{"ClientWhitelist":[],"EnableRateLimiting":false,"Period":null,"PeriodTimespan":0.0,"Limit":0}}],"GlobalConfiguration":{"RequestIdKey":null,"ServiceDiscoveryProvider":{"Provider":null,"Host":null,"Port":0},"AdministrationPath":null,"RateLimitOptions":{"ClientIdHeader":"ClientId","QuotaExceededMessage":null,"RateLimitCounterPrefix":"ocelot","DisableRateLimitHeaders":false,"HttpStatusCode":429}}}
 | 
				
			||||||
@@ -15,12 +15,12 @@
 | 
				
			|||||||
            "AuthenticationOptions": {
 | 
					            "AuthenticationOptions": {
 | 
				
			||||||
                "Provider": "IdentityServer",
 | 
					                "Provider": "IdentityServer",
 | 
				
			||||||
                "ProviderRootUrl": "http://localhost:52888",
 | 
					                "ProviderRootUrl": "http://localhost:52888",
 | 
				
			||||||
                "ScopeName": "api",
 | 
					                "ApiName": "api",
 | 
				
			||||||
                "AdditionalScopes": [
 | 
					                "AllowedScopes": [
 | 
				
			||||||
                    "openid",
 | 
					                    "openid",
 | 
				
			||||||
                    "offline_access"
 | 
					                    "offline_access"
 | 
				
			||||||
                ],
 | 
					                ],
 | 
				
			||||||
                "ScopeSecret": "secret"
 | 
					                "ApiSecret": "secret"
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            "AddHeadersToRequest": {
 | 
					            "AddHeadersToRequest": {
 | 
				
			||||||
                "CustomerId": "Claims[CustomerId] > value",
 | 
					                "CustomerId": "Claims[CustomerId] > value",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,20 +29,20 @@ namespace Ocelot.UnitTests.Configuration
 | 
				
			|||||||
                {
 | 
					                {
 | 
				
			||||||
                    Provider = "Geoff",
 | 
					                    Provider = "Geoff",
 | 
				
			||||||
                    ProviderRootUrl = "http://www.bbc.co.uk/",
 | 
					                    ProviderRootUrl = "http://www.bbc.co.uk/",
 | 
				
			||||||
                    ScopeName = "Laura",
 | 
										ApiName = "Laura",
 | 
				
			||||||
                    RequireHttps = true,
 | 
					                    RequireHttps = true,
 | 
				
			||||||
                    AdditionalScopes = new List<string> {"cheese"},
 | 
										AllowedScopes = new List<string> {"cheese"},
 | 
				
			||||||
                    ScopeSecret = "secret"
 | 
					                    ApiSecret = "secret"
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var expected = new AuthenticationOptionsBuilder()
 | 
					            var expected = new AuthenticationOptionsBuilder()
 | 
				
			||||||
                    .WithProvider(fileReRoute.AuthenticationOptions?.Provider)
 | 
					                    .WithProvider(fileReRoute.AuthenticationOptions?.Provider)
 | 
				
			||||||
                    .WithProviderRootUrl(fileReRoute.AuthenticationOptions?.ProviderRootUrl)
 | 
					                    .WithProviderRootUrl(fileReRoute.AuthenticationOptions?.ProviderRootUrl)
 | 
				
			||||||
                    .WithScopeName(fileReRoute.AuthenticationOptions?.ScopeName)
 | 
					                    .WithApiName(fileReRoute.AuthenticationOptions?.ApiName)
 | 
				
			||||||
                    .WithRequireHttps(fileReRoute.AuthenticationOptions.RequireHttps)
 | 
					                    .WithRequireHttps(fileReRoute.AuthenticationOptions.RequireHttps)
 | 
				
			||||||
                    .WithAdditionalScopes(fileReRoute.AuthenticationOptions?.AdditionalScopes)
 | 
					                    .WithAllowedScopes(fileReRoute.AuthenticationOptions?.AllowedScopes)
 | 
				
			||||||
                    .WithScopeSecret(fileReRoute.AuthenticationOptions?.ScopeSecret)
 | 
					                    .WithApiSecret(fileReRoute.AuthenticationOptions?.ApiSecret)
 | 
				
			||||||
                    .Build();
 | 
					                    .Build();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            this.Given(x => x.GivenTheFollowing(fileReRoute))
 | 
					            this.Given(x => x.GivenTheFollowing(fileReRoute))
 | 
				
			||||||
@@ -63,12 +63,12 @@ namespace Ocelot.UnitTests.Configuration
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        private void ThenTheFollowingIsReturned(AuthenticationOptions expected)
 | 
					        private void ThenTheFollowingIsReturned(AuthenticationOptions expected)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _result.AdditionalScopes.ShouldBe(expected.AdditionalScopes);
 | 
					            _result.AllowedScopes.ShouldBe(expected.AllowedScopes);
 | 
				
			||||||
            _result.Provider.ShouldBe(expected.Provider);
 | 
					            _result.Provider.ShouldBe(expected.Provider);
 | 
				
			||||||
            _result.ProviderRootUrl.ShouldBe(expected.ProviderRootUrl);
 | 
					            _result.ProviderRootUrl.ShouldBe(expected.ProviderRootUrl);
 | 
				
			||||||
            _result.RequireHttps.ShouldBe(expected.RequireHttps);
 | 
					            _result.RequireHttps.ShouldBe(expected.RequireHttps);
 | 
				
			||||||
            _result.ScopeName.ShouldBe(expected.ScopeName);
 | 
					            _result.ApiName.ShouldBe(expected.ApiName);
 | 
				
			||||||
            _result.ScopeSecret.ShouldBe(expected.ScopeSecret);
 | 
					            _result.ApiSecret.ShouldBe(expected.ApiSecret);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -403,9 +403,9 @@ namespace Ocelot.UnitTests.Configuration
 | 
				
			|||||||
                    .WithProvider("IdentityServer")
 | 
					                    .WithProvider("IdentityServer")
 | 
				
			||||||
                    .WithProviderRootUrl("http://localhost:51888")
 | 
					                    .WithProviderRootUrl("http://localhost:51888")
 | 
				
			||||||
                    .WithRequireHttps(false)
 | 
					                    .WithRequireHttps(false)
 | 
				
			||||||
                    .WithScopeSecret("secret")
 | 
					                    .WithApiSecret("secret")
 | 
				
			||||||
                    .WithScopeName("api")
 | 
					                    .WithApiName("api")
 | 
				
			||||||
                    .WithAdditionalScopes(new List<string>())
 | 
					                    .WithAllowedScopes(new List<string>())
 | 
				
			||||||
                    .Build();
 | 
					                    .Build();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var expected = new List<ReRoute>
 | 
					            var expected = new List<ReRoute>
 | 
				
			||||||
@@ -434,12 +434,12 @@ namespace Ocelot.UnitTests.Configuration
 | 
				
			|||||||
                        ReRouteIsCaseSensitive = true,
 | 
					                        ReRouteIsCaseSensitive = true,
 | 
				
			||||||
                        AuthenticationOptions = new FileAuthenticationOptions
 | 
					                        AuthenticationOptions = new FileAuthenticationOptions
 | 
				
			||||||
                            {
 | 
					                            {
 | 
				
			||||||
                                AdditionalScopes =  new List<string>(),
 | 
													AllowedScopes=  new List<string>(),
 | 
				
			||||||
                                Provider = "IdentityServer",
 | 
					                                Provider = "IdentityServer",
 | 
				
			||||||
                                ProviderRootUrl = "http://localhost:51888",
 | 
					                                ProviderRootUrl = "http://localhost:51888",
 | 
				
			||||||
                                RequireHttps = false,
 | 
					                                RequireHttps = false,
 | 
				
			||||||
                                ScopeName = "api",
 | 
													ApiName= "api",
 | 
				
			||||||
                                ScopeSecret = "secret"
 | 
					                                ApiSecret = "secret"
 | 
				
			||||||
                            },
 | 
					                            },
 | 
				
			||||||
                        AddHeadersToRequest =
 | 
					                        AddHeadersToRequest =
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
@@ -471,9 +471,9 @@ namespace Ocelot.UnitTests.Configuration
 | 
				
			|||||||
                    .WithProvider("IdentityServer")
 | 
					                    .WithProvider("IdentityServer")
 | 
				
			||||||
                    .WithProviderRootUrl("http://localhost:51888")
 | 
					                    .WithProviderRootUrl("http://localhost:51888")
 | 
				
			||||||
                    .WithRequireHttps(false)
 | 
					                    .WithRequireHttps(false)
 | 
				
			||||||
                    .WithScopeSecret("secret")
 | 
					                    .WithApiSecret("secret")
 | 
				
			||||||
                    .WithScopeName("api")
 | 
					                    .WithApiName("api")
 | 
				
			||||||
                    .WithAdditionalScopes(new List<string>())
 | 
					                    .WithAllowedScopes(new List<string>())
 | 
				
			||||||
                    .Build();
 | 
					                    .Build();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var expected = new List<ReRoute>
 | 
					            var expected = new List<ReRoute>
 | 
				
			||||||
@@ -498,12 +498,12 @@ namespace Ocelot.UnitTests.Configuration
 | 
				
			|||||||
                        ReRouteIsCaseSensitive = true,
 | 
					                        ReRouteIsCaseSensitive = true,
 | 
				
			||||||
                        AuthenticationOptions = new FileAuthenticationOptions
 | 
					                        AuthenticationOptions = new FileAuthenticationOptions
 | 
				
			||||||
                            {
 | 
					                            {
 | 
				
			||||||
                                AdditionalScopes =  new List<string>(),
 | 
													AllowedScopes =  new List<string>(),
 | 
				
			||||||
                                Provider = "IdentityServer",
 | 
					                                Provider = "IdentityServer",
 | 
				
			||||||
                                ProviderRootUrl = "http://localhost:51888",
 | 
					                                ProviderRootUrl = "http://localhost:51888",
 | 
				
			||||||
                                RequireHttps = false,
 | 
					                                RequireHttps = false,
 | 
				
			||||||
                                ScopeName = "api",
 | 
													ApiName= "api",
 | 
				
			||||||
                                ScopeSecret = "secret"
 | 
					                                ApiSecret = "secret"
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@@ -592,12 +592,12 @@ namespace Ocelot.UnitTests.Configuration
 | 
				
			|||||||
                var result = _config.Data.ReRoutes[i].AuthenticationOptions;
 | 
					                var result = _config.Data.ReRoutes[i].AuthenticationOptions;
 | 
				
			||||||
                var expected = expectedReRoutes[i].AuthenticationOptions;
 | 
					                var expected = expectedReRoutes[i].AuthenticationOptions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                result.AdditionalScopes.ShouldBe(expected.AdditionalScopes);
 | 
					                result.AllowedScopes.ShouldBe(expected.AllowedScopes);
 | 
				
			||||||
                result.Provider.ShouldBe(expected.Provider);
 | 
					                result.Provider.ShouldBe(expected.Provider);
 | 
				
			||||||
                result.ProviderRootUrl.ShouldBe(expected.ProviderRootUrl);
 | 
					                result.ProviderRootUrl.ShouldBe(expected.ProviderRootUrl);
 | 
				
			||||||
                result.RequireHttps.ShouldBe(expected.RequireHttps);
 | 
					                result.RequireHttps.ShouldBe(expected.RequireHttps);
 | 
				
			||||||
                result.ScopeName.ShouldBe(expected.ScopeName);
 | 
					                result.ApiName.ShouldBe(expected.ApiName);
 | 
				
			||||||
                result.ScopeSecret.ShouldBe(expected.ScopeSecret);
 | 
					                result.ApiSecret.ShouldBe(expected.ApiSecret);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,7 @@
 | 
				
			|||||||
    <TargetFramework>netcoreapp1.1</TargetFramework>
 | 
					    <TargetFramework>netcoreapp1.1</TargetFramework>
 | 
				
			||||||
    <AssemblyName>Ocelot.UnitTests</AssemblyName>
 | 
					    <AssemblyName>Ocelot.UnitTests</AssemblyName>
 | 
				
			||||||
    <PackageId>Ocelot.UnitTests</PackageId>
 | 
					    <PackageId>Ocelot.UnitTests</PackageId>
 | 
				
			||||||
 | 
					    <OutputType>Exe</OutputType>
 | 
				
			||||||
    <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
 | 
					    <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
 | 
				
			||||||
    <RuntimeIdentifiers>osx.10.11-x64;osx.10.12-x64;win7-x64;win10-x64</RuntimeIdentifiers>
 | 
					    <RuntimeIdentifiers>osx.10.11-x64;osx.10.12-x64;win7-x64;win10-x64</RuntimeIdentifiers>
 | 
				
			||||||
    <RuntimeFrameworkVersion>1.1.1</RuntimeFrameworkVersion>
 | 
					    <RuntimeFrameworkVersion>1.1.1</RuntimeFrameworkVersion>
 | 
				
			||||||
@@ -17,6 +18,10 @@
 | 
				
			|||||||
    <ProjectReference Include="..\..\src\Ocelot\Ocelot.csproj" />
 | 
					    <ProjectReference Include="..\..\src\Ocelot\Ocelot.csproj" />
 | 
				
			||||||
  </ItemGroup>
 | 
					  </ItemGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <ItemGroup>
 | 
				
			||||||
 | 
					  <Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
 | 
				
			||||||
 | 
					  </ItemGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <ItemGroup>
 | 
					  <ItemGroup>
 | 
				
			||||||
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0-preview-20170106-08" />
 | 
					    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0-preview-20170106-08" />
 | 
				
			||||||
    <PackageReference Include="xunit.runner.visualstudio" Version="2.2.0-beta5-build1225" />
 | 
					    <PackageReference Include="xunit.runner.visualstudio" Version="2.2.0-beta5-build1225" />
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,6 @@ using Ocelot.Errors;
 | 
				
			|||||||
using Ocelot.Middleware;
 | 
					using Ocelot.Middleware;
 | 
				
			||||||
using Ocelot.Requester;
 | 
					using Ocelot.Requester;
 | 
				
			||||||
using Ocelot.Responder;
 | 
					using Ocelot.Responder;
 | 
				
			||||||
using Ocelot.Responses;
 | 
					 | 
				
			||||||
using Shouldly;
 | 
					using Shouldly;
 | 
				
			||||||
using TestStack.BDDfy;
 | 
					using TestStack.BDDfy;
 | 
				
			||||||
using Xunit;
 | 
					using Xunit;
 | 
				
			||||||
@@ -14,7 +13,7 @@ namespace Ocelot.UnitTests.Responder
 | 
				
			|||||||
    public class ErrorsToHttpStatusCodeMapperTests
 | 
					    public class ErrorsToHttpStatusCodeMapperTests
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        private readonly IErrorsToHttpStatusCodeMapper _codeMapper;
 | 
					        private readonly IErrorsToHttpStatusCodeMapper _codeMapper;
 | 
				
			||||||
        private Response<int> _result;
 | 
					        private int _result;
 | 
				
			||||||
        private List<Error> _errors;
 | 
					        private List<Error> _errors;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public ErrorsToHttpStatusCodeMapperTests()
 | 
					        public ErrorsToHttpStatusCodeMapperTests()
 | 
				
			||||||
@@ -77,7 +76,7 @@ namespace Ocelot.UnitTests.Responder
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        private void ThenTheResponseIsStatusCodeIs(int expectedCode)
 | 
					        private void ThenTheResponseIsStatusCodeIs(int expectedCode)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _result.Data.ShouldBe(expectedCode);
 | 
					            _result.ShouldBe(expectedCode);
 | 
				
			||||||
        }    
 | 
					        }    
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1 +1 @@
 | 
				
			|||||||
{"ReRoutes":[{"DownstreamPathTemplate":"/test/test/{test}","UpstreamPathTemplate":null,"UpstreamHttpMethod":null,"AuthenticationOptions":{"Provider":null,"ProviderRootUrl":null,"ScopeName":null,"RequireHttps":false,"AdditionalScopes":[],"ScopeSecret":null},"AddHeadersToRequest":{},"AddClaimsToRequest":{},"RouteClaimsRequirement":{},"AddQueriesToRequest":{},"RequestIdKey":null,"FileCacheOptions":{"TtlSeconds":0},"ReRouteIsCaseSensitive":false,"ServiceName":null,"DownstreamScheme":"https","DownstreamHost":"localhost","DownstreamPort":80,"QoSOptions":{"ExceptionsAllowedBeforeBreaking":0,"DurationOfBreak":0,"TimeoutValue":0},"LoadBalancer":null}],"GlobalConfiguration":{"RequestIdKey":null,"ServiceDiscoveryProvider":{"Provider":"consul","Host":"blah","Port":198},"AdministrationPath":"testy"}}
 | 
					{"ReRoutes":[{"DownstreamPathTemplate":"/test/test/{test}","UpstreamPathTemplate":null,"UpstreamHttpMethod":null,"AuthenticationOptions":{"Provider":null,"ProviderRootUrl":null,"ApiName":null,"RequireHttps":false,"AllowedScopes":[],"ApiSecret":null},"AddHeadersToRequest":{},"AddClaimsToRequest":{},"RouteClaimsRequirement":{},"AddQueriesToRequest":{},"RequestIdKey":null,"FileCacheOptions":{"TtlSeconds":0},"ReRouteIsCaseSensitive":false,"ServiceName":null,"DownstreamScheme":"https","DownstreamHost":"localhost","DownstreamPort":80,"QoSOptions":{"ExceptionsAllowedBeforeBreaking":0,"DurationOfBreak":0,"TimeoutValue":0},"LoadBalancer":null}],"GlobalConfiguration":{"RequestIdKey":null,"ServiceDiscoveryProvider":{"Provider":"consul","Host":"blah","Port":198},"AdministrationPath":"testy"}}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user