Documentation ¶
Overview ¶
Package starfish provides a library for building a HTTP edge router. For every request, it will check against a list of matching functions, and serve the request with the appropriate handler. This can be used to build reverse proxies, file servers, edge gateways, etc - see the examples for inspiration.
Index ¶
- Constants
- Variables
- func Proxy(upstream string) http.Handler
- func ProxyURL(origin *url.URL) http.Handler
- func ServeHTTP(w http.ResponseWriter, r *http.Request)
- func Static(path string) http.Handler
- type BoolMatcher
- type Handler
- type HandlerFunc
- type Matcher
- type MatcherFunc
- type Route
- type Router
- func (router *Router) Append(routes ...Route)
- func (router *Router) Clear()
- func (router *Router) ListenAndServe(addr string) error
- func (router *Router) ListenAndServeTLS(addr, cert, key string) error
- func (router *Router) Match(matcher Matcher) Handler
- func (router *Router) MatchFunc(matchFunc func(*http.Request) bool) Handler
- func (router *Router) Pop() Route
- func (router *Router) PopN(n int) []Route
- func (router *Router) Push(route Route)
- func (router *Router) Replace(newRoutes []Route) []Route
- func (router *Router) Routes() []Route
- func (router *Router) ServeHTTP(w http.ResponseWriter, r *http.Request)
Examples ¶
Constants ¶
const Always = BoolMatcher(true)
Always is a Matcher which always matches
Variables ¶
var Append = defaultRouter.Append
Append routes to the default router
var BadGateway = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { http.Error(w, http.StatusText(http.StatusBadGateway), http.StatusBadGateway) })
BadGateway always gives a 502
var Clear = defaultRouter.Clear
Clear the routes of the default router
var ListenAndServe = defaultRouter.ListenAndServe
ListenAndServe serves HTTP on the default router
var ListenAndServeTLS = defaultRouter.ListenAndServeTLS
ListenAndServeTLS serves HTTPS on the default router
var MatchFunc = defaultRouter.MatchFunc
MatchFunc calls the default router's MatchFunc
var Never = BoolMatcher(false)
Never is a Matcher which never matches
var Pop = defaultRouter.Pop
Pop a route from the default router
var PopN = defaultRouter.PopN
PopN routes from the default router
var Push = defaultRouter.Push
Push a route to the default router
var Replace = defaultRouter.Replace
Replace the routes of the default router
var Routes = defaultRouter.Routes
Routes of the default router
Functions ¶
func Proxy ¶
Proxy creates a new proxy to the given host. If the URL is invalid, it'll serve a BadGateway instead.
Example ¶
fooHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "Hello from upstream!") }) fooServer := httptest.NewServer(fooHandler) fooURL, _ := url.Parse(fooServer.URL) mainHandler := Proxy(fooURL) r := httptest.NewRequest(http.MethodGet, "https://example.com", nil) w := httptest.NewRecorder() mainHandler.ServeHTTP(w, r) resp := w.Result() body, _ := ioutil.ReadAll(resp.Body) fmt.Println(string(body))
Output: Hello from upstream!
Types ¶
type BoolMatcher ¶
type BoolMatcher bool
BoolMatcher gives a Matcher which always either matches or not, depending on its underlying value
type Handler ¶
type Handler interface { Handle(http.Handler) Route HandleFunc(func(http.ResponseWriter, *http.Request)) Route }
A Handler should have a Handle function which returns a Route
type HandlerFunc ¶
A HandlerFunc is an adapter to allow the use of ordinary functions as Handlers.
func (HandlerFunc) HandleFunc ¶
func (f HandlerFunc) HandleFunc(h func(http.ResponseWriter, *http.Request)) Route
HandleFunc calls f(http.HandlerFunc(h))
type MatcherFunc ¶
A MatcherFunc is an adapter to allow the use of ordinary functions as Matchers.
type Router ¶
type Router []Route
A Router is essentially a safely accessible list of Routes that also implements http.Handler.
Example ¶
host := func(host string) Matcher { return MatcherFunc(func(r *http.Request) bool { return r.Host == host }) } stringer := func(s string) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, s) }) } r := new(Router) test := func(url string) { w := httptest.NewRecorder() r.ServeHTTP(w, httptest.NewRequest(http.MethodGet, url, nil)) resp := w.Result() body, _ := ioutil.ReadAll(resp.Body) fmt.Println(string(body)) } r.Match(host("foo.com")).Handle(stringer("Hello from foo!")) test("http://foo.com") test("http://bar.com") r.Match(host("bar.com")).Handle(stringer("Hello from bar!")) test("http://foo.com") test("http://bar.com") r.Pop() test("http://foo.com") test("http://bar.com") r.Clear() test("http://foo.com") test("http://bar.com") r.MatchFunc(func(r *http.Request) bool { return true }).HandleFunc(http.NotFound)
Output: Hello from foo! 404 page not found Hello from foo! Hello from bar! Hello from foo! 404 page not found 404 page not found 404 page not found
func (*Router) ListenAndServe ¶
ListenAndServe listens on the given port and serves HTTP
func (*Router) ListenAndServeTLS ¶
ListenAndServeTLS listens on the given port and serves HTTPS