/// <summary>
		/// Initializes a new instance of the <see cref="RuleSetContext"/> class.
		/// </summary>
		/// <param name="copy">The copy.</param>
		internal RuleSetContext(RuleSetContext copy)
		{
			if (copy == null)
				throw new ArgumentNullException("copy");

			RuleSet = copy.RuleSet;
			RequestedUrl = copy.RequestedUrl;
			_responseContent = copy._responseContent;
			HttpContext = copy.HttpContext;
			IsOutputRuleSet = copy.IsOutputRuleSet;
			LogCategory = String.Empty;
		}
예제 #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="RuleSetContext"/> class.
        /// </summary>
        /// <param name="copy">The copy.</param>
        internal RuleSetContext(RuleSetContext copy)
        {
            if (copy == null)
            {
                throw new ArgumentNullException("copy");
            }

            RuleSet          = copy.RuleSet;
            RequestedUrl     = copy.RequestedUrl;
            _responseContent = copy._responseContent;
            HttpContext      = copy.HttpContext;
            IsOutputRuleSet  = copy.IsOutputRuleSet;
            LogCategory      = String.Empty;
        }
		/// <summary>
		/// Initializes a new instance of the <see cref="RuleContext"/> class.
		/// </summary>
		/// <param name="index">The index.</param>
		/// <param name="ruleSetContext">The rule set context.</param>
		/// <param name="currentContent"></param>
		/// <param name="rule">The rule.</param>
		public RuleContext(int index, RuleSetContext ruleSetContext, byte[] currentContent, IRule rule)
			: base(ruleSetContext)
		{
			if (currentContent == null)
				throw new ArgumentNullException("currentContent");

			if (rule == null)
				throw new ArgumentNullException("rule");

			RuleIndex = index;
			LogCategory = "Rule " + index;
			_currentContent = currentContent;
			_substitutedContent = currentContent;
			CurrentUrl = ruleSetContext.RequestedUrl;
			_substitutedUrl = ruleSetContext.RequestedUrl;
			CurrentRule = rule;
		}
        /// <summary>
        /// Initializes a new instance of the <see cref="RuleContext"/> class.
        /// </summary>
        /// <param name="index">The index.</param>
        /// <param name="ruleSetContext">The rule set context.</param>
        /// <param name="currentContent"></param>
        /// <param name="rule">The rule.</param>
        public RuleContext(int index, RuleSetContext ruleSetContext, byte[] currentContent, IRule rule)
            : base(ruleSetContext)
        {
            if (currentContent == null)
            {
                throw new ArgumentNullException("currentContent");
            }

            if (rule == null)
            {
                throw new ArgumentNullException("rule");
            }

            RuleIndex           = index;
            LogCategory         = "Rule " + index;
            _currentContent     = currentContent;
            _substitutedContent = currentContent;
            CurrentUrl          = ruleSetContext.RequestedUrl;
            _substitutedUrl     = ruleSetContext.RequestedUrl;
            CurrentRule         = rule;
        }
예제 #5
0
        /// <summary>
        /// Gets the value.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <returns></returns>
        public string GetValue(string input, RuleSetContext context)
        {
            // if the value has already been cached then return that value instead of reprocessing
            if (GetKeyValue(context.HttpContext) != null)
            {
                return(GetKeyValue(context.HttpContext));
            }

            string value = String.Empty;

            if ((_type & ServerVariableType.ServerVariables) != 0)
            {
                value = context.HttpContext.Request.ServerVariables[_name];

                // check to see if the value was found if not try the switch statement
                if (String.IsNullOrEmpty(value))
                {
                    switch (_name)
                    {
                    case "TIME_YEAR":
                        value = DateTime.Today.Year.ToString();
                        break;

                    case "TIME_MON":
                        value = DateTime.Today.Month.ToString();
                        break;

                    case "TIME_DAY":
                        value = DateTime.Today.Day.ToString();
                        break;

                    case "TIME_HOUR":
                        value = DateTime.Now.Hour.ToString();
                        break;

                    case "TIME_MIN":
                        value = DateTime.Now.Minute.ToString();
                        break;

                    case "TIME_SEC":
                        value = DateTime.Now.Second.ToString();
                        break;

                    case "TIME_WDAY":
                        value = DateTime.Today.DayOfWeek.ToString();
                        break;

                    case "TIME":
                        value = DateTime.Now.ToString("f");
                        break;

                    case "API_VERSION":
                        value = String.Empty;
                        break;                                // TODO: figure out how to attack this

                    case "THE_REQUEST":
                        value = context.HttpContext.Request.ServerVariables["REQUEST_METHOD"] + " " + context.HttpContext.Request.ServerVariables["PATH_INFO"] + " " + context.HttpContext.Request.ServerVariables["SERVER_PROTOCOL"];
                        break;

                    case "REQUEST_URI":
                        value = context.HttpContext.Request.ServerVariables["URL"];
                        break;

                    case "REQUEST_FILENAME":
                        value = context.HttpContext.Request.ServerVariables["PATH_TRANSLATED"];
                        break;

                    case "IS_SUBREQ":
                        value = String.IsNullOrEmpty(context.HttpContext.Request.Headers["X-Rewriter-Transfer"]) ? Boolean.FalseString : Boolean.TrueString;
                        break;
                    }
                }
            }
            else if ((_type & ServerVariableType.Headers) != 0)
            {
                value = context.HttpContext.Request.Headers[_name];
            }
            else if ((_type & ServerVariableType.QueryString) != 0)
            {
                value = context.HttpContext.Request.QueryString[_name];
            }
            else if ((_type & ServerVariableType.Form) != 0)
            {
                value = context.HttpContext.Request.Form[_name];
            }
            else if ((_type & ServerVariableType.Cookies) != 0)
            {
                var cookie = context.HttpContext.Request.Cookies[_name];

                // if cookie was found set the value to the value of the cookie
                if (cookie != null)
                {
                    value = cookie.Value;
                }
            }

            Manager.LogIf(context.LogLevel >= 2, "Input: " + value, context.LogCategory);

            SetKeyValue(context.HttpContext, value);
            return(value);
        }
		/// <summary>
		/// Gets the value.
		/// </summary>
		/// <param name="context">The context.</param>
		/// <returns></returns>
		public string GetValue(string input, RuleSetContext context)
		{
			// if the value has already been cached then return that value instead of reprocessing
			if (GetKeyValue(context.HttpContext) != null)
				return GetKeyValue(context.HttpContext);

			string value = String.Empty;

			if ((_type & ServerVariableType.ServerVariables) != 0)
			{
				value = context.HttpContext.Request.ServerVariables[_name];

				// check to see if the value was found if not try the switch statement
				if (String.IsNullOrEmpty(value))
				{
					switch (_name)
					{
						case "TIME_YEAR":
							value = DateTime.Today.Year.ToString();
							break;
						case "TIME_MON":
							value = DateTime.Today.Month.ToString();
							break;
						case "TIME_DAY":
							value = DateTime.Today.Day.ToString();
							break;
						case "TIME_HOUR":
							value = DateTime.Now.Hour.ToString();
							break;
						case "TIME_MIN":
							value = DateTime.Now.Minute.ToString();
							break;
						case "TIME_SEC":
							value = DateTime.Now.Second.ToString();
							break;
						case "TIME_WDAY":
							value = DateTime.Today.DayOfWeek.ToString();
							break;
						case "TIME":
							value = DateTime.Now.ToString("f");
							break;
						case "API_VERSION":
							value = String.Empty;
							break;// TODO: figure out how to attack this
						case "THE_REQUEST":
							value = context.HttpContext.Request.ServerVariables["REQUEST_METHOD"] + " " + context.HttpContext.Request.ServerVariables["PATH_INFO"] + " " + context.HttpContext.Request.ServerVariables["SERVER_PROTOCOL"];
							break;
						case "REQUEST_URI":
							value = context.HttpContext.Request.ServerVariables["URL"];
							break;
						case "REQUEST_FILENAME":
							value = context.HttpContext.Request.ServerVariables["PATH_TRANSLATED"];
							break;
						case "IS_SUBREQ":
							value = String.IsNullOrEmpty(context.HttpContext.Request.Headers["X-Rewriter-Transfer"]) ? Boolean.FalseString : Boolean.TrueString;
							break;
					}
				}
			}
			else if ((_type & ServerVariableType.Headers) != 0)
				value = context.HttpContext.Request.Headers[_name];
			else if ((_type & ServerVariableType.QueryString) != 0)
				value = context.HttpContext.Request.QueryString[_name];
			else if ((_type & ServerVariableType.Form) != 0)
				value = context.HttpContext.Request.Form[_name];
			else if ((_type & ServerVariableType.Cookies) != 0)
			{
				var cookie = context.HttpContext.Request.Cookies[_name];

				// if cookie was found set the value to the value of the cookie
				if (cookie != null)
					value = cookie.Value;
			}

			Manager.LogIf(context.LogLevel >= 2, "Input: " + value, context.LogCategory);

			SetKeyValue(context.HttpContext, value);
			return value;
		}
예제 #7
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="httpContext"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        public byte[] RunOutputRules(HttpContextBase httpContext, byte[] content)
        {
            var context = new RuleSetContext(this, content, httpContext);

            byte[] currentContent = content;

            if (!EngineEnabled)
            {
                Manager.LogIf(!EngineEnabled && LogLevel >= 9, "Rewrite Engine Is DISABLED", "OutRewrite");
            }

            if (_outputRules.Count > 0 && EngineEnabled)
            {
                Manager.LogIf(LogLevel >= 1, "**********************************************************************************");
                //Manager.LogIf(LogLevel >= 9, "Input: " + currentContent, "OutRewrite");

                var    temporyFlags   = (IRuleFlagProcessor)null;
                bool   skipNextChain  = false;
                byte[] initialContent = currentContent;

                // process rules according to their settings
                for (int i = 0; i < _outputRules.Count; i++)
                {
                    var ruleContext = new RuleContext(i, context, currentContent, _outputRules[i]);
                    temporyFlags = _outputRules[i].Flags;

                    bool containsChain         = RuleFlagsProcessor.HasChain(_outputRules[i].Flags);
                    bool previousContainsChain = RuleFlagsProcessor.HasChain(_outputRules[Math.Max(0, i - 1)].Flags);

                    // if the previous rule doesn't contain a chain flag then set the initial URL
                    // this will be used to reset a chain if one of the chain rules fail
                    if (!previousContainsChain)
                    {
                        initialContent = currentContent;
                    }

                    // skip if the current rule or the last rule has a chain flag
                    // and if the skip next chain is set
                    if (skipNextChain && (previousContainsChain || containsChain))
                    {
                        continue;
                    }
                    else
                    {
                        skipNextChain = false;
                    }

                    if (_outputRules[i].TryExecute(ruleContext))
                    {
                        var flagResponse = temporyFlags.Apply(ruleContext);
                        currentContent = ruleContext.SubstitutedContent;
                        i = ruleContext.RuleIndex ?? -1;
                        bool breakLoop = false;

                        // apply the flags to the rules, and only do special processing
                        // for the flag responses listed in the switch statement below
                        switch (flagResponse)
                        {
                        case RuleFlagProcessorResponse.ExitRuleSet:
                            return(null);

                        case RuleFlagProcessorResponse.LastRule:
                            breakLoop = true;
                            break;
                        }

                        // break the loop because we have reached the last rule as indicated by a flag
                        if (breakLoop)
                        {
                            break;
                        }
                    }
                    else if (containsChain)
                    {
                        skipNextChain = true;

                        // reset the current URL back to the initial URL from the start of the chain
                        currentContent = initialContent;
                    }
                    else if (previousContainsChain)
                    {
                        // reset the current URL back to the initial URL from the start of the chain
                        currentContent = initialContent;
                    }
                }

                //Manager.LogIf(LogLevel >= 9, "Output: " + currentContent, "OutRewrite");
                Manager.LogIf(LogLevel >= 1, "**********************************************************************************");
            }

            return(currentContent);
        }
예제 #8
0
        /// <summary>
        /// Runs the rules.
        /// </summary>
        /// <param name="httpContext">The HTTP context.</param>
        /// <param name="url">The URL.</param>
        /// <returns>
        /// Returns a rewritten <see cref="System.Uri"/>, or a value of <see langword="null"/> if no rewriting was done to <paramref name="url"/>.
        /// </returns>
        public Uri RunRules(HttpContextBase httpContext, Uri url)
        {
            var context    = new RuleSetContext(this, url, httpContext);
            var currentUrl = url;

            if (!EngineEnabled)
            {
                Manager.LogIf(!EngineEnabled && LogLevel >= 9, "Rewrite Engine Is DISABLED", "Rewrite");
            }

            if (_rules.Count > 0 && EngineEnabled)
            {
                Manager.LogIf(LogLevel >= 1, "**********************************************************************************");
                Manager.LogIf(LogLevel >= 1, "Input: " + currentUrl, "Rewrite");

                // check if max number of internal transfers have been exceeded
                if (InternalTransferCount(httpContext) > MaxInternalTransfers)
                {
                    string message = "Exceeded the max number of internal transfers.";
                    Manager.LogIf(LogLevel >= 1, message, "Error");
                    throw new HttpException(500, message);
                }

                var temporyFlags  = (IRuleFlagProcessor)null;
                var skipNextChain = false;
                var initialUrl    = currentUrl;

                if (!String.IsNullOrEmpty(VirtualBase) && VirtualBase != "/")
                {
                    currentUrl = RemoveBase(VirtualBase, currentUrl);
                }

                // process rules according to their settings
                for (int i = 0; i < _rules.Count; i++)
                {
                    var ruleContext = new RuleContext(i, context, currentUrl, _rules[i]);
                    temporyFlags = _rules[i].Flags;

                    // continue if this rule shouldn't be processed because it doesn't allow internal transfer requests
                    if (RuleFlagsProcessor.HasNotForInternalSubRequests(temporyFlags) && IsInternalTransfer(httpContext))
                    {
                        continue;
                    }

                    bool containsChain         = RuleFlagsProcessor.HasChain(_rules[i].Flags);
                    bool previousContainsChain = RuleFlagsProcessor.HasChain(_rules[Math.Max(0, i - 1)].Flags);

                    // if the previous rule doesn't contain a chain flag then set the initial URL
                    // this will be used to reset a chain if one of the chain rules fail
                    if (!previousContainsChain)
                    {
                        initialUrl = currentUrl;
                    }

                    // skip if the current rule or the last rule has a chain flag
                    // and if the skip next chain is set
                    if (skipNextChain && (previousContainsChain || containsChain))
                    {
                        continue;
                    }
                    else
                    {
                        skipNextChain = false;
                    }

                    if (_rules[i].TryExecute(ruleContext))
                    {
                        var flagResponse = temporyFlags.Apply(ruleContext);
                        currentUrl = ruleContext.SubstitutedUrl;
                        i          = ruleContext.RuleIndex ?? -1;
                        bool breakLoop = false;

                        // apply the flags to the rules, and only do special processing
                        // for the flag responses listed in the switch statement below
                        switch (flagResponse)
                        {
                        case RuleFlagProcessorResponse.ExitRuleSet:
                            return(null);

                        case RuleFlagProcessorResponse.LastRule:
                            breakLoop = true;
                            break;
                        }

                        // break the loop because we have reached the last rule as indicated by a flag
                        if (breakLoop)
                        {
                            break;
                        }
                    }
                    else if (containsChain)
                    {
                        skipNextChain = true;

                        // reset the current URL back to the initial URL from the start of the chain
                        currentUrl = initialUrl;
                    }
                    else if (previousContainsChain)
                    {
                        // reset the current URL back to the initial URL from the start of the chain
                        currentUrl = initialUrl;
                    }
                }

                // if the scheme, host, and ports do not match on the request vs the rewrite a redirect needs to be performed instead of a rewrite
                if (Uri.Compare(currentUrl, context.RequestedUrl, UriComponents.SchemeAndServer, UriFormat.SafeUnescaped, StringComparison.OrdinalIgnoreCase) != 0)
                {
                    Manager.LogIf(LogLevel >= 1, "Output: 302 Redirect to " + currentUrl, "Rewrite");
                    Manager.Redirect(httpContext, "found", currentUrl);
                }

                if (!String.IsNullOrEmpty(VirtualBase) && VirtualBase != "/")
                {
                    currentUrl = AddBase(VirtualBase, currentUrl);
                }

                Manager.LogIf(LogLevel >= 1, "Output: " + currentUrl, "Rewrite");
                Manager.LogIf(LogLevel >= 1, "**********************************************************************************");

                Manager.TryToAddXRewriteUrlHeader(httpContext);
                Manager.TryToAddVanityHeader(httpContext);
            }

            // if the http request url matches for both the request and the rewrite no work was done so the url should be null
            if (Uri.Compare(currentUrl, url, UriComponents.HttpRequestUrl, UriFormat.SafeUnescaped, StringComparison.OrdinalIgnoreCase) == 0)
            {
                currentUrl = null;
            }

            return(currentUrl);
        }
예제 #9
0
		/// <summary>
		/// 
		/// </summary>
		/// <param name="httpContext"></param>
		/// <param name="content"></param>
		/// <returns></returns>
		public byte[] RunOutputRules(HttpContextBase httpContext, byte[] content)
		{
			var context = new RuleSetContext(this, content, httpContext);
			byte[] currentContent = content;

			if (!EngineEnabled)
				Manager.LogIf(!EngineEnabled && LogLevel >= 9, "Rewrite Engine Is DISABLED", "OutRewrite");

			if (_outputRules.Count > 0 && EngineEnabled)
			{
				Manager.LogIf(LogLevel >= 1, "**********************************************************************************");
				//Manager.LogIf(LogLevel >= 9, "Input: " + currentContent, "OutRewrite");

				var temporyFlags = (IRuleFlagProcessor)null;
				bool skipNextChain = false;
				byte[] initialContent = currentContent;

				// process rules according to their settings
				for (int i = 0; i < _outputRules.Count; i++)
				{
					var ruleContext = new RuleContext(i, context, currentContent, _outputRules[i]);
					temporyFlags = _outputRules[i].Flags;

					bool containsChain = RuleFlagsProcessor.HasChain(_outputRules[i].Flags);
					bool previousContainsChain = RuleFlagsProcessor.HasChain(_outputRules[Math.Max(0, i - 1)].Flags);

					// if the previous rule doesn't contain a chain flag then set the initial URL
					// this will be used to reset a chain if one of the chain rules fail
					if (!previousContainsChain)
						initialContent = currentContent;

					// skip if the current rule or the last rule has a chain flag
					// and if the skip next chain is set
					if (skipNextChain && (previousContainsChain || containsChain))
						continue;
					else
						skipNextChain = false;

					if (_outputRules[i].TryExecute(ruleContext))
					{
						var flagResponse = temporyFlags.Apply(ruleContext);
						currentContent = ruleContext.SubstitutedContent;
						i = ruleContext.RuleIndex ?? -1;
						bool breakLoop = false;

						// apply the flags to the rules, and only do special processing
						// for the flag responses listed in the switch statement below
						switch (flagResponse)
						{
							case RuleFlagProcessorResponse.ExitRuleSet:
								return null;
							case RuleFlagProcessorResponse.LastRule:
								breakLoop = true;
								break;
						}

						// break the loop because we have reached the last rule as indicated by a flag
						if (breakLoop)
							break;
					}
					else if (containsChain)
					{
						skipNextChain = true;

						// reset the current URL back to the initial URL from the start of the chain
						currentContent = initialContent;
					}
					else if (previousContainsChain)
					{
						// reset the current URL back to the initial URL from the start of the chain
						currentContent = initialContent;
					}
				}

				//Manager.LogIf(LogLevel >= 9, "Output: " + currentContent, "OutRewrite");
				Manager.LogIf(LogLevel >= 1, "**********************************************************************************");
			}

			return currentContent;
		}
예제 #10
0
		/// <summary>
		/// Runs the rules.
		/// </summary>
		/// <param name="httpContext">The HTTP context.</param>
		/// <param name="url">The URL.</param>
		/// <returns>
		/// Returns a rewritten <see cref="System.Uri"/>, or a value of <see langword="null"/> if no rewriting was done to <paramref name="url"/>.
		/// </returns>
		public Uri RunRules(HttpContextBase httpContext, Uri url)
		{
			var context = new RuleSetContext(this, url, httpContext);
			var currentUrl = url;

			if (!EngineEnabled)
				Manager.LogIf(!EngineEnabled && LogLevel >= 9, "Rewrite Engine Is DISABLED", "Rewrite");

			if (_rules.Count > 0 && EngineEnabled)
			{
				Manager.LogIf(LogLevel >= 1, "**********************************************************************************");
				Manager.LogIf(LogLevel >= 1, "Input: " + currentUrl, "Rewrite");

				// check if max number of internal transfers have been exceeded
				if (InternalTransferCount(httpContext) > MaxInternalTransfers)
				{
					string message = "Exceeded the max number of internal transfers.";
					Manager.LogIf(LogLevel >= 1, message, "Error");
					throw new HttpException(500, message);
				}

				var temporyFlags = (IRuleFlagProcessor)null;
				var skipNextChain = false;
				var initialUrl = currentUrl;

				if (!String.IsNullOrEmpty(VirtualBase) && VirtualBase != "/")
					currentUrl = RemoveBase(VirtualBase, currentUrl);

				// process rules according to their settings
				for (int i = 0; i < _rules.Count; i++)
				{
					var ruleContext = new RuleContext(i, context, currentUrl, _rules[i]);
					temporyFlags = _rules[i].Flags;

					// continue if this rule shouldn't be processed because it doesn't allow internal transfer requests
					if (RuleFlagsProcessor.HasNotForInternalSubRequests(temporyFlags) && IsInternalTransfer(httpContext))
						continue;

					bool containsChain = RuleFlagsProcessor.HasChain(_rules[i].Flags);
					bool previousContainsChain = RuleFlagsProcessor.HasChain(_rules[Math.Max(0, i - 1)].Flags);

					// if the previous rule doesn't contain a chain flag then set the initial URL
					// this will be used to reset a chain if one of the chain rules fail
					if (!previousContainsChain)
						initialUrl = currentUrl;

					// skip if the current rule or the last rule has a chain flag
					// and if the skip next chain is set
					if (skipNextChain && (previousContainsChain || containsChain))
						continue;
					else
						skipNextChain = false;

					if (_rules[i].TryExecute(ruleContext))
					{
						var flagResponse = temporyFlags.Apply(ruleContext);
						currentUrl = ruleContext.SubstitutedUrl;
						i = ruleContext.RuleIndex ?? -1;
						bool breakLoop = false;

						// apply the flags to the rules, and only do special processing
						// for the flag responses listed in the switch statement below
						switch (flagResponse)
						{
							case RuleFlagProcessorResponse.ExitRuleSet:
								return null;
							case RuleFlagProcessorResponse.LastRule:
								breakLoop = true;
								break;
						}

						// break the loop because we have reached the last rule as indicated by a flag
						if (breakLoop)
							break;
					}
					else if (containsChain)
					{
						skipNextChain = true;

						// reset the current URL back to the initial URL from the start of the chain
						currentUrl = initialUrl;
					}
					else if (previousContainsChain)
					{
						// reset the current URL back to the initial URL from the start of the chain
						currentUrl = initialUrl;
					}
				}

				// if the scheme, host, and ports do not match on the request vs the rewrite a redirect needs to be performed instead of a rewrite
				if (Uri.Compare(currentUrl, context.RequestedUrl, UriComponents.SchemeAndServer, UriFormat.SafeUnescaped, StringComparison.OrdinalIgnoreCase) != 0)
				{
					Manager.LogIf(LogLevel >= 1, "Output: 302 Redirect to " + currentUrl, "Rewrite");
					Manager.Redirect(httpContext, "found", currentUrl);
				}

				if (!String.IsNullOrEmpty(VirtualBase) && VirtualBase != "/")
					currentUrl = AddBase(VirtualBase, currentUrl);

				Manager.LogIf(LogLevel >= 1, "Output: " + currentUrl, "Rewrite");
				Manager.LogIf(LogLevel >= 1, "**********************************************************************************");

				Manager.TryToAddXRewriteUrlHeader(httpContext);
				Manager.TryToAddVanityHeader(httpContext);
			}

			// if the http request url matches for both the request and the rewrite no work was done so the url should be null
			if (Uri.Compare(currentUrl, url, UriComponents.HttpRequestUrl, UriFormat.SafeUnescaped, StringComparison.OrdinalIgnoreCase) == 0)
				currentUrl = null;

			return currentUrl;
		}