[mirror] Scalable static site server for Git forges (like GitHub Pages)

Consolidate return values into `BlobMetadata`. NFC

+6 -1
src/backend.go
··· 31 31 FeatureCheckDomainMarker BackendFeature = "check-domain-marker" 32 32 ) 33 33 34 + type BlobMetadata struct { 35 + Size int64 36 + LastModified time.Time 37 + } 38 + 34 39 type GetManifestOptions struct { 35 40 // If true and the manifest is past the cache `MaxAge`, `GetManifest` blocks and returns 36 41 // a fresh object instead of revalidating in background and returning a stale object. ··· 77 82 78 83 // Retrieve a blob. Returns `reader, size, mtime, err`. 79 84 GetBlob(ctx context.Context, name string) ( 80 - reader io.ReadSeeker, size uint64, mtime time.Time, err error, 85 + reader io.ReadSeeker, metadata BlobMetadata, err error, 81 86 ) 82 87 83 88 // Store a blob. If a blob called `name` already exists, this function returns `nil` without
+2 -3
src/backend_fs.go
··· 11 11 "os" 12 12 "path/filepath" 13 13 "strings" 14 - "time" 15 14 ) 16 15 17 16 type FSBackend struct { ··· 118 117 func (fs *FSBackend) GetBlob( 119 118 ctx context.Context, name string, 120 119 ) ( 121 - reader io.ReadSeeker, size uint64, mtime time.Time, err error, 120 + reader io.ReadSeeker, metadata BlobMetadata, err error, 122 121 ) { 123 122 blobPath := filepath.Join(splitBlobName(name)...) 124 123 stat, err := fs.blobRoot.Stat(blobPath) ··· 134 133 err = fmt.Errorf("open: %w", err) 135 134 return 136 135 } 137 - return file, uint64(stat.Size()), stat.ModTime(), nil 136 + return file, BlobMetadata{int64(stat.Size()), stat.ModTime()}, nil 138 137 } 139 138 140 139 func (fs *FSBackend) PutBlob(ctx context.Context, name string, data []byte) error {
+3 -3
src/backend_s3.go
··· 266 266 func (s3 *S3Backend) GetBlob( 267 267 ctx context.Context, name string, 268 268 ) ( 269 - reader io.ReadSeeker, size uint64, mtime time.Time, err error, 269 + reader io.ReadSeeker, metadata BlobMetadata, err error, 270 270 ) { 271 271 loader := func(ctx context.Context, name string) (*CachedBlob, error) { 272 272 logc.Printf(ctx, "s3: get blob %s\n", name) ··· 316 316 } 317 317 } else { 318 318 reader = bytes.NewReader(cached.blob) 319 - size = uint64(len(cached.blob)) 320 - mtime = cached.mtime 319 + metadata.Size = int64(len(cached.blob)) 320 + metadata.LastModified = cached.mtime 321 321 } 322 322 return 323 323 }
+7 -5
src/collect.go
··· 5 5 "context" 6 6 "fmt" 7 7 "io" 8 - "time" 9 8 ) 10 9 11 10 type Flusher interface { ··· 66 65 67 66 case Type_ExternalFile: 68 67 var blobReader io.Reader 69 - var blobMtime time.Time 68 + var blobMetadata BlobMetadata 70 69 var blobData []byte 71 - blobReader, _, blobMtime, err = backend.GetBlob(context, string(entry.Data)) 70 + blobReader, blobMetadata, err = backend.GetBlob(context, string(entry.Data)) 71 + if err != nil { 72 + return 73 + } 74 + blobData, err = io.ReadAll(blobReader) 72 75 if err != nil { 73 76 return 74 77 } 75 - blobData, _ = io.ReadAll(blobReader) 76 78 header.Typeflag = tar.TypeReg 77 79 header.Mode = 0644 78 - header.ModTime = blobMtime 80 + header.ModTime = blobMetadata.LastModified 79 81 err = appendFile(&header, blobData, entry.GetTransform()) 80 82 81 83 case Type_Symlink:
+1 -1
src/main.go
··· 287 287 logc.Fatalln(ctx, err) 288 288 } 289 289 290 - reader, _, _, err := backend.GetBlob(ctx, *getBlob) 290 + reader, _, err := backend.GetBlob(ctx, *getBlob) 291 291 if err != nil { 292 292 logc.Fatalln(ctx, err) 293 293 }
+4 -4
src/observe.go
··· 344 344 func (backend *observedBackend) GetBlob( 345 345 ctx context.Context, name string, 346 346 ) ( 347 - reader io.ReadSeeker, size uint64, mtime time.Time, err error, 347 + reader io.ReadSeeker, metadata BlobMetadata, err error, 348 348 ) { 349 349 span, ctx := ObserveFunction(ctx, "GetBlob", "blob.name", name) 350 - if reader, size, mtime, err = backend.inner.GetBlob(ctx, name); err == nil { 351 - ObserveData(ctx, "blob.size", size) 350 + if reader, metadata, err = backend.inner.GetBlob(ctx, name); err == nil { 351 + ObserveData(ctx, "blob.size", metadata.Size) 352 352 blobsRetrievedCount.Inc() 353 - blobsRetrievedBytes.Add(float64(size)) 353 + blobsRetrievedBytes.Add(float64(metadata.Size)) 354 354 } 355 355 span.Finish() 356 356 return
+3 -1
src/pages.go
··· 292 292 w.WriteHeader(http.StatusNotModified) 293 293 return nil 294 294 } else { 295 - reader, _, mtime, err = backend.GetBlob(r.Context(), string(entry.Data)) 295 + var metadata BlobMetadata 296 + reader, metadata, err = backend.GetBlob(r.Context(), string(entry.Data)) 296 297 if err != nil { 297 298 ObserveError(err) // all storage errors must be reported 298 299 w.WriteHeader(http.StatusInternalServerError) 299 300 fmt.Fprintf(w, "internal server error: %s\n", err) 300 301 return err 301 302 } 303 + mtime = metadata.LastModified 302 304 w.Header().Set("ETag", etag) 303 305 } 304 306 } else if entry.GetType() == Type_Directory {