client: only fetch necessary packages when cache missing
When a httpSource is used without a Cache implementation, only fetch
packages which are represented in the index. Previously if there
wasn't a Cache implementation every pacakge was enumerated, ignoring
the contents of the retrieved index.
Change-Id: I8e8e0ce412b3ded188afd6bb109d96efb7e7f27c
Reviewed-on: https://go-review.googlesource.com/c/vulndb/+/333455
Trust: Roland Shoemaker <roland@golang.org>
Trust: Zvonimir Pavlinovic <zpavlinovic@google.com>
Run-TryBot: Roland Shoemaker <roland@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Zvonimir Pavlinovic <zpavlinovic@google.com>
diff --git a/client/client.go b/client/client.go
index c7a22a0..acf29d3 100644
--- a/client/client.go
+++ b/client/client.go
@@ -158,12 +158,12 @@
}
var stillNeed []string
- if hs.cache != nil {
- for _, p := range packages {
- lastModified, present := index[p]
- if !present {
- continue
- }
+ for _, p := range packages {
+ lastModified, present := index[p]
+ if !present {
+ continue
+ }
+ if hs.cache != nil {
if cached, err := hs.cache.ReadEntries(hs.dbName, p); err != nil {
return nil, err
} else if len(cached) != 0 {
@@ -179,10 +179,8 @@
continue
}
}
- stillNeed = append(stillNeed, p)
}
- } else {
- stillNeed = packages
+ stillNeed = append(stillNeed, p)
}
for _, p := range stillNeed {
diff --git a/client/client_test.go b/client/client_test.go
index 1000797..c8c04cd 100644
--- a/client/client_test.go
+++ b/client/client_test.go
@@ -5,12 +5,15 @@
package client
import (
+ "encoding/json"
"fmt"
"io/ioutil"
"net"
"net/http"
+ "net/http/httptest"
"os"
"path"
+ "reflect"
"runtime"
"testing"
"time"
@@ -156,3 +159,30 @@
}
}
}
+
+func TestCorrectFetchesNoCache(t *testing.T) {
+ fetches := map[string]int{}
+ ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ fetches[r.URL.Path]++
+ if r.URL.Path == "/index.json" {
+ j, _ := json.Marshal(osv.DBIndex{
+ "a": time.Now(),
+ "b": time.Now(),
+ })
+ w.Write(j)
+ } else {
+ w.Write([]byte("[]"))
+ }
+ }))
+ defer ts.Close()
+
+ hs := &httpSource{url: ts.URL, c: new(http.Client)}
+ _, err := hs.Get([]string{"a", "b", "c"})
+ if err != nil {
+ t.Fatalf("unexpected error: %s", err)
+ }
+ expectedFetches := map[string]int{"/index.json": 1, "/a.json": 1, "/b.json": 1}
+ if !reflect.DeepEqual(fetches, expectedFetches) {
+ t.Errorf("unexpected fetches, got %v, want %v", fetches, expectedFetches)
+ }
+}