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 httpfilter contains the HTTPFilter interface and a registry for 20// storing and retrieving their implementations. 21package httpfilter 22 23import ( 24 "github.com/golang/protobuf/proto" 25 iresolver "google.golang.org/grpc/internal/resolver" 26) 27 28// FilterConfig represents an opaque data structure holding configuration for a 29// filter. Embed this interface to implement it. 30type FilterConfig interface { 31 isFilterConfig() 32} 33 34// Filter defines the parsing functionality of an HTTP filter. A Filter may 35// optionally implement either ClientInterceptorBuilder or 36// ServerInterceptorBuilder or both, indicating it is capable of working on the 37// client side or server side or both, respectively. 38type Filter interface { 39 // TypeURLs are the proto message types supported by this filter. A filter 40 // will be registered by each of its supported message types. 41 TypeURLs() []string 42 // ParseFilterConfig parses the provided configuration proto.Message from 43 // the LDS configuration of this filter. This may be an anypb.Any or a 44 // udpa.type.v1.TypedStruct for filters that do not accept a custom type. 45 // The resulting FilterConfig will later be passed to Build. 46 ParseFilterConfig(proto.Message) (FilterConfig, error) 47 // ParseFilterConfigOverride parses the provided override configuration 48 // proto.Message from the RDS override configuration of this filter. This 49 // may be an anypb.Any or a udpa.type.v1.TypedStruct for filters that do 50 // not accept a custom type. The resulting FilterConfig will later be 51 // passed to Build. 52 ParseFilterConfigOverride(proto.Message) (FilterConfig, error) 53} 54 55// ClientInterceptorBuilder constructs a Client Interceptor. If this type is 56// implemented by a Filter, it is capable of working on a client. 57type ClientInterceptorBuilder interface { 58 // BuildClientInterceptor uses the FilterConfigs produced above to produce 59 // an HTTP filter interceptor for clients. config will always be non-nil, 60 // but override may be nil if no override config exists for the filter. It 61 // is valid for Build to return a nil Interceptor and a nil error. In this 62 // case, the RPC will not be intercepted by this filter. 63 BuildClientInterceptor(config, override FilterConfig) (iresolver.ClientInterceptor, error) 64} 65 66// ServerInterceptorBuilder constructs a Server Interceptor. If this type is 67// implemented by a Filter, it is capable of working on a server. 68type ServerInterceptorBuilder interface { 69 // BuildServerInterceptor uses the FilterConfigs produced above to produce 70 // an HTTP filter interceptor for servers. config will always be non-nil, 71 // but override may be nil if no override config exists for the filter. It 72 // is valid for Build to return a nil Interceptor and a nil error. In this 73 // case, the RPC will not be intercepted by this filter. 74 BuildServerInterceptor(config, override FilterConfig) (iresolver.ServerInterceptor, error) 75} 76 77var ( 78 // m is a map from scheme to filter. 79 m = make(map[string]Filter) 80) 81 82// Register registers the HTTP filter Builder to the filter map. b.TypeURLs() 83// will be used as the types for this filter. 84// 85// NOTE: this function must only be called during initialization time (i.e. in 86// an init() function), and is not thread-safe. If multiple filters are 87// registered with the same type URL, the one registered last will take effect. 88func Register(b Filter) { 89 for _, u := range b.TypeURLs() { 90 m[u] = b 91 } 92} 93 94// Get returns the HTTPFilter registered with typeURL. 95// 96// If no filter is register with typeURL, nil will be returned. 97func Get(typeURL string) Filter { 98 return m[typeURL] 99} 100