public async Task Proto_Added(string startValue, string scheme, ForwardedTransformActions action, string expected) { var randomFactory = new TestRandomFactory(); var httpContext = new DefaultHttpContext(); httpContext.Request.Scheme = scheme; var proxyRequest = new HttpRequestMessage(); proxyRequest.Headers.Add("Forwarded", startValue.Split("|", StringSplitOptions.RemoveEmptyEntries)); var transform = new RequestHeaderForwardedTransform(randomFactory, forFormat: NodeFormat.None, byFormat: NodeFormat.None, host: false, proto: true, action); await transform.ApplyAsync(new RequestTransformContext() { HttpContext = httpContext, ProxyRequest = proxyRequest, HeadersCopied = true, }); if (string.IsNullOrEmpty(expected)) { Assert.False(proxyRequest.Headers.TryGetValues("Forwarded", out _)); } else { Assert.Equal(expected.Split("|", StringSplitOptions.RemoveEmptyEntries), proxyRequest.Headers.GetValues("Forwarded")); } }
public async Task AllValues_Added(string startValue, ForwardedTransformActions action, string expected) { var randomFactory = new TestRandomFactory(); randomFactory.Instance = new TestRandom() { Sequence = new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 } }; var httpContext = new DefaultHttpContext(); httpContext.Request.Scheme = "https"; httpContext.Request.Host = new HostString("myHost", 80); httpContext.Connection.RemoteIpAddress = IPAddress.IPv6Loopback; httpContext.Connection.RemotePort = 10; var proxyRequest = new HttpRequestMessage(); proxyRequest.Headers.Add("Forwarded", startValue.Split("|", StringSplitOptions.RemoveEmptyEntries)); var transform = new RequestHeaderForwardedTransform(randomFactory, forFormat: NodeFormat.IpAndPort, byFormat: NodeFormat.Random, host: true, proto: true, action); await transform.ApplyAsync(new RequestTransformContext() { HttpContext = httpContext, ProxyRequest = proxyRequest, HeadersCopied = true, }); Assert.Equal(expected.Split("|", StringSplitOptions.RemoveEmptyEntries), proxyRequest.Headers.GetValues("Forwarded")); }
public async Task Scheme_Added(string startValue, string scheme, ForwardedTransformActions action, string expected) { var httpContext = new DefaultHttpContext(); httpContext.Request.Scheme = scheme; var proxyRequest = new HttpRequestMessage(); proxyRequest.Headers.Add("name", startValue.Split(";", StringSplitOptions.RemoveEmptyEntries)); var transform = new RequestHeaderXForwardedProtoTransform("name", action); await transform.ApplyAsync(new RequestTransformContext() { HttpContext = httpContext, ProxyRequest = proxyRequest, HeadersCopied = true, }); if (string.IsNullOrEmpty(expected)) { Assert.False(proxyRequest.Headers.TryGetValues("name", out var _)); } else { Assert.Equal(expected.Split(";", StringSplitOptions.RemoveEmptyEntries), proxyRequest.Headers.GetValues("name")); } }
public void AddXForwarded(Func <TransformBuilderContext, string, ForwardedTransformActions, TransformBuilderContext> addFunc, string transformName, ForwardedTransformActions action) { var builderContext = CreateBuilderContext(); addFunc(builderContext, "prefix-" + transformName, action); ValidateXForwarded(builderContext, transformName, "prefix-", action); }
public RequestHeaderForwardedTransform(IRandomFactory randomFactory, NodeFormat forFormat, NodeFormat byFormat, bool host, bool proto, ForwardedTransformActions action) { _randomFactory = randomFactory ?? throw new ArgumentNullException(nameof(randomFactory)); ForFormat = forFormat; ByFormat = byFormat; HostEnabled = host; ProtoEnabled = proto; Debug.Assert(action != ForwardedTransformActions.Off); TransformAction = action; }
public RequestHeaderXForwardedPrefixTransform(string headerName, ForwardedTransformActions action) { if (string.IsNullOrEmpty(headerName)) { throw new ArgumentException($"'{nameof(headerName)}' cannot be null or empty.", nameof(headerName)); } HeaderName = headerName; Debug.Assert(action != ForwardedTransformActions.Off); TransformAction = action; }
public void WithTransformXForwarded( ForwardedTransformActions xDefault, ForwardedTransformActions?xFor, ForwardedTransformActions?xHost, ForwardedTransformActions?xProto, ForwardedTransformActions?xPrefix) { var routeConfig = new RouteConfig(); var prefix = "prefix-"; routeConfig = routeConfig.WithTransformXForwarded(prefix, xDefault, xFor, xHost, xProto, xPrefix); var builderContext = ValidateAndBuild(routeConfig, _factory); if (xFor != ForwardedTransformActions.Off) { ValidateXForwardedTransform("For", prefix, xFor ?? xDefault, builderContext.RequestTransforms.OfType <RequestHeaderXForwardedForTransform>().Single()); } else { Assert.Empty(builderContext.RequestTransforms.OfType <RequestHeaderXForwardedForTransform>()); } if (xHost != ForwardedTransformActions.Off) { ValidateXForwardedTransform("Host", prefix, xHost ?? xDefault, builderContext.RequestTransforms.OfType <RequestHeaderXForwardedHostTransform>().Single()); } else { Assert.Empty(builderContext.RequestTransforms.OfType <RequestHeaderXForwardedHostTransform>()); } if (xProto != ForwardedTransformActions.Off) { ValidateXForwardedTransform("Proto", prefix, xProto ?? xDefault, builderContext.RequestTransforms.OfType <RequestHeaderXForwardedProtoTransform>().Single()); } else { Assert.Empty(builderContext.RequestTransforms.OfType <RequestHeaderXForwardedProtoTransform>()); } if (xPrefix != ForwardedTransformActions.Off) { ValidateXForwardedTransform("Prefix", prefix, xPrefix ?? xDefault, builderContext.RequestTransforms.OfType <RequestHeaderXForwardedPrefixTransform>().Single()); } else { Assert.Empty(builderContext.RequestTransforms.OfType <RequestHeaderXForwardedPrefixTransform>()); } }
/// <summary> /// Clones the route and adds the transform which will add X-Forwarded-* headers. /// </summary> public static RouteConfig WithTransformXForwarded( this RouteConfig route, string headerPrefix = "X-Forwarded-", ForwardedTransformActions xDefault = ForwardedTransformActions.Set, ForwardedTransformActions?xFor = null, ForwardedTransformActions?xHost = null, ForwardedTransformActions?xProto = null, ForwardedTransformActions?xPrefix = null) { return(route.WithTransform(transform => { transform[ForwardedTransformFactory.XForwardedKey] = xDefault.ToString(); if (xFor != null) { transform[ForwardedTransformFactory.ForKey] = xFor.Value.ToString(); } if (xPrefix != null) { transform[ForwardedTransformFactory.PrefixKey] = xPrefix.Value.ToString(); } if (xHost != null) { transform[ForwardedTransformFactory.HostKey] = xHost.Value.ToString(); } if (xProto != null) { transform[ForwardedTransformFactory.ProtoKey] = xProto.Value.ToString(); } transform[ForwardedTransformFactory.HeaderPrefixKey] = headerPrefix; })); }
/// <summary> /// Adds the transform which will add X-Forwarded-Proto request header. /// </summary> public static TransformBuilderContext AddXForwardedProto(this TransformBuilderContext context, string headerName = "X-Forwarded-Proto", ForwardedTransformActions action = ForwardedTransformActions.Set) { context.UseDefaultForwarders = false; if (action == ForwardedTransformActions.Off) { return(context); } context.RequestTransforms.Add(new RequestHeaderXForwardedProtoTransform(headerName, action)); return(context); }
/// <summary> /// Adds the transform which will add the Forwarded header as defined by [RFC 7239](https://tools.ietf.org/html/rfc7239). /// </summary> public static TransformBuilderContext AddForwarded(this TransformBuilderContext context, bool useHost = true, bool useProto = true, NodeFormat forFormat = NodeFormat.Random, NodeFormat byFormat = NodeFormat.Random, ForwardedTransformActions action = ForwardedTransformActions.Set) { context.UseDefaultForwarders = false; if (action == ForwardedTransformActions.Off) { return(context); } if (byFormat != NodeFormat.None || forFormat != NodeFormat.None || useHost || useProto) { var random = context.Services.GetRequiredService <IRandomFactory>(); context.RequestTransforms.Add(new RequestHeaderForwardedTransform(random, forFormat, byFormat, useHost, useProto, action)); // Remove the X-Forwarded headers when an Forwarded transform is enabled TransformHelpers.RemoveAllXForwardedHeaders(context, ForwardedTransformFactory.DefaultXForwardedPrefix); } return(context); }
/// <summary> /// Clones the route and adds the transform which will add the Forwarded header as defined by [RFC 7239](https://tools.ietf.org/html/rfc7239). /// </summary> public static RouteConfig WithTransformForwarded(this RouteConfig route, bool useHost = true, bool useProto = true, NodeFormat forFormat = NodeFormat.Random, NodeFormat byFormat = NodeFormat.Random, ForwardedTransformActions action = ForwardedTransformActions.Set) { var headers = new List <string>(); if (forFormat != NodeFormat.None) { headers.Add(ForwardedTransformFactory.ForKey); } if (byFormat != NodeFormat.None) { headers.Add(ForwardedTransformFactory.ByKey); } if (useHost) { headers.Add(ForwardedTransformFactory.HostKey); } if (useProto) { headers.Add(ForwardedTransformFactory.ProtoKey); } return(route.WithTransform(transform => { transform[ForwardedTransformFactory.ForwardedKey] = string.Join(',', headers); transform[ForwardedTransformFactory.ActionKey] = action.ToString(); if (forFormat != NodeFormat.None) { transform.Add(ForwardedTransformFactory.ForFormatKey, forFormat.ToString()); } if (byFormat != NodeFormat.None) { transform.Add(ForwardedTransformFactory.ByFormatKey, byFormat.ToString()); } })); }
/// <summary> /// Adds the transform which will add X-Forwarded-* request headers. /// </summary> public static TransformBuilderContext AddXForwarded(this TransformBuilderContext context, ForwardedTransformActions action = ForwardedTransformActions.Set) { context.AddXForwardedFor(action: action); context.AddXForwardedPrefix(action: action); context.AddXForwardedHost(action: action); context.AddXForwardedProto(action: action); // Remove the Forwarded header when an X-Forwarded transform is enabled TransformHelpers.RemoveForwardedHeader(context); return(context); }
public async Task By_Added(string startValue, string ip, int port, NodeFormat format, ForwardedTransformActions action, string expected) { var randomFactory = new TestRandomFactory(); randomFactory.Instance = new TestRandom() { Sequence = new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 } }; var httpContext = new DefaultHttpContext(); httpContext.Connection.LocalIpAddress = string.IsNullOrEmpty(ip) ? null : IPAddress.Parse(ip); httpContext.Connection.LocalPort = port; var proxyRequest = new HttpRequestMessage(); proxyRequest.Headers.Add("Forwarded", startValue.Split("|", StringSplitOptions.RemoveEmptyEntries)); var transform = new RequestHeaderForwardedTransform(randomFactory, forFormat: NodeFormat.None, byFormat: format, host: false, proto: false, action); await transform.ApplyAsync(new RequestTransformContext() { HttpContext = httpContext, ProxyRequest = proxyRequest, HeadersCopied = true, }); Assert.Equal(expected.Split("|", StringSplitOptions.RemoveEmptyEntries), proxyRequest.Headers.GetValues("Forwarded")); }
/// <summary> /// Adds the transform which will add X-Forwarded-* request headers. /// </summary> public static TransformBuilderContext AddXForwarded(this TransformBuilderContext context, ForwardedTransformActions action = ForwardedTransformActions.Set) { context.AddXForwardedFor(action: action); context.AddXForwardedPrefix(action: action); context.AddXForwardedHost(action: action); context.AddXForwardedProto(action: action); return(context); }