mirror of
https://git.rwth-aachen.de/acs/public/villas/web-backend-go/
synced 2025-03-30 00:00:12 +01:00
s3: fix broken presigned urls when internal s3 endpoint was different from external
This commit is contained in:
parent
49fe2e6e1f
commit
66d6c3f944
2 changed files with 48 additions and 6 deletions
|
@ -67,6 +67,7 @@ func InitConfig() error {
|
||||||
adminMail = flag.String("admin-mail", "", "Initial admin mail address")
|
adminMail = flag.String("admin-mail", "", "Initial admin mail address")
|
||||||
s3Bucket = flag.String("s3-bucket", "", "S3 Bucket for uploading files")
|
s3Bucket = flag.String("s3-bucket", "", "S3 Bucket for uploading files")
|
||||||
s3Endpoint = flag.String("s3-endpoint", "", "Endpoint of S3 API for file uploads")
|
s3Endpoint = flag.String("s3-endpoint", "", "Endpoint of S3 API for file uploads")
|
||||||
|
s3EndpointPublic = flag.String("s3-endpoint-public", "", "Public endpoint address of S3 API for file uploads")
|
||||||
s3Region = flag.String("s3-region", "default", "S3 Region for file uploads")
|
s3Region = flag.String("s3-region", "default", "S3 Region for file uploads")
|
||||||
s3NoSSL = flag.Bool("s3-nossl", false, "Use encrypted connections to the S3 API")
|
s3NoSSL = flag.Bool("s3-nossl", false, "Use encrypted connections to the S3 API")
|
||||||
s3PathStyle = flag.Bool("s3-pathstyle", false, "Use path-style S3 API")
|
s3PathStyle = flag.Bool("s3-pathstyle", false, "Use path-style S3 API")
|
||||||
|
@ -103,6 +104,7 @@ func InitConfig() error {
|
||||||
"admin.mail": *adminMail,
|
"admin.mail": *adminMail,
|
||||||
"s3.bucket": *s3Bucket,
|
"s3.bucket": *s3Bucket,
|
||||||
"s3.endpoint": *s3Endpoint,
|
"s3.endpoint": *s3Endpoint,
|
||||||
|
"s3.endpoint-public": *s3EndpointPublic,
|
||||||
"s3.region": *s3Region,
|
"s3.region": *s3Region,
|
||||||
"jwt.secret": *jwtSecret,
|
"jwt.secret": *jwtSecret,
|
||||||
"jwt.expires-after": *jwtExpiresAfter,
|
"jwt.expires-after": *jwtExpiresAfter,
|
||||||
|
|
|
@ -22,13 +22,16 @@
|
||||||
package file
|
package file
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"net/url"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.rwth-aachen.de/acs/public/villas/web-backend-go/configuration"
|
"git.rwth-aachen.de/acs/public/villas/web-backend-go/configuration"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
"github.com/aws/aws-sdk-go/aws/session"
|
"github.com/aws/aws-sdk-go/aws/session"
|
||||||
"github.com/aws/aws-sdk-go/service/s3"
|
"github.com/aws/aws-sdk-go/service/s3"
|
||||||
"github.com/aws/aws-sdk-go/service/s3/s3manager"
|
"github.com/aws/aws-sdk-go/service/s3/s3manager"
|
||||||
|
@ -83,7 +86,7 @@ func createS3Session() (*session.Session, error) {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create session: %s", err)
|
return nil, fmt.Errorf("failed to create session: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return sess, nil
|
return sess, nil
|
||||||
|
@ -110,7 +113,7 @@ func (f *File) putS3(fileContent io.Reader) error {
|
||||||
Body: fileContent,
|
Body: fileContent,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to upload file, %v", err)
|
return fmt.Errorf("failed to upload file: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -128,16 +131,21 @@ func (f *File) getS3Url() (string, error) {
|
||||||
svc := s3.New(sess)
|
svc := s3.New(sess)
|
||||||
|
|
||||||
req, _ := svc.GetObjectRequest(&s3.GetObjectInput{
|
req, _ := svc.GetObjectRequest(&s3.GetObjectInput{
|
||||||
Bucket: aws.String(bucket),
|
Bucket: aws.String(bucket),
|
||||||
Key: aws.String(f.Key),
|
Key: aws.String(f.Key),
|
||||||
ResponseContentType: aws.String(f.Type),
|
ResponseContentType: aws.String(f.Type),
|
||||||
// ResponseContentDisposition: aws.String("attachment; filename=" + f.Name),
|
ResponseContentDisposition: aws.String("attachment; filename=" + f.Name),
|
||||||
// ResponseContentEncoding: aws.String(),
|
// ResponseContentEncoding: aws.String(),
|
||||||
// ResponseContentLanguage: aws.String(),
|
// ResponseContentLanguage: aws.String(),
|
||||||
// ResponseCacheControl: aws.String(),
|
// ResponseCacheControl: aws.String(),
|
||||||
// ResponseExpires: aws.String(),
|
// ResponseExpires: aws.String(),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
err = updateS3Request(req)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
urlStr, err := req.Presign(5 * 24 * 60 * time.Minute)
|
urlStr, err := req.Presign(5 * 24 * 60 * time.Minute)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
@ -170,3 +178,35 @@ func (f *File) deleteS3() error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// updateS3Request updates the request host to the public accessible S3
|
||||||
|
// endpoint host so that presigned URLs are still valid when accessed
|
||||||
|
// by the user
|
||||||
|
func updateS3Request(req *request.Request) error {
|
||||||
|
epURL, err := getS3EndpointURL()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
req.HTTPRequest.URL.Scheme = epURL.Scheme
|
||||||
|
req.HTTPRequest.URL.Host = epURL.Host
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getS3EndpointURL() (*url.URL, error) {
|
||||||
|
ep, err := configuration.GlobalConfig.String("s3.endpoint-public")
|
||||||
|
if err != nil {
|
||||||
|
ep, err = configuration.GlobalConfig.String("s3.endpoint")
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("missing s3.endpoint setting")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
epURL, err := url.Parse(ep)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return epURL, nil
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue