1
0
Форкнуть 0

unit tests for client IP header telemetry initializer

This commit is contained in:
Sergey Kanzhelev 2015-03-30 13:43:40 -07:00
Родитель 5e93ae73c4
Коммит 2627b2def5
2 изменённых файлов: 135 добавлений и 46 удалений

Просмотреть файл

@ -16,10 +16,8 @@
/// This telemetry initializer extracts client IP address and populates telemetry.Context.Location.Ip property.
/// Lot's of code reuse from Microsoft.ApplicationInsights.Extensibility.Web.TelemetryInitializers.WebClientIpHeaderTelemetryInitializer
/// </summary>
public class WebClientIpHeaderTelemetryInitializer : ITelemetryInitializer
public class WebClientIpHeaderTelemetryInitializer : TelemetryInitializerBase
{
private IServiceProvider serviceProvider;
private readonly char[] HeaderValuesSeparatorDefault = new char[] { ',' };
private const string HeaderNameDefault = "X-Forwarded-For";
@ -29,8 +27,8 @@
public WebClientIpHeaderTelemetryInitializer(IServiceProvider serviceProvider)
: base(serviceProvider)
{
this.serviceProvider = serviceProvider;
this.headerNames = new List<string>();
this.HeaderNames.Add(HeaderNameDefault);
this.UseFirstIp = true;
@ -72,48 +70,6 @@
/// </summary>
public bool UseFirstIp { get; set; }
public void Initialize(ITelemetry telemetry)
{
var request = this.serviceProvider.GetService<RequestTelemetry>();
if (!string.IsNullOrEmpty(request.Context.Location.Ip))
{
telemetry.Context.Location.Ip = request.Context.Location.Ip;
}
else
{
var context = this.serviceProvider.GetService<HttpContextHolder>().Context;
string resultIp = null;
foreach (var name in this.HeaderNames)
{
var headerValue = context.Request.Headers[name];
if (!string.IsNullOrEmpty(headerValue))
{
var ip = GetIpFromHeader(headerValue);
ip = CutPort(ip);
if (IsCorrectIpAddress(ip))
{
resultIp = ip;
break;
}
}
}
if (string.IsNullOrEmpty(resultIp))
{
var connectionFeature = context.GetFeature<IHttpConnectionFeature>();
if (connectionFeature != null)
{
resultIp = connectionFeature.RemoteIpAddress.ToString();
}
}
request.Context.Location.Ip = resultIp;
telemetry.Context.Location.Ip = resultIp;
}
}
private static string CutPort(string address)
{
// For Web sites in Azure header contains ip address with port e.g. 50.47.87.223:54464
@ -151,5 +107,45 @@
return this.UseFirstIp ? ips[0].Trim() : ips[ips.Length - 1].Trim();
}
protected override void OnInitializeTelemetry(HttpContext platformContext, RequestTelemetry requestTelemetry, ITelemetry telemetry)
{
if (!string.IsNullOrEmpty(telemetry.Context.Location.Ip))
{
//already populated
return;
}
if (string.IsNullOrEmpty(requestTelemetry.Context.Location.Ip))
{
string resultIp = null;
foreach (var name in this.HeaderNames)
{
var headerValue = platformContext.Request.Headers[name];
if (!string.IsNullOrEmpty(headerValue))
{
var ip = GetIpFromHeader(headerValue);
ip = CutPort(ip);
if (IsCorrectIpAddress(ip))
{
resultIp = ip;
break;
}
}
}
if (string.IsNullOrEmpty(resultIp))
{
var connectionFeature = platformContext.GetFeature<IHttpConnectionFeature>();
if (connectionFeature != null)
{
resultIp = connectionFeature.RemoteIpAddress.ToString();
}
}
requestTelemetry.Context.Location.Ip = resultIp;
}
telemetry.Context.Location.Ip = requestTelemetry.Context.Location.Ip;
}
}
}

Просмотреть файл

@ -0,0 +1,93 @@
namespace Microsoft.ApplicationInsights.AspNet.Tests.TelemetryInitializers
{
using Microsoft.ApplicationInsights.AspNet.Implementation;
using Microsoft.ApplicationInsights.AspNet.TelemetryInitializers;
using Microsoft.ApplicationInsights.AspNet.Tests.Helpers;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.AspNet.Http.Core;
using System;
using System.Collections.Generic;
using Xunit;
public class WebClientIpHeaderTelemetryInitializerTests
{
[Fact]
public void InitializeDoesNotThrowIfHttpContextHolderIsUnavailable()
{
var initializer = new WebClientIpHeaderTelemetryInitializer(new TestServiceProvider());
initializer.Initialize(new RequestTelemetry());
}
[Fact]
public void InitializeDoesNotThrowIfHttpContextIsUnavailable()
{
var serviceProvider = new TestServiceProvider(new List<object>() { new HttpContextHolder() });
var initializer = new WebClientIpHeaderTelemetryInitializer(serviceProvider);
initializer.Initialize(new RequestTelemetry());
}
[Fact]
public void InitializeDoesNotThrowIfRequestTelemetryIsUnavailable()
{
var contextHolder = new HttpContextHolder();
contextHolder.Context = new DefaultHttpContext();
var serviceProvider = new TestServiceProvider(new List<object>() { contextHolder });
var initializer = new WebClientIpHeaderTelemetryInitializer(serviceProvider);
initializer.Initialize(new RequestTelemetry());
}
[Fact]
public void InitializeSetsIPFromStandardHeader()
{
var requestTelemetry = new RequestTelemetry();
var contextHolder = new HttpContextHolder();
contextHolder.Context = new DefaultHttpContext();
contextHolder.Context.Request.Headers.Add("X-Forwarded-For", new string[] { "127.0.0.3" });
var serviceProvider = new TestServiceProvider(new List<object>() { contextHolder, requestTelemetry });
var initializer = new WebClientIpHeaderTelemetryInitializer(serviceProvider);
initializer.Initialize(requestTelemetry);
Assert.Equal("127.0.0.3", requestTelemetry.Context.Location.Ip);
}
[Fact]
public void InitializeSetsIPFromCustomHeader()
{
var requestTelemetry = new RequestTelemetry();
var contextHolder = new HttpContextHolder();
contextHolder.Context = new DefaultHttpContext();
contextHolder.Context.Request.Headers.Add("HEADER", new string[] { "127.0.0.3;127.0.0.4" });
var serviceProvider = new TestServiceProvider(new List<object>() { contextHolder, requestTelemetry });
var initializer = new WebClientIpHeaderTelemetryInitializer(serviceProvider);
initializer.HeaderNames.Add("HEADER");
initializer.HeaderValueSeparators = ",;";
initializer.Initialize(requestTelemetry);
Assert.Equal("127.0.0.3", requestTelemetry.Context.Location.Ip);
}
[Fact]
public void InitializeDoesNotOverrideIPProvidedInline()
{
var requestTelemetry = new RequestTelemetry();
requestTelemetry.Context.Location.Ip = "127.0.0.4";
var contextHolder = new HttpContextHolder();
contextHolder.Context = new DefaultHttpContext();
contextHolder.Context.Request.Headers.Add("X-Forwarded-For", new string[] { "127.0.0.3" });
var serviceProvider = new TestServiceProvider(new List<object>() { contextHolder, requestTelemetry });
var initializer = new WebClientIpHeaderTelemetryInitializer(serviceProvider);
initializer.Initialize(requestTelemetry);
Assert.Equal("127.0.0.4", requestTelemetry.Context.Location.Ip);
}
}
}