summaryrefslogtreecommitdiff
path: root/internal/storage/storage_common.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/storage/storage_common.go')
-rw-r--r--internal/storage/storage_common.go121
1 files changed, 121 insertions, 0 deletions
diff --git a/internal/storage/storage_common.go b/internal/storage/storage_common.go
new file mode 100644
index 000000000..3e1311525
--- /dev/null
+++ b/internal/storage/storage_common.go
@@ -0,0 +1,121 @@
+// GoToSocial
+// Copyright (C) GoToSocial Authors admin@gotosocial.org
+// SPDX-License-Identifier: AGPL-3.0-or-later
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+package storage
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "io"
+ "net/url"
+ "time"
+
+ "code.superseriousbusiness.org/gotosocial/internal/config"
+ "codeberg.org/gruf/go-bytesize"
+ "codeberg.org/gruf/go-storage"
+ "codeberg.org/gruf/go-storage/disk"
+)
+
+// PresignedURL represents a pre signed S3 URL with
+// an expiry time.
+type PresignedURL struct {
+ *url.URL
+ Expiry time.Time // link expires at this time
+}
+
+// IsInvalidKey returns whether error is an invalid-key
+// type error returned by the underlying storage library.
+func IsInvalidKey(err error) bool {
+ return errors.Is(err, storage.ErrInvalidKey)
+}
+
+// IsAlreadyExist returns whether error is an already-exists
+// type error returned by the underlying storage library.
+func IsAlreadyExist(err error) bool {
+ return errors.Is(err, storage.ErrAlreadyExists)
+}
+
+// IsNotFound returns whether error is a not-found error
+// type returned by the underlying storage library.
+func IsNotFound(err error) bool {
+ return errors.Is(err, storage.ErrNotFound)
+}
+
+// Get returns the byte value for key in storage.
+func (d *Driver) Get(ctx context.Context, key string) ([]byte, error) {
+ return d.Storage.ReadBytes(ctx, key)
+}
+
+// GetStream returns an io.ReadCloser for the value bytes at key in the storage.
+func (d *Driver) GetStream(ctx context.Context, key string) (io.ReadCloser, error) {
+ return d.Storage.ReadStream(ctx, key)
+}
+
+// Put writes the supplied value bytes at key in the storage
+func (d *Driver) Put(ctx context.Context, key string, value []byte) (int, error) {
+ return d.Storage.WriteBytes(ctx, key, value)
+}
+
+// Delete attempts to remove the supplied key (and corresponding value) from storage.
+func (d *Driver) Delete(ctx context.Context, key string) error {
+ return d.Storage.Remove(ctx, key)
+}
+
+// Has checks if the supplied key is in the storage.
+func (d *Driver) Has(ctx context.Context, key string) (bool, error) {
+ stat, err := d.Storage.Stat(ctx, key)
+ return (stat != nil), err
+}
+
+// WalkKeys walks the keys in the storage.
+func (d *Driver) WalkKeys(ctx context.Context, walk func(string) error) error {
+ return d.Storage.WalkKeys(ctx, storage.WalkKeysOpts{
+ Step: func(entry storage.Entry) error {
+ return walk(entry.Key)
+ },
+ })
+}
+
+func AutoConfig() (*Driver, error) {
+ switch backend := config.GetStorageBackend(); backend {
+ case "s3":
+ return NewS3Storage()
+ case "local":
+ return NewFileStorage()
+ default:
+ return nil, fmt.Errorf("invalid storage backend: %s", backend)
+ }
+}
+
+func NewFileStorage() (*Driver, error) {
+ // Load runtime configuration
+ basePath := config.GetStorageLocalBasePath()
+
+ // Use default disk config with
+ // increased write buffer size.
+ diskCfg := disk.DefaultConfig()
+ diskCfg.WriteBufSize = int(16 * bytesize.KiB)
+
+ // Open the disk storage implementation
+ disk, err := disk.Open(basePath, &diskCfg)
+ if err != nil {
+ return nil, fmt.Errorf("error opening disk storage: %w", err)
+ }
+
+ return &Driver{Storage: disk}, nil
+}