Example #1
0
        public void ExecuteResult(HttpContextBase httpContext, ProcessInboundRulesResult ruleResult)
        {
            var httpRequest  = httpContext.Request;
            var httpResponse = httpContext.Response;

            var responseHeaders = ruleResult.ProcessedResults.SelectMany(e => e.ResponseHeaders);
            var replacements    = new RewriteHelper.Replacements
            {
                RequestHeaders         = RequestHeaders,
                RequestServerVariables = RequestServerVariables
            };

            httpResponse.Clear();

            foreach (var responseHeader in responseHeaders)
            {
                var responseHeaderValue = RewriteHelper.ReplaceTokens(replacements, responseHeader.Value);
                httpResponse.Headers.Set(responseHeader.VariableName, responseHeaderValue);
            }

            if (ruleResult.FinalAction is IBaseRedirect)
            {
                if (Configuration.AnalyticsTrackingEnabled)
                {
                    Tracking.TrackRedirect(ruleResult);
                }

                var redirectAction = ruleResult.FinalAction as IBaseRedirect;
                int statusCode;

                if (redirectAction.StatusCode.HasValue)
                {
                    statusCode = (int)(redirectAction.StatusCode.Value);
                }
                else
                {
                    statusCode = (int)HttpStatusCode.MovedPermanently;
                }

                httpResponse.RedirectLocation = ruleResult.RewrittenUri.ToString();
                httpResponse.StatusCode       = statusCode;

                if (redirectAction.HttpCacheability.HasValue)
                {
                    httpResponse.Cache.SetCacheability(redirectAction.HttpCacheability.Value);
                }
            }
            else if (ruleResult.FinalAction is IBaseRewrite)
            {
                var rewrittenUrl = ruleResult.RewrittenUri;

                var isLocal = String.Equals(httpRequest.Url.Host, rewrittenUrl.Host,
                                            StringComparison.OrdinalIgnoreCase);

                if (!isLocal)
                {
                    throw new ApplicationException("Rewrite Url must be a local URL");
                }

                httpContext.Server.TransferRequest(rewrittenUrl.PathAndQuery, true, httpRequest.HttpMethod, RequestHeaders, true);
            }
            else if (ruleResult.FinalAction is AbortRequest)
            {
                // do nothing
            }
            else if (ruleResult.FinalAction is CustomResponse)
            {
                var customResponse = ruleResult.FinalAction as CustomResponse;

                httpResponse.TrySkipIisCustomErrors = true;

                httpResponse.StatusCode        = customResponse.StatusCode;
                httpResponse.StatusDescription = customResponse.ErrorDescription;

                // TODO: Implement Status Reason?
                //httpResponse.??? = customResponse.Reason;

                if (customResponse.SubStatusCode.HasValue)
                {
                    httpResponse.SubStatusCode = customResponse.SubStatusCode.Value;
                }
            }

            httpResponse.End();
        }
Example #2
0
        private InboundRuleResult ProcessRegularExpressionInboundRule(Uri originalUri, InboundRule inboundRule)
        {
            var ruleResult = new InboundRuleResult
            {
                OriginalUri  = originalUri,
                RewrittenUri = originalUri
            };

            Match inboundRuleMatch,
                  lastConditionMatch = null;

            // test rule match
            var isInboundRuleMatch = TestRuleMatches(inboundRule, originalUri, out inboundRuleMatch);
            ConditionMatchResult conditionMatchResult = null;

            // test conditions matches
            if (isInboundRuleMatch && inboundRule.Conditions != null && inboundRule.Conditions.Any())
            {
                var replacements = new RewriteHelper.Replacements
                {
                    RequestHeaders         = RequestHeaders,
                    RequestServerVariables = RequestServerVariables
                };

                conditionMatchResult = RewriteHelper.TestConditionMatches(inboundRule, replacements, out lastConditionMatch);
                isInboundRuleMatch   = conditionMatchResult.Matched;
            }

            // test site name restrictions
            if (isInboundRuleMatch && !string.IsNullOrEmpty(inboundRule.SiteNameRestriction))
            {
                isInboundRuleMatch = TestSiteNameRestriction(inboundRule);
            }

            if (isInboundRuleMatch && inboundRule.Action != null)
            {
                ruleResult.RuleMatched = true;

                if (inboundRule.ResponseHeaders.Any())
                {
                    ruleResult.ResponseHeaders = inboundRule.ResponseHeaders;
                }

                Log.Debug(this, "INBOUND RULE MATCH - requestUri: {0} inboundRule: {1}", originalUri, inboundRule.Name);

                // TODO: Need to implement Rewrite, None

                if (inboundRule.Action is Redirect)
                {
                    ProcessRedirectAction(inboundRule, originalUri, inboundRuleMatch, lastConditionMatch, ruleResult);
                }
                else if (inboundRule.Action is Rewrite)
                {
                    ProcessRewriteAction(inboundRule, originalUri, inboundRuleMatch, lastConditionMatch, ruleResult);
                }
                else if (inboundRule.Action is ItemQueryRedirect)
                {
                    ProcessItemQueryRedirectAction(inboundRule, originalUri, inboundRuleMatch, lastConditionMatch, ruleResult);
                }
                else if (inboundRule.Action is AbortRequest || inboundRule.Action is CustomResponse)
                {
                    ProcessActionProcessing(ruleResult);
                }
                else
                {
                    throw new NotImplementedException("Redirect Action, Custome Response and Abort Reqeust Action are the only supported type of redirects");
                }

                ruleResult.ResultAction         = inboundRule.Action;
                ruleResult.ConditionMatchResult = conditionMatchResult;
            }
            else if (inboundRule.Action == null)
            {
                Log.Warn(this, "Inbound Rule has no Action set - inboundRule: {0} inboundRule ItemId: {1}", inboundRule.Name, inboundRule.ItemId);

                // we are going to skip this because we don't know what to do with it during processing
                ruleResult.RuleMatched = false;
            }

            return(ruleResult);
        }
Example #3
0
        private static string ProcessRuleReplacementsWithMatchTags(string responseString, Using?outboundRuleUsing,
                                                                   IEnumerable <MatchTag> matchTags, string rewritePattern, string rewriteValue)
        {
            const string startKey      = "start";
            const string innerKey      = "inner";
            const string endKey        = "end";
            const string nameKey       = "name";
            const string startquoteKey = "startquote";
            const string valueKey      = "value";
            const string endquoteKey   = "endquote";

            const string tagPatternFormat =
                @"(?<" + startKey + @"><{0}\s+)(?<" + innerKey + @">.*?{1}=(?:""|').*?)(?<" + endKey + @">\s*/?>)";

            const string attributePatternFormat =
                @"(?<" + nameKey + @">{0}=)(?<" + startquoteKey + @">""|')(?<" + valueKey + @">.*?)(?<" +
                endquoteKey + @">""|')";

            var output = responseString;

            foreach (var matchTag in matchTags)
            {
                var tag        = matchTag.Tag;
                var attribute  = matchTag.Attribute;
                var tagPattern = string.Format(tagPatternFormat, tag, attribute);
                var tagRegex   = new Regex(tagPattern);

                output = tagRegex.Replace(responseString, tagMatch =>
                {
                    var tagMatchGroups   = tagMatch.Groups;
                    var tagStart         = tagMatchGroups[startKey].Value;
                    var tagInnards       = tagMatchGroups[innerKey].Value;
                    var tagEnd           = tagMatchGroups[endKey].Value;
                    var attributePattern = string.Format(attributePatternFormat, attribute);
                    var attributeRegex   = new Regex(attributePattern);

                    var newTagInnards = attributeRegex.Replace(tagInnards, attributeMatch =>
                    {
                        var attributeMatchGroups = attributeMatch.Groups;
                        var attributeValue       = attributeMatchGroups[valueKey].Value;

                        var attributeValueRegex = new Regex(rewritePattern);
                        var attributeValueMatch = attributeValueRegex.Match(attributeValue);

                        if (attributeValueMatch.Success)
                        {
                            var attributeName       = attributeMatchGroups[nameKey].Value;
                            var attributeStartQuote = attributeMatchGroups[startquoteKey].Value;
                            var attributeEndQuote   = attributeMatchGroups[endquoteKey].Value;

                            // need to determine where the match occurs within the original string
                            var attributeValueMatchIndex  = attributeValueMatch.Index;
                            var attributeValueMatchLength = attributeValueMatch.Length;
                            string attributeValueReplaced;

                            if (outboundRuleUsing == Using.ExactMatch)
                            {
                                attributeValueReplaced = attributeValueMatch.Value.Replace(
                                    attributeValueMatch.Value, rewriteValue);
                            }
                            else
                            {
                                attributeValueReplaced = RewriteHelper.ReplaceRuleBackReferences(attributeValueMatch,
                                                                                                 rewriteValue);
                            }

                            var newAttributeValue = attributeValue.Substring(0, attributeValueMatchIndex) +
                                                    attributeValueReplaced +
                                                    attributeValue.Substring(attributeValueMatchIndex +
                                                                             attributeValueMatchLength);

                            var attributeOutput = attributeName + attributeStartQuote + newAttributeValue +
                                                  attributeEndQuote;

                            return(attributeOutput);
                        }

                        return(attributeMatch.Value);
                    });

                    var tagOutput = tagStart + newTagInnards + tagEnd;

                    return(tagOutput);
                });
            }
            return(output);
        }