1/* 2 * 3 * Copyright 2021 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19// Package router implements the Envoy Router HTTP filter. 20package router 21 22import ( 23 "fmt" 24 25 "github.com/golang/protobuf/proto" 26 "github.com/golang/protobuf/ptypes" 27 iresolver "google.golang.org/grpc/internal/resolver" 28 "google.golang.org/grpc/xds/internal/httpfilter" 29 "google.golang.org/protobuf/types/known/anypb" 30 31 pb "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/router/v3" 32) 33 34// TypeURL is the message type for the Router configuration. 35const TypeURL = "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" 36 37func init() { 38 httpfilter.Register(builder{}) 39} 40 41// IsRouterFilter returns true iff a HTTP filter is a Router filter. 42func IsRouterFilter(b httpfilter.Filter) bool { 43 _, ok := b.(builder) 44 return ok 45} 46 47type builder struct { 48} 49 50func (builder) TypeURLs() []string { return []string{TypeURL} } 51 52func (builder) ParseFilterConfig(cfg proto.Message) (httpfilter.FilterConfig, error) { 53 // The gRPC router filter does not currently use any fields from the 54 // config. Verify type only. 55 if cfg == nil { 56 return nil, fmt.Errorf("router: nil configuration message provided") 57 } 58 any, ok := cfg.(*anypb.Any) 59 if !ok { 60 return nil, fmt.Errorf("router: error parsing config %v: unknown type %T", cfg, cfg) 61 } 62 msg := new(pb.Router) 63 if err := ptypes.UnmarshalAny(any, msg); err != nil { 64 return nil, fmt.Errorf("router: error parsing config %v: %v", cfg, err) 65 } 66 return config{}, nil 67} 68 69func (builder) ParseFilterConfigOverride(override proto.Message) (httpfilter.FilterConfig, error) { 70 if override != nil { 71 return nil, fmt.Errorf("router: unexpected config override specified: %v", override) 72 } 73 return config{}, nil 74} 75 76var ( 77 _ httpfilter.ClientInterceptorBuilder = builder{} 78 _ httpfilter.ServerInterceptorBuilder = builder{} 79) 80 81func (builder) BuildClientInterceptor(cfg, override httpfilter.FilterConfig) (iresolver.ClientInterceptor, error) { 82 if _, ok := cfg.(config); !ok { 83 return nil, fmt.Errorf("router: incorrect config type provided (%T): %v", cfg, cfg) 84 } 85 if override != nil { 86 return nil, fmt.Errorf("router: unexpected override configuration specified: %v", override) 87 } 88 // The gRPC router is implemented within the xds resolver's config 89 // selector, not as a separate plugin. So we return a nil HTTPFilter, 90 // which will not be invoked. 91 return nil, nil 92} 93 94func (builder) BuildServerInterceptor(cfg, override httpfilter.FilterConfig) (iresolver.ServerInterceptor, error) { 95 if _, ok := cfg.(config); !ok { 96 return nil, fmt.Errorf("router: incorrect config type provided (%T): %v", cfg, cfg) 97 } 98 if override != nil { 99 return nil, fmt.Errorf("router: unexpected override configuration specified: %v", override) 100 } 101 // The gRPC router is currently unimplemented on the server side. So we 102 // return a nil HTTPFilter, which will not be invoked. 103 return nil, nil 104} 105 106// The gRPC router filter does not currently support any configuration. Verify 107// type only. 108type config struct { 109 httpfilter.FilterConfig 110} 111