Watch
1
0
Fork
You've already forked pkg-proxy
1
mirror of https://github.com/git-pkgs/proxy.git synced 2026-09-16 07:42:05 -04:00
pkg-proxy/internal/handler/container_metadata.go
Andrew Nesbitt b67cfb1014
Add Homebrew JSON API and bottle proxy support (#254)
* Add Homebrew JSON API and bottle proxy support

* Fix Homebrew HEAD offline fallback and non-sha256 OCI manifest handling

Route Homebrew API HEAD requests through ProxyCached so a warm cache
answers without an upstream call and stale entries are served when the
upstream is unreachable. HEAD still reaches upstream as HEAD when
metadata caching is disabled.

Limit OCI manifest digest verification to sha256 references and
Docker-Content-Digest headers so other digest algorithms are proxied
instead of rejected, and log the failing expected value.

* Reconcile with #280 and #301 after rebase

Compute real manifest digests in #280's fixture upstreams so the new
verification accepts them, and add headerETag / headerLastModified to

* Send fixed Accept for Homebrew API and match If-None-Match properly

The Homebrew API cache key does not include Accept, so replaying the
client header could serve one representation under another; the API
does not negotiate anyway. Compare If-None-Match with weak comparison,
list splitting and "*" per RFC 7232 instead of string equality, and
apply the same helper to the metadata and swift responders.

* Reconcile with #298 and #304 after rebase

Move the configureScanning doc comment back to its function after the
auto-merge stacked it on mountProtocolHandlers, and drop the second
ETag/Last-Modified set in writeMetadataCachedResponse now that the
pre-304 set covers both response paths.
2026-09-03 16:59:12 +01:00

39 lines
1.3 KiB
Go

package handler
import (
"bytes"
"context"
"database/sql"
"fmt"
"time"
"github.com/git-pkgs/proxy/internal/database"
)
func (h *ContainerHandler) storeContainerMetadata(ctx context.Context, ecosystem, cacheKey string, body []byte, etag, link, contentType, contentDigest string, lastModified, fetchedAt time.Time) (int64, error) {
if h.proxy.DB == nil || h.proxy.Storage == nil {
return int64(len(body)), nil
}
storagePath := metadataStoragePath(ecosystem, cacheKey)
size, _, err := h.proxy.Storage.Store(ctx, storagePath, bytes.NewReader(body))
if err != nil {
return 0, fmt.Errorf("storing metadata: %w", err)
}
err = h.proxy.DB.UpsertMetadataCache(&database.MetadataCacheEntry{
Ecosystem: ecosystem,
Name: cacheKey,
StoragePath: storagePath,
ETag: sql.NullString{String: etag, Valid: etag != ""},
Link: sql.NullString{String: link, Valid: link != ""},
ContentType: sql.NullString{String: contentType, Valid: contentType != ""},
ContentDigest: sql.NullString{String: contentDigest, Valid: contentDigest != ""},
Size: sql.NullInt64{Int64: size, Valid: true},
LastModified: sql.NullTime{Time: lastModified, Valid: !lastModified.IsZero()},
FetchedAt: sql.NullTime{Time: fetchedAt, Valid: !fetchedAt.IsZero()},
})
if err != nil {
return 0, err
}
return size, nil
}