aspnetcore/src/Microsoft.AspNetCore.Rewrite/Internal/ModRewrite/ModRewriteRewriteAction.cs

114 lines
4.2 KiB
C#

// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
namespace Microsoft.AspNetCore.Rewrite.Internal.ModRewrite
{
public class ModRewriteRewriteAction : UrlAction
{
private readonly string ForwardSlash = "/";
public RuleTermination Result { get; }
public bool QueryStringAppend { get; }
public bool QueryStringDelete { get; }
public bool EscapeBackReferences { get; }
public ModRewriteRewriteAction(
RuleTermination result,
Pattern pattern,
bool queryStringAppend,
bool queryStringDelete,
bool escapeBackReferences)
{
Result = result;
Url = pattern;
QueryStringAppend = queryStringAppend;
QueryStringDelete = queryStringDelete;
EscapeBackReferences = escapeBackReferences;
}
public override void ApplyAction(RewriteContext context, MatchResults ruleMatch, MatchResults condMatch)
{
var pattern = Url.Evaluate(context, ruleMatch, condMatch);
// TODO PERF, substrings, object creation, etc.
if (pattern.IndexOf("://", StringComparison.Ordinal) >= 0)
{
string scheme;
HostString host;
PathString path;
QueryString query;
FragmentString fragment;
UriHelper.FromAbsolute(pattern, out scheme, out host, out path, out query, out fragment);
if (query.HasValue)
{
if (QueryStringAppend)
{
context.HttpContext.Request.QueryString = context.HttpContext.Request.QueryString.Add(query);
}
else
{
context.HttpContext.Request.QueryString = query;
}
}
else if (QueryStringDelete)
{
context.HttpContext.Request.QueryString = QueryString.Empty;
}
context.HttpContext.Request.Scheme = scheme;
context.HttpContext.Request.Host = host;
context.HttpContext.Request.Path = path;
}
else
{
var split = pattern.IndexOf('?');
if (split >= 0)
{
var path = pattern.Substring(0, split);
if (path.StartsWith(ForwardSlash))
{
context.HttpContext.Request.Path = PathString.FromUriComponent(path);
}
else
{
context.HttpContext.Request.Path = PathString.FromUriComponent(ForwardSlash + path);
}
if (QueryStringAppend)
{
context.HttpContext.Request.QueryString = context.HttpContext.Request.QueryString.Add(
QueryString.FromUriComponent(
pattern.Substring(split)));
}
else
{
context.HttpContext.Request.QueryString = QueryString.FromUriComponent(
pattern.Substring(split));
}
}
else
{
if (pattern.StartsWith(ForwardSlash))
{
context.HttpContext.Request.Path = PathString.FromUriComponent(pattern);
}
else
{
context.HttpContext.Request.Path = PathString.FromUriComponent(ForwardSlash + pattern);
}
if (QueryStringDelete)
{
context.HttpContext.Request.QueryString = QueryString.Empty;
}
}
}
context.Result = Result;
}
}
}