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(); }
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); }
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); }