Documentation
¶
Overview ¶
Package rules contains implementation of all kinds of blocking rules.
Index ¶
- Constants
- func FillRequestForHostname(r *Request, hostname string)
- type CosmeticOption
- type CosmeticRule
- type CosmeticRuleType
- type DNSMX
- type DNSRewrite
- type DNSSRV
- type DNSSVCB
- type HostRule
- type ListID
- type MatchingResult
- type NetworkRule
- func (r *NetworkRule) GetFilterListID() (id ListID)
- func (r *NetworkRule) GetPermittedDomains() (domains []string)
- func (r *NetworkRule) IsGeneric() (ok bool)
- func (r *NetworkRule) IsHigherPriority(other *NetworkRule) (ok bool)
- func (r *NetworkRule) IsHostLevelNetworkRule() (ok bool)
- func (r *NetworkRule) IsOptionDisabled(option NetworkRuleOption) (ok bool)
- func (r *NetworkRule) IsOptionEnabled(option NetworkRuleOption) (ok bool)
- func (r *NetworkRule) IsRegexRule() (ok bool)
- func (r *NetworkRule) Match(req *Request) (ok bool)
- func (r *NetworkRule) String() (s string)
- func (r *NetworkRule) Text() (s string)
- type NetworkRuleOption
- type RCode
- type RRType
- type RRValue
- type Request
- type RequestType
- type Rule
- type RuleSyntaxError
Constants ¶
const ( // ErrTooWideRule is returned if the rule matches all URLs but has no // domain, denyallow, client, or ctag restrictions. ErrTooWideRule errors.Error = "the rule is too wide, add domain, denyallow, client, " + "or ctag restrictions or make it more specific" // ErrUnsupportedRule signals that this might be a valid rule type, but it // is not yet supported by this module. ErrUnsupportedRule errors.Error = "this type of rules is unsupported" )
const ( // MaskAnyCharacter is a wildcard character. It is used to represent any // set of characters. This can also be an empty string or a string of any // length. MaskAnyCharacter = "*" // MaskPipe points to the beginning or the end of address. The value // depends on the character placement in the mask. For example, a rule // like "swf|" matches "http://example.com/annoyingflash.swf", but not // "http://example.com/swf/index.html". "|http://example.org" matches // "http://example.org", but not "http://domain.com?url=http://example.org". MaskPipe = "|" // MaskSeparator is any character that isn't a letter, a digit, or one of // the following: '_', '-', '.', '%'. MaskSeparator = "^" // MaskStartURL matches the beginning of an address. It is used to not // specify a particular protocol and subdomain in address mask. That is, // "||" stands for "http://*.", "https://*.", "ws://*.", and "wss://*." all // at once. MaskStartURL = "||" )
const ( // RegexAnyCharacter corresponds to [MaskAnyCharacter]. RegexAnyCharacter = ".*" // RegexEndString corresponds to [MaskPipe] when it is at the end of a // pattern. RegexEndString = "$" // RegexSeparator corresponds to [MaskSeparator]. RegexSeparator = "([^ a-zA-Z0-9.%_-]|$)" // RegexStartString corresponds to [MaskPipe] when it is at the beginning of // a pattern. RegexStartString = "^" // RegexStartURL corresponds to [MaskStartURL]. RegexStartURL = `^(http|https|ws|wss)://([a-z0-9-_.]+\.)?` )
TODO(a.garipov): Rename consistently.
Variables ¶
This section is empty.
Functions ¶
func FillRequestForHostname ¶ added in v0.17.1
FillRequestForHostname fills the given instance of request r for matching the hostname. It uses "http://" as a protocol for request URL and TypeDocument as request type.
Types ¶
type CosmeticOption ¶
type CosmeticOption uint32
CosmeticOption is the bitset of various content script options.
const ( // CosmeticOptionGenericCSS is set if generic elemhide and CSS rules are // enabled. It can be disabled by a $generichide rule. CosmeticOptionGenericCSS CosmeticOption = 1 << iota // CosmeticOptionCSS is set if elemhide and CSS rules are enabled. It can // be disabled by an $elemhide rule. CosmeticOptionCSS // CosmeticOptionJS is set if JS rules and scriptlets are enabled. It can // be disabled by a $jsinject rule. CosmeticOptionJS CosmeticOptionSourceGenericCSS CosmeticOptionSourceCSS CosmeticOptionSourceJS CosmeticOptionAll = CosmeticOptionGenericCSS | CosmeticOptionCSS | CosmeticOptionJS CosmeticOptionNone = CosmeticOption(0) )
Valid CosmeticOption masks.
type CosmeticRule ¶
type CosmeticRule struct {
// Content meaning depends on the rule type:
// - Element hiding: content is just a selector;
// - CSS: content is a selector + style definition;
// - JS: text of the script to be injected.
Content string
// Type of the rule.
Type CosmeticRuleType
// Whitelist means that this rule is meant to disable rules with the same
// content on the specified domains.
//
// See https://adguard.com/kb/general/ad-filtering/create-own-filters/#elemhide-exceptions
//
// TODO(a.garipov): Consider unexporting.
Whitelist bool
// ExtendedCSS means that this rule is supposed to be applied by the
// Javascript library.
//
// See https://github.com/AdguardTeam/ExtendedCss.
ExtendedCSS bool
// contains filtered or unexported fields
}
CosmeticRule represents a cosmetic rule (element hiding, CSS, scriptlet).
func NewCosmeticRule ¶
func NewCosmeticRule(ruleText string, id ListID) (r *CosmeticRule, err error)
NewCosmeticRule parses the rule text and creates a rule.
func (*CosmeticRule) GetFilterListID ¶
func (r *CosmeticRule) GetFilterListID() (id ListID)
GetFilterListID implements the Rule interface for *CosmeticRule.
func (*CosmeticRule) GetPermittedDomains ¶
func (r *CosmeticRule) GetPermittedDomains() []string
GetPermittedDomains returns a slice of permitted domains.
func (*CosmeticRule) IsGeneric ¶
func (r *CosmeticRule) IsGeneric() (ok bool)
IsGeneric returns true if r is not limited to a specific domain.
func (*CosmeticRule) Match ¶
func (r *CosmeticRule) Match(hostname string) (ok bool)
Match returns true if this rule can be used on the specified hostname.
func (*CosmeticRule) String ¶
func (r *CosmeticRule) String() (s string)
String returns original rule text.
func (*CosmeticRule) Text ¶
func (r *CosmeticRule) Text() (s string)
Text implements the Rule interface for *CosmeticRule.
type CosmeticRuleType ¶
type CosmeticRuleType uint8
CosmeticRuleType is the enumeration of different cosmetic rule types.
const ( // CosmeticElementHiding is for ## rules. // // See https://adguard.com/kb/general/ad-filtering/create-own-filters/#cosmetic-elemhide-rules. CosmeticElementHiding CosmeticRuleType = iota // CosmeticCSS is for #$# rules. // // See https://adguard.com/kb/general/ad-filtering/create-own-filters/#cosmetic-css-rules. CosmeticCSS // CosmeticJS is for #%# rules. // // See https://adguard.com/kb/general/ad-filtering/create-own-filters/#javascript-rules. CosmeticJS // CosmeticHTML is for $$ rules. // // See https://adguard.com/kb/general/ad-filtering/create-own-filters/#html-filtering-rules. // // TODO(ameshkov): Move HTML filtering rules to a separate file/structure. CosmeticHTML )
Valid CosmeticRuleType values.
type DNSMX ¶ added in v0.14.1
DNSMX is the type of RRValue values returned for MX records in DNS rewrites.
type DNSRewrite ¶ added in v0.14.0
type DNSRewrite struct {
// Value is the value for the record. See [RRValue] documentation for more
// details.
Value RRValue
// NewCNAME is the new CNAME. If set, clients must ignore other fields,
// resolve the CNAME, and set the new records accordingly.
NewCNAME string
// RCode is the new DNS RCODE.
RCode RCode
// RRType is the new DNS resource record (RR) type. It is only non-zero
// if RCode is dns.RCodeSuccess.
RRType RRType
}
DNSRewrite is a DNS rewrite ($dnsrewrite) rule.
type DNSSRV ¶ added in v0.14.4
DNSSRV is the type of RRValue values returned for SRV records in DNS rewrites.
type DNSSVCB ¶ added in v0.14.1
DNSSVCB is the type of RRValue values returned for HTTPS and SVCB records in dns rewrites.
See https://tools.ietf.org/html/draft-ietf-dnsop-svcb-https-02.
type HostRule ¶
type HostRule struct {
// IP is the address of the rule.
IP netip.Addr
// Hostnames is the slice of hostnames associated with IP.
Hostnames []string
// contains filtered or unexported fields
}
HostRule is a structure for simple host-level rules, i.e. /etc/hosts syntax.
See http://man7.org/linux/man-pages/man5/hosts.5.html. It also supports "just domain" syntax; in that case, the IP will be set to 0.0.0.0.
TODO(a.garipov): Consider using [hostsfile.Record].
func NewHostRule ¶
NewHostRule parses the rule and creates a new *HostRule.
func (*HostRule) GetFilterListID ¶
GetFilterListID implements the Rule interface for *HostRule.
type ListID ¶ added in v0.22.0
type ListID uint64
ListID is the unique ID of a filtering-rule list.
TODO(a.garipov): See if there are better types for this. Currently, it is a uint64 to make it possible to use maphash and the similar hashing functions and also for performance reasons.
type MatchingResult ¶
type MatchingResult struct {
// BasicRule is a rule matching the request. It could lead to one of the
// following:
// - block the request;
// - unblock the request (a regular whitelist rule or a document-level
// whitelist rule);
// - modify the way cosmetic rules work for this request;
// - modify the response (see $redirect rules).
BasicRule *NetworkRule
// DocumentRule is a rule matching the request's referrer and having one of
// the following modifiers:
// - $document: this one basically disables everything;
// - $urlblock: disables network-level rules (not cosmetic);
// - $genericblock: disables generic network-level rules.
//
// Other document-level modifiers like $jsinject or $content will be ignored
// here as they don't do anything
DocumentRule *NetworkRule
// StealthRule is a whitelist rule that negates stealth-mode features. Note
// that the stealth rule can be received from both rules and sourceRules.
//
// See https://adguard.com/kb/general/ad-filtering/create-own-filters/#stealth-modifier.
StealthRule *NetworkRule
// CspRules are rules modifying the response's content-security-policy. See
// modifier $csp.
CspRules []*NetworkRule
// CookieRules are rules modifying the request's and response's cookies.
// See modifier $cookie.
CookieRules []*NetworkRule
// ReplaceRules are rules modifying the response's content. See modifier
// $replace.
ReplaceRules []*NetworkRule
}
MatchingResult contains all rules matching a web request and provides methods for processing of the request.
func NewMatchingResult ¶
func NewMatchingResult(rules, sourceRules []*NetworkRule) (res *MatchingResult)
NewMatchingResult returns a new properly initialized *MatchingResult. rules are the rules matching the request URL. sourceRules are the rules matching the referrer. Items of rules and sourceRules must not be nil.
func (*MatchingResult) GetBasicResult ¶
func (m *MatchingResult) GetBasicResult() (r *NetworkRule)
GetBasicResult returns a rule that should be applied to the web request.
Possible outcomes are:
- If r is nil, bypass the request.
- If r is a whitelist rule, bypass the request.
- If r is a blocking rule, block the request.
func (*MatchingResult) GetCosmeticOption ¶
func (m *MatchingResult) GetCosmeticOption() (o CosmeticOption)
GetCosmeticOption returns the cosmetic options.
type NetworkRule ¶
type NetworkRule struct {
// DNSRewrite is the DNS rewrite rule, if any.
DNSRewrite *DNSRewrite
// Shortcut is the longest substring of the rule pattern with no special
// characters.
Shortcut string
// Whitelist is true if this is an exception rule.
//
// TODO(a.garipov): Consider unexporting.
Whitelist bool
// contains filtered or unexported fields
}
NetworkRule is a basic filtering rule.
See https://adguard.com/kb/general/ad-filtering/create-own-filters/#basic-rules.
func GetDNSBasicRule ¶ added in v0.17.1
func GetDNSBasicRule(rules []*NetworkRule) (basicRule *NetworkRule)
GetDNSBasicRule returns a rule that should be applied to the DNS request. Elements of rules must not be nil.
func NewNetworkRule ¶
func NewNetworkRule(ruleText string, id ListID) (r *NetworkRule, err error)
NewNetworkRule parses the rule text and returns a filter rule.
func (*NetworkRule) GetFilterListID ¶
func (r *NetworkRule) GetFilterListID() (id ListID)
GetFilterListID implements the Rule interface for *NetworkRule.
func (*NetworkRule) GetPermittedDomains ¶
func (r *NetworkRule) GetPermittedDomains() (domains []string)
GetPermittedDomains returns the domains this rule is allowed on.
func (*NetworkRule) IsGeneric ¶
func (r *NetworkRule) IsGeneric() (ok bool)
IsGeneric returns true if the rule is considered generic. A generic rule is not restricted to a set of domains. Note that it might be forbidden on some domains, though.
func (*NetworkRule) IsHigherPriority ¶
func (r *NetworkRule) IsHigherPriority(other *NetworkRule) (ok bool)
IsHigherPriority checks if the rule has higher priority than the specified rule. The priority rules are:
- whitelist + $important;
- $important;
- whitelist;
- basic rules.
func (*NetworkRule) IsHostLevelNetworkRule ¶
func (r *NetworkRule) IsHostLevelNetworkRule() (ok bool)
IsHostLevelNetworkRule checks if this rule can be used for hosts-level blocking.
func (*NetworkRule) IsOptionDisabled ¶
func (r *NetworkRule) IsOptionDisabled(option NetworkRuleOption) (ok bool)
IsOptionDisabled returns true if the specified option is disabled.
func (*NetworkRule) IsOptionEnabled ¶
func (r *NetworkRule) IsOptionEnabled(option NetworkRuleOption) (ok bool)
IsOptionEnabled returns true if the specified option is enabled.
func (*NetworkRule) IsRegexRule ¶
func (r *NetworkRule) IsRegexRule() (ok bool)
IsRegexRule returns true if the rule is a regular expression rule.
func (*NetworkRule) Match ¶
func (r *NetworkRule) Match(req *Request) (ok bool)
Match checks if this filtering rule matches the specified request. req must not be nil.
func (*NetworkRule) String ¶
func (r *NetworkRule) String() (s string)
String returns original rule text.
func (*NetworkRule) Text ¶
func (r *NetworkRule) Text() (s string)
Text implements the Rule interface for *NetworkRule.
type NetworkRuleOption ¶
type NetworkRuleOption uint64
NetworkRuleOption is the bitset of various rule options.
const ( // OptionThirdParty means that the $third-party modifier is set. OptionThirdParty NetworkRuleOption = 1 << iota // OptionMatchCase means that the $match-case modifier is set. OptionMatchCase // OptionImportant means that the $important modifier is set. OptionImportant // OptionBadfilter means that the $badfilter modifier is set. OptionBadfilter // OptionElemhide means that the $elemhide modifier is set. OptionElemhide // OptionGenerichide means that the $generichide modifier is set. OptionGenerichide // OptionGenericblock means that the $genericblock modifier is set. OptionGenericblock // OptionJsinject means that the $jsinject modifier is set. OptionJsinject // OptionUrlblock means that the $urlblock modifier is set. OptionUrlblock // OptionContent means that the $content modifier is set. OptionContent // OptionExtension means that the $extension modifier is set. OptionExtension // OptionStealth means that the $stealth modifier is set. OptionStealth // OptionEmpty means that the $empty modifier is set. // // TODO(ameshkov): Get rid of it, as it is deprecated in favor of // $redirect. OptionEmpty // OptionMp4 means that the $mp4 modifier is set. // // TODO(ameshkov): Get rid of it, as it is deprecated in favor of // $redirect. OptionMp4 // OptionPopup means that the $popup modifier is set. OptionPopup // OptionCsp means that the $csp modifier is set. // // TODO(ameshkov): Implement. OptionCsp // OptionReplace means that the $replace modifier is set. // // TODO(ameshkov): Implement. OptionReplace // OptionCookie means that the $cookie modifier is set. // // TODO(ameshkov): Implement. OptionCookie // OptionRedirect means that the $redirect modifier is set. // // TODO(ameshkov): Implement. OptionRedirect // OptionBlacklistOnly are the blacklist-only options. OptionBlacklistOnly = OptionEmpty | OptionMp4 | OptionPopup // OptionWhitelistOnly are the whitelist-only options. OptionWhitelistOnly = OptionContent | OptionElemhide | OptionExtension | OptionGenericblock | OptionGenerichide | OptionJsinject | OptionStealth | OptionUrlblock // OptionHostLevelRulesOnly are the options supported by host-level network // rules. OptionHostLevelRulesOnly = OptionImportant | OptionBadfilter )
NetworkRuleOption masks.
TODO(a.garipov): Rename to NetworkOptionFoo etc.
func (NetworkRuleOption) Count ¶
func (o NetworkRuleOption) Count() (n int)
Count returns the number of enabled options.
type RCode ¶ added in v0.14.0
type RCode = int
RCode is a semantic alias for int when used as a DNS response code RCODE.
type RRType ¶ added in v0.14.0
type RRType = uint16
RRType is a semantic alias for uint16 when used as a DNS resource record (RR) type.
type RRValue ¶ added in v0.14.0
type RRValue = any
RRValue is the value of a resource record. Depending on the RRType, it will have different types:
- netip.Addr for dns.TypeA and dns.TypeAAAA;
- non-nil *DNSMX for dns.TypeMX;
- string for dns.TypePTR (it's also a valid FQDN);
- string for dns.TypeTXT;
- non-nil *DNSSVCB for dns.TypeHTTPS and dns.TypeSVCB;
- non-nil *DNSSRV for dns.TypeSRV;
- nil otherwise, but new types may be added in the future.
type Request ¶
type Request struct {
// ClientTags is the set of tags to match against $ctag modifiers.
ClientTags *container.SortedSliceSet[string]
// ClientIdentifiers is the list of client IDs to match against $client
// modifiers, if any.
ClientIdentifiers *container.SortedSliceSet[string]
// ClientIP is the IP address to match against $client modifiers, if any.
ClientIP netip.Addr
// URL is the full request URL.
URL string
// URLLowerCase is the full request URL in lower case.
URLLowerCase string
// Hostname is the hostname to filter.
Hostname string
// Domain is the effective top-level domain of the request with an
// additional label.
Domain string
// SourceURL is the full URL of the source.
SourceURL string
// SourceHostname is the hostname of the source.
SourceHostname string
// SourceDomain is the effective top-level domain of the source with an
// additional label.
SourceDomain string
// RequestType is the type of the filtering request.
RequestType RequestType
// DNSType is the type of the resource record (RR) of a DNS request, for
// example A or AAAA. See [RRValue] for all acceptable constants and their
// corresponding values.
DNSType uint16
// ThirdParty is true if the filtering request should consider $third-party
// modifier.
ThirdParty bool
// IsHostnameRequest means that the request is for a given Hostname, and not
// for a URL, and we don't really know what protocol it is. This can be
// true for DNS requests, for HTTP CONNECT, or for SNI matching.
IsHostnameRequest bool
}
Request is a web filtering request.
func NewRequest ¶
func NewRequest(url, sourceURL string, requestType RequestType) (r *Request)
NewRequest returns a properly initialized *Request.
func NewRequestForHostname ¶
NewRequestForHostname creates a new instance of Request for matching the hostname. It uses "http://" as a protocol and TypeDocument as a request type.
type RequestType ¶
type RequestType uint32
RequestType is a bitset of the types of a request to be filtered.
TODO(a.garipov): Consider switching to uint16.
const ( // TypeDocument means the main frame. TypeDocument RequestType = 1 << iota // TypeSubdocument means iframe requests; see the $subdocument modifier. TypeSubdocument // TypeScript means JavaScript and other script requests; see the $script // modifier. TypeScript // TypeStylesheet means CSS requests; see the $stylesheet modifier. TypeStylesheet // TypeObject means Flash and similar objects; see the $object modifier. TypeObject // TypeImage means images; see the $image modifier. TypeImage // TypeXmlhttprequest means AJAX or fetch requests, see the $xmlhttprequest // modifier. TypeXmlhttprequest // TypeMedia means video, music, etc.; see the $media modifier. TypeMedia // TypeFont means any custom font; see the $font modifier. TypeFont // TypeWebsocket means a WebSocket connection; see the $websocket modifier. TypeWebsocket // TypePing means navigator.sendBeacon() or ping attribute on links; see the // $ping modifier. TypePing // TypeOther means any other request type. TypeOther )
RequestType masks.
See https://adguard.com/kb/general/ad-filtering/create-own-filters/#content-type-modifiers.
TODO(a.garipov): Rename consistently.
func (RequestType) Count ¶
func (t RequestType) Count() (n int)
Count returns the number of the enabled request types.
type Rule ¶
type Rule interface {
// Text returns the original rule text.
//
// TODO(a.garipov): Replace with String.
Text() (s string)
// GetFilterListID returns ID of the filter list this rule belongs to.
//
// TODO(a.garipov): Rename to ListID.
GetFilterListID() (id ListID)
}
Rule is a base interface for all filtering rules.
TODO(a.garipov): Rename to Interface.
type RuleSyntaxError ¶
type RuleSyntaxError struct {
// contains filtered or unexported fields
}
RuleSyntaxError represents an error while parsing a filtering rule.
TODO(a.garipov): Consider implementing errors.Wrapper.
func (*RuleSyntaxError) Error ¶
func (e *RuleSyntaxError) Error() (s string)
Error implements the error interface for *RuleSyntaxError.