124 lines
3.2 KiB
Go
124 lines
3.2 KiB
Go
// Copyright 2020-2021 Buf Technologies, Inc.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package rpc
|
|
|
|
import (
|
|
"context"
|
|
)
|
|
|
|
// ServerInfo contains server rpc info.
|
|
type ServerInfo struct {
|
|
// Service is the rpc service component.
|
|
//
|
|
// May be empty.
|
|
// Example: "foo.bar.v1" is the service for "/foo.bar.v1/Baz".
|
|
Service string
|
|
// Method is the rpc method component.
|
|
//
|
|
// May be empty.
|
|
// Example: "Baz" is the method for "/foo/bar.v1/Baz".
|
|
Method string
|
|
}
|
|
|
|
// ServerInterceptor is a server interceptor.
|
|
type ServerInterceptor interface {
|
|
Intercept(
|
|
ctx context.Context,
|
|
request interface{},
|
|
serverInfo *ServerInfo,
|
|
serverHandler ServerHandler,
|
|
) (interface{}, error)
|
|
}
|
|
|
|
// ServerInterceptorFunc is a function that implements ServerInterceptor.
|
|
type ServerInterceptorFunc func(
|
|
ctx context.Context,
|
|
request interface{},
|
|
serverInfo *ServerInfo,
|
|
serverHandler ServerHandler,
|
|
) (interface{}, error)
|
|
|
|
// Intercept implements ServerInterceptor.
|
|
func (i ServerInterceptorFunc) Intercept(
|
|
ctx context.Context,
|
|
request interface{},
|
|
serverInfo *ServerInfo,
|
|
serverHandler ServerHandler,
|
|
) (interface{}, error) {
|
|
return i(ctx, request, serverInfo, serverHandler)
|
|
}
|
|
|
|
// ServerHandler is a server handler.
|
|
type ServerHandler interface {
|
|
Handle(
|
|
ctx context.Context,
|
|
request interface{},
|
|
) (interface{}, error)
|
|
}
|
|
|
|
// ServerHandlerFunc is a function that implements ServerHandler.
|
|
type ServerHandlerFunc func(
|
|
ctx context.Context,
|
|
request interface{},
|
|
) (interface{}, error)
|
|
|
|
// Handle implements ServerHandler.
|
|
func (h ServerHandlerFunc) Handle(
|
|
ctx context.Context,
|
|
request interface{},
|
|
) (interface{}, error) {
|
|
return h(ctx, request)
|
|
}
|
|
|
|
// NewChainedServerInterceptor returns a new chained ServerInterceptor.
|
|
//
|
|
// Returns nil if interceptors is empty.
|
|
func NewChainedServerInterceptor(interceptors ...ServerInterceptor) ServerInterceptor {
|
|
switch n := len(interceptors); n {
|
|
case 0:
|
|
return nil
|
|
case 1:
|
|
return interceptors[0]
|
|
default:
|
|
return ServerInterceptorFunc(
|
|
func(
|
|
ctx context.Context,
|
|
request interface{},
|
|
serverInfo *ServerInfo,
|
|
serverHandler ServerHandler,
|
|
) (_ interface{}, retErr error) {
|
|
chainer := func(
|
|
currentInterceptor ServerInterceptor,
|
|
currentHandler ServerHandler,
|
|
) ServerHandler {
|
|
return ServerHandlerFunc(
|
|
func(
|
|
currentCtx context.Context,
|
|
currentRequest interface{},
|
|
) (interface{}, error) {
|
|
return currentInterceptor.Intercept(currentCtx, currentRequest, serverInfo, currentHandler)
|
|
},
|
|
)
|
|
}
|
|
chainedHandler := serverHandler
|
|
for i := n - 1; i >= 0; i-- {
|
|
chainedHandler = chainer(interceptors[i], chainedHandler)
|
|
}
|
|
return chainedHandler.Handle(ctx, request)
|
|
},
|
|
)
|
|
}
|
|
}
|