fix: Compress everything with Gzip

This commit is contained in:
TwiN 2022-12-30 21:37:52 -05:00
parent a1c8422c2f
commit 616a654b27
2 changed files with 6 additions and 26 deletions

View File

@ -1,14 +1,11 @@
package handler package handler
import ( import (
"bytes"
"compress/gzip"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
"log" "log"
"net/http" "net/http"
"strings"
"time" "time"
"github.com/TwiN/gatus/v5/client" "github.com/TwiN/gatus/v5/client"
@ -31,25 +28,14 @@ var (
) )
// EndpointStatuses handles requests to retrieve all EndpointStatus // EndpointStatuses handles requests to retrieve all EndpointStatus
// Due to the size of the response, this function leverages a cache. // Due to how intensive this operation can be on the storage, this function leverages a cache.
// Must not be wrapped by GzipHandler
func EndpointStatuses(cfg *config.Config) http.HandlerFunc { func EndpointStatuses(cfg *config.Config) http.HandlerFunc {
return func(writer http.ResponseWriter, r *http.Request) { return func(writer http.ResponseWriter, r *http.Request) {
page, pageSize := extractPageAndPageSizeFromRequest(r) page, pageSize := extractPageAndPageSizeFromRequest(r)
gzipped := strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") value, exists := cache.Get(fmt.Sprintf("endpoint-status-%d-%d", page, pageSize))
var exists bool
var value interface{}
if gzipped {
writer.Header().Set("Content-Encoding", "gzip")
value, exists = cache.Get(fmt.Sprintf("endpoint-status-%d-%d-gzipped", page, pageSize))
} else {
value, exists = cache.Get(fmt.Sprintf("endpoint-status-%d-%d", page, pageSize))
}
var data []byte var data []byte
if !exists { if !exists {
var err error var err error
buffer := &bytes.Buffer{}
gzipWriter := gzip.NewWriter(buffer)
endpointStatuses, err := store.Get().GetAllEndpointStatuses(paging.NewEndpointStatusParams().WithResults(page, pageSize)) endpointStatuses, err := store.Get().GetAllEndpointStatuses(paging.NewEndpointStatusParams().WithResults(page, pageSize))
if err != nil { if err != nil {
log.Printf("[handler][EndpointStatuses] Failed to retrieve endpoint statuses: %s", err.Error()) log.Printf("[handler][EndpointStatuses] Failed to retrieve endpoint statuses: %s", err.Error())
@ -69,14 +55,7 @@ func EndpointStatuses(cfg *config.Config) http.HandlerFunc {
http.Error(writer, "unable to marshal object to JSON", http.StatusInternalServerError) http.Error(writer, "unable to marshal object to JSON", http.StatusInternalServerError)
return return
} }
_, _ = gzipWriter.Write(data)
_ = gzipWriter.Close()
gzippedData := buffer.Bytes()
cache.SetWithTTL(fmt.Sprintf("endpoint-status-%d-%d", page, pageSize), data, cacheTTL) cache.SetWithTTL(fmt.Sprintf("endpoint-status-%d-%d", page, pageSize), data, cacheTTL)
cache.SetWithTTL(fmt.Sprintf("endpoint-status-%d-%d-gzipped", page, pageSize), gzippedData, cacheTTL)
if gzipped {
data = gzippedData
}
} else { } else {
data = value.([]byte) data = value.([]byte)
} }

View File

@ -16,6 +16,7 @@ func CreateRouter(cfg *config.Config) *mux.Router {
if cfg.Metrics { if cfg.Metrics {
router.Handle("/metrics", promhttp.Handler()).Methods("GET") router.Handle("/metrics", promhttp.Handler()).Methods("GET")
} }
router.Use(GzipHandler)
api := router.PathPrefix("/api").Subrouter() api := router.PathPrefix("/api").Subrouter()
protected := api.PathPrefix("/").Subrouter() protected := api.PathPrefix("/").Subrouter()
unprotected := api.PathPrefix("/").Subrouter() unprotected := api.PathPrefix("/").Subrouter()
@ -29,8 +30,8 @@ func CreateRouter(cfg *config.Config) *mux.Router {
} }
// Endpoints // Endpoints
unprotected.Handle("/v1/config", ConfigHandler{securityConfig: cfg.Security}).Methods("GET") unprotected.Handle("/v1/config", ConfigHandler{securityConfig: cfg.Security}).Methods("GET")
protected.HandleFunc("/v1/endpoints/statuses", EndpointStatuses(cfg)).Methods("GET") // No GzipHandler for this one, because we cache the content as Gzipped already protected.HandleFunc("/v1/endpoints/statuses", EndpointStatuses(cfg)).Methods("GET")
protected.HandleFunc("/v1/endpoints/{key}/statuses", GzipHandlerFunc(EndpointStatus)).Methods("GET") protected.HandleFunc("/v1/endpoints/{key}/statuses", EndpointStatus).Methods("GET")
unprotected.HandleFunc("/v1/endpoints/{key}/health/badge.svg", HealthBadge).Methods("GET") unprotected.HandleFunc("/v1/endpoints/{key}/health/badge.svg", HealthBadge).Methods("GET")
unprotected.HandleFunc("/v1/endpoints/{key}/uptimes/{duration}/badge.svg", UptimeBadge).Methods("GET") unprotected.HandleFunc("/v1/endpoints/{key}/uptimes/{duration}/badge.svg", UptimeBadge).Methods("GET")
unprotected.HandleFunc("/v1/endpoints/{key}/response-times/{duration}/badge.svg", ResponseTimeBadge(cfg)).Methods("GET") unprotected.HandleFunc("/v1/endpoints/{key}/response-times/{duration}/badge.svg", ResponseTimeBadge(cfg)).Methods("GET")
@ -45,6 +46,6 @@ func CreateRouter(cfg *config.Config) *mux.Router {
if err != nil { if err != nil {
panic(err) panic(err)
} }
router.PathPrefix("/").Handler(GzipHandler(http.FileServer(http.FS(staticFileSystem)))) router.PathPrefix("/").Handler(http.FileServer(http.FS(staticFileSystem)))
return router return router
} }