Add gated cover byte fetcher

This commit is contained in:
2026-08-10 00:36:19 +07:00
parent e8d1cba6c5
commit cf06801bc5
8 changed files with 559 additions and 25 deletions
+15 -4
View File
@@ -156,9 +156,8 @@ func KaganeImageID(cover string) (string, bool) {
return m[1], true
}
// IsKaganeCoverContentType reports whether a fetched response is safe to store
// and serve as a cover.
func IsKaganeCoverContentType(contentType string) bool {
// IsCoverContentType reports whether a fetched response is safe to store and serve.
func IsCoverContentType(contentType string) bool {
switch contentType {
case "image/webp", "image/jpeg", "image/png", "image/avif", "image/gif":
return true
@@ -609,7 +608,7 @@ func (s *Store) getCover(sourceURL string) ([]byte, string, bool, error) {
}
func (s *Store) putCover(sourceURL string, body []byte, contentType string) error {
if !IsKaganeCoverContentType(contentType) {
if !IsCoverContentType(contentType) {
return fmt.Errorf("put cover %q: unsupported content type %q", sourceURL, contentType)
}
address := coverSourceAddress(sourceURL)
@@ -647,6 +646,18 @@ func (s *Store) putCover(sourceURL string, body []byte, contentType string) erro
return nil
}
// GetCover returns the immutable object addressed by its source URL. Missing
// files are reported with ok=false so callers can retry acquisition later.
func (s *Store) GetCover(sourceURL string) ([]byte, string, bool, error) {
return s.getCover(sourceURL)
}
// PutCover persists bytes under the source URL's content address. A later
// write for the same URL cannot replace the immutable object.
func (s *Store) PutCover(sourceURL string, body []byte, contentType string) error {
return s.putCover(sourceURL, body, contentType)
}
// GetKaganeCover returns one persisted cover. Missing covers are reported with
// ok=false rather than as an error so the web handler can fetch them once.
func (s *Store) GetKaganeCover(imageID string) ([]byte, string, bool, error) {