wip: file download

This commit is contained in:
loveuer
2024-10-13 22:19:41 +08:00
parent 777253063b
commit 0b58c3347b
7 changed files with 190 additions and 6 deletions

View File

@ -34,6 +34,8 @@ func Init(ctx context.Context) error {
register("/api/bucket/files", handler.BucketFiles)
register("/api/bucket/create", handler.BucketCreate)
register("/api/file/upload", handler.FileUpload)
register("/api/file/info", handler.FileInfo)
register("/api/file/get", handler.FileGet)
return nil
}

View File

@ -86,3 +86,61 @@ func FileUpload(c *ndh.Ctx) error {
return c.Send200(req)
}
func FileInfo(c *ndh.Ctx) error {
type Req struct {
ConnId uint64 `json:"conn_id"`
Bucket string `json:"bucket"`
Key string `json:"key"`
}
var (
err error
req = new(Req)
client *s3.Client
info *s3.ObjectInfo
)
if err = c.ReqParse(req); err != nil {
return c.Send400(err.Error())
}
if _, client, err = manager.Manager.Use(req.ConnId); err != nil {
return c.Send500(err.Error())
}
if info, err = client.GetObjectInfo(c.Context(), req.Bucket, req.Key); err != nil {
return c.Send500(err.Error())
}
return c.Send200(info)
}
func FileGet(c *ndh.Ctx) error {
type Req struct {
ConnId uint64 `json:"conn_id"`
Bucket string `json:"bucket"`
Key string `json:"key"`
}
var (
err error
req = new(Req)
client *s3.Client
link *s3.ObjectEntry
)
if err = c.ReqParse(req); err != nil {
return c.Send400(err.Error())
}
if _, client, err = manager.Manager.Use(req.ConnId); err != nil {
return c.Send500(err.Error())
}
if link, err = client.GetObject(c.Context(), req.Bucket, req.Key); err != nil {
return c.Send500(err.Error())
}
return c.Send200(link)
}

90
internal/s3/get.go Normal file
View File

@ -0,0 +1,90 @@
package s3
import (
"context"
"github.com/aws/aws-sdk-go-v2/aws"
v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4"
"github.com/aws/aws-sdk-go-v2/service/s3"
"github.com/labstack/gommon/log"
"net/http"
"time"
)
type ObjectInfo struct {
Bucket string
Key string
ContentType string
Expire int64
}
func (c *Client) GetObjectInfo(ctx context.Context, bucket string, key string) (*ObjectInfo, error) {
var (
err error
input = &s3.HeadObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
}
output *s3.HeadObjectOutput
)
if output, err = c.client.HeadObject(ctx, input); err != nil {
return nil, err
}
return &ObjectInfo{
Bucket: bucket,
Key: key,
ContentType: aws.ToString(output.ContentType),
Expire: aws.ToTime(output.Expires).UnixMilli(),
}, nil
}
// GetObject
// https://docs.aws.amazon.com/AmazonS3/latest/userguide/example_s3_Scenario_PresignedUrl_section.html
type Presigner struct {
PresignClient *s3.PresignClient
}
func (presigner *Presigner) GetObject(ctx context.Context, bucketName string, objectKey string, lifetimeSecs int64) (*v4.PresignedHTTPRequest, error) {
request, err := presigner.PresignClient.PresignGetObject(ctx, &s3.GetObjectInput{
Bucket: aws.String(bucketName),
Key: aws.String(objectKey),
}, func(opts *s3.PresignOptions) {
opts.Expires = time.Duration(lifetimeSecs * int64(time.Second))
})
if err != nil {
log.Error("Presigner: couldn't get a presigned request to get %v:%v. Here's why: %v\n",
bucketName, objectKey, err)
}
return request, err
}
type ObjectEntry struct {
URL string
Method string
Header http.Header
}
func (c *Client) GetObject(ctx context.Context, bucket string, key string, lifetimes ...int64) (*ObjectEntry, error) {
var (
err error
lifetime int64 = 5 * 60
pc = &Presigner{PresignClient: s3.NewPresignClient(c.client)}
output *v4.PresignedHTTPRequest
)
if len(lifetimes) > 0 && lifetimes[0] > 0 {
lifetime = lifetimes[0]
}
if output, err = pc.GetObject(ctx, bucket, key, lifetime); err != nil {
return nil, err
}
return &ObjectEntry{
URL: output.URL,
Method: output.Method,
Header: output.SignedHeader,
}, nil
}