diff options
Diffstat (limited to 'cmd/generate/httpcache.go')
-rw-r--r-- | cmd/generate/httpcache.go | 45 |
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 { |