Add RequestCached and RequestCachedBytes functions for caching HTTP requests
This commit is contained in:
52
main.go
52
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)
|
||||
}
|
||||
|
Reference in New Issue
Block a user