Help us shape the future of Go! Take the 2026 Go Developer Survey

rules

package
v0.23.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 25, 2026 License: GPL-3.0 Imports: 17 Imported by: 8

Documentation

Overview

Package rules contains implementation of all kinds of blocking rules.

Index

Constants

View Source
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, " +
		"respgeo, 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"
)
View Source
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 = "||"
)
View Source
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

func FillRequestForHostname(r *Request, hostname string)

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

type DNSMX struct {
	Exchange   string
	Preference uint16
}

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

type DNSSRV struct {
	Target   string
	Priority uint16
	Weight   uint16
	Port     uint16
}

DNSSRV is the type of RRValue values returned for SRV records in DNS rewrites.

type DNSSVCB added in v0.14.1

type DNSSVCB struct {
	Params   map[string]string
	Target   string
	Priority uint16
}

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

func NewHostRule(ruleText string, id ListID) (h *HostRule, err error)

NewHostRule parses the rule and creates a new *HostRule.

func (*HostRule) GetFilterListID

func (f *HostRule) GetFilterListID() (id ListID)

GetFilterListID implements the Rule interface for *HostRule.

func (*HostRule) Match

func (f *HostRule) Match(hostname string) (ok bool)

Match returns true if this filtering rule matches the specified hostname.

func (*HostRule) String

func (f *HostRule) String() (s string)

String returns original rule text.

func (*HostRule) Text

func (f *HostRule) Text() (s string)

Text 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:

  1. whitelist + $important;
  2. $important;
  3. whitelist;
  4. 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:

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

	// ResponseCountry is the country ISO code of the DNS response to match
	// the request target against rules with $respgeo modifiers, if any.  It is
	// ignored if [Request.IsAnswer] is false.
	ResponseCountry string

	// 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

	// ResponseASN is the AS number of the DNS response to match the request
	// target against rules with $respgeo modifiers, if any.  It is ignored if
	// [Request.IsAnswer] is false.
	ResponseASN uint32

	// 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

	// IsAnswer is true if the filtering request is for filtering a DNS
	// response.
	IsAnswer 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

	// ThirdParty is true if the filtering request should consider $third-party
	// modifier.
	ThirdParty 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

func NewRequestForHostname(hostname string) (r *Request)

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.

func NewRule

func NewRule(line string, id ListID) (r Rule, err error)

NewRule creates a new filtering rule from the specified line. It returns nil if the line is empty or if it is a comment.

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL