gobis

package module
v1.31.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 25, 2024 License: Apache-2.0 Imports: 20 Imported by: 21

README

Gobis Build Status GoDoc

Gobis is a lightweight API Gateway written in go which can be used programmatically or as a standalone server.

It's largely inspired by Netflix/zuul.

Summary

Installation

go get github/orange-cloudfoundry/gobis

Usage

Gobis provide an handler to make it useable on your server.

You can found found gobis.ProxyRoute options in the godoc: https://godoc.org/github.com/orange-cloudfoundry/gobis#ProxyRoute

Example:

package main
import (
        "github.com/orange-cloudfoundry/gobis"
        "github.com/orange-cloudfoundry/gobis-middlewares/cors"
        log "github.com/sirupsen/logrus"
        "net/http"
)
func main(){
	builder := gobis.Builder()
	routes := builder.AddRoute("/app/**", "http://www.mocky.io/v2/595625d22900008702cd71e8").
		WithName("myapi").
        WithMiddlewareParams(cors.CorsConfig{
            Cors: &cors.CorsOptions{
                AllowedOrigins: []string{"http://localhost"},
            },
        }).
        Build()
        
    log.SetLevel(log.DebugLevel) // set verbosity to debug for logs
    gobisHandler, err := gobis.NewHandler(routes, cors.NewCors()) // we add cors middleware
    if err != nil {
            panic(err)
    }
    err = http.ListenAndServe(":8080", gobisHandler)
    if err != nil {
            panic(err)
    }
}

The builder is a more convenient way to build complex and multiple route programmatically see doc Builder.

You can see doc DefaultHandlerConfig to know more about possible parameters.

You can also see doc ProxyRoute to see available options for routes.

Headers sent by gobis to reversed app

Gobis will send some headers to the app when the request is forwarded:

  • X-Gobis-Forward: This is a dummy header to say to the app that the requested was forwarded by gobis.
  • X-Gobis-Username: User name of a logged user set by a middleware.
  • X-Gobis-Groups: User's groups of a logged user set by a middleware.
Example using gobis as a middleware
package main
import (
	"github.com/orange-cloudfoundry/gobis"
	"github.com/orange-cloudfoundry/gobis-middlewares/cors"
	"github.com/gorilla/mux"
	"net/http"
)
func main() {
	rtr := mux.NewRouter()
	rtr.HandleFunc("/hello", http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
    		w.Write([]byte("hello world"))
    }))
	builder := gobis.Builder()
    routes := builder.AddRoute("/app/**", "http://www.mocky.io/v2/595625d22900008702cd71e8").
        WithName("myapi").
        WithMiddlewareParams(cors.CorsConfig{
            Cors: &cors.CorsOptions{
                AllowedOrigins: []string{"http://localhost"},
            },
        }).
        Build()
        
	mid, err := gobis.NewGobisMiddleware(routes)
	if err != nil {
		panic(err)
	}
	
	err = http.ListenAndServe(":8080", mid(rtr))
	if err != nil {
		panic(err)
	}

	// hitting /hello will show hello world
	// hitting /app/something will forward against gobis
}

Middlewares

Gobis permit to add middlewares on handler to be able to enhance your upstream url, for example:

  • add basic auth security
  • add monitoring
  • add cors headers
  • ...
Create your middleware

You can see example from cors middleware.

To use it simply add it to your RouterFactory.

Here an example

package main
import (
        "github.com/orange-cloudfoundry/gobis"
        log "github.com/sirupsen/logrus"
        "net/http"
)
type TraceConfig struct{
      EnableTrace bool  `mapstructure:"enable_trace" json:"enable_trace" yaml:"enable_trace"`
}
type traceMiddleware struct {}
func (traceMiddleware) Handler(proxyRoute gobis.ProxyRoute, params interface{}, next http.Handler) (http.Handler, error) {
        // Params has been decode route middleware params, this decoded agains schema you gave in schema function
        traceConfig := params.(TraceConfig)
        if !traceConfig.EnableTrace {
            return next, nil
        }
        return TraceHandler(next), nil
}
// Schema function is required in order to gobis to decode params from route and sent it back to handler function through `params`
// It use https://github.com/mitchellh/mapstructure when decode to inject in handler
func (traceMiddleware) Schema() interface{} {
        return TraceConfig{}
}
func TraceHandler(h http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
                groups := gobis.Groups(r) // retrieve current user groups set by other middlewares with gobis.AddGroups(r, "mygroup1", "mygroup2")
                user := gobis.Username(r) // retrieve current user name set by other middlewares with gobis.SetUsername(r, "username")
                path := gobis.Path(r) // retrieve the path which will be passed to upstream (wihtout trailling path name on your route)
                routeName := gobis.RouteName(r) // retrieve the current route name which use this handler
                log.Info("Url received: "+ r.URL.String())
                h.ServeHTTP(w, r)
        })
}
func main(){
        configHandler := gobis.DefaultHandlerConfig{
                StartPath: "/gobis",
                Routes: []gobis.ProxyRoute{
                    {
                        Name: "myapi",
                        Path: "/app/**",
                        Url: "http://www.mocky.io/v2/595625d22900008702cd71e8",
                    },
                },
        }
        log.SetLevel(log.DebugLevel) // set verbosity to debug for logs
        gobisHandler, err := gobis.NewDefaultHandler(
                    configHandler,
                    &traceMiddleware{},
                )
        if err != nil {
                panic(err)
        }
        err = http.ListenAndServe(":8080", gobisHandler)
        if err != nil {
                panic(err)
        }
}

Available middlewares

Middlewares are located on repo https://github.com/orange-cloudfoundry/gobis-middlewares

Running a standalone server

You can run a prepared gobis server with all default middlewares in one command line, see repo https://github.com/orange-cloudfoundry/gobis-server .

This server can be ran on cloud like Kubernetes, Cloud Foundry or Heroku.

Pro tips

You can set multiple middleware params programmatically by using a dummy structure containing each config you wanna set, example:

package main
import (
    "github.com/orange-cloudfoundry/gobis-middlewares/trace"
    "github.com/orange-cloudfoundry/gobis-middlewares/cors"
    "github.com/orange-cloudfoundry/gobis"
)
func main(){
    configHandler := gobis.DefaultHandlerConfig{
            Routes: []gobis.ProxyRoute{
                {
                    Name: "myapi",
                    Path: "/app/**",
                    Url: "http://www.mocky.io/v2/595625d22900008702cd71e8",
                    MiddlewareParams: struct {
                        trace.TraceConfig
                        cors.CorsConfig
                    }{
                        TraceConfig: trace.TraceConfig{
                            Trace: &trace.TraceOptions{
                                Enabled: true,
                            },
                        },
                        CorsConfig: cors.CorsConfig{
                            Cors: &cors.CorsOptions{
                                Enabled: true,
                            },
                        },
                    },
                },
            },
    }
    gobisHandler, err := gobis.NewDefaultHandler(configHandler, trace.NewTrace(), cors.NewCors())
}

FAQ

Why this name ?

Gobis is inspired by zuul which also a kind of dinosaur which come from the family of Ankylosauridae, the gobis(aurus) come also from this family.

Documentation

Overview

Package gobis Mark header as dirty to not forward those headers in the upstream url Useful for middleware when they ask for authorization header fox example

Index

Constants

View Source
const (
	XForwardedProto  = "X-Forwarded-Proto"
	XForwardedFor    = "X-Forwarded-For"
	XForwardedHost   = "X-Forwarded-Host"
	XForwardedServer = "X-Forwarded-Server"
)
View Source
const (
	GobisHeaderName = "X-Gobis-Forward"
	XGobisUsername  = "X-Gobis-Username"
	XGobisGroups    = "X-Gobis-Groups"
)
View Source
const (
	PathRegex = "(?i)^((/[^/\\*]*)*)(/((\\*){1,2}))?$"
)

Variables

This section is empty.

Functions

func AddContextValue

func AddContextValue(req *http.Request, key, val interface{})

AddContextValue Add a context value to a http request without having to override request by yourself

func AddGroups

func AddGroups(req *http.Request, groups ...string)

AddGroups add groups to a request context

func DirtHeader

func DirtHeader(req *http.Request, header string, oldValue ...string)

DirtHeader Mark a http header as dirty Useful to prevent some headers added and used by middleware to not be sent to upstream if oldValue is not empty it will make proxy rewrite header with this value

func DirtyHeaders

func DirtyHeaders(req *http.Request) *map[string]string

DirtyHeaders Retrieve all http headers marked as dirty

func ForwardRequest

func ForwardRequest(proxyRoute ProxyRoute, req *http.Request, restPath string)

func GetMiddlewareName

func GetMiddlewareName(i interface{}) string

func Groups

func Groups(req *http.Request) []string

retrieve groups from request context

func InjectContextValue

func InjectContextValue(req *http.Request, key, inject interface{}) error

InjectContextValue Inject a value from a request context to an interface This is the same behaviour as json.Unmarshal

func InterfaceToMap

func InterfaceToMap(is ...interface{}) map[string]interface{}

func IsDirtyHeader

func IsDirtyHeader(req *http.Request, header string) bool

IsDirtyHeader Return true if a http header is marked as dirty

func NewDefaultTransport

func NewDefaultTransport() *http.Transport

func NewGobisMiddleware

func NewGobisMiddleware(routes []ProxyRoute, middlewareHandlers ...MiddlewareHandler) (func(next http.Handler) http.Handler, error)

func NewRouteTransport

func NewRouteTransport(route ProxyRoute) http.RoundTripper

func NewRouteTransportWithHttpTransport

func NewRouteTransportWithHttpTransport(route ProxyRoute, httpTransport *http.Transport) http.RoundTripper

func Path

func Path(req *http.Request) string

Path Retrieve rest of the path from a request url to his context

func RouteName

func RouteName(req *http.Request) string

RouteName Retrieve routes name used in this request

func SetGroups

func SetGroups(req *http.Request, groups ...string)

SetGroups add groups to a request context this call AddGroups, it's simply for UX

func SetPath

func SetPath(req *http.Request, path string)

SetPath Set the rest of the path from a request url to his context (used by router factory)

func SetProtectedHeaders

func SetProtectedHeaders(protectHeaders []string)

func SetUsername

func SetUsername(req *http.Request, username string)

SetUsername Set the username to a request context

func UndirtHeader

func UndirtHeader(req *http.Request, header string)

UndirtHeader Remove a http header from the list of dirty header

func Username

func Username(req *http.Request) string

Username Retrieve username from a request context

Types

type CreateTransportFunc

type CreateTransportFunc func(ProxyRoute) http.RoundTripper

type DefaultHandler

type DefaultHandler struct {
	// contains filtered or unexported fields
}

func (DefaultHandler) GetServerAddr

func (h DefaultHandler) GetServerAddr() string

func (*DefaultHandler) ServeHTTP

func (h *DefaultHandler) ServeHTTP(w http.ResponseWriter, req *http.Request)

type DefaultHandlerConfig

type DefaultHandlerConfig struct {
	// List of routes
	Routes []ProxyRoute `json:"routes" yaml:"routes"`
	// List of headers which cannot be removed by `sensitive_headers`
	ProtectedHeaders []string `json:"protected_headers" yaml:"protected_headers"`
	// Set the path where all path from routes should start (e.g.: if set to `/root` request for the next routes will be localhost/root/app)
	StartPath string `json:"start_path" yaml:"start_path"`
}

type ErrMiddleware

type ErrMiddleware string

func (ErrMiddleware) Error

func (e ErrMiddleware) Error() string

type GobisContextKey

type GobisContextKey int

type GobisHandler

type GobisHandler interface {
	GetServerAddr() string
	ServeHTTP(http.ResponseWriter, *http.Request)
}

func NewDefaultHandler

func NewDefaultHandler(config DefaultHandlerConfig, middlewareHandlers ...MiddlewareHandler) (GobisHandler, error)

func NewHandler

func NewHandler(routes []ProxyRoute, middlewareHandlers ...MiddlewareHandler) (GobisHandler, error)

func NewHandlerWithFactory added in v1.4.1

func NewHandlerWithFactory(routes []ProxyRoute, factory RouterFactory) (GobisHandler, error)

type HostMatcher

type HostMatcher struct {
	glob.Glob
	// contains filtered or unexported fields
}

func NewHostMatcher

func NewHostMatcher(hostOrWildcard string) *HostMatcher

func (HostMatcher) String

func (re HostMatcher) String() string

func (*HostMatcher) UnmarshalJSON

func (re *HostMatcher) UnmarshalJSON(data []byte) error

func (*HostMatcher) UnmarshalYAML

func (re *HostMatcher) UnmarshalYAML(unmarshal func(interface{}) error) error

type HostMatchers

type HostMatchers []*HostMatcher

func (HostMatchers) Match

func (m HostMatchers) Match(s string) bool

type JsonError

type JsonError struct {
	Status    int    `json:"status"`
	Title     string `json:"title"`
	Details   string `json:"details"`
	RouteName string `json:"route_name"`
}

type MiddlewareChainRoutes

type MiddlewareChainRoutes struct {
	// contains filtered or unexported fields
}

func NewMiddlewareChainRoutes

func NewMiddlewareChainRoutes(routerFactory RouterFactory) *MiddlewareChainRoutes

func (MiddlewareChainRoutes) Handler

func (m MiddlewareChainRoutes) Handler(route ProxyRoute, params interface{}, next http.Handler) (http.Handler, error)

func (MiddlewareChainRoutes) Schema

func (m MiddlewareChainRoutes) Schema() interface{}

type MiddlewareConfig

type MiddlewareConfig struct {
	// List of routes
	Routes []ProxyRoute `json:"routes" yaml:"routes"`
	// Set the path where all path from routes should start (e.g.: if set to `/root` request for the next routes will be localhost/root/app)
	StartPath string `json:"start_path" yaml:"start_path"`
}

type MiddlewareContextKey

type MiddlewareContextKey int
const (
	GroupContextKey MiddlewareContextKey = iota
	UsernameContextKey
)

type MiddlewareHandler

type MiddlewareHandler interface {
	Handler(route ProxyRoute, params interface{}, next http.Handler) (http.Handler, error)
	Schema() interface{}
}

type PathMatcher

type PathMatcher struct {
	// contains filtered or unexported fields
}

func NewPathMatcher

func NewPathMatcher(path string) *PathMatcher

func (PathMatcher) AppPath

func (re PathMatcher) AppPath() string

func (PathMatcher) CreateRoutePath

func (re PathMatcher) CreateRoutePath(finalPath string) string

func (PathMatcher) String

func (re PathMatcher) String() string

func (*PathMatcher) UnmarshalCloud added in v1.1.0

func (re *PathMatcher) UnmarshalCloud(data interface{}) error

func (*PathMatcher) UnmarshalJSON

func (re *PathMatcher) UnmarshalJSON(data []byte) error

func (*PathMatcher) UnmarshalYAML

func (re *PathMatcher) UnmarshalYAML(unmarshal func(interface{}) error) error

type ProxyRoute

type ProxyRoute struct {
	// Name of your routes
	Name string `json:"name" yaml:"name"`
	// Path which gobis handler should listen to
	// You can use globs:
	//   - appending /* will only make requests available in first level of upstream
	//   - appending /** will pass everything to upstream
	// e.g.: /app/**
	Path *PathMatcher `json:"path" yaml:"path"`
	// Url Upstream url where all request will be redirected (if ForwardedHeader option not set)
	// Query parameters can be passed, e.g.: http://localhost?param=1
	// User and password are given as basic auth too (this is not recommended to use it), e.g.: http://user:password@localhost
	// Can be empty if ForwardedHeader is set
	// This is ignored if ForwardHandler is set
	Url string `json:"url" yaml:"url"`
	// ForwardedHeader If set upstream url will be taken from the value of this header inside the received request
	// Url option will be used for the router to match host and path (if not empty) found in value of this header and host and path found in url (If NoUrlMatch is false)
	// this useful, for example, to create a cloud foundry routes service: https://docs.cloudfoundry.org/services/route-services.html
	ForwardedHeader string `json:"forwarded_header" yaml:"forwarded_header"`
	// SensitiveHeaders List of headers which should not be sent to upstream
	SensitiveHeaders []string `json:"sensitive_headers" yaml:"sensitive_headers"`
	// Methods List of http methods allowed (Default: all methods are accepted)
	Methods []string `json:"methods" yaml:"methods"`
	// HttpProxy An url to a http proxy to make requests to upstream pass to this
	HttpProxy string `json:"http_proxy" yaml:"http_proxy"`
	// HttpsProxy An url to a https proxy to make requests to upstream pass to this
	HttpsProxy string `json:"https_proxy" yaml:"https_proxy"`
	// NoProxy Force to never use proxy even proxy from environment variables
	NoProxy bool `json:"no_proxy" yaml:"no_proxy"`
	// NoBuffer Responses from upstream are buffered by default, it can be issue when sending big files
	// Set to true to stream response
	NoBuffer bool `json:"no_buffer" yaml:"no_buffer"`
	// RemoveProxyHeaders Set to true to not send X-Forwarded-* headers to upstream
	RemoveProxyHeaders bool `json:"remove_proxy_headers" yaml:"remove_proxy_headers"`
	// InsecureSkipVerify Set to true to not check ssl certificates from upstream (not really recommended)
	InsecureSkipVerify bool `json:"insecure_skip_verify" yaml:"insecure_skip_verify"`
	// MiddlewareParams It was made to pass arbitrary params to use it after in gobis middlewares
	// This can be a structure (to set them programmatically) or a map[string]interface{} (to set them from a config file)
	MiddlewareParams interface{} `json:"middleware_params" yaml:"middleware_params"`
	// ShowError Set to true to see errors on web page when there is a panic error on gobis
	ShowError bool `json:"show_error" yaml:"show_error"`
	// UseFullPath Set to true to use full path
	// e.g.: path=/metrics/** and request=/metrics/foo this will be redirected to /metrics/foo on upstream instead of /foo
	UseFullPath bool `json:"use_full_path" yaml:"use_full_path"`
	// Routes Chain others routes in a routes
	Routes []ProxyRoute `json:"routes" yaml:"routes"`
	// ForwardHandler Set a handler to use to forward request to this handler when using gobis programmatically
	ForwardHandler http.Handler `json:"-" yaml:"-"`
	// OptionsPassthrough Will forward directly to proxied route OPTIONS method without using middlewares
	OptionsPassthrough bool `json:"options_passthrough" yaml:"options_passthrough"`
	// HostsPassthrough Will forward directly to proxied route without using middlewares when http header host given match one of host in this list
	// Wildcard are allowed
	// E.g.: - *.my.passthroughurl.com -> this will allow all routes matching this wildcard to passthrough middleware
	// **Warning**: host header can be forged by user, this may be a security issue if not used properly.
	HostsPassthrough HostMatchers `json:"hosts_passthrough" yaml:"hosts_passthrough"`
}

func (ProxyRoute) Check

func (r ProxyRoute) Check() error

func (ProxyRoute) CreateRoutePath

func (r ProxyRoute) CreateRoutePath(finalPath string) string

func (ProxyRoute) PathAsStartPath

func (r ProxyRoute) PathAsStartPath() string

func (ProxyRoute) RequestPath

func (r ProxyRoute) RequestPath(req *http.Request) string

func (ProxyRoute) RouteMatcher

func (r ProxyRoute) RouteMatcher() *regexp.Regexp

func (*ProxyRoute) UnmarshalJSON

func (r *ProxyRoute) UnmarshalJSON(data []byte) error

func (*ProxyRoute) UnmarshalYAML

func (r *ProxyRoute) UnmarshalYAML(unmarshal func(interface{}) error) error

func (ProxyRoute) UpstreamUrl

func (r ProxyRoute) UpstreamUrl(req *http.Request) *url.URL

type ProxyRouteBuilder

type ProxyRouteBuilder struct {
	// contains filtered or unexported fields
}

func Builder

func Builder() *ProxyRouteBuilder

func (*ProxyRouteBuilder) AddHostPassthrough

func (b *ProxyRouteBuilder) AddHostPassthrough(hostsOrWildcards ...string) *ProxyRouteBuilder

func (*ProxyRouteBuilder) AddRoute

func (b *ProxyRouteBuilder) AddRoute(path, url string) *ProxyRouteBuilder

func (*ProxyRouteBuilder) AddRouteHandler

func (b *ProxyRouteBuilder) AddRouteHandler(path string, forwardHandler http.Handler) *ProxyRouteBuilder

func (*ProxyRouteBuilder) AddSubRoute

func (b *ProxyRouteBuilder) AddSubRoute(path, url string) *ProxyRouteBuilder

func (*ProxyRouteBuilder) AddSubRouteHandler

func (b *ProxyRouteBuilder) AddSubRouteHandler(path string, forwardHandler http.Handler) *ProxyRouteBuilder

func (*ProxyRouteBuilder) Build

func (b *ProxyRouteBuilder) Build() []ProxyRoute

func (*ProxyRouteBuilder) Finish

func (b *ProxyRouteBuilder) Finish() *ProxyRouteBuilder

func (*ProxyRouteBuilder) Parent

func (b *ProxyRouteBuilder) Parent() *ProxyRouteBuilder

func (*ProxyRouteBuilder) WithForwardedHeader

func (b *ProxyRouteBuilder) WithForwardedHeader(header string) *ProxyRouteBuilder

func (*ProxyRouteBuilder) WithHttpProxy

func (b *ProxyRouteBuilder) WithHttpProxy(httpProxy, httpsProxy string) *ProxyRouteBuilder

func (*ProxyRouteBuilder) WithInsecureSkipVerify

func (b *ProxyRouteBuilder) WithInsecureSkipVerify() *ProxyRouteBuilder

func (*ProxyRouteBuilder) WithMethods

func (b *ProxyRouteBuilder) WithMethods(methods ...string) *ProxyRouteBuilder

func (*ProxyRouteBuilder) WithMiddlewareParams

func (b *ProxyRouteBuilder) WithMiddlewareParams(params ...interface{}) *ProxyRouteBuilder

func (*ProxyRouteBuilder) WithName

func (b *ProxyRouteBuilder) WithName(name string) *ProxyRouteBuilder

func (*ProxyRouteBuilder) WithOptionsPassthrough

func (b *ProxyRouteBuilder) WithOptionsPassthrough() *ProxyRouteBuilder

func (*ProxyRouteBuilder) WithSensitiveHeaders

func (b *ProxyRouteBuilder) WithSensitiveHeaders(headers ...string) *ProxyRouteBuilder

func (*ProxyRouteBuilder) WithShowError

func (b *ProxyRouteBuilder) WithShowError() *ProxyRouteBuilder

func (*ProxyRouteBuilder) WithoutBuffer

func (b *ProxyRouteBuilder) WithoutBuffer() *ProxyRouteBuilder

func (*ProxyRouteBuilder) WithoutProxy

func (b *ProxyRouteBuilder) WithoutProxy() *ProxyRouteBuilder

func (*ProxyRouteBuilder) WithoutProxyHeaders

func (b *ProxyRouteBuilder) WithoutProxyHeaders() *ProxyRouteBuilder

type RouteTransport

type RouteTransport struct {
	// contains filtered or unexported fields
}

func (*RouteTransport) InitHttpTransport

func (r *RouteTransport) InitHttpTransport()

func (*RouteTransport) ProxyFromRouteOrEnv

func (r *RouteTransport) ProxyFromRouteOrEnv(req *http.Request) (*url.URL, error)

func (*RouteTransport) RoundTrip

func (r *RouteTransport) RoundTrip(req *http.Request) (*http.Response, error)

func (*RouteTransport) TransformRequest

func (r *RouteTransport) TransformRequest(req *http.Request)

type RouterContextKey

type RouterContextKey int

type RouterFactory

type RouterFactory interface {
	CreateMuxRouter([]ProxyRoute, string) (*mux.Router, error)
	CreateForwardHandler(ProxyRoute) (http.HandlerFunc, error)
	CreateReverseHandler(ProxyRoute) (http.Handler, error)
}

func NewRouterFactory

func NewRouterFactory(middlewareHandlers ...MiddlewareHandler) RouterFactory

func NewRouterFactoryWithMuxRouter

func NewRouterFactoryWithMuxRouter(muxRouterOption func() *mux.Router, middlewares ...MiddlewareHandler) RouterFactory

type RouterFactoryService

type RouterFactoryService struct {
	CreateTransportFunc CreateTransportFunc
	MiddlewareHandlers  []MiddlewareHandler
	// contains filtered or unexported fields
}

func (RouterFactoryService) CreateForwardHandler

func (r RouterFactoryService) CreateForwardHandler(proxyRoute ProxyRoute) (http.HandlerFunc, error)

func (RouterFactoryService) CreateMuxRouter

func (r RouterFactoryService) CreateMuxRouter(proxyRoutes []ProxyRoute, startPath string) (*mux.Router, error)

func (RouterFactoryService) CreateReverseHandler

func (r RouterFactoryService) CreateReverseHandler(proxyRoute ProxyRoute) (http.Handler, error)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL