diff --git a/find/client/client.go b/find/client/client.go index aa82ec2..6d4fe08 100644 --- a/find/client/client.go +++ b/find/client/client.go @@ -55,7 +55,8 @@ func New(baseURL string, options ...Option) (*Client, error) { }, nil } -// Find looks up content entries by multihash. +// Find looks up content entries by multihash. If no results are found then a +// nil response without error is returned. func (c *Client) Find(ctx context.Context, m multihash.Multihash) (*model.FindResponse, error) { u := c.findURL.JoinPath(m.B58String()) req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil) @@ -63,7 +64,26 @@ func (c *Client) Find(ctx context.Context, m multihash.Multihash) (*model.FindRe return nil, err } - return c.sendRequest(req) + req.Header.Set("Content-Type", "application/json") + resp, err := c.c.Do(req) + if err != nil { + return nil, err + } + // Handle failed requests + if resp.StatusCode != http.StatusOK { + if resp.StatusCode == http.StatusNotFound { + return nil, nil + } + return nil, fmt.Errorf("find query failed: %v", http.StatusText(resp.StatusCode)) + } + + defer resp.Body.Close() + b, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + return model.UnmarshalFindResponse(b) } func (c *Client) ListProviders(ctx context.Context) ([]*model.ProviderInfo, error) { @@ -154,26 +174,3 @@ func (c *Client) GetStats(ctx context.Context) (*model.Stats, error) { return model.UnmarshalStats(body) } - -func (c *Client) sendRequest(req *http.Request) (*model.FindResponse, error) { - req.Header.Set("Content-Type", "application/json") - resp, err := c.c.Do(req) - if err != nil { - return nil, err - } - // Handle failed requests - if resp.StatusCode != http.StatusOK { - if resp.StatusCode == http.StatusNotFound { - return &model.FindResponse{}, nil - } - return nil, fmt.Errorf("batch find query failed: %v", http.StatusText(resp.StatusCode)) - } - - defer resp.Body.Close() - b, err := io.ReadAll(resp.Body) - if err != nil { - return nil, err - } - - return model.UnmarshalFindResponse(b) -} diff --git a/find/client/dhash_client.go b/find/client/dhash_client.go index f465e61..a346a62 100644 --- a/find/client/dhash_client.go +++ b/find/client/dhash_client.go @@ -98,7 +98,8 @@ func (c *DHashClient) PCache() *pcache.ProviderCache { } // Find launches FindAsync in a separate go routine and assembles the result -// into FindResponse as if it was a synchronous invocation. +// into FindResponse as if it was a synchronous invocation. If no results are +// found then a nil response without error is returned. func (c *DHashClient) Find(ctx context.Context, mh multihash.Multihash) (*model.FindResponse, error) { resChan := make(chan model.ProviderResult) errChan := make(chan error, 1) @@ -107,18 +108,25 @@ func (c *DHashClient) Find(ctx context.Context, mh multihash.Multihash) (*model. errChan <- c.FindAsync(ctx, mh, resChan) }() - mhr := model.MultihashResult{ - Multihash: mh, - } + var providerResults []model.ProviderResult for pr := range resChan { - mhr.ProviderResults = append(mhr.ProviderResults, pr) + providerResults = append(providerResults, pr) } err := <-errChan if err != nil { return nil, err } + if len(providerResults) == 0 { + return nil, nil + } + return &model.FindResponse{ - MultihashResults: []model.MultihashResult{mhr}, + MultihashResults: []model.MultihashResult{ + model.MultihashResult{ + Multihash: mh, + ProviderResults: providerResults, + }, + }, }, nil } diff --git a/find/client/interface.go b/find/client/interface.go index c93a65e..99c7c8f 100644 --- a/find/client/interface.go +++ b/find/client/interface.go @@ -12,14 +12,14 @@ import ( // Finder is the interface implemented by all find clients. type Finder interface { - // Find queries for provider content records for a single multihash. + // Find queries for provider content records for a single multihash. If no + // results are found then a nil response without error is returned. Find(context.Context, multihash.Multihash) (*model.FindResponse, error) } // FindBatch is a convenience function to lookup results for multiple // multihashes. This works with either the Client or DHashClient. If no results -// are found, then an error is not returned and there are no results in the -// response. +// are found then a nil response without error is returned. func FindBatch(ctx context.Context, finder Finder, mhs []multihash.Multihash) (*model.FindResponse, error) { var resp *model.FindResponse for i := range mhs { @@ -31,6 +31,10 @@ func FindBatch(ctx context.Context, finder Finder, mhs []multihash.Multihash) (* } return nil, err } + if r == nil { + // multihash not found + continue + } if resp == nil { resp = r } else {