2022-08-15 06:16:22 +00:00
|
|
|
package redirector
|
2022-04-02 08:47:14 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
_ "embed"
|
|
|
|
"encoding/json"
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
|
|
"net/http"
|
2022-08-14 07:42:49 +00:00
|
|
|
"strconv"
|
2022-04-02 08:47:14 +00:00
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
2022-08-14 07:42:49 +00:00
|
|
|
// legacyMirrorsHandler will list the mirrors by region in the legacy format
|
|
|
|
// it is preferred to use mirrors.json, but this handler is here for build support
|
2022-08-15 06:16:22 +00:00
|
|
|
func (r *Redirector) legacyMirrorsHandler(w http.ResponseWriter, req *http.Request) {
|
2022-04-02 08:47:14 +00:00
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
|
|
|
|
|
|
mirrorOutput := make(map[string][]string)
|
|
|
|
|
2022-08-15 06:16:22 +00:00
|
|
|
for region, mirrors := range r.regionMap {
|
2022-04-02 08:47:14 +00:00
|
|
|
list := make([]string, len(mirrors))
|
|
|
|
|
|
|
|
for i, mirror := range mirrors {
|
2022-08-15 06:16:22 +00:00
|
|
|
list[i] = req.URL.Scheme + "://" + mirror.Host + "/" + strings.TrimLeft(mirror.Path, "/")
|
2022-04-02 08:47:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
mirrorOutput[region] = list
|
|
|
|
}
|
|
|
|
|
|
|
|
json.NewEncoder(w).Encode(mirrorOutput)
|
|
|
|
}
|
|
|
|
|
2022-08-14 07:42:49 +00:00
|
|
|
// mirrorsHandler is a simple handler that will return the list of servers
|
2022-08-15 06:16:22 +00:00
|
|
|
func (r *Redirector) mirrorsHandler(w http.ResponseWriter, req *http.Request) {
|
2022-04-02 08:47:14 +00:00
|
|
|
w.Header().Set("Content-Type", "application/json")
|
2022-08-15 06:16:22 +00:00
|
|
|
json.NewEncoder(w).Encode(r.servers)
|
2022-04-02 08:47:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
|
|
|
//go:embed assets/status-up.svg
|
|
|
|
statusUp []byte
|
|
|
|
|
|
|
|
//go:embed assets/status-down.svg
|
|
|
|
statusDown []byte
|
|
|
|
|
|
|
|
//go:embed assets/status-unknown.svg
|
|
|
|
statusUnknown []byte
|
|
|
|
)
|
|
|
|
|
2022-08-14 07:42:49 +00:00
|
|
|
// mirrorStatusHandler is a fancy svg-returning handler.
|
|
|
|
// it is used to display mirror statuses on a config repo of sorts
|
2022-08-15 06:16:22 +00:00
|
|
|
func (r *Redirector) mirrorStatusHandler(w http.ResponseWriter, req *http.Request) {
|
|
|
|
serverHost := chi.URLParam(req, "server")
|
2022-04-02 08:47:14 +00:00
|
|
|
|
|
|
|
w.Header().Set("Content-Type", "image/svg+xml;charset=utf-8")
|
2022-08-14 07:42:49 +00:00
|
|
|
w.Header().Set("Cache-Control", "max-age=120")
|
2022-04-02 08:47:14 +00:00
|
|
|
|
|
|
|
if serverHost == "" {
|
|
|
|
w.Write(statusUnknown)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
serverHost = strings.Replace(serverHost, "_", ".", -1)
|
|
|
|
|
2022-08-15 06:16:22 +00:00
|
|
|
server, ok := r.hostMap[serverHost]
|
2022-04-02 08:47:14 +00:00
|
|
|
|
|
|
|
if !ok {
|
2022-08-14 07:42:49 +00:00
|
|
|
w.Header().Set("Content-Length", strconv.Itoa(len(statusUnknown)))
|
2022-04-02 08:47:14 +00:00
|
|
|
w.Write(statusUnknown)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-08-14 07:42:49 +00:00
|
|
|
key := "offline"
|
|
|
|
|
|
|
|
if server.Available {
|
|
|
|
key = "online"
|
|
|
|
}
|
|
|
|
|
|
|
|
w.Header().Set("ETag", "\""+key+"\"")
|
|
|
|
|
2022-08-15 06:16:22 +00:00
|
|
|
if match := req.Header.Get("If-None-Match"); match != "" {
|
2022-08-14 07:42:49 +00:00
|
|
|
if strings.Trim(match, "\"") == key {
|
|
|
|
w.WriteHeader(http.StatusNotModified)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-02 08:47:14 +00:00
|
|
|
if server.Available {
|
2022-08-14 07:42:49 +00:00
|
|
|
w.Header().Set("Content-Length", strconv.Itoa(len(statusUp)))
|
2022-04-02 08:47:14 +00:00
|
|
|
w.Write(statusUp)
|
|
|
|
} else {
|
2022-08-14 07:42:49 +00:00
|
|
|
w.Header().Set("Content-Length", strconv.Itoa(len(statusDown)))
|
2022-04-02 08:47:14 +00:00
|
|
|
w.Write(statusDown)
|
|
|
|
}
|
|
|
|
}
|