diff options
Diffstat (limited to 'internal')
-rw-r--r-- | internal/config/config.go | 1 | ||||
-rw-r--r-- | internal/config/defaults.go | 1 | ||||
-rw-r--r-- | internal/config/helpers.gen.go | 25 | ||||
-rw-r--r-- | internal/config/validate.go | 24 | ||||
-rw-r--r-- | internal/storage/storage.go | 38 |
5 files changed, 83 insertions, 6 deletions
diff --git a/internal/config/config.go b/internal/config/config.go index a6499d822..bba284d56 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -110,6 +110,7 @@ type Configuration struct { StorageS3UseSSL bool `name:"storage-s3-use-ssl" usage:"Use SSL for S3 connections. Only set this to 'false' when testing locally"` StorageS3BucketName string `name:"storage-s3-bucket" usage:"Place blobs in this bucket"` StorageS3Proxy bool `name:"storage-s3-proxy" usage:"Proxy S3 contents through GoToSocial instead of redirecting to a presigned URL"` + StorageS3RedirectURL string `name:"storage-s3-redirect-url" usage:"Custom URL to use for redirecting S3 media links. If set, this will be used instead of the S3 bucket URL."` StatusesMaxChars int `name:"statuses-max-chars" usage:"Max permitted characters for posted statuses, including content warning"` StatusesPollMaxOptions int `name:"statuses-poll-max-options" usage:"Max amount of options permitted on a poll"` diff --git a/internal/config/defaults.go b/internal/config/defaults.go index 835841c84..d16df6802 100644 --- a/internal/config/defaults.go +++ b/internal/config/defaults.go @@ -85,6 +85,7 @@ var Defaults = Configuration{ StorageLocalBasePath: "/gotosocial/storage", StorageS3UseSSL: true, StorageS3Proxy: false, + StorageS3RedirectURL: "", StatusesMaxChars: 5000, StatusesPollMaxOptions: 6, diff --git a/internal/config/helpers.gen.go b/internal/config/helpers.gen.go index 587fba364..7523f17ad 100644 --- a/internal/config/helpers.gen.go +++ b/internal/config/helpers.gen.go @@ -1500,6 +1500,31 @@ func GetStorageS3Proxy() bool { return global.GetStorageS3Proxy() } // SetStorageS3Proxy safely sets the value for global configuration 'StorageS3Proxy' field func SetStorageS3Proxy(v bool) { global.SetStorageS3Proxy(v) } +// GetStorageS3RedirectURL safely fetches the Configuration value for state's 'StorageS3RedirectURL' field +func (st *ConfigState) GetStorageS3RedirectURL() (v string) { + st.mutex.RLock() + v = st.config.StorageS3RedirectURL + st.mutex.RUnlock() + return +} + +// SetStorageS3RedirectURL safely sets the Configuration value for state's 'StorageS3RedirectURL' field +func (st *ConfigState) SetStorageS3RedirectURL(v string) { + st.mutex.Lock() + defer st.mutex.Unlock() + st.config.StorageS3RedirectURL = v + st.reloadToViper() +} + +// StorageS3RedirectURLFlag returns the flag name for the 'StorageS3RedirectURL' field +func StorageS3RedirectURLFlag() string { return "storage-s3-redirect-url" } + +// GetStorageS3RedirectURL safely fetches the value for global configuration 'StorageS3RedirectURL' field +func GetStorageS3RedirectURL() string { return global.GetStorageS3RedirectURL() } + +// SetStorageS3RedirectURL safely sets the value for global configuration 'StorageS3RedirectURL' field +func SetStorageS3RedirectURL(v string) { global.SetStorageS3RedirectURL(v) } + // GetStatusesMaxChars safely fetches the Configuration value for state's 'StatusesMaxChars' field func (st *ConfigState) GetStatusesMaxChars() (v int) { st.mutex.RLock() diff --git a/internal/config/validate.go b/internal/config/validate.go index d79d83b9d..723d5c931 100644 --- a/internal/config/validate.go +++ b/internal/config/validate.go @@ -19,6 +19,8 @@ package config import ( "fmt" + "net/url" + "strings" "github.com/miekg/dns" "github.com/superseriousbusiness/gotosocial/internal/gtserror" @@ -118,6 +120,28 @@ func Validate() error { errf("%s must be set", WebAssetBaseDirFlag()) } + // `storage-s3-redirect-url` + if s3RedirectURL := GetStorageS3RedirectURL(); s3RedirectURL != "" { + if strings.HasSuffix(s3RedirectURL, "/") { + errf( + "%s must not end with a trailing slash", + StorageS3RedirectURLFlag(), + ) + } + + if url, err := url.Parse(s3RedirectURL); err != nil { + errf( + "%s invalid: %w", + StorageS3RedirectURLFlag(), err, + ) + } else if url.Scheme != "https" && url.Scheme != "http" { + errf( + "%s scheme must be https or http", + StorageS3RedirectURLFlag(), + ) + } + } + // Custom / LE TLS settings. // // Only one of custom certs or LE can be set, diff --git a/internal/storage/storage.go b/internal/storage/storage.go index 5d5baf283..f3cb814f1 100644 --- a/internal/storage/storage.go +++ b/internal/storage/storage.go @@ -79,6 +79,7 @@ type Driver struct { Proxy bool Bucket string PresignedCache *ttl.Cache[string, PresignedURL] + RedirectURL string } // Get returns the byte value for key in storage. @@ -163,12 +164,27 @@ func (d *Driver) URL(ctx context.Context, key string) *PresignedURL { return &e.Value } - u, err := s3.Client().PresignedGetObject(ctx, d.Bucket, key, urlCacheTTL, url.Values{ - "response-content-type": []string{mime.TypeByExtension(path.Ext(key))}, - }) - if err != nil { - // If URL request fails, fallback is to fetch the file. So ignore the error here - return nil + var ( + u *url.URL + err error + ) + + if d.RedirectURL != "" { + u, err = url.Parse(d.RedirectURL + "/" + key) + if err != nil { + // If URL parsing fails, fallback is to + // fetch the file. So ignore the error here + return nil + } + } else { + u, err = s3.Client().PresignedGetObject(ctx, d.Bucket, key, urlCacheTTL, url.Values{ + "response-content-type": []string{mime.TypeByExtension(path.Ext(key))}, + }) + if err != nil { + // If URL request fails, fallback is to + // fetch the file. So ignore the error here + return nil + } } psu := PresignedURL{ @@ -204,6 +220,14 @@ func (d *Driver) ProbeCSPUri(ctx context.Context) (string, error) { return "", nil } + // If an S3 redirect URL is set, just + // return this URL without probing; we + // likely don't have write access on it + // anyway since it's probs a CDN bucket. + if d.RedirectURL != "" { + return d.RedirectURL + "/", nil + } + const cspKey = "gotosocial-csp-probe" // Create an empty file in S3 storage. @@ -273,6 +297,7 @@ func NewS3Storage() (*Driver, error) { secret := config.GetStorageS3SecretKey() secure := config.GetStorageS3UseSSL() bucket := config.GetStorageS3BucketName() + redirectURL := config.GetStorageS3RedirectURL() // Open the s3 storage implementation s3, err := s3.Open(endpoint, bucket, &s3.Config{ @@ -300,5 +325,6 @@ func NewS3Storage() (*Driver, error) { Bucket: config.GetStorageS3BucketName(), Storage: s3, PresignedCache: presignedCache, + RedirectURL: redirectURL, }, nil } |