// Create all routes and start the HTTP-server func serveRequests() { router := httprouter.New() // Default API-message router.GET("/api", routes.ApiIndex) // API setupApi1(router) setupApi2(router) // Web-Frontend if lib.GetConfiguration().Application.UseWebFrontend { setupWebFrontend(router) } else { router.GET("/", routes.NoWebFrontendIndex) } // 404 Handler router.NotFound = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { http.Error(w, "Error 404: Not Found", 404) }) logging.MustGetLogger("").Debug("Listening on " + lib.GetConfiguration().Address + ":" + strconv.Itoa(lib.GetConfiguration().Port) + "...") logging.MustGetLogger("").Fatal(http.ListenAndServe(lib.GetConfiguration().Address+":"+strconv.Itoa(lib.GetConfiguration().Port), router)) }
// Updates the application's check-interval in the database. func ApiSettingsInterval(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { if !lib.IsLoggedIn(r) { SendJsonMessage(w, http.StatusUnauthorized, false, "Unauthorized.") return } // Get data from Request r.ParseForm() temp := r.Form.Get("interval") value, err := strconv.Atoi(temp) // Simple Validation if err != nil || value < 10 || value > 600 { SendJsonMessage(w, http.StatusBadRequest, false, "Unable to process your Request: Submit a valid value between 10 and 600 seconds.") return } // Update Database-Row db := lib.GetDatabase() _, err = db.Exec("UPDATE settings SET value = ? WHERE name = 'interval';", value) if err != nil { logging.MustGetLogger("").Error("Unable to change Interval: ", err) SendJsonMessage(w, http.StatusInternalServerError, false, "Unable to process your Request: "+err.Error()) return } // Update Configuration lib.GetConfiguration().Dynamic.Interval = value SendJsonMessage(w, http.StatusOK, true, "") }
// Creates a timer to regularly check all Websites func startCheckTimer() { timer := time.NewTimer(time.Second * time.Duration(lib.GetConfiguration().Dynamic.Interval)) go func() { <-timer.C checkAllSites() startCheckTimer() }() }
// Renders the main-page func ViewIndex(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { // Parse template-files data := SiteData{lib.GetConfiguration().Application.Title} t, err := template.ParseFiles("views/index.html", "views/partials/styles.html", "views/partials/footer.html", "views/partials/scripts.html") if t != nil { w.Header().Set("Content-Type", "text/html") t.Execute(w, data) } else { logging.MustGetLogger("").Error("Error while parsing Template: ", err) http.Error(w, "Error 500: Internal Server Error", http.StatusInternalServerError) } }
// Checks all enabled Websites func checkAllSites() { // Check for internet-connection if !lib.GetConfiguration().Application.RunCheckIfOffline { res, err := goreq.Request{Uri: "https://google.com", Method: "HEAD", UserAgent: "UpAndRunning2 (https://github.com/MarvinMenzerath/UpAndRunning2)", MaxRedirects: 1, Timeout: 5 * time.Second}.Do() if err != nil { logging.MustGetLogger("").Warning("Did not check Websites because of missing internet-connection: ", err) return } else { if res.StatusCode != 200 { logging.MustGetLogger("").Warning("Did not check Websites because of missing internet-connection.") res.Body.Close() return } } } // Query the Database db := lib.GetDatabase() rows, err := db.Query("SELECT id, protocol, url, checkMethod FROM websites WHERE enabled = 1;") if err != nil { logging.MustGetLogger("").Error("Unable to fetch Websites: ", err) return } defer rows.Close() // Check every Website count := 0 for rows.Next() { var website lib.Website err = rows.Scan(&website.Id, &website.Protocol, &website.Url, &website.CheckMethod) if err != nil { logging.MustGetLogger("").Error("Unable to read Website-Row: ", err) return } go website.RunCheck(false) count++ time.Sleep(time.Millisecond * 200) } // Check for Errors err = rows.Err() if err != nil { logging.MustGetLogger("").Error("Unable to read Website-Rows: ", err) return } logging.MustGetLogger("").Info("Checked " + strconv.Itoa(count) + " active Websites.") }
// Renders the admin-backend if the user is logged in. // If the user is not logged in, he will be redirected to the login-page. func ViewAdmin(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { if !lib.IsLoggedIn(r) { http.Redirect(w, r, "/admin/login", http.StatusFound) return } // Parse template-files c := lib.GetConfiguration() data := AdminSiteData{c.Application.Title, c.Dynamic.Interval, c.Static.Version, runtime.Version(), runtime.GOOS + "_" + runtime.GOARCH} t, err := template.ParseFiles("views/admin.html", "views/partials/styles.html", "views/partials/footer.html", "views/partials/scripts.html") if t != nil { w.Header().Set("Content-Type", "text/html") t.Execute(w, data) } else { logging.MustGetLogger("").Error("Error while parsing Template: ", err) http.Error(w, "Error 500: Internal Server Error", http.StatusInternalServerError) } }
// UpAndRunning2 Main - The application's entrance-point func main() { // Logger lib.SetupLogger() // Welcome logging.MustGetLogger("").Info("Welcome to UpAndRunning2 v" + VERSION + " [" + goVersion + "@" + goArch + "]!") // Config lib.ReadConfigurationFromFile("config/local.json") lib.SetStaticConfiguration(lib.StaticConfiguration{VERSION, goVersion, goArch}) // Database lib.OpenDatabase(lib.GetConfiguration().Database) // Config (again) lib.ReadConfigurationFromDatabase(lib.GetDatabase()) // Admin-User admin := lib.Admin{} admin.Init() // Session-Management lib.InitSessionManagement() // Additional Libraries goreq.SetConnectTimeout(5 * time.Second) lib.InitHttpStatusCodeMap() go lib.RunTelegramBot() // Start Checking and Serving checkAllSites() startCheckTimer() startCleaningTimer() serveRequests() lib.GetDatabase().Close() }