Skip to content

Commit 66210c7

Browse files
committed
what
1 parent 75be79c commit 66210c7

9 files changed

+399
-48
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ out
33
.env
44
assets/
55
samples/
6+
.DS_Store

cache.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ package main
22

33
import "net/http"
44

5-
func cacheMiddleware(next http.Handler) http.Handler {
5+
func noCacheMiddleware(next http.Handler) http.Handler {
66
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
7-
w.Header().Set("Cache-Control", "max-age=3600")
7+
w.Header().Set("Cache-Control", "no-store")
88
next.ServeHTTP(w, r)
99
})
1010
}

go.mod

+21
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,24 @@ require (
1313
github.com/lib/pq v1.10.9
1414
github.com/mattn/go-sqlite3 v1.14.24
1515
)
16+
17+
require (
18+
github.com/aws/aws-sdk-go-v2 v1.32.7 // indirect
19+
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 // indirect
20+
github.com/aws/aws-sdk-go-v2/config v1.28.7 // indirect
21+
github.com/aws/aws-sdk-go-v2/credentials v1.17.48 // indirect
22+
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.22 // indirect
23+
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.26 // indirect
24+
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.26 // indirect
25+
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect
26+
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.26 // indirect
27+
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 // indirect
28+
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.7 // indirect
29+
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.7 // indirect
30+
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.7 // indirect
31+
github.com/aws/aws-sdk-go-v2/service/s3 v1.72.0 // indirect
32+
github.com/aws/aws-sdk-go-v2/service/sso v1.24.8 // indirect
33+
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.7 // indirect
34+
github.com/aws/aws-sdk-go-v2/service/sts v1.33.3 // indirect
35+
github.com/aws/smithy-go v1.22.1 // indirect
36+
)

go.sum

+36
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,39 @@
1+
github.com/aws/aws-sdk-go-v2 v1.32.7 h1:ky5o35oENWi0JYWUZkB7WYvVPP+bcRF5/Iq7JWSb5Rw=
2+
github.com/aws/aws-sdk-go-v2 v1.32.7/go.mod h1:P5WJBrYqqbWVaOxgH0X/FYYD47/nooaPOZPlQdmiN2U=
3+
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 h1:lL7IfaFzngfx0ZwUGOZdsFFnQ5uLvR0hWqqhyE7Q9M8=
4+
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7/go.mod h1:QraP0UcVlQJsmHfioCrveWOC1nbiWUl3ej08h4mXWoc=
5+
github.com/aws/aws-sdk-go-v2/config v1.28.7 h1:GduUnoTXlhkgnxTD93g1nv4tVPILbdNQOzav+Wpg7AE=
6+
github.com/aws/aws-sdk-go-v2/config v1.28.7/go.mod h1:vZGX6GVkIE8uECSUHB6MWAUsd4ZcG2Yq/dMa4refR3M=
7+
github.com/aws/aws-sdk-go-v2/credentials v1.17.48 h1:IYdLD1qTJ0zanRavulofmqut4afs45mOWEI+MzZtTfQ=
8+
github.com/aws/aws-sdk-go-v2/credentials v1.17.48/go.mod h1:tOscxHN3CGmuX9idQ3+qbkzrjVIx32lqDSU1/0d/qXs=
9+
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.22 h1:kqOrpojG71DxJm/KDPO+Z/y1phm1JlC8/iT+5XRmAn8=
10+
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.22/go.mod h1:NtSFajXVVL8TA2QNngagVZmUtXciyrHOt7xgz4faS/M=
11+
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.26 h1:I/5wmGMffY4happ8NOCuIUEWGUvvFp5NSeQcXl9RHcI=
12+
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.26/go.mod h1:FR8f4turZtNy6baO0KJ5FJUmXH/cSkI9fOngs0yl6mA=
13+
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.26 h1:zXFLuEuMMUOvEARXFUVJdfqZ4bvvSgdGRq/ATcrQxzM=
14+
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.26/go.mod h1:3o2Wpy0bogG1kyOPrgkXA8pgIfEEv0+m19O9D5+W8y8=
15+
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ=
16+
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc=
17+
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.26 h1:GeNJsIFHB+WW5ap2Tec4K6dzcVTsRbsT1Lra46Hv9ME=
18+
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.26/go.mod h1:zfgMpwHDXX2WGoG84xG2H+ZlPTkJUU4YUvx2svLQYWo=
19+
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 h1:iXtILhvDxB6kPvEXgsDhGaZCSC6LQET5ZHSdJozeI0Y=
20+
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1/go.mod h1:9nu0fVANtYiAePIBh2/pFUSwtJ402hLnp854CNoDOeE=
21+
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.7 h1:tB4tNw83KcajNAzaIMhkhVI2Nt8fAZd5A5ro113FEMY=
22+
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.7/go.mod h1:lvpyBGkZ3tZ9iSsUIcC2EWp+0ywa7aK3BLT+FwZi+mQ=
23+
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.7 h1:8eUsivBQzZHqe/3FE+cqwfH+0p5Jo8PFM/QYQSmeZ+M=
24+
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.7/go.mod h1:kLPQvGUmxn/fqiCrDeohwG33bq2pQpGeY62yRO6Nrh0=
25+
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.7 h1:Hi0KGbrnr57bEHWM0bJ1QcBzxLrL/k2DHvGYhb8+W1w=
26+
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.7/go.mod h1:wKNgWgExdjjrm4qvfbTorkvocEstaoDl4WCvGfeCy9c=
27+
github.com/aws/aws-sdk-go-v2/service/s3 v1.72.0 h1:SAfh4pNx5LuTafKKWR02Y+hL3A+3TX8cTKG1OIAJaBk=
28+
github.com/aws/aws-sdk-go-v2/service/s3 v1.72.0/go.mod h1:r+xl5yzMk9083rMR+sJ5TYj9Tihvf/l1oxzZXDgGj2Q=
29+
github.com/aws/aws-sdk-go-v2/service/sso v1.24.8 h1:CvuUmnXI7ebaUAhbJcDy9YQx8wHR69eZ9I7q5hszt/g=
30+
github.com/aws/aws-sdk-go-v2/service/sso v1.24.8/go.mod h1:XDeGv1opzwm8ubxddF0cgqkZWsyOtw4lr6dxwmb6YQg=
31+
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.7 h1:F2rBfNAL5UyswqoeWv9zs74N/NanhK16ydHW1pahX6E=
32+
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.7/go.mod h1:JfyQ0g2JG8+Krq0EuZNnRwX0mU0HrwY/tG6JNfcqh4k=
33+
github.com/aws/aws-sdk-go-v2/service/sts v1.33.3 h1:Xgv/hyNgvLda/M9l9qxXc4UFSgppnRczLxlMs5Ae/QY=
34+
github.com/aws/aws-sdk-go-v2/service/sts v1.33.3/go.mod h1:5Gn+d+VaaRgsjewpMvGazt0WfcFO+Md4wLOuBfGR9Bc=
35+
github.com/aws/smithy-go v1.22.1 h1:/HPHZQ0g7f4eUeK6HKglFz8uwVfZKgoI25rb/J+dnro=
36+
github.com/aws/smithy-go v1.22.1/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
137
github.com/golang-jwt/jwt/v5 v5.0.0-rc.1 h1:tDQ1LjKga657layZ4JLsRdxgvupebc0xuPwRNuTfUgs=
238
github.com/golang-jwt/jwt/v5 v5.0.0-rc.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
339
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=

handler_get_thumbnail.go

-32
This file was deleted.

handler_upload_thumbnail.go

+66-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
package main
22

33
import (
4+
"crypto/rand"
5+
"encoding/base64"
46
"fmt"
7+
"io"
8+
"mime"
59
"net/http"
10+
"os"
11+
"path/filepath"
612

713
"github.com/bootdotdev/learn-file-storage-s3-golang-starter/internal/auth"
814
"github.com/google/uuid"
@@ -28,10 +34,67 @@ func (cfg *apiConfig) handlerUploadThumbnail(w http.ResponseWriter, r *http.Requ
2834
return
2935
}
3036

31-
3237
fmt.Println("uploading thumbnail for video", videoID, "by user", userID)
3338

34-
// TODO: implement the upload here
39+
const maxMemory = 10 << 20
40+
r.ParseMultipartForm(maxMemory)
41+
42+
file, header, err := r.FormFile("thumbnail")
43+
if err != nil {
44+
respondWithError(w, http.StatusBadRequest, "Unable to parse form file", err)
45+
return
46+
}
47+
defer file.Close()
48+
49+
mimeType := header.Header.Get("Content-Type")
50+
mediaType, _, err := mime.ParseMediaType(mimeType)
51+
if mediaType != "image/jpeg" && mediaType != "image/png" {
52+
respondWithError(w, http.StatusBadRequest, "Upload a valid jpeg/png", err)
53+
return
54+
}
55+
56+
extensions, err := mime.ExtensionsByType(mimeType)
57+
if err != nil || len(extensions) == 0 {
58+
respondWithError(w, http.StatusBadRequest, "Invalid file format", err)
59+
return
60+
}
61+
62+
video, err := cfg.db.GetVideo(videoID)
63+
if err != nil || video.UserID != userID {
64+
respondWithError(w, http.StatusUnauthorized, "Unauthorized", err)
65+
return
66+
}
67+
68+
b := make([]byte, 32)
69+
_, err = rand.Read(b)
70+
if err != nil {
71+
respondWithError(w, http.StatusInternalServerError, "Internal Server Error", err)
72+
return
73+
}
74+
75+
filenameNoExt := base64.RawURLEncoding.EncodeToString(b)
76+
77+
filename := filepath.Join(cfg.assetsRoot, filenameNoExt+extensions[0])
78+
newfile, err := os.Create(filename)
79+
if err != nil {
80+
respondWithError(w, http.StatusInternalServerError, "Internal Server Error", err)
81+
return
82+
}
83+
84+
_, err = io.Copy(newfile, file)
85+
if err != nil {
86+
respondWithError(w, http.StatusInternalServerError, "Internal Server Error", err)
87+
return
88+
}
89+
90+
thumbnailURL := fmt.Sprintf("http://localhost:%s/assets/%s", cfg.port, filenameNoExt+extensions[0])
91+
video.ThumbnailURL = &thumbnailURL
92+
93+
err = cfg.db.UpdateVideo(video)
94+
if err != nil {
95+
respondWithError(w, http.StatusInternalServerError, "Error uploading video thumbnail", err)
96+
return
97+
}
3598

36-
respondWithJSON(w, http.StatusOK, struct{}{})
99+
respondWithJSON(w, http.StatusOK, video)
37100
}

0 commit comments

Comments
 (0)