From 07d574acd9feaf9d4994c914b022f227c16e132f Mon Sep 17 00:00:00 2001 From: Darius Rapalis Date: Sun, 16 Mar 2025 11:24:00 +0200 Subject: [PATCH] url signing --- handler_upload_video.go | 10 ++++++++-- handler_video_meta.go | 23 +++++++++++++++++++++-- main.go | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 4 deletions(-) diff --git a/handler_upload_video.go b/handler_upload_video.go index d4964c6..d5d7562 100644 --- a/handler_upload_video.go +++ b/handler_upload_video.go @@ -163,7 +163,7 @@ func (cfg *apiConfig) handlerUploadVideo(w http.ResponseWriter, r *http.Request) return } - url := fmt.Sprintf("http://%s.s3.%s.amazonaws.com/%s", cfg.s3Bucket, cfg.s3Region, fileName) + url := fmt.Sprintf("%s,%s", cfg.s3Bucket, fileName) video.VideoURL = &url @@ -179,5 +179,11 @@ func (cfg *apiConfig) handlerUploadVideo(w http.ResponseWriter, r *http.Request) return } - respondWithJSON(w, http.StatusOK, video) + vid, err := cfg.dbVideoToSignedVideo(video) + if err != nil { + respondWithError(w, http.StatusInternalServerError, "Couldn't convert video to signed video", err) + return + } + + respondWithJSON(w, http.StatusOK, vid) } diff --git a/handler_video_meta.go b/handler_video_meta.go index 3266038..6f494aa 100644 --- a/handler_video_meta.go +++ b/handler_video_meta.go @@ -95,7 +95,12 @@ func (cfg *apiConfig) handlerVideoGet(w http.ResponseWriter, r *http.Request) { return } - respondWithJSON(w, http.StatusOK, video) + vid, err := cfg.dbVideoToSignedVideo(video) + if err != nil { + respondWithError(w, http.StatusInternalServerError, "Couldn't convert video to signed video", err) + return + } + respondWithJSON(w, http.StatusOK, vid) } func (cfg *apiConfig) handlerVideosRetrieve(w http.ResponseWriter, r *http.Request) { @@ -116,5 +121,19 @@ func (cfg *apiConfig) handlerVideosRetrieve(w http.ResponseWriter, r *http.Reque return } - respondWithJSON(w, http.StatusOK, videos) + var vids []database.Video + if len(videos) > 0 { + for _, video := range videos { + vid, err := cfg.dbVideoToSignedVideo(video) + if err != nil { + respondWithError(w, http.StatusInternalServerError, "Couldn't convert video to signed video", err) + return + } + vids = append(vids, vid) + } + } else { + vids = make([]database.Video, 0) + } + + respondWithJSON(w, http.StatusOK, vids) } diff --git a/main.go b/main.go index 40fc39a..afb34a8 100644 --- a/main.go +++ b/main.go @@ -4,13 +4,17 @@ import ( "bytes" "context" "encoding/json" + "errors" "fmt" + "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/s3" "log" "net/http" "os" "os/exec" + "strings" + "time" "github.com/bootdotdev/learn-file-storage-s3-golang-starter/internal/database" @@ -80,6 +84,37 @@ func processVideoForFastStart(filePath string) (string, error) { return newName, nil } +func generatePresignedURL(s3Client *s3.Client, bucket, key string, expireTime time.Duration) (string, error) { + presignedClient := s3.NewPresignClient(s3Client) + obj, err := presignedClient.PresignGetObject(context.Background(), &s3.GetObjectInput{ + Bucket: aws.String(bucket), + Key: aws.String(key), + }, s3.WithPresignExpires(expireTime)) + if err != nil { + return "", err + } + return obj.URL, nil +} + +func (cfg *apiConfig) dbVideoToSignedVideo(video database.Video) (database.Video, error) { + + if video.VideoURL == nil { + return video, nil + } + + pieces := strings.Split(*video.VideoURL, ",") + if len(pieces) < 2 { + return database.Video{}, errors.New("Invalid video URL") + } + bucket, key := pieces[0], pieces[1] + url, err := generatePresignedURL(cfg.s3Client, bucket, key, time.Second*600) + if err != nil { + return database.Video{}, err + } + video.VideoURL = &url + return video, nil +} + func main() { godotenv.Load(".env")