Skip to content

Commit

Permalink
Added UseRawTarget option to AspNetRequestUrlRenderer
Browse files Browse the repository at this point in the history
  • Loading branch information
sm-g committed Mar 21, 2020
1 parent 0ab102c commit 5a3d92a
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 7 deletions.
27 changes: 21 additions & 6 deletions src/Shared/LayoutRenderers/AspNetRequestUrlRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using NLog.Web.Internal;
#if ASP_NET_CORE
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;

#else
using System.Collections.Specialized;
Expand All @@ -24,7 +25,7 @@ namespace NLog.Web.LayoutRenderers
/// ${aspnet-request-url:IncludePort=true} - produces http://www.exmaple.com:80/
/// ${aspnet-request-url:IncludePort=false} - produces http://www.exmaple.com/
/// ${aspnet-request-url:IncludeScheme=false} - produces www.exmaple.com/
/// ${aspnet-request-url:IncludePort=true:IncludeQueryString=true} - produces http://www.exmaple.com:80/?t=1
/// ${aspnet-request-url:IncludePort=true:IncludeQueryString=true} - produces http://www.exmaple.com:80/?t=1
/// </code>
/// </example>
[LayoutRenderer("aspnet-request-url")]
Expand All @@ -37,7 +38,7 @@ public class AspNetRequestUrlRenderer : AspNetLayoutRendererBase
public bool IncludeQueryString { get; set; } = false;

/// <summary>
/// To specify whether to include /exclude the Port. Default is false.
/// To specify whether to include / exclude the Port. Default is false.
/// </summary>
public bool IncludePort { get; set; } = false;

Expand All @@ -51,6 +52,11 @@ public class AspNetRequestUrlRenderer : AspNetLayoutRendererBase
/// </summary>
public bool IncludeScheme { get; set; } = true;

/// <summary>
/// To specify whether to use raw path and full query (for ASP.NET Core only). Default is false.
/// </summary>
public bool UseRawTarget { get; set; } = false;

/// <summary>
/// Renders the Request URL from the HttpRequest
/// </summary>
Expand Down Expand Up @@ -112,11 +118,20 @@ private void RenderUrl(HttpRequest httpRequest, StringBuilder builder)
builder.Append(httpRequest.Host.Port.Value);
}

builder.Append(httpRequest.PathBase.ToUriComponent());
builder.Append(httpRequest.Path.ToUriComponent());
if (IncludeQueryString)
IHttpRequestFeature httpRequestFeature;
if (UseRawTarget && (httpRequestFeature = httpRequest.HttpContext.Features.Get<IHttpRequestFeature>()) != null)
{
builder.Append(httpRequest.QueryString.Value);
builder.Append(httpRequestFeature.RawTarget);
}
else
{
builder.Append(httpRequest.PathBase.ToUriComponent());
builder.Append(httpRequest.Path.ToUriComponent());

if (IncludeQueryString)
{
builder.Append(httpRequest.QueryString.Value);
}
}
}
#endif
Expand Down
61 changes: 60 additions & 1 deletion tests/Shared/LayoutRenderers/AspNetRequestUrlRendererTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,15 @@
using Microsoft.Extensions.Primitives;
using HttpContextBase = Microsoft.AspNetCore.Http.HttpContext;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
#endif
using NLog.Web.LayoutRenderers;
using NSubstitute;

using Xunit;

using System.IO;

namespace NLog.Web.Tests.LayoutRenderers
{
public class AspNetRequestUrlRendererTests : LayoutRenderersTestBase<AspNetRequestUrlRenderer>
Expand Down Expand Up @@ -147,7 +151,30 @@ public void UrlPresentRenderNonEmpty_ExcludeHost_IncludeQueryString()
Assert.Equal("http:///Test.asp?t=1", result);
}

private static AspNetRequestUrlRenderer CreateRenderer(string hostBase, string queryString = "", string scheme = "http", string page = "/", string pathBase = "")
[Fact]
public void UrlPresentRenderNonEmpty_UseRawTarget()
{
var renderer = CreateRenderer("www.google.com:80", "?t=1", "http", "/Test.asp", rawTarget: "/rawTarget");
renderer.UseRawTarget = true;

string result = renderer.Render(LogEventInfo.CreateNullEvent());

Assert.Equal("http://www.google.com/rawTarget", result);
}

[Fact]
public void UrlPresentRenderNonEmpty_UseRawTarget_IncludeQueryString()
{
var renderer = CreateRenderer("www.google.com:80", "?t=1", "http", "/Test.asp", rawTarget: "/rawTarget");
renderer.UseRawTarget = true;
renderer.IncludeQueryString = true;

string result = renderer.Render(LogEventInfo.CreateNullEvent());

Assert.Equal("http://www.google.com/rawTarget", result);
}

private static AspNetRequestUrlRenderer CreateRenderer(string hostBase, string queryString = "", string scheme = "http", string page = "/", string pathBase = "", string rawTarget = null)
{
var (renderer, httpContext) = CreateWithHttpContext();

Expand All @@ -160,8 +187,40 @@ private static AspNetRequestUrlRenderer CreateRenderer(string hostBase, string q
httpContext.Request.QueryString.Returns(new QueryString(queryString));
httpContext.Request.Host.Returns(new HostString(hostBase));
httpContext.Request.Scheme.Returns(scheme);

if (rawTarget != null)
{
httpContext.Request.HttpContext.Returns(httpContext);

var httpRequestFeature = new HttpRequestFeatureMock();
httpRequestFeature.RawTarget = rawTarget;
var collection = new FeatureCollection();
collection.Set<IHttpRequestFeature>(httpRequestFeature);
httpContext.Features.Returns(collection);
}
#endif
return renderer;
}

#if ASP_NET_CORE

private class HttpRequestFeatureMock : IHttpRequestFeature
{
#region Implementation of IHttpRequestFeature

public Stream Body { get; set; }
public IHeaderDictionary Headers { get; set; }
public string Method { get; set; }
public string Path { get; set; }
public string PathBase { get; set; }
public string Protocol { get; set; }
public string QueryString { get; set; }
public string RawTarget { get; set; }
public string Scheme { get; set; }

#endregion Implementation of IHttpRequestFeature
}

#endif
}
}

0 comments on commit 5a3d92a

Please sign in to comment.