1"use strict";(self.webpackChunkrspamd_docs=self.webpackChunkrspamd_docs||[]).push([[5674],{25475:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>l,default:()=>h,frontMatter:()=>d,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"modules/trie","title":"Trie module","description":"Deprecation warning","source":"@site/docs/modules/trie.md","sourceDirName":"modules","slug":"/modules/trie","permalink":"/modules/trie","draft":false,"unlisted":false,"editUrl":"https://github.com/rspamd/docs.rspamd.com/edit/master/docs/modules/trie.md","tags":[],"version":"current","frontMatter":{"title":"Trie module"},"sidebar":"docs","previous":{"title":"SURBL module","permalink":"/modules/surbl"},"next":{"title":"URL redirector module","permalink":"/modules/url_redirector"}}');var s=n(74848),i=n(28453);const d={title:"Trie module"},l="Trie plugin",o={},c=[{value:"Deprecation warning",id:"deprecation-warning",level:3},{value:"Module description",id:"module-description",level:2},{value:"Configuration",id:"configuration",level:2},{value:"Per-rule options",id:"per-rule-options",level:2},{value:"Search modes",id:"search-modes",level:2}];function a(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"trie-plugin",children:"Trie plugin"})}),"\n",(0,s.jsx)(t.h3,{id:"deprecation-warning",children:"Deprecation warning"}),"\n",(0,s.jsxs)(t.p,{children:["This plugin is obsolete as all its functionality is now provided by the ",(0,s.jsx)(t.a,{href:"/modules/multimap",children:"multimap module"}),". The multimap module supports regular expressions and pattern-based rules that fully encompass the features listed below. Additionally, using the regular expressions module for the same purposes is safe, as these expressions are typically accelerated by a multi-pattern lookup engine. Therefore, there are no plans to remove it from Rspamd."]}),"\n",(0,s.jsx)(t.h2,{id:"module-description",children:"Module description"}),"\n",(0,s.jsx)(t.p,{children:"The Trie plugin is specifically designed for efficiently searching multiple strings within raw messages or text parts. It achieves this with remarkable speed by utilizing the aho-corasick algorithm, which performs exceptionally well even with large texts and numerous input strings."}),"\n",(0,s.jsx)(t.p,{children:"This module offers a user-friendly interface for working with the search trie structure."}),"\n",(0,s.jsx)(t.h2,{id:"configuration",children:"Configuration"}),"\n",(0,s.jsx)(t.p,{children:"Here is an example of trie configuration:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-hcl",children:'trie {\n\t# Each subsection defines a single rule with associated symbol\n\tSYMBOL1 {\n\t\t# Define rules in the file (it is *NOT* a map)\n\t\tfile = "/some/path";\n\t\t# Raw rules search within the whole undecoded messages\n\t\traw = true;\n\t\t# If we have multiple occurrences of strings from this rule\n\t\t# then we insert a symbol multiple times\n\t\tmulti = true;\n\t}\n\tSYMBOL2 {\n\t\tpatterns = [\n\t\t\t"pattern1",\n\t\t\t"pattern2",\n\t\t\t"pattern3"\n\t\t]\n\t}\n\tSYMBOL3 {\n\t\t# Search within decoded message body parts\n\t\tbody = true;\n\t\tpatterns = [\n\t\t\t"pattern4"\n\t\t]\n\t}\n}\n'})}),"\n",(0,s.jsx)(t.h2,{id:"per-rule-options",children:"Per-rule options"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Option"}),(0,s.jsx)(t.th,{children:"Type"}),(0,s.jsx)(t.th,{children:"Description"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"file"})}),(0,s.jsx)(t.td,{children:"string"}),(0,s.jsxs)(t.td,{children:["Path to a plain-text file of patterns, one per line; ",(0,s.jsx)(t.code,{children:"#"}),"-prefixed lines are skipped. Not a dynamic map \u2014 changes require reload."]})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"patterns"})}),(0,s.jsx)(t.td,{children:"list"}),(0,s.jsxs)(t.td,{children:["Inline list of pattern strings. Mutually exclusive with ",(0,s.jsx)(t.code,{children:"file"}),"."]})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"raw"})}),(0,s.jsx)(t.td,{children:"boolean"}),(0,s.jsxs)(t.td,{children:["Search the whole undecoded raw message. Mutually exclusive with ",(0,s.jsx)(t.code,{children:"body"}),"."]})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"body"})}),(0,s.jsx)(t.td,{children:"boolean"}),(0,s.jsxs)(t.td,{children:["Search the decoded message body (equivalent to ",(0,s.jsx)(t.code,{children:"search_rawbody"}),"). Mutually exclusive with ",(0,s.jsx)(t.code,{children:"raw"}),"."]})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"multi"})}),(0,s.jsx)(t.td,{children:"boolean"}),(0,s.jsx)(t.td,{children:"Insert the symbol once per match position rather than only once per pattern per message."})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"binary"})}),(0,s.jsx)(t.td,{children:"boolean"}),(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.strong,{children:"Not yet implemented."})," Setting this option logs an error and skips loading the pattern file."]})]})]})]}),"\n",(0,s.jsx)(t.h2,{id:"search-modes",children:"Search modes"}),"\n",(0,s.jsxs)(t.p,{children:["Each rule routes its patterns into exactly one of three tries, selected by ",(0,s.jsx)(t.code,{children:"raw"})," and ",(0,s.jsx)(t.code,{children:"body"}),":"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"MIME-part mode"})," (default \u2014 neither ",(0,s.jsx)(t.code,{children:"raw"})," nor ",(0,s.jsx)(t.code,{children:"body"})," set): patterns are searched across each decoded MIME text part via ",(0,s.jsx)(t.code,{children:"search_mime"}),"."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:(0,s.jsx)(t.code,{children:"raw = true"})}),": patterns are searched across the entire undecoded raw message via ",(0,s.jsx)(t.code,{children:"search_rawmsg"}),"."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:(0,s.jsx)(t.code,{children:"body = true"})}),": patterns are searched across the decoded message body via ",(0,s.jsx)(t.code,{children:"search_rawbody"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["Despite the Aho-Corasick trie's impressive speed, it only supports plain strings and lacks the ability to differentiate word boundaries. For instance, the string ",(0,s.jsx)(t.code,{children:"test"})," would be found in texts such as ",(0,s.jsx)(t.code,{children:"test"}),", ",(0,s.jsx)(t.code,{children:"tests"})," or even ",(0,s.jsx)(t.code,{children:"123testing"}),". As a result, it is more suitable for searching for specific and relatively precise patterns, rather than for matching whole words."]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>d,x:()=>l});var r=n(96540);const s={},i=r.createContext(s);function d(e){const t=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:d(e.components),r.createElement(i.Provider,{value:t},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.