Skip to content
This repository has been archived by the owner on Dec 20, 2018. It is now read-only.

Commit

Permalink
Adds XML comments and feedback from 1on1 with Nate.
Browse files Browse the repository at this point in the history
  • Loading branch information
Justin Kotalik committed Aug 30, 2016
1 parent 4a06b37 commit af2c1ac
Show file tree
Hide file tree
Showing 27 changed files with 157 additions and 128 deletions.
5 changes: 3 additions & 2 deletions samples/RewriteSample/Rewrite.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Rewrite path with additional sub directory
RewriteCond %{QUERY_STRING} id=20
RewriteRule ^(.*)$ - [G]
RewriteCond %{HTTP_HOST} !^www\.example\.com [NC,OR]
RewriteCond %{SERVER_PORT} !^5000$
RewriteRule ^/(.*) http://www.example.com/$1 [L,R=302]
25 changes: 8 additions & 17 deletions samples/RewriteSample/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,16 @@ namespace RewriteSample
{
public class Startup
{
public void Configure(IApplicationBuilder app, IHostingEnvironment hostingEnv)
public void Configure(IApplicationBuilder app, IHostingEnvironment hostingEnvironment)
{
// Four main use cases for Rewrite Options.
// 1. Importing from a UrlRewrite file, which are IIS Rewrite rules.
// This file is in xml format, starting with the <rewrite> tag.
// 2. Importing from a mod_rewrite file, which are mod_rewrite rules.
// This file is in standard mod_rewrite format which only contains rewrite information.
// 3. Inline rules in code, where you can specify rules such as rewrites and redirects
// based on certain conditions. Ex: RedirectToHttps will check if the request is https,
// else it will redirect the request with https.
// 4. Functional rules. If a user has a very specific function they would like to implement
// (ex StringReplace) that are easy to implement in code, they can do so by calling
// AddFunctionalRule(Func);
// TODO make this startup do something useful.
var options = new RewriteOptions()
.AddRedirect("(.*)/$", "$1")
.AddRewrite(@"app/(\d+)", "app?id=$1")
.AddRedirectToHttps(302)
.AddIISUrlRewrite(hostingEnvironment, "UrlRewrite.xml")
.AddApacheModRewrite(hostingEnvironment, "Rewrite.txt");

app.UseRewriter(new RewriteOptions()
.Rewrite(@"foo/(\d+)", "foo?id=$1")
.ImportFromUrlRewrite(hostingEnv, "UrlRewrite.xml")
.ImportFromModRewrite(hostingEnv, "Rewrite.txt"));
app.UseRewriter(options);

app.Run(context => context.Response.WriteAsync($"Rewritten Url: {context.Request.Path + context.Request.QueryString}"));
}
Expand Down
7 changes: 5 additions & 2 deletions samples/RewriteSample/UrlRewrite.xml
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
<rewrite>
<rules>
<rule name="" stopProcessing="true">
<match url="foo/bar" />
<action type="Redirect" redirectType="Found" url="foo/" />
<match url="(.*)" />
<conditions>
<add input="{QUERY_STRING}" pattern="id=20" />
</conditions>
<action type="Rewrite" url="app?id=10" appendQueryString="false"/>
</rule>
</rules>
</rewrite>
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,18 @@

namespace Microsoft.AspNetCore.Rewrite
{
public static class ModRewriteOptionsExtensions
/// <summary>
/// Apache mod_rewrite extensions on top of the <see cref="RewriteOptions"/>
/// </summary>
public static class ApacheModRewriteOptionsExtensions
{
/// <summary>
/// Imports rules from a mod_rewrite file and adds the rules to current rules.
/// </summary>
/// <param name="options">The Rewrite options.</param>
/// <param name="hostingEnvironment">The Hosting Environment</param>
/// <param name="filePath">The path to the file containing mod_rewrite rules.</param>
public static RewriteOptions ImportFromModRewrite(this RewriteOptions options, IHostingEnvironment hostingEnvironment, string filePath)
public static RewriteOptions AddApacheModRewrite(this RewriteOptions options, IHostingEnvironment hostingEnvironment, string filePath)
{
if (options == null)
{
Expand All @@ -36,16 +39,16 @@ public static RewriteOptions ImportFromModRewrite(this RewriteOptions options, I
var path = Path.Combine(hostingEnvironment.ContentRootPath, filePath);
using (var stream = File.OpenRead(path))
{
return options.ImportFromModRewrite(new StreamReader(stream));
return options.AddApacheModRewrite(new StreamReader(stream));
}
}

/// <summary>
/// Imports rules from a mod_rewrite file and adds the rules to current rules.
/// </summary>
/// <param name="options">The Rewrite options.</param>
/// <param name="reader">Text reader containing a stream of mod_rewrite rules.</param>
public static RewriteOptions ImportFromModRewrite(this RewriteOptions options, TextReader reader)
/// <param name="reader">A stream of mod_rewrite rules.</param>
public static RewriteOptions AddApacheModRewrite(this RewriteOptions options, TextReader reader)
{
if (options == null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,18 @@

namespace Microsoft.AspNetCore.Rewrite
{
public static class UrlRewriteOptionsExtensions
/// <summary>
/// IIS Url rewrite extensions on top of the <see cref="RewriteOptions"/>
/// </summary>
public static class IISUrlRewriteOptionsExtensions
{
/// <summary>
/// Imports rules from a mod_rewrite file and adds the rules to current rules.
/// </summary>
/// <param name="options">The UrlRewrite options.</param>
/// <param name="hostingEnvironment"></param>
/// <param name="filePath">The path to the file containing urlrewrite rules.</param>
public static RewriteOptions ImportFromUrlRewrite(this RewriteOptions options, IHostingEnvironment hostingEnvironment, string filePath)
public static RewriteOptions AddIISUrlRewrite(this RewriteOptions options, IHostingEnvironment hostingEnvironment, string filePath)
{
if (options == null)
{
Expand All @@ -36,7 +39,7 @@ public static RewriteOptions ImportFromUrlRewrite(this RewriteOptions options, I
var path = Path.Combine(hostingEnvironment.ContentRootPath, filePath);
using (var stream = File.OpenRead(path))
{
return ImportFromUrlRewrite(options, new StreamReader(stream));
return AddIISUrlRewrite(options, new StreamReader(stream));
}
}

Expand All @@ -45,7 +48,7 @@ public static RewriteOptions ImportFromUrlRewrite(this RewriteOptions options, I
/// </summary>
/// <param name="options">The UrlRewrite options.</param>
/// <param name="reader">The text reader stream.</param>
public static RewriteOptions ImportFromUrlRewrite(this RewriteOptions options, TextReader reader)
public static RewriteOptions AddIISUrlRewrite(this RewriteOptions options, TextReader reader)
{
if (options == null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ public override void ApplyRule(RewriteContext context)
{
var result = initMatchResults.Result(Replacement);
var request = context.HttpContext.Request;

if (result.IndexOf("://", StringComparison.Ordinal) >= 0)
{
string scheme;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ public class FlagParser
{ "noescape", FlagType.NoEscape },
{ "ns", FlagType.NoSubReq },
{ "nosubreq", FlagType.NoSubReq },
{ "or", FlagType.Or },
{ "ornext", FlagType.Or },
{ "p", FlagType.Proxy },
{ "proxy", FlagType.Proxy },
{ "pt", FlagType.PassThrough },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Microsoft.AspNetCore.Rewrite.Internal.PreActions;
using Microsoft.AspNetCore.Rewrite.Internal.UrlActions;
using Microsoft.AspNetCore.Rewrite.Internal.UrlMatches;

Expand All @@ -13,19 +12,18 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
public class RuleBuilder
{
private IList<Condition> _conditions;
private UrlAction _action;
private IList<UrlAction> _actions = new List<UrlAction>();
private UrlMatch _match;
private List<PreAction> _preActions;

private readonly TimeSpan RegexTimeout = TimeSpan.FromMilliseconds(1);

public ModRewriteRule Build()
{
if (_action == null || _match == null)
if (_actions.Count == 0 || _match == null)
{
throw new InvalidOperationException("Cannot create ModRewriteRule without action and match");
}
return new ModRewriteRule(_match, _conditions, _action, _preActions);
return new ModRewriteRule(_match, _conditions, _actions);
}

public void AddRule(string rule)
Expand Down Expand Up @@ -169,31 +167,26 @@ public void AddRule(string rule)
Flags flags)
{
// first create pre conditions
if (_preActions == null)
{
_preActions = new List<PreAction>();
}

string flag;
if (flags.GetValue(FlagType.Cookie, out flag))
{
// parse cookie
_preActions.Add(new ChangeCookiePreAction(flag));
_actions.Add(new ChangeCookieAction(flag));
}

if (flags.GetValue(FlagType.Env, out flag))
{
// parse env
_preActions.Add(new ChangeEnvironmentPreAction(flag));
_actions.Add(new ChangeEnvironmentAction(flag));
}

if (flags.HasFlag(FlagType.Forbidden))
{
_action = new ForbiddenAction();
_actions.Add(new ForbiddenAction());
}
else if (flags.HasFlag(FlagType.Gone))
{
_action = new GoneAction();
_actions.Add(new GoneAction());
}
else
{
Expand All @@ -210,13 +203,13 @@ public void AddRule(string rule)
{
throw new FormatException(Resources.FormatError_InputParserInvalidInteger(statusCode, -1));
}
_action = new RedirectAction(res, pattern, queryStringAppend, queryStringDelete, escapeBackReference);
_actions.Add(new RedirectAction(res, pattern, queryStringAppend, queryStringDelete, escapeBackReference));
}
else
{
var last = flags.HasFlag(FlagType.End) || flags.HasFlag(FlagType.Last);
var termination = last ? RuleTermination.StopRules : RuleTermination.Continue;
_action = new RewriteAction(termination, pattern, queryStringAppend, queryStringDelete, escapeBackReference);
_actions.Add(new RewriteAction(termination, pattern, queryStringAppend, queryStringDelete, escapeBackReference));
}
}
}
Expand Down
15 changes: 6 additions & 9 deletions src/Microsoft.AspNetCore.Rewrite/Internal/ModRewriteRule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,13 @@ public class ModRewriteRule : Rule
{
public UrlMatch InitialMatch { get; }
public IList<Condition> Conditions { get; }
public UrlAction Action { get; }
public IList<PreAction> PreActions { get; }
public IList<UrlAction> Actions { get; }

public ModRewriteRule(UrlMatch initialMatch, IList<Condition> conditions, UrlAction urlAction, IList<PreAction> preActions)
public ModRewriteRule(UrlMatch initialMatch, IList<Condition> conditions, IList<UrlAction> urlActions)
{
Conditions = conditions;
InitialMatch = initialMatch;
Action = urlAction;
PreActions = preActions;
Actions = urlActions;
}

public override void ApplyRule(RewriteContext context)
Expand Down Expand Up @@ -46,12 +44,11 @@ public override void ApplyRule(RewriteContext context)
// At this point, we know our rule passed, first apply pre conditions,
// which can modify things like the cookie or env, and then apply the action
context.Logger?.ModRewriteMatchedRule();
foreach (var preAction in PreActions)

foreach (var action in Actions)
{
preAction.ApplyAction(context.HttpContext, initMatchRes, condMatchRes);
action.ApplyAction(context, initMatchRes, condMatchRes);
}

Action.ApplyAction(context, initMatchRes, condMatchRes);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ namespace Microsoft.AspNetCore.Rewrite.Internal.PatternSegments
{
public class IsHttpsModSegment : PatternSegment
{
// Note: Mod rewrite pattern matches on lower case "on" and "off"
// while IIS looks for capitalized "ON" and "OFF"
public override string Evaluate(RewriteContext context, MatchResults ruleMatch, MatchResults condMatch)
{
return context.HttpContext.Request.IsHttps ? "on" : "off";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@

namespace Microsoft.AspNetCore.Rewrite.Internal.PatternSegments
{
public class IsHttpsSegment : PatternSegment
{
public class IsHttpsUrlSegment : PatternSegment
{
// Note: Mod rewrite pattern matches on lower case "on" and "off"
// while IIS looks for capitalized "ON" and "OFF"
public override string Evaluate(RewriteContext context, MatchResults ruleMatch, MatchResults condMatch)
{
return context.HttpContext.Request.IsHttps ? "ON" : "OFF";
Expand Down
12 changes: 0 additions & 12 deletions src/Microsoft.AspNetCore.Rewrite/Internal/PreAction.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@
using System;
using Microsoft.AspNetCore.Http;

namespace Microsoft.AspNetCore.Rewrite.Internal.PreActions
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlActions
{
public class ChangeCookiePreAction : PreAction
public class ChangeCookieAction : UrlAction
{
public ChangeCookiePreAction(string cookie)
public ChangeCookieAction(string cookie)
{
// TODO
throw new NotImplementedException(cookie);
}

public override void ApplyAction(HttpContext context, MatchResults ruleMatch, MatchResults condMatch)
public override void ApplyAction(RewriteContext context, MatchResults ruleMatch, MatchResults condMatch)
{
// modify the cookies

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@
using System;
using Microsoft.AspNetCore.Http;

namespace Microsoft.AspNetCore.Rewrite.Internal.PreActions
namespace Microsoft.AspNetCore.Rewrite.Internal.UrlActions
{
public class ChangeEnvironmentPreAction : PreAction
public class ChangeEnvironmentAction : UrlAction
{
public ChangeEnvironmentPreAction(string env)
public ChangeEnvironmentAction(string env)
{
// TODO
throw new NotImplementedException();
}

public override void ApplyAction(HttpContext context, MatchResults ruleMatch, MatchResults condMatch)
public override void ApplyAction(RewriteContext context, MatchResults ruleMatch, MatchResults condMatch)
{
// Do stuff to modify the env
throw new NotImplementedException();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ public class RedirectAction : UrlAction
queryStringDelete: true,
escapeBackReferences: false)
{

}

public override void ApplyAction(RewriteContext context, MatchResults ruleMatch, MatchResults condMatch)
Expand All @@ -58,7 +57,6 @@ public override void ApplyAction(RewriteContext context, MatchResults ruleMatch,
{
pattern = '/' + pattern;
}

response.StatusCode = StatusCode;

// url can either contain the full url or the path and query
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public override void ApplyAction(RewriteContext context, MatchResults ruleMatch,
{
var pattern = Url.Evaluate(context, ruleMatch, condMatch);
var request = context.HttpContext.Request;

if (EscapeBackReferences)
{
// because escapebackreferences will be encapsulated by the pattern, just escape the pattern
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public static PatternSegment FindServerVariable(string serverVariable)
case "HTTP_URL":
return new UrlSegment();
case "HTTPS":
return new IsHttpsSegment();
return new IsHttpsUrlSegment();
case "LOCAL_ADDR":
return new LocalAddressSegment();
case "HTTP_PROXY_CONNECTION":
Expand Down
Loading

0 comments on commit af2c1ac

Please sign in to comment.