Add support for region paths
This commit is contained in:
parent
20ae76ff06
commit
a571832239
11
config.go
11
config.go
|
@ -46,6 +46,17 @@ func reloadConfig() {
|
||||||
// Reload server list
|
// Reload server list
|
||||||
reloadServers()
|
reloadServers()
|
||||||
|
|
||||||
|
// Create mirror map
|
||||||
|
mirrors := make(map[string][]*Server)
|
||||||
|
|
||||||
|
for _, server := range servers {
|
||||||
|
mirrors[server.Continent] = append(mirrors[server.Continent], server)
|
||||||
|
}
|
||||||
|
|
||||||
|
mirrors["default"] = append(mirrors["NA"], mirrors["EU"]...)
|
||||||
|
|
||||||
|
mirrorMap = mirrors
|
||||||
|
|
||||||
// Check top choices size
|
// Check top choices size
|
||||||
if topChoices > len(servers) {
|
if topChoices > len(servers) {
|
||||||
topChoices = len(servers)
|
topChoices = len(servers)
|
||||||
|
|
60
http.go
60
http.go
|
@ -3,6 +3,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/jmcvetta/randutil"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
@ -19,21 +20,19 @@ func statusHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
func legacyMirrorsHandler(w http.ResponseWriter, r *http.Request) {
|
func legacyMirrorsHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
|
||||||
mirrors := make(map[string][]string)
|
mirrorOutput := make(map[string][]string)
|
||||||
|
|
||||||
for _, server := range servers {
|
for region, mirrors := range mirrorMap {
|
||||||
u := &url.URL{
|
list := make([]string, len(mirrors))
|
||||||
Scheme: r.URL.Scheme,
|
|
||||||
Host: server.Host,
|
for i, mirror := range mirrors {
|
||||||
Path: server.Path,
|
list[i] = r.URL.Scheme + "://" + mirror.Host + "/" + strings.TrimLeft(mirror.Path, "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
mirrors[server.Continent] = append(mirrors[server.Continent], u.String())
|
mirrorOutput[region] = list
|
||||||
}
|
}
|
||||||
|
|
||||||
mirrors["default"] = append(mirrors["NA"], mirrors["EU"]...)
|
json.NewEncoder(w).Encode(mirrorOutput)
|
||||||
|
|
||||||
json.NewEncoder(w).Encode(mirrors)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func mirrorsHandler(w http.ResponseWriter, r *http.Request) {
|
func mirrorsHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -61,13 +60,49 @@ func redirectHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
ip = net.ParseIP(overrideIP)
|
ip = net.ParseIP(overrideIP)
|
||||||
}
|
}
|
||||||
|
|
||||||
server, distance, err := servers.Closest(ip)
|
var server *Server
|
||||||
|
var distance float64
|
||||||
|
|
||||||
|
if strings.HasPrefix(r.URL.Path, "/region") {
|
||||||
|
parts := strings.Split(r.URL.Path, "/")
|
||||||
|
|
||||||
|
// region = parts[2]
|
||||||
|
if mirrors, ok := mirrorMap[parts[2]]; ok {
|
||||||
|
choices := make([]randutil.Choice, len(mirrors))
|
||||||
|
|
||||||
|
for i, item := range mirrors {
|
||||||
|
if !item.Available {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
choices[i] = randutil.Choice{
|
||||||
|
Weight: item.Weight,
|
||||||
|
Item: item,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
choice, err := randutil.WeightedChoice(choices)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
server = choice.Item.(*Server)
|
||||||
|
|
||||||
|
r.URL.Path = strings.Join(parts[3:], "/")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if server == nil {
|
||||||
|
server, distance, err = servers.Closest(ip)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
scheme := r.URL.Scheme
|
scheme := r.URL.Scheme
|
||||||
|
|
||||||
if scheme == "" {
|
if scheme == "" {
|
||||||
|
@ -102,7 +137,10 @@ func redirectHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
server.Redirects.Inc()
|
server.Redirects.Inc()
|
||||||
redirectsServed.Inc()
|
redirectsServed.Inc()
|
||||||
|
|
||||||
|
if distance > 0 {
|
||||||
w.Header().Set("X-Geo-Distance", fmt.Sprintf("%f", distance))
|
w.Header().Set("X-Geo-Distance", fmt.Sprintf("%f", distance))
|
||||||
|
}
|
||||||
|
|
||||||
w.Header().Set("Location", u.String())
|
w.Header().Set("Location", u.String())
|
||||||
w.WriteHeader(http.StatusFound)
|
w.WriteHeader(http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|
2
main.go
2
main.go
|
@ -20,6 +20,7 @@ import (
|
||||||
var (
|
var (
|
||||||
db *maxminddb.Reader
|
db *maxminddb.Reader
|
||||||
servers ServerList
|
servers ServerList
|
||||||
|
mirrorMap map[string][]*Server
|
||||||
|
|
||||||
dlMap map[string]string
|
dlMap map[string]string
|
||||||
|
|
||||||
|
@ -110,6 +111,7 @@ func main() {
|
||||||
r.Use(RealIPMiddleware)
|
r.Use(RealIPMiddleware)
|
||||||
r.Use(logger.Logger("router", log.StandardLogger()))
|
r.Use(logger.Logger("router", log.StandardLogger()))
|
||||||
|
|
||||||
|
r.Head("/status", statusHandler)
|
||||||
r.Get("/status", statusHandler)
|
r.Get("/status", statusHandler)
|
||||||
r.Get("/mirrors", legacyMirrorsHandler)
|
r.Get("/mirrors", legacyMirrorsHandler)
|
||||||
r.Get("/mirrors.json", mirrorsHandler)
|
r.Get("/mirrors.json", mirrorsHandler)
|
||||||
|
|
|
@ -160,6 +160,10 @@ func (s ServerList) Closest(ip net.IP) (*Server, float64, error) {
|
||||||
choices := make([]randutil.Choice, topChoices)
|
choices := make([]randutil.Choice, topChoices)
|
||||||
|
|
||||||
for i, item := range c[0:topChoices] {
|
for i, item := range c[0:topChoices] {
|
||||||
|
if item.Server == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
choices[i] = randutil.Choice{
|
choices[i] = randutil.Choice{
|
||||||
Weight: item.Server.Weight,
|
Weight: item.Server.Weight,
|
||||||
Item: item,
|
Item: item,
|
||||||
|
|
Loading…
Reference in New Issue