@@ -7,22 +7,38 @@ import (
77 "regexp"
88 "strconv"
99 "strings"
10+ "text/template"
1011
12+ "github.com/Masterminds/sprig"
1113 "github.com/go-yaml/yaml"
1214 "go.uber.org/zap"
1315)
1416
17+ type FilterCfg struct {
18+ Name string `yaml:"name"`
19+ Match string `yaml:"match"`
20+ Template string `yaml:"template"`
21+ }
22+
23+ type FilterTemplate struct {
24+ Name string
25+ Match string
26+ Template * template.Template
27+ }
28+
1529// EngCfg defines an engine configuration
1630type EngCfg struct {
17- PostBan []string `yaml:"postBan"`
18- UrlBan []string `yaml:"urlBan"`
31+ PostBan []string `yaml:"postBan"`
32+ UrlBan []string `yaml:"urlBan"`
33+ Filter []FilterCfg `yaml:"postFilter"`
1934}
2035
2136// Eng http.Request rule engine.
2237type Eng struct {
2338 cfg EngCfg
2439 postBan []* regexp.Regexp
2540 urlBan []* regexp.Regexp
41+ filter map [* regexp.Regexp ]FilterTemplate
2642 logger * zap.Logger
2743}
2844
@@ -32,6 +48,27 @@ func (e *Eng) ProcessRequest(w http.ResponseWriter, r *http.Request) {
3248 b , _ := ioutil .ReadAll (r .Body )
3349 r .Body .Close ()
3450
51+ // run filter if there is a body
52+ if len (b ) > 0 {
53+ for rgx , filter := range e .filter {
54+
55+ // find the match first and populate data structure
56+ matches := rgx .FindAll (bytes .ToLower (b ), len (b ))
57+ for _ , match := range matches {
58+ filter .Match = string (match )
59+ // send the match to the template
60+ var tplReturn bytes.Buffer
61+ if err := filter .Template .Execute (& tplReturn , filter ); err != nil {
62+ // something bad happened
63+ e .logger .Error ("Filter failed: " + err .Error ())
64+ continue
65+ }
66+
67+ b = rgx .ReplaceAll (b , tplReturn .Bytes ())
68+ }
69+ }
70+ }
71+
3572 // search for qstring contraband
3673 for _ , rgx := range e .urlBan {
3774 buri := bytes .ToLower ([]byte (r .RequestURI ))
@@ -89,10 +126,26 @@ func NewEngFromYml(filename string, logger *zap.Logger) (*Eng, error) {
89126 urlBan = append (urlBan , rxp )
90127 }
91128
129+ filter := make (map [* regexp.Regexp ]FilterTemplate , 0 )
130+
131+ for _ , filterCfg := range engCfg .Filter {
132+ rxp := regexp .MustCompile (strings .ToLower (filterCfg .Match ))
133+ tmpl , err := template .New (filterCfg .Name ).Funcs (sprig .TxtFuncMap ()).Parse (filterCfg .Template )
134+ if err != nil {
135+ logger .Error ("Template parsing error: " + err .Error ())
136+ }
137+
138+ filter [rxp ] = FilterTemplate {
139+ Name : filterCfg .Name ,
140+ Template : tmpl ,
141+ }
142+ }
143+
92144 eng := & Eng {
93145 cfg : engCfg ,
94146 postBan : postBan ,
95147 urlBan : urlBan ,
148+ filter : filter ,
96149 logger : logger ,
97150 }
98151
0 commit comments