// loadRoutes is a helper function which loads routes from the passed mongo // collection and registers them with the passed proxy mux. func loadRoutes(c *mgo.Collection, mux *triemux.Mux, backends map[string]http.Handler) { route := &Route{} iter := c.Find(nil).Sort("incoming_path", "route_type").Iter() goneHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { http.Error(w, "410 gone", http.StatusGone) }) for iter.Next(&route) { prefix := (route.RouteType == "prefix") // the database contains paths with % encoded routes. // Unescape them here because the http.Request objects we match against contain the unescaped variants. incomingURL, err := url.Parse(route.IncomingPath) if err != nil { logWarn(fmt.Sprintf("router: found route %+v with invalid incoming path '%s', skipping!", route, route.IncomingPath)) continue } switch route.Handler { case "backend": handler, ok := backends[route.BackendID] if !ok { logWarn(fmt.Sprintf("router: found route %+v which references unknown backend "+ "%s, skipping!", route, route.BackendID)) continue } mux.Handle(incomingURL.Path, prefix, handler) logDebug(fmt.Sprintf("router: registered %s (prefix: %v) for %s", incomingURL.Path, prefix, route.BackendID)) case "redirect": redirectTemporarily := (route.RedirectType == "temporary") handler := handlers.NewRedirectHandler(incomingURL.Path, route.RedirectTo, prefix, redirectTemporarily) mux.Handle(incomingURL.Path, prefix, handler) logDebug(fmt.Sprintf("router: registered %s (prefix: %v) -> %s", incomingURL.Path, prefix, route.RedirectTo)) case "gone": mux.Handle(incomingURL.Path, prefix, goneHandler) logDebug(fmt.Sprintf("router: registered %s (prefix: %v) -> Gone", incomingURL.Path, prefix)) case "boom": // Special handler so that we can test failure behaviour. mux.Handle(incomingURL.Path, prefix, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { panic("Boom!!!") })) logDebug(fmt.Sprintf("router: registered %s (prefix: %v) -> Boom!!!", incomingURL.Path, prefix)) default: logWarn(fmt.Sprintf("router: found route %+v with unknown handler type "+ "%s, skipping!", route, route.Handler)) continue } } if err := iter.Err(); err != nil { panic(err) } }
// loadRoutes is a helper function which loads routes from the passed mongo // collection and registers them with the passed proxy mux. func loadRoutes(c *mgo.Collection, mux *triemux.Mux, backends map[string]http.Handler) { route := &Route{} iter := c.Find(nil).Sort("incoming_path", "route_type").Iter() for iter.Next(&route) { prefix := (route.RouteType == "prefix") switch route.Handler { case "backend": handler, ok := backends[route.BackendId] if !ok { logWarn(fmt.Sprintf("router: found route %+v which references unknown backend "+ "%s, skipping!", route, route.BackendId)) continue } mux.Handle(route.IncomingPath, prefix, handler) logDebug(fmt.Sprintf("router: registered %s (prefix: %v) for %s", route.IncomingPath, prefix, route.BackendId)) case "redirect": redirectTemporarily := (route.RedirectType == "temporary") handler := handlers.NewRedirectHandler(route.IncomingPath, route.RedirectTo, prefix, redirectTemporarily) mux.Handle(route.IncomingPath, prefix, handler) logDebug(fmt.Sprintf("router: registered %s (prefix: %v) -> %s", route.IncomingPath, prefix, route.RedirectTo)) case "gone": handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusGone) }) mux.Handle(route.IncomingPath, prefix, handler) logDebug(fmt.Sprintf("router: registered %s (prefix: %v) -> Gone", route.IncomingPath, prefix)) case "boom": // Special handler so that we can test failure behaviour. mux.Handle(route.IncomingPath, prefix, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { panic("Boom!!!") })) logDebug(fmt.Sprintf("router: registered %s (prefix: %v) -> Boom!!!", route.IncomingPath, prefix)) default: logWarn(fmt.Sprintf("router: found route %+v with unknown handler type "+ "%s, skipping!", route, route.Handler)) continue } } if err := iter.Err(); err != nil { panic(err) } }