summaryrefslogtreecommitdiff
path: root/cmd/generate/httpcache.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/generate/httpcache.go')
-rw-r--r--cmd/generate/httpcache.go45
1 files changed, 38 insertions, 7 deletions
diff --git a/cmd/generate/httpcache.go b/cmd/generate/httpcache.go
index 1fb0429..2192737 100644
--- a/cmd/generate/httpcache.go
+++ b/cmd/generate/httpcache.go
@@ -11,7 +11,32 @@ import (
"sort"
)
-var httpCache = map[string]string{}
+type httpCacheEntry struct {
+ Body string
+ Err error
+}
+
+var httpCache = map[string]httpCacheEntry{}
+
+type httpStatusError struct {
+ StatusCode int
+ Status string
+}
+
+// Is implements the interface for [errors.Is].
+func (e *httpStatusError) Is(target error) bool {
+ switch target {
+ case os.ErrNotExist:
+ return e.StatusCode == http.StatusNotFound
+ default:
+ return false
+ }
+}
+
+// Error implements [error].
+func (e *httpStatusError) Error() string {
+ return fmt.Sprintf("unexpected HTTP status: %v", e.Status)
+}
func httpGet(u string, hdr map[string]string) (string, error) {
cacheKey := url.QueryEscape(u)
@@ -26,23 +51,25 @@ func httpGet(u string, hdr map[string]string) (string, error) {
if cache, ok := httpCache[cacheKey]; ok {
fmt.Printf("CACHE-GET %q\n", u)
- return cache, nil
+ return cache.Body, cache.Err
}
if err := os.Mkdir(".http-cache", 0777); err != nil && !os.IsExist(err) {
return "", err
}
cacheFile := filepath.Join(".http-cache", cacheKey)
if bs, err := os.ReadFile(cacheFile); err == nil {
- httpCache[cacheKey] = string(bs)
fmt.Printf("CACHE-GET %q\n", u)
- return httpCache[cacheKey], nil
+ httpCache[cacheKey] = httpCacheEntry{Body: string(bs)}
+ return httpCache[cacheKey].Body, nil
} else if !os.IsNotExist(err) {
+ httpCache[cacheKey] = httpCacheEntry{Err: err}
return "", err
}
fmt.Printf("GET %q...", u)
req, err := http.NewRequest(http.MethodGet, u, nil)
if err != nil {
+ httpCache[cacheKey] = httpCacheEntry{Err: err}
return "", err
}
for k, v := range hdr {
@@ -51,23 +78,27 @@ func httpGet(u string, hdr map[string]string) (string, error) {
resp, err := http.DefaultClient.Do(req)
if err != nil {
fmt.Printf(" err\n")
+ httpCache[cacheKey] = httpCacheEntry{Err: err}
return "", err
}
if resp.StatusCode != http.StatusOK {
fmt.Printf(" err\n")
- return "", fmt.Errorf("unexpected HTTP status: %v", resp.Status)
+ httpCache[cacheKey] = httpCacheEntry{Err: err}
+ return "", &httpStatusError{StatusCode: resp.StatusCode, Status: resp.Status}
}
bs, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Printf(" err\n")
+ httpCache[cacheKey] = httpCacheEntry{Err: err}
+ httpCache[cacheKey] = httpCacheEntry{Err: err}
return "", err
}
fmt.Printf(" ok\n")
if err := os.WriteFile(cacheFile, bs, 0666); err != nil {
return "", err
}
- httpCache[cacheKey] = string(bs)
- return httpCache[cacheKey], nil
+ httpCache[cacheKey] = httpCacheEntry{Body: string(bs)}
+ return httpCache[cacheKey].Body, nil
}
func httpGetJSON(u string, hdr map[string]string, out any) error {