armbian-router/main.go

132 lines
3.0 KiB
Go
Raw Normal View History

2022-01-10 04:47:40 +00:00
package main
import (
2022-01-10 04:53:23 +00:00
"github.com/oschwald/maxminddb-golang"
log "github.com/sirupsen/logrus"
"github.com/spf13/viper"
"net"
"net/http"
"net/url"
"strings"
2022-01-10 04:47:40 +00:00
)
var (
2022-01-10 04:53:23 +00:00
db *maxminddb.Reader
servers ServerList
dlMap map[string]string
2022-01-10 04:47:40 +00:00
)
2022-01-10 04:53:23 +00:00
// City represents a MaxmindDB city
2022-01-10 04:47:40 +00:00
type City struct {
2022-01-10 04:53:23 +00:00
Location struct {
Latitude float64 `maxminddb:"latitude"`
Longitude float64 `maxminddb:"longitude"`
} `maxminddb:"location"`
2022-01-10 04:47:40 +00:00
}
func main() {
viper.SetDefault("bind", ":8080")
2022-01-10 04:53:23 +00:00
viper.SetConfigName("dlrouter") // name of config file (without extension)
viper.SetConfigType("yaml") // REQUIRED if the config file does not have the extension in the name
viper.AddConfigPath("/etc/dlrouter/") // path to look for the config file in
viper.AddConfigPath("$HOME/.dlrouter") // call multiple times to add many search paths
viper.AddConfigPath(".") // optionally look for config in the working directory
err := viper.ReadInConfig() // Find and read the config file
if err != nil { // Handle errors reading the config file
log.WithError(err).Fatalln("Unable to load config file")
}
db, err = maxminddb.Open(viper.GetString("geodb"))
if err != nil {
log.WithError(err).Fatalln("Unable to open database")
}
if mapFile := viper.GetString("dl_map"); mapFile != "" {
log.WithField("file", mapFile).Info("Loading download map")
dlMap, err = loadMap(mapFile)
if err != nil {
log.WithError(err).Fatalln("Unable to load download map")
}
}
2022-01-10 04:53:23 +00:00
serverList := viper.GetStringSlice("servers")
for _, server := range serverList {
var prefix string
if !strings.HasPrefix(server, "http") {
prefix = "https://"
}
u, err := url.Parse(prefix + server)
if err != nil {
log.WithFields(log.Fields{
"error": err,
"server": server,
}).Warning("Server is invalid")
continue
}
ips, err := net.LookupIP(u.Host)
if err != nil {
log.WithFields(log.Fields{
"error": err,
"server": server,
}).Warning("Could not resolve address")
continue
}
var city City
err = db.Lookup(ips[0], &city)
if err != nil {
log.WithFields(log.Fields{
"error": err,
"server": server,
}).Warning("Could not geolocate address")
continue
}
servers = append(servers, &Server{
Host: u.Host,
Path: u.Path,
Latitude: city.Location.Latitude,
Longitude: city.Location.Longitude,
})
log.WithFields(log.Fields{
"server": u.Host,
"path": u.Path,
"latitude": city.Location.Latitude,
"longitude": city.Location.Longitude,
}).Info("Added server")
}
log.Info("Servers added, checking statuses")
// Force initial check before running
servers.Check()
// Start check loop
go servers.checkLoop()
log.Info("Starting")
mux := http.NewServeMux()
mux.HandleFunc("/status", statusHandler)
mux.HandleFunc("/mirrors", mirrorsHandler)
mux.HandleFunc("/reload", reloadHandler)
2022-01-10 05:15:07 +00:00
mux.HandleFunc("/dl_map", dlMapHandler)
mux.HandleFunc("/", RealIPMiddleware(redirectHandler))
2022-01-10 04:53:23 +00:00
http.ListenAndServe(viper.GetString("bind"), mux)
2022-01-10 04:47:40 +00:00
}