1
1
package block
2
2
3
3
import (
4
+ "bytes"
4
5
"encoding/hex"
5
- "errors"
6
6
7
7
"github.com/zalando/skipper/filters"
8
- )
9
-
10
- var (
11
- ErrClosed = errors .New ("reader closed" )
8
+ "github.com/zalando/skipper/io"
9
+ "github.com/zalando/skipper/metrics"
12
10
)
13
11
14
12
type blockSpec struct {
15
13
MaxMatcherBufferSize uint64
16
14
hex bool
17
15
}
18
16
17
+ type toBlockKeys struct { Str []byte }
18
+
19
+ func (b toBlockKeys ) String () string {
20
+ return string (b .Str )
21
+ }
22
+
19
23
type block struct {
20
- toblockList []toblockKeys
24
+ toblockList []toBlockKeys
21
25
maxEditorBuffer uint64
22
- maxBufferHandling maxBufferHandling
26
+ maxBufferHandling io.MaxBufferHandling
27
+ metrics metrics.Metrics
23
28
}
24
29
25
30
// NewBlockFilter *deprecated* version of NewBlock
@@ -52,7 +57,7 @@ func (bs *blockSpec) CreateFilter(args []interface{}) (filters.Filter, error) {
52
57
return nil , filters .ErrInvalidFilterParameters
53
58
}
54
59
55
- sargs := make ([]toblockKeys , 0 , len (args ))
60
+ sargs := make ([]toBlockKeys , 0 , len (args ))
56
61
for _ , w := range args {
57
62
v , ok := w .(string )
58
63
if ! ok {
@@ -63,33 +68,50 @@ func (bs *blockSpec) CreateFilter(args []interface{}) (filters.Filter, error) {
63
68
if err != nil {
64
69
return nil , err
65
70
}
66
- sargs = append (sargs , toblockKeys { str : a })
71
+ sargs = append (sargs , toBlockKeys { Str : a })
67
72
} else {
68
- sargs = append (sargs , toblockKeys { str : []byte (v )})
73
+ sargs = append (sargs , toBlockKeys { Str : []byte (v )})
69
74
}
70
75
}
71
76
72
- b := & block {
77
+ return & block {
73
78
toblockList : sargs ,
74
- maxBufferHandling : maxBufferBestEffort ,
79
+ maxBufferHandling : io . MaxBufferBestEffort ,
75
80
maxEditorBuffer : bs .MaxMatcherBufferSize ,
76
- }
81
+ metrics : metrics .Default ,
82
+ }, nil
83
+ }
77
84
78
- return * b , nil
85
+ func blockMatcher (m metrics.Metrics , matches []toBlockKeys ) func (b []byte ) (int , error ) {
86
+ return func (b []byte ) (int , error ) {
87
+ for _ , s := range matches {
88
+ s := s
89
+ if bytes .Contains (b , s .Str ) {
90
+ m .IncCounter ("blocked.requests" )
91
+ return 0 , io .ErrBlocked
92
+ }
93
+ }
94
+ return len (b ), nil
95
+ }
79
96
}
80
97
81
- func (b block ) Request (ctx filters.FilterContext ) {
98
+ func (b * block ) Request (ctx filters.FilterContext ) {
82
99
req := ctx .Request ()
83
100
if req .ContentLength == 0 {
84
101
return
85
102
}
86
-
87
- req .Body = newMatcher (
88
- req .Body ,
89
- b .toblockList ,
90
- b .maxEditorBuffer ,
91
- b .maxBufferHandling ,
92
- )
103
+ // fix filter chaining - https://github.com/zalando/skipper/issues/2605
104
+ ctx .Request ().Header .Del ("Content-Length" )
105
+ ctx .Request ().ContentLength = - 1
106
+
107
+ req .Body = io .InspectReader (
108
+ req .Context (),
109
+ io.BufferOptions {
110
+ MaxBufferHandling : b .maxBufferHandling ,
111
+ ReadBufferSize : b .maxEditorBuffer ,
112
+ },
113
+ blockMatcher (b .metrics , b .toblockList ),
114
+ req .Body )
93
115
}
94
116
95
- func (block ) Response (filters.FilterContext ) {}
117
+ func (* block ) Response (filters.FilterContext ) {}
0 commit comments