From 7b9446238858dc802fef0929d4419c997b29b6a8 Mon Sep 17 00:00:00 2001 From: PhatPhuckDave Date: Mon, 11 Aug 2025 10:24:43 +0200 Subject: [PATCH] Add RequestCached and RequestCachedBytes functions for caching HTTP requests --- main.go | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/main.go b/main.go index db95bc5..fadf173 100644 --- a/main.go +++ b/main.go @@ -1,7 +1,12 @@ package cyutils import ( + "encoding/json" + "fmt" + "io" "net/http" + "os" + "path/filepath" "sync" "golang.org/x/time/rate" @@ -77,3 +82,50 @@ func LimitedHttp(rps float64, burst int) *http.Client { Transport: transport, } } + +func RequestCached[T any](req *http.Request, filename string) (T, error) { + var zero T + + data, err := os.ReadFile(filename) + if err != nil { + if !os.IsNotExist(err) { + return zero, fmt.Errorf("failed to read cache: %w", err) + } + + resp, httpErr := http.DefaultClient.Do(req) + if httpErr != nil { + return zero, fmt.Errorf("HTTP request failed: %w", httpErr) + } + defer resp.Body.Close() + + body, readErr := io.ReadAll(resp.Body) + if readErr != nil { + return zero, fmt.Errorf("failed to read response body: %w", readErr) + } + + dir := filepath.Dir(filename) + if dir != "." && dir != "" { + if mkErr := os.MkdirAll(dir, 0o755); mkErr != nil { + return zero, fmt.Errorf("failed to create cache dir %s: %w", dir, mkErr) + } + } + if writeErr := os.WriteFile(filename, body, 0o644); writeErr != nil { + return zero, fmt.Errorf("failed to write cache %s: %w", filename, writeErr) + } + data = body + } + + if _, ok := any(zero).([]byte); ok { + return any(data).(T), nil + } + + var out T + if err := json.Unmarshal(data, &out); err != nil { + return zero, fmt.Errorf("failed to unmarshal cached response: %w", err) + } + return out, nil +} + +func RequestCachedBytes(req *http.Request, filename string) ([]byte, error) { + return RequestCached[[]byte](req, filename) +}