Add GrpcWeb middleware
Co-authored-by: Kevin Pollet <pollet.kevin@gmail.com>
This commit is contained in:
parent
7a6bfd3336
commit
bd3eaf4f5e
19 changed files with 251 additions and 2 deletions
|
@ -34,12 +34,23 @@ type Middleware struct {
|
|||
PassTLSClientCert *PassTLSClientCert `json:"passTLSClientCert,omitempty" toml:"passTLSClientCert,omitempty" yaml:"passTLSClientCert,omitempty" export:"true"`
|
||||
Retry *Retry `json:"retry,omitempty" toml:"retry,omitempty" yaml:"retry,omitempty" export:"true"`
|
||||
ContentType *ContentType `json:"contentType,omitempty" toml:"contentType,omitempty" yaml:"contentType,omitempty" export:"true"`
|
||||
GrpcWeb *GrpcWeb `json:"grpcWeb,omitempty" toml:"grpcWeb,omitempty" yaml:"grpcWeb,omitempty" export:"true"`
|
||||
|
||||
Plugin map[string]PluginConf `json:"plugin,omitempty" toml:"plugin,omitempty" yaml:"plugin,omitempty" export:"true"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen=true
|
||||
|
||||
// GrpcWeb holds the gRPC web middleware configuration.
|
||||
// This middleware converts a gRPC web request to an HTTP/2 gRPC request.
|
||||
type GrpcWeb struct {
|
||||
// AllowOrigins is a list of allowable origins.
|
||||
// Can also be a wildcard origin "*".
|
||||
AllowOrigins []string `json:"allowOrigins,omitempty" toml:"allowOrigins,omitempty" yaml:"allowOrigins,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen=true
|
||||
|
||||
// ContentType holds the content-type middleware configuration.
|
||||
// This middleware exists to enable the correct behavior until at least the default one can be changed in a future version.
|
||||
type ContentType struct {
|
||||
|
|
|
@ -353,6 +353,27 @@ func (in *ForwardingTimeouts) DeepCopy() *ForwardingTimeouts {
|
|||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *GrpcWeb) DeepCopyInto(out *GrpcWeb) {
|
||||
*out = *in
|
||||
if in.AllowOrigins != nil {
|
||||
in, out := &in.AllowOrigins, &out.AllowOrigins
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GrpcWeb.
|
||||
func (in *GrpcWeb) DeepCopy() *GrpcWeb {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(GrpcWeb)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HTTPConfiguration) DeepCopyInto(out *HTTPConfiguration) {
|
||||
*out = *in
|
||||
|
@ -734,6 +755,11 @@ func (in *Middleware) DeepCopyInto(out *Middleware) {
|
|||
*out = new(ContentType)
|
||||
**out = **in
|
||||
}
|
||||
if in.GrpcWeb != nil {
|
||||
in, out := &in.GrpcWeb, &out.GrpcWeb
|
||||
*out = new(GrpcWeb)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Plugin != nil {
|
||||
in, out := &in.Plugin, &out.Plugin
|
||||
*out = make(map[string]PluginConf, len(*in))
|
||||
|
|
27
pkg/middlewares/grpcweb/grpcweb.go
Normal file
27
pkg/middlewares/grpcweb/grpcweb.go
Normal file
|
@ -0,0 +1,27 @@
|
|||
package grpcweb
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/improbable-eng/grpc-web/go/grpcweb"
|
||||
"github.com/traefik/traefik/v2/pkg/config/dynamic"
|
||||
"github.com/traefik/traefik/v2/pkg/log"
|
||||
"github.com/traefik/traefik/v2/pkg/middlewares"
|
||||
)
|
||||
|
||||
const typeName = "grpc-web"
|
||||
|
||||
// New builds a new gRPC web request converter.
|
||||
func New(ctx context.Context, next http.Handler, config dynamic.GrpcWeb, name string) http.Handler {
|
||||
log.FromContext(middlewares.GetLoggerCtx(ctx, name, typeName)).Debug("Creating middleware")
|
||||
|
||||
return grpcweb.WrapHandler(next, grpcweb.WithCorsForRegisteredEndpointsOnly(false), grpcweb.WithOriginFunc(func(origin string) bool {
|
||||
for _, originCfg := range config.AllowOrigins {
|
||||
if originCfg == "*" || originCfg == origin {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}))
|
||||
}
|
|
@ -279,6 +279,7 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client)
|
|||
PassTLSClientCert: middleware.Spec.PassTLSClientCert,
|
||||
Retry: retry,
|
||||
ContentType: middleware.Spec.ContentType,
|
||||
GrpcWeb: middleware.Spec.GrpcWeb,
|
||||
Plugin: plugin,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ type MiddlewareSpec struct {
|
|||
PassTLSClientCert *dynamic.PassTLSClientCert `json:"passTLSClientCert,omitempty"`
|
||||
Retry *Retry `json:"retry,omitempty"`
|
||||
ContentType *dynamic.ContentType `json:"contentType,omitempty"`
|
||||
GrpcWeb *dynamic.GrpcWeb `json:"grpcWeb,omitempty"`
|
||||
// Plugin defines the middleware plugin configuration.
|
||||
// More info: https://doc.traefik.io/traefik/plugins/
|
||||
Plugin map[string]apiextensionv1.JSON `json:"plugin,omitempty"`
|
||||
|
|
|
@ -769,6 +769,11 @@ func (in *MiddlewareSpec) DeepCopyInto(out *MiddlewareSpec) {
|
|||
*out = new(dynamic.ContentType)
|
||||
**out = **in
|
||||
}
|
||||
if in.GrpcWeb != nil {
|
||||
in, out := &in.GrpcWeb, &out.GrpcWeb
|
||||
*out = new(dynamic.GrpcWeb)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Plugin != nil {
|
||||
in, out := &in.Plugin, &out.Plugin
|
||||
*out = make(map[string]v1.JSON, len(*in))
|
||||
|
|
|
@ -17,6 +17,7 @@ import (
|
|||
"github.com/traefik/traefik/v2/pkg/middlewares/circuitbreaker"
|
||||
"github.com/traefik/traefik/v2/pkg/middlewares/compress"
|
||||
"github.com/traefik/traefik/v2/pkg/middlewares/customerrors"
|
||||
"github.com/traefik/traefik/v2/pkg/middlewares/grpcweb"
|
||||
"github.com/traefik/traefik/v2/pkg/middlewares/headers"
|
||||
"github.com/traefik/traefik/v2/pkg/middlewares/inflightreq"
|
||||
"github.com/traefik/traefik/v2/pkg/middlewares/ipallowlist"
|
||||
|
@ -219,6 +220,16 @@ func (b *Builder) buildConstructor(ctx context.Context, middlewareName string) (
|
|||
}
|
||||
}
|
||||
|
||||
// GrpcWeb
|
||||
if config.GrpcWeb != nil {
|
||||
if middleware != nil {
|
||||
return nil, badConf
|
||||
}
|
||||
middleware = func(next http.Handler) (http.Handler, error) {
|
||||
return grpcweb.New(ctx, next, *config.GrpcWeb, middlewareName), nil
|
||||
}
|
||||
}
|
||||
|
||||
// Headers
|
||||
if config.Headers != nil {
|
||||
if middleware != nil {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue