package httprp import ( "context" "net/http" "net/http/httputil" "net/url" ) // RequestFunc may take information from an HTTP request and put it into a // request context. BeforeFuncs are executed prior to invoking the // endpoint. type RequestFunc func(context.Context, *http.Request) context.Context // Server is a proxying request handler. type Server struct { proxy http.Handler before []RequestFunc errorEncoder func(w http.ResponseWriter, err error) } // NewServer constructs a new server that implements http.Server and will proxy // requests to the given base URL using its scheme, host, and base path. // If the target's path is "/base" and the incoming request was for "/dir", // the target request will be for /base/dir. func NewServer( baseURL *url.URL, options ...ServerOption, ) *Server { s := &Server{ proxy: httputil.NewSingleHostReverseProxy(baseURL), } for _, option := range options { option(s) } return s } // ServerOption sets an optional parameter for servers. type ServerOption func(*Server) // ServerBefore functions are executed on the HTTP request object before the // request is decoded. func ServerBefore(before ...RequestFunc) ServerOption { return func(s *Server) { s.before = append(s.before, before...) } } // ServeHTTP implements http.Handler. func (s Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { ctx := r.Context() for _, f := range s.before { ctx = f(ctx, r) } s.proxy.ServeHTTP(w, r) }