示例#1
0
        /// <summary>
        /// Removes verbose data from the constructed instance.
        /// </summary>
        public override void TrimExcessData()
        {
            ApplicableDomains.Clear();
            ExceptionDomains.Clear();

            OriginalRule = string.Empty;
        }
示例#2
0
        /// <summary>
        /// Determines whether or not this filter is a match for the supplied HTTP request/response.
        /// </summary>
        /// <param name="uri">
        /// The URI to check against for a match.
        /// </param>
        /// <param name="rawHeaders">
        /// The headers for the request/response we're checking to see if we match against. These may
        /// modify the capability to match depending on their content, such as content-type, etc.
        /// </param>
        /// <returns>
        /// True if this filter is a positive match against the supplied URI, false otherwise.
        /// </returns>
        public bool IsMatch(Uri uri, NameValueCollection rawHeaders)
        {
            // Make sure that the headers match up with our options.
            if (this.Options != UrlFilterOptions.None)
            {
                string headerVal          = null;
                long   xmlHttpRequestBits = ((OptionsLong & (long)UrlFilterOptions.ExceptXmlHttpRequest) | (OptionsLong & (long)UrlFilterOptions.XmlHttpRequest));
                if ((headerVal = rawHeaders.Get("X-Requested-With")) != null)
                {
                    if (headerVal.EqualsAtICase("XMLHttpRequest", 0))
                    {
                        xmlHttpRequestBits &= ~(long)UrlFilterOptions.XmlHttpRequest;
                    }
                    else
                    {
                        xmlHttpRequestBits &= ~(long)UrlFilterOptions.ExceptXmlHttpRequest;
                    }
                }

                if (xmlHttpRequestBits != 0)
                {
                    // XML HttpRequest bits were not cleared, meaning that one of those options was
                    // not satisifed.
                    return(false);
                }

                long thirdPartyBits = ((OptionsLong & (long)UrlFilterOptions.ThirdParty) | (OptionsLong & (long)UrlFilterOptions.ExceptThirdParty));
                if ((headerVal = rawHeaders.Get("Referer")) != null)
                {
                    if (Uri.TryCreate(headerVal, UriKind.RelativeOrAbsolute, out Uri refererUri))
                    {
                        string hostWithoutWww = refererUri.Host;

                        if (hostWithoutWww.StartsWithQuick("www."))
                        {
                            hostWithoutWww = hostWithoutWww.Substring(4);
                        }

                        if (hostWithoutWww.EqualsAtICase(uri.Host, 0))
                        {
                            thirdPartyBits &= ~(long)UrlFilterOptions.ExceptThirdParty;
                        }
                        else
                        {
                            thirdPartyBits &= ~(long)UrlFilterOptions.ThirdParty;
                        }


                        if (ApplicableDomains.Count > 0 && !ApplicableDomains.Contains(hostWithoutWww))
                        {
                            return(false);
                        }

                        if (ExceptionDomains.Count > 0 && ExceptionDomains.Contains(hostWithoutWww))
                        {
                            return(false);
                        }

                        // While we have the referer field, let's go ahead and check if we have
                        // referer options and if we do or don't have a match.
                        //
                        // This is a shortcut. We unfortunately need to also execute this code also
                        // when there are no options.
                        if (ApplicableReferers.Count > 0 && !ApplicableReferers.Contains(hostWithoutWww))
                        {
                            return(false);
                        }

                        if (ExceptReferers.Count > 0 && ExceptReferers.Contains(hostWithoutWww))
                        {
                            return(false);
                        }
                    }
                }
                else
                {
                    // The "Referer" field can be omitted when it's a brand new browser request/fresh
                    // browser context, meaning that this request is not third party in the least
                    // bit. So, we clear this bit in this special case.
                    thirdPartyBits &= ~(long)UrlFilterOptions.ExceptThirdParty;
                }

                if (thirdPartyBits != 0)
                {
                    // Third party bits not cleared, meaning that one of those options was not satisifed.
                    return(false);
                }

                long contentTypeBits = ((OptionsLong & (long)UrlFilterOptions.Image) | (OptionsLong & (long)UrlFilterOptions.Script) | (OptionsLong & (long)UrlFilterOptions.StyleSheet) | (OptionsLong & (long)UrlFilterOptions.ExceptImage) | (OptionsLong & (long)UrlFilterOptions.ExceptScript) | (OptionsLong & (long)UrlFilterOptions.ExceptStyleSheet));

                if ((headerVal = rawHeaders.Get("Content-Type")) != null)
                {
                    if (headerVal.IndexOfQuick("script") != -1)
                    {
                        contentTypeBits &= ~(long)UrlFilterOptions.Script;
                    }
                    else
                    {
                        contentTypeBits &= ~(long)UrlFilterOptions.ExceptScript;

                        if (headerVal.IndexOfQuick("image") != -1)
                        {
                            contentTypeBits &= ~(long)UrlFilterOptions.Image;
                        }
                        else
                        {
                            contentTypeBits &= ~(long)UrlFilterOptions.ExceptImage;

                            if (headerVal.IndexOfQuick("css") != -1)
                            {
                                contentTypeBits &= ~(long)UrlFilterOptions.StyleSheet;
                            }
                            else
                            {
                                contentTypeBits &= ~(long)UrlFilterOptions.ExceptStyleSheet;
                            }
                        }
                    }
                }

                if (contentTypeBits != 0)
                {
                    // XML HttpRequest bits were not cleared, meaning that one of those options was
                    // not satisifed.
                    return(false);
                }
            }
            else
            {
                if (ApplicableReferers.Count > 0 || ExceptReferers.Count > 0)
                {
                    string headerVal = null;
                    if ((headerVal = rawHeaders.Get("Referer")) != null)
                    {
                        if (Uri.TryCreate(headerVal, UriKind.RelativeOrAbsolute, out Uri refererUri))
                        {
                            string hostWithoutWww = refererUri.Host;

                            if (hostWithoutWww.StartsWithQuick("www."))
                            {
                                hostWithoutWww = hostWithoutWww.Substring(4);
                            }

                            if (ApplicableReferers.Count > 0 && !ApplicableReferers.Contains(hostWithoutWww))
                            {
                                return(false);
                            }

                            if (ExceptReferers.Count > 0 && ExceptReferers.Contains(hostWithoutWww))
                            {
                                return(false);
                            }
                        }
                    }
                }
            }

            if (ApplicableDomains.Count > 0 || ExceptionDomains.Count > 0)
            {
                string hostWithoutWww = uri.Host;

                if (hostWithoutWww.StartsWithQuick("www."))
                {
                    hostWithoutWww = hostWithoutWww.Substring(4);
                }

                if (ApplicableDomains.Count > 0 && !ApplicableDomains.Contains(hostWithoutWww))
                {
                    return(false);
                }

                if (ExceptionDomains.Count > 0 && ExceptionDomains.Contains(hostWithoutWww))
                {
                    return(false);
                }
            }

            int matchIndex = 0;

            foreach (var part in Parts)
            {
                matchIndex = part.IsMatch(uri, matchIndex);

                if (matchIndex == -1)
                {
                    return(false);
                }
            }

            // If all parts were found, then this match was a success.
            return(true);
        }