github.com/xmidt-org/webpa-common@v1.11.9/xhttp/xfilter/constructor.go (about)

     1  package xfilter
     2  
     3  import (
     4  	"net/http"
     5  
     6  	gokithttp "github.com/go-kit/kit/transport/http"
     7  )
     8  
     9  // Option is a configuration option for a filter constructor
    10  type Option func(*constructor)
    11  
    12  func WithFilters(f ...Interface) Option {
    13  	return func(c *constructor) {
    14  		c.filters = append(c.filters, f...)
    15  	}
    16  }
    17  
    18  func WithErrorEncoder(ee gokithttp.ErrorEncoder) Option {
    19  	return func(c *constructor) {
    20  		if ee != nil {
    21  			c.errorEncoder = ee
    22  		} else {
    23  			c.errorEncoder = gokithttp.DefaultErrorEncoder
    24  		}
    25  	}
    26  }
    27  
    28  // NewConstructor returns an Alice-style decorator that filters requests
    29  // sent to the decorated handler.  If no filters are configured, the returned
    30  // constructor simply returns the handler unmodified.
    31  func NewConstructor(o ...Option) func(http.Handler) http.Handler {
    32  	c := &constructor{
    33  		errorEncoder: gokithttp.DefaultErrorEncoder,
    34  	}
    35  
    36  	for _, f := range o {
    37  		f(c)
    38  	}
    39  
    40  	return c.decorate
    41  }
    42  
    43  // constructor is the internal contextual type for decoration
    44  type constructor struct {
    45  	errorEncoder gokithttp.ErrorEncoder
    46  	filters      []Interface
    47  }
    48  
    49  func (c constructor) decorate(next http.Handler) http.Handler {
    50  	if len(c.filters) > 0 {
    51  		return http.HandlerFunc(func(response http.ResponseWriter, request *http.Request) {
    52  			for _, f := range c.filters {
    53  				if err := f.Allow(request); err != nil {
    54  					c.errorEncoder(request.Context(), err, response)
    55  					return
    56  				}
    57  			}
    58  
    59  			next.ServeHTTP(response, request)
    60  		})
    61  	}
    62  
    63  	return next
    64  }