@@ -6,9 +6,11 @@ package download
6
6
import (
7
7
"bytes"
8
8
"context"
9
+ "crypto/sha256"
9
10
"encoding/json"
10
11
"errors"
11
12
"fmt"
13
+ "io"
12
14
"net/http"
13
15
"net/http/httptest"
14
16
"os"
@@ -246,6 +248,11 @@ func (t *testFixture) oneShot(ctx context.Context, u Update) {
246
248
t .etags ["test/bundle1" ] = u .ETag
247
249
}
248
250
251
+ type fileInfo struct {
252
+ name string
253
+ length int64
254
+ }
255
+
249
256
type testServer struct {
250
257
t * testing.T
251
258
customAuth func (http.ResponseWriter , * http.Request ) error
@@ -256,6 +263,7 @@ type testServer struct {
256
263
server * httptest.Server
257
264
etagInResponse bool
258
265
longPoll bool
266
+ testdataHashes map [string ]fileInfo
259
267
}
260
268
261
269
func newTestServer (t * testing.T ) * testServer {
@@ -339,68 +347,58 @@ func (t *testServer) handle(w http.ResponseWriter, r *http.Request) {
339
347
340
348
var buf bytes.Buffer
341
349
342
- if r .URL .Path == "/v2/org/repo/manifests/latest" {
343
- w .Header ().Add ("Content-Length" , "596" )
344
- w .Header ().Add ("Content-Type" , "application/vnd.oci.image.manifest.v1+json" )
345
- w .Header ().Add ("Docker-Content-Digest" , "sha256:fe9c2930b6d8cc1bf3fa0c560996a95c75f0d0668bee71138355d9784c8c99b8" )
346
- w .WriteHeader (200 )
347
- return
348
- }
349
- if r .URL .Path == "/v2/org/repo/manifests/sha256:fe9c2930b6d8cc1bf3fa0c560996a95c75f0d0668bee71138355d9784c8c99b8" {
350
- w .Header ().Add ("Content-Length" , "596" )
351
- w .Header ().Add ("Content-Type" , "application/vnd.oci.image.manifest.v1+json" )
352
- w .Header ().Add ("Docker-Content-Digest" , "sha256:fe9c2930b6d8cc1bf3fa0c560996a95c75f0d0668bee71138355d9784c8c99b8" )
353
- w .WriteHeader (200 )
354
- bs , err := os .ReadFile ("testdata/manifest.layer" )
355
- if err != nil {
356
- w .WriteHeader (404 )
357
- return
350
+ if strings .HasPrefix (r .URL .Path , "/v2/org/repo/" ) {
351
+ // build test data to hash map to serve testdata files by hash
352
+ if t .testdataHashes == nil {
353
+ t .testdataHashes = make (map [string ]fileInfo )
354
+ files , err := os .ReadDir ("testdata" )
355
+ if err != nil {
356
+ t .t .Fatalf ("failed to read testdata directory: %s" , err )
357
+ }
358
+ for _ , file := range files {
359
+ if file .IsDir () {
360
+ continue
361
+ }
362
+ hash , length , err := getFileSHAandSize ("testdata/" + file .Name ())
363
+ if err != nil {
364
+ t .t .Fatalf ("failed to read testdata file: %s" , err )
365
+ }
366
+ t .testdataHashes [fmt .Sprintf ("%x" , hash )] = fileInfo {name : file .Name (), length : length }
367
+ }
358
368
}
359
- buf .WriteString (string (bs ))
360
- w .Write (buf .Bytes ())
361
- return
362
369
}
363
- if r .URL .Path == "/v2/org/repo/blobs/sha256:c5834dbce332cabe6ae68a364de171a50bf5b08024c27d7c08cc72878b4df7ff" {
364
- w .Header ().Add ("Content-Length" , "464" )
365
- w .Header ().Add ("Content-Type" , "application/vnd.oci.image.layer.v1.tar+gzip,application/vnd.oci.image.config.v1+json" )
366
- w .Header ().Add ("Docker-Content-Digest" , "sha256:c5834dbce332cabe6ae68a364de171a50bf5b08024c27d7c08cc72878b4df7ff" )
367
- w .WriteHeader (200 )
368
- bs , err := os .ReadFile ("testdata/manifest.layer" )
369
- if err != nil {
370
- w .WriteHeader (404 )
371
- return
372
- }
373
- buf .WriteString (string (bs ))
374
- buf .WriteTo (w )
375
370
376
- return
377
- }
378
- if r .URL .Path == "/v2/org/repo/blobs/sha256:b206ac766b0f3f880f6a62c4bb5ba5192d29deaefd989a1961603346a7555bdd" {
379
- w .Header ().Add ("Content-Length" , "568" )
380
- w .Header ().Add ("Content-Type" , "application/vnd.oci.image.layer.v1.tar+gzip" )
381
- w .Header ().Add ("Docker-Content-Digest" , "sha256:b206ac766b0f3f880f6a62c4bb5ba5192d29deaefd989a1961603346a7555bdd" )
382
- w .WriteHeader (200 )
383
- bs , err := os .ReadFile ("testdata/tar.layer" )
384
- if err != nil {
385
- w .WriteHeader (404 )
371
+ if strings .HasPrefix (r .URL .Path , "/v2/org/repo/blobs/sha256:" ) || strings .HasPrefix (r .URL .Path , "/v2/org/repo/manifests/sha256:" ) {
372
+ sha := strings .TrimPrefix (strings .TrimPrefix (r .URL .Path , "/v2/org/repo/blobs/sha256:" ), "/v2/org/repo/manifests/sha256:" )
373
+ if fileInfo , ok := t .testdataHashes [sha ]; ok {
374
+ w .Header ().Add ("Content-Length" , strconv .Itoa (int (fileInfo .length )))
375
+ w .Header ().Add ("Content-Type" , "application/gzip" )
376
+ w .Header ().Add ("Docker-Content-Digest" , "sha256:" + sha )
377
+ w .WriteHeader (200 )
378
+ bs , err := os .ReadFile ("testdata/" + fileInfo .name )
379
+ if err != nil {
380
+ w .WriteHeader (404 )
381
+ return
382
+ }
383
+ buf .WriteString (string (bs ))
384
+ w .Write (buf .Bytes ())
386
385
return
387
386
}
388
- buf .WriteString (string (bs ))
389
- w .Write (buf .Bytes ())
387
+ w .WriteHeader (404 )
390
388
return
391
389
}
392
- if r .URL .Path == "/v2/org/repo/blobs/sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a" {
393
- w .Header ().Add ("Content-Length" , "2" )
394
- w .Header ().Add ("Content-Type" , "application/vnd.oci.image.config.v1+json" )
395
- w .Header ().Add ("Docker-Content-Digest" , "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a" )
396
- w .WriteHeader (200 )
397
- bs , err := os .ReadFile ("testdata/config.layer" )
390
+
391
+ if strings .HasPrefix (r .URL .Path , "/v2/org/repo/manifests/" ) {
392
+ sha , size , err := getFileSHAandSize ("testdata/" + strings .TrimPrefix (r .URL .Path , "/v2/org/repo/manifests/" ) + ".manifest" )
398
393
if err != nil {
399
394
w .WriteHeader (404 )
400
395
return
401
396
}
402
- buf .WriteString (string (bs ))
403
- w .Write (buf .Bytes ())
397
+
398
+ w .Header ().Add ("Content-Length" , strconv .Itoa (int (size )))
399
+ w .Header ().Add ("Content-Type" , "application/vnd.oci.image.manifest.v1+json" )
400
+ w .Header ().Add ("Docker-Content-Digest" , "sha256:" + fmt .Sprintf ("%x" , sha ))
401
+ w .WriteHeader (200 )
404
402
return
405
403
}
406
404
name := strings .TrimPrefix (r .URL .Path , "/bundles/" )
@@ -487,3 +485,17 @@ func getPreferHeaderField(r *http.Request, field string) string {
487
485
}
488
486
return ""
489
487
}
488
+
489
+ func getFileSHAandSize (filePath string ) ([]byte , int64 , error ) {
490
+ f , err := os .Open (filePath )
491
+ if err != nil {
492
+ return nil , 0 , err
493
+ }
494
+ defer f .Close ()
495
+ hash := sha256 .New ()
496
+ w , err := io .Copy (hash , f )
497
+ if err != nil {
498
+ return nil , w , err
499
+ }
500
+ return hash .Sum (nil ), w , nil
501
+ }
0 commit comments