2023-09-11 17:09:08 +00:00
|
|
|
/*
|
2024-01-14 18:39:14 +00:00
|
|
|
Copyright © 2024 Seednode <seednode@seedno.de>
|
2023-09-11 17:09:08 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
package cmd
|
|
|
|
|
|
|
|
import (
|
2023-09-12 18:06:45 +00:00
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
2023-09-11 17:09:08 +00:00
|
|
|
"net/http"
|
2023-09-12 18:06:45 +00:00
|
|
|
"sort"
|
|
|
|
"strings"
|
|
|
|
"time"
|
2023-09-11 17:09:08 +00:00
|
|
|
|
|
|
|
"github.com/julienschmidt/httprouter"
|
2024-01-30 16:12:05 +00:00
|
|
|
"github.com/klauspost/compress/zstd"
|
2023-09-12 21:32:19 +00:00
|
|
|
"seedno.de/seednode/roulette/types"
|
2023-09-11 17:09:08 +00:00
|
|
|
)
|
|
|
|
|
2024-01-30 16:12:05 +00:00
|
|
|
func serveExtensions(formats types.Types, available bool, errorChannel chan<- error) httprouter.Handle {
|
|
|
|
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
|
|
|
startTime := time.Now()
|
|
|
|
|
|
|
|
w.Header().Set("Content-Type", "text/plain;charset=UTF-8")
|
|
|
|
|
|
|
|
var extensions string
|
|
|
|
|
|
|
|
if available {
|
|
|
|
extensions = types.SupportedFormats.GetExtensions()
|
|
|
|
} else {
|
|
|
|
extensions = formats.GetExtensions()
|
|
|
|
}
|
|
|
|
|
|
|
|
written, err := w.Write([]byte(extensions))
|
|
|
|
if err != nil {
|
|
|
|
errorChannel <- err
|
|
|
|
}
|
|
|
|
|
|
|
|
if Verbose {
|
|
|
|
fmt.Printf("%s | SERVE: Registered extension list (%s) to %s in %s\n",
|
|
|
|
startTime.Format(logDate),
|
|
|
|
humanReadableSize(written),
|
|
|
|
realIP(r),
|
|
|
|
time.Since(startTime).Round(time.Microsecond),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-15 14:51:41 +00:00
|
|
|
func serveIndex(args []string, index *fileIndex, errorChannel chan<- error) httprouter.Handle {
|
2023-09-12 18:06:45 +00:00
|
|
|
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
|
|
|
startTime := time.Now()
|
|
|
|
|
2023-09-28 15:09:45 +00:00
|
|
|
indexDump := index.List()
|
2023-09-12 18:06:45 +00:00
|
|
|
|
|
|
|
sort.SliceStable(indexDump, func(p, q int) bool {
|
|
|
|
return strings.ToLower(indexDump[p]) < strings.ToLower(indexDump[q])
|
|
|
|
})
|
|
|
|
|
2024-01-25 15:30:28 +00:00
|
|
|
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
|
2023-12-17 11:16:46 +00:00
|
|
|
|
2024-01-15 14:51:41 +00:00
|
|
|
response, err := json.MarshalIndent(indexDump, "", " ")
|
2023-09-12 18:06:45 +00:00
|
|
|
if err != nil {
|
2023-09-15 19:28:21 +00:00
|
|
|
errorChannel <- err
|
2023-09-12 18:06:45 +00:00
|
|
|
|
|
|
|
serverError(w, r, nil)
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2024-01-15 14:51:41 +00:00
|
|
|
response = append(response, []byte("\n")...)
|
|
|
|
|
2023-10-04 20:47:43 +00:00
|
|
|
written, err := w.Write(response)
|
|
|
|
if err != nil {
|
|
|
|
errorChannel <- err
|
|
|
|
}
|
2023-09-12 18:06:45 +00:00
|
|
|
|
|
|
|
if Verbose {
|
2023-09-26 10:29:55 +00:00
|
|
|
fmt.Printf("%s | SERVE: JSON index page (%s) to %s in %s\n",
|
2023-09-13 14:26:15 +00:00
|
|
|
startTime.Format(logDate),
|
2023-10-04 20:47:43 +00:00
|
|
|
humanReadableSize(written),
|
2023-09-12 18:06:45 +00:00
|
|
|
realIP(r),
|
|
|
|
time.Since(startTime).Round(time.Microsecond),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-09-13 03:35:15 +00:00
|
|
|
|
2024-01-30 16:12:05 +00:00
|
|
|
func serveIndexRebuild(args []string, index *fileIndex, formats types.Types, encoder *zstd.Encoder, errorChannel chan<- error) httprouter.Handle {
|
2023-09-13 03:35:15 +00:00
|
|
|
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
|
|
|
startTime := time.Now()
|
|
|
|
|
2024-01-30 16:12:05 +00:00
|
|
|
rebuildIndex(args, index, formats, encoder, errorChannel)
|
2023-09-13 03:35:15 +00:00
|
|
|
|
2024-01-30 16:12:05 +00:00
|
|
|
w.Header().Set("Content-Type", "text/plain;charset=UTF-8")
|
2023-09-13 03:35:15 +00:00
|
|
|
|
2024-01-30 16:12:05 +00:00
|
|
|
_, err := w.Write([]byte("Ok\n"))
|
2023-10-04 20:47:43 +00:00
|
|
|
if err != nil {
|
|
|
|
errorChannel <- err
|
2024-01-30 16:12:05 +00:00
|
|
|
|
|
|
|
return
|
2023-10-04 20:47:43 +00:00
|
|
|
}
|
2023-09-13 03:35:15 +00:00
|
|
|
|
|
|
|
if Verbose {
|
2024-01-30 16:12:05 +00:00
|
|
|
fmt.Printf("%s | SERVE: Index rebuild requested by %s took %s\n",
|
2023-09-13 14:26:15 +00:00
|
|
|
startTime.Format(logDate),
|
2023-09-13 03:35:15 +00:00
|
|
|
realIP(r),
|
|
|
|
time.Since(startTime).Round(time.Microsecond),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-15 14:51:41 +00:00
|
|
|
func serveMediaTypes(formats types.Types, available bool, errorChannel chan<- error) httprouter.Handle {
|
2023-09-13 03:35:15 +00:00
|
|
|
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
|
|
|
startTime := time.Now()
|
|
|
|
|
2024-01-25 15:30:28 +00:00
|
|
|
w.Header().Set("Content-Type", "text/plain;charset=UTF-8")
|
2023-12-17 11:16:46 +00:00
|
|
|
|
2024-01-15 14:51:41 +00:00
|
|
|
var mediaTypes string
|
2023-09-13 03:35:15 +00:00
|
|
|
|
2024-01-15 14:51:41 +00:00
|
|
|
if available {
|
|
|
|
mediaTypes = types.SupportedFormats.GetMediaTypes()
|
|
|
|
} else {
|
|
|
|
mediaTypes = formats.GetMediaTypes()
|
2023-09-13 03:35:15 +00:00
|
|
|
}
|
|
|
|
|
2024-01-15 14:51:41 +00:00
|
|
|
written, err := w.Write([]byte(mediaTypes))
|
2023-10-04 20:47:43 +00:00
|
|
|
if err != nil {
|
|
|
|
errorChannel <- err
|
|
|
|
}
|
2023-09-13 03:35:15 +00:00
|
|
|
|
|
|
|
if Verbose {
|
2024-01-15 14:51:41 +00:00
|
|
|
fmt.Printf("%s | SERVE: Available media type list (%s) to %s in %s\n",
|
2023-09-13 14:26:15 +00:00
|
|
|
startTime.Format(logDate),
|
2023-10-04 20:47:43 +00:00
|
|
|
humanReadableSize(written),
|
2023-09-13 03:35:15 +00:00
|
|
|
realIP(r),
|
|
|
|
time.Since(startTime).Round(time.Microsecond),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-09-13 17:00:24 +00:00
|
|
|
|
2024-01-30 16:12:05 +00:00
|
|
|
func registerAPIHandlers(mux *httprouter.Router, args []string, index *fileIndex, formats types.Types, encoder *zstd.Encoder, errorChannel chan<- error) {
|
2023-09-28 15:09:45 +00:00
|
|
|
if Index {
|
2024-01-15 15:28:59 +00:00
|
|
|
mux.GET(Prefix+AdminPrefix+"/index", serveIndex(args, index, errorChannel))
|
2024-01-30 16:12:05 +00:00
|
|
|
mux.POST(Prefix+AdminPrefix+"/index/rebuild", serveIndexRebuild(args, index, formats, encoder, errorChannel))
|
2023-09-13 17:00:24 +00:00
|
|
|
}
|
|
|
|
|
2024-01-15 15:28:59 +00:00
|
|
|
mux.GET(Prefix+AdminPrefix+"/extensions/available", serveExtensions(formats, true, errorChannel))
|
|
|
|
mux.GET(Prefix+AdminPrefix+"/extensions/enabled", serveExtensions(formats, false, errorChannel))
|
|
|
|
mux.GET(Prefix+AdminPrefix+"/types/available", serveMediaTypes(formats, true, errorChannel))
|
|
|
|
mux.GET(Prefix+AdminPrefix+"/types/enabled", serveMediaTypes(formats, false, errorChannel))
|
2023-09-13 17:00:24 +00:00
|
|
|
}
|