// HandleNotFound handles pages not found. In particular, this handler is used // when we have no matching route for a request. This also means it's not // useful to inject the livereload paraphernalia here. func HandleNotFound(templates *template.Template) httpctx.Handler { return httpctx.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotFound) err := templates.Lookup("404.html").Execute(w, nil) if err != nil { logger := termlog.FromContext(ctx) logger.Shout("Could not execute template: %s", err) } }) }
// Router constructs the main Devd router that serves all requests func (dd *Devd) Router(logger termlog.Logger, templates *template.Template) (http.Handler, error) { mux := http.NewServeMux() hasGlobal := false ci := inject.CopyInject{} if dd.HasLivereload() { ci = livereload.Injector } for match, route := range dd.Routes { if match == "/" { hasGlobal = true } handler := dd.WrapHandler( logger, route.Endpoint.Handler(templates, ci), ) handler = http.StripPrefix(route.Path, handler) mux.Handle(match, handler) } if dd.HasLivereload() { lr := livereload.NewServer("livereload", logger) mux.Handle(livereload.EndpointPath, lr) mux.Handle(livereload.ScriptPath, http.HandlerFunc(lr.ServeScript)) if dd.LivereloadRoutes { err := WatchRoutes(dd.Routes, lr, dd.Excludes, logger) if err != nil { return nil, fmt.Errorf("Could not watch routes for livereload: %s", err) } } if len(dd.WatchPaths) > 0 { err := WatchPaths(dd.WatchPaths, dd.Excludes, lr, logger) if err != nil { return nil, fmt.Errorf("Could not watch path for livereload: %s", err) } } } if !hasGlobal { mux.Handle( "/", dd.WrapHandler(logger, httpctx.HandlerFunc(HandleNotFound)), ) } var h http.Handler = mux if dd.Credentials != nil { h = httpauth.SimpleBasicAuth( dd.Credentials.username, dd.Credentials.password, )(h) } return hostPortStrip(h), nil }