schnutibox/vendor/github.com/bufbuild/buf/internal/pkg/rpc/middleware.go

124 lines
3.2 KiB
Go
Raw Normal View History

// 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)
},
)
}
}