Skip to content

Commit

Permalink
Merge 85c9bf1 into 884b318
Browse files Browse the repository at this point in the history
  • Loading branch information
magnus-tretton37 committed Mar 20, 2019
2 parents 884b318 + 85c9bf1 commit bae2fc9
Show file tree
Hide file tree
Showing 4 changed files with 315 additions and 15 deletions.
6 changes: 3 additions & 3 deletions .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ image: Visual Studio 2017
install:
- ps: dotnet tool install coveralls.net --tool-path tools
build_script:
- cmd: dotnet build src/Castle.Sdk -c Release -f netstandard2.0
- cmd: dotnet build src/Castle.Sdk -c Release -f net461
- cmd: dotnet build src/Castle.Sdk
- cmd: dotnet build src/Tests -c Debug
test_script:
- ps: dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:Include="[Castle.Sdk*]*" src/Tests/Tests.csproj
- ps: dotnet test --no-build /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:Include="[Castle.Sdk*]*" src/Tests/Tests.csproj
- ps: .\tools\csmacnz.coveralls.exe --opencover -i src/Tests/coverage.opencover.xml --useRelativePaths --repoToken $env:COVERALLS_REPO_TOKEN --commitId $env:APPVEYOR_REPO_COMMIT --commitBranch $env:APPVEYOR_REPO_BRANCH --commitAuthor $env:APPVEYOR_REPO_COMMIT_AUTHOR --commitEmail $env:APPVEYOR_REPO_COMMIT_AUTHOR_EMAIL --commitMessage $env:APPVEYOR_REPO_COMMIT_MESSAGE --jobId $env:APPVEYOR_JOB_ID
61 changes: 49 additions & 12 deletions src/Castle.Sdk/Context.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using Castle.Messages.Requests;

Expand All @@ -8,42 +9,78 @@ namespace Castle
public static class Context
{
#if NET461
public static RequestContext FromHttpRequest(System.Web.HttpRequestBase request)
public static RequestContext FromHttpRequest(System.Web.HttpRequestBase request, string[] ipHeaders = null)
{
var headers = new Dictionary<string, string>();
foreach (string key in request.Headers.Keys)
{
headers.Add(key, request.Headers[key]);
}

var clientId = request.Headers.AllKeys.Contains("X-Castle-Client-ID", StringComparer.OrdinalIgnoreCase)
? request.Headers["X-Castle-Client-ID"]
: request.Cookies["__cid"]?.Value;
var clientId = GetClientIdForFramework(request.Headers, name => request.Cookies[name]?.Value);

var ip = GetIpForFramework(request.Headers, ipHeaders, () => request.UserHostAddress);

return new RequestContext()
{
ClientId = clientId,
Headers = headers,
Ip = request.UserHostAddress
Ip = ip
};
}
#endif

#if NETSTANDARD2_0
public static RequestContext FromHttpRequest(Microsoft.AspNetCore.Http.HttpRequest request)
internal static string GetClientIdForFramework(NameValueCollection headers, Func<string, string> getCookieValue)
{
var clientId = request.Headers.TryGetValue("X-Castle-Client-ID", out var headerId)
? headerId.First()
: request.Cookies["__cid"];
return headers.AllKeys.Contains("X-Castle-Client-ID", StringComparer.OrdinalIgnoreCase)
? headers["X-Castle-Client-ID"]
: getCookieValue("__cid") ?? "";
}

internal static string GetIpForFramework(NameValueCollection headers, string[] ipHeaders, Func<string> getIpFromHttpContext)
{
foreach (var header in ipHeaders ?? new string[] { })
{
if (headers.AllKeys.Contains(header, StringComparer.OrdinalIgnoreCase))
return headers[header];
}

return getIpFromHttpContext();
}

#if NETSTANDARD2_0
public static RequestContext FromHttpRequest(Microsoft.AspNetCore.Http.HttpRequest request, string[] ipHeaders = null)
{
return new RequestContext()
{
ClientId = clientId,
ClientId = GetClientIdForCore(request.Headers, request.Cookies),
Headers = request.Headers.ToDictionary(x => x.Key, y => y.Value.FirstOrDefault()),
Ip = request.HttpContext.Connection.RemoteIpAddress.ToString(),
Ip = GetIpForCore(request.Headers, ipHeaders, () => request.HttpContext.Connection.RemoteIpAddress.ToString())
};
}

internal static string GetClientIdForCore(
IDictionary<string, Microsoft.Extensions.Primitives.StringValues> headers,
Microsoft.AspNetCore.Http.IRequestCookieCollection cookies)
{
return headers.TryGetValue("X-Castle-Client-ID", out var headerId)
? headerId.First()
: cookies["__cid"] ?? "";
}

internal static string GetIpForCore(
IDictionary<string, Microsoft.Extensions.Primitives.StringValues> headers,
string[] ipHeaders,
Func<string> getIpFromHttpContext)
{
foreach (var header in ipHeaders ?? new string[] {})
{
if (headers.TryGetValue(header, out var headerValues))
return headerValues.First();
}

return getIpFromHttpContext();
}
#endif
}
}
137 changes: 137 additions & 0 deletions src/Tests/Messages/When_creating_request_context_for_Core.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
using System.Collections.Generic;
using AutoFixture.Xunit2;
using Castle;
using FluentAssertions;
using Microsoft.AspNetCore.Http.Internal;
using Microsoft.Extensions.Primitives;
using Xunit;

namespace Tests.Messages
{
public class When_creating_request_context_for_Core
{
[Theory, AutoData]
public void Should_get_client_id_from_castle_header_if_present(
string castleHeaderValue,
string cookieValue)
{
var headers = new Dictionary<string, StringValues>()
{
["X-Castle-Client-ID"] = castleHeaderValue,
};

var cookies = new RequestCookieCollection(new Dictionary<string, string>()
{
["__cid"] = cookieValue
});

var result = Context.GetClientIdForCore(headers, cookies);

result.Should().Be(castleHeaderValue);
}

[Theory, AutoData]
public void Should_get_client_id_from_cookie_if_castle_header_not_present(
string otherHeader,
string otherHeaderValue,
string cookieValue)
{
var headers = new Dictionary<string, StringValues>()
{
[otherHeader] = otherHeaderValue
};

var cookies = new RequestCookieCollection(new Dictionary<string, string>()
{
["__cid"] = cookieValue
});

var result = Context.GetClientIdForCore(headers, cookies);

result.Should().Be(cookieValue);
}

[Theory, AutoData]
public void Should_use_empty_string_if_unable_to_get_client_id(
string otherHeader,
string otherHeaderValue,
string otherCookie,
string otherCookieValue)
{
var headers = new Dictionary<string, StringValues>()
{
[otherHeader] = otherHeaderValue
};

var cookies = new RequestCookieCollection(new Dictionary<string, string>()
{
[otherCookie] = otherCookieValue
});

var result = Context.GetClientIdForCore(headers, cookies);

result.Should().Be("");
}

[Theory, AutoData]
public void Should_get_ip_from_supplied_headers_in_order(
string ipHeader,
string ip,
string secondaryIpHeader,
string secondaryIp,
string otherHeader,
string otherHeaderValue,
string httpContextIp)
{
var headers = new Dictionary<string, StringValues>()
{
[ipHeader] = ip,
[secondaryIpHeader] = secondaryIp,
[otherHeader] = otherHeaderValue
};

var result = Context.GetIpForCore(headers, new [] { ipHeader, secondaryIpHeader }, () => httpContextIp);

result.Should().Be(ip);
}

[Theory, AutoData]
public void Should_get_ip_from_second_header_if_first_is_not_found(
string ipHeader,
string secondaryIpHeader,
string secondaryIp,
string otherHeader,
string otherHeaderValue,
string httpContextIp)
{
var headers = new Dictionary<string, StringValues>()
{
[secondaryIpHeader] = secondaryIp,
[otherHeader] = otherHeaderValue
};

var result = Context.GetIpForCore(headers, new[] { ipHeader, secondaryIpHeader }, () => httpContextIp);

result.Should().Be(secondaryIp);
}

[Theory, AutoData]
public void Should_get_ip_from_httpcontext_if_no_header_supplied(
string ipHeader,
string ip,
string otherHeader,
string otherHeaderValue,
string httpContextIp)
{
var headers = new Dictionary<string, StringValues>()
{
[ipHeader] = ip,
[otherHeader] = otherHeaderValue
};

var result = Context.GetIpForCore(headers, null, () => httpContextIp);

result.Should().Be(httpContextIp);
}
}
}
126 changes: 126 additions & 0 deletions src/Tests/Messages/When_creating_request_context_for_Framework.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
using System.Collections.Specialized;
using AutoFixture.Xunit2;
using Castle;
using FluentAssertions;
using Xunit;

namespace Tests.Messages
{
public class When_creating_request_context_for_Framework
{
[Theory, AutoData]
public void Should_get_client_id_from_castle_header_if_present(
string castleHeaderValue,
string cookieValue)
{
var headers = new NameValueCollection
{
["X-Castle-Client-ID"] = castleHeaderValue
};

string GetCookie(string name) => name == "__cid" ? cookieValue : null;

var result = Context.GetClientIdForFramework(headers, GetCookie);

result.Should().Be(castleHeaderValue);
}

[Theory, AutoData]
public void Should_get_client_id_from_cookie_if_castle_header_not_present(
string otherHeader,
string otherHeaderValue,
string cookieValue)
{
var headers = new NameValueCollection
{
[otherHeader] = otherHeaderValue
};

string GetCookie(string name) => name == "__cid" ? cookieValue : null;

var result = Context.GetClientIdForFramework(headers, GetCookie);

result.Should().Be(cookieValue);
}

[Theory, AutoData]
public void Should_use_empty_string_if_unable_to_get_client_id(
string otherHeader,
string otherHeaderValue,
string otherCookie,
string otherCookieValue)
{
var headers = new NameValueCollection
{
[otherHeader] = otherHeaderValue
};

string GetCookie(string name) => name == otherCookie ? otherCookieValue : null;

var result = Context.GetClientIdForFramework(headers, GetCookie);

result.Should().Be("");
}

[Theory, AutoData]
public void Should_get_ip_from_supplied_headers_in_order(
string ipHeader,
string ip,
string secondaryIpHeader,
string secondaryIp,
string otherHeader,
string otherHeaderValue,
string httpContextIp)
{
var headers = new NameValueCollection
{
[ipHeader] = ip,
[secondaryIpHeader] = secondaryIp,
[otherHeader] = otherHeaderValue
};

var result = Context.GetIpForFramework(headers, new [] { ipHeader, secondaryIpHeader }, () => httpContextIp);

result.Should().Be(ip);
}

[Theory, AutoData]
public void Should_get_ip_from_second_header_if_first_is_not_found(
string ipHeader,
string secondaryIpHeader,
string secondaryIp,
string otherHeader,
string otherHeaderValue,
string httpContextIp)
{
var headers = new NameValueCollection
{
[secondaryIpHeader] = secondaryIp,
[otherHeader] = otherHeaderValue
};

var result = Context.GetIpForFramework(headers, new[] { ipHeader, secondaryIpHeader }, () => httpContextIp);

result.Should().Be(secondaryIp);
}

[Theory, AutoData]
public void Should_get_ip_from_httpcontext_if_no_header_supplied(
string ipHeader,
string ip,
string otherHeader,
string otherHeaderValue,
string httpContextIp)
{
var headers = new NameValueCollection
{
[ipHeader] = ip,
[otherHeader] = otherHeaderValue
};

var result = Context.GetIpForFramework(headers, null, () => httpContextIp);

result.Should().Be(httpContextIp);
}
}
}

0 comments on commit bae2fc9

Please sign in to comment.