generic: return content length alongside body

This increases efficiency for bigger response bodies.

Signed-off-by: Yonah <contrib@gensokyo.uk>
This commit is contained in:
Yonah 2025-09-18 06:06:46 +09:00
parent 00b50dab08
commit 21871a387c
Signed by: yonah
SSH Key Fingerprint: SHA256:vnQvK8+XXH9Tbni2AV1a/8qdVK/zPcXw52GM0ruQvwA
4 changed files with 13 additions and 13 deletions

View File

@ -10,12 +10,12 @@ type netDirect struct {
c http.Client c http.Client
} }
func (n *netDirect) Get(ctx context.Context, url string) (io.ReadCloser, error) { func (n *netDirect) Get(ctx context.Context, url string) (io.ReadCloser, int64, error) {
var resp *http.Response var resp *http.Response
if req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil); err != nil { if req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil); err != nil {
return nil, err return nil, -2, err
} else if resp, err = n.c.Do(req); err != nil { } else if resp, err = n.c.Do(req); err != nil {
return nil, err return nil, -2, err
} }
return resp.Body, nil return resp.Body, resp.ContentLength, nil
} }

View File

@ -16,7 +16,7 @@ const (
type Net interface { type Net interface {
// Get makes a get request to url and returns the response body. // Get makes a get request to url and returns the response body.
// The caller must close the body after it finishes reading from it. // The caller must close the body after it finishes reading from it.
Get(ctx context.Context, url string) (body io.ReadCloser, err error) Get(ctx context.Context, url string) (body io.ReadCloser, contentLength int64, err error)
} }
// Response is a generic API response. // Response is a generic API response.

View File

@ -47,7 +47,7 @@ func (s *Song) Enrich(ctx context.Context, n Net) error {
} }
var v SongResponse var v SongResponse
if body, err := n.Get(ctx, APIPrefix+"/song/"+s.CID.String()); err != nil { if body, _, err := n.Get(ctx, APIPrefix+"/song/"+s.CID.String()); err != nil {
return err return err
} else { } else {
if err = json.NewDecoder(body).Decode(&v); err != nil { if err = json.NewDecoder(body).Decode(&v); err != nil {

View File

@ -168,22 +168,22 @@ func TestSongEnrich(t *testing.T) {
type stubNetSongEnrichErrorCloser stubNetSongEnrich type stubNetSongEnrichErrorCloser stubNetSongEnrich
func (n stubNetSongEnrichErrorCloser) Get(ctx context.Context, url string) (io.ReadCloser, error) { func (n stubNetSongEnrichErrorCloser) Get(ctx context.Context, url string) (io.ReadCloser, int64, error) {
r, err := stubNetSongEnrich(n).Get(ctx, url) r, l, err := stubNetSongEnrich(n).Get(ctx, url)
if r != nil { if r != nil {
r = errorCloser{r} r = errorCloser{r}
} }
return r, err return r, l, err
} }
type stubNetSongEnrich map[StringInt][]byte type stubNetSongEnrich map[StringInt][]byte
func (n stubNetSongEnrich) Get(_ context.Context, url string) (io.ReadCloser, error) { func (n stubNetSongEnrich) Get(_ context.Context, url string) (io.ReadCloser, int64, error) {
if i, err := strconv.Atoi(strings.TrimPrefix(url, APIPrefix+"/song/")); err != nil { if i, err := strconv.Atoi(strings.TrimPrefix(url, APIPrefix+"/song/")); err != nil {
return nil, err return nil, -2, err
} else if b, ok := n[StringInt(i)]; !ok { } else if b, ok := n[StringInt(i)]; !ok {
return nil, fmt.Errorf("song cid %d requested, but is not present", i) return nil, -2, fmt.Errorf("song cid %d requested, but is not present", i)
} else { } else {
return nopCloser{bytes.NewReader(b)}, nil return nopCloser{bytes.NewReader(b)}, int64(len(b)), nil
} }
} }