github.com/authzed/spicedb@v1.32.1-0.20240520085336-ebda56537386/internal/middleware/chain.go (about) 1 package middleware 2 3 import ( 4 "context" 5 6 "google.golang.org/grpc" 7 ) 8 9 // Vendored from grpc-go-middleware 10 // These were removed in v2, see: https://github.com/grpc-ecosystem/go-grpc-middleware/pull/385 11 12 // ChainUnaryServer creates a single interceptor out of a chain of many interceptors. 13 // 14 // Execution is done in left-to-right order, including passing of context. 15 // For example ChainUnaryServer(one, two, three) will execute one before two before three, and three 16 // will see context changes of one and two. 17 func ChainUnaryServer(interceptors ...grpc.UnaryServerInterceptor) grpc.UnaryServerInterceptor { 18 n := len(interceptors) 19 20 return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { 21 chainer := func(currentInter grpc.UnaryServerInterceptor, currentHandler grpc.UnaryHandler) grpc.UnaryHandler { 22 return func(currentCtx context.Context, currentReq interface{}) (interface{}, error) { 23 return currentInter(currentCtx, currentReq, info, currentHandler) 24 } 25 } 26 27 chainedHandler := handler 28 for i := n - 1; i >= 0; i-- { 29 chainedHandler = chainer(interceptors[i], chainedHandler) 30 } 31 32 return chainedHandler(ctx, req) 33 } 34 } 35 36 // ChainStreamServer creates a single interceptor out of a chain of many interceptors. 37 // 38 // Execution is done in left-to-right order, including passing of context. 39 // For example ChainUnaryServer(one, two, three) will execute one before two before three. 40 // If you want to pass context between interceptors, use WrapServerStream. 41 func ChainStreamServer(interceptors ...grpc.StreamServerInterceptor) grpc.StreamServerInterceptor { 42 n := len(interceptors) 43 44 return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { 45 chainer := func(currentInter grpc.StreamServerInterceptor, currentHandler grpc.StreamHandler) grpc.StreamHandler { 46 return func(currentSrv interface{}, currentStream grpc.ServerStream) error { 47 return currentInter(currentSrv, currentStream, info, currentHandler) 48 } 49 } 50 51 chainedHandler := handler 52 for i := n - 1; i >= 0; i-- { 53 chainedHandler = chainer(interceptors[i], chainedHandler) 54 } 55 56 return chainedHandler(srv, ss) 57 } 58 }