Skip to content

Commit

Permalink
${aspnet-request-url} Added UseRawTarget option (#530)
Browse files Browse the repository at this point in the history
* Added UseRawTarget option to AspNetRequestUrlRenderer

* docs

* UseRawTarget only for ASP.NET Core

* fix tests

Co-authored-by: Julian Verdurmen <[email protected]>
  • Loading branch information
sm-g and 304NotModified authored Apr 14, 2020
1 parent 77f77ec commit 85b35f6
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 8 deletions.
35 changes: 28 additions & 7 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,16 @@ public class AspNetRequestUrlRenderer : AspNetLayoutRendererBase
/// </summary>
public bool IncludeScheme { get; set; } = true;

#if ASP_NET_CORE

/// <summary>
/// To specify whether to use raw path and full query. Default is false.
/// See https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.http.features.ihttprequestfeature.rawtarget
/// </summary>
public bool UseRawTarget { get; set; } = false;

#endif

/// <summary>
/// Renders the Request URL from the HttpRequest
/// </summary>
Expand All @@ -68,6 +79,7 @@ protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent)
}

#if !ASP_NET_CORE

private void RenderUrl(HttpRequestBase httpRequest, StringBuilder builder)
{
var url = httpRequest.Url;
Expand Down Expand Up @@ -112,13 +124,22 @@ 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(httpRequestFeature.RawTarget);
}
else
{
builder.Append(httpRequest.QueryString.Value);
builder.Append(httpRequest.PathBase.ToUriComponent());
builder.Append(httpRequest.Path.ToUriComponent());

if (IncludeQueryString)
{
builder.Append(httpRequest.QueryString.Value);
}
}
}
#endif
}
}
}
62 changes: 61 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 @@ -146,8 +150,32 @@ public void UrlPresentRenderNonEmpty_ExcludeHost_IncludeQueryString()

Assert.Equal("http:///Test.asp?t=1", result);
}
#if ASP_NET_CORE
[Fact]
public void UrlPresentRenderNonEmpty_UseRawTarget()
{
var renderer = CreateRenderer("www.google.com:80", "?t=1", "http", "/Test.asp", rawTarget: "/rawTarget");
renderer.UseRawTarget = true;

private static AspNetRequestUrlRenderer CreateRenderer(string hostBase, string queryString = "", string scheme = "http", string page = "/", string pathBase = "")
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);
}
#endif

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 +188,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 85b35f6

Please sign in to comment.