69 lines
1.6 KiB
Go
69 lines
1.6 KiB
Go
// SPDX-FileCopyrightText: 2021 Luke Granger-Brown <depot@lukegb.com>
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package fuphttp
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log"
|
|
"strconv"
|
|
"time"
|
|
|
|
"gocloud.dev/blob"
|
|
"gocloud.dev/gcerrors"
|
|
)
|
|
|
|
type Metadata struct {
|
|
// ExpiresAt is the expiry time of the object.
|
|
// May be the zero time, if this object does not expire.
|
|
// Stored in expires-at.
|
|
ExpiresAt time.Time
|
|
|
|
// Attributes is the underlying gocloud Attributes.
|
|
Attributes *blob.Attributes
|
|
}
|
|
|
|
// metadata retrieves the Metadata for the object.
|
|
// Note: if the object is expired, it will delete it.
|
|
func metadata(ctx context.Context, bucket *blob.Bucket, filename string) (*Metadata, error) {
|
|
attrs, err := bucket.Attributes(ctx, filename)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("Attributes(%q): %w", filename, err)
|
|
}
|
|
|
|
m := Metadata{
|
|
Attributes: attrs,
|
|
}
|
|
|
|
var exp time.Time
|
|
if expStr, ok := attrs.Metadata["expires-at"]; ok {
|
|
// Check for expiry.
|
|
expSec, err := strconv.ParseInt(expStr, 10, 64)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("parsing expiration %q for %q: %v", expStr, filename, err)
|
|
}
|
|
|
|
exp = time.Unix(expSec, 0)
|
|
if exp.Before(time.Now()) {
|
|
// This file has expired. Delete it from the backing storage.
|
|
err := bucket.Delete(ctx, filename)
|
|
switch errorCode(err) {
|
|
case gcerrors.NotFound:
|
|
// Something probably deleted it before we could get there.
|
|
case gcerrors.OK:
|
|
// This was fine.
|
|
default:
|
|
log.Printf("deleting expired file %q: %v", filename, err)
|
|
}
|
|
return nil, &fupError{
|
|
Code: gcerrors.NotFound,
|
|
}
|
|
}
|
|
|
|
m.ExpiresAt = exp
|
|
}
|
|
|
|
return &m, nil
|
|
}
|