Skip to content

Commit e5a5ffd

Browse files
committed
新增响应过滤插件
1 parent 9cae36a commit e5a5ffd

8 files changed

Lines changed: 398 additions & 40 deletions

File tree

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,29 @@
11
package response_filter
22

3+
import (
4+
"fmt"
5+
"github.com/eolinker/eosc"
6+
)
7+
38
type Config struct {
4-
BodyFilter []string `json:"body_filter" label:"响应体过滤字段"`
5-
HeaderFilter []string `json:"header_filter" label:"响应头过滤字段"`
9+
BodyFilter []string `json:"body_filter" label:"响应体过滤字段"`
10+
HeaderFilter []string `json:"header_filter" label:"响应头过滤字段"`
11+
HeaderFilterType string `json:"header_filter_type" label:"响应头过滤类型" enum:"black,white" default:"black"`
12+
BodyFilterType string `json:"body_filter_type" label:"响应体过滤类型" enum:"black,white" default:"black"`
13+
}
14+
15+
func check(conf *Config, workers map[eosc.RequireId]eosc.IWorker) error {
16+
if conf.HeaderFilterType == "" {
17+
conf.HeaderFilterType = "black"
18+
}
19+
if conf.HeaderFilterType != "white" && conf.HeaderFilterType != "black" {
20+
return fmt.Errorf("header_filter_type must be white or black")
21+
}
22+
if conf.BodyFilterType == "" {
23+
conf.BodyFilterType = "black"
24+
}
25+
if conf.BodyFilterType != "white" && conf.BodyFilterType != "black" {
26+
return fmt.Errorf("body_filter_type must be white or black")
27+
}
28+
return nil
629
}

drivers/plugins/response-filter/executor.go

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
package response_filter
22

33
import (
4-
"github.com/ohler55/ojg/jp"
5-
"github.com/ohler55/ojg/oj"
6-
74
"github.com/eolinker/apinto/drivers"
85
"github.com/eolinker/eosc"
96
"github.com/eolinker/eosc/eocontext"
@@ -16,8 +13,7 @@ var _ eosc.IWorker = (*executor)(nil)
1613

1714
type executor struct {
1815
drivers.WorkerBase
19-
bodyFilter []jp.Expr
20-
headerFilter []string
16+
filters []IFilter
2117
}
2218

2319
func (e *executor) DoFilter(ctx eocontext.EoContext, next eocontext.IChain) (err error) {
@@ -32,23 +28,17 @@ func (e *executor) DoHttpFilter(ctx http_service.IHttpContext, next eocontext.IC
3228
return err
3329
}
3430
}
35-
body := ctx.Response().GetBody()
36-
n, err := oj.Parse(body)
37-
if err != nil {
38-
return err
39-
}
40-
for _, filter := range e.bodyFilter {
41-
filter.Del(n)
42-
}
43-
body, err = oj.Marshal(n)
44-
ctx.Response().SetBody(body)
45-
for _, filter := range e.headerFilter {
46-
ctx.Response().DelHeader(filter)
31+
for _, filter := range e.filters {
32+
err = filter.Filter(ctx)
33+
if err != nil {
34+
return err
35+
}
4736
}
4837
return nil
4938
}
5039

5140
func (e *executor) Destroy() {
41+
e.filters = nil
5242
return
5343
}
5444

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,62 @@
11
package response_filter
22

33
import (
4-
"strings"
5-
64
"github.com/eolinker/apinto/drivers"
75
"github.com/eolinker/eosc"
8-
"github.com/ohler55/ojg/jp"
96
)
107

118
const (
12-
Name = "response_filter"
9+
Name = "response_filter"
10+
WhiteFilterType = "white"
11+
BlackFilterType = "black"
1312
)
1413

1514
func Register(register eosc.IExtenderDriverRegister) {
1615
register.RegisterExtenderDriver(Name, NewFactory())
1716
}
1817

1918
func NewFactory() eosc.IExtenderDriverFactory {
20-
return drivers.NewFactory[Config](Create)
19+
return drivers.NewFactory[Config](Create, check)
2120
}
2221

2322
func Create(id, name string, conf *Config, workers map[eosc.RequireId]eosc.IWorker) (eosc.IWorker, error) {
24-
bodyFilter := make([]jp.Expr, 0, len(conf.BodyFilter))
25-
for _, filter := range conf.BodyFilter {
26-
key := filter
27-
if !strings.HasPrefix(key, "$.") {
28-
key = "$." + key
23+
filters := make([]IFilter, 0, 4)
24+
if len(conf.BodyFilter) > 0 {
25+
switch conf.BodyFilterType {
26+
case WhiteFilterType:
27+
filter, err := NewBodyWhiteFilter(conf.BodyFilter)
28+
if err != nil {
29+
return nil, err
30+
}
31+
filters = append(filters, filter)
32+
case BlackFilterType:
33+
filter, err := NewBodyBlackFilter(conf.BodyFilter)
34+
if err != nil {
35+
return nil, err
36+
}
37+
filters = append(filters, filter)
2938
}
30-
expr, err := jp.ParseString(filter)
31-
if err != nil {
32-
return nil, err
39+
}
40+
41+
if len(conf.HeaderFilter) > 0 {
42+
switch conf.HeaderFilterType {
43+
case WhiteFilterType:
44+
filter, err := NewHeaderWhiteFilter(conf.HeaderFilter)
45+
if err != nil {
46+
return nil, err
47+
}
48+
filters = append(filters, filter)
49+
case BlackFilterType:
50+
filter, err := NewHeaderBlackFilter(conf.HeaderFilter)
51+
if err != nil {
52+
return nil, err
53+
}
54+
filters = append(filters, filter)
3355
}
34-
bodyFilter = append(bodyFilter, expr)
3556
}
3657

3758
return &executor{
38-
WorkerBase: drivers.Worker(id, name),
39-
bodyFilter: bodyFilter,
40-
headerFilter: conf.HeaderFilter,
59+
WorkerBase: drivers.Worker(id, name),
60+
filters: filters,
4161
}, nil
4262
}
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
package response_filter
2+
3+
import (
4+
"fmt"
5+
http_service "github.com/eolinker/eosc/eocontext/http-context"
6+
"github.com/ohler55/ojg/jp"
7+
"github.com/ohler55/ojg/oj"
8+
"strings"
9+
)
10+
11+
func removeDuplicateStrings(input []string) []string {
12+
seen := make(map[string]struct{})
13+
result := make([]string, 0, len(input))
14+
for _, str := range input {
15+
if str == "" {
16+
continue
17+
}
18+
if _, exists := seen[str]; !exists {
19+
seen[str] = struct{}{}
20+
result = append(result, str)
21+
}
22+
}
23+
24+
return result
25+
}
26+
27+
type IFilter interface {
28+
Filter(ctx http_service.IHttpContext) error
29+
}
30+
31+
func NewBodyWhiteFilter(keys []string) (IFilter, error) {
32+
rules, err := SafeCompile(removeDuplicateStrings(keys))
33+
if err != nil {
34+
return nil, err
35+
}
36+
return &BodyWhiteFilter{rules: rules}, nil
37+
}
38+
39+
type BodyWhiteFilter struct {
40+
rules []CompiledRule
41+
}
42+
43+
func (b *BodyWhiteFilter) Filter(ctx http_service.IHttpContext) error {
44+
newBody, err := Extract(string(ctx.Response().GetBody()), b.rules)
45+
if err != nil {
46+
return fmt.Errorf("failed to generate new body: %v", err)
47+
}
48+
ctx.Response().SetBody([]byte(newBody))
49+
return nil
50+
}
51+
52+
func NewBodyBlackFilter(keys []string) (IFilter, error) {
53+
es, err := newExprSlice(removeDuplicateStrings(keys))
54+
if err != nil {
55+
return nil, err
56+
}
57+
return &BodyBlackFilter{es: es}, nil
58+
}
59+
60+
type BodyBlackFilter struct {
61+
es []jp.Expr
62+
}
63+
64+
func (b *BodyBlackFilter) Filter(ctx http_service.IHttpContext) error {
65+
body := ctx.Response().GetBody()
66+
n, err := oj.Parse(body)
67+
if err != nil {
68+
return err
69+
}
70+
for _, filter := range b.es {
71+
filter.Del(n)
72+
}
73+
body, err = oj.Marshal(n)
74+
ctx.Response().SetBody(body)
75+
return nil
76+
}
77+
78+
func NewHeaderWhiteFilter(keys []string) (IFilter, error) {
79+
return &HeaderWhiteFilter{keys: removeDuplicateStrings(keys)}, nil
80+
}
81+
82+
type HeaderWhiteFilter struct {
83+
keys []string
84+
}
85+
86+
func (h *HeaderWhiteFilter) Filter(ctx http_service.IHttpContext) error {
87+
header := ctx.Response().Headers()
88+
ctx.Response().HeaderReset()
89+
for _, key := range h.keys {
90+
if value := header.Get(key); value != "" {
91+
ctx.Response().SetHeader(key, value)
92+
}
93+
}
94+
return nil
95+
}
96+
97+
func NewHeaderBlackFilter(keys []string) (IFilter, error) {
98+
return &HeaderBlackFilter{keys: removeDuplicateStrings(keys)}, nil
99+
}
100+
101+
type HeaderBlackFilter struct {
102+
keys []string
103+
}
104+
105+
func (h *HeaderBlackFilter) Filter(ctx http_service.IHttpContext) error {
106+
for _, key := range h.keys {
107+
ctx.Response().DelHeader(key)
108+
}
109+
return nil
110+
}
111+
112+
func newExprSlice(rules []string) ([]jp.Expr, error) {
113+
es := make([]jp.Expr, 0, len(rules))
114+
for _, filter := range rules {
115+
key := filter
116+
if !strings.HasPrefix(key, "$.") {
117+
key = "$." + key
118+
}
119+
expr, err := jp.ParseString(filter)
120+
if err != nil {
121+
return nil, err
122+
}
123+
es = append(es, expr)
124+
}
125+
return es, nil
126+
}

0 commit comments

Comments
 (0)