@@ -87,11 +87,11 @@ func (f *flightCache[T]) Do(key string, fn func() (T, error)) (T, error) {
8787}
8888
8989type Cache struct {
90- etagCache * sync.Map
9190 headFlight * singleflight.Group
9291 getFlight * singleflight.Group
9392
9493 discoverKeys * flightCache [[]Key ]
94+ etags * flightCache [* http.Response ]
9595}
9696
9797// NewCache returns a new Cache, which allows us to persist the results of HEAD requests
@@ -113,33 +113,13 @@ func NewCache(etag bool) *Cache {
113113 }
114114
115115 if etag {
116- c .etagCache = & sync.Map {}
116+ //nolint:bodyclose // Body is already closed before caching.
117+ c .etags = newFlightCache [* http.Response ]()
117118 }
118119
119120 return c
120121}
121122
122- func (c * Cache ) load (cacheFile string ) (* http.Response , bool ) {
123- if c == nil || c .etagCache == nil {
124- return nil , false
125- }
126-
127- v , ok := c .etagCache .Load (cacheFile )
128- if ! ok {
129- return nil , false
130- }
131-
132- return v .(* http.Response ), true
133- }
134-
135- func (c * Cache ) store (cacheFile string , resp * http.Response ) {
136- if c == nil || c .etagCache == nil {
137- return
138- }
139-
140- c .etagCache .Store (cacheFile , resp )
141- }
142-
143123// cache
144124type cache struct {
145125 dir string
@@ -209,12 +189,7 @@ func (t *cacheTransport) RoundTrip(request *http.Request) (*http.Response, error
209189}
210190
211191func (t * cacheTransport ) head (request * http.Request , cacheFile string ) (* http.Response , error ) {
212- resp , ok := t .cache .load (cacheFile )
213- if ok {
214- return resp , nil
215- }
216-
217- v , err , _ := t .cache .headFlight .Do (cacheFile , func () (any , error ) {
192+ fetch := func () (* http.Response , error ) {
218193 req := request .Clone (request .Context ())
219194 req .Method = http .MethodHead
220195 resp , err := t .wrapped .Do (req )
@@ -225,14 +200,19 @@ func (t *cacheTransport) head(request *http.Request, cacheFile string) (*http.Re
225200 // HEAD shouldn't have a body. Make sure we close it so we can reuse the connection.
226201 defer resp .Body .Close ()
227202
228- t .cache .store (cacheFile , resp )
229-
230203 return resp , nil
204+ }
205+
206+ v , err , _ := t .cache .headFlight .Do (cacheFile , func () (any , error ) {
207+ if t .cache .etags != nil {
208+ return t .cache .etags .Do (cacheFile , fetch )
209+ }
210+ //nolint:bodyclose // Body is already closed in fetch.
211+ return fetch ()
231212 })
232213 if err != nil {
233214 return nil , err
234215 }
235-
236216 return v .(* http.Response ), nil
237217}
238218
0 commit comments