go.uber.org/yarpc@v1.72.1/api/middleware/inbound.go (about) 1 // Copyright (c) 2022 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package middleware 22 23 import ( 24 "context" 25 26 "go.uber.org/yarpc/api/transport" 27 ) 28 29 // UnaryInbound defines a transport-level middleware for 30 // `UnaryHandler`s. 31 // 32 // UnaryInbound middleware MAY do zero or more of the following: change the 33 // context, change the request, call the ResponseWriter, modify the response 34 // body by wrapping the ResponseWriter, handle the returned error, call the 35 // given handler zero or more times. 36 // 37 // UnaryInbound middleware MUST be thread-safe. 38 // 39 // UnaryInbound middleware is re-used across requests and MAY be called multiple times 40 // for the same request. 41 type UnaryInbound interface { 42 Handle(ctx context.Context, req *transport.Request, resw transport.ResponseWriter, h transport.UnaryHandler) error 43 } 44 45 // NopUnaryInbound is a inbound middleware that does not do anything special. It 46 // simply calls the underlying Handler. 47 var NopUnaryInbound UnaryInbound = nopUnaryInbound{} 48 49 // ApplyUnaryInbound applies the given InboundMiddleware to the given Handler. 50 func ApplyUnaryInbound(h transport.UnaryHandler, i UnaryInbound) transport.UnaryHandler { 51 if i == nil { 52 return h 53 } 54 return unaryHandlerWithMiddleware{h: h, i: i} 55 } 56 57 // UnaryInboundFunc adapts a function into an InboundMiddleware. 58 type UnaryInboundFunc func(context.Context, *transport.Request, transport.ResponseWriter, transport.UnaryHandler) error 59 60 // Handle for UnaryInboundFunc 61 func (f UnaryInboundFunc) Handle(ctx context.Context, req *transport.Request, resw transport.ResponseWriter, h transport.UnaryHandler) error { 62 return f(ctx, req, resw, h) 63 } 64 65 type unaryHandlerWithMiddleware struct { 66 h transport.UnaryHandler 67 i UnaryInbound 68 } 69 70 func (h unaryHandlerWithMiddleware) Handle(ctx context.Context, req *transport.Request, resw transport.ResponseWriter) error { 71 return h.i.Handle(ctx, req, resw, h.h) 72 } 73 74 type nopUnaryInbound struct{} 75 76 func (nopUnaryInbound) Handle(ctx context.Context, req *transport.Request, resw transport.ResponseWriter, handler transport.UnaryHandler) error { 77 return handler.Handle(ctx, req, resw) 78 } 79 80 // OnewayInbound defines a transport-level middleware for 81 // `OnewayHandler`s. 82 // 83 // OnewayInbound middleware MAY do zero or more of the following: change the 84 // context, change the request, handle the returned error, call the given 85 // handler zero or more times. 86 // 87 // OnewayInbound middleware MUST be thread-safe. 88 // 89 // OnewayInbound middleware is re-used across requests and MAY be called 90 // multiple times for the same request. 91 type OnewayInbound interface { 92 HandleOneway(ctx context.Context, req *transport.Request, h transport.OnewayHandler) error 93 } 94 95 // NopOnewayInbound is an inbound middleware that does not do 96 // anything special. It simply calls the underlying OnewayHandler. 97 var NopOnewayInbound OnewayInbound = nopOnewayInbound{} 98 99 // ApplyOnewayInbound applies the given OnewayInbound middleware to 100 // the given OnewayHandler. 101 func ApplyOnewayInbound(h transport.OnewayHandler, i OnewayInbound) transport.OnewayHandler { 102 if i == nil { 103 return h 104 } 105 return onewayHandlerWithMiddleware{h: h, i: i} 106 } 107 108 // OnewayInboundFunc adapts a function into a OnewayInbound Middleware. 109 type OnewayInboundFunc func(context.Context, *transport.Request, transport.OnewayHandler) error 110 111 // HandleOneway for OnewayInboundFunc 112 func (f OnewayInboundFunc) HandleOneway(ctx context.Context, req *transport.Request, h transport.OnewayHandler) error { 113 return f(ctx, req, h) 114 } 115 116 type onewayHandlerWithMiddleware struct { 117 h transport.OnewayHandler 118 i OnewayInbound 119 } 120 121 func (h onewayHandlerWithMiddleware) HandleOneway(ctx context.Context, req *transport.Request) error { 122 return h.i.HandleOneway(ctx, req, h.h) 123 } 124 125 type nopOnewayInbound struct{} 126 127 func (nopOnewayInbound) HandleOneway(ctx context.Context, req *transport.Request, handler transport.OnewayHandler) error { 128 return handler.HandleOneway(ctx, req) 129 } 130 131 // StreamInbound defines a transport-level middleware for 132 // `StreamHandler`s. 133 // 134 // StreamInbound middleware MAY do zero or more of the following: change the 135 // stream, handle the returned error, call the given handler zero or more times. 136 // 137 // StreamInbound middleware MUST be thread-safe. 138 // 139 // StreamInbound middleware is re-used across requests and MAY be called 140 // multiple times for the same request. 141 type StreamInbound interface { 142 HandleStream(s *transport.ServerStream, h transport.StreamHandler) error 143 } 144 145 // NopStreamInbound is an inbound middleware that does not do 146 // anything special. It simply calls the underlying StreamHandler. 147 var NopStreamInbound StreamInbound = nopStreamInbound{} 148 149 // ApplyStreamInbound applies the given StreamInbound middleware to 150 // the given StreamHandler. 151 func ApplyStreamInbound(h transport.StreamHandler, i StreamInbound) transport.StreamHandler { 152 if i == nil { 153 return h 154 } 155 return streamHandlerWithMiddleware{h: h, i: i} 156 } 157 158 // StreamInboundFunc adapts a function into a StreamInbound Middleware. 159 type StreamInboundFunc func(*transport.ServerStream, transport.StreamHandler) error 160 161 // HandleStream for StreamInboundFunc 162 func (f StreamInboundFunc) HandleStream(s *transport.ServerStream, h transport.StreamHandler) error { 163 return f(s, h) 164 } 165 166 type streamHandlerWithMiddleware struct { 167 h transport.StreamHandler 168 i StreamInbound 169 } 170 171 func (h streamHandlerWithMiddleware) HandleStream(s *transport.ServerStream) error { 172 return h.i.HandleStream(s, h.h) 173 } 174 175 type nopStreamInbound struct{} 176 177 func (nopStreamInbound) HandleStream(s *transport.ServerStream, handler transport.StreamHandler) error { 178 return handler.HandleStream(s) 179 }