Filter 提供请求处理抽象。用户可以将多个过滤器组合成过滤器链。 当从监听器接收到请求时,过滤器将在其预处理或后处理阶段逐一处理它。 因为 pixiu 想要提供网络协议转换功能,所以过滤器包含网络过滤器以及网络过滤器之下的过滤器,例如 http 过滤器。 请求处理顺序如下。
client -> listner -> network filter such as httpconnectionmanager -> http filter chain
您可以在 pkg/filter 中找到所有过滤器。以下仅列出一些过滤器。
有两个抽象接口:plugin 和 filter。
// HttpFilter 描述 http 过滤器
type HttpFilter interface {
// PrepareFilterChain 将过滤器添加到链中
PrepareFilterChain(ctx *http.HttpContext) error
// Handle 过滤器钩子函数
Handle(ctx *http.HttpContext)
Apply() error
// Config 获取过滤器的配置
Config() interface{}
}
// HttpFilter 描述 http 过滤器
type HttpFilter interface {
// PrepareFilterChain 将过滤器添加到链中
PrepareFilterChain(ctx *http.HttpContext) error
// Handle 过滤器钩子函数
Handle(ctx *http.HttpContext)
Apply() error
// Config 获取过滤器的配置
Config() interface{}
}
您应该定义自己的 plugin 和 filter,然后实现其函数。
此外,您可能需要定义过滤器专有的配置,如下所示。
// Config 描述 Filter 的配置
type Config struct {
AllowOrigin []string `yaml:"allow_origin" json:"allow_origin" mapstructure:"allow_origin"`
// AllowMethods access-control-allow-methods
AllowMethods string `yaml:"allow_methods" json:"allow_methods" mapstructure:"allow_methods"`
// AllowHeaders access-control-allow-headers
AllowHeaders string `yaml:"allow_headers" json:"allow_headers" mapstructure:"allow_headers"`
// ExposeHeaders access-control-expose-headers
ExposeHeaders string `yaml:"expose_headers" json:"expose_headers" mapstructure:"expose_headers"`
// MaxAge access-control-max-age
MaxAge string `yaml:"max_age" json:"max_age" mapstructure:"max_age"`
AllowCredentials bool `yaml:"allow_credentials" json:"allow_credentials" mapstructure:"allow_credentials"`
}
您可以在 plugin 的 CreateFilter 函数中初始化过滤器专有的配置实例,并在 config 函数中返回它。
func (p *Plugin) CreateFilter() (filter.HttpFilter, error) {
return &Filter{cfg: &Config{}}, nil
}
func (f *Filter) Config() interface{} {
return f.cfg
}
然后 pixiu 将通过 pixiu 配置 yaml 文件填充其值。 在填充配置值后,pixiu 将调用 Apply 函数,您应该准备过滤器,例如获取远程信息等。 当请求到来时,pixiu 将调用 PrepareFilterChain 函数,以允许过滤器将自身添加到请求过滤器链中。
func (f *Filter) PrepareFilterChain(ctx *http.HttpContext) error {
ctx.AppendFilterFunc(f.Handle)
return nil
}
如果不使用 AppendFilterFunc 将自身添加到过滤器链中,则过滤器将不会处理本次请求。 最终 pixiu 将调用 Handle 函数。
func (f *Filter) Handle(ctx *http.HttpContext) {
f.handleCors(ctx)
ctx.Next()
}
在处理请求期间有两个阶段,预处理和后处理。在调用 ctx.Next 函数之前,阶段为预处理。而在调用它之后,阶段为后处理。
在 init 函数中将 plugin 注册到管理中。
const (
// Kind is the kind of Fallback.
Kind = constant.HTTPCorsFilter
)
func init() {
filter.RegisterHttpFilter(&Plugin{})
}
在 pkg/pluginregistry/registry.go 文件中添加未命名导入,以使 init 函数被调用。
_ "github.com/apache/dubbo-go-pixiu/pkg/filter/cors"
在 yaml 文件中添加过滤器配置。
http_filters:
- name: dgp.filter.http.httpproxy
config:
- name: dgp.filter.http.cors
config:
allow_origin:
- api.dubbo.com
allow_methods: ""
allow_headers: ""
expose_headers: ""
max_age: ""
allow_credentials: false
有一个简单的过滤器位于 pkg/filter/cors,它提供 http cors 功能。
type (
// Plugin 是 http 过滤器插件。
Plugin struct {
}
// Filter 是 http 过滤器实例
Filter struct {
cfg *Config
}
// Config 描述 Filter 的配置
Config struct {
AllowOrigin []string `yaml:"allow_origin" json:"allow_origin" mapstructure:"allow_origin"`
// AllowMethods access-control-allow-methods
AllowMethods string `yaml:"allow_methods" json:"allow_methods" mapstructure:"allow_methods"`
// AllowHeaders access-control-allow-headers
AllowHeaders string `yaml:"allow_headers" json:"allow_headers" mapstructure:"allow_headers"`
// ExposeHeaders access-control-expose-headers
ExposeHeaders string `yaml:"expose_headers" json:"expose_headers" mapstructure:"expose_headers"`
// MaxAge access-control-max-age
MaxAge string `yaml:"max_age" json:"max_age" mapstructure:"max_age"`
AllowCredentials bool `yaml:"allow_credentials" json:"allow_credentials" mapstructure:"allow_credentials"`
}
)