Pixiu Filter体系介绍

怎样编写一个Filter

更详细的信息,请移步Blog《谈谈Pixiu的Filter》

我们来尝试写一个简单的Filter,这个Filter将会有简单的配置,在Decode阶段把请求的Body Log出来,并翻转后作为Mock的返回值。最后在Encode阶段根据配置把返回值Log出来。

1.首先创建一个Filter

  1. type DemoFilter struct {
  2. logPrefix string
  3. }
  4. // Decode阶段,发生在调用Upstream之前
  5. func (f *DemoFilter) Decode(ctx *contexthttp.HttpContext) filter.FilterStatus {
  6. body, _ := ioutil.ReadAll(ctx.Request.Body)
  7. logger.Infof("request body: %s", body)
  8. //reverse res str
  9. runes := []rune(string(body))
  10. for i := 0; i < len(runes)/2; i += 1 {
  11. runes[i], runes[len(runes)-1-i] = runes[len(runes)-1-i], runes[i]
  12. }
  13. reverse := string(runes)
  14. //mock response
  15. ctx.SendLocalReply(200, []byte(reverse))
  16. return filter.Stop
  17. }
  18. // Encode阶段,此时可以获取到Upstream的Response
  19. func (f *DemoFilter) Encode(ctx *contexthttp.HttpContext) filter.FilterStatus {
  20. res := ctx.SourceResp.(string)
  21. logger.Infof("%s: %s", f.logPrefix, res)
  22. return filter.Continue
  23. }

2.创建Filter Factory

  1. type (
  2. DemoFilterFactory struct {
  3. conf *Config
  4. }
  5. // Config describe the config of Filter
  6. Config struct {
  7. LogPrefix string `yaml:"logPrefix,omitempty"`
  8. }
  9. )
  10. func (f *DemoFilterFactory) PrepareFilterChain(ctx *contexthttp.HttpContext, chain filter.FilterChain) error {
  11. demo := &DemoFilter{logPrefix: f.conf.LogPrefix}
  12. chain.AppendDecodeFilters(demo)
  13. chain.AppendEncodeFilters(demo)
  14. return nil
  15. }
  16. func (f *DemoFilterFactory) Config() interface{} {
  17. return f.conf
  18. }
  19. func (f *DemoFilterFactory) Apply() error {
  20. return nil
  21. }

3.创建Filter Plugin,并注册自己

  1. //important
  2. func init() {
  3. filter.RegisterHttpFilter(&Plugin{})
  4. }
  5. type Plugin struct {
  6. }
  7. func (p *Plugin) Kind() string {
  8. return "dgp.filters.demo"
  9. }
  10. func (p *Plugin) CreateFilterFactory() (filter.HttpFilterFactory, error) {
  11. return &DemoFilterFactory{conf: &Config{}}, nil
  12. }

4.配置文件中配置此Filter,并启动Pixiu

  1. static_resources:
  2. listeners:
  3. - name: "net/http"
  4. protocol_type: "HTTP"
  5. address:
  6. socket_address:
  7. address: "0.0.0.0"
  8. port: 8888
  9. filter_chains:
  10. filters:
  11. - name: dgp.filter.httpconnectionmanager
  12. config:
  13. route_config:
  14. routes:
  15. - match:
  16. prefix: "/"
  17. http_filters:
  18. - name: dgp.filters.demo
  19. config:

5.访问并查看日志与结果

  1. curl localhost:8888/demo -d "eiv al tse’c"
  2. cest la vie%

日志

  1. 2022-02-19T20:20:11.900+0800 INFO demo/demo.go:62 request body: eiv al tsec
  2. 2022-02-19T20:20:11.900+0800 INFO demo/demo.go:71 : eiv al tsec

最后修改 December 16, 2022: Fix check (#1736) (97972c1)