-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplugin.go
70 lines (60 loc) · 2.53 KB
/
plugin.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// This is the filter_on_field plugin. It contains the code that implements the
// Traefik interfaces, and filters requests based on the parameters passed in the configuration, allowing all values
// except those that match the disallowed content.
package traefik_filter_on_field
import (
"context"
"net/http"
"regexp"
)
// A configuration struct for the filter. This is populated from the Traefik configuration, regardless
// of whether it's used via the dynamic configuration or the static configuration.
type Config struct {
// The name of the field to filter on
FieldName string `yaml:"fieldName" json:"fieldName" toml:"fieldName" redis:"fieldName"`
// The message to return when disallowed content is found. This is returned as the Error Response body.
ResponseMessage string `yaml:"responseMessage" json:"responseMessage" toml:"responseMessage" redis:"responseMessage"`
// A group of regular expressions representing content that is not allowed
DisallowedContent []string `yaml:"disallowedContent" json:"disallowedContent" toml:"disallowedContent" redis:"disallowedContent"`
}
// The Filter On Field Struct that implements all of the Traefik interfaces in order to be used as a Traefik
// middleware plugin.
type FilterOnField struct {
next http.Handler
config *Config
name string
ctx context.Context
}
// Create a default version of the configuration.
func CreateConfig() *Config {
return &Config{
ResponseMessage: "Disallowed content",
}
}
// Create a new instance of the filter. This is called by Traefik when the plugin is loaded and returns a new instance of the filter.
// It takes a configuration struct, the next handler in the chain, and the name of the filter.
func New(ctx context.Context, next http.Handler, config *Config, name string) (http.Handler, error) {
return &FilterOnField{
next: next,
config: config,
name: name,
ctx: ctx,
}, nil
}
// The ServeHTTP method is called by Traefik when a request is received. It takes a response writer and a request. When the checks pass,
// it calls the next handler in the chain. When the checks fail, it returns an error response.
func (f *FilterOnField) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
parameter := req.FormValue(f.config.FieldName)
if parameter == "" {
f.next.ServeHTTP(rw, req)
}
for _, pattern := range f.config.DisallowedContent {
regex := regexp.MustCompile(pattern)
if regex.MatchString(parameter) {
rw.WriteHeader(http.StatusBadRequest)
rw.Write([]byte(f.config.ResponseMessage))
return
}
}
f.next.ServeHTTP(rw, req)
}