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  }